Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Create event type based point breakdown
- Loading branch information
Showing
1 changed file
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
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 memberResults = await context.env.D1.prepare( | ||
"SELECT id, name FROM et_members;", | ||
).all(); | ||
|
||
if (!memberResults.success) | ||
throw new Response(null, { | ||
status: 500, | ||
}); | ||
|
||
const pointData: { | ||
[k: string]: { | ||
[p: string]: number; | ||
}; | ||
} = {}; | ||
|
||
const nameData: { | ||
[k: string]: { | ||
name: string; | ||
}; | ||
} = {}; | ||
|
||
for (const row of memberResults.results) | ||
nameData[row.id as string] = { name: row.name as string }; | ||
|
||
const eventsResult = await context.env.D1.prepare( | ||
"SELECT answered_at, created_by, day, month, performed_at, reached_minimum_player_count, type, year FROM events;", | ||
).all(); | ||
|
||
if (!eventsResult.success) | ||
throw new Response(null, { | ||
status: 500, | ||
}); | ||
|
||
for (const row of eventsResult.results) { | ||
const creator = row.created_by as string; | ||
const type = row.type as string; | ||
|
||
if (!pointData[creator]) continue; | ||
|
||
if (row.performed_at) pointData[creator][type as string] += 10; | ||
else { | ||
const now = new Date(); | ||
const currentYear = now.getUTCFullYear(); | ||
const currentMonth = now.getUTCMonth() + 1; | ||
const currentDay = now.getUTCDate(); | ||
|
||
if ( | ||
(row.year as number) < currentYear || | ||
(currentYear === row.year && currentMonth > (row.month as number)) || | ||
(currentMonth === row.month && | ||
currentYear === row.year && | ||
(row.day as number) < currentDay) | ||
) | ||
pointData[creator][type] -= 5; | ||
} | ||
|
||
switch (row.type) { | ||
case "gamenight": | ||
if (row.reached_minimum_player_count) | ||
pointData[creator].gamenight += 10; | ||
|
||
break; | ||
|
||
case "rotw": | ||
if ( | ||
(row.answered_at as number) - (row.performed_at as number) >= | ||
86400000 | ||
) | ||
pointData[creator].rotw += 10; | ||
|
||
break; | ||
|
||
default: | ||
break; | ||
} | ||
} | ||
|
||
return Object.assign(pointData, nameData); | ||
} | ||
|
||
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> | ||
); | ||
} |