117 lines
2.7 KiB
TypeScript
117 lines
2.7 KiB
TypeScript
import {
|
|
Anchor,
|
|
Avatar,
|
|
Group,
|
|
Pagination,
|
|
Stack,
|
|
Table,
|
|
Text,
|
|
Title,
|
|
} from '@mantine/core';
|
|
import { usePagination } from '@mantine/hooks';
|
|
import { Trans, useTranslation } from 'next-i18next';
|
|
|
|
// 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',
|
|
}
|
|
|
|
const PAGINATION_ITEMS = 20;
|
|
|
|
export function ContributorsTable({ contributors }: { contributors: Contributors[] }) {
|
|
const pagination = usePagination({
|
|
total: contributors.length / PAGINATION_ITEMS,
|
|
initialPage: 1,
|
|
});
|
|
const { t } = useTranslation(['layout/modals/about']);
|
|
|
|
const rows = contributors
|
|
.slice(
|
|
(pagination.active - 1) * PAGINATION_ITEMS,
|
|
(pagination.active - 1) * PAGINATION_ITEMS + PAGINATION_ITEMS
|
|
)
|
|
.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>
|
|
<Title order={3}>{t('contributors', { count: contributors.length })}</Title>
|
|
<Text>
|
|
<Trans
|
|
i18nKey="layout/modals/about:contributorsDescription"
|
|
components={{
|
|
a: <Anchor href="https://homarr.dev/docs/community/developer-guides" target="_blank" />,
|
|
}}
|
|
/>
|
|
</Text>
|
|
|
|
<Table withBorder>
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
style={{
|
|
width: 400,
|
|
}}
|
|
>
|
|
Contributor
|
|
</th>
|
|
<th
|
|
style={{
|
|
width: 400,
|
|
}}
|
|
>
|
|
Contributions
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>{rows}</tbody>
|
|
</Table>
|
|
<Pagination
|
|
style={{
|
|
justifyContent: 'center',
|
|
}}
|
|
total={contributors.length / PAGINATION_ITEMS}
|
|
value={pagination.active}
|
|
onNextPage={() => pagination.next()}
|
|
onPreviousPage={() => pagination.previous()}
|
|
onChange={(targetPage) => pagination.setPage(targetPage)}
|
|
/>
|
|
</Stack>
|
|
);
|
|
}
|