refactor(userProfile + tsx instead of jsx): created custom components for form userProfile

This commit is contained in:
Laurian-Dufrechou
2023-04-30 19:57:01 +02:00
parent c78b6e67c8
commit c5da6c9730
20 changed files with 512 additions and 334 deletions
+39 -1
View File
@@ -36,7 +36,8 @@
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"react-query": "^3.39.3", "react-query": "^3.39.3",
"socket.io": "^4.6.1", "socket.io": "^4.6.1",
"socket.io-client": "^4.6.1" "socket.io-client": "^4.6.1",
"yup": "^1.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/bcrypt": "^5.0.0", "@types/bcrypt": "^5.0.0",
@@ -6888,6 +6889,11 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/property-expr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
},
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -8021,6 +8027,11 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
}, },
"node_modules/tiny-case": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="
},
"node_modules/tiny-glob": { "node_modules/tiny-glob": {
"version": "0.2.9", "version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
@@ -8071,6 +8082,11 @@
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
}, },
"node_modules/toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
},
"node_modules/tr46": { "node_modules/tr46": {
"version": "0.0.3", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -8530,6 +8546,28 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/yup": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/yup/-/yup-1.1.1.tgz",
"integrity": "sha512-KfCGHdAErqFZWA5tZf7upSUnGKuTOnsI3hUsLr7fgVtx+DK04NPV01A68/FslI4t3s/ZWpvXJmgXhd7q6ICnag==",
"dependencies": {
"property-expr": "^2.0.5",
"tiny-case": "^1.0.3",
"toposort": "^2.0.2",
"type-fest": "^2.19.0"
}
},
"node_modules/yup/node_modules/type-fest": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zip-stream": { "node_modules/zip-stream": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
+2 -1
View File
@@ -37,7 +37,8 @@
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"react-query": "^3.39.3", "react-query": "^3.39.3",
"socket.io": "^4.6.1", "socket.io": "^4.6.1",
"socket.io-client": "^4.6.1" "socket.io-client": "^4.6.1",
"yup": "^1.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/bcrypt": "^5.0.0", "@types/bcrypt": "^5.0.0",
@@ -18,16 +18,14 @@ import { useState } from "react";
import SearchFailCard from "./SearchFailCard"; import SearchFailCard from "./SearchFailCard";
import LoadingPage from "@/components/LoadingPage"; import LoadingPage from "@/components/LoadingPage";
export default function CardUser(props) { export default function CardUser({
const { users,
users, loggedUser,
loggedUser, userLikes,
userLikes, setUserLikes,
setUserLikes, userDislikes,
userDislikes, setUserDislikes,
setUserDislikes, }) {
} = props;
const toast = useToast({ const toast = useToast({
position: "top", position: "top",
duration: 2000, duration: 2000,
@@ -0,0 +1,53 @@
import {
Editable,
EditableInput,
EditablePreview,
FormControl,
FormErrorMessage,
FormLabel,
} from "@chakra-ui/react";
import { Controller, ControllerProps } from "react-hook-form";
type CustomEditableProps = {
label: string;
isDisabled?: boolean;
} & Omit<ControllerProps, "render">;
export default function CustomEditable(props: CustomEditableProps) {
const {
defaultValue,
label,
name,
isDisabled = false,
...controllerProps
} = props;
return (
<Controller
{...controllerProps}
name={name}
defaultValue={defaultValue}
render={({ field, fieldState: { invalid, error } }) => {
return (
<FormControl id={name} isInvalid={invalid}>
<FormLabel as="legend" htmlFor={name}>
{label}
</FormLabel>
<Editable
{...field}
id={name}
fontWeight="bold"
isDisabled={isDisabled}
placeholder={"Non renseigné"}
color={isDisabled ? "gray.500" : undefined}
>
<EditablePreview />
<EditableInput />
</Editable>
<FormErrorMessage as="b">{error?.message}</FormErrorMessage>
</FormControl>
);
}}
/>
);
}
@@ -0,0 +1,54 @@
import {
Editable,
EditablePreview,
EditableTextarea,
FormControl,
FormErrorMessage,
FormLabel,
} from "@chakra-ui/react";
import { Controller, ControllerProps } from "react-hook-form";
type CustomEditableProps = {
label: string;
isDisabled?: boolean;
} & Omit<ControllerProps, "render">;
export default function CustomEditableArea(props: CustomEditableProps) {
const {
defaultValue,
label,
name,
isDisabled = false,
...controllerProps
} = props;
return (
<Controller
{...controllerProps}
name={name}
defaultValue={defaultValue}
render={({ field, fieldState: { invalid, error } }) => {
return (
<FormControl id={name} isInvalid={invalid}>
<FormLabel as="legend" htmlFor={name}>
{label}
</FormLabel>
<Editable
{...field}
id={name}
fontWeight="bold"
width={"100%"}
isDisabled={isDisabled}
placeholder={"Non renseigné"}
color={isDisabled ? "gray.500" : undefined}
>
<EditablePreview />
<EditableTextarea />
</Editable>
<FormErrorMessage as="b">{error?.message}</FormErrorMessage>
</FormControl>
);
}}
/>
);
}
@@ -0,0 +1,60 @@
import { FormLabel, HStack, Radio, RadioGroup } from "@chakra-ui/react";
import { Gender } from "@prisma/client";
import { Controller, ControllerProps } from "react-hook-form";
type CustomRadioGenderProps = {
label: string;
} & Omit<ControllerProps, "render">;
export default function CustomRadioGender(props: CustomRadioGenderProps) {
const { defaultValue, label, name, ...controllerProps } = props;
const getTextGender = (gender: string) => {
switch (gender) {
case Gender.MALE:
return "Homme";
case Gender.FEMALE:
return "Femme";
case Gender.OTHER:
return "Autre";
case Gender.UNKNOWN:
return "Non renseigné";
}
};
return (
<>
<FormLabel as={"legend"} htmlFor={name}>
{label}
</FormLabel>
<Controller
{...controllerProps}
name={name}
render={({ field }) => {
return (
<RadioGroup
{...field}
colorScheme={"purple"}
id={name}
as="b"
defaultValue={defaultValue}
>
<HStack spacing={"0.5rem"}>
<Radio value={Gender.MALE}>{getTextGender(Gender.MALE)}</Radio>
<Radio value={Gender.FEMALE}>
{getTextGender(Gender.FEMALE)}
</Radio>
<Radio value={Gender.OTHER}>
{getTextGender(Gender.OTHER)}
</Radio>
<Radio value={Gender.UNKNOWN}>
{getTextGender(Gender.UNKNOWN)}
</Radio>
</HStack>
</RadioGroup>
);
}}
/>
</>
);
}
@@ -0,0 +1,93 @@
import {
Box,
FormLabel,
RangeSlider,
RangeSliderFilledTrack,
RangeSliderThumb,
RangeSliderTrack,
Tooltip,
} from "@chakra-ui/react";
import { Controller, ControllerProps } from "react-hook-form";
import { FaGreaterThan, FaLessThan } from "react-icons/fa";
type CustomRangeSliderProps = {
label: string;
defaultValue: [number, number];
sliderAgeValue: number[];
setSliderAgeValue: React.Dispatch<React.SetStateAction<number[]>>;
showTooltipAge: boolean;
setShowTooltipAge: React.Dispatch<React.SetStateAction<boolean>>;
name: string;
} & Omit<ControllerProps, "render">;
export default function CustomRangeSlider(props: CustomRangeSliderProps) {
const {
defaultValue,
label,
setSliderAgeValue,
setShowTooltipAge,
showTooltipAge,
sliderAgeValue,
name,
...controllerProps
} = props;
return (
<>
<FormLabel as={"legend"} htmlFor={name}>
{label}
</FormLabel>
<Controller
{...controllerProps}
name={name}
render={({ field: { onChange } }) => (
<RangeSlider
aria-label={["min", "max"]}
colorScheme={"purple"}
min={18}
max={99}
id={name}
color={"pink.500"}
defaultValue={defaultValue}
onChange={(v: [number, number]) => {
setSliderAgeValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipAge(true)}
onMouseLeave={() => setShowTooltipAge(false)}
>
<RangeSliderTrack>
<RangeSliderFilledTrack bgColor={"purple.500"} />
</RangeSliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[0]}`}
>
<RangeSliderThumb boxSize={6} index={0}>
<Box color={"purple.500"} as={FaLessThan} />
</RangeSliderThumb>
</Tooltip>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[1]}`}
>
<RangeSliderThumb boxSize={6} index={1}>
<Box color={"purple.500"} as={FaGreaterThan} />
</RangeSliderThumb>
</Tooltip>
</RangeSlider>
)}
/>
</>
);
}
@@ -0,0 +1,80 @@
import {
Box,
FormLabel,
Slider,
SliderFilledTrack,
SliderThumb,
SliderTrack,
Tooltip,
} from "@chakra-ui/react";
import { Controller, ControllerProps } from "react-hook-form";
import { FaWalking } from "react-icons/fa";
type CustomSliderProps = {
label: string;
defaultValue: [number, number];
sliderDistanceValue: number;
setSliderDistanceValue: React.Dispatch<React.SetStateAction<number>>;
showTooltipDistance: boolean;
setShowTooltipDistance: React.Dispatch<React.SetStateAction<boolean>>;
name: string;
} & Omit<ControllerProps, "render">;
export default function CustomSlider(props: CustomSliderProps) {
const {
defaultValue,
label,
sliderDistanceValue,
setSliderDistanceValue,
showTooltipDistance,
setShowTooltipDistance,
name,
...controllerProps
} = props;
return (
<>
<FormLabel as={"legend"} htmlFor={name}>
{label}
</FormLabel>
<Controller
{...controllerProps}
name={name}
render={({ field: { onChange } }) => (
<Slider
aria-label={"distance"}
colorScheme={"purple"}
min={20}
max={250}
id={"distance"}
color={"pink.500"}
defaultValue={defaultValue}
onChange={(v) => {
setSliderDistanceValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipDistance(true)}
onMouseLeave={() => setShowTooltipDistance(false)}
>
<SliderTrack>
<SliderFilledTrack bgColor={"purple.500"} />
</SliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipDistance}
label={`${sliderDistanceValue} km`}
>
<SliderThumb boxSize={6}>
<Box color={"purple.500"} as={FaWalking} />
</SliderThumb>
</Tooltip>
</Slider>
)}
/>
</>
);
}
@@ -6,7 +6,7 @@ export default function ProfileBadgeList(props) {
<Flex gap={"0.5rem"} mt={"1vh"} flexWrap="wrap"> <Flex gap={"0.5rem"} mt={"1vh"} flexWrap="wrap">
{userPassions.map((idPassion, index) => ( {userPassions.map((idPassion, index) => (
<Tag key={index} colorScheme={"purple"}> <Tag key={index} colorScheme={"purple"}>
{passions !== null && passions !== undefined {passions !== null && passions !== undefined && passions.length > 0
? passions.find((element) => element.id === idPassion).name ? passions.find((element) => element.id === idPassion).name
: ""} : ""}
</Tag> </Tag>
+92 -321
View File
@@ -9,27 +9,9 @@ import {
Center, Center,
Container, Container,
Divider, Divider,
Editable,
EditableInput,
EditablePreview,
EditableTextarea,
Flex, Flex,
FormControl,
FormErrorMessage,
FormLabel, FormLabel,
HStack,
Radio,
RadioGroup,
RangeSlider,
RangeSliderFilledTrack,
RangeSliderThumb,
RangeSliderTrack,
Slider,
SliderFilledTrack,
SliderThumb,
SliderTrack,
Text, Text,
Tooltip,
useToast, useToast,
VStack, VStack,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
@@ -38,11 +20,14 @@ import ModalModifyImages from "@/components/layout/user_profile/ModalModifyImage
import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePassion"; import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePassion";
import ProfileTagList from "@/components/layout/user_profile/ProfileTagList"; import ProfileTagList from "@/components/layout/user_profile/ProfileTagList";
import LoadingPage from "@/components/LoadingPage"; import LoadingPage from "@/components/LoadingPage";
import CustomEditable from "@/components/layout/user_profile/CustomEditable";
import { FaGreaterThan, FaLessThan, FaWalking } from "react-icons/fa"; import CustomEditableArea from "@/components/layout/user_profile/CustomEditableArea";
import CustomRadioGender from "@/components/layout/user_profile/CustomRadioGender";
import CustomRangeSlider from "@/components/layout/user_profile/CustomRangeSlider";
import CustomSlider from "@/components/layout/user_profile/CustomSlider";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form"; import { useForm } from "react-hook-form";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
export default function UserProfile() { export default function UserProfile() {
@@ -50,18 +35,18 @@ export default function UserProfile() {
const toast = useToast({ position: "top", isClosable: true }); const toast = useToast({ position: "top", isClosable: true });
const [currentlyLoading, setCurrentlyLoading] = useState(false); const [currentlyLoading, setCurrentlyLoading] = useState(false);
const [passions, setPassions] = useState(null); const [passions, setPassions] = useState([] as any[]);
const [showTooltipAge, setShowTooltipAge] = useState(true); const [showTooltipAge, setShowTooltipAge] = useState(false);
const [sliderAgeValue, setSliderAgeValue] = useState([] as number[]); const [sliderAgeValue, setSliderAgeValue] = useState([[] as number[]]);
// const [showTooltipDistance, setShowTooltipDistance] = useState(true); const [showTooltipDistance, setShowTooltipDistance] = useState(false);
// const [sliderDistanceValue, setSliderDistanceValue] = useState([]); const [sliderDistanceValue, setSliderDistanceValue] = useState<number>(0);
const { const {
handleSubmit, handleSubmit,
control, control,
formState: { errors }, formState: { errors },
} = useForm(); } = useForm({ mode: "onBlur" });
useEffect(() => { useEffect(() => {
fetch(`/api/passions`) fetch(`/api/passions`)
@@ -88,7 +73,7 @@ export default function UserProfile() {
const { user } = session as unknown as Session; const { user } = session as unknown as Session;
setSliderAgeValue([user.ageMin, user.ageMax]); setSliderAgeValue([user.ageMin, user.ageMax]);
// setSliderDistanceValue(user.distance); setSliderDistanceValue(user.distance);
return fetch(`/api/users/${user.id}`) return fetch(`/api/users/${user.id}`)
.then((res) => res.json()) .then((res) => res.json())
@@ -112,19 +97,6 @@ export default function UserProfile() {
if (status === "unauthenticated") router.push("/"); if (status === "unauthenticated") router.push("/");
} }
const getTextGender = (gender: string) => {
switch (gender) {
case Gender.MALE:
return "Homme";
case Gender.FEMALE:
return "Femme";
case Gender.OTHER:
return "Autre";
case Gender.UNKNOWN:
return "Non renseigné";
}
};
const saveData = (values: any) => { const saveData = (values: any) => {
let trueValues = {}; let trueValues = {};
console.log(values); console.log(values);
@@ -208,77 +180,34 @@ export default function UserProfile() {
<Box as="form" onSubmit={handleSubmit(saveData)} width={"80%"}> <Box as="form" onSubmit={handleSubmit(saveData)} width={"80%"}>
<Flex width={"100%"} justify={"space-between"} mb={"1rem"}> <Flex width={"100%"} justify={"space-between"} mb={"1rem"}>
<Box> <Box>
<FormControl id="firstName" isInvalid={errors.firstName}> <CustomEditable
<FormLabel as="legend" htmlFor={"firstName"}> name="firstName"
Prénom : defaultValue={
</FormLabel> userData.firstName === null ? "" : userData.firstName
<Controller }
name={"firstName"} control={control}
control={control} rules={{
defaultValue={ required: { value: true, message: "Prénom requis" },
userData.firstName === null ? "" : userData.firstName }}
} label={"Prénom :"}
rules={{ />
required: { value: true, message: "Prénom requis" },
}}
render={({ field }) => {
return (
<Editable
{...field}
id={"firstName"}
as={"b"}
placeholder={"Non renseigné"}
>
<EditablePreview />
<EditableInput />
</Editable>
);
}}
/>
<FormErrorMessage as="b">
{errors.firstName?.message}
</FormErrorMessage>
</FormControl>
</Box> </Box>
<Box> <Box>
<FormControl id="lastName" isInvalid={errors.lastName}> <CustomEditable
<FormLabel as={"legend"} htmlFor={"lastName"}> name="lastName"
Nom : defaultValue={
</FormLabel> userData.lastName === null ? "" : userData.lastName
<Controller }
name={"lastName"} control={control}
control={control} rules={{
defaultValue={ required: { value: true, message: "Nom requis" },
userData.lastName === null ? "" : userData.lastName }}
} label={"Nom :"}
rules={{ />
required: { value: true, message: "Nom requis" },
}}
render={({ field }) => (
<Editable
{...field}
id={"lastName"}
as={"b"}
placeholder={"Non renseigné"}
>
<EditablePreview />
<EditableInput />
</Editable>
)}
/>
<FormErrorMessage as={"b"}>
{errors.lastName?.message}
</FormErrorMessage>
</FormControl>
</Box> </Box>
<Box> <Box>
<FormLabel as={"legend"} htmlFor={"birthdate"}> <CustomEditable
Date de naissance : name="birthdate"
</FormLabel>
<Editable
id={"birthdate"}
as="b"
color={"grey"}
isDisabled={true} isDisabled={true}
defaultValue={ defaultValue={
userData.birthdate === undefined || userData.birthdate === undefined ||
@@ -286,118 +215,61 @@ export default function UserProfile() {
? "Non renseigné" ? "Non renseigné"
: formateDate(userData.birthdate.toString()) : formateDate(userData.birthdate.toString())
} }
> control={control}
<EditablePreview /> label={"Date de naissance :"}
</Editable> />
</Box> </Box>
</Flex> </Flex>
<Divider colorScheme={"purple"} /> <Divider colorScheme={"purple"} />
<Flex justify={"space-between"} my={"1rem"}> <Flex justify={"space-between"} my={"1rem"}>
<Box> <Box>
<FormLabel as={"legend"} htmlFor={"location"}> <CustomEditable
Ville : name="location"
</FormLabel>
<Editable
id={"location"}
as="b"
color={"grey"}
isDisabled={true} isDisabled={true}
defaultValue={ defaultValue={
userData.location === null || userData.location === "" userData.location === null || userData.location === ""
? "Rendez vous sur la carte" ? "Rendez vous sur la carte"
: userData.location : userData.location
} }
> control={control}
<EditablePreview /> label={"Ville :"}
</Editable> />
</Box> </Box>
<Box> <Box>
<FormLabel as={"legend"} htmlFor={"email"}> <CustomEditable
Adresse mail : name="email"
</FormLabel>
<Editable
id={"email"}
as="b"
color={"grey"}
isDisabled={true} isDisabled={true}
defaultValue={userData.email} defaultValue={userData.email}
> control={control}
<EditablePreview /> label={"Adresse mail :"}
</Editable> />
</Box> </Box>
</Flex> </Flex>
<Divider colorScheme={"purple"} /> <Divider colorScheme={"purple"} />
<Box my={"1rem"}> <Box my={"1rem"}>
<FormControl id="lastName" isInvalid={errors.bio}> <CustomEditableArea
<FormLabel as={"legend"} htmlFor={"bio"}> name="bio"
À propos : defaultValue={userData.bio === null ? "" : userData.bio}
</FormLabel> control={control}
<Controller rules={{
name={"bio"} maxLength: {
control={control} value: 240,
defaultValue={userData.bio === null ? "" : userData.bio} message: "240 caractères maximum",
rules={{ },
maxLength: { }}
value: 240, label={"À propos :"}
message: "240 caractères maximum", />
},
}}
render={({ field }) => (
<Editable
{...field}
id={"bio"}
as="b"
width={"100%"}
placeholder={"Non renseigné"}
defaultValue={userData.bio === null ? "" : userData.bio}
>
<EditablePreview />
<EditableTextarea />
</Editable>
)}
/>
<FormErrorMessage as="b">
{errors?.bio?.message ?? ""}
</FormErrorMessage>
</FormControl>
</Box> </Box>
<Divider colorScheme={"purple"} /> <Divider colorScheme={"purple"} />
<Box my={"1rem"}> <Box my={"1rem"}>
<Box> <Box>
<FormLabel as={"legend"} htmlFor={"gender"}> <CustomRadioGender
Genre :
</FormLabel>
<Controller
name={"gender"} name={"gender"}
label={"Genre :"}
control={control} control={control}
render={({ field }) => ( defaultValue={
<RadioGroup userData.gender === null ? Gender.UNKNOWN : userData.gender
{...field} }
colorScheme={"purple"}
id={"gender"}
as="b"
defaultValue={
userData.gender === null
? Gender.UNKNOWN
: userData.gender
}
>
<HStack spacing={"0.5rem"}>
<Radio value={Gender.MALE}>
{getTextGender(Gender.MALE)}
</Radio>
<Radio value={Gender.FEMALE}>
{getTextGender(Gender.FEMALE)}
</Radio>
<Radio value={Gender.OTHER}>
{getTextGender(Gender.OTHER)}
</Radio>
<Radio value={Gender.UNKNOWN}>
{getTextGender(Gender.UNKNOWN)}
</Radio>
</HStack>
</RadioGroup>
)}
/> />
</Box> </Box>
</Box> </Box>
@@ -426,139 +298,39 @@ export default function UserProfile() {
</Text> </Text>
</Center> </Center>
<Box my={"1rem"}> <Box my={"1rem"}>
<FormLabel as={"legend"} htmlFor={"prefGender"}> <CustomRadioGender
Genre :
</FormLabel>
<Controller
name={"prefGender"} name={"prefGender"}
label={"Genre :"}
control={control} control={control}
render={({ field }) => ( defaultValue={
<RadioGroup userData.prefGender === null
{...field} ? Gender.UNKNOWN
colorScheme={"purple"} : userData.gender
id={"prefGender"} }
as="b"
defaultValue={
userData.prefGender === null
? Gender.UNKNOWN
: userData.gender
}
>
<HStack spacing={"0.5rem"}>
<Radio value={Gender.MALE}>
{getTextGender(Gender.MALE)}
</Radio>
<Radio value={Gender.FEMALE}>
{getTextGender(Gender.FEMALE)}
</Radio>
<Radio value={Gender.OTHER}>
{getTextGender(Gender.OTHER)}
</Radio>
<Radio value={Gender.UNKNOWN}>
{getTextGender(Gender.UNKNOWN)}
</Radio>
</HStack>
</RadioGroup>
)}
/> />
</Box> </Box>
<Box> <Box>
<FormLabel as={"legend"} htmlFor={"prefGender"}> <CustomRangeSlider
Age :
</FormLabel>
<Controller
name={"age"}
control={control} control={control}
render={({ field: { onChange } }) => ( label={"Age :"}
<RangeSlider name={"age"}
aria-label={["min", "max"]} defaultValue={[userData.ageMin, userData.ageMax]}
colorScheme={"purple"} setSliderAgeValue={setSliderAgeValue}
min={18} setShowTooltipAge={setShowTooltipAge}
max={99} showTooltipAge={showTooltipAge}
id={"age"} sliderAgeValue={sliderAgeValue}
color={"pink.500"}
defaultValue={[userData.ageMin, userData.ageMax]}
onChange={(v) => {
setSliderAgeValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipAge(true)}
onMouseLeave={() => setShowTooltipAge(false)}
>
<RangeSliderTrack>
<RangeSliderFilledTrack bgColor={"purple.500"} />
</RangeSliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[0]}`}
>
<RangeSliderThumb boxSize={6} index={0}>
<Box color={"purple.500"} as={FaLessThan} />
</RangeSliderThumb>
</Tooltip>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[1]}`}
>
<RangeSliderThumb boxSize={6} index={1}>
<Box color={"purple.500"} as={FaGreaterThan} />
</RangeSliderThumb>
</Tooltip>
</RangeSlider>
)}
/> />
</Box> </Box>
{/* <Box> <CustomSlider
<FormLabel as={"legend"} htmlFor={"distance"}> control={control}
Distance : label={"Distance :"}
</FormLabel> name={"distance"}
<Controller defaultValue={userData.distance}
name={"distance"} setSliderDistanceValue={setSliderDistanceValue}
control={control} setShowTooltipDistance={setShowTooltipDistance}
render={({ field: { onChange } }) => ( showTooltipDistance={showTooltipDistance}
<Slider sliderDistanceValue={sliderDistanceValue}
aria-label={"distance"} />
colorScheme={"purple"}
min={20}
max={250}
id={"distance"}
color={"pink.500"}
defaultValue={userData.distance}
onChange={(v) => {
setSliderDistanceValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipDistance(true)}
onMouseLeave={() => setShowTooltipDistance(false)}
>
<SliderTrack>
<SliderFilledTrack bgColor={"purple.500"} />
</SliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipDistance}
label={`${sliderDistanceValue} km`}
>
<SliderThumb boxSize={6}>
<Box color={"purple.500"} as={FaWalking} />
</SliderThumb>
</Tooltip>
</Slider>
)}
/>
</Box> */}
</Box> </Box>
<Divider colorScheme={"purple"} /> <Divider colorScheme={"purple"} />
<Center gap={"1rem"} my={"1rem"}> <Center gap={"1rem"} my={"1rem"}>
@@ -584,5 +356,4 @@ export default function UserProfile() {
</Container> </Container>
</Box> </Box>
); );
// }
} }
+30
View File
@@ -4267,6 +4267,11 @@
"object-assign" "^4.1.1" "object-assign" "^4.1.1"
"react-is" "^16.13.1" "react-is" "^16.13.1"
"property-expr@^2.0.5":
"integrity" "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
"resolved" "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz"
"version" "2.0.5"
"punycode@^2.1.0": "punycode@^2.1.0":
"integrity" "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" "integrity" "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
"resolved" "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
@@ -4954,6 +4959,11 @@
"resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" "resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
"version" "0.2.0" "version" "0.2.0"
"tiny-case@^1.0.3":
"integrity" "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="
"resolved" "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz"
"version" "1.0.3"
"tiny-glob@^0.2.9": "tiny-glob@^0.2.9":
"integrity" "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==" "integrity" "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg=="
"resolved" "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz" "resolved" "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz"
@@ -4991,6 +5001,11 @@
"resolved" "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" "resolved" "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz"
"version" "1.0.6" "version" "1.0.6"
"toposort@^2.0.2":
"integrity" "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
"resolved" "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz"
"version" "2.0.2"
"tr46@~0.0.3": "tr46@~0.0.3":
"integrity" "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" "integrity" "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
"resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
@@ -5094,6 +5109,11 @@
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz"
"version" "0.8.1" "version" "0.8.1"
"type-fest@^2.19.0":
"integrity" "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz"
"version" "2.19.0"
"typed-array-length@^1.0.4": "typed-array-length@^1.0.4":
"integrity" "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==" "integrity" "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng=="
"resolved" "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" "resolved" "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz"
@@ -5312,6 +5332,16 @@
"resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
"version" "0.1.0" "version" "0.1.0"
"yup@^1.1.1":
"integrity" "sha512-KfCGHdAErqFZWA5tZf7upSUnGKuTOnsI3hUsLr7fgVtx+DK04NPV01A68/FslI4t3s/ZWpvXJmgXhd7q6ICnag=="
"resolved" "https://registry.npmjs.org/yup/-/yup-1.1.1.tgz"
"version" "1.1.1"
dependencies:
"property-expr" "^2.0.5"
"tiny-case" "^1.0.3"
"toposort" "^2.0.2"
"type-fest" "^2.19.0"
"zip-stream@^4.1.0": "zip-stream@^4.1.0":
"integrity" "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==" "integrity" "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A=="
"resolved" "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz" "resolved" "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz"