select country via dropdown

This commit is contained in:
Kalle (Sendou) 2020-10-22 14:40:45 +03:00
parent 25ac18acd3
commit 129c502516
7 changed files with 36 additions and 47 deletions

View File

@ -1,26 +0,0 @@
import { useTranslation } from "lib/useMockT";
import React from "react";
interface FlagProps {
code: string;
size?: "16" | "32";
}
const Flag: React.FC<FlagProps> = ({ code, size = "16" }) => {
const { t } = useTranslation();
return (
<img
src={`https://www.countryflags.io/${code}/flat/${size}.png`}
style={{
display: "inline",
margin: "0 8px",
width: `${size}px`,
height: `${size}px`,
}}
alt={t(`countries;${code.toUpperCase()}`)}
title={t(`countries;${code.toUpperCase()}`)}
/>
);
};
export default Flag;

View File

@ -1,4 +1,4 @@
import { fieldAuthorizePlugin, makeSchema } from "@nexus/schema";
import { makeSchema } from "@nexus/schema";
import * as userTypes from "graphql/schema/user";
import { nexusSchemaPrisma } from "nexus-plugin-prisma/schema";
import path from "path";
@ -6,7 +6,7 @@ import path from "path";
export const schema = makeSchema({
types: [userTypes],
// FIXME: set complexity plugin
plugins: [nexusSchemaPrisma(), fieldAuthorizePlugin()],
plugins: [nexusSchemaPrisma()],
outputs: {
// FIXME: should be in graphql/generated instead root
schema: path.join(process.cwd(), "schema.graphql"),

View File

@ -107,9 +107,6 @@ export const Mutation = mutationType({
args: {
profile: arg({ type: UpdateUserProfileInput, required: true }),
},
authorize: async (_root, _args, ctx) => {
return true;
},
resolve: async (_root, args, ctx) => {
const user = await getMySession(ctx.req);
if (!user) throw Error("Not logged in");
@ -123,10 +120,15 @@ export const Mutation = mutationType({
},
});
if (profileWithSameCustomUrl) throw Error("Custom URL already taken");
if (
profileWithSameCustomUrl &&
profileWithSameCustomUrl.userId !== user.id
)
throw Error("Custom URL already taken");
}
const argsForDb = {
...args.profile,
// can't set array as undefined or null -> need to use [] instead due to how prisma does things
weaponPool: args.profile?.weaponPool ? args.profile.weaponPool : [],
customUrlPath: args.profile?.customUrlPath
@ -138,7 +140,6 @@ export const Mutation = mutationType({
twitchName: args.profile?.twitchName
? args.profile.twitchName.toLowerCase()
: null,
...args.profile?.weaponPool,
};
// FIXME: set custom url to lowerCase
@ -148,8 +149,7 @@ export const Mutation = mutationType({
...argsForDb,
},
update: {
...args.profile,
weaponPool: args.profile?.weaponPool ? args.profile.weaponPool : [],
...argsForDb,
},
where: { userId: user.id },
});

View File

@ -5,7 +5,7 @@
import * as Context from "./graphql/context"
import * as Prisma from ".prisma/client"
import { FieldAuthorizeResolver } from "@nexus/schema/dist/plugins/fieldAuthorizePlugin"
declare global {
@ -144,15 +144,6 @@ declare global {
interface NexusGenPluginTypeConfig<TypeName extends string> {
}
interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {
/**
* Authorization for an individual field. Returning "true"
* or "Promise<true>" means the field can be accessed.
* Returning "false" or "Promise<false>" will respond
* with a "Not Authorized" error for the field.
* Returning or throwing an error will also prevent the
* resolver from executing.
*/
authorize?: FieldAuthorizeResolver<TypeName, FieldName>
}
interface NexusGenPluginSchemaConfig {
}

View File

@ -24,6 +24,7 @@ const extendedTheme = extendTheme({
// 3) input styling
// 4) focus color
// 5) form label bolded
// 6) dropdown border + focus colors
components: {
Button: {
defaultProps: {

View File

@ -1,7 +1,7 @@
import { Avatar, Box, Flex, Heading, IconButton } from "@chakra-ui/core";
import Flag from "components/Flag";
import Section from "components/Section";
import WeaponImage from "components/WeaponImage";
import { getEmojiFlag } from "countries-list";
import { GetUserByIdentifierQuery } from "generated/graphql";
import { useTranslation } from "lib/useMockT";
import { useMyTheme } from "lib/useMyTheme";
@ -52,7 +52,11 @@ const AvatarWithInfo: React.FC<AvatarWithInfoProps> = ({ user }) => {
<Heading fontFamily="'Rubik', sans-serif" size="lg">
{user.fullUsername}
</Heading>
{user.profile?.country && <Flag code={user.profile.country} />}
{user.profile?.country && (
<Box as="span" ml={1}>
{getEmojiFlag(user.profile.country)}
</Box>
)}
</Flex>
<Flex alignItems="center" justifyContent="center">
<Flex flexWrap="wrap" alignItems="center" justifyContent="center">

View File

@ -14,9 +14,11 @@ import {
ModalFooter,
ModalHeader,
ModalOverlay,
Select,
useToast,
} from "@chakra-ui/core";
import { zodResolver } from "@hookform/resolvers/zod";
import { countries } from "countries-list";
import {
GetUserByIdentifierQuery,
UpdateUserProfileInput,
@ -165,6 +167,23 @@ const ProfileModal: React.FC<Props> = ({
</InputGroup>
<FormErrorMessage>{errors.youtubeId?.message}</FormErrorMessage>
</FormControl>
<FormLabel htmlFor="country" mt={4}>
{t("users;Country")}
</FormLabel>
<Select
ref={register}
name="country"
placeholder="Select country"
>
{(Object.keys(countries) as Array<keyof typeof countries>).map(
(countryCode) => (
<option key={countryCode} value={countryCode}>
{countries[countryCode].name}
</option>
)
)}
</Select>
</ModalBody>
<ModalFooter>