import { useState, useEffect, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { apiUrl } from '@/config/api'; import { useGetStockQuery, useUpdateStockMutation, useUploadStockPictureMutation, useDeleteStockMutation, } from '/src/api/apiStock'; /**/ import { selectUtils } from '../store/slice/utilsSlice'; /**/ 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 { ResponseModals } from '../components/Modals/ResponseModals'; /**/ import { Modal} from '../components/Modals/Modal'; const isValidImage = (file) => { const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png']; if (allowedTypes.includes(file.type)) return true; const ext = file.name.split('.').pop().toLowerCase(); return ['jpg', 'jpeg', 'png'].includes(ext); }; export function EditStockPage() { const { id } = useParams(); const navigate = useNavigate(); const navigateBack = () => navigate( `/promotions` ); const { data: stock, isFetching, error } = useGetStockQuery( { stockId: id } ); const [ updateStock ] = useUpdateStockMutation(); const [ uploadPicture ] = useUploadStockPictureMutation(); const [ deleteStock ] = useDeleteStockMutation(); const [ isModalSuccess, setModalSuccess ] = useState( false ); const [ errors, setErrors ] = useState({ name: '', dateRange: '' }); const [ form, setForm ] = useState({ name: '', anons: '', picture: '', }); const [ anons, setAnons ] = useState( '' ); const [ content, setContent ] = useState( '' ); const fileInputRef = useRef(); useEffect( () => { if ( !stock ) return; let datetimeLocalStart = ''; let datetimeLocalEnd = ''; if ( stock.startDate ) { const dateStart = new Date( stock.startDate ); const yearStart = dateStart.getFullYear(); const monthStart = String( dateStart.getMonth() + 1 ).padStart( 2, '0' ); const dayStart = String( dateStart.getDate() ).padStart( 2, '0' ); const hoursStart = String( dateStart.getHours() ).padStart( 2, '0' ); const minutesStart = String( dateStart.getMinutes() ).padStart( 2, '0' ); datetimeLocalStart = `${ yearStart }-${ monthStart }-${ dayStart }T${ hoursStart }:${ minutesStart }`; } if ( stock.endDate ) { const dateEnd = new Date( stock.endDate ); const yearEnd = dateEnd.getFullYear(); const monthEnd = String( dateEnd.getMonth() + 1 ).padStart( 2, '0' ); const dayEnd = String( dateEnd.getDate() ).padStart( 2, '0' ); const hoursEnd = String( dateEnd.getHours() ).padStart( 2, '0' ); const minutesEnd = String( dateEnd.getMinutes() ).padStart( 2, '0' ); datetimeLocalEnd = `${ yearEnd }-${ monthEnd }-${ dayEnd }T${ hoursEnd }:${ minutesEnd }`; } setForm(prev => ({ ...prev, name: stock.name ?? '', startDate: datetimeLocalStart, endDate: datetimeLocalEnd, picture: stock.picture ? apiUrl(`/uploads/${stock.picture}`) : '', })); setAnons( stock.anons ) setContent( stock.content ) }, [ stock ]); const startDateInputRef = useRef(null); const endDateInputRef = useRef(null); const handleChange = (key) => (e) => { setForm(f => ({ ...f, [key]: e.target.value })); setErrors(err => ({ ...err, [key === 'name' ? 'name' : 'dateRange']: '' })); }; const handleFile = (e) => { const file = e.target.files[0]; if (!file) return window.alert('Файл не выбран') if (!isValidImage(file)) { return window.alert('Изображения должны быть только формата JPG, JPEG или PNG'); } const url = window.URL.createObjectURL(file); setForm(f => ({ ...f, _file: file, picture: url })); }; const handleSave = async () => { let hasError = false; const newErrors = { name:'', dateRange:'' }; if (!form.name.trim()) { newErrors.name = 'Название не может быть пустым'; hasError = true; } const start = new Date(form.startDate); const end = new Date(form.endDate); if (isNaN(start) || isNaN(end) || start > end) { newErrors.dateRange = 'Дата начал акции должна быть не позже даты окончания'; hasError = true; } if (hasError) { setErrors(newErrors); window.alert('Пожалуйста исправьте ошибки в форме.'); return; } try { await updateStock({ stockId: id, data: { name: form.name, anons: anons, content: content, startDate: String(form.startDate), endDate: String(form.endDate), } }).unwrap(); if (form._file) { await uploadPicture({ id, file: form._file }).unwrap(); } } catch (err) { console.error('Ошибка при обновлении акции:', err) } setModalSuccess(true) window.setTimeout(() => { window.location.reload() }, 2000); console.log('success update promotion') }; const handleDelete = async () => { try { await deleteStock({stockId: id}).unwrap() console.log('success delete') setModalSuccess(true) window.setTimeout(() => { navigateBack() }, 2000); } catch (err) { console.error('Ошибка при удалении специалиста:', err) } } if ( isFetching ) return if ( error ) return if ( !stock ) return ( ) return ( Название {errors.name && {errors.name}} Начало акции: { if (startDateInputRef.current?.showPicker) { startDateInputRef.current.showPicker(); } }} onChange={handleChange('startDate')} /> Окончание акции: { if (endDateInputRef.current?.showPicker) { endDateInputRef.current.showPicker(); } }} onChange={handleChange('endDate')} /> {errors.dateRange && ( {errors.dateRange} )} *Время указывается по МСК Анонс Изображение {form.picture && ( )} fileInputRef.current.click()} > Загрузить… Полное описание Изменения успешно внесены. ) }
Изменения успешно внесены.