diff --git a/app/db/models/calendar/findTournamentTeamMemberCountsByEventId.sql b/app/db/models/calendar/findTournamentTeamMemberCountsByEventId.sql new file mode 100644 index 000000000..8484305ff --- /dev/null +++ b/app/db/models/calendar/findTournamentTeamMemberCountsByEventId.sql @@ -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"; diff --git a/app/db/models/calendar/queries.server.ts b/app/db/models/calendar/queries.server.ts index 8300dae01..aed16ff69 100644 --- a/app/db/models/calendar/queries.server.ts +++ b/app/db/models/calendar/queries.server.ts @@ -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 & { 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); diff --git a/app/features/tournament/queries/participantTwitchUsersByTournamentId.server.ts b/app/features/tournament/queries/participantTwitchUsersByTournamentId.server.ts index 3b2c74774..a6efb5994 100644 --- a/app/features/tournament/queries/participantTwitchUsersByTournamentId.server.ts +++ b/app/features/tournament/queries/participantTwitchUsersByTournamentId.server.ts @@ -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 `); diff --git a/app/routes/calendar/index.tsx b/app/routes/calendar/index.tsx index 96e9d782b..78706c2e3 100644 --- a/app/routes/calendar/index.tsx +++ b/app/routes/calendar/index.tsx @@ -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({
- -

- {calendarEvent.name}{" "} - {calendarEvent.nthAppearance > 1 ? ( - - {t("day", { - number: calendarEvent.nthAppearance, - })} - - ) : null} -

- +
+ +

+ {calendarEvent.name}{" "} + {calendarEvent.nthAppearance > 1 ? ( + + {t("day", { + number: calendarEvent.nthAppearance, + })} + + ) : null} +

+ + {calendarEvent.participantCounts && + calendarEvent.participantCounts.teams > 0 ? ( +
+ {" "} + {t("count.teams", { + count: calendarEvent.participantCounts.teams, + })}{" "} + /{" "} + {t("count.players", { + count: calendarEvent.participantCounts.players, + })} +
+ ) : null} +
svg { + width: 1rem; + margin-block-end: 1px; +} + .calendar__event__bottom-info-container { display: flex; align-items: center; diff --git a/public/locales/en/calendar.json b/public/locales/en/calendar.json index 31a00e54b..5ef883dde 100644 --- a/public/locales/en/calendar.json +++ b/public/locales/en/calendar.json @@ -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",