mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-09 04:02:40 -05:00
player page skeleton
This commit is contained in:
parent
8266b5418a
commit
69133195bd
|
|
@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
|
|||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
loading: boolean;
|
||||
loading?: boolean;
|
||||
error?: ApolloError;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import { Image, ImageProps } from "@chakra-ui/core";
|
||||
import Image from "next/image";
|
||||
|
||||
interface ModeImageProps {
|
||||
mode: "SZ" | "TC" | "RM" | "CB";
|
||||
size: 32 | 64 | 128;
|
||||
}
|
||||
|
||||
const ModeImage: React.FC<ModeImageProps & ImageProps> = ({
|
||||
mode,
|
||||
...props
|
||||
}) => {
|
||||
return <Image src={`/modes/${mode}.png`} {...props} />;
|
||||
const ModeImage: React.FC<ModeImageProps> = ({ mode, size }) => {
|
||||
return <Image src={`/modes/${mode}.png`} width={size} height={size} />;
|
||||
};
|
||||
|
||||
export default ModeImage;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ export type Query = {
|
|||
__typename?: 'Query';
|
||||
getUserByIdentifier?: Maybe<User>;
|
||||
getXRankPlacements: Array<XRankPlacement>;
|
||||
getPlayersXRankPlacements: Array<XRankPlacement>;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -52,6 +53,11 @@ export type QueryGetXRankPlacementsArgs = {
|
|||
mode: RankedMode;
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetPlayersXRankPlacementsArgs = {
|
||||
playerId: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateUserProfileInput = {
|
||||
twitterName?: Maybe<Scalars['String']>;
|
||||
customUrlPath?: Maybe<Scalars['String']>;
|
||||
|
|
@ -124,6 +130,26 @@ export type PlayerIdModeMonthYearCompoundUniqueInput = {
|
|||
year: Scalars['Int'];
|
||||
};
|
||||
|
||||
export type GetPlayersXRankPlacementsQueryVariables = Exact<{
|
||||
playerId: Scalars['String'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetPlayersXRankPlacementsQuery = (
|
||||
{ __typename?: 'Query' }
|
||||
& { getPlayersXRankPlacements: Array<(
|
||||
{ __typename?: 'XRankPlacement' }
|
||||
& Pick<XRankPlacement, 'id' | 'playerName' | 'ranking' | 'xPower' | 'weapon' | 'mode' | 'month' | 'year'>
|
||||
& { player: (
|
||||
{ __typename?: 'Player' }
|
||||
& { user?: Maybe<(
|
||||
{ __typename?: 'User' }
|
||||
& Pick<User, 'avatarUrl' | 'fullUsername' | 'profilePath'>
|
||||
)> }
|
||||
) }
|
||||
)> }
|
||||
);
|
||||
|
||||
export type UpdateUserProfileMutationVariables = Exact<{
|
||||
profile: UpdateUserProfileInput;
|
||||
}>;
|
||||
|
|
@ -174,6 +200,53 @@ export type GetXRankPlacementsQuery = (
|
|||
);
|
||||
|
||||
|
||||
export const GetPlayersXRankPlacementsDocument = gql`
|
||||
query getPlayersXRankPlacements($playerId: String!) {
|
||||
getPlayersXRankPlacements(playerId: $playerId) {
|
||||
id
|
||||
playerName
|
||||
ranking
|
||||
xPower
|
||||
weapon
|
||||
mode
|
||||
month
|
||||
year
|
||||
player {
|
||||
user {
|
||||
avatarUrl
|
||||
fullUsername
|
||||
profilePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useGetPlayersXRankPlacementsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useGetPlayersXRankPlacementsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useGetPlayersXRankPlacementsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useGetPlayersXRankPlacementsQuery({
|
||||
* variables: {
|
||||
* playerId: // value for 'playerId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useGetPlayersXRankPlacementsQuery(baseOptions?: Apollo.QueryHookOptions<GetPlayersXRankPlacementsQuery, GetPlayersXRankPlacementsQueryVariables>) {
|
||||
return Apollo.useQuery<GetPlayersXRankPlacementsQuery, GetPlayersXRankPlacementsQueryVariables>(GetPlayersXRankPlacementsDocument, baseOptions);
|
||||
}
|
||||
export function useGetPlayersXRankPlacementsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetPlayersXRankPlacementsQuery, GetPlayersXRankPlacementsQueryVariables>) {
|
||||
return Apollo.useLazyQuery<GetPlayersXRankPlacementsQuery, GetPlayersXRankPlacementsQueryVariables>(GetPlayersXRankPlacementsDocument, baseOptions);
|
||||
}
|
||||
export type GetPlayersXRankPlacementsQueryHookResult = ReturnType<typeof useGetPlayersXRankPlacementsQuery>;
|
||||
export type GetPlayersXRankPlacementsLazyQueryHookResult = ReturnType<typeof useGetPlayersXRankPlacementsLazyQuery>;
|
||||
export type GetPlayersXRankPlacementsQueryResult = Apollo.QueryResult<GetPlayersXRankPlacementsQuery, GetPlayersXRankPlacementsQueryVariables>;
|
||||
export const UpdateUserProfileDocument = gql`
|
||||
mutation UpdateUserProfile($profile: UpdateUserProfileInput!) {
|
||||
updateUserProfile(profile: $profile)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { arg, extendType, intArg, objectType } from "@nexus/schema";
|
||||
import { arg, extendType, intArg, objectType, stringArg } from "@nexus/schema";
|
||||
|
||||
export const XRankPlacmement = objectType({
|
||||
name: "XRankPlacement",
|
||||
|
|
@ -45,7 +45,22 @@ export const Query = extendType({
|
|||
resolve: (_root, args, ctx) => {
|
||||
return ctx.prisma.xRankPlacement.findMany({
|
||||
where: { month: args.month, year: args.year, mode: args.mode },
|
||||
orderBy: [{ ranking: "asc" }, { month: "desc" }, { year: "desc" }],
|
||||
orderBy: { ranking: "asc" },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
t.field("getPlayersXRankPlacements", {
|
||||
type: "XRankPlacement",
|
||||
nullable: false,
|
||||
list: [true],
|
||||
args: {
|
||||
playerId: stringArg({ nullable: false }),
|
||||
},
|
||||
resolve: (_root, args, ctx) => {
|
||||
return ctx.prisma.xRankPlacement.findMany({
|
||||
where: { playerId: args.playerId },
|
||||
orderBy: [{ month: "desc" }, { year: "desc" }],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ export interface NexusGenFieldTypes {
|
|||
youtubeId: string | null; // String
|
||||
}
|
||||
Query: { // field return type
|
||||
getPlayersXRankPlacements: NexusGenRootTypes['XRankPlacement'][]; // [XRankPlacement!]!
|
||||
getUserByIdentifier: NexusGenRootTypes['User'] | null; // User
|
||||
getXRankPlacements: NexusGenRootTypes['XRankPlacement'][]; // [XRankPlacement!]!
|
||||
}
|
||||
|
|
@ -145,6 +146,7 @@ export interface NexusGenFieldTypeNames {
|
|||
youtubeId: 'String'
|
||||
}
|
||||
Query: { // field return type name
|
||||
getPlayersXRankPlacements: 'XRankPlacement'
|
||||
getUserByIdentifier: 'User'
|
||||
getXRankPlacements: 'XRankPlacement'
|
||||
}
|
||||
|
|
@ -185,6 +187,9 @@ export interface NexusGenArgTypes {
|
|||
}
|
||||
}
|
||||
Query: {
|
||||
getPlayersXRankPlacements: { // args
|
||||
playerId: string; // String!
|
||||
}
|
||||
getUserByIdentifier: { // args
|
||||
identifier: string; // String!
|
||||
}
|
||||
|
|
|
|||
61
pages/player/[id].tsx
Normal file
61
pages/player/[id].tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import { PrismaClient } from "@prisma/client";
|
||||
import LoadingBoundary from "components/LoadingBoundary";
|
||||
import {
|
||||
GetPlayersXRankPlacementsDocument,
|
||||
useGetPlayersXRankPlacementsQuery,
|
||||
} from "generated/graphql";
|
||||
import { initializeApollo } from "lib/apollo";
|
||||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import Player from "scenes/Player";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// FIXME: should probably not prerender all player pages -- where userId is not null
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
const players = await prisma.player.findMany({});
|
||||
return {
|
||||
paths: players.map((p) => ({ params: { id: p.playerId } })),
|
||||
fallback: true,
|
||||
};
|
||||
};
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
const apolloClient = initializeApollo(null, { prisma: new PrismaClient() });
|
||||
|
||||
const data = await apolloClient.query({
|
||||
query: GetPlayersXRankPlacementsDocument,
|
||||
variables: {
|
||||
// FIXME: why ! needed?
|
||||
playerId: params!.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log({ params });
|
||||
console.log({ data });
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialApolloState: apolloClient.cache.extract(),
|
||||
playerId: params!.id,
|
||||
},
|
||||
//notfound
|
||||
};
|
||||
};
|
||||
|
||||
const PlayerPage = ({ playerId }: { playerId: string }) => {
|
||||
const router = useRouter();
|
||||
|
||||
const { data } = useGetPlayersXRankPlacementsQuery({
|
||||
variables: { playerId },
|
||||
skip: router.isFallback,
|
||||
});
|
||||
|
||||
return (
|
||||
<LoadingBoundary>
|
||||
<Player placements={data!.getPlayersXRankPlacements} />
|
||||
</LoadingBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayerPage;
|
||||
66
scenes/Player/index.tsx
Normal file
66
scenes/Player/index.tsx
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { Text } from "@chakra-ui/core";
|
||||
import ModeImage from "components/ModeImage";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table";
|
||||
import WeaponImage from "components/WeaponImage";
|
||||
import { GetPlayersXRankPlacementsQuery } from "generated/graphql";
|
||||
import { getRankingString } from "lib/getRankingString";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useMyTheme } from "lib/useMyTheme";
|
||||
|
||||
interface Props {
|
||||
placements: NonNullable<
|
||||
GetPlayersXRankPlacementsQuery["getPlayersXRankPlacements"]
|
||||
>;
|
||||
}
|
||||
|
||||
const PlayerPage: React.FC<Props> = ({ placements }) => {
|
||||
const { t } = useTranslation();
|
||||
const { gray } = useMyTheme();
|
||||
console.log({ placements });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table maxW="50rem">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader width={4} />
|
||||
<TableHeader>{t("xsearch;Name")}</TableHeader>
|
||||
<TableHeader>{t("xsearch;X Power")}</TableHeader>
|
||||
<TableHeader>{t("xsearch;Mode")}</TableHeader>
|
||||
<TableHeader>{t("freeagents;Weapon")}</TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{placements.map((record) => {
|
||||
return (
|
||||
<TableRow key={record.id}>
|
||||
<TableCell color={gray}>
|
||||
{getRankingString(record.ranking)}
|
||||
</TableCell>
|
||||
<TableCell>{record.playerName}</TableCell>
|
||||
<TableCell>
|
||||
<Text fontWeight="bold">{record.xPower}</Text>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<ModeImage mode={record.mode} size={32} />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<WeaponImage name={record.weapon} size={32} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PlayerPage;
|
||||
19
scenes/Player/queries/getPlayersXRankPlacements.graphql
Normal file
19
scenes/Player/queries/getPlayersXRankPlacements.graphql
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
query getPlayersXRankPlacements($playerId: String!) {
|
||||
getPlayersXRankPlacements(playerId: $playerId) {
|
||||
id
|
||||
playerName
|
||||
ranking
|
||||
xPower
|
||||
weapon
|
||||
mode
|
||||
month
|
||||
year
|
||||
player {
|
||||
user {
|
||||
avatarUrl
|
||||
fullUsername
|
||||
profilePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ type Profile {
|
|||
}
|
||||
|
||||
type Query {
|
||||
getPlayersXRankPlacements(playerId: String!): [XRankPlacement!]!
|
||||
getUserByIdentifier(identifier: String!): User
|
||||
getXRankPlacements(mode: RankedMode!, month: Int!, year: Int!): [XRankPlacement!]!
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user