"use client"; import { useEffect,useRef, useState } from "react"; import { UserPlus, X, Users as UsersIcon } from "lucide-react"; import { api } from "@/lib/api"; import { useLanguage } from "@/contexts/LanguageContext"; const ROLES = [ { role: "admin", label: "Admin", desc: "Full access: products, QRs, batches, compliance, users, billing." }, { role: "finance", label: "Finance", desc: "Billing, invoices, payment methods, subscription only." }, { role: "user", label: "User", desc: "Create products, generate QRs, manage batches, view analytics." }, ]; const ROLE_BADGE: Record = { admin: "bg-red-100 text-red-700 border border-red-200", finance: "bg-violet-100 text-violet-700 border border-violet-200", user: "bg-blue-100 text-blue-700 border border-blue-200", manager: "bg-green-100 text-green-700 border border-green-200", quality: "bg-orange-100 text-orange-700 border border-orange-200", production: "bg-cyan-100 text-cyan-700 border border-cyan-200", }; const STATUS_BADGE: Record = { active: "bg-emerald-50 text-emerald-700", pending: "bg-amber-50 text-amber-700", disabled: "bg-rose-50 text-rose-700", }; export default function UsersPanel() { const [tab, setTab] = useState<"users" | "roles">("users"); const [data, setData] = useState(null); const [org, setOrg] = useState(null); const [open, setOpen] = useState(false); const [invite, setInvite] = useState({ email: "", role: "user", department: "",password: "",name: "", }); const [err, setErr] = useState(""); const { t } = useLanguage(); const [openMenu, setOpenMenu] = useState(null); const [editingUser, setEditingUser] = useState(null); const menuRef = useRef(null); const [search, setSearch] = useState(""); const [filters, setFilters] = useState({ role: "", status: "", department: "", joinedFrom: "", joinedTo: "", }); const [detailTab, setDetailTab] = useState< "profile" | "permissions" | "activity" >("profile"); const [activityLogs, setActivityLogs] = useState([]); const [selectedUser, setSelectedUser] = useState(null); const filteredUsers = (data?.items ?? []).filter((m: any) => { const keyword = search.toLowerCase(); const matchesSearch = !search || m.name?.toLowerCase().includes(keyword) || m.email?.toLowerCase().includes(keyword); const matchesRole = !filters.role || m.role === filters.role; const matchesStatus = !filters.status || m.status === filters.status; const matchesDepartment = !filters.department || m.department === filters.department; const joined = m.joined_at ? new Date(m.joined_at) : null; const from = !filters.joinedFrom || (joined && joined >= new Date(filters.joinedFrom)); const to = !filters.joinedTo || (joined && joined <= new Date(filters.joinedTo + "T23:59:59")); return ( matchesSearch && matchesRole && matchesStatus && matchesDepartment && from && to ); }); const [showFilters, setShowFilters] = useState(false); const [selected, setSelected] = useState([]); function toggleSelectAll(checked: boolean) { if (checked) { setSelected((data?.items ?? []).map((m: any) => m.member_id)); } else { setSelected([]); } } const toggleSelect = (memberId: string, checked: boolean) => { if (checked) { setSelected((prev) => prev.includes(memberId) ? prev : [...prev, memberId] ); } else { setSelected((prev) => prev.filter((id) => id !== memberId)); } };async function updateUser() { try { await api(`/users/${editingUser.member_id}`, { method: "PUT", body: JSON.stringify({ role: invite.role, department: invite.department, }), }); setOpen(false); setEditingUser(null); setInvite({ email: "", role: "user", department: "", name: "",password: "", }); load(); } catch (e) { console.error(e); } } function load() { api("/users").then(setData).catch(() => setData({ items: [], kpis: {} })); api("/organization").then(setOrg).catch(() => {}); } useEffect(() => { load(); }, []); useEffect(() => { function handleClickOutside(event: MouseEvent) { if ( menuRef.current && !menuRef.current.contains(event.target as Node) ) { setOpenMenu(null); } } document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); async function sendInvite() { setErr(""); try { await api("/users/invite", { method: "POST", body: JSON.stringify(invite) }); setOpen(false); setInvite({ email: "", role: "user", department: "" ,password: "",name: "",}); load(); } catch (e: any) { setErr(typeof e.detail === "object" ? e.detail.message : e.detail || "Invite failed"); } } async function setRole(member_id: string, role: string) { await api(`/users/${member_id}`, { method: "PUT", body: JSON.stringify({ role }) }); load(); } async function setStatus(member_id: string, status: string) { await api(`/users/${member_id}`, { method: "PUT", body: JSON.stringify({ status }) }); load(); } const k = data?.kpis ?? {}; const roleSummary = data?.role_summary ?? {}; function Permission({ text }: { text: string }) { return (
{text}
); } return (

{t.users_management}

{(["users", "roles"] as const).map((t) => ( ))}
{tab === "users" ? (
setSearch(e.target.value)} className="w-72 rounded-lg border border-slate-300 px-3 py-2 text-sm" />
{filteredUsers.map((m:any,index:number)=>( { setSelectedUser(m); setDetailTab("profile"); try { const logs = await api(`/users/${m.member_id}/activity`); setActivityLogs(logs.items ?? []); } catch { setActivityLogs([]); } }} className="hover:bg-slate-50 cursor-pointer" > ))} {data?.items?.length === 0 && ( )}
0 && selected.length === data.items.length } onChange={(e) => toggleSelectAll(e.target.checked)} className="h-4 w-4 rounded border-slate-300" />
{t.user} {t.role} {t.department} {t.status} {t.last_login} Joined On Action
toggleSelect(m.member_id, e.target.checked) } className="h-4 w-4 rounded border-slate-300" />
{(m.name?.[0] ?? "U").toUpperCase()}
{m.name}
{m.email}
{m.role} {m.department ?? "—"} {m.status} {m.last_login ? new Date(m.last_login).toLocaleString() : "—"} {m.joined_at ? new Date(m.joined_at).toLocaleString() : "—"} e.stopPropagation()} >
{openMenu === m.member_id && (
)}
No team members yet.
) : ( <>

Role Summary

{ROLES.map((r) => { const count = (data?.items ?? []).filter( (u: any) => u.role === r.role ).length; return (
{r.label}
{count}
{r.desc}
); })}
)} {/* Org profile */} {org && (

{t.organization_profile}

)} {selectedUser && (
setSelectedUser(null)} >
e.stopPropagation()} > {/* Header */}

User Detail

{/* Profile */} {/* Profile */}
{selectedUser.name?.[0]?.toUpperCase()}
{selectedUser.name}
{selectedUser.role}
{/* Enable / Disable button */} {selectedUser.status}
{/* Email + Phone */}
Email {selectedUser.email ?? "—"}
Phone {selectedUser.phone ?? "—"}
{/* Details */} {detailTab === "profile" && ( <> {/* Your existing Info components */} )} {detailTab === "permissions" && (

Permissions

{selectedUser.role === "admin" && ( <> )} {selectedUser.role === "finance" && ( <> )} {selectedUser.role === "user" && ( <> )}
)} {detailTab === "activity" && (
{activityLogs.length === 0 ? (
No activity found
) : (
{activityLogs.map((log) => (
{log.action}
{log.details}
{new Date(log.created_at).toLocaleString()}
))}
)}
)} {/* Buttons */}
)} {/* Invite modal */} {open && (
setOpen(false)}>
e.stopPropagation()}>

{editingUser ? "Edit User" : t.invite_user}

{err &&

{err}

} {!editingUser && ( )}
)}
); } function Kpi({ label, value }: any) { return (
{label}
{value}
); } function Info({ label, value }: any) { return (
{label} {value ?? "—"}
); }