mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-23 12:40:42 +08:00
Basic user stats in the accounts page (#1158)
Closes #747 Blocked by #1156 #1166 Very simplistic, not much styling
This commit is contained in:
@@ -307,4 +307,9 @@ export class OasstApiClient {
|
||||
const backendUser = await this.post<BackendUser>(`/api/v1/frontend_users/`, user);
|
||||
await this.put<void>(`/api/v1/users/${backendUser.user_id}?tos_acceptance=true`);
|
||||
}
|
||||
|
||||
async fetch_user_stats(user: BackendUserCore) {
|
||||
const backendUser = await this.get<BackendUser>(`/api/v1/frontend_users/${user.auth_method}/${user.id}`);
|
||||
return this.get(`/api/v1/users/${backendUser.user_id}/stats`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
import { Divider, Flex, Grid, Icon, Text } from "@chakra-ui/react";
|
||||
import { Box, Divider, Flex, Grid, Icon, Text } from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { useSession } from "next-auth/react";
|
||||
import React from "react";
|
||||
export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props";
|
||||
import { Pencil } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SurveyCard } from "src/components/Survey/SurveyCard";
|
||||
import { get } from "src/lib/api";
|
||||
import { getTypeSafei18nKey } from "src/lib/i18n";
|
||||
import { LeaderboardEntity, LeaderboardTimeFrame } from "src/types/Leaderboard";
|
||||
import uswSWRImmutable from "swr/immutable";
|
||||
|
||||
export default function Account() {
|
||||
const { t } = useTranslation("leaderboard");
|
||||
const { data: session } = useSession();
|
||||
|
||||
const { data } = uswSWRImmutable<{ [time in LeaderboardTimeFrame]: LeaderboardEntity }>("/api/user_stats", get);
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -23,11 +32,9 @@ export default function Account() {
|
||||
/>
|
||||
</Head>
|
||||
<main className="oa-basic-theme p-6">
|
||||
<Flex m="auto" className="max-w-7xl" alignContent="center">
|
||||
<Flex direction="column" m="auto" className="max-w-7xl" alignContent="center" gap={4}>
|
||||
<SurveyCard className="w-full">
|
||||
<Text as="b" display="block" fontSize="2xl" py={2}>
|
||||
Your Account
|
||||
</Text>
|
||||
<Title>{t("your_account")}</Title>
|
||||
<Divider />
|
||||
<Grid gridTemplateColumns="repeat(2, max-content)" alignItems="center" gap={6} py={4}>
|
||||
<Text as="b">Username</Text>
|
||||
@@ -40,10 +47,71 @@ export default function Account() {
|
||||
<Text as="b">Email</Text>
|
||||
<Text>{session.user.email ?? "(No Email)"}</Text>
|
||||
</Grid>
|
||||
<p></p>
|
||||
</SurveyCard>
|
||||
<SurveyCard>
|
||||
<Title>{t("your_stats")}</Title>
|
||||
{[
|
||||
LeaderboardTimeFrame.total,
|
||||
LeaderboardTimeFrame.day,
|
||||
LeaderboardTimeFrame.week,
|
||||
LeaderboardTimeFrame.month,
|
||||
].map((key) => {
|
||||
const values = data[key];
|
||||
if (!values) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Box key={key} py={4}>
|
||||
<Title>{t(getTypeSafei18nKey(key))}</Title>
|
||||
<Flex w="full" wrap="wrap" alignItems="flex-start" gap={4}>
|
||||
<TableColumn>
|
||||
<Entry title={t("score")} value={values.leader_score} />
|
||||
<Entry title={t("rank")} value={values.rank} />
|
||||
<Entry title={t("prompt")} value={values.prompts} />
|
||||
<Entry title={t("accepted_prompts")} value={values.accepted_prompts} />
|
||||
</TableColumn>
|
||||
<TableColumn>
|
||||
<Entry title={t("replies_assistant")} value={values.replies_assistant} />
|
||||
<Entry title={t("accepted")} value={values.accepted_replies_assistant} />
|
||||
<Entry title={t("replies_prompter")} value={values.replies_prompter} />
|
||||
<Entry title={t("accepted")} value={values.accepted_replies_prompter} />
|
||||
</TableColumn>
|
||||
<TableColumn>
|
||||
<Entry title={t("labels_full")} value={values.labels_full} />
|
||||
<Entry title={t("labels_simple")} value={values.labels_simple} />
|
||||
<Entry title={t("rankings")} value={values.rankings_total} />
|
||||
<Entry title={t("reply_ranked_1")} value={values.reply_ranked_1} />
|
||||
</TableColumn>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</SurveyCard>
|
||||
</Flex>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const Title = ({ children }) => (
|
||||
<Text as="b" display="block" fontSize="2xl" py={2}>
|
||||
{children}
|
||||
</Text>
|
||||
);
|
||||
|
||||
const TableColumn = ({ children }) => {
|
||||
return (
|
||||
<Grid gridTemplateColumns="1fr max-content" mx={8} w="60" gap={2}>
|
||||
{children}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
const Entry = ({ title, value }) => {
|
||||
return (
|
||||
<>
|
||||
<span className="text-start">{title}</span>
|
||||
<span className="text-end">{value}</span>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { withoutRole } from "src/lib/auth";
|
||||
import { createApiClientFromUser } from "src/lib/oasst_client_factory";
|
||||
import { getBackendUserCore } from "src/lib/users";
|
||||
|
||||
const handler = withoutRole("banned", async (req, res, token) => {
|
||||
const user = await getBackendUserCore(token.sub);
|
||||
const oasstApiClient = createApiClientFromUser(user);
|
||||
const stats = await oasstApiClient.fetch_user_stats(user);
|
||||
res.status(200).json(stats);
|
||||
});
|
||||
|
||||
export default handler;
|
||||
Reference in New Issue
Block a user