mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-09 12:13:10 -05:00
can mutate profile
This commit is contained in:
parent
87cf160553
commit
0886a2b4c9
|
|
@ -43,6 +43,38 @@ export type QueryGetUserByIdentifierArgs = {
|
|||
identifier: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateUserProfileInput = {
|
||||
twitterName?: Maybe<Scalars['String']>;
|
||||
customUrlPath?: Maybe<Scalars['String']>;
|
||||
twitchName?: Maybe<Scalars['String']>;
|
||||
youtubeId?: Maybe<Scalars['String']>;
|
||||
country?: Maybe<Scalars['String']>;
|
||||
bio?: Maybe<Scalars['String']>;
|
||||
sensStick?: Maybe<Scalars['Float']>;
|
||||
sensMotion?: Maybe<Scalars['Float']>;
|
||||
weaponPool?: Maybe<Array<Scalars['String']>>;
|
||||
};
|
||||
|
||||
export type Mutation = {
|
||||
__typename?: 'Mutation';
|
||||
updateUserProfile: Scalars['Boolean'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateUserProfileArgs = {
|
||||
profile?: Maybe<UpdateUserProfileInput>;
|
||||
};
|
||||
|
||||
export type UpdateUserProfileMutationVariables = Exact<{
|
||||
profile: UpdateUserProfileInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateUserProfileMutation = (
|
||||
{ __typename?: 'Mutation' }
|
||||
& Pick<Mutation, 'updateUserProfile'>
|
||||
);
|
||||
|
||||
export type GetUserByIdentifierQueryVariables = Exact<{
|
||||
identifier: Scalars['String'];
|
||||
}>;
|
||||
|
|
@ -61,6 +93,36 @@ export type GetUserByIdentifierQuery = (
|
|||
);
|
||||
|
||||
|
||||
export const UpdateUserProfileDocument = gql`
|
||||
mutation UpdateUserProfile($profile: UpdateUserProfileInput!) {
|
||||
updateUserProfile(profile: $profile)
|
||||
}
|
||||
`;
|
||||
export type UpdateUserProfileMutationFn = Apollo.MutationFunction<UpdateUserProfileMutation, UpdateUserProfileMutationVariables>;
|
||||
|
||||
/**
|
||||
* __useUpdateUserProfileMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useUpdateUserProfileMutation` within a React component and pass it any options that fit your needs.
|
||||
* When your component renders, `useUpdateUserProfileMutation` returns a tuple that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - An object with fields that represent the current status of the mutation's execution
|
||||
*
|
||||
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||
*
|
||||
* @example
|
||||
* const [updateUserProfileMutation, { data, loading, error }] = useUpdateUserProfileMutation({
|
||||
* variables: {
|
||||
* profile: // value for 'profile'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useUpdateUserProfileMutation(baseOptions?: Apollo.MutationHookOptions<UpdateUserProfileMutation, UpdateUserProfileMutationVariables>) {
|
||||
return Apollo.useMutation<UpdateUserProfileMutation, UpdateUserProfileMutationVariables>(UpdateUserProfileDocument, baseOptions);
|
||||
}
|
||||
export type UpdateUserProfileMutationHookResult = ReturnType<typeof useUpdateUserProfileMutation>;
|
||||
export type UpdateUserProfileMutationResult = Apollo.MutationResult<UpdateUserProfileMutation>;
|
||||
export type UpdateUserProfileMutationOptions = Apollo.BaseMutationOptions<UpdateUserProfileMutation, UpdateUserProfileMutationVariables>;
|
||||
export const GetUserByIdentifierDocument = gql`
|
||||
query GetUserByIdentifier($identifier: String!) {
|
||||
getUserByIdentifier(identifier: $identifier) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const schema = makeSchema({
|
|||
typegen: path.join(process.cwd(), "nexus-typegen.ts"),
|
||||
},
|
||||
nonNullDefaults: {
|
||||
input: true,
|
||||
input: false,
|
||||
output: true,
|
||||
},
|
||||
typegenAutoConfig: {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export const UpdateUserProfileInput = inputObjectType({
|
|||
export const Mutation = mutationType({
|
||||
definition(t) {
|
||||
t.field("updateUserProfile", {
|
||||
type: Profile,
|
||||
type: "Boolean",
|
||||
nullable: false,
|
||||
args: {
|
||||
profile: UpdateUserProfileInput,
|
||||
|
|
@ -113,12 +113,14 @@ export const Mutation = mutationType({
|
|||
console.log({ session });
|
||||
|
||||
// FIXME: set custom url to lowerCase
|
||||
return await ctx.prisma.profile.upsert({
|
||||
await ctx.prisma.profile.upsert({
|
||||
create: { user: { connect: { id: 4 } }, ...args.profile },
|
||||
// FIXME: doing it like this makes removing values impossible?
|
||||
update: args.profile,
|
||||
where: { userId: 4 },
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@ declare global {
|
|||
|
||||
export interface NexusGenInputs {
|
||||
UpdateUserProfileInput: { // input type
|
||||
bio: string; // String!
|
||||
country: string; // String!
|
||||
customUrlPath: string; // String!
|
||||
sensMotion: number; // Float!
|
||||
sensStick: number; // Float!
|
||||
twitchName: string; // String!
|
||||
twitterName: string; // String!
|
||||
weaponPool: string[]; // [String!]!
|
||||
youtubeId: string; // String!
|
||||
bio?: string | null; // String
|
||||
country?: string | null; // String
|
||||
customUrlPath?: string | null; // String
|
||||
sensMotion?: number | null; // Float
|
||||
sensStick?: number | null; // Float
|
||||
twitchName?: string | null; // String
|
||||
twitterName?: string | null; // String
|
||||
weaponPool?: string[] | null; // [String!]
|
||||
youtubeId?: string | null; // String
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ export interface NexusGenAllTypes extends NexusGenRootTypes {
|
|||
|
||||
export interface NexusGenFieldTypes {
|
||||
Mutation: { // field return type
|
||||
updateUserProfile: NexusGenRootTypes['Profile']; // Profile!
|
||||
updateUserProfile: boolean; // Boolean!
|
||||
}
|
||||
Profile: { // field return type
|
||||
bio: string | null; // String
|
||||
|
|
@ -90,7 +90,7 @@ export interface NexusGenFieldTypes {
|
|||
export interface NexusGenArgTypes {
|
||||
Mutation: {
|
||||
updateUserProfile: { // args
|
||||
profile: NexusGenInputs['UpdateUserProfileInput']; // UpdateUserProfileInput!
|
||||
profile?: NexusGenInputs['UpdateUserProfileInput'] | null; // UpdateUserProfileInput
|
||||
}
|
||||
}
|
||||
Query: {
|
||||
|
|
|
|||
|
|
@ -18,18 +18,17 @@ const extendedTheme = extendTheme({
|
|||
},
|
||||
}),
|
||||
},
|
||||
// FIXME:
|
||||
// 1) round iconButton
|
||||
// 2) table-like lime green input addons
|
||||
// 3) input styling
|
||||
// 4) focus color
|
||||
components: {
|
||||
Button: {
|
||||
defaultProps: {
|
||||
colorScheme: "lime",
|
||||
color: "black",
|
||||
colorScheme: "theme",
|
||||
},
|
||||
},
|
||||
// IconButton: {
|
||||
// defaultProps: {
|
||||
// isRound: true,
|
||||
// },
|
||||
// },
|
||||
Modal: {
|
||||
baseStyle: (props) => ({
|
||||
content: {
|
||||
|
|
@ -42,7 +41,7 @@ const extendedTheme = extendTheme({
|
|||
},
|
||||
},
|
||||
colors: {
|
||||
lime: {
|
||||
theme: {
|
||||
50: "#e4ffdf",
|
||||
100: "#bbffb0",
|
||||
200: "#92ff7f",
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ const AvatarWithInfo: React.FC<AvatarWithInfoProps> = ({ user }) => {
|
|||
/>
|
||||
</a>
|
||||
)}
|
||||
{user.profile?.weaponPool.length && (
|
||||
{user.profile?.weaponPool && user.profile?.weaponPool.length > 0 && (
|
||||
<Flex
|
||||
mt="0.2rem"
|
||||
w="100%"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ import {
|
|||
ModalOverlay,
|
||||
} from "@chakra-ui/core";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import {
|
||||
UpdateUserProfileInput,
|
||||
useUpdateUserProfileMutation,
|
||||
} from "generated/graphql";
|
||||
import { useTranslation } from "lib/useMockT";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { ProfileSchema } from "validators/Profile";
|
||||
|
|
@ -26,17 +30,21 @@ interface Props {
|
|||
|
||||
const ProfileModal: React.FC<Props> = ({ isOpen, onClose }) => {
|
||||
const { t } = useTranslation();
|
||||
const { handleSubmit, errors, register } = useForm({
|
||||
|
||||
const { handleSubmit, errors, register } = useForm<UpdateUserProfileInput>({
|
||||
resolver: zodResolver(ProfileSchema),
|
||||
});
|
||||
const [updateUserProfile] = useUpdateUserProfileMutation();
|
||||
|
||||
const onSubmit = (data) => {
|
||||
const onSubmit = async (data: UpdateUserProfileInput) => {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (data[key] === "") {
|
||||
data[key] = null;
|
||||
const typedKey = key as keyof typeof data;
|
||||
if (data[typedKey] === "") {
|
||||
data[typedKey] = null;
|
||||
}
|
||||
});
|
||||
|
||||
await updateUserProfile({ variables: { profile: data } });
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
|
|
|
|||
3
scenes/Profile/mutations/UpdateUserProfile.graphql
Normal file
3
scenes/Profile/mutations/UpdateUserProfile.graphql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
mutation UpdateUserProfile($profile: UpdateUserProfileInput!) {
|
||||
updateUserProfile(profile: $profile)
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
type Mutation {
|
||||
updateUserProfile(profile: UpdateUserProfileInput!): Profile!
|
||||
updateUserProfile(profile: UpdateUserProfileInput): Boolean!
|
||||
}
|
||||
|
||||
type Profile {
|
||||
|
|
@ -23,15 +23,15 @@ type Query {
|
|||
}
|
||||
|
||||
input UpdateUserProfileInput {
|
||||
bio: String!
|
||||
country: String!
|
||||
customUrlPath: String!
|
||||
sensMotion: Float!
|
||||
sensStick: Float!
|
||||
twitchName: String!
|
||||
twitterName: String!
|
||||
weaponPool: [String!]!
|
||||
youtubeId: String!
|
||||
bio: String
|
||||
country: String
|
||||
customUrlPath: String
|
||||
sensMotion: Float
|
||||
sensStick: Float
|
||||
twitchName: String
|
||||
twitterName: String
|
||||
weaponPool: [String!]
|
||||
youtubeId: String
|
||||
}
|
||||
|
||||
type User {
|
||||
|
|
|
|||
|
|
@ -1,173 +1,37 @@
|
|||
//import isISO31661Alpha2 from "validator/es/lib/isISO31661Alpha2";
|
||||
import { weaponsWithHero } from "lib/lists/weaponsWithHero";
|
||||
import * as z from "zod";
|
||||
|
||||
export const ProfileSchema = z.object({
|
||||
bio: z.string().max(10000).optional(),
|
||||
bio: z.string().max(10000).optional().nullable(),
|
||||
country: z
|
||||
.string()
|
||||
//.refine((val) => isISO31661Alpha2(val))
|
||||
.optional(),
|
||||
customUrlPath: z.string().max(32).optional(),
|
||||
.optional()
|
||||
.nullable(),
|
||||
customUrlPath: z.string().max(32).optional().nullable(),
|
||||
sensMotion: z
|
||||
.number()
|
||||
.min(5)
|
||||
.max(5)
|
||||
.refine((val) => (val * 10) % 5 === 0)
|
||||
.optional(),
|
||||
.optional()
|
||||
.nullable(),
|
||||
sensStick: z
|
||||
.number()
|
||||
.min(5)
|
||||
.max(5)
|
||||
.refine((val) => (val * 10) % 5 === 0)
|
||||
.optional(),
|
||||
twitchName: z.string().max(25).optional(),
|
||||
twitterName: z.string().max(15).optional(),
|
||||
youtubeId: z.string().optional(),
|
||||
.optional()
|
||||
.nullable(),
|
||||
twitchName: z.string().max(25).optional().nullable(),
|
||||
twitterName: z.string().max(15).optional().nullable(),
|
||||
youtubeId: z.string().optional().nullable(),
|
||||
// weaponsWithHero
|
||||
weaponPool: z
|
||||
.array(
|
||||
z.enum([
|
||||
"Sploosh-o-matic",
|
||||
"Neo Sploosh-o-matic",
|
||||
"Sploosh-o-matic 7",
|
||||
"Splattershot Jr.",
|
||||
"Custom Splattershot Jr.",
|
||||
"Kensa Splattershot Jr.",
|
||||
"Splash-o-matic",
|
||||
"Neo Splash-o-matic",
|
||||
"Aerospray MG",
|
||||
"Aerospray RG",
|
||||
"Aerospray PG",
|
||||
"Splattershot",
|
||||
"Hero Shot Replica",
|
||||
"Tentatek Splattershot",
|
||||
"Octo Shot Replica",
|
||||
"Kensa Splattershot",
|
||||
".52 Gal",
|
||||
".52 Gal Deco",
|
||||
"Kensa .52 Gal",
|
||||
"N-ZAP '85",
|
||||
"N-ZAP '89",
|
||||
"N-ZAP '83",
|
||||
"Splattershot Pro",
|
||||
"Forge Splattershot Pro",
|
||||
"Kensa Splattershot Pro",
|
||||
".96 Gal",
|
||||
".96 Gal Deco",
|
||||
"Jet Squelcher",
|
||||
"Custom Jet Squelcher",
|
||||
"L-3 Nozzlenose",
|
||||
"L-3 Nozzlenose D",
|
||||
"Kensa L-3 Nozzlenose",
|
||||
"H-3 Nozzlenose",
|
||||
"H-3 Nozzlenose D",
|
||||
"Cherry H-3 Nozzlenose",
|
||||
"Squeezer",
|
||||
"Foil Squeezer",
|
||||
"Luna Blaster",
|
||||
"Luna Blaster Neo",
|
||||
"Kensa Luna Blaster",
|
||||
"Blaster",
|
||||
"Hero Blaster Replica",
|
||||
"Custom Blaster",
|
||||
"Range Blaster",
|
||||
"Custom Range Blaster",
|
||||
"Grim Range Blaster",
|
||||
"Rapid Blaster",
|
||||
"Rapid Blaster Deco",
|
||||
"Kensa Rapid Blaster",
|
||||
"Rapid Blaster Pro",
|
||||
"Rapid Blaster Pro Deco",
|
||||
"Clash Blaster",
|
||||
"Clash Blaster Neo",
|
||||
"Carbon Roller",
|
||||
"Carbon Roller Deco",
|
||||
"Splat Roller",
|
||||
"Hero Roller Replica",
|
||||
"Krak-On Splat Roller",
|
||||
"Kensa Splat Roller",
|
||||
"Dynamo Roller",
|
||||
"Gold Dynamo Roller",
|
||||
"Kensa Dynamo Roller",
|
||||
"Flingza Roller",
|
||||
"Foil Flingza Roller",
|
||||
"Inkbrush",
|
||||
"Inkbrush Nouveau",
|
||||
"Permanent Inkbrush",
|
||||
"Octobrush",
|
||||
"Herobrush Replica",
|
||||
"Octobrush Nouveau",
|
||||
"Kensa Octobrush",
|
||||
"Classic Squiffer",
|
||||
"New Squiffer",
|
||||
"Fresh Squiffer",
|
||||
"Splat Charger",
|
||||
"Hero Charger Replica",
|
||||
"Firefin Splat Charger",
|
||||
"Kensa Charger",
|
||||
"Splatterscope",
|
||||
"Firefin Splatterscope",
|
||||
"Kensa Splatterscope",
|
||||
"E-liter 4K",
|
||||
"Custom E-liter 4K",
|
||||
"E-liter 4K Scope",
|
||||
"Custom E-liter 4K Scope",
|
||||
"Bamboozler 14 Mk I",
|
||||
"Bamboozler 14 Mk II",
|
||||
"Bamboozler 14 Mk III",
|
||||
"Goo Tuber",
|
||||
"Custom Goo Tuber",
|
||||
"Slosher",
|
||||
"Hero Slosher Replica",
|
||||
"Slosher Deco",
|
||||
"Soda Slosher",
|
||||
"Tri-Slosher",
|
||||
"Tri-Slosher Nouveau",
|
||||
"Sloshing Machine",
|
||||
"Sloshing Machine Neo",
|
||||
"Kensa Sloshing Machine",
|
||||
"Bloblobber",
|
||||
"Bloblobber Deco",
|
||||
"Explosher",
|
||||
"Custom Explosher",
|
||||
"Mini Splatling",
|
||||
"Zink Mini Splatling",
|
||||
"Kensa Mini Splatling",
|
||||
"Heavy Splatling",
|
||||
"Hero Splatling Replica",
|
||||
"Heavy Splatling Deco",
|
||||
"Heavy Splatling Remix",
|
||||
"Hydra Splatling",
|
||||
"Custom Hydra Splatling",
|
||||
"Ballpoint Splatling",
|
||||
"Ballpoint Splatling Nouveau",
|
||||
"Nautilus 47",
|
||||
"Nautilus 79",
|
||||
"Dapple Dualies",
|
||||
"Dapple Dualies Nouveau",
|
||||
"Clear Dapple Dualies",
|
||||
"Splat Dualies",
|
||||
"Hero Dualie Replicas",
|
||||
"Enperry Splat Dualies",
|
||||
"Kensa Splat Dualies",
|
||||
"Glooga Dualies",
|
||||
"Glooga Dualies Deco",
|
||||
"Kensa Glooga Dualies",
|
||||
"Dualie Squelchers",
|
||||
"Custom Dualie Squelchers",
|
||||
"Dark Tetra Dualies",
|
||||
"Light Tetra Dualies",
|
||||
"Splat Brella",
|
||||
"Hero Brella Replica",
|
||||
"Sorella Brella",
|
||||
"Tenta Brella",
|
||||
"Tenta Sorella Brella",
|
||||
"Tenta Camo Brella",
|
||||
"Undercover Brella",
|
||||
"Undercover Sorella Brella",
|
||||
"Kensa Undercover Brella",
|
||||
])
|
||||
)
|
||||
.array(z.string())
|
||||
.max(5)
|
||||
.optional(),
|
||||
.refine((arr) => arr.every((val) => weaponsWithHero.includes(val as any)))
|
||||
.optional()
|
||||
.nullable(),
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user