From 463f0fada24b012d00375285aec3a6889f30b6db Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Tue, 9 Aug 2022 23:44:55 +0300 Subject: [PATCH] Event results initial table component --- TODO.md | 1 + app/components/Avatar.tsx | 5 +- app/db/models/calendar.server.ts | 38 +++++++++++-- app/routes/calendar/$id/index.tsx | 89 ++++++++++++++++++++++++------- app/styles/calendar-event.css | 11 ++++ 5 files changed, 120 insertions(+), 24 deletions(-) diff --git a/TODO.md b/TODO.md index cf299de2d..cd8bbd06d 100644 --- a/TODO.md +++ b/TODO.md @@ -23,6 +23,7 @@ Calendar ## Other +- [ ] Refactor Avatar to accept player object instead of separate fields - [ ] Redirect to event page after submitting results - [x] date input take in account time zone difference between server and client - [x] User selector allow passing users from top level diff --git a/app/components/Avatar.tsx b/app/components/Avatar.tsx index 637693160..059d9582a 100644 --- a/app/components/Avatar.tsx +++ b/app/components/Avatar.tsx @@ -3,11 +3,12 @@ import type { User } from "~/db/types"; import * as React from "react"; const dimensions = { + xxs: 24, xs: 36, sm: 44, md: 81, lg: 125, -}; +} as const; export function Avatar({ discordId, @@ -17,7 +18,7 @@ export function Avatar({ ...rest }: Pick & { className?: string; - size: "xs" | "sm" | "md" | "lg"; + size: keyof typeof dimensions; } & React.ButtonHTMLAttributes) { const [isErrored, setIsErrored] = React.useState(false); // TODO: just show text... my profile? diff --git a/app/db/models/calendar.server.ts b/app/db/models/calendar.server.ts index c2724b2a7..eabaeeb4b 100644 --- a/app/db/models/calendar.server.ts +++ b/app/db/models/calendar.server.ts @@ -212,12 +212,20 @@ const findWinnersByEventIdStm = sql.prepare(` "CalendarEventResultTeam"."name" as "teamName", "CalendarEventResultTeam"."placement", "CalendarEventResultPlayer"."userId" as "playerId", - "CalendarEventResultPlayer"."name" as "playerName" + "CalendarEventResultPlayer"."name" as "playerName", + "User"."discordName" as "playerDiscordName", + "User"."discordDiscriminator" as "playerDiscordDiscriminator", + "User"."discordId" as "playerDiscordId", + "User"."discordAvatar" as "playerDiscordAvatar" from "CalendarEventResultTeam" join "CalendarEventResultPlayer" on "CalendarEventResultPlayer"."teamId" = "CalendarEventResultTeam"."id" + join + "User" + on + "User"."id" = "CalendarEventResultPlayer"."userId" where "CalendarEventResultTeam"."eventId" = $eventId order by "placement" asc `); @@ -228,18 +236,40 @@ export function findResultsByEventId(eventId: CalendarEvent["id"]) { teamName: CalendarEventResultTeam["name"]; placement: CalendarEventResultTeam["placement"]; playerId: CalendarEventResultPlayer["userId"]; - playerName: CalendarEventResultPlayer["name"]; + playerName: CalendarEventResultPlayer["name"] | null; + playerDiscordName: User["discordName"] | null; + playerDiscordDiscriminator: User["discordDiscriminator"] | null; + playerDiscordId: User["discordId"] | null; + playerDiscordAvatar: User["discordAvatar"]; }>; const result: Array<{ teamName: CalendarEventResultTeam["name"]; placement: CalendarEventResultTeam["placement"]; - players: Array; + players: Array< + | string + | Pick< + User, + | "id" + | "discordId" + | "discordName" + | "discordDiscriminator" + | "discordAvatar" + > + >; }> = []; for (const row of rows) { const team = result.find((team) => team.teamName === row.teamName); - const player = row.playerName ?? { id: row.playerId! }; + const player = row.playerName ?? { + // player name and user id are mutually exclusive + // also if user id exists we know a joined user also has to exist + id: row.playerId!, + discordId: row.playerDiscordId!, + discordName: row.playerDiscordName!, + discordDiscriminator: row.playerDiscordDiscriminator!, + discordAvatar: row.playerDiscordAvatar, + }; if (team) { team.players.push(player); diff --git a/app/routes/calendar/$id/index.tsx b/app/routes/calendar/$id/index.tsx index 80f41d05c..c1ebaf9c5 100644 --- a/app/routes/calendar/$id/index.tsx +++ b/app/routes/calendar/$id/index.tsx @@ -6,6 +6,7 @@ import { } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import type { UseDataFunctionReturn } from "@remix-run/react/dist/components"; +import { Link } from "@remix-run/react/dist/components"; import clsx from "clsx"; import * as React from "react"; import { useTranslation } from "react-i18next"; @@ -29,6 +30,7 @@ import { calendarEditPage, calendarReportWinnersPage, resolveBaseUrl, + userPage, } from "~/utils/urls"; import { actualNumber, id } from "~/utils/zod"; import { Tags } from "../components/Tags"; @@ -69,7 +71,7 @@ export const loader = async ({ params, request }: LoaderArgs) => { export default function CalendarEventPage() { const user = useUser(); - const { event, badgePrizes } = useLoaderData(); + const data = useLoaderData(); const { i18n } = useTranslation(); const isMounted = useIsMounted(); @@ -77,11 +79,11 @@ export default function CalendarEventPage() {
- {event.startTimes.map((startTime, i) => ( + {data.event.startTimes.map((startTime, i) => ( Day {i + 1} @@ -105,13 +107,13 @@ export default function CalendarEventPage() {
-

{event.name}

- +

{data.event.name}

+
- {event.discordUrl ? ( + {data.event.discordUrl ? ( ) : null} - {resolveBaseUrl(event.bracketUrl)} + {resolveBaseUrl(data.event.bracketUrl)} - {canEditCalendarEvent({ user, event }) && ( + {canEditCalendarEvent({ user, event: data.event }) && ( Edit @@ -138,12 +140,12 @@ export default function CalendarEventPage() { )} {canReportCalendarEventWinners({ user, - event, - startTimes: event.startTimes, + event: data.event, + startTimes: data.event.startTimes, }) && ( Report winners @@ -152,17 +154,68 @@ export default function CalendarEventPage() {
+
- {discordFullName(event)} + {discordFullName(data.event)}
-
{event.description}
+
{data.event.description}
); } + +function Results() { + const data = useLoaderData(); + + return ( +
+
{data.event.participantCount} teams participated
+ + + + + + + + + + {data.results.map((result, i) => ( + + + + + + ))} + +
PlacementNameMembers
{result.placement}{result.teamName} +
    + {result.players.map((player) => ( +
  • + {typeof player === "string" ? ( + player + ) : ( + + {" "} + {discordFullName(player)} + + )} +
  • + ))} +
+
+
+ ); +} diff --git a/app/styles/calendar-event.css b/app/styles/calendar-event.css index f086228c6..7f1dbb081 100644 --- a/app/styles/calendar-event.css +++ b/app/styles/calendar-event.css @@ -24,3 +24,14 @@ font-weight: var(--semi-bold); gap: var(--s-1); } + +.event__results-table { + font-size: var(--fonts-sm); +} + +.event__results-players { + display: flex; + flex-wrap: wrap; + gap: var(--s-2); + list-style: none; +}