quad table

This commit is contained in:
Kalle (Sendou)
2020-12-12 14:33:16 +02:00
parent 2c409bb6c7
commit c01967113c
19 changed files with 180 additions and 32 deletions

View File

@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname $0)/_/husky.sh"
npm run prettier:pre-commit && npm run ex:pre-commit
npm run ex:pre-commit

View File

@@ -1,3 +1,3 @@
.next
prisma/migrations
locales/**/*
locales/**/*.js

View File

@@ -0,0 +1,126 @@
import { Box, Flex, Text } from "@chakra-ui/react";
import { Trans } from "@lingui/macro";
import { useLingui } from "@lingui/react";
import { Player } from "@prisma/client";
import MyLink from "components/common/MyLink";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "components/common/Table";
import WeaponImage from "components/common/WeaponImage";
import { getRankingString } from "lib/strings";
import { useMyTheme } from "lib/useMyTheme";
import { GetPlayerWithPlacementsData } from "prisma/queries/getPlayerWithPlacements";
interface Props {
player: NonNullable<GetPlayerWithPlacementsData>;
}
const QuadTable: React.FC<Props> = ({ player }) => {
const { i18n } = useLingui();
const { gray } = useMyTheme();
return (
<Table maxW="50rem">
<TableHead>
<TableRow>
<TableHeader />
<TableHeader>
<Trans>Date</Trans>
</TableHeader>
<TableHeader>
<Trans>Power</Trans>
</TableHeader>
<TableHeader>
<Trans>Weapon</Trans>
</TableHeader>
<TableHeader>
<Trans>Mates</Trans>
</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{player.leaguePlacements.QUAD.map(({ squad }, index) => {
return (
<TableRow key={squad.id}>
<TableCell color={gray}>{getRankingString(index + 1)}</TableCell>
<TableCell>
{new Date(squad.startTime).toLocaleString(i18n.locale, {
month: "numeric",
year: "numeric",
hour: "numeric",
day: "numeric",
})}
</TableCell>
<TableCell>
<Text fontWeight="bold">{squad.leaguePower}</Text>
</TableCell>
<TableCell>
<WeaponImage
name={
squad.members.find(
(member) =>
member.player.switchAccountId === player.switchAccountId
)!.weapon
}
size={32}
/>
</TableCell>
<TableCell>
<LeagueMates
mates={squad.members.filter(
(member) =>
member.player.switchAccountId !== player.switchAccountId
)}
/>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
};
function LeagueMates({
mates,
}: {
mates: {
player: Player & {
user: {
username: string;
discriminator: string;
discordId: string;
discordAvatar: string | null;
} | null;
};
weapon: string;
}[];
}) {
return (
<>
{mates.map((mate) => (
<Flex align="center" key={mate.player.switchAccountId}>
<WeaponImage name={mate.weapon} size={32} />
<Box ml={2}>
<MyLink
href={
mate.player.user
? `/u/${mate.player.user.discordId}`
: `/player/${mate.player.switchAccountId}`
}
prefetch={false}
>
{mate.player.name ?? "???"}
</MyLink>
</Box>
</Flex>
))}
</>
);
}
export default QuadTable;

View File

@@ -18,10 +18,10 @@ import { useMyTheme } from "lib/useMyTheme";
import { GetPlayerWithPlacementsData } from "prisma/queries/getPlayerWithPlacements";
interface Props {
placements: GetPlayerWithPlacementsData;
player: NonNullable<GetPlayerWithPlacementsData>;
}
const TwinTable: React.FC<Props> = ({ placements }) => {
const TwinTable: React.FC<Props> = ({ player }) => {
const { i18n } = useLingui();
const { gray } = useMyTheme();
return (
@@ -47,7 +47,7 @@ const TwinTable: React.FC<Props> = ({ placements }) => {
</TableRow>
</TableHead>
<TableBody>
{placements?.leaguePlacements.TWIN.map(({ squad }, index) => {
{player.leaguePlacements.TWIN.map(({ squad }, index) => {
return (
<TableRow key={squad.id}>
<TableCell color={gray}>{getRankingString(index + 1)}</TableCell>
@@ -67,8 +67,7 @@ const TwinTable: React.FC<Props> = ({ placements }) => {
name={
squad.members.find(
(member) =>
member.player.switchAccountId ===
placements.switchAccountId
member.player.switchAccountId === player.switchAccountId
)!.weapon
}
size={32}
@@ -79,8 +78,7 @@ const TwinTable: React.FC<Props> = ({ placements }) => {
mate={
squad.members.find(
(member) =>
member.player.switchAccountId !==
placements.switchAccountId
member.player.switchAccountId !== player.switchAccountId
)!.player
}
/>
@@ -90,8 +88,7 @@ const TwinTable: React.FC<Props> = ({ placements }) => {
name={
squad.members.find(
(member) =>
member.player.switchAccountId !==
placements.switchAccountId
member.player.switchAccountId !== player.switchAccountId
)!.weapon
}
size={32}
@@ -120,7 +117,7 @@ function LeagueMate({
if (!mate.user && !mate.name) return <>{"???"}</>;
if (mate.user)
return (
<MyLink href={`/u/${mate.user.discordId}`}>
<MyLink href={`/u/${mate.user.discordId}`} prefetch={false}>
<Flex alignItems="center">
<UserAvatar user={mate.user} size="sm" mr={2} />
{mate.user.username}
@@ -128,7 +125,11 @@ function LeagueMate({
</MyLink>
);
return <MyLink href={`/player/${mate.switchAccountId}`}>{mate.name}</MyLink>;
return (
<MyLink href={`/player/${mate.switchAccountId}`} prefetch={false}>
{mate.name}
</MyLink>
);
}
export default TwinTable;

View File

@@ -15,10 +15,10 @@ import { useMyTheme } from "lib/useMyTheme";
import { GetPlayerWithPlacementsData } from "prisma/queries/getPlayerWithPlacements";
interface Props {
placements: NonNullable<GetPlayerWithPlacementsData>["placements"];
player: NonNullable<GetPlayerWithPlacementsData>;
}
const XRankTable: React.FC<Props> = ({ placements }) => {
const XRankTable: React.FC<Props> = ({ player }) => {
const { gray } = useMyTheme();
return (
@@ -47,7 +47,7 @@ const XRankTable: React.FC<Props> = ({ placements }) => {
</TableRow>
</TableHead>
<TableBody>
{placements.map((record) => {
{player.placements.map((record) => {
return (
<TableRow key={record.id}>
<TableCell color={gray}>

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Waffe",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Name",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Όπλο",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Όνομα",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "Date",
"Power": "Power",
"Weapon": "Weapon",
"Mates": "Mates",
"Mate": "Mate",
"Mate's weapon": "Mate's weapon",
"Name": "Name",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "Search for users by their Discord tag or Twitter name",
"Top 500 Tier Lists": "Top 500 Tier Lists",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": "Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown."
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Arma",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Nombre",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Arme",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Nom",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Arma",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Nome",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "무기",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "이름",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Arma",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Nome",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -52,6 +52,7 @@
"Date": "",
"Power": "",
"Weapon": "Vapen",
"Mates": "",
"Mate": "",
"Mate's weapon": "",
"Name": "Namn",
@@ -244,4 +245,4 @@
"Search for users by their Discord tag or Twitter name": "",
"Top 500 Tier Lists": "",
"Here you can find X Rank Top 500 usage tier lists. For example for a weapon to be in the X tier it needs at least 30 placements in that mode that month. Below the weapon count and X Power average are shown.": ""
}
}

View File

@@ -1,5 +1,6 @@
import { t } from "@lingui/macro";
import Breadcrumbs from "components/common/Breadcrumbs";
import QuadTable from "components/player/QuadTable";
import TwinTable from "components/player/TwinTable";
import XRankTable from "components/player/XRankTable";
import { GetStaticPaths, GetStaticProps } from "next";
@@ -17,7 +18,9 @@ interface Props {
const PlayerPage = (props: Props) => {
const player = props.player!;
const [tab, setTab] = useState<"XRANK" | "TWIN" | "QUAD">("XRANK");
const [tab, setTab] = useState<"XRANK" | "TWIN" | "QUAD">("QUAD");
console.log({ player });
return (
<>
@@ -28,8 +31,9 @@ const PlayerPage = (props: Props) => {
]}
/>
{tab === "XRANK" && <XRankTable placements={player.placements} />}
{tab === "TWIN" && <TwinTable placements={player} />}
{tab === "XRANK" && <XRankTable player={player} />}
{tab === "TWIN" && <TwinTable player={player} />}
{tab === "QUAD" && <QuadTable player={player} />}
</>
);

View File

@@ -28,7 +28,6 @@ export const getPlayerWithPlacements = async (switchAccountId: string) => {
};
function getTopLeaguePlacements() {
// TODO: remove duplicates
const result: { TWIN: LeaguePlacementArray; QUAD: LeaguePlacementArray } = {
TWIN: [],
QUAD: [],
@@ -36,7 +35,13 @@ export const getPlayerWithPlacements = async (switchAccountId: string) => {
if (!player) return result;
const timeScoreSet = new Set<string>();
for (const placement of player.leaguePlacements) {
const identifier =
placement.squad.startTime.toString() + placement.squad.leaguePower;
if (timeScoreSet.has(identifier)) continue;
timeScoreSet.add(identifier);
result[placement.squad.members.length === 2 ? "TWIN" : "QUAD"].push(
placement
);