mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-06-28 16:20:34 +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:
@@ -1,18 +1,33 @@
|
||||
{
|
||||
"accepted": "↪ Accepted",
|
||||
"accepted_prompts": "Accepted prompts",
|
||||
"daily": "Daily",
|
||||
"day": "Day",
|
||||
"good_rankings": "Good rankings",
|
||||
"label": "Labels",
|
||||
"labels_full": "Labels (full)",
|
||||
"labels_simple": "Labels (simple)",
|
||||
"last_updated_at": "Last updated at: {{val, datetime}}",
|
||||
"leaderboard": "Leaderboard",
|
||||
"month": "Month",
|
||||
"monthly": "Monthly",
|
||||
"next": "Next",
|
||||
"overall": "Overall",
|
||||
"previous": "Previous",
|
||||
"prompt": "Prompts",
|
||||
"rank": "Rank",
|
||||
"rankings": "Rankings",
|
||||
"replies_assistant": "Replies as Assistant",
|
||||
"replies_prompter": "Replies as Prompter",
|
||||
"reply": "Replies",
|
||||
"reply_ranked_1": "Replies ranked first",
|
||||
"score": "Score",
|
||||
"top_5_contributors_today": "Top 5 Contributors Today",
|
||||
"total": "Total",
|
||||
"user": "User",
|
||||
"view_all": "View all",
|
||||
"weekly": "Weekly"
|
||||
"week": "Week",
|
||||
"weekly": "Weekly",
|
||||
"your_account": "Your account",
|
||||
"your_stats": "Your statistics"
|
||||
}
|
||||
|
||||
@@ -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