import { useState } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Search, Plus, Building2, Trash2, Pencil, Users, Shield } from "lucide-react"; import { entitiesService } from "@/services/entities.service"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useToast } from "@/hooks/use-toast"; const ENTITY_TYPES = [ { value: "corporate", label: "Corporate" }, { value: "university", label: "University" }, { value: "school", label: "School" }, { value: "government", label: "Government" }, { value: "freelance", label: "Freelance" }, ]; export default function EntitiesPage() { const [search, setSearch] = useState(""); const [createOpen, setCreateOpen] = useState(false); const [editOpen, setEditOpen] = useState(false); const [editEntity, setEditEntity] = useState<{ id: number; name: string; code: string; type: string } | null>(null); const [form, setForm] = useState({ name: "", code: "", type: "" }); const { toast } = useToast(); const qc = useQueryClient(); const entitiesQ = useQuery({ queryKey: ["entities"], queryFn: () => entitiesService.list({ size: 200 }), }); const createMut = useMutation({ mutationFn: (data: { name: string; code?: string; type?: string }) => entitiesService.create(data as Partial), onSuccess: () => { qc.invalidateQueries({ queryKey: ["entities"] }); setCreateOpen(false); setForm({ name: "", code: "", type: "" }); toast({ title: "Entity created" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const updateMut = useMutation({ mutationFn: ({ id, data }: { id: number; data: Record }) => entitiesService.update(id, data as Partial), onSuccess: () => { qc.invalidateQueries({ queryKey: ["entities"] }); setEditOpen(false); toast({ title: "Entity updated" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const deleteMut = useMutation({ mutationFn: (id: number) => entitiesService.delete(id), onSuccess: () => { qc.invalidateQueries({ queryKey: ["entities"] }); toast({ title: "Deleted" }); }, onError: (err: Error) => toast({ title: "Error", description: err.message, variant: "destructive" }), }); const raw = entitiesQ.data as unknown; const entities: { id: number; name: string; code: string; type: string; user_count: number; role_count: number; active: boolean }[] = (() => { if (!raw) return []; if (Array.isArray(raw)) return raw as never[]; const r = raw as { items?: unknown; data?: unknown }; const arr = (r.items ?? r.data ?? []) as never[]; return Array.isArray(arr) ? arr : []; })(); const filtered = entities.filter( (e) => e.name?.toLowerCase().includes(search.toLowerCase()) || e.code?.toLowerCase().includes(search.toLowerCase()), ); const loading = entitiesQ.isLoading; function openEdit(e: typeof entities[0]) { setEditEntity({ id: e.id, name: e.name, code: e.code, type: e.type }); setEditOpen(true); } return (

Entities

Manage organizations and entities on the platform.

setSearch(e.target.value)} />
{entities.length} total
{loading ? (
) : ( Name Code Type Users Roles Status {filtered.length === 0 && ( No entities found. )} {filtered.map((e) => (
{e.name}
{e.code} {e.type || "—"} {e.user_count ?? 0} {e.role_count ?? 0} {e.active !== false ? "Active" : "Inactive"}
))}
)} {/* Create Dialog */} Create Entity
setForm((f) => ({ ...f, name: e.target.value }))} placeholder="Organization name" />
setForm((f) => ({ ...f, code: e.target.value }))} placeholder="ORG_CODE (auto-generated if empty)" />
{/* Edit Dialog */} Edit Entity {editEntity && (
setEditEntity((prev) => prev ? { ...prev, name: e.target.value } : prev)} />
setEditEntity((prev) => prev ? { ...prev, code: e.target.value } : prev)} />
)}
); }