diff --git a/website/public/locales/en/leaderboard.json b/website/public/locales/en/leaderboard.json index c2dd0832..d1d7ed92 100644 --- a/website/public/locales/en/leaderboard.json +++ b/website/public/locales/en/leaderboard.json @@ -7,5 +7,6 @@ "rank": "Rank", "score": "Score", "user": "User", - "weekly": "Weekly" + "weekly": "Weekly", + "prompt_tasks": "Prompt Tasks" } diff --git a/website/src/components/DataTable.tsx b/website/src/components/DataTable.tsx index 466393eb..d29a2813 100644 --- a/website/src/components/DataTable.tsx +++ b/website/src/components/DataTable.tsx @@ -1,8 +1,6 @@ import { Box, Button, - Card, - CardBody, Flex, FormControl, FormLabel, @@ -49,6 +47,7 @@ export type DataTableProps = { onFilterChange?: (items: FilterItem[]) => void; disableNext?: boolean; disablePrevious?: boolean; + disablePagination?: boolean; }; export const DataTable = ({ @@ -61,6 +60,7 @@ export const DataTable = ({ onFilterChange, disableNext, disablePrevious, + disablePagination, }: DataTableProps) => { const { getHeaderGroups, getRowModel } = useReactTable({ data, @@ -79,8 +79,8 @@ export const DataTable = ({ onFilterChange(newValues); }; return ( - - + <> + {disablePagination && ( - - - {caption} - - {getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - ))} - - ))} - - - {getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - ))} - - ))} - -
- - {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} - {(header.column.columnDef as DataTableColumnDef).filterable && ( - value.id === header.id)?.value ?? ""} - onChange={(value) => handleFilterChange({ id: header.id, value })} - label={flexRender(header.column.columnDef.header, header.getContext())} - > - )} - -
{flexRender(cell.column.columnDef.cell, cell.getContext())}
-
-
-
+ )} + + + {caption} + + {getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + ))} + + ))} + + + {getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + ))} + + ))} + +
+ + {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} + {(header.column.columnDef as DataTableColumnDef).filterable && ( + value.id === header.id)?.value ?? ""} + onChange={(value) => handleFilterChange({ id: header.id, value })} + label={flexRender(header.column.columnDef.header, header.getContext())} + > + )} + +
{flexRender(cell.column.columnDef.cell, cell.getContext())}
+
+ ); }; diff --git a/website/src/components/LeaderboardGridCell/LeaderboardGridCell.tsx b/website/src/components/LeaderboardGridCell/LeaderboardGridCell.tsx index 7886784a..a65b7c2a 100644 --- a/website/src/components/LeaderboardGridCell/LeaderboardGridCell.tsx +++ b/website/src/components/LeaderboardGridCell/LeaderboardGridCell.tsx @@ -1,90 +1,61 @@ -import { Table, TableContainer, Tbody, Td, Text, Th, Thead, Tr, useColorModeValue } from "@chakra-ui/react"; +import { CircularProgress } from "@chakra-ui/react"; +import { createColumnHelper } from "@tanstack/react-table"; import { useTranslation } from "next-i18next"; import React, { useMemo } from "react"; -import { useTable } from "react-table"; import { get } from "src/lib/api"; -import { LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard"; +import { LeaderboardEntity, LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard"; import useSWRImmutable from "swr/immutable"; -const getColumns = (t) => [ - { - Header: t("rank"), - accessor: "rank", - style: { width: "90px" }, - }, - { - Header: t("score"), - accessor: "leader_score", - style: { width: "90px" }, - }, - { - Header: t("user"), - accessor: "display_name", - }, -]; +import { DataTable } from "../DataTable"; + +const columnHelper = createColumnHelper(); /** * Presents a grid of leaderboard entries with more detailed information. */ const LeaderboardGridCell = ({ timeFrame }: { timeFrame: LeaderboardTimeFrame }) => { - const { t } = useTranslation(["leaderboard", "common"]); - const { data: reply } = useSWRImmutable(`/api/leaderboard?time_frame=${timeFrame}`, get, { + const { t } = useTranslation("leaderboard"); + const { + data: reply, + isLoading, + error, + } = useSWRImmutable(`/api/leaderboard?time_frame=${timeFrame}`, get, { revalidateOnMount: true, }); - const columns = useMemo(() => getColumns(t), [t]); - - const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ - columns, - data: reply?.leaderboard ?? [], - }); - - const backgroundColor = useColorModeValue("white", "gray.800"); + const columns = useMemo( + () => [ + columnHelper.accessor("rank", { + header: t("rank"), + }), + columnHelper.accessor("display_name", { + header: t("user"), + }), + columnHelper.accessor("leader_score", { + header: t("score"), + }), + columnHelper.accessor("prompts", { + header: t("pro"), + }), + ], + [t] + ); const lastUpdated = useMemo(() => { const val = new Date(reply?.last_updated); return t("last_updated_at", { val, formatParams: { val: { dateStyle: "full", timeStyle: "short" } } }); }, [t, reply?.last_updated]); + console.log(reply, isLoading); - if (!reply) { - return null; + if (isLoading) { + return ; } - return ( - - - - {headerGroups.map((headerGroup, idx) => ( - - {headerGroup.headers.map((column) => ( - - ))} - - ))} - + if (error) { + return Unable to load leaderboard; + } - - {rows.map((row) => { - prepareRow(row); - return ( - - {row.cells.map((cell, idx) => { - return ( - - ); - })} - - ); - })} - -
- {column.render("Header")} -
- {cell.render("Cell")} -
- {lastUpdated} -
- ); + return ; }; export { LeaderboardGridCell }; diff --git a/website/src/pages/leaderboard.tsx b/website/src/pages/leaderboard.tsx index e413366f..052c94ad 100644 --- a/website/src/pages/leaderboard.tsx +++ b/website/src/pages/leaderboard.tsx @@ -1,4 +1,4 @@ -import { Box, Heading, Tab, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react"; +import { Box, Card, CardBody, Heading, Tab, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react"; import Head from "next/head"; import { useTranslation } from "next-i18next"; import { getDashboardLayout } from "src/components/Layout"; @@ -18,29 +18,33 @@ const Leaderboard = () => { {t("leaderboard")} - - - {t("daily")} - {t("weekly")} - {t("monthly")} - {t("overall")} - + + + + + {t("daily")} + {t("weekly")} + {t("monthly")} + {t("overall")} + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + );