ladder matches preliminary UI

This commit is contained in:
Kalle (Sendou)
2021-02-04 20:37:22 +02:00
parent 5f97557863
commit a4e4c96128
4 changed files with 182 additions and 77 deletions

View File

@@ -0,0 +1,72 @@
import { Box, BoxProps, Flex, HStack } from "@chakra-ui/react";
import SubText from "components/common/SubText";
import TwitterAvatar from "components/common/TwitterAvatar";
import UserAvatar from "components/common/UserAvatar";
import { useMyTheme } from "hooks/common";
import { Unpacked } from "lib/types";
import { GetAllLadderRegisteredTeamsData } from "prisma/queries/getAllLadderRegisteredTeams";
interface Props {
roster: Unpacked<GetAllLadderRegisteredTeamsData>["roster"];
}
const LadderTeam: React.FC<Props & BoxProps> = ({ roster, ...props }) => {
const { gray } = useMyTheme();
const teamTuple = roster
.filter((member) => member.team)
.map((member) => member.team)
.reduce(
(
acc: [
{
name: string;
twitterName: string;
nameForUrl: string;
},
number
][],
cur
) => {
const tuple = acc.find(([{ name }]) => name === cur!.name);
if (tuple) tuple[1]++;
acc.push([{ ...(cur as any) }, 1]);
return acc;
},
[]
)
.find((tuple) => tuple[1] >= 3);
return (
<Box {...props}>
{teamTuple && roster.length === 4 ? (
<Flex fontWeight="bold" align="center">
{teamTuple[0].twitterName && (
<TwitterAvatar
twitterName={teamTuple[0].twitterName}
size="sm"
mr={1}
/>
)}
{teamTuple[0].name}
{teamTuple[1] === 3 && roster.length >= 4 && (
<SubText ml={1}>+1</SubText>
)}
</Flex>
) : (
<HStack>
{roster.map((member) => (
<UserAvatar key={member.id} user={member} size="sm" />
))}
</HStack>
)}
<Box color={gray} fontSize="sm" mt={2}>
{roster
.map((user) => `${user.username}#${user.discriminator}`)
.join(", ")}
</Box>
</Box>
);
};
export default LadderTeam;

View File

@@ -0,0 +1,34 @@
import { Box } from "@chakra-ui/react";
import { Unpacked } from "lib/types";
import { GetLadderDayData } from "prisma/queries/getLadderDay";
import LadderTeam from "./LadderTeam";
interface Props {
matchUp: Unpacked<NonNullable<GetLadderDayData>["matches"]>;
}
const MatchUp: React.FC<Props> = ({ matchUp }) => {
return (
<>
<Box>
<LadderTeam
roster={matchUp.players
.filter((player) => player.team === "ALPHA")
.map((player) => player.user)}
/>
</Box>
<Box fontSize="xl">
{matchUp.teamAScore}-{matchUp.teamBScore}
</Box>
<Box>
<LadderTeam
roster={matchUp.players
.filter((player) => player.team === "BRAVO")
.map((player) => player.user)}
/>
</Box>
</>
);
};
export default MatchUp;

View File

@@ -1,10 +1,11 @@
import { Box, Flex, HStack } from "@chakra-ui/react";
import { Box, Center, Flex, Grid, Heading } from "@chakra-ui/react";
import { t, Trans } from "@lingui/macro";
import Breadcrumbs from "components/common/Breadcrumbs";
import ModeImage from "components/common/ModeImage";
import MyContainer from "components/common/MyContainer";
import SubText from "components/common/SubText";
import TwitterAvatar from "components/common/TwitterAvatar";
import UserAvatar from "components/common/UserAvatar";
import LadderTeam from "components/play/LadderTeam";
import MatchUp from "components/play/MatchUp";
import RegisterHeader from "components/play/RegisterHeader";
import { useMyTheme } from "hooks/common";
import { useLadderTeams } from "hooks/play";
@@ -14,6 +15,7 @@ import { GetStaticProps } from "next";
import prisma from "prisma/client";
import { getAllLadderRegisteredTeamsForMatches } from "prisma/queries/getAllLadderRegisteredTeamsForMatches";
import { getLadderDay, GetLadderDayData } from "prisma/queries/getLadderDay";
import { Fragment } from "react";
interface Props {
ladderDay: GetLadderDayData;
@@ -23,91 +25,79 @@ const PlayPage: React.FC<Props> = ({ ladderDay }) => {
const { gray } = useMyTheme();
const { data } = useLadderTeams(!ladderDay);
console.log({ ladderDay });
return (
<MyContainer>
<Breadcrumbs pages={[{ name: t`Play` }]} />
<Box fontSize="lg" fontWeight="bold">
{ladderDay ? (
<>Next event: {new Date(ladderDay.date).toLocaleString()}</>
) : (
<>
<Trans>
Next ladder date is not confirmed. Follow this page for updates!
</Trans>
</>
)}
</Box>
{!ladderDay?.matches.length && (
<Box fontSize="lg" fontWeight="bold">
{ladderDay ? (
<>Next event: {new Date(ladderDay.date).toLocaleString()}</>
) : (
<>
<Trans>
Next ladder date is not confirmed. Follow this page for updates!
</Trans>
</>
)}
</Box>
)}
{ladderDay && ladderDay.matches.length === 0 && (
<>
<RegisterHeader />
<Box mt={4}>
{data
?.sort((a, b) => b.roster.length - a.roster.length)
.map((team) => {
const teamTuple = team.roster
.filter((member) => member.team)
.map((member) => member.team)
.reduce(
(
acc: [
{
name: string;
twitterName: string;
nameForUrl: string;
},
number
][],
cur
) => {
const tuple = acc.find(
([{ name }]) => name === cur!.name
);
if (tuple) tuple[1]++;
acc.push([{ ...(cur as any) }, 1]);
return acc;
},
[]
)
.find((tuple) => tuple[1] >= 3);
return (
<Box key={team.id} my={4}>
{teamTuple && team.roster.length === 4 ? (
<Flex fontWeight="bold" align="center">
{teamTuple[0].twitterName && (
<TwitterAvatar
twitterName={teamTuple[0].twitterName}
size="sm"
mr={1}
/>
)}
{teamTuple[0].name}
{teamTuple[1] === 3 && team.roster.length >= 4 && (
<SubText ml={1}>+1</SubText>
)}
</Flex>
) : (
<HStack>
{team.roster.map((member) => (
<UserAvatar key={member.id} user={member} size="sm" />
))}
</HStack>
)}
<Box color={gray} fontSize="sm" mt={2}>
{team.roster
.map((user) => `${user.username}#${user.discriminator}`)
.join(", ")}
</Box>
</Box>
);
})}
.map((team) => (
<LadderTeam key={team.id} roster={team.roster} my={2} />
))}
</Box>
</>
)}
{ladderDay && ladderDay.matches.length > 0 && (
<>{ladderDay.matches.length} matches pending</>
<>
{[1, 2].map((round) => (
<Fragment key={round}>
<Heading size="md" fontFamily="'Rubik', sans-serif">
Round {round}
</Heading>
<SubText mt={4}>Maplist</SubText>
{(ladderDay.matches.find((match) => match.order === round)!
.maplist as any[]).map(({ stage, mode }, i) => {
return (
<Flex
key={stage + mode}
align="center"
color={gray}
fontSize="sm"
my={2}
>
{i + 1}){" "}
<Center mx={1}>
<ModeImage mode={mode} size={24} />
</Center>{" "}
{stage}
</Flex>
);
})}
<Grid
templateColumns="3fr 1fr 3fr"
placeItems="center"
rowGap={4}
mt={8}
mb={8}
>
{ladderDay.matches
.filter((match) => match.order === round)
.map((match) => (
<MatchUp
key={match.players[0].user.discordId}
matchUp={match}
/>
))}
</Grid>
</Fragment>
))}
</>
)}
</MyContainer>
);

View File

@@ -18,12 +18,21 @@ export const getLadderDay = async () => {
teamBScore: true,
players: {
select: {
team: true,
user: {
select: {
username: true,
id: true,
discordAvatar: true,
discriminator: true,
discordId: true,
discriminator: true,
username: true,
team: {
select: {
name: true,
nameForUrl: true,
twitterName: true,
},
},
},
},
},