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

329 lines
9.7 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 { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { apiUrl } from '@/config/api';
import { useGetFilialsQuery, useUpdateFilialMutation, useUploadFilialPictureMutation } from '../api/apiFilial';
import { selectUtils } from '../store/slice/utilsSlice';
import { selectRegions } from '../store/slice/regionSlice';
/**/
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 { PhoneInput } from '../components/Input/PhoneInput';
export const EditFilialPage = () => {
const { id } = useParams();
const { data: filialsRaw = [], isLoading, loadingError } = useGetFilialsQuery();
const PHOTO_PLACEHOLDER = '/src/assets/photo-placeholder.png';
const photoInputRef = useRef(null);
const filials = filialsRaw.length === 0 ? [] : filialsRaw.data;
const filial = filials.find( ( filial ) => String( filial.fid ) === id );
const regions = useSelector( selectRegions );
const RELOAD_TIMEOUT = useSelector(selectUtils).RELOAD_TIMEOUT;
const [ updateFilial ] = useUpdateFilialMutation();
const [uploadPicture] = useUploadFilialPictureMutation();
const navigate = useNavigate();
const navigateBack = () => navigate( `/filials` );
const [ form, setForm ] = useState({
id: '',
regionId: '',
address: '',
name: '',
siteId: '',
company: '',
phone: '',
active: '',
email: '',
fid: '',
origin: '',
picture: null,
policy: '',
});
const updateField = ( key, value ) => {
const normalized = value === undefined || value === null ? '' : value;
setForm(prev => ({ ...prev, [key]: normalized }));
};
const [ modal, setModal ] = useState( undefined );
const [previewFile, setPreviewFile] = useState(null);
useEffect(() => {
if (!filial) return;
const filialData = {
id: filial.id,
regionId: filial.regionId,
address: filial.address,
name: filial.name,
siteId: filial.siteId,
company: filial.company,
phone: filial.phone,
active: filial.active,
email: filial.email,
fid: filial.fid,
origin: filial.origin,
picture: apiUrl(filial.pictureLink),
policy: filial.policy,
}
setForm({... filialData})
}, [ filial ]);
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);
};
const handlePhotoUpload = () => {
const file = photoInputRef.current.files[0]
if (!file) return window.alert('Файл не выбран')
if (!isValidImage(file)) {
return window.alert('Изображения должны быть только формата JPG, JPEG или PNG');
}
updateField('picture', window.URL.createObjectURL(file));
setPreviewFile(file);
}
const handleSave = async () => {
setModal('loading');
const data = {
id: form.id,
fid: form.fid,
active: form.active,
regionId: Number(form.regionId),
address: form.address || '',
name: form.name || '',
company: form.company || '',
phone: form.phone ? form.phone.replaceAll(' ', '') : '',
email: form.email || '',
policy: form.policy || '',
origin: form.origin || '',
};
try {
await updateFilial( { filialId: form.fid, data: form.siteId ? { ...data, siteId: form.siteId } : data } ).unwrap();
if (previewFile) {
await uploadPicture({ id: form.id, file: previewFile }).unwrap();
console.log('success photo update')
}
setModal('success');
window.setTimeout(() => { window.location.reload() }, RELOAD_TIMEOUT);
}
catch ( error ) {
setModal('error')
console.error('Filial update error:', error);
}
}
if ( isLoading ) return <LoadingComponent />
if ( loadingError ) return <ErrorComponent />
if ( !filial ) return (
<NotFindElement
message={ `Филиал с ID=${id} не найден.` }
navigateBack={ navigateBack }
/>
)
return (
<EditElementForm
navigateBack={ navigateBack }
header={ `Редактировать филиал #${ filial.fid }` }
handleSave={ handleSave }
isAddSpecialist={ true }
>
<div style={{ display: 'flex', gap: '1rem' }} className='photo-filial-block'>
<div className='align-self-start'>
<div className="form-group d-flex flex-column" style={{ gap: '0.75rem' }}>
<img
src={ form.picture }
alt="Фото врача"
style={{ width: '12rem', height: '12rem', objectFit: 'cover', borderRadius: '3%' }}
className=""
onError={ e => e.currentTarget.src = PHOTO_PLACEHOLDER }
/>
<button
type="button"
className="btn btn-outline-secondary"
style={{ width: '100%' }}
onClick={ () => photoInputRef.current.click() }
>
Загрузить фото
</button>
<input
type="file"
accept="image/*"
ref={ photoInputRef }
style={{ display: 'none' }}
onChange={handlePhotoUpload}
/>
</div>
</div>
<div style={{ flexGrow: 1 }}>
<div style={{ flexGrow: 1 }}>
<div className='d-flex filial-input-string' style={{ gap: '1rem' }}>
<div className="form-group">
<label htmlFor="regionSelect">
Город
</label>
<select
id="regionSelect"
className="form-control w-auto"
value={ form.regionId }
onChange={( e ) => updateField( 'regionId', e.target.value )}
>
{
Object.entries( regions ).map(( [ key, label ] ) => (
<option key={ key } value={ key }>
{ label }
</option>
))
}
</select>
</div>
<div className="form-group" style={{ flexGrow: 1 }}>
<label>
ID филиала
</label>
<input
type="text"
className="form-control"
value={ form.fid }
onChange={( e ) => updateField( 'fid', e.target.value )}
/>
</div>
<div className="form-group" style={{ flexGrow: 1 }}>
<label>
Calltouch ID
</label>
<input
type="text"
className="form-control"
value={ form.siteId }
onChange={( e ) => updateField( 'siteId', e.target.value )}
/>
</div>
</div>
</div>
<div>
<div className="form-group">
<label>
Название
</label>
<input
type="text"
className="form-control"
value={ form.name }
onChange={( e ) => updateField( 'name', e.target.value )}
/>
</div>
<div className="form-group">
<label>
Компания
</label>
<input
type="text"
className="form-control"
value={ form.company }
onChange={( e ) => updateField( 'company', e.target.value )}
/>
</div>
</div>
</div>
</div>
<div className="form-group">
<label>
Адрес
</label>
<input
type="text"
className="form-control"
value={ form.address }
onChange={( e ) => updateField( 'address', e.target.value )}
/>
</div>
<div className="form-group">
<label>
Телефон
</label>
<PhoneInput
value={form.phone}
onChange={(val) => updateField('phone', val)}
/>
</div>
<div className="form-group">
<label>
Электронная почта филиала
</label>
<input
type="text"
className="form-control"
value={ form.email }
onChange={( e ) => updateField( 'email', e.target.value )}
/>
</div>
<div className="form-group">
<label>
Ссылка на сайт
</label>
<input
type="text"
className="form-control"
value={ form.origin }
onChange={( e ) => updateField( 'origin', e.target.value )}
/>
</div>
<div className="form-group">
<label>
Ссылка на политику кониденциальности
</label>
<input
type="text"
className="form-control"
value={ form.policy }
onChange={( e ) => updateField( 'policy', e.target.value )}
/>
</div>
<ResponseModals
modal={ modal }
setModal={ setModal }
/>
</EditElementForm>
)
}