import {useEffect, useState, useMemo, useRef} from 'react' import {useParams, useNavigate, useLocation } from 'react-router-dom' import DatePicker from "react-datepicker"; import { useUpdateSpecialistMutation, useDeleteSpecialistMutation, useUploadSpecialistPictureMutation } from '../api/apiSpecialist' import { useCreateLocationMutation, useUpdateLocationMutation, useDeleteLocationMutation } from '/src/api/apiLocation.js' import { useCreateCertificateMutation, useUpdateCertificateMutation, useUploadSertificatePictureMutation, useDeleteCertificateMutation, } from '/src/api/apiCertificate.js' import { useAddSpecialistMutation, useRemoveSpecialistMutation } from '../api/apiStock' import { useSpecialist } from '../hooks/useSpecialist'; // 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 { TagInput } from '../components/Input/Taginput'; import { TagStaticInput } from '../components/Input/TagStaticInput'; import { TagKodoperStaticInput } from '../components/Input/TagKodoperStatic'; import { TextEditor } from '../components/Editors/TextEditor' import Modal from '../components/Modals/Modal'; import DcodeModal from '../components/Modals/DcodeModal'; import KodoperModal from '../components/Modals/KodoperModal'; import { CertificatesForm } from '../components/Docs/Certificates'; import { PortfolioForm } from '../components/Docs/Portfolio'; import { StocksForm } from '../components/Docs/Stocks' import { StockModal } from '../components/Modals/StockModal' import PHOTO_PLACEHOLDER from '../assets/photo-placeholder.png' const formatStockDate = (date) => { const dateStart = new Date(date); const year = dateStart.getFullYear(); const month = String(dateStart.getMonth() + 1).padStart(2, '0'); const day = String(dateStart.getDate()).padStart(2, '0'); const hours = String(dateStart.getHours()).padStart(2, '0'); const minutes = String(dateStart.getMinutes()).padStart(2, '0'); return `${hours}:${minutes}, ${day}.${month}.${year}`; } const regionOptions = { 91: 'Саратов' , 92: 'Волгоград', 93: 'Воронеж', 94: 'Краснодар', }; const sTypeOptions = { 0: 'Взрослый врач', 1: 'Детский врач', 2: 'Администрация', 3: 'Стоматология', 4: 'Мед. сестра', }; const getYear = (date) => { const dateObject = new Date(date); return String(dateObject.getFullYear()) } const formatCategory = (rawCategory) => { if (!rawCategory) return 'Не указано' const categoryLowerCase = rawCategory.toLowerCase(); switch (categoryLowerCase) { case 'высшая': case 'ведущий специалист': return 'Высшая'; case 'первая': case 'главный специалист': return 'Первая'; case 'вторая': return 'Вторая'; default: return 'Не указано' } } export const EditSpecialistPage = () => { const { id } = useParams(); const { state } = useLocation(); const queryParams = { search: state?.search ?? '', region: state?.region ?? '', page: state?.page ?? null, } const navigate = useNavigate(); const navigateBack = () => { let query = ''; Object.keys(queryParams).map( param => { if (queryParams[param]) query += `&${param}=${queryParams[param]}`; }); if (query) query = `?${query.slice(1)}`; navigate( `/specialist${query}` ); } const dateInputRef = useRef(null); const patientAgeInputRef = useRef(null); const [ locations, setLocations ] = useState([]); const [ initialLocations, setInitialLocations ] = useState([]); const setFromRawLocations = (rawLocations) => { const selectedDcodes = [...new Set(rawLocations.map(({dcode}) => dcode))]; const arr = selectedDcodes.filter(dcode => !dcodes.includes(dcode)).map(dc => String(dc)); setDcodes(arr) setLocations(rawLocations) } const [ stocks, setStocks ] = useState([]); const [ stocksFromChild, setStocksFromChild ] = useState([]); const [ anons, setAnons ] = useState(''); const [ content, setContent ] = useState(''); const [displayKodoper, setDisplayKodoper] = useState([]); const [errors, setErrors] = useState({ lastName: '', firstName: '', middleName: '', videoUrl: '', videoCardUrl: '', patientAge: '', prodoctorLink: '', }); const categoryList = [ 'Не указано', 'Вторая', 'Первая', 'Высшая', ]; const [isModalKodopers, setModalKodopers] = useState(false); const [kodopers, setKodopers] = useState([]); const [certificates, setCertificates] = useState([]); const [portfolio, setPortfolio] = useState([]); const [ form, setForm ] = useState({ nameString: '', lastName: '', firstName: '', middleName: '', active: false, // boolean displaySchedule: null, // boolean // hideSchedule: false, // booleal // alias: undefined, // string post: '', // string experience: undefined, // number sType: null, // number regionId: null, // number anons: '', // string + add redactor content: '', // string + add redactor tags: [], // json highlightedTags: [], // json videoUrl: '', // string videoCardUrl: '', // string scheduleText: '', //isCastom: false, // has autoupdate - boolean category: '', // +++++++ previewPicture: undefined, // string filialId: null, // from locations.locations[0].filial kodoper: null, // <<<---??? prodoctor: '', prodoctorLink: '', prodoctorText: '', onlyOnlineMode: '', // isChildrenDoctor: undefined, // from sType patientAge: undefined, // integer initStocks: [], //isCastomChecker: undefined, // degree: '', isLeadingSpecialist: false, isChiefSpecialist: false, education: '', academicDegree: '', professionalCompetencies:'', advancedTraining: '', certificates: '', certificatesGallery: [], adultsReception: '', cost: '', hasPromotion: false, onlineConsultationLink: '', onlyOnline: false, hasProDoctorsAward: false, proDoctorsAwardText: '', proDoctorsAwardLink: '', postTags: [], operationPhotoUrl: '', }); const updateField = ( key, value ) => { setForm(prev => ({ ...prev, [key]: value })); }; const [isModalStocks, setModalStocks] = useState(false); const regexCyrillic = /^[А-ЯЁ][а-яё]+$/; const regexRutube = /^https:\/\/rutube\.ru\/.*$/; const regexProdoctor = /^https:\/\/prodoctorov\.ru\/.*$/; const validateField = (field, value) => { let error = ''; const currentYear = new Date().getFullYear(); switch (field) { case 'lastName': case 'firstName': case 'middleName': if (!value) error = 'Обязательное поле'; else if (!regexCyrillic.test(value)) error = 'Только кириллица, с заглавной буквы'; break; case 'experience': if (!value) { error = 'Обязательное поле'; } else if (Number(getYear(value)) > Number(currentYear)) { error = 'Год должен быть не больше текущего'; } break; case 'videoUrl': case 'videoCardUrl': if (value && !regexRutube.test(value)) error = 'Должно быть ссылкой с rutube'; break; case 'prodoctorLink': if (form.prodoctor) { if (!value) { error = 'Укажите ссылку'; } else { if (value && !regexProdoctor.test(value)) error = 'Должно быть ссылкой с prodoctorov.ru'; } } else { error = '' } break; case 'patientAge': if (form.isChildrenDoctor) { if ( !value ) { error = 'Укажите возраст'; } else { const num = Number(value); if (!Number.isInteger(num) || num < 0 || num > 18) error = 'Возраст не может быть меньше 0 и больше 18'; } } else { error = '' } break; } setErrors(prev => ({ ...prev, [field]: error })); }; const handleBlur = e => { const { name, value } = e.target; validateField(name, value); }; const isFormValid = () => { ['lastName', 'firstName', 'middleName', 'videoUrl', 'videoCardUrl', 'patientAge', 'prodoctorLink', 'experience'].forEach(f => validateField(f, form[f])); const a = form.prodoctor ? ( form.prodoctorLink.length > 0 ) : true; const b = form.isChildrenDoctor ? ( form.patientAge ) : true; return Object.entries(errors).every( ([key, err]) => { return !err; } ) && form.lastName && form.firstName && form.middleName && a && b && form.experience; }; const [ tags, setTags ] = useState([]); const [ highlightedTags, setHighlightedTags ] = useState([]); const [ postTags, setPostTags ] = useState([]); const [ dcodes, setDcodes ] = useState([]); const photoInputRef = useRef(null) const photoOperationInputRef = useRef(null) const certificatesGalleryInputRef = useRef(null) const { isLoading, error, specialist, filials, regions, departments, kodoperDetails } = useSpecialist(id); const [updateSpecialist, { isLoading: isUpdating, isError: updateError }] = useUpdateSpecialistMutation(); const [uploadPicture, { isLoadingPicture, isErrorOicture }] = useUploadSpecialistPictureMutation(); const [deleteSpecialist, { isLoading: isDeleting, isError: deleteError }] = useDeleteSpecialistMutation(); const [createLocation] = useCreateLocationMutation(); const [updateLocation]= useUpdateLocationMutation(); const [deleteLocation] = useDeleteLocationMutation(); const [addSpecialistToStock] = useAddSpecialistMutation(); const [removeSpecialistToStock] = useRemoveSpecialistMutation(); const [createCertifcate] = useCreateCertificateMutation(); const [updateCertifcate] = useUpdateCertificateMutation(); const [uploadCertifcatePicture] = useUploadSertificatePictureMutation(); const [deleteCertifcate] = useDeleteCertificateMutation(); const filialsList = useMemo(() => { const arr = filials?.data ?? []; return arr.map(({ fid, regionId, shortName }) => ({ id: fid, regionId, shortName })); }, [filials?.data]); const departmentsList = useMemo(() => { const arr = departments?.data ?? []; return arr.map(({ did, name }) => ({ id: did, name })); }, [departments?.data]); useEffect( () => { if ( specialist ) { const initial = specialist.post ? specialist.post.split(',').map(s => s.trim()) : []; const reorderInit = []; initial.map((element, index) => { if (element.length < 4) { if (index > 0) { reorderInit.pop(); reorderInit.push(`${ initial[index-1]}, ${element}`); return } reorderInit.push(element); return } reorderInit.push(element); return }); setPostTags(reorderInit); if (specialist.locations) { setInitialLocations(specialist.locations); const rawLocations = specialist.locations.map(loc => { return { ...loc, name: specialist.nameString, } }); setLocations(rawLocations.map((location) => { const parsedDate = new Date(location.nearestDate); const now = new Date(); if (parsedDate > now) { return { ...location, checkedDate: true, key: `${location.dcode}${location.department}${location.filial}` } } return { ...location, checkedDate: false, key: `${location.dcode}${location.department}${location.filial}` } })); } updateField('lastName', specialist.fullName?.lastName); updateField('firstName', specialist.fullName?.firstName); updateField('middleName', specialist.fullName?.middleName); updateField('alias', specialist.alias); updateField('active', specialist.active); setAnons(specialist.anons); setContent(specialist.content); updateField('regionId', specialist.regionId); updateField('sType', specialist.sType); updateField('scheduleText', specialist.scheduleText); updateField('videoUrl', specialist.video); updateField('videoCardUrl', specialist.videoVertical); updateField('kodoper', specialist.kodoper); setKodopers(specialist.kodoper); updateField('onlyOnlineMode', Boolean(specialist.onlyOnlineMode)); updateField('prodoctor', specialist.prodoctor); updateField('degree', specialist.degree); updateField('prodoctorLink', specialist.prodoctorLink ?? ''); updateField('prodoctorText', specialist.prodoctorText ?? ''); setDisplayKodoper([...kodoperDetails]) if (specialist?.dcodes) setDcodes([...specialist.dcodes.split(',')]) if ( specialist.tags ) setTags([...specialist.tags]) if ( specialist.highlightedTags ) setHighlightedTags([...specialist.highlightedTags]) if ( specialist.stocks.length > 0 ) { setStocks([...specialist.stocks]); setStocksFromChild([...specialist.stocks]) updateField('initStocks', specialist.stocks); } updateField('category', formatCategory(specialist.category)); updateField('previewPicture', `https://api.sovamed.ru${specialist.pictureLink}`); const formattedDate = specialist.experience ? `${specialist.experience}-01-01` : ''; updateField('experience', formattedDate); updateField('hideSchedule', !specialist.displaySchedule); updateField('patientAge', specialist.patientAge); updateField('isChildrenDoctor', specialist.sType === 1 ? true : false); if (specialist.specialistDocs) { specialist.specialistDocs.forEach(doc => { if (doc.type === 'certificate') { setCertificates(prev => { if (prev.some(item => item.id === doc.id)) { return prev; } return [...prev, doc]; }); } if (doc.type === 'portfolio') { setPortfolio(prev => { if (prev.some(item => item.id === doc.id)) { return prev; } return [...prev, doc]; }); } }); } } }, [ specialist, kodoperDetails ] ); const [previewFile, setPreviewFile] = useState(null) 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('previewPicture', window.URL.createObjectURL(file)); setPreviewFile(file); } const handlePhotoOperationUpload = () => { const file = photoOperationInputRef.current.files[0] if (!file) return window.alert('Файл не выбран') updateField('operationPhotoUrl', { file, url: window.URL.createObjectURL(file) }); } const handleWrapper = () => { if (!isFormValid()) { window.alert('Пожалуйста, исправьте ошибки в форме'); return; } handleSave(); } const [certsFromChild, setCertsFromChild] = useState([]); const [portfolioFromChild, setPortfolioFromChild] = useState([]); const handleSave = async () => { if (!isFormValid()) { window.alert('Пожалуйста, исправьте ошибки в форме'); return; } const arr = []; dcodes.map(dcode => { if (arr.includes(String(dcode))) return arr.push(String(dcode)) }) locations.map(location => { if (arr.includes(String(location.dcode))) return arr.push(String(location.dcode)) }) const data = { nameString: `${form.lastName} ${form.firstName} ${form.middleName}`, fullName: { lastName: form.firstName, firstName: form.lastName, middleName: form.middleName }, active: form.active ?? false, displaySchedule: !form.hideSchedule, alias: form.alias ?? '', degree: form.degree ?? '', post: postTags.join(', ') ?? '', experience: getYear(form.experience) ?? '', sType: Number(form.sType), regionId: Number(form.regionId), anons: anons ?? '', content: content ?? '', tags: tags ?? [], highlightedTags: highlightedTags ?? [], video: form.videoUrl ?? '', videoVertical: form.videoCardUrl ?? '', scheduleText: form.scheduleText ?? '', dcodes: arr.map((dcode) => String(dcode).trim()).join(',') ?? '',// dcodes.map((dcode) => dcode.trim()).join(','), category: form.category === 'Не указано' ? '' : form.category, kodoper: kodopers ?? [], patientAge: form.isChildrenDoctor ? (!isNaN(Number(form.patientAge)) ? Number(form.patientAge) : null) : null, onlyOnlineMode: form.onlyOnlineMode ?? false, prodoctor: form.prodoctor, prodoctorLink: form.prodoctor ? (form.prodoctorLink.length > 0 ? form.prodoctorLink : '') : '', prodoctorText: form.prodoctor ? (form.prodoctorText.length > 0 ? form.prodoctorText : '') : '', }; const formattedLocations = locations.map(location => ({ active: location?.active ? location.active : false, dcode: location.dcode, department: location.department, filial: location.filial, id: location?.id, onlineMode: location.onlineMode, nearestDate: location.nearestDate, })); function isEqualExceptId(a, b) { for (const key in a) { if (key === 'id') continue; if (a[key] !== b[key]) return false; } for (const key in b) { if (key === 'id') continue; if (a[key] !== b[key]) return false; } return true; } function diffArrays(initial, current) { const currentMap = new Map(current.map(item => [item.id, item])); const initialMap = new Map(initial.map(item => [item.id, item])); const deletedLocations = []; const changedLocations = []; const addedLocations = []; for (const item of initial) { const curr = currentMap.get(item.id); if (!curr) { deletedLocations.push(item); } else if (!isEqualExceptId(item, curr)) { changedLocations.push({ ...curr }); } } for (const item of current) { if (!initialMap.has(item.id)) { addedLocations.push(item); } } return { deletedLocations, changedLocations, addedLocations }; } const { deletedLocations, changedLocations, addedLocations } = diffArrays(initialLocations, formattedLocations); try { await updateSpecialist({ specialistId: id, data: data, }).unwrap(); console.log('success specialist update') for (let i = 0; i < deletedLocations.length; i += 1) { await deleteLocation(deletedLocations[i].id).unwrap() } console.log('success delete locations') for (let i = 0; i < addedLocations.length; i += 1) { const [day, month, year] = addedLocations[i].nearestDate.split('.'); const isoDate = `${year}-${month}-${day}`; await createLocation({ specialistId: id, data: { active: addedLocations[i].active, dcode: addedLocations[i].dcode, department: addedLocations[i].department, filial: addedLocations[i].filial, nearestDate: isoDate, onlineMode: addedLocations[i].onlineMode, } }).unwrap() } console.log('success create locations') for (let i = 0; i < changedLocations.length; i += 1) { await updateLocation({ specialistId: id, locationId: changedLocations[i].id, data: { active: changedLocations[i].active, }, }).unwrap() } console.log('success update locations') //-------------------------------------------------- const initMap = new Map([...certificates.map(c => [c.id, c]), ...portfolio.map(c => [c.id, c])]); const currMap = new Map([...certsFromChild.filter(c => c.id).map(c => [c.id, c]), ...portfolioFromChild.filter(c => c.id).map(c => [c.id, c])]); const created = [...certsFromChild.filter(c => c.id == null), ...portfolioFromChild.filter(c => c.id == null)]; const deleted = [...certificates.filter(c => !currMap.has(c.id)), ...portfolio.filter(c => !currMap.has(c.id))]; const modified = [ ...certsFromChild .filter(c => c.id != null && initMap.has(c.id)) .filter(c => { const orig = initMap.get(c.id); return ( c.name !== orig.name || c.description !== orig.description || c.picture !== orig.picture || c.active !== orig.active ); }), ...portfolioFromChild .filter(c => c.id != null && initMap.has(c.id)) .filter(c => { const orig = initMap.get(c.id); return ( c.name !== orig.name || c.description !== orig.description || c.picture !== orig.picture || c.active !== orig.active ); }) ]; for (let i = 0; i < created.length; i += 1) { if (created[i].name.trim().length === 0 && created[i].description.trim().length === 0) continue const response = await createCertifcate({ specialistId: id, data: { name: created[i].name, description: String(created[i].description), active: created[i].active, type: created[i].type, }, }).unwrap() if (created[i].picture) await uploadCertifcatePicture({ id: response.id, file: created[i]._file, }).unwrap() } console.log('success create cert') for (let i = 0; i < modified.length; i += 1) { if (modified[i].name.trim().length === 0 && modified[i].description.trim().length === 0) continue await updateCertifcate({ specialistId: id, id: modified[i].id, data: { active: modified[i].active, description: modified[i].description, name: modified[i].name, type: modified[i].type, }, }).unwrap() if (modified[i]?._file) { await uploadCertifcatePicture({ id: modified[i].id, file: modified[i]._file, }).unwrap() } } console.log('success update cert') for (let i = 0; i < deleted.length; i += 1) { await deleteCertifcate({ id: deleted[i].id, }).unwrap() } console.log('success delete cert') if (previewFile) { await uploadPicture({ id, file: previewFile }).unwrap(); console.log('success photo update') } const initIds = new Set(form.initStocks.map(s => s.id)); const childIds = new Set(stocksFromChild.map(s => s.id)); const deletedStocs = form.initStocks.filter(s => !childIds.has(s.id)); const addedStocks = stocksFromChild.filter(s => !initIds.has(s.id)); for (let i = 0; i < addedStocks.length; i += 1) { await addSpecialistToStock({ stockId: addedStocks[i].id, specialistId: id, }).unwrap() } console.log('success added promotions') for (let i = 0; i < deletedStocs.length; i += 1) { await removeSpecialistToStock({ stockId: deletedStocs[i].id, specialistId: id, }).unwrap() } console.log('success delete promotions') setModalSuccess(true) window.setTimeout(() => { window.location.reload() }, 2000); } catch (err) { console.error('Ошибка при обновлении специалиста:', err) } } const handleDelete = async () => { try { await deleteSpecialist(id).unwrap() console.log('success delete') setModalSuccess(true) window.setTimeout(() => { navigateBack() }, 2000); } catch (err) { console.error('Ошибка при удалении специалиста:', err) } } /* useEffect(() => { if (patientAgeInputRef.current) { patientAgeInputRef.current.focus(); } }, [ form.isChildrenDoctor ]); */ const [isModalCustomOpen, setModalCustomOpen] = useState(false); const [isModalDeleteOpen, setModalDeleteOpen] = useState(false); const [isModalSuccess, setModalSuccess] = useState(false); const [isModalDcodes, setModalDcodes] = useState(false); if ( isLoading ) return if ( error ) return if ( !specialist ) return return ( setModalDeleteOpen(true) } // addSpecialist={ navigateAddSpecialist } >
Личный кабинет врача
Фото врача e.currentTarget.src = PHOTO_PLACEHOLDER ?? '/assets/photo-placeholder.png' } />
updateField('lastName', e.target.value) } onBlur={handleBlur} /> {errors.lastName && {errors.lastName}}
updateField('firstName', e.target.value) } onBlur={handleBlur} /> {errors.firstName && {errors.firstName}}
updateField('middleName', e.target.value) } pattern="[А-ЯЁ][а-яё]+" title="Только буквы кириллицы, первая буква заглавная" onBlur={handleBlur} /> {errors.middleName && {errors.middleName}}
updateField('alias', e.target.value) } />
{form.isChildrenDoctor &&
{ if (patientAgeInputRef.current) patientAgeInputRef.current.focus() }} style={{ backgroundColor: 'white', borderTopRightRadius: 0, borderBottomRightRadius: 0, borderRight: 'none', height: 'calc(1.5em + .75rem + 2px)' }} >Прием детей с { updateField('patientAge', e.target.value) validateField('patientAge', form.patientAge); }} onBlur={handleBlur} /> { if (patientAgeInputRef.current) patientAgeInputRef.current.focus() }} style={{ backgroundColor: 'white', borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeft: 'none', height: 'calc(1.5em + .75rem + 2px)' }} >лет
{errors.patientAge && {errors.patientAge}}
}
updateField('degree', e.target.value) } />
{/*
{ if (dateInputRef.current?.showPicker) { dateInputRef.current.showPicker(); } }} onChange={e => { updateField('experience', e.target.value) }} />
*/}
{ updateField('experience', e); validateField('experience', e); }} className="form-control" calendarClassName="react-datepicker-bootstrap" popperClassName="react-datepicker-popper" showYearPicker dateFormat="yyyy" yearItemNumber={10} />
{errors.experience && {errors.experience}}
updateField('active', e.target.checked)} />
updateField('scheduleText', e.target.value)} />
updateField('hideSchedule', e.target.checked)} />
updateField('onlyOnlineMode', e.target.checked)} />
Расписание из Инфоклиники
{locations.length > 0 &&
{/*
Филиалы:
*/ }
{locations.map((location, index) => { return ( ) } )}
dcode Филиал Отделение Ближайшая дата приема Онлайн прием Отображать на сайте
{ location.dcode } { filialsList.find(filial => filial.id === location.filial)?.shortName } { departmentsList.find(department => Number(department.id) === Number(location.department))?.name } { location.nearestDate ? location.nearestDate : '' } { location.onlineMode ? 'да' : 'нет' } { const checked = e.target.checked; setLocations(prev => prev.map(l => l.key === location.key ? { ...l, active: checked } : l )); } //updateField('active', e.target.checked) } />
}
Услуги врача
{Boolean(kodopers) && kodopers.length > 0 && } {displayKodoper.length > 0 &&
Добавленные услуги:
{ displayKodoper.map((item, index) => )}
Мед. код Услуга Отделение Филиал Стоимость
{ item.kodoper } { item.schname } { item.specname } { item.fname } { `${item.priceInfo.price} ₽` }
}
Акции
{ stocksFromChild.length > 0 &&
{ stocksFromChild.map((stock, index) => ) }
Название Начало акции Окончание акции
{ stock.name } { formatStockDate(stock.startDate) } { formatStockDate(stock.endDate) }
}
{ /* updateField('anons', e.target.value)} /> */ }
{ /* updateField('content', e.target.value)} /> */ }
{ }
{ }
updateField('videoUrl', e.target.value) } onBlur={handleBlur} /> {errors.videoUrl && {errors.videoUrl}}
updateField('videoCardUrl', e.target.value) } onBlur={handleBlur} /> {errors.videoCardUrl && {errors.videoCardUrl}}
{ updateField('prodoctor', e.target.checked) if (!e.target.checked) { updateField('prodoctorText', '') updateField('prodoctorLink', '') setErrors(prev => ({ ...prev, prodoctorLink: '' })); } }} />
{ form.prodoctor && <>
updateField('prodoctorText', e.target.value)} />
{ updateField('prodoctorLink', e.target.value) validateField('prodoctorLink', form.prodoctorLink) }} onBlur={handleBlur} /> {errors.prodoctorLink && {errors.prodoctorLink}}
}
setModalDeleteOpen(false)} onConfirm={() => { setModalDeleteOpen(false) handleDelete() }} title="Вы уверены?" hasButtons={true} confirmText={'Удалить врача'} >

Этим действием, вы удалите врача.

Вы уверены?

Изменения успешно внесены.

setModalDcodes(false)} departments={departmentsList} filials={filialsList} /> { setKodopers(selectedCodopers) setDisplayKodoper(displayedCodopers) }} onCancel={() => setModalKodopers(false)} /> { setStocks(selectedStocks) }} onCancel={() => setModalStocks(false)} />
); }