Skip to content

Commit

Permalink
Add admin school table
Browse files Browse the repository at this point in the history
  • Loading branch information
bortoz committed Dec 7, 2024
1 parent 340a159 commit 172be44
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 8 deletions.
16 changes: 10 additions & 6 deletions src/web/admin/dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Suspense } from "react";

import { Card, CardActions, CardBody } from "@olinfo/react-components";
import { Link } from "wouter";

import type { Participation, Student } from "~/models";
import { Loading } from "~/web/components";
Expand Down Expand Up @@ -29,12 +30,15 @@ export default function Dashboard() {
</CardBody>
</Card>
<Card>
<CardBody title="Statistiche">
<div className="h-20">
<Suspense fallback={<Loading />}>
<ContestInformation />
</Suspense>
</div>
<CardBody title="Scuole">
<Suspense fallback={<Loading />}>
<ContestInformation />
</Suspense>
<CardActions>
<Link href="/schools/" className="btn btn-primary">
Gestione scuole
</Link>
</CardActions>
</CardBody>
</Card>
{contest.hasOnline && (
Expand Down
12 changes: 10 additions & 2 deletions src/web/admin/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createContext, lazy, useContext } from "react";

import { Link, Redirect, Route, useParams } from "wouter";
import { Link, Redirect, Route, Switch, useParams } from "wouter";

import type { Contest } from "~/models";

import { AdminLayout } from "./layout";
import { SchoolTable } from "./school-table";

type AdminContextProps = {
name: string;
Expand Down Expand Up @@ -57,7 +58,14 @@ function ProviderInner({ contests, ...props }: AdminProviderProps) {

return (
<AdminContext.Provider value={{ ...props, contest, contests }}>
<Dashboard />
<Switch>
<Route path="/">
<Dashboard />
</Route>
<Route path="/schools">
<SchoolTable />
</Route>
</Switch>
</AdminContext.Provider>
);
}
Expand Down
107 changes: 107 additions & 0 deletions src/web/admin/school-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { type ComponentType, Suspense, lazy, useMemo } from "react";

import type { CellEditRequestEvent, ColDef, ICellRendererParams } from "@ag-grid-community/core";
import { AG_GRID_LOCALE_IT } from "@ag-grid-community/locale";
import type { AgGridReactProps } from "@ag-grid-community/react/dist/types/src/shared/interfaces";

import type { Participation, Student } from "~/models";
import { Loading } from "~/web/components";
import { participationConverter } from "~/web/firebase/common/converters";
import { useCollection } from "~/web/firebase/hooks";

import { useAdmin } from "./provider";

import "@ag-grid-community/styles/ag-grid.css";
import "@ag-grid-community/styles/ag-theme-quartz.css";
import { useCount } from "~/web/firebase/hooks/count";

const AgGridReact: ComponentType<AgGridReactProps> = lazy(() => import("~/web/components/ag-grid"));

export function SchoolTable() {
const { contest } = useAdmin();

const [participations, setParticipation] = useCollection(
"participations",
participationConverter,
{
constraints: { contestId: contest.id },
subscribe: true,
},
);

const colDefs = useMemo(() => columnDefinition(), []);

const onCellEditRequest = async (ev: CellEditRequestEvent) => {
const participation = ev.data as Participation;
if (ev.colDef.field === "finalized") {
await setParticipation({ ...participation, finalized: ev.newValue });
}
ev.api.refreshCells({ force: true });
};

return (
<Suspense fallback={<Loading />}>
<div className="ag-theme-quartz-auto-dark relative grow p-2">
<div className="absolute inset-0">
<AgGridReact
rowData={participations}
getRowId={(row) => (row.data as Participation).id}
columnDefs={colDefs}
singleClickEdit={true}
readOnlyEdit={true}
rowSelection="single"
onCellEditRequest={onCellEditRequest}
enableBrowserTooltips={true}
localeText={AG_GRID_LOCALE_IT}
/>
</div>
</div>
</Suspense>
);
}

function columnDefinition(): ColDef[] {
return [
{
field: "schoolId",
headerName: "ID",
width: 150,
filter: true,
},
{
field: "name",
headerName: "Nome",
minWidth: 200,
flex: 1,
filter: true,
},
{
field: "count",
headerName: "Studenti",
width: 100,
sortable: false,
cellRenderer: ({ data }: ICellRendererParams<Participation>) => {
if (!data) return;
return (
<Suspense>
<Count participationId={data.id} />
</Suspense>
);
},
},
{
field: "finalized",
headerName: "Finalizzato",
width: 100,
filter: true,
cellDataType: "boolean",
editable: true,
},
];
}

function Count({ participationId }: { participationId: string }) {
return useCount<Student>(`participations/${participationId}/students`, {
constraints: { disabled: false },
});
}

0 comments on commit 172be44

Please sign in to comment.