import { useState, useEffect } from 'react' import { useNavigate, useParams } from 'react-router-dom' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { api } from '../../../api/client' import ImagePicker from './components/ImagePicker' import ConfirmDialog from '../../../components/common/ConfirmDialog' import FormField, { formInputClass, formInputStyle } from '../../../components/common/FormField' export default function AdminMenuForm() { const navigate = useNavigate() const queryClient = useQueryClient() const { id } = useParams() const isEdit = !!id const [pickerOpen, setPickerOpen] = useState(false) const [confirmDelete, setConfirmDelete] = useState(false) const [form, setForm] = useState({ title: '', description: '', slug: '', image_id: null, image: null, }) const [errors, setErrors] = useState({}) const { data: menuData } = useQuery({ queryKey: ['admin', 'menus', id], queryFn: () => api(`/api/admin/menus/${id}`), enabled: isEdit, }) useEffect(() => { if (!isEdit) { setForm({ title: '', description: '', slug: '', image_id: null, image: null }) return } if (menuData) { setForm({ title: menuData.title || '', description: menuData.description || '', slug: (menuData.url || '').replace(/^\/+/, ''), image_id: menuData.image_id, image: menuData.image, }) } }, [isEdit, id, menuData]) const update = (patch) => setForm((prev) => ({ ...prev, ...patch })) const handleSlugChange = (value) => { update({ slug: value.replace(/^\/+/, '') }) } const fullUrl = `/${form.slug.trim()}` const validate = () => { const errs = {} if (!form.title.trim()) errs.title = '제목을 입력해주세요' if (!form.slug.trim()) errs.slug = '경로를 입력해주세요' else if (!/^[a-zA-Z0-9\-/]+$/.test(form.slug.trim())) errs.slug = '영문, 숫자, 하이픈(-), 슬래시(/)만 사용할 수 있습니다' setErrors(errs) return Object.keys(errs).length === 0 } const saveMutation = useMutation({ mutationFn: async () => { const payload = { title: form.title.trim(), description: form.description.trim(), url: fullUrl, image_id: form.image_id, } if (isEdit) { return api(`/api/admin/menus/${id}`, { method: 'PATCH', body: payload }) } return api('/api/admin/menus', { method: 'POST', body: payload }) }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['admin', 'menus'] }) queryClient.invalidateQueries({ queryKey: ['menus'] }) navigate('/admin') }, onError: (err) => alert(err.message), }) const handleSubmit = (e) => { e.preventDefault() if (!validate()) return saveMutation.mutate() } const deleteMutation = useMutation({ mutationFn: () => api(`/api/admin/menus/${id}`, { method: 'DELETE' }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['admin', 'menus'] }) queryClient.invalidateQueries({ queryKey: ['menus'] }) navigate('/admin') }, onError: (err) => alert(err.message), }) return (
홈 화면에 표시되는 카드의 정보를 설정합니다