From 69133195bde26de29d8cdbd43cc982fbf9eb8d58 Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Tue, 3 Nov 2020 15:18:40 +0200 Subject: [PATCH] player page skeleton --- components/LoadingBoundary.tsx | 2 +- components/ModeImage.tsx | 10 +-- generated/graphql.tsx | 73 +++++++++++++++++++ graphql/schema/xRankPlacement.ts | 19 ++++- nexus-typegen.ts | 5 ++ pages/player/[id].tsx | 61 ++++++++++++++++ scenes/Player/index.tsx | 66 +++++++++++++++++ .../queries/getPlayersXRankPlacements.graphql | 19 +++++ schema.graphql | 1 + 9 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 pages/player/[id].tsx create mode 100644 scenes/Player/index.tsx create mode 100644 scenes/Player/queries/getPlayersXRankPlacements.graphql diff --git a/components/LoadingBoundary.tsx b/components/LoadingBoundary.tsx index aa271b304..91e4b2fdd 100644 --- a/components/LoadingBoundary.tsx +++ b/components/LoadingBoundary.tsx @@ -5,7 +5,7 @@ import { useEffect, useState } from "react"; interface Props { children: React.ReactNode; - loading: boolean; + loading?: boolean; error?: ApolloError; } diff --git a/components/ModeImage.tsx b/components/ModeImage.tsx index 12739ce02..3ee1f4dbf 100644 --- a/components/ModeImage.tsx +++ b/components/ModeImage.tsx @@ -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 = ({ - mode, - ...props -}) => { - return ; +const ModeImage: React.FC = ({ mode, size }) => { + return ; }; export default ModeImage; diff --git a/generated/graphql.tsx b/generated/graphql.tsx index c8f4f1b01..2d88b452d 100644 --- a/generated/graphql.tsx +++ b/generated/graphql.tsx @@ -38,6 +38,7 @@ export type Query = { __typename?: 'Query'; getUserByIdentifier?: Maybe; getXRankPlacements: Array; + getPlayersXRankPlacements: Array; }; @@ -52,6 +53,11 @@ export type QueryGetXRankPlacementsArgs = { mode: RankedMode; }; + +export type QueryGetPlayersXRankPlacementsArgs = { + playerId: Scalars['String']; +}; + export type UpdateUserProfileInput = { twitterName?: Maybe; customUrlPath?: Maybe; @@ -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 + & { player: ( + { __typename?: 'Player' } + & { user?: Maybe<( + { __typename?: 'User' } + & Pick + )> } + ) } + )> } +); + 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) { + return Apollo.useQuery(GetPlayersXRankPlacementsDocument, baseOptions); + } +export function useGetPlayersXRankPlacementsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + return Apollo.useLazyQuery(GetPlayersXRankPlacementsDocument, baseOptions); + } +export type GetPlayersXRankPlacementsQueryHookResult = ReturnType; +export type GetPlayersXRankPlacementsLazyQueryHookResult = ReturnType; +export type GetPlayersXRankPlacementsQueryResult = Apollo.QueryResult; export const UpdateUserProfileDocument = gql` mutation UpdateUserProfile($profile: UpdateUserProfileInput!) { updateUserProfile(profile: $profile) diff --git a/graphql/schema/xRankPlacement.ts b/graphql/schema/xRankPlacement.ts index 24551c3c9..66f2a0045 100644 --- a/graphql/schema/xRankPlacement.ts +++ b/graphql/schema/xRankPlacement.ts @@ -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" }], }); }, }); diff --git a/nexus-typegen.ts b/nexus-typegen.ts index 826a1efd6..372af11ed 100644 --- a/nexus-typegen.ts +++ b/nexus-typegen.ts @@ -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! } diff --git a/pages/player/[id].tsx b/pages/player/[id].tsx new file mode 100644 index 000000000..5339d3f50 --- /dev/null +++ b/pages/player/[id].tsx @@ -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 ( + + + + ); +}; + +export default PlayerPage; diff --git a/scenes/Player/index.tsx b/scenes/Player/index.tsx new file mode 100644 index 000000000..b7472a281 --- /dev/null +++ b/scenes/Player/index.tsx @@ -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 = ({ placements }) => { + const { t } = useTranslation(); + const { gray } = useMyTheme(); + console.log({ placements }); + + return ( + <> + + + + + {t("xsearch;Name")} + {t("xsearch;X Power")} + {t("xsearch;Mode")} + {t("freeagents;Weapon")} + + + + {placements.map((record) => { + return ( + + + {getRankingString(record.ranking)} + + {record.playerName} + + {record.xPower} + + + + + + + + + ); + })} + +
+ + ); +}; + +export default PlayerPage; diff --git a/scenes/Player/queries/getPlayersXRankPlacements.graphql b/scenes/Player/queries/getPlayersXRankPlacements.graphql new file mode 100644 index 000000000..15fb7ebcd --- /dev/null +++ b/scenes/Player/queries/getPlayersXRankPlacements.graphql @@ -0,0 +1,19 @@ +query getPlayersXRankPlacements($playerId: String!) { + getPlayersXRankPlacements(playerId: $playerId) { + id + playerName + ranking + xPower + weapon + mode + month + year + player { + user { + avatarUrl + fullUsername + profilePath + } + } + } +} diff --git a/schema.graphql b/schema.graphql index 7016cbb2f..bde605d67 100644 --- a/schema.graphql +++ b/schema.graphql @@ -36,6 +36,7 @@ type Profile { } type Query { + getPlayersXRankPlacements(playerId: String!): [XRankPlacement!]! getUserByIdentifier(identifier: String!): User getXRankPlacements(mode: RankedMode!, month: Int!, year: Int!): [XRankPlacement!]! }