player page skeleton

This commit is contained in:
Kalle (Sendou) 2020-11-03 15:18:40 +02:00
parent 8266b5418a
commit 69133195bd
9 changed files with 247 additions and 9 deletions

View File

@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
interface Props {
children: React.ReactNode;
loading: boolean;
loading?: boolean;
error?: ApolloError;
}

View File

@ -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;

View File

@ -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)

View File

@ -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" }],
});
},
});

View File

@ -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
View 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
View 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;

View 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
}
}
}
}

View File

@ -36,6 +36,7 @@ type Profile {
}
type Query {
getPlayersXRankPlacements(playerId: String!): [XRankPlacement!]!
getUserByIdentifier(identifier: String!): User
getXRankPlacements(mode: RankedMode!, month: Int!, year: Int!): [XRankPlacement!]!
}