import { Box, Button, FormControl, FormErrorMessage, FormLabel, Input, InputGroup, InputLeftAddon, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Select, useToast, } from "@chakra-ui/core"; import { zodResolver } from "@hookform/resolvers/zod"; import { t, Trans } from "@lingui/macro"; import { useLingui } from "@lingui/react"; import { countries } from "countries-list"; import { GetUserByIdentifierDocument, GetUserByIdentifierQuery, UpdateUserProfileInput, useUpdateUserProfileMutation, } from "generated/graphql"; import MarkdownTextarea from "lib/components/MarkdownTextarea"; import WeaponSelector from "lib/components/WeaponSelector"; import { getToastOptions } from "lib/getToastOptions"; import { Controller, useForm } from "react-hook-form"; import { FaGamepad, FaTwitch, FaTwitter, FaYoutube } from "react-icons/fa"; import { profileSchemaFrontend, PROFILE_CHARACTER_LIMIT, } from "validators/profile"; import * as z from "zod"; const sensOptions = [ "-5", "-4.5", "-4", "-3.5", "-3", "-2.5", "-2", "-1.5", "-1", "-0.5", "0", "+0.5", "+1", "+1.5", "+2", "+2.5", "+3", "+3.5", "+4", "+4.5", "+5", ]; const sensToString = (sens: number | undefined | null) => { if (sens === undefined || sens === null) return ""; return sens > 0 ? `+${sens}` : `${sens}`; }; interface Props { onClose: () => void; existingProfile?: NonNullable< GetUserByIdentifierQuery["getUserByIdentifier"] >["profile"]; identifier: string; } type FormData = z.infer; const ProfileModal: React.FC = ({ onClose, existingProfile, identifier, }) => { const { i18n } = useLingui(); const { handleSubmit, errors, register, watch, control } = useForm({ resolver: zodResolver(profileSchemaFrontend), defaultValues: existingProfile ? { ...existingProfile, sensMotion: sensToString(existingProfile.sensMotion), sensStick: sensToString(existingProfile.sensStick), } : undefined, }); // FIXME: bio length show const watchBio = watch("bio", existingProfile?.bio ?? ""); const toast = useToast(); const [updateUserProfile, { loading }] = useUpdateUserProfileMutation({ onCompleted: () => { toast(getToastOptions(i18n._(t`Profile updated`), "success")); onClose(); }, onError: (error) => { toast(getToastOptions(error.message, "error")); }, }); const onSubmit = async (formData: FormData) => { const mutationData: UpdateUserProfileInput = { ...formData, // sens is treated as string on the frontend side of things because // html select uses strings sensStick: typeof formData.sensStick === "string" ? parseFloat(formData.sensStick) : null, sensMotion: typeof formData.sensMotion === "string" ? parseFloat(formData.sensMotion) : null, }; for (const [key, value] of Object.entries(mutationData)) { if (value === "" || value === undefined) { const typedKey = key as keyof Omit; mutationData[typedKey] = null; } } await updateUserProfile({ variables: { profile: mutationData }, update: (cache) => { const query = { query: GetUserByIdentifierDocument, variables: { identifier }, }; const data = cache.readQuery(query); cache.writeQuery({ ...query, data: { ...data, getUserByIdentifier: { ...data!.getUserByIdentifier!, profile: mutationData, }, }, }); }, }); }; // FIXME: modal seems slow to popup at least in dev? return ( Editing profile
Custom URL {errors.customUrlPath?.message} {" "} Twitter name {errors.twitterName?.message} Twitch name {errors.twitchName?.message} YouTube channel ID {errors.youtubeId?.message} Country {/* FIXME: placeholders for dropdowns */} Weapon pool ( )} /> {/* Seems to be mistyped */} {/* @ts-ignore */} {errors.weaponPool?.message} Stick sensitivity Motion sensitivity
); }; export default ProfileModal;