fix profile update modal

This commit is contained in:
Kalle (Sendou) 2021-01-15 13:49:20 +02:00
parent 4d427d6b15
commit fcbbe28a3c
2 changed files with 91 additions and 92 deletions

View File

@ -32,20 +32,19 @@ import { GetTeamData } from "prisma/queries/getTeam";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { FaTwitter } from "react-icons/fa"; import { FaTwitter } from "react-icons/fa";
import { FiEdit } from "react-icons/fi";
import { mutate } from "swr"; import { mutate } from "swr";
import * as z from "zod"; import * as z from "zod";
interface Props { interface Props {
team: NonNullable<GetTeamData>; team: NonNullable<GetTeamData>;
closeModal: () => void;
} }
type FormData = z.infer<typeof teamSchema>; type FormData = z.infer<typeof teamSchema>;
const TeamProfileModal: React.FC<Props> = ({ team }) => { const TeamProfileModal: React.FC<Props> = ({ team, closeModal }) => {
const { i18n } = useLingui(); const { i18n } = useLingui();
const toast = useToast(); const toast = useToast();
const [isOpen, setIsOpen] = useState(false);
const [sending, setSending] = useState(false); const [sending, setSending] = useState(false);
const { handleSubmit, errors, register, watch } = useForm<FormData>({ const { handleSubmit, errors, register, watch } = useForm<FormData>({
@ -57,7 +56,7 @@ const TeamProfileModal: React.FC<Props> = ({ team }) => {
const watchRecruitingPost = watch("recruitingPost", team.recruitingPost); const watchRecruitingPost = watch("recruitingPost", team.recruitingPost);
const onSubmit = async (formData: FormData) => { const onSubmit = async (formData: FormData) => {
const modifiedData: FormData = {}; const modifiedData: FormData = formData;
for (const [key, value] of Object.entries(formData)) { for (const [key, value] of Object.entries(formData)) {
if (value === "" || value === undefined) { if (value === "" || value === undefined) {
@ -76,99 +75,85 @@ const TeamProfileModal: React.FC<Props> = ({ team }) => {
toast(getToastOptions(t`Team profile updated`, "success")); toast(getToastOptions(t`Team profile updated`, "success"));
setIsOpen(false); closeModal();
}; };
return ( return (
<> <Modal isOpen onClose={closeModal} size="xl" closeOnOverlayClick={false}>
<Button leftIcon={<FiEdit />} onClick={() => setIsOpen(true)} size="sm"> <ModalOverlay>
<Trans>Edit team profile</Trans> <ModalContent>
</Button> <ModalHeader>
{isOpen && ( <Trans>Editing team profile</Trans>
<Modal </ModalHeader>
isOpen <ModalCloseButton borderRadius="50%" />
onClose={() => setIsOpen(false)} <form onSubmit={handleSubmit(onSubmit)}>
size="xl" <ModalBody pb={6}>
closeOnOverlayClick={false} <FormControl isInvalid={!!errors.twitterName}>
> <FormLabel htmlFor="twitterName">
<ModalOverlay> <Box
<ModalContent> as={FaTwitter}
<ModalHeader> display="inline-block"
<Trans>Editing team profile</Trans> mr={2}
</ModalHeader> mb={1}
<ModalCloseButton borderRadius="50%" /> color="#1DA1F2"
<form onSubmit={handleSubmit(onSubmit)}> />{" "}
<ModalBody pb={6}> <Trans>Twitter name</Trans>
<FormControl isInvalid={!!errors.twitterName}> </FormLabel>
<FormLabel htmlFor="twitterName"> <InputGroup>
<Box <InputLeftAddon children="https://twitter.com/" />
as={FaTwitter} <Input
display="inline-block" name="twitterName"
mr={2} ref={register}
mb={1} placeholder="olivesplatoon"
color="#1DA1F2"
/>{" "}
<Trans>Twitter name</Trans>
</FormLabel>
<InputGroup>
<InputLeftAddon children="https://twitter.com/" />
<Input
name="twitterName"
ref={register}
placeholder="olivesplatoon"
/>
</InputGroup>
<FormHelperText>
<Trans>
Twitter is also used to get the team's avatar.
</Trans>
</FormHelperText>
<FormErrorMessage>
{errors.twitterName?.message}
</FormErrorMessage>
</FormControl>
<MarkdownTextarea
fieldName="bio"
title={i18n._(t`Bio`)}
error={errors.bio}
register={register}
value={watchBio ?? ""}
maxLength={TEAM_BIO_CHARACTER_LIMIT}
placeholder={i18n._(
t`# I'm a header
I'm **bolded**. Embedding weapon images is easy too: :luna_blaster:`
)}
/> />
</InputGroup>
<FormHelperText>
<Trans>Twitter is also used to get the team's avatar.</Trans>
</FormHelperText>
<FormErrorMessage>
{errors.twitterName?.message}
</FormErrorMessage>
</FormControl>
<MarkdownTextarea <MarkdownTextarea
fieldName="recruitingPost" fieldName="bio"
title={i18n._(t`Recruiting post`)} title={i18n._(t`Bio`)}
error={errors.recruitingPost} error={errors.bio}
register={register} register={register}
value={watchRecruitingPost ?? ""} value={watchBio ?? ""}
maxLength={TEAM_RECRUITING_POST_CHARACTER_LIMIT} maxLength={TEAM_BIO_CHARACTER_LIMIT}
placeholder={i18n._( placeholder={i18n._(
t`# I'm a header t`# I'm a header
I'm **bolded**. Embedding weapon images is easy too: :luna_blaster:` I'm **bolded**. Embedding weapon images is easy too: :luna_blaster:`
)} )}
/> />
</ModalBody>
<ModalFooter> <MarkdownTextarea
<Button mr={3} type="submit" isLoading={sending}> fieldName="recruitingPost"
<Trans>Save</Trans> title={i18n._(t`Recruiting post`)}
</Button> error={errors.recruitingPost}
<Button onClick={() => setIsOpen(false)} variant="outline"> register={register}
<Trans>Cancel</Trans> value={watchRecruitingPost ?? ""}
</Button> maxLength={TEAM_RECRUITING_POST_CHARACTER_LIMIT}
</ModalFooter> placeholder={i18n._(
</form> t`# I'm a header
</ModalContent> I'm **bolded**. Embedding weapon images is easy too: :luna_blaster:`
</ModalOverlay> )}
</Modal> />
)} </ModalBody>
</>
<ModalFooter>
<Button mr={3} type="submit" isLoading={sending}>
<Trans>Save</Trans>
</Button>
<Button onClick={closeModal} variant="outline">
<Trans>Cancel</Trans>
</Button>
</ModalFooter>
</form>
</ModalContent>
</ModalOverlay>
</Modal>
); );
}; };

View File

@ -37,6 +37,7 @@ import Image from "next/image";
import { getTeam, GetTeamData } from "prisma/queries/getTeam"; import { getTeam, GetTeamData } from "prisma/queries/getTeam";
import { Fragment, useEffect, useState } from "react"; import { Fragment, useEffect, useState } from "react";
import { FaTwitter } from "react-icons/fa"; import { FaTwitter } from "react-icons/fa";
import { FiEdit } from "react-icons/fi";
import useSWR, { mutate } from "swr"; import useSWR, { mutate } from "swr";
interface Props { interface Props {
@ -106,6 +107,7 @@ const TeamPage: React.FC<Props> = (props) => {
const team = data!; const team = data!;
const [sending, setSending] = useState(false); const [sending, setSending] = useState(false);
const [profileModalIsOpen, setProfileModalIsOpen] = useState(false);
const [user] = useUser(); const [user] = useUser();
const toast = useToast(); const toast = useToast();
@ -133,6 +135,12 @@ const TeamPage: React.FC<Props> = (props) => {
return ( return (
<MyContainer> <MyContainer>
{profileModalIsOpen && (
<TeamProfileModal
team={team}
closeModal={() => setProfileModalIsOpen(false)}
/>
)}
<Flex align="center" justify="center"> <Flex align="center" justify="center">
{team.twitterName && ( {team.twitterName && (
<TwitterAvatar twitterName={team.twitterName} size="lg" mr={2} /> <TwitterAvatar twitterName={team.twitterName} size="lg" mr={2} />
@ -159,7 +167,7 @@ const TeamPage: React.FC<Props> = (props) => {
{teamXPData.teamXP !== "2000" && ( {teamXPData.teamXP !== "2000" && (
<Popover trigger="hover" variant="responsive"> <Popover trigger="hover" variant="responsive">
<PopoverTrigger> <PopoverTrigger>
<Center mt={2}> <Center>
<Image src={`/layout/xsearch.png`} height={24} width={24} /> <Image src={`/layout/xsearch.png`} height={24} width={24} />
<SubText ml={1}>{teamXPData.teamXP}</SubText> <SubText ml={1}>{teamXPData.teamXP}</SubText>
</Center> </Center>
@ -210,7 +218,13 @@ const TeamPage: React.FC<Props> = (props) => {
<Center my={4}> <Center my={4}>
<Stack direction={["column", "row"]} spacing={4}> <Stack direction={["column", "row"]} spacing={4}>
<TeamManagementModal team={team} /> <TeamManagementModal team={team} />
<TeamProfileModal team={team} /> <Button
leftIcon={<FiEdit />}
onClick={() => setProfileModalIsOpen(true)}
size="sm"
>
<Trans>Edit team profile</Trans>
</Button>
</Stack> </Stack>
</Center> </Center>
)} )}