import { useState, useEffect } from 'react'; import { useNavigate, useParams, Link } from 'react-router-dom'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { motion } from 'framer-motion'; import { Save, Upload, X, Home, ChevronRight, User, Instagram, Calendar, Tag } from 'lucide-react'; import Toast from '../../../components/Toast'; import CustomDatePicker from '../../../components/admin/CustomDatePicker'; import AdminLayout from '../../../components/admin/AdminLayout'; import useAdminAuth from '../../../hooks/useAdminAuth'; import useToast from '../../../hooks/useToast'; import { fetchAdminApi, fetchAdminFormData } from '../../../api'; function AdminMemberEdit() { const navigate = useNavigate(); const queryClient = useQueryClient(); const { name } = useParams(); const { user, isAuthenticated } = useAdminAuth(); const { toast, setToast } = useToast(); const [saving, setSaving] = useState(false); const [imagePreview, setImagePreview] = useState(null); const [imageFile, setImageFile] = useState(null); const [nicknameInput, setNicknameInput] = useState(''); const [formData, setFormData] = useState({ name: '', name_en: '', birth_date: '', instagram: '', is_former: false, nicknames: [] }); // 멤버 상세 조회 const { data: memberData, isLoading: loading, isError } = useQuery({ queryKey: ['admin', 'member', name], queryFn: () => fetchAdminApi(`/api/members/${encodeURIComponent(name)}`), enabled: isAuthenticated, }); // 데이터 로드 시 폼에 반영 useEffect(() => { if (memberData) { const birthDate = memberData.birth_date ? memberData.birth_date.split('T')[0] : ''; setFormData({ name: memberData.name || '', name_en: memberData.name_en || '', birth_date: birthDate, instagram: memberData.instagram || '', is_former: !!memberData.is_former, nicknames: memberData.nicknames || [] }); setImagePreview(memberData.image_url); } }, [memberData]); // 에러 처리 useEffect(() => { if (isError) { setToast({ message: '멤버 정보를 불러오는데 실패했습니다.', type: 'error' }); } }, [isError, setToast]); const handleImageChange = (e) => { const file = e.target.files[0]; if (file) { setImageFile(file); const reader = new FileReader(); reader.onloadend = () => setImagePreview(reader.result); reader.readAsDataURL(file); } }; // 별명 추가 const handleAddNickname = () => { const trimmed = nicknameInput.trim(); if (trimmed && !formData.nicknames.includes(trimmed)) { setFormData({ ...formData, nicknames: [...formData.nicknames, trimmed] }); setNicknameInput(''); } }; // 별명 삭제 const handleRemoveNickname = (nickname) => { setFormData({ ...formData, nicknames: formData.nicknames.filter(n => n !== nickname) }); }; // Enter 키로 별명 추가 const handleNicknameKeyDown = (e) => { if (e.key === 'Enter') { e.preventDefault(); handleAddNickname(); } }; const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); try { const form = new FormData(); form.append('name', formData.name); form.append('name_en', formData.name_en); form.append('birth_date', formData.birth_date); form.append('instagram', formData.instagram); form.append('is_former', formData.is_former ? '1' : '0'); form.append('nicknames', JSON.stringify(formData.nicknames)); if (imageFile) { form.append('image', imageFile); } await fetchAdminFormData(`/api/members/${encodeURIComponent(name)}`, form, 'PUT'); // 목록 캐시 무효화 (목록 페이지에서 최신 데이터 표시) queryClient.invalidateQueries({ queryKey: ['admin', 'members'] }); // 목록 페이지로 이동하면서 토스트 메시지 전달 navigate('/admin/members', { state: { toast: { message: '멤버 정보가 수정되었습니다.', type: 'success' } } }); } catch (err) { setToast({ message: err.message || '멤버 수정에 실패했습니다.', type: 'error' }); } finally { setSaving(false); } }; return ( {/* Toast */} setToast(null)} /> {/* 메인 콘텐츠 */}
{/* 브레드크럼 */}
멤버 관리 멤버 수정
{/* 타이틀 */}

멤버 수정

멤버 정보를 수정합니다

{loading ? (
) : (
{/* 이미지 업로드 영역 */}
document.getElementById('imageInput').click()} > {imagePreview ? ( <> 프로필 미리보기
변경
) : (
클릭하여 업로드
)}
{/* 입력 폼 영역 */}
{/* 이름 */}
setFormData({ ...formData, name: e.target.value })} required className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="멤버 이름" />
setFormData({ ...formData, name_en: e.target.value })} className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="ENGLISH NAME" />
{/* 생년월일 */}
setFormData({ ...formData, birth_date: date })} />
{/* 인스타그램 */}
setFormData({ ...formData, instagram: e.target.value })} className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="https://www.instagram.com/username" />
{/* 별명 */}
{/* 별명 입력 */} setNicknameInput(e.target.value)} onKeyDown={handleNicknameKeyDown} className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="별명을 입력하고 Enter" /> {/* 별명 태그 목록 */} {formData.nicknames.length > 0 && (
{formData.nicknames.map((nickname, index) => ( {nickname} ))}
)}

별명은 일정 검색 시 사용됩니다

{/* 활동 상태 */}
{/* 버튼 영역 */}
)}
); } export default AdminMemberEdit;