Employee directory
A searchable list of employees with an org chart of who reports to whom. It loads its data on the server through the block's client.
pnpm dev:example) to see it.Add the components
terminal npx shadcn add card empty skeletonInstall the glue
Install the block with
npx better-supabase add employees. The glue items are copied into your app, so edit them as you need.None: the page calls the block's client on the server.
Write the screen
React and shadcn
View in the exampleemployee-directory.tsx /** * Render inside `<Suspense>`: the employees as an org chart, each manager * above their reports, with a search. Private details open in a sheet for * callers with `employees.view_sensitive`. */ export async function EmployeeDirectory() { const [session, t] = await Promise.all([ getSession(), getExtracted("people"), ]); if (!can(session, "employees.read")) { forbidden(); } const directory = await settle(loadDirectory); if (directory.kind === "no-organization") { return null; } const canWrite = can(session, "employees.write"); const canViewSensitive = can(session, "employees.view_sensitive"); const managers = directory.kind === "ok" ? directory.data.map((employee) => ({ value: employee.id, label: employee.name, })) : []; const addEmployee = canWrite ? ( <AddEmployeeDialog managers={managers} canViewSensitive={canViewSensitive} /> ) : null; return ( <Card data-recipe="employee-directory"> <CardHeader> <CardTitle>{t("Employees")}</CardTitle> <CardDescription> {t("Everyone in the organization and who they report to.")} </CardDescription> {addEmployee && managers.length > 0 ? ( <CardAction>{addEmployee}</CardAction> ) : null} </CardHeader> <CardContent> {directory.kind === "error" ? ( <PeopleLoadError title={t("The directory didn't load")} /> ) : directory.data.length === 0 ? ( <Empty className="border"> <EmptyHeader> <EmptyMedia variant="icon"> <UsersIcon /> </EmptyMedia> <EmptyTitle>{t("No employees yet")}</EmptyTitle> <EmptyDescription> {canWrite ? t("Add the first employee to start the org chart.") : t("Ask an admin to add employees.")} </EmptyDescription> </EmptyHeader> {addEmployee ? <EmptyContent>{addEmployee}</EmptyContent> : null} </Empty> ) : ( <EmployeeTable employees={directory.data} canViewSensitive={canViewSensitive} /> )} </CardContent> </Card> ); }