"use client"; import React, { useEffect, useState } from "react"; import { AdminHeader, AlertBanner, Modal, ConfirmDeleteModal, getClientToken } from "../_components/AdminComponents"; import { adminGetMembers, adminCreateMember, adminUpdateMember, adminDeleteMember, adminGetAlumni, adminCreateAlumnus, adminUpdateAlumnus, adminDeleteAlumnus, AdminMember, AdminAlumnus, } from "../../../lib/adminApi"; const MEMBER_DEGREES = [ "Professor", "PhD", "PhDCandidate", "PhDStudent", "MSCandidate", "MSStudent", ]; const ALUMNI_DEGREES = ["PhD", "MS"]; export default function AdminMembersPage() { const [tab, setTab] = useState<"active" | "alumni">("active"); const [members, setMembers] = useState([]); const [alumni, setAlumni] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [successMsg, setSuccessMsg] = useState(null); // Active Member Modal State const [isMemberModalOpen, setIsMemberModalOpen] = useState(false); const [editingMember, setEditingMember] = useState(null); const [memberForm, setMemberForm] = useState({ name_ko: "", name_en: "", degree: "PhDStudent", affiliation: "", email: "", is_advisor: false, display_order: 0, }); // Alumni Modal State const [isAlumniModalOpen, setIsAlumniModalOpen] = useState(false); const [editingAlumnus, setEditingAlumnus] = useState(null); const [alumniForm, setAlumniForm] = useState({ name_ko: "", name_en: "", degree: "MS", graduated_at: "", major: "", current_position: "", }); const [isSubmitting, setIsSubmitting] = useState(false); const [deletingMemberId, setDeletingMemberId] = useState(null); const [deletingAlumniId, setDeletingAlumniId] = useState(null); const loadData = async () => { try { setIsLoading(true); setError(null); const [mList, aList] = await Promise.all([adminGetMembers(), adminGetAlumni()]); setMembers(mList); setAlumni(aList); } catch (err: any) { setError(err?.message || "Failed to load members data."); } finally { setIsLoading(false); } }; useEffect(() => { loadData(); }, []); // Member Handlers const handleOpenMemberCreate = () => { setEditingMember(null); setMemberForm({ name_ko: "", name_en: "", degree: "PhDStudent", affiliation: "", email: "", is_advisor: false, display_order: members.length + 1, }); setIsMemberModalOpen(true); }; const handleOpenMemberEdit = (m: AdminMember) => { setEditingMember(m); setMemberForm({ name_ko: m.name_ko, name_en: m.name_en, degree: m.degree, affiliation: m.affiliation || "", email: m.email || "", is_advisor: m.is_advisor, display_order: m.display_order, }); setIsMemberModalOpen(true); }; const handleMemberSubmit = async (e: React.FormEvent) => { e.preventDefault(); const token = getClientToken(); if (!token) { setError("Unauthorized. Please log in."); return; } const payload = { name_ko: memberForm.name_ko.trim(), name_en: memberForm.name_en.trim(), degree: memberForm.degree, affiliation: memberForm.affiliation.trim() || undefined, email: memberForm.email.trim() || undefined, is_advisor: memberForm.is_advisor, display_order: Number(memberForm.display_order) || 0, }; setIsSubmitting(true); setError(null); try { if (editingMember) { await adminUpdateMember(token, editingMember.id, payload); setSuccessMsg(`Member "${payload.name_ko}" updated successfully.`); } else { await adminCreateMember(token, payload); setSuccessMsg(`Member "${payload.name_ko}" created successfully.`); } setIsMemberModalOpen(false); await loadData(); } catch (err: any) { setError(err?.message || "Failed to save member."); } finally { setIsSubmitting(false); } }; const handleConfirmDeleteMember = async () => { if (!deletingMemberId) return; const token = getClientToken(); if (!token) return; setIsSubmitting(true); try { await adminDeleteMember(token, deletingMemberId); setSuccessMsg("Member deleted successfully."); setDeletingMemberId(null); await loadData(); } catch (err: any) { setError(err?.message || "Failed to delete member."); } finally { setIsSubmitting(false); } }; // Alumni Handlers const handleOpenAlumniCreate = () => { setEditingAlumnus(null); setAlumniForm({ name_ko: "", name_en: "", degree: "MS", graduated_at: "", major: "", current_position: "", }); setIsAlumniModalOpen(true); }; const handleOpenAlumniEdit = (a: AdminAlumnus) => { setEditingAlumnus(a); setAlumniForm({ name_ko: a.name_ko, name_en: a.name_en, degree: a.degree, graduated_at: a.graduated_at, major: a.major || "", current_position: a.current_position || "", }); setIsAlumniModalOpen(true); }; const handleAlumniSubmit = async (e: React.FormEvent) => { e.preventDefault(); const token = getClientToken(); if (!token) return; const payload = { name_ko: alumniForm.name_ko.trim(), name_en: alumniForm.name_en.trim(), degree: alumniForm.degree, graduated_at: alumniForm.graduated_at.trim(), major: alumniForm.major.trim() || undefined, current_position: alumniForm.current_position.trim() || undefined, }; setIsSubmitting(true); setError(null); try { if (editingAlumnus) { await adminUpdateAlumnus(token, editingAlumnus.id, payload); setSuccessMsg(`Alumnus "${payload.name_ko}" updated successfully.`); } else { await adminCreateAlumnus(token, payload); setSuccessMsg(`Alumnus "${payload.name_ko}" created successfully.`); } setIsAlumniModalOpen(false); await loadData(); } catch (err: any) { setError(err?.message || "Failed to save alumnus."); } finally { setIsSubmitting(false); } }; const handleConfirmDeleteAlumnus = async () => { if (!deletingAlumniId) return; const token = getClientToken(); if (!token) return; setIsSubmitting(true); try { await adminDeleteAlumnus(token, deletingAlumniId); setSuccessMsg("Alumnus deleted successfully."); setDeletingAlumniId(null); await loadData(); } catch (err: any) { setError(err?.message || "Failed to delete alumnus."); } finally { setIsSubmitting(false); } }; return (
{tab === "active" ? "+ Add Active Member" : "+ Add Alumnus"} } /> {/* Tabs */}
{error && setError(null)} />} {successMsg && setSuccessMsg(null)} />} {isLoading ? (
Loading records...
) : tab === "active" ? ( /* Active Members Table */
{members.length === 0 ? ( ) : ( members.map((m) => ( )) )}
Order Name (Ko / En) Degree Affiliation / Email Actions
No active members found.
{m.display_order}
{m.name_ko} ({m.name_en}) {m.is_advisor && ( Advisor )}
{m.degree}
{m.affiliation || "—"}
{m.email || "—"}
) : ( /* Alumni Table */
{alumni.length === 0 ? ( ) : ( alumni.map((a) => ( )) )}
Graduation Date Name (Ko / En) Degree Major / Current Position Actions
No alumni found.
{a.graduated_at} {a.name_ko} ({a.name_en}) {a.degree}
{a.current_position || "—"}
{a.major || "—"}
)} {/* Member Modal */} setIsMemberModalOpen(false)} >
setMemberForm({ ...memberForm, name_ko: e.target.value })} placeholder="e.g. 홍길동" required className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setMemberForm({ ...memberForm, name_en: e.target.value })} placeholder="e.g. Gildong Hong" required className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setMemberForm({ ...memberForm, display_order: Number(e.target.value) })} className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setMemberForm({ ...memberForm, affiliation: e.target.value })} placeholder="e.g. School of Electronic Engineering" className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setMemberForm({ ...memberForm, email: e.target.value })} placeholder="e.g. user@knu.ac.kr" className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setMemberForm({ ...memberForm, is_advisor: e.target.checked })} className="rounded text-cobalt focus:ring-cobalt" />
{/* Alumni Modal */} setIsAlumniModalOpen(false)} >
setAlumniForm({ ...alumniForm, name_ko: e.target.value })} placeholder="e.g. 홍길동" required className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setAlumniForm({ ...alumniForm, name_en: e.target.value })} placeholder="e.g. Gildong Hong" required className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setAlumniForm({ ...alumniForm, graduated_at: e.target.value })} placeholder="e.g. 2024-02" required className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setAlumniForm({ ...alumniForm, current_position: e.target.value })} placeholder="e.g. Samsung Electronics, Principal Engineer" className="w-full px-3 py-2 text-sm border border-line rounded bg-ivory text-ink focus:outline-none focus:ring-1 focus:ring-cobalt" />
setDeletingMemberId(null)} onConfirm={handleConfirmDeleteMember} isSubmitting={isSubmitting} title="Delete Member" description="Are you sure you want to delete this member?" /> setDeletingAlumniId(null)} onConfirm={handleConfirmDeleteAlumnus} isSubmitting={isSubmitting} title="Delete Alumnus" description="Are you sure you want to delete this alumnus?" />
); }