"use client" /** * Programs — the scope every school-family product is filtered by. * * One view, because a program does not come in types. School is a filter * rather than a tab: two schools are the normal shape of a workspace, and a * tab per school would be a nav that grows with the contract. * * Rows are read-only. The counts they carry are read off People and Courses, * so the way to change one is to change the records under it, which is why the * table offers no row menu. */ import * as React from "react" import { useNavigate } from "react-router" import { buildAdminProgramColumns } from "@/components/admin/admin-columns" import { AdminHubClient, type AdminHubView } from "@/components/admin/admin-hub-client" import { ADMIN_PROGRAMS, adminProgramsKpi, type AdminProgram } from "@/lib/mock/admin-directory" export function AdminProgramsClient() { const navigate = useNavigate() const views = React.useMemo[]>( () => [ { id: "programs", label: "Programs", icon: "fa-sitemap", rows: ADMIN_PROGRAMS, columns: buildAdminProgramColumns(ADMIN_PROGRAMS), emptyState: "No programs yet. Import them from your student system to scope the rest of the workspace.", }, ], [], ) const metrics = React.useMemo(() => adminProgramsKpi(ADMIN_PROGRAMS), []) return ( title="Program Management" hubKey="admin-programs" views={views} metrics={metrics} searchAriaLabel="Search programs" objectLabel="programs" getRowId={row => row.id} getRowSelectionLabel={row => row.name} getRowHref={row => `/programs/${row.id}`} onRowNavigate={href => navigate(href)} defaultSort={{ key: "name", dir: "asc" }} /> ) }