/
TimurIsm
/
OpenEyes
Обзор
Документация
Войти
/
TimurIsm
/
OpenEyes
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
front/src/adminOption/EditArticle.jsx
170 строк
6 KB
TimurIsm
first_commit
16 май 2026, 15:34
16 май 2026, 15:34
4d3f198
Код
Авторство
О чём код?
import React, { useState, useEffect, useMemo, useCallback } from 'react'; import { fetchArticlesList, deleteArticle, updateArticle } from '../http/articlesAPI'; import ModalConfirm from '../modals/ModalConfirm'; import EditArticleModal from '../modals/EditArticleModal'; import SearchBar from '../components/SearchBar'; import AlertMessage from '../components/AlertMessage'; import { EditIcon, DeleteIcon } from '../buttons/IconButton'; const EditArticle = () => { const [articlesState, setArticlesState] = useState({ articles: [], searchTerm: '', alertMessage: null }); const [modalState, setModalState] = useState({ type: null, articleId: null, article: null, }); useEffect(() => { const loadArticles = async () => { try { const data = await fetchArticlesList(); setArticlesState(prev => ({ ...prev, articles: data.sort((a, b) => a.id - b.id), alertMessage: null })); } catch (error) { console.error('Ошибка при загрузке статей:', error); setArticlesState(prev => ({ ...prev, alertMessage: {type: 'error', message: 'Ошибка при загрузке статей'} })); } }; loadArticles(); }, []); const handleSearch = useCallback((e) => { setArticlesState(prev => ({ ...prev, searchTerm: e.target.value })); }, []); const filteredArticles = useMemo(() => { return articlesState.articles.filter(article => article.title.toLowerCase().includes(articlesState.searchTerm.toLowerCase())).sort((a, b) => a.id - b.id); }, [articlesState.articles, articlesState.searchTerm]); const handleDelete = useCallback((id) => { setModalState({type: 'delete', articleId: id,}); }, []); const confirmDelete = useCallback(async () => { try { setArticlesState((prev) => ({ ...prev, articles: prev.articles.filter((article) => article.id !== modalState.articleId).sort((a, b) => a.id - b.id), alertMessage: {type: 'success', message: 'Статья успешно удалена!'} })); setModalState({ type: null, articleId: null }); await deleteArticle(modalState.articleId); } catch (error) { console.error('Ошибка при удалении статьи:', error); setArticlesState(prev => ({ ...prev, alertMessage: {type: 'error', message: 'Ошибка при удалении статьи'} })); } }, [modalState]); const handleEdit = useCallback((article) => { setModalState({ type: 'edit', articleId: article.id, article, }); }, []); const handleSave = useCallback(async (updatedArticleData) => { try { setArticlesState(prev => ({ ...prev, articles: prev.articles.map(article => article.id === modalState.articleId ? { ...article, ...updatedArticleData } : article).sort((a, b) => a.id - b.id), alertMessage: {type: 'success', message: 'Статья успешно обновлена!'} })); setModalState({ type: null, articleId: null, article: null }); await updateArticle(modalState.articleId, updatedArticleData); } catch (error) { console.error('Ошибка при обновлении статьи:', error); setArticlesState(prev => ({ ...prev, alertMessage: {type: 'error', message: 'Ошибка при обновлении статьи'} })); } }, [modalState]); const closeModal = useCallback(() => { setModalState({ type: null, articleId: null, article: null }); }, []); return ( <div className="p-4"> <h2 className="text-2xl font-bold mb-8 text-center">Редактирование статей</h2> <div className="flex justify-center"> <div className="md:w-1/2 w-full"> <SearchBar searchTerm={articlesState.searchTerm} handleSearch={handleSearch} placeholderText={"Поиск статьи..."} /> {articlesState.alertMessage && ( <div className="mb-4"> <AlertMessage type={articlesState.alertMessage.type} message={articlesState.alertMessage.message} /> </div> )} </div> </div> <div className="flex justify-center"> <div className="space-y-8 md:w-1/2 w-full mb-4 mt-4"> {filteredArticles.map(article => ( <div key={article.id} className="flex justify-between items-center p-4 bg-white border border-gray-200 rounded-lg shadow-md"> <span className="text-lg font-semibold break-words whitespace-normal overflow-hidden"> {article.title} </span> <div className="flex space-x-4"> <button onClick={() => handleEdit(article)} className="text-gray-500 hover:text-gray-700" > <EditIcon className="w-6 h-6" /> </button> <button onClick={() => handleDelete(article.id)} className="text-gray-500 hover:text-gray-700" > <DeleteIcon className="w-6 h-6" /> </button> </div> </div> ))} </div> </div> <ModalConfirm isOpen={modalState.type === 'delete'} onClose={closeModal} onConfirm={confirmDelete} message="Вы уверены, что хотите удалить эту статью?" /> <EditArticleModal isOpen={modalState.type === 'edit'} onClose={closeModal} onSave={handleSave} article={modalState.article} /> </div> ); }; export default EditArticle;