🚧 WIP on about page

This commit is contained in:
ajnart
2023-10-31 23:48:24 +01:00
parent 4072ebc5a5
commit ea8c8ffee2
6 changed files with 3227 additions and 0 deletions

View File

@@ -39,6 +39,8 @@ import { useColorTheme } from '~/tools/color';
import { usePrimaryGradient } from '../../Common/useGradient';
import Credits from './Credits';
import Tip from './Tip';
import { TranslatorsTable } from './Translators';
import { ContributorsTable } from './Contributors';
interface AboutModalProps {
opened: boolean;
@@ -175,6 +177,8 @@ export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutMod
</Grid.Col>
</Grid>
<Credits />
<TranslatorsTable />
<ContributorsTable />
</Modal>
);
};

View File

@@ -0,0 +1,94 @@
import {
Anchor,
Avatar,
Group,
Loader,
ScrollArea,
Stack,
Table,
Text,
createStyles,
} from '@mantine/core';
import { useQuery } from '@tanstack/react-query';
import { cache } from 'react';
import { REPO_URL } from '../../../../../data/constants';
// Generated by https://quicktype.io
export interface Contributors {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: Type;
site_admin: boolean;
contributions: number;
}
export enum Type {
Bot = 'Bot',
User = 'User',
}
export function ContributorsTable() {
// Type data as Contributors
const { data, isFetching } = useQuery({
queryKey: ['contributors'],
cacheTime: 1000 * 60 * 60 * 24,
staleTime: 1000 * 60 * 60 * 5,
queryFn: () =>
fetch(`https://api.github.com/repos/${REPO_URL}/contributors?per_page=25`, {
cache: 'force-cache',
}).then((res) => res.json()) as Promise<Contributors[]>,
});
if (isFetching || !data) return <Loader />;
const rows = data.map((contributor) => (
<tr key={contributor.id}>
<td>
<Anchor href={`https://github.com/${contributor.login}`} target="_blank">
<Group noWrap>
<Avatar
size={25}
radius="lg"
src={contributor.avatar_url}
alt={contributor.login}
/>
{contributor.login}
</Group>
</Anchor>
</td>
<td>{contributor.contributions}</td>
</tr>
));
return (
<Stack>
<h5>Credits to our amazing contributors</h5>
<ScrollArea h={800}>
<Table miw={700}>
<thead>
<tr>
<th>Contributor</th>
<th>Contributions</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</Table>
</ScrollArea>
</Stack>
);
}

View File

@@ -0,0 +1,20 @@
.header {
position: sticky;
top: 0;
background-color: var(--mantine-color-body);
transition: box-shadow 150ms ease;
&::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
border-bottom: rem(1px) solid
light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-3));
}
}
.scrolled {
box-shadow: var(--mantine-shadow-sm);
}

View File

@@ -0,0 +1,60 @@
import { Anchor, Avatar, Group, ScrollArea, Stack, Table, Text, createStyles } from '@mantine/core';
import cx from 'clsx';
import Link from 'next/link';
import { useState } from 'react';
import CrowdinReport from '../../../../../data/crowdin-report.json';
export function TranslatorsTable() {
// Only the first 30 translators are shown
const translators = CrowdinReport.data.slice(0, 30);
const rows = translators.map((translator) => (
<tr key={translator.user.id}>
<td>
<Anchor href={`https://crowdin.com/profile/${translator.user.username}`} target="_blank">
<Group noWrap>
<Avatar
size={25}
radius="lg"
src={translator.user.avatarUrl}
alt={translator.user.username}
/>
{translator.user.username}
</Group>
</Anchor>
</td>
<td>{translator.translated}</td>
<td>{translator.approved}</td>
<td>{translator.target}</td>
<td>
<Text lineClamp={1}>
{translator.languages.map((language) => (
<span key={language.id}>{language.name}, </span>
))}
</Text>
</td>
</tr>
));
return (
<Stack>
<h5>Credits to our amazing translators</h5>
<ScrollArea h={800}>
<Table miw={700}>
<thead>
<tr>
<th>Translator</th>
<th>Translated</th>
<th>Approved</th>
<th>Target</th>
<th>Languages</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</Table>
</ScrollArea>
</Stack>
);
}