Files
adminpanel/src/pages/EditArticlePage.jsx
T
2026-06-03 18:38:00 +03:00

114 lines
6.6 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { useGetArticleQuery, useUpdateArticleMutation, useDeleteArticleMutation } from '/src/api/apiArticle';
import { selectRegions } from '../store/slice/regionSlice';
import { TextEditor } from '../components/Editors/TextEditor';
import { LoadingComponent } from '../components/Placeholders/LoadingComponent';
import { ErrorComponent } from '../components/Placeholders/ErrorComponent';
import { NotFindElement } from '../components/Placeholders/NotFindElement';
import { EditElementForm } from '../components/Forms/EditElementForm';
import Modal from '../components/Modals/Modal';
export function EditArticlePage() {
const { id } = useParams();
const navigate = useNavigate();
const navigateBack = () => navigate(`/article`);
const regions = useSelector(selectRegions);
const { data: item, isFetching, error } = useGetArticleQuery({ articleId: id });
const [updateArticle] = useUpdateArticleMutation();
const [deleteArticle] = useDeleteArticleMutation();
const [isModalSuccess, setModalSuccess] = useState(false);
const [errors, setErrors] = useState({ name: '', alias: '', regionId: '' });
const [form, setForm] = useState({
name: '',
active: false,
regionId: '',
alias: '',
previewPicture: '',
doctors: '',
services: '',
});
const [anons, setAnons] = useState('');
const [content, setContent] = useState('');
useEffect(() => {
if (!item) return;
setForm({
name: item.name ?? '',
active: Boolean(item.active),
regionId: item.regionId ?? '',
alias: item.alias ?? '',
previewPicture: item.previewPicture ?? '',
doctors: item.doctors == null ? '' : JSON.stringify(item.doctors, null, 2),
services: item.services == null ? '' : JSON.stringify(item.services, null, 2),
});
setAnons(item.anons ?? '');
setContent(item.content ?? '');
}, [item]);
const handleChange = (key) => (e) => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
setForm((f) => ({ ...f, [key]: value }));
if (key === 'name' || key === 'alias' || key === 'regionId') setErrors((err) => ({ ...err, [key]: '' }));
};
const handleDelete = async () => {
try {
await deleteArticle({ articleId: id }).unwrap();
setModalSuccess(true);
window.setTimeout(() => navigateBack(), 2000);
} catch (err) {
console.error('Ошибка при удалении:', err);
}
};
const handleSave = async () => {
const newErrors = { name: '', alias: '', regionId: '' };
let hasError = false;
if (!String(form.name ?? '').trim()) { newErrors.name = 'Название не может быть пустым'; hasError = true; }
if (!String(form.alias ?? '').trim()) { newErrors.alias = 'Alias не может быть пустым'; hasError = true; }
if (form.regionId === '' || form.regionId == null) { newErrors.regionId = 'Укажите регион'; hasError = true; }
if (hasError) { setErrors(newErrors); window.alert('Пожалуйста исправьте ошибки в форме.'); return; }
const data = { anons, content };
try {
data.name = form.name === '' ? null : form.name;
data.active = Boolean(form.active);
data.regionId = form.regionId === '' ? null : Number(form.regionId);
data.alias = form.alias === '' ? null : form.alias;
data.previewPicture = form.previewPicture === '' ? null : form.previewPicture;
data.doctors = !form.doctors || !String(form.doctors).trim() ? null : JSON.parse(form.doctors);
data.services = !form.services || !String(form.services).trim() ? null : JSON.parse(form.services);
} catch (e) { window.alert('Пожалуйста исправьте ошибки в форме.'); return; }
try {
await updateArticle({ articleId: id, data }).unwrap();
setModalSuccess(true);
window.setTimeout(() => window.location.reload(), 2000);
} catch (err) {
console.error('Ошибка сохранения:', err);
}
};
if (isFetching) return <LoadingComponent />;
if (error) return <ErrorComponent />;
if (!item) return <NotFindElement message={`Статья с ID=${id} не найдена.`} navigateBack={navigateBack} />;
return (
<EditElementForm navigateBack={navigateBack} header={`Редактирование: статью #${id}`} handleSave={handleSave} handleDelete={handleDelete}>
<div className="form-group"><label>Название</label><input type="text" className="form-control" value={form.name} onChange={handleChange('name')} />
{errors.name && <small className="text-danger">{errors.name}</small>}</div>
<div className="form-group form-check"><input type="checkbox" className="form-check-input" id="active" checked={Boolean(form.active)} onChange={handleChange('active')} /><label className="form-check-label" htmlFor="active">Активно</label></div>
<div className="form-group"><label>Регион</label><select className="form-control" value={form.regionId === '' || form.regionId == null ? '' : String(form.regionId)} onChange={handleChange('regionId')}><option value=""></option>{Object.entries(regions).map(([rid, name]) => (<option key={rid} value={rid}>{name}</option>))}</select>
{errors.regionId && <small className="text-danger">{errors.regionId}</small>}</div>
<div className="form-group"><label>Alias</label><input type="text" className="form-control" value={form.alias} onChange={handleChange('alias')} />
{errors.alias && <small className="text-danger">{errors.alias}</small>}</div>
<div className="form-group"><label>Анонс</label><TextEditor content={anons} setContent={setAnons} /></div>
<div className="form-group"><label>Контент</label><TextEditor content={content} setContent={setContent} /></div>
<div className="form-group"><label>previewPicture</label><input type="text" className="form-control" value={form.previewPicture} onChange={handleChange('previewPicture')} /></div>
<div className="form-group"><label>doctors (JSON)</label><textarea className="form-control font-monospace" rows={4} value={form.doctors} onChange={handleChange('doctors')} /></div>
<div className="form-group"><label>services (JSON)</label><textarea className="form-control font-monospace" rows={4} value={form.services} onChange={handleChange('services')} /></div>
<Modal isOpen={isModalSuccess} title="Изменения внесены" hasButtons={false}><p className="mb-1">Изменения успешно внесены.</p></Modal>
</EditElementForm>
);
}