mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-07 19:55:46 -05:00
Calendar: Participant counts
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
select
|
||||
count(*) as "memberCount"
|
||||
from
|
||||
"TournamentTeam"
|
||||
left join "TournamentTeamMember" on "TournamentTeamMember"."tournamentTeamId" = "TournamentTeam"."id"
|
||||
where
|
||||
"TournamentTeam"."tournamentId" = @tournamentId
|
||||
group by
|
||||
"TournamentTeam"."id";
|
||||
@@ -42,6 +42,8 @@ import findTieBreakerMapPoolByEventIdSql from "./findTieBreakerMapPoolByEventId.
|
||||
import deleteByIdSql from "./deleteById.sql";
|
||||
import createTournamentSql from "./createTournament.sql";
|
||||
import deleteTournamentByIdSql from "./deleteTournamentById.sql";
|
||||
import findTournamentTeamMemberCountsByEventIdSql from "./findTournamentTeamMemberCountsByEventId.sql";
|
||||
import { sumArray } from "~/utils/number";
|
||||
|
||||
const createStm = sql.prepare(createSql);
|
||||
const updateStm = sql.prepare(updateSql);
|
||||
@@ -355,6 +357,30 @@ function addTagArray<
|
||||
return { ...row, tags };
|
||||
}
|
||||
|
||||
const findTournamentTeamMemberCountsByEventIdStm = sql.prepare(
|
||||
findTournamentTeamMemberCountsByEventIdSql
|
||||
);
|
||||
|
||||
function addParticipantsCounts<
|
||||
T extends { tournamentId: CalendarEvent["tournamentId"] }
|
||||
>(arg: T) {
|
||||
if (!arg.tournamentId) return arg;
|
||||
|
||||
const counts = findTournamentTeamMemberCountsByEventIdStm.all({
|
||||
tournamentId: arg.tournamentId,
|
||||
}) as Array<{
|
||||
memberCount: number;
|
||||
}>;
|
||||
|
||||
return {
|
||||
...arg,
|
||||
participantCounts: {
|
||||
teams: counts.length,
|
||||
players: sumArray(counts.map((c) => c.memberCount)),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function findAllBetweenTwoTimestamps({
|
||||
startTime,
|
||||
endTime,
|
||||
@@ -374,10 +400,12 @@ export function findAllBetweenTwoTimestamps({
|
||||
eventDateId: CalendarEventDate["id"];
|
||||
} & Pick<User, "discordName" | "discordDiscriminator"> & {
|
||||
nthAppearance: number;
|
||||
} & { hasBadge: number }
|
||||
} & { hasBadge: number } & {
|
||||
participantCounts?: { teams: number; players: number };
|
||||
}
|
||||
>;
|
||||
|
||||
return rows.map(addTagArray).map(addBadges);
|
||||
return rows.map(addTagArray).map(addBadges).map(addParticipantsCounts);
|
||||
}
|
||||
|
||||
const findByIdStm = sql.prepare(findByIdSql);
|
||||
|
||||
@@ -8,7 +8,9 @@ const stm = sql.prepare(/* sql */ `
|
||||
from "User"
|
||||
left join "TournamentTeamMember" on "TournamentTeamMember"."userId" = "User"."id"
|
||||
left join "TournamentTeam" on "TournamentTeam"."id" = "TournamentTeamMember"."tournamentTeamId"
|
||||
left join "TournamentTeamCheckIn" on "TournamentTeamCheckIn"."tournamentTeamId" = "TournamentTeam"."id"
|
||||
where "TournamentTeam"."tournamentId" = @tournamentId
|
||||
and "TournamentTeamCheckIn"."checkedInAt" is not null
|
||||
and "User"."twitch" is not null
|
||||
`);
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
import { actualNumber } from "~/utils/zod";
|
||||
import { Tags } from "./components/Tags";
|
||||
import { Divider } from "~/components/Divider";
|
||||
import { UsersIcon } from "~/components/icons/Users";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
@@ -403,24 +404,39 @@ function EventsList({
|
||||
</div>
|
||||
</div>
|
||||
<div className="stack xs">
|
||||
<Link
|
||||
to={
|
||||
calendarEvent.tournamentId
|
||||
? tournamentPage(calendarEvent.tournamentId)
|
||||
: String(calendarEvent.eventId)
|
||||
}
|
||||
>
|
||||
<h2 className="calendar__event__title">
|
||||
{calendarEvent.name}{" "}
|
||||
{calendarEvent.nthAppearance > 1 ? (
|
||||
<span className="calendar__event__day">
|
||||
{t("day", {
|
||||
number: calendarEvent.nthAppearance,
|
||||
})}
|
||||
</span>
|
||||
) : null}
|
||||
</h2>
|
||||
</Link>
|
||||
<div>
|
||||
<Link
|
||||
to={
|
||||
calendarEvent.tournamentId
|
||||
? tournamentPage(calendarEvent.tournamentId)
|
||||
: String(calendarEvent.eventId)
|
||||
}
|
||||
>
|
||||
<h2 className="calendar__event__title">
|
||||
{calendarEvent.name}{" "}
|
||||
{calendarEvent.nthAppearance > 1 ? (
|
||||
<span className="calendar__event__day">
|
||||
{t("day", {
|
||||
number: calendarEvent.nthAppearance,
|
||||
})}
|
||||
</span>
|
||||
) : null}
|
||||
</h2>
|
||||
</Link>
|
||||
{calendarEvent.participantCounts &&
|
||||
calendarEvent.participantCounts.teams > 0 ? (
|
||||
<div className="calendar__event__participant-counts">
|
||||
<UsersIcon />{" "}
|
||||
{t("count.teams", {
|
||||
count: calendarEvent.participantCounts.teams,
|
||||
})}{" "}
|
||||
/{" "}
|
||||
{t("count.players", {
|
||||
count: calendarEvent.participantCounts.players,
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<Tags
|
||||
tags={calendarEvent.tags}
|
||||
badges={calendarEvent.badgePrizes}
|
||||
|
||||
@@ -155,6 +155,20 @@
|
||||
color: var(--text-lighter);
|
||||
}
|
||||
|
||||
.calendar__event__participant-counts {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text-lighter);
|
||||
font-size: var(--fonts-xs);
|
||||
gap: var(--s-2);
|
||||
margin-block-end: var(--s-1);
|
||||
}
|
||||
|
||||
.calendar__event__participant-counts > svg {
|
||||
width: 1rem;
|
||||
margin-block-end: 1px;
|
||||
}
|
||||
|
||||
.calendar__event__bottom-info-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
"createMapList": "Create map list",
|
||||
"from": "From {{author}}",
|
||||
"pastEvents.dividerText": "Past events",
|
||||
"count.teams_one": "{{count}} team",
|
||||
"count.players_one": "{{count}} player",
|
||||
"count.teams_other": "{{count}} teams",
|
||||
"count.players_other": "{{count}} players",
|
||||
|
||||
"forms.dates": "Dates",
|
||||
"forms.bracketUrl": "Bracket URL",
|
||||
|
||||
Reference in New Issue
Block a user