Files
car-crushers-portal/app/routes/events-team_.events-breakdown.tsx
Regalijan cfc57c838e
All checks were successful
Test, Build, Deploy / Test, Build, and Deploy (push) Successful in 55s
Test, Build, Deploy / Create Sentry Release (push) Successful in 6s
More events team nonsense
2026-04-11 03:30:46 -04:00

137 lines
3.0 KiB
TypeScript

import {
Container,
Heading,
Table,
TableCaption,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
export async function loader({ context }: { context: RequestContext }) {
const { current_user: user } = context.data;
if (!user)
throw new Response(null, {
status: 401,
});
if (![1 << 4, 1 << 12].find((p) => user.permissions & p))
throw new Response(null, {
status: 403,
});
const { prisma } = context.data;
const memberResults = await prisma.etMember.findMany({
select: {
id: true,
name: true,
},
});
const data: {
[k: string]: {
fotd: number;
name: string;
};
} & {
[k: string]: {
[k: string]: number;
};
} = {};
for (const row of memberResults) {
data[row.id].fotd = 0;
data[row.id].gamenight = 0;
data[row.id].name = row.name;
data[row.id].rotw = 0;
data[row.id].qotd = 0;
}
const eventsResult = await prisma.event.findMany({
select: {
answered_at: true,
created_by: true,
day: true,
month: true,
performed_at: true,
reached_minimum_player_count: true,
type: true,
year: true,
},
});
for (const row of eventsResult) {
const creator = row.created_by;
const type = row.type;
if (!data[creator]) continue;
if (row.performed_at) data[creator][type] += 10;
else {
const now = new Date();
const currentYear = now.getUTCFullYear();
const currentMonth = now.getUTCMonth() + 1;
const currentDay = now.getUTCDate();
if (
row.year < currentYear ||
(currentYear === row.year && currentMonth > row.month) ||
(currentMonth === row.month &&
currentYear === row.year &&
row.day < currentDay)
)
data[creator][type] -= 5;
}
if (row.type === "gamenight" && row.reached_minimum_player_count)
data[creator].gamenight += 10;
}
return data;
}
export default function () {
const data = useLoaderData<typeof loader>();
return (
<Container maxW="container.lg">
<Heading>Points Breakdown</Heading>
<TableContainer mt="16px">
<Table variant="simple">
<TableCaption>
Total points breakdown by event type. This does not include
deductions from strikes.
</TableCaption>
<Thead>
<Tr>
<Th>Discord ID</Th>
<Th>Name</Th>
<Th>FoTD Points</Th>
<Th>Gamenight Points</Th>
<Th>QoTD Points</Th>
<Th>RoTW Points</Th>
</Tr>
</Thead>
<Tbody>
{Object.entries(data).map(([k, v]) => (
<Tr>
<Td>{k}</Td>
<Td>{v.name}</Td>
<Td>{v.fotd}</Td>
<Td>{v.gamenight}</Td>
<Td>{v.qotd}</Td>
<Td>{v.rotw}</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Container>
);
}