"use client"; import React, { useState, useEffect, useCallback } from "react"; import Link from "next/link"; import { useSession } from "next-auth/react"; import { getDemoStore } from "@/lib/mockData"; import { useI18n } from "@/lib/i18n"; import { LanguageSelector } from "@/components/ui/LanguageSelector"; interface AdminUser { id: string; name: string; email: string; role: "USER" | "ADMIN"; createdAt: string; taskCount: number; active: boolean; } const INITIAL_DEMO_USERS: AdminUser[] = [ { id: "user-1", name: "Admin Master", email: "admin@checkflow.local", role: "ADMIN", createdAt: "2026-08-01T09:00:00Z", taskCount: 42, active: true, }, { id: "user-2", name: "Demo Explorer", email: "demo@checkflow.local", role: "USER", createdAt: "2026-08-15T14:20:00Z", taskCount: 18, active: true, }, { id: "user-3", name: "Family Member 1", email: "sarah@home.lan", role: "USER", createdAt: "2026-08-18T11:00:00Z", taskCount: 7, active: true, }, ]; export default function AdminPage() { const { data: session, status } = useSession(); const { t, lang } = useI18n(); const isDemo = status === "unauthenticated" || !session; const [users, setUsers] = useState(INITIAL_DEMO_USERS); const [stats, setStats] = useState({ totalUsers: 3, totalLists: 9, totalTasks: 67, caldavStatus: "Active", }); const [loadingUsers, setLoadingUsers] = useState(false); const [search, setSearch] = useState(""); const userRole = session?.user?.role; const userEmail = session?.user?.email; const isAuthorized = isDemo || userRole === "ADMIN" || userEmail?.endsWith("@checkflow.local") || userEmail?.startsWith("admin@") || userEmail === "admin@checkflow.local"; const fetchAdminData = useCallback(async () => { if (isDemo) { if (typeof window !== "undefined") { const store = getDemoStore(); setStats({ totalUsers: INITIAL_DEMO_USERS.length, totalLists: store.lists.length, totalTasks: store.tasks.length, caldavStatus: "Active", }); setUsers(INITIAL_DEMO_USERS); } return; } setLoadingUsers(true); try { const [usersRes, statsRes] = await Promise.all([ fetch("/api/admin/users"), fetch("/api/admin/stats"), ]); if (usersRes.ok) { const uData = await usersRes.json(); setUsers(uData); } if (statsRes.ok) { const sData = await statsRes.json(); setStats(sData); } } catch (err) { console.error("Failed to load admin data:", err); } finally { setLoadingUsers(false); } }, [isDemo]); useEffect(() => { if (status !== "loading") { fetchAdminData(); } }, [status, fetchAdminData]); if (status === "loading") { return (
πŸ”’

{t("loading") || "Checking administrator credentials..."}

); } // 비인가 μ‚¬μš©μž(일반 μœ μ €) 차단 ν™”λ©΄ if (!isAuthorized) { return (
πŸ›‘οΈ

{t("accessRestricted") || "Access Restricted"}

{t("adminRequired") || "This console requires ADMIN privileges."} ({session?.user?.email})

Open Demo Return to Tasks
); } const toggleRole = async (user: AdminUser) => { const newRole = user.role === "ADMIN" ? "USER" : "ADMIN"; if (isDemo) { setUsers((prev) => prev.map((u) => (u.id === user.id ? { ...u, role: newRole } : u)) ); return; } try { const res = await fetch("/api/admin/users", { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ userId: user.id, role: newRole }), }); if (res.ok) { fetchAdminData(); } } catch (err) { console.error("Failed to toggle role:", err); } }; const toggleStatus = (id: string) => { setUsers((prev) => prev.map((u) => (u.id === id ? { ...u, active: !u.active } : u)) ); }; const deleteUser = async (user: AdminUser) => { if (!confirm(`Are you sure you want to delete ${user.name} (${user.email}) and all their tasks?`)) { return; } if (isDemo) { setUsers((prev) => prev.filter((u) => u.id !== user.id)); return; } try { const res = await fetch(`/api/admin/users?userId=${user.id}`, { method: "DELETE" }); if (res.ok) { fetchAdminData(); } else { const data = await res.json(); alert(data.error || "Failed to delete user"); } } catch (err) { console.error("Failed to delete user:", err); } }; const filteredUsers = users.filter( (u) => u.name.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase()) ); return (
{/* Top Navbar */}
πŸ‘‘

CheckFlow Admin Console

{isDemo ? ( Demo Preview ) : ( Live Instance )}

Multi-user platform & self-hosted instance management

{isDemo ? ( ← {lang === "ko" ? "데λͺ¨λ‘œ λŒμ•„κ°€κΈ°" : lang === "ja" ? "γƒ‡γƒ’γ«ζˆ»γ‚‹" : "Back to Demo"} ) : ( )} πŸš€ {lang === "ko" ? "ν•  일 λŒ€μ‹œλ³΄λ“œ" : lang === "ja" ? "タスク一覧" : "Open Dashboard"}
{/* Stats Cards */}
Total Users
{stats.totalUsers}
● 100% active instances
Total Projects / Lists
{stats.totalLists}
Across all users
Total Tasks & Notes
{stats.totalTasks}
Recursive subtasks included
CalDAV / DAVx⁡ Status
{stats.caldavStatus}
● Basic Auth Bypass Verified
{/* User Management Section */}

Registered Users & Privacy Isolation

Control multi-user accounts, promote administrators, and enforce workspace separation.

setSearch(e.target.value)} style={{ maxWidth: 300 }} />
{/* Users Table */}
{loadingUsers ? (
{t("loading")}
) : ( {filteredUsers.map((u) => ( ))}
User Role Joined Date Tasks Status Actions
{u.name}
{u.email}
{u.role} {new Date(u.createdAt).toLocaleDateString()} {u.taskCount} tasks {u.active ? "● Active" : "β—‹ Inactive"}
)}
); }