mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-26 04:57:08 -05:00
user page player / player page backend
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname $0)/_/husky.sh"
|
||||
|
||||
npm run ex:pre-commit && npm run prettier:pre-commit
|
||||
npm run prettier:pre-commit && npm run ex:pre-commit
|
||||
@@ -12,10 +12,10 @@ import {
|
||||
import WeaponImage from "components/common/WeaponImage";
|
||||
import { getRankingString } from "lib/strings";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
import { GetPlayersTop500Placements } from "prisma/queries/getPlayersTop500Placements";
|
||||
import { GetPlayerWithPlacementsData } from "prisma/queries/getPlayerWithPlacements";
|
||||
|
||||
interface Props {
|
||||
placements: NonNullable<GetPlayersTop500Placements>["placements"];
|
||||
placements: NonNullable<GetPlayerWithPlacementsData>["placements"];
|
||||
}
|
||||
|
||||
const PlayerPage: React.FC<Props> = ({ placements }) => {
|
||||
|
||||
@@ -4,14 +4,16 @@ import PlayerTable from "components/player/PlayerTable";
|
||||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import prisma from "prisma/client";
|
||||
import {
|
||||
GetPlayersTop500Placements,
|
||||
getPlayersTop500Placements,
|
||||
} from "prisma/queries/getPlayersTop500Placements";
|
||||
getPlayerWithPlacements,
|
||||
GetPlayerWithPlacementsData,
|
||||
} from "prisma/queries/getPlayerWithPlacements";
|
||||
|
||||
const PlayerPage = ({ player }: Props) => {
|
||||
// TODO: spinner
|
||||
if (!player) return null;
|
||||
|
||||
console.log({ player });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Breadcrumbs
|
||||
@@ -42,17 +44,17 @@ export const getStaticPaths: GetStaticPaths = async () => {
|
||||
};
|
||||
|
||||
interface Props {
|
||||
player: GetPlayersTop500Placements;
|
||||
player: GetPlayerWithPlacementsData;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
const player = await getPlayersTop500Placements(params!.id as string);
|
||||
const player = await getPlayerWithPlacements(params!.id as string);
|
||||
|
||||
if (!player || !player.placements) return { notFound: true };
|
||||
|
||||
return {
|
||||
props: {
|
||||
player: { ...player, leaguePlacements: null } as any,
|
||||
player: player,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ import useUser from "lib/useUser";
|
||||
import { isCustomUrl } from "lib/validators/profile";
|
||||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import prisma from "prisma/client";
|
||||
import { getPlayersTop500Placements } from "prisma/queries/getPlayersTop500Placements";
|
||||
import { getPlayersPeak } from "prisma/queries/getPlayersPeak";
|
||||
import {
|
||||
getUserByIdentifier,
|
||||
GetUserByIdentifierData,
|
||||
@@ -192,38 +192,15 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
};
|
||||
}
|
||||
|
||||
const peakXPowers: Partial<Record<RankedMode, number>> = {};
|
||||
let peakLeaguePowers: Partial<Record<LeagueType, number>> = {};
|
||||
|
||||
if (!!user.player?.switchAccountId) {
|
||||
const player = await getPlayersTop500Placements(
|
||||
user.player.switchAccountId
|
||||
);
|
||||
|
||||
for (const placement of player!.placements) {
|
||||
peakXPowers[placement.mode] = Math.max(
|
||||
peakXPowers[placement.mode] ?? 0,
|
||||
placement.xPower
|
||||
);
|
||||
}
|
||||
|
||||
peakLeaguePowers = player!.leaguePlacements.reduce(
|
||||
(acc, cur) => {
|
||||
acc[cur.squad.type] = Math.max(
|
||||
acc[cur.squad.type],
|
||||
cur.squad.leaguePower
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
{ TWIN: -1, QUAD: -1 }
|
||||
);
|
||||
}
|
||||
const peak = user.player?.switchAccountId
|
||||
? await getPlayersPeak(user.player.switchAccountId)
|
||||
: { peakXPowers: {}, peakLeaguePowers: {} };
|
||||
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
peakXPowers,
|
||||
peakLeaguePowers,
|
||||
peakXPowers: peak.peakXPowers,
|
||||
peakLeaguePowers: peak.peakLeaguePowers,
|
||||
},
|
||||
revalidate: 1,
|
||||
};
|
||||
|
||||
85
prisma/queries/getPlayerWithPlacements.ts
Normal file
85
prisma/queries/getPlayerWithPlacements.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import prisma from "prisma/client";
|
||||
|
||||
export type GetPlayerWithPlacementsData = Prisma.PromiseReturnType<
|
||||
typeof getPlayerWithPlacements
|
||||
>;
|
||||
|
||||
export const getPlayerWithPlacements = async (switchAccountId: string) => {
|
||||
const player = await getPlayer();
|
||||
|
||||
if (!player) return null;
|
||||
|
||||
type PlayerWithPlacements = Prisma.PromiseReturnType<typeof getPlayer>;
|
||||
type LeaguePlacementArray = NonNullable<PlayerWithPlacements>["leaguePlacements"];
|
||||
|
||||
return {
|
||||
...player,
|
||||
placements: player.placements.sort((a, b) => {
|
||||
if (a.year !== b.year) return b.year - a.year;
|
||||
if (a.month !== b.month) return b.month - a.month;
|
||||
|
||||
const modes = ["SZ", "TC", "RM", "CB"];
|
||||
return modes.indexOf(a.mode) - modes.indexOf(b.mode);
|
||||
}),
|
||||
leaguePlacements: JSON.parse(
|
||||
JSON.stringify(getTopLeaguePlacements())
|
||||
) as ReturnType<typeof getTopLeaguePlacements>,
|
||||
};
|
||||
|
||||
function getTopLeaguePlacements() {
|
||||
const result: { TWIN: LeaguePlacementArray; QUAD: LeaguePlacementArray } = {
|
||||
TWIN: [],
|
||||
QUAD: [],
|
||||
};
|
||||
|
||||
if (!player) return result;
|
||||
|
||||
for (const placement of player.leaguePlacements) {
|
||||
result[placement.squad.members.length === 2 ? "TWIN" : "QUAD"].push(
|
||||
placement
|
||||
);
|
||||
}
|
||||
|
||||
result.TWIN.sort((a, b) => b.squad.leaguePower - a.squad.leaguePower);
|
||||
result.QUAD.sort((a, b) => b.squad.leaguePower - a.squad.leaguePower);
|
||||
|
||||
return { TWIN: result.TWIN.slice(0, 10), QUAD: result.QUAD.slice(0, 10) };
|
||||
}
|
||||
|
||||
function getPlayer() {
|
||||
return prisma.player.findUnique({
|
||||
where: { switchAccountId },
|
||||
include: {
|
||||
leaguePlacements: {
|
||||
select: {
|
||||
squad: {
|
||||
select: {
|
||||
startTime: true,
|
||||
leaguePower: true,
|
||||
members: {
|
||||
select: {
|
||||
weapon: true,
|
||||
player: {
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
username: true,
|
||||
discriminator: true,
|
||||
discordId: true,
|
||||
discordAvatar: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
placements: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
47
prisma/queries/getPlayersPeak.ts
Normal file
47
prisma/queries/getPlayersPeak.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Prisma, RankedMode } from "@prisma/client";
|
||||
import prisma from "prisma/client";
|
||||
|
||||
export type GetPlayersPeakData = Prisma.PromiseReturnType<
|
||||
typeof getPlayersPeak
|
||||
>;
|
||||
|
||||
export const getPlayersPeak = async (switchAccountId: string) => {
|
||||
const player = await prisma.player.findUnique({
|
||||
where: { switchAccountId },
|
||||
select: {
|
||||
placements: {
|
||||
select: {
|
||||
xPower: true,
|
||||
mode: true,
|
||||
},
|
||||
},
|
||||
leaguePlacements: {
|
||||
select: { squad: { select: { leaguePower: true, type: true } } },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!player) return { peakXPowers: {}, peakLeaguePowers: {} };
|
||||
|
||||
const peakXPowers: Partial<Record<RankedMode, number>> = {};
|
||||
|
||||
for (const placement of player.placements) {
|
||||
peakXPowers[placement.mode] = Math.max(
|
||||
peakXPowers[placement.mode] ?? 0,
|
||||
placement.xPower
|
||||
);
|
||||
}
|
||||
|
||||
const peakLeaguePowers = player.leaguePlacements.reduce(
|
||||
(acc: { TWIN?: number; QUAD?: number }, cur) => {
|
||||
acc[cur.squad.type] = Math.max(
|
||||
acc[cur.squad.type] ?? 0,
|
||||
cur.squad.leaguePower
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
{ TWIN: undefined, QUAD: undefined }
|
||||
);
|
||||
|
||||
return { peakXPowers, peakLeaguePowers };
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import prisma from "prisma/client";
|
||||
|
||||
export type GetPlayersTop500Placements = Prisma.PromiseReturnType<
|
||||
typeof getPlayersTop500Placements
|
||||
>;
|
||||
|
||||
export const getPlayersTop500Placements = async (switchAccountId: string) => {
|
||||
const player = await prisma.player.findUnique({
|
||||
where: { switchAccountId },
|
||||
include: {
|
||||
leaguePlacements: { include: { squad: { include: { members: true } } } },
|
||||
placements: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!player) return null;
|
||||
|
||||
return {
|
||||
...player,
|
||||
placements: player.placements.sort((a, b) => {
|
||||
if (a.year !== b.year) return b.year - a.year;
|
||||
if (a.month !== b.month) return b.month - a.month;
|
||||
|
||||
const modes = ["SZ", "TC", "RM", "CB"];
|
||||
return modes.indexOf(a.mode) - modes.indexOf(b.mode);
|
||||
}),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user