From b3883a6e90cafb2fcd5f40b7a0edc17ee7d54867 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Fri, 19 Jun 2026 01:03:45 +0330 Subject: [PATCH] feat(clinic): add image deletion functionality with confirmation dialog --- assets/admin/pages/BlogFormPage.tsx | 6 +++-- assets/admin/pages/ClinicDetailPage.tsx | 36 ++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/assets/admin/pages/BlogFormPage.tsx b/assets/admin/pages/BlogFormPage.tsx index 19c85b14..b6d6a296 100644 --- a/assets/admin/pages/BlogFormPage.tsx +++ b/assets/admin/pages/BlogFormPage.tsx @@ -52,11 +52,12 @@ export default function BlogFormPage() { const { data, isLoading } = useQuery({ queryKey: ['blog', uuid], - queryFn: () => api.get>(`/api/v1/blog/${uuid}`), + queryFn: () => api.get>(`/api/v1/blog/${uuid}`), enabled: isEdit, }); - const blog = data?.data; + // detail endpoint is double-nested: success(['data' => $blog->toArray()]) + const blog = data?.data?.data; const { register, handleSubmit, control, watch, setValue, formState: { errors, isSubmitting } } = useForm({ resolver: zodResolver(schema), @@ -178,6 +179,7 @@ export default function BlogFormPage() { field.onChange(editor.getData()) } config={{ + licenseKey: 'GPL', language: 'fa', toolbar: [ 'heading', '|', diff --git a/assets/admin/pages/ClinicDetailPage.tsx b/assets/admin/pages/ClinicDetailPage.tsx index b2c6fb7a..2295551b 100644 --- a/assets/admin/pages/ClinicDetailPage.tsx +++ b/assets/admin/pages/ClinicDetailPage.tsx @@ -479,6 +479,7 @@ export default function ClinicDetailPage() { const [addrFormOpen, setAddrFormOpen] = useState(false); const [editingClinicAddr, setEditingClinicAddr] = useState(null); const [deleteAddrConfirm, setDeleteAddrConfirm] = useState(null); + const [deleteImageConfirm, setDeleteImageConfirm] = useState(null); const emptyAddrForm = { name: '', address: '', telephone: '', province_id: null as number | null, city_id: null as number | null, latitude: null as number | null, longitude: null as number | null }; const [addrForm, setAddrForm] = useState(emptyAddrForm); @@ -636,6 +637,16 @@ export default function ClinicDetailPage() { finally { setGalleryUploading(false); } }; + const handleGalleryRemove = async (url: string) => { + if (!clinic) return; + try { + const remaining = (clinic.images_clinic ?? []).filter(img => img?.url && img.url !== url); + await api.patch(`/api/v1/clinic/${uuid}`, { image_clinic: remaining }); + toast.success('تصویر حذف شد'); + qc.invalidateQueries({ queryKey: ['clinic-detail', uuid] }); + } catch (e: any) { toast.error(e?.message ?? 'خطا در حذف تصویر'); } + }; + const hue = HUES_LIST[(uuid?.charCodeAt(0) ?? 0) % HUES_LIST.length]; const logo = clinic?.logo ?? clinic?.clinic_logo; // شهر و استان از آدرس DoctorAddress (منبع واقعی) نه از Clinic entity @@ -915,8 +926,17 @@ export default function ClinicDetailPage() { ) : (
{clinic.images_clinic.filter(img => img?.url).map((img, i) => ( -
+
+
))}
@@ -1161,6 +1181,20 @@ export default function ClinicDetailPage() { onCancel={() => setDeleteAddrConfirm(null)} /> + {/* Delete Gallery Image Confirm */} + { + if (deleteImageConfirm) handleGalleryRemove(deleteImageConfirm); + setDeleteImageConfirm(null); + }} + onCancel={() => setDeleteImageConfirm(null)} + /> + {/* Edit modal — portal to escape Leaflet transform context */} {editOpen && createPortal(