From 485d7951520026bab19e9cc5d374d80bf65541b2 Mon Sep 17 00:00:00 2001 From: Anthony RICHARD Date: Wed, 29 Jan 2025 13:17:10 +0100 Subject: [PATCH] Add quiz behind --- app/(quiz)/quiz.tsx | 116 +++++++++---- assets/images/wheelchair.png | Bin 0 -> 40203 bytes components/BackButton.tsx | 10 +- components/CheckBox.tsx | 149 +++++++++++++++++ components/CheckButtonComponent.tsx | 68 -------- components/CheckboxComponent.tsx | 34 ---- components/Icons.tsx | 27 ++- components/form/FormError.tsx | 6 +- components/form/FormInput.tsx | 13 +- components/form/LoginForm.tsx | 5 +- components/form/SecretTextInput.tsx | 8 +- components/form/SigninForm.tsx | 5 +- components/modals/CodeSent.tsx | 6 +- components/quiz/ActivityQuestion.tsx | 144 ++++++++-------- components/quiz/AgeQuestion.tsx | 37 +++-- components/quiz/BeginnerQuestion.tsx | 54 ++++-- components/quiz/FrequencyQuestion.tsx | 25 ++- components/quiz/GenderQuestion.tsx | 96 +++++------ components/quiz/GoalQuestion.tsx | 108 ++++++++---- components/quiz/HeightQuestion.tsx | 37 +++-- components/quiz/IllnessQuestion.tsx | 54 ++++++ components/quiz/LvlQuestion.tsx | 15 -- components/quiz/Question.tsx | 5 +- components/quiz/SleepQuestion.tsx | 157 ++++++++++-------- components/quiz/SportQuestion.tsx | 230 +++++++++----------------- components/quiz/WeightQuestion.tsx | 45 +++-- components/ui/Button.tsx | 17 +- components/ui/Screen.tsx | 5 +- components/ui/Slider.tsx | 5 +- components/ui/Text.tsx | 18 +- model/User.ts | 146 ++++++++++++++++ model/enums/Enums.ts | 42 +++++ package-lock.json | 17 ++ package.json | 1 + 34 files changed, 1066 insertions(+), 639 deletions(-) create mode 100644 assets/images/wheelchair.png create mode 100644 components/CheckBox.tsx delete mode 100644 components/CheckButtonComponent.tsx delete mode 100644 components/CheckboxComponent.tsx create mode 100644 components/quiz/IllnessQuestion.tsx delete mode 100644 components/quiz/LvlQuestion.tsx create mode 100644 model/User.ts create mode 100644 model/enums/Enums.ts diff --git a/app/(quiz)/quiz.tsx b/app/(quiz)/quiz.tsx index 41f80ac..91ac624 100644 --- a/app/(quiz)/quiz.tsx +++ b/app/(quiz)/quiz.tsx @@ -1,57 +1,107 @@ import BackButton from "@/components/BackButton"; import { toBgColor, toTextColor } from "@/components/Constants"; +import WeightQuestion, { + WeightQuestionRef, +} from "@/components/quiz/WeightQuestion"; +import React, { useRef, useState } from "react"; +import { View } from "react-native"; import Button from "@/components/ui/Button"; import Screen from "@/components/ui/Screen"; import Text from "@/components/ui/Text"; -import React from "react"; -import { View } from "react-native"; -import FrequencyQuestion from "@/components/quiz/FrequencyQuestion"; -import GoalQuestion from "@/components/quiz/GoalQuestion"; -import GenderQuestion from "@/components/quiz/GenderQuestion"; -import WeightQuestion from "@/components/quiz/WeightQuestion"; -import HeightQuestion from "@/components/quiz/HeightQuestion"; -import AgeQuestion from "@/components/quiz/AgeQuestion"; -import BeginnerQuestion from "@/components/quiz/BeginnerQuestion"; -import LvlQuestion from "@/components/quiz/LvlQuestion"; -import SleepQuestion from "@/components/quiz/SleepQuestion"; -import SportQuestion from "@/components/quiz/SportQuestion"; +import FrequencyQuestion, { + FrequencyQuestionRef, +} from "@/components/quiz/FrequencyQuestion"; +import GoalQuestion, { GoalQuestionRef } from "@/components/quiz/GoalQuestion"; +import GenderQuestion, { + GenderQuestionRef, +} from "@/components/quiz/GenderQuestion"; +import HeightQuestion, { + HeightQuestionRef, +} from "@/components/quiz/HeightQuestion"; +import AgeQuestion, { AgeQuestionRef } from "@/components/quiz/AgeQuestion"; +import BeginnerQuestion, { + BeginnerQuestionRef, +} from "@/components/quiz/BeginnerQuestion"; +import ActivityQuestion, { + ActivityQuestionRef, +} from "@/components/quiz/ActivityQuestion"; +import SportQuestion, { + SportQuestionRef, +} from "@/components/quiz/SportQuestion"; +import SleepQuestion, { + SleepQuestionRef, +} from "@/components/quiz/SleepQuestion"; export default function Quiz() { - const [currentQuestionIndex, setCurrentQuestionIndex] = React.useState(0); + const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); + const goalRef = useRef(null); + const genderRef = useRef(null); + const weightRef = useRef(null); + const heightRef = useRef(null); + const ageRef = useRef(null); + const beginnerRef = useRef(null); + const activityRef = useRef(null); + const frequencyRef = useRef(null); + const sportQuestionRef = useRef(null); + const sleepQuestionRef = useRef(null); + interface Question { component: React.ForwardRefExoticComponent>; props: T; } + const questions: Question[] = [ - { component: GoalQuestion, props: {} }, - { component: GenderQuestion, props: {} }, - { component: WeightQuestion, props: {} }, - { component: HeightQuestion, props: {} }, - { component: AgeQuestion, props: {} }, - { component: BeginnerQuestion, props: {} }, - { component: LvlQuestion, props: {} }, - { component: FrequencyQuestion, props: { isMale: true } }, - { component: SportQuestion, props: {} }, - { component: SleepQuestion, props: {} }, + { component: GoalQuestion, props: { ref: goalRef } }, + { component: GenderQuestion, props: { ref: genderRef } }, + { + component: WeightQuestion, + props: { ref: weightRef }, + }, + { component: HeightQuestion, props: { ref: heightRef } }, + { component: AgeQuestion, props: { ref: ageRef } }, + { component: BeginnerQuestion, props: { ref: beginnerRef } }, + { component: ActivityQuestion, props: { ref: activityRef } }, + //{ component: IllnessQuestion, props: {} }, + { + component: FrequencyQuestion, + props: { ref: frequencyRef, isMale: genderRef.current?.getAnswer() }, + }, + { component: SportQuestion, props: { ref: sportQuestionRef } }, + { component: SleepQuestion, props: { ref: sleepQuestionRef } }, ]; - const goBack = () => { - if (currentQuestionIndex >= 1) { - setCurrentQuestionIndex(currentQuestionIndex - 1); - } - }; - const goNext = () => { if (currentQuestionIndex < questions.length - 1) { setCurrentQuestionIndex(currentQuestionIndex + 1); + } else { + collect(); } }; + const collect = () => { + console.log("Goal:", goalRef.current?.getAnswer()); + console.log("Sexe:", genderRef.current?.getAnswer()); + console.log("Weight:", weightRef.current?.getAnswer()); + console.log("Height:", heightRef.current?.getAnswer()); + console.log("Age:", ageRef.current?.getAnswer()); + console.log("Beginner:", beginnerRef.current?.getAnswer()); + console.log("Activity:", activityRef.current?.getAnswer()); + console.log("Frequency:", frequencyRef.current?.getAnswer()); + console.log("Sport:", sportQuestionRef.current?.getAnswer()); + console.log("Sleep:", sleepQuestionRef.current?.getAnswer()); + }; + return ( - - + + setCurrentQuestionIndex((i) => Math.max(i - 1, 0))} + /> + + Questionnaire + {currentQuestionIndex + 1} sur {questions.length} @@ -66,7 +116,9 @@ export default function Quiz() { }) )} diff --git a/assets/images/wheelchair.png b/assets/images/wheelchair.png new file mode 100644 index 0000000000000000000000000000000000000000..e6005c3ae5a0cc9d66c11312b96f422812670dfd GIT binary patch literal 40203 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 - (props, ref): React.ReactElement => { - const { icon, onPress } = props; + ({ icon, onPress, className, ...props }, ref): React.ReactElement => { const defaultOnPress = () => { router.back(); }; return ( diff --git a/components/CheckBox.tsx b/components/CheckBox.tsx new file mode 100644 index 0000000..6827d96 --- /dev/null +++ b/components/CheckBox.tsx @@ -0,0 +1,149 @@ +import React, { forwardRef } from "react"; +import { View, TouchableOpacity, ViewProps } from "react-native"; +import Text from "./ui/Text"; +import { + AntDesign, + Entypo, + FontAwesome6, + Ionicons, + MaterialCommunityIcons, +} from "@expo/vector-icons"; +import { + AntDesignIconNames, + CommunityIconNames, + EntypoIconNames, + FontAwesome6IconNames, + FontAwesomeIconNames, + IonIconNames, +} from "./Icons"; + +export type CheckBoxDirection = "row" | "col"; + +interface CheckBoxProps extends ViewProps { + label?: string; + onChange: () => void; + antIcon?: AntDesignIconNames; + entypoIcon?: EntypoIconNames; + fontAwesomeIcon?: FontAwesomeIconNames; + fontAwesome6Icon?: FontAwesome6IconNames; + communityIcon?: CommunityIconNames; + IonIcon?: IonIconNames; + value: boolean; + isCheckIconVisible?: boolean; + endText?: string; + direction?: CheckBoxDirection; +} + +export default forwardRef( + ( + { + label, + onChange, + antIcon, + entypoIcon, + fontAwesomeIcon, + fontAwesome6Icon, + communityIcon, + IonIcon, + value, + isCheckIconVisible, + endText, + direction, + className, + ...props + }, + ref + ) => { + return ( + + + {antIcon ? ( + + ) : null} + {entypoIcon ? ( + + ) : null} + {communityIcon ? ( + + ) : null} + {fontAwesomeIcon ? ( + + ) : null} + {fontAwesome6Icon ? ( + + ) : null} + {IonIcon ? ( + + ) : null} + + + {label != null ? ( + + {label} + + ) : null} + + {isCheckIconVisible ? ( + + {value && } + + ) : null} + + {endText != null ? ( + {endText} + ) : null} + + ); + } +); diff --git a/components/CheckButtonComponent.tsx b/components/CheckButtonComponent.tsx deleted file mode 100644 index 0340f2c..0000000 --- a/components/CheckButtonComponent.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, {Component} from "react"; -import {View, Text, TouchableOpacity, Image} from "react-native"; -import { - AntDesign, - Entypo, - FontAwesome6, - MaterialCommunityIcons, -} from "@expo/vector-icons"; -import { - AntDesignIconNames, - CommunityIconNames, - EntypoIconNames, - FontAwesomeIconNames, -} from "./Icons"; - -interface CheckButtonProps { - label: string; - value: boolean; - onChange: () => void; - antIcon?: AntDesignIconNames; - entypoIcon?: EntypoIconNames; - fontAwesomeIcon?: FontAwesomeIconNames; - communityIcon?: CommunityIconNames; -} - -const CheckButton: React.FC = ({ label, value, onChange, antIcon, - entypoIcon, - fontAwesomeIcon, - communityIcon, }) => { - return ( - - - {antIcon ? ( - - ) : null} - {entypoIcon ? ( - - ) : null} - {communityIcon ? ( - - ) : null} - {fontAwesomeIcon ? ( - - ) : null} - - {label} - - - ); -}; - -export default CheckButton; \ No newline at end of file diff --git a/components/CheckboxComponent.tsx b/components/CheckboxComponent.tsx deleted file mode 100644 index 9103363..0000000 --- a/components/CheckboxComponent.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, {Component} from "react"; -import {View, Text, TouchableOpacity, Image} from "react-native"; -import {AntDesign, FontAwesome6} from "@expo/vector-icons"; -import {AntDesignIconNames} from "./Icons"; - -interface CheckBoxProps { - label: string; - value: boolean; - onChange: () => void; - icon: AntDesignIconNames | string; -} - -const CheckBox: React.FC = ({ label, value, onChange, icon }) => { - let AwesomIconList = ["weight-scale", "beer"]; - return ( - - - {AwesomIconList.includes(icon) ? ( - - ) : ( - - )} - - - {label} - - - {value && } - - - ); -}; - -export default CheckBox; \ No newline at end of file diff --git a/components/Icons.tsx b/components/Icons.tsx index 22831ae..272d8ee 100644 --- a/components/Icons.tsx +++ b/components/Icons.tsx @@ -1,3 +1,26 @@ -import { AntDesign } from "@expo/vector-icons"; +import { + AntDesign, + Entypo, + FontAwesome, + Ionicons, + MaterialCommunityIcons, +} from "@expo/vector-icons"; -export type AntDesignIconNames = keyof typeof AntDesign.glyphMap; \ No newline at end of file +export type AntDesignIconNames = keyof typeof AntDesign.glyphMap; +export type EntypoIconNames = keyof typeof Entypo.glyphMap; +export type FontAwesomeIconNames = keyof typeof FontAwesome.glyphMap; +export type FontAwesome6IconNames = + | "person-running" + | "person-walking" + | "person-hiking" + | "skateboarding" + | "bike" + | "basketball" + | "heart" + | "yoga" + | "setting" + | "beer" + | "shield-heart" + | "weight-scale"; +export type CommunityIconNames = keyof typeof MaterialCommunityIcons.glyphMap; +export type IonIconNames = keyof typeof Ionicons.glyphMap; diff --git a/components/form/FormError.tsx b/components/form/FormError.tsx index c0c16af..7e640ae 100644 --- a/components/form/FormError.tsx +++ b/components/form/FormError.tsx @@ -8,9 +8,7 @@ interface Props extends ExtendedTextProps { } export default React.forwardRef( - (props, ref): React.ReactElement => { - const { isVisible, ...rest } = props; - + ({ isVisible, ...props }, ref): React.ReactElement => { const buildClassName = (): string => { return ( "flex-row items-center gap-2 bg-red-300 p-4 border-2 border-red-500 rounded-3xl" + @@ -22,7 +20,7 @@ export default React.forwardRef( return ( - + ); } diff --git a/components/form/FormInput.tsx b/components/form/FormInput.tsx index 340d082..c348e35 100644 --- a/components/form/FormInput.tsx +++ b/components/form/FormInput.tsx @@ -12,8 +12,8 @@ interface Props extends FormInputProps { } export default React.forwardRef( - (props, ref): React.ReactElement => { - const { + ( + { onBlur, onChangeText, value, @@ -22,9 +22,10 @@ export default React.forwardRef( label, placeholder, onPress, - ...rest - } = props; - + ...props + }, + ref + ): React.ReactElement => { return ( {label} @@ -37,7 +38,7 @@ export default React.forwardRef( onChangeText={onChangeText} value={value} {...ref} - {...rest} + {...props} /> {afterIcon != null ? ( diff --git a/components/form/LoginForm.tsx b/components/form/LoginForm.tsx index b43e57d..7d8bbbb 100644 --- a/components/form/LoginForm.tsx +++ b/components/form/LoginForm.tsx @@ -10,8 +10,7 @@ import { useSession } from "@/ctx"; import { router } from "expo-router"; export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; + ({ ...props }, ref): React.ReactElement => { const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const [error, setError] = React.useState(""); @@ -47,7 +46,7 @@ export default React.forwardRef( }; return ( - + ( - (props, ref): React.ReactElement => { - const { onBlur, onChangeText, value, label, ...rest } = props; + ( + { onBlur, onChangeText, value, label, ...props }, + ref + ): React.ReactElement => { const [showPassword, setShowPassword] = useState(false); const toggleShowPassword = () => { @@ -22,7 +24,7 @@ export default React.forwardRef( onPress={toggleShowPassword} secureTextEntry={!showPassword} {...ref} - {...rest} + {...props} /> ); } diff --git a/components/form/SigninForm.tsx b/components/form/SigninForm.tsx index c1e5a1e..9c574df 100644 --- a/components/form/SigninForm.tsx +++ b/components/form/SigninForm.tsx @@ -8,8 +8,7 @@ import { EMPTY_FIELD, INVALID_EMAIL, NOT_MATCHING_PASSWORD } from "../Errors"; import FormError from "./FormError"; export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; + ({ ...props }, ref): React.ReactElement => { const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const [confirmPassword, setConfirmPassword] = React.useState(""); @@ -52,7 +51,7 @@ export default React.forwardRef( }; return ( - + ( - (props, ref): React.ReactElement => { - const { email, onPress, ...rest } = props; - + ({ email, onPress, ...props }, ref): React.ReactElement => { return ( - + diff --git a/components/quiz/ActivityQuestion.tsx b/components/quiz/ActivityQuestion.tsx index e72d312..b8f5a05 100644 --- a/components/quiz/ActivityQuestion.tsx +++ b/components/quiz/ActivityQuestion.tsx @@ -1,78 +1,78 @@ -import React from "react"; +import React, { useImperativeHandle, useState } from "react"; import Question, { QuestionChildProps } from "./Question"; -import Checkbox from "../CheckboxComponent"; -import {View} from "react-native"; -import {FontAwesome6} from "@expo/vector-icons"; +import Checkbox from "../CheckBox"; +import { View } from "react-native"; +import { + CommunityIconNames, + AntDesignIconNames, + EntypoIconNames, + FontAwesome6IconNames, +} from "../Icons"; +import { ESportLevel, SportLevels } from "@/model/enums/Enums"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; +export interface ActivityQuestionRef { + getAnswer: () => ESportLevel; +} - const [checkedOne, setCheckedOne] = React.useState(true); - const [checkedTwo, setCheckedTwo] = React.useState(false); - const [checkedThree, setCheckedThree] = React.useState(false); - const [checkedFour, setCheckedFour] = React.useState(false); - const [checkedFive, setCheckedFive] = React.useState(false); - const handleChangeOne = () => { - if(!checkedOne) { - setCheckedOne(!checkedOne); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeTwo = () => { - if(!checkedTwo) { - setCheckedOne(false); - setCheckedTwo(!checkedTwo); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeThree = () => { - if(!checkedThree) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(!checkedThree); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeFour = () => { - if(!checkedFour) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(!checkedFour); - setCheckedFive(false); - } - }; - const handleChangeFive = () => { - if(!checkedFive) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(!checkedFive); - } - }; +export default React.forwardRef( + ({ ...props }, ref): React.ReactElement => { + const [checkedItems, setCheckedItems] = useState([ + true, + ...Array(4).fill(false), + ]); - return ( - - - - - - - - - - ); + const handleChange = (index: number) => { + const newCheckedState = checkedItems.map((_, i) => i === index); + setCheckedItems(newCheckedState); + }; + + useImperativeHandle(ref, () => ({ + getAnswer: () => { + var selected = 0; + checkedItems.forEach((item, index) => { + if (item) { + selected = index; + } + }); + return SportLevels[SportLevels.length - 1 - selected]; + }, + })); + + interface IData { + label: string; + commIcon?: CommunityIconNames; + antIcon?: AntDesignIconNames; + entypoIcon?: EntypoIconNames; + fontAwesomeIcon?: FontAwesome6IconNames; } + + const data: IData[] = [ + { label: "Athlète", antIcon: "smile-circle" }, + { label: "Très sportif", antIcon: "smileo" }, + { label: "Un peu sportif", antIcon: "meh" }, + { label: "Peu sportif", antIcon: "frowno" }, + { label: "Pas du tout sportif", antIcon: "frown" }, + ]; + + return ( + + + {data.map((item, index) => ( + handleChange(index)} + antIcon={item.antIcon} + endText={(data.length - index).toString()} + /> + ))} + + + ); + } ); diff --git a/components/quiz/AgeQuestion.tsx b/components/quiz/AgeQuestion.tsx index d262412..414a6ad 100644 --- a/components/quiz/AgeQuestion.tsx +++ b/components/quiz/AgeQuestion.tsx @@ -1,38 +1,53 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; import Slider from "../ui/Slider"; import { View } from "react-native"; import Text from "../ui/Text"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const MIN_AGE = 18; - const MAX_AGE = 100; - const [age, setAge] = React.useState(MIN_AGE); +const MIN_AGE = 18; +const MAX_AGE = 100; + +export interface AgeQuestionRef { + getAnswer: () => number; +} + +export default forwardRef( + (props, ref): ReactElement => { + const [answer, setAnswer] = useState(MIN_AGE); + + useImperativeHandle(ref, () => ({ + getAnswer: () => answer, + })); + return ( - {age <= MIN_AGE ? ( + {answer <= MIN_AGE ? ( - de ) : null} - {age >= MAX_AGE ? ( + {answer >= MAX_AGE ? ( + de ) : null} - {age} + {answer} - + ans ); diff --git a/components/quiz/BeginnerQuestion.tsx b/components/quiz/BeginnerQuestion.tsx index a6fb270..b694265 100644 --- a/components/quiz/BeginnerQuestion.tsx +++ b/components/quiz/BeginnerQuestion.tsx @@ -1,15 +1,35 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; -import SegmentedControl from "../ui/SegmentedControl"; -import { Image } from "react-native"; +import { Image, View } from "react-native"; //@ts-ignore import BenchImage from "@/assets/images/bench.png"; +import CheckBox from "../CheckBox"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const ANSWERS = ["Non", "Oui"]; - const [answer, setAnswer] = React.useState("Oui"); +export interface BeginnerQuestionRef { + getAnswer: () => boolean; +} + +export default forwardRef( + (props, ref): ReactElement => { + const [answer, setAnswer] = useState(false); + + useImperativeHandle(ref, () => ({ + getAnswer: () => answer, + })); + + function handleChangeOne() { + setAnswer(true); + } + + function handleChangeTwo() { + setAnswer(false); + } return ( ( {...props} > - + + + + ); } diff --git a/components/quiz/FrequencyQuestion.tsx b/components/quiz/FrequencyQuestion.tsx index 3b8d5a1..a228c6e 100644 --- a/components/quiz/FrequencyQuestion.tsx +++ b/components/quiz/FrequencyQuestion.tsx @@ -1,20 +1,33 @@ -import React from "react"; +import React, { useImperativeHandle } from "react"; import Question, { QuestionChildProps } from "./Question"; import Text from "../ui/Text"; import SegmentedControl from "../ui/SegmentedControl"; import { View } from "react-native"; +const ANSWERS = ["1", "2", "3", "4", "5"]; + +export interface FrequencyQuestionRef { + getAnswer: () => number; +} + export interface FrequencyQuestionProps extends QuestionChildProps { isMale: boolean; } -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { isMale, ...rest } = props; - const ANSWERS = ["1", "2", "3", "4", "5"]; +export default React.forwardRef( + ({ isMale, ...props }, ref): React.ReactElement => { const [answer, setAnswer] = React.useState("1"); + + useImperativeHandle(ref, () => ({ + getAnswer: () => parseInt(answer), + })); + return ( - + Je suis {isMale ? "prêt" : "prête"} à m'entraîner diff --git a/components/quiz/GenderQuestion.tsx b/components/quiz/GenderQuestion.tsx index 993b448..fe49795 100644 --- a/components/quiz/GenderQuestion.tsx +++ b/components/quiz/GenderQuestion.tsx @@ -1,51 +1,55 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; -import Checkbox from "../CheckboxComponent"; -import {View} from "react-native"; -import {FontAwesome6} from "@expo/vector-icons"; +import Checkbox from "../CheckBox"; +import { View } from "react-native"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; +export interface GenderQuestionRef { + getAnswer: () => boolean; +} - const [checkedOne, setCheckedOne] = React.useState(false); - const [checkedTwo, setCheckedTwo] = React.useState(false); - const [checkedThree, setCheckedThree] = React.useState(true); - const handleChangeOne = () => { - if(!checkedOne) - { - setCheckedOne(!checkedOne); - setCheckedTwo(false); - setCheckedThree(false); - } - }; - const handleChangeTwo = () => { - if(!checkedTwo) { - setCheckedOne(false); - setCheckedTwo(!checkedTwo); - setCheckedThree(false); - } - }; - const handleChangeThree = () => { - if(!checkedThree) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(!checkedThree); - } - }; +export default forwardRef( + ({ ...props }, ref): ReactElement => { + const [answer, setAnswer] = useState(true); - return ( - - - - - - - - ); - } + useImperativeHandle(ref, () => ({ + getAnswer: () => answer, + })); + + const handleChangeOne = () => { + setAnswer(true); + }; + const handleChangeTwo = () => { + setAnswer(false); + }; + + return ( + + + + + + + ); + } ); diff --git a/components/quiz/GoalQuestion.tsx b/components/quiz/GoalQuestion.tsx index cfa0978..80d4fb1 100644 --- a/components/quiz/GoalQuestion.tsx +++ b/components/quiz/GoalQuestion.tsx @@ -1,47 +1,87 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; -import Checkbox from "../CheckboxComponent"; -import {View} from "react-native"; -import {FontAwesome6} from "@expo/vector-icons"; +import { View } from "react-native"; +import { + CommunityIconNames, + AntDesignIconNames, + EntypoIconNames, + FontAwesome6IconNames, + IonIconNames, +} from "../Icons"; +import CheckBox from "../CheckBox"; +import { EGoal, Goals } from "@/model/enums/Enums"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; +export interface GoalQuestionRef { + getAnswer: () => EGoal; +} - const [checkedOne, setCheckedOne] = React.useState(true); - const [checkedTwo, setCheckedTwo] = React.useState(false); - const [checkedThree, setCheckedThree] = React.useState(false); - const [checkedFour, setCheckedFour] = React.useState(false); - const [checkedFive, setCheckedFive] = React.useState(false); - const handleChangeOne = () => { - setCheckedOne(!checkedOne); +export default forwardRef( + ({ ...props }, ref): ReactElement => { + const [checkedItems, setCheckedItems] = useState([ + true, + ...Array(4).fill(false), + ]); + + interface IData { + label: string; + commIcon?: CommunityIconNames; + antIcon?: AntDesignIconNames; + entypoIcon?: EntypoIconNames; + fontAwesomeIcon?: FontAwesome6IconNames; + ionIcon?: IonIconNames; + } + + const data: IData[] = [ + { label: "Perte de poids", commIcon: "weight" }, + { label: "Renforcement musculaire", commIcon: "arm-flex-outline" }, + { label: "Prise de masse", ionIcon: "beer-outline" }, + { label: "Amélioration endurance", fontAwesomeIcon: "shield-heart" }, + { label: "Maintenir en forme", antIcon: "linechart" }, + ]; + + const handleChange = (index: number) => { + const newCheckedState = checkedItems.map((_, i) => i === index); + setCheckedItems(newCheckedState); }; - const handleChangeTwo = () => { - setCheckedTwo(!checkedTwo); - }; - const handleChangeThree = () => { - setCheckedThree(!checkedThree); - }; - const handleChangeFour = () => { - setCheckedFour(!checkedFour); - }; - const handleChangeFive = () => { - setCheckedFive(!checkedFive); - }; + + useImperativeHandle(ref, () => ({ + getAnswer: () => { + var selected = 0; + checkedItems.forEach((item, index) => { + if (item) { + selected = index; + } + }); + return Goals[selected]; + }, + })); return ( - - - - - - - + + {data.map((item, index) => ( + handleChange(index)} + fontAwesome6Icon={item.fontAwesomeIcon} + communityIcon={item.commIcon} + antIcon={item.antIcon} + entypoIcon={item.entypoIcon} + IonIcon={item.ionIcon} + /> + ))} + ); } diff --git a/components/quiz/HeightQuestion.tsx b/components/quiz/HeightQuestion.tsx index ef4afe6..cb11bcb 100644 --- a/components/quiz/HeightQuestion.tsx +++ b/components/quiz/HeightQuestion.tsx @@ -1,17 +1,32 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; import Slider from "../ui/Slider"; import Text from "../ui/Text"; import { View } from "react-native"; import SegmentedControl from "../ui/SegmentedControl"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const MIN_HEIGHT = 120; - const MAX_HEIGHT = 250; +const MIN_HEIGHT = 120; +const MAX_HEIGHT = 250; + +export interface HeightQuestionRef { + getAnswer: () => number; +} + +export default forwardRef( + ({ ...props }, ref): ReactElement => { + const [answer, setAnswer] = useState(MIN_HEIGHT); const UNITS = ["cm", "inch"]; - const [height, setHeight] = React.useState(MIN_HEIGHT); - const [unit, setUnit] = React.useState("cm"); + const [unit, setUnit] = useState("cm"); + + useImperativeHandle(ref, () => ({ + getAnswer: () => answer, + })); + return ( ( onValueChange={setUnit} /> - {height <= MIN_HEIGHT ? ( + {answer <= MIN_HEIGHT ? ( - de ) : null} - {height >= MAX_HEIGHT ? ( + {answer >= MAX_HEIGHT ? ( + de ) : null} - {height} + {answer} {unit} @@ -40,7 +55,7 @@ export default React.forwardRef( ); diff --git a/components/quiz/IllnessQuestion.tsx b/components/quiz/IllnessQuestion.tsx new file mode 100644 index 0000000..4822d66 --- /dev/null +++ b/components/quiz/IllnessQuestion.tsx @@ -0,0 +1,54 @@ +import React, { useState } from "react"; +import Question, { QuestionChildProps } from "./Question"; +import { Image, View, Text } from "react-native"; +import { MultiSelect } from "react-native-element-dropdown"; + +//@ts-ignore +import WheelChair from "@/assets/images/wheelchair.png"; +import { EHealthProblem } from "@/model/enums/Enums"; + +export default React.forwardRef( + ({ ...props }, ref) => { + const [selected, setSelected] = useState([]); + + type DataItem = { + label: string; + value: EHealthProblem; + }; + + const data: DataItem[] = [ + { label: "Arthrose", value: "ARTHROSE" }, + { label: "Migraine", value: "MIGRAINE" }, + ]; + + const renderItem = (item: { label: string }) => { + return ( + + {item.label} + + ); + }; + + return ( + + + + + + + ); + } +); diff --git a/components/quiz/LvlQuestion.tsx b/components/quiz/LvlQuestion.tsx deleted file mode 100644 index df81f7c..0000000 --- a/components/quiz/LvlQuestion.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import Question, { QuestionChildProps } from "./Question"; - -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; - return ( - - ); - } -); diff --git a/components/quiz/Question.tsx b/components/quiz/Question.tsx index 1dea95d..84e0d9d 100644 --- a/components/quiz/Question.tsx +++ b/components/quiz/Question.tsx @@ -11,14 +11,13 @@ interface QuestionProps extends QuestionChildProps { } export default React.forwardRef( - (props, ref): React.ReactElement => { - const { question, isVisible, children, ...rest } = props; + ({ question, isVisible, children, ...props }, ref): React.ReactElement => { const getClassName = () => { return "gap-6" + " " + (isVisible ? "block" : "hidden"); }; return ( - + {question} diff --git a/components/quiz/SleepQuestion.tsx b/components/quiz/SleepQuestion.tsx index f7d36a9..6dd9752 100644 --- a/components/quiz/SleepQuestion.tsx +++ b/components/quiz/SleepQuestion.tsx @@ -1,78 +1,91 @@ -import React from "react"; +import React, { useImperativeHandle, useState } from "react"; import Question, { QuestionChildProps } from "./Question"; -import Checkbox from "../CheckboxComponent"; -import {View} from "react-native"; -import {FontAwesome6} from "@expo/vector-icons"; +import Checkbox from "../CheckBox"; +import { View } from "react-native"; +import { ESleepLevel, SleepLevels } from "@/model/enums/Enums"; +import { AntDesignIconNames } from "../Icons"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; +export interface SleepQuestionRef { + getAnswer: () => ESleepLevel; +} - const [checkedOne, setCheckedOne] = React.useState(true); - const [checkedTwo, setCheckedTwo] = React.useState(false); - const [checkedThree, setCheckedThree] = React.useState(false); - const [checkedFour, setCheckedFour] = React.useState(false); - const [checkedFive, setCheckedFive] = React.useState(false); - const handleChangeOne = () => { - if(!checkedOne) { - setCheckedOne(!checkedOne); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeTwo = () => { - if(!checkedTwo) { - setCheckedOne(false); - setCheckedTwo(!checkedTwo); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeThree = () => { - if(!checkedThree) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(!checkedThree); - setCheckedFour(false); - setCheckedFive(false); - } - }; - const handleChangeFour = () => { - if(!checkedFour) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(!checkedFour); - setCheckedFive(false); - } - }; - const handleChangeFive = () => { - if(!checkedFive) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(!checkedFive); - } - }; +export default React.forwardRef( + ({ ...props }, ref): React.ReactElement => { + const [checkedItems, setCheckedItems] = useState([ + true, + ...Array(4).fill(false), + ]); - return ( - - - - - - - - - - ); + const handleChange = (index: number) => { + const newCheckedState = checkedItems.map((_, i) => i === index); + setCheckedItems(newCheckedState); + }; + + useImperativeHandle(ref, () => ({ + getAnswer: () => { + var selected = 0; + checkedItems.forEach((item, index) => { + if (item) { + selected = index; + } + }); + return SleepLevels[SleepLevels.length - 1 - selected]; + }, + })); + + interface IData { + label: string; + icon: AntDesignIconNames; + endText: string; } + + const data: IData[] = [ + { + label: "Excellent", + icon: "smile-circle", + endText: ">8 heures", + }, + { + label: "Bien", + icon: "smileo", + endText: "7-8 heures", + }, + { + label: "Mauvaise", + icon: "meh", + endText: "6-7 heures", + }, + { + label: "Très mauvaise", + icon: "frowno", + endText: "3-4 heures", + }, + { + label: "Insomniaque", + icon: "frown", + endText: "<2 heures", + }, + ]; + + return ( + + + {data.map((item, index) => ( + handleChange(index)} + antIcon={item.icon} + endText={item.endText} + /> + ))} + + + ); + } ); diff --git a/components/quiz/SportQuestion.tsx b/components/quiz/SportQuestion.tsx index 9dbd409..2bc3767 100644 --- a/components/quiz/SportQuestion.tsx +++ b/components/quiz/SportQuestion.tsx @@ -1,160 +1,86 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; -import CheckButton from "../CheckButtonComponent"; -import {View} from "react-native"; -import {FontAwesome6} from "@expo/vector-icons"; +import { View } from "react-native"; +import CheckBox from "../CheckBox"; +import { + AntDesignIconNames, + CommunityIconNames, + EntypoIconNames, + FontAwesome6IconNames, +} from "../Icons"; +import { ESport, Sports } from "@/model/enums/Enums"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; +export interface SportQuestionRef { + getAnswer: () => ESport; +} - const [checkedOne, setCheckedOne] = React.useState(true); - const [checkedTwo, setCheckedTwo] = React.useState(false); - const [checkedThree, setCheckedThree] = React.useState(false); - const [checkedFour, setCheckedFour] = React.useState(false); - const [checkedFive, setCheckedFive] = React.useState(false); - const [checkedSix, setCheckedSix] = React.useState(false); - const [checkedSeven, setCheckedSeven] = React.useState(false); - const [checkedEight, setCheckedEight] = React.useState(false); - const [checkedNine, setCheckedNine] = React.useState(false); - const handleChangeOne = () => { - if(!checkedOne) { - setCheckedOne(!checkedOne); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeTwo = () => { - if(!checkedTwo) { - setCheckedOne(false); - setCheckedTwo(!checkedTwo); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeThree = () => { - if(!checkedThree) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(!checkedThree); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeFour = () => { - if(!checkedFour) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(!checkedFour); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeFive = () => { - if(!checkedFive) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(!checkedFive); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeSix = () => { - if(!checkedSix) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(!checkedSix); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeSeven = () => { - if(!checkedSeven) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(!checkedSeven); - setCheckedEight(false); - setCheckedNine(false); - } - }; - const handleChangeEight = () => { - if(!checkedEight) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(!checkedEight); - setCheckedNine(false); - } - }; - const handleChangeNine = () => { - if(!checkedNine) { - setCheckedOne(false); - setCheckedTwo(false); - setCheckedThree(false); - setCheckedFour(false); - setCheckedFive(false); - setCheckedSix(false); - setCheckedSeven(false); - setCheckedEight(false); - setCheckedNine(!checkedNine); - } - }; +export default forwardRef( + (props, ref): ReactElement => { + const [checkedItems, setCheckedItems] = useState([ + true, + ...Array(8).fill(false), + ]); - return ( - - - - - + const handleChange = (index: number) => { + const newCheckedState = checkedItems.map((_, i) => i === index); + setCheckedItems(newCheckedState); + }; - - - + useImperativeHandle(ref, () => ({ + getAnswer: () => { + var selected = 0; + checkedItems.forEach((item, index) => { + if (item) { + selected = index; + } + }); + return Sports[selected]; + }, + })); - - - - - - ); + interface IData { + label: string; + commIcon?: CommunityIconNames; + antIcon?: AntDesignIconNames; + entypoIcon?: EntypoIconNames; + fontAwesomeIcon?: FontAwesome6IconNames; } + + const data: IData[] = [ + { label: "Course", fontAwesomeIcon: "person-running" }, + { label: "Marche", fontAwesomeIcon: "person-walking" }, + { label: "Rando", fontAwesomeIcon: "person-hiking" }, + { label: "Skate", commIcon: "skateboarding" }, + { label: "Cyclisme", commIcon: "bike" }, + { label: "Basket", fontAwesomeIcon: "basketball" }, + { label: "Cardio", antIcon: "heart" }, + { label: "Yoga", commIcon: "yoga" }, + { label: "Autre", entypoIcon: "dots-three-horizontal" }, + ]; + + return ( + + + {data.map((item, index) => ( + handleChange(index)} + fontAwesome6Icon={item.fontAwesomeIcon} + communityIcon={item.commIcon} + antIcon={item.antIcon} + entypoIcon={item.entypoIcon} + direction="col" + /> + ))} + + + ); + } ); diff --git a/components/quiz/WeightQuestion.tsx b/components/quiz/WeightQuestion.tsx index 8bfb597..fefadfd 100644 --- a/components/quiz/WeightQuestion.tsx +++ b/components/quiz/WeightQuestion.tsx @@ -1,37 +1,52 @@ -import React from "react"; +import React, { + forwardRef, + ReactElement, + useImperativeHandle, + useState, +} from "react"; import Question, { QuestionChildProps } from "./Question"; import Slider from "../ui/Slider"; import Text from "../ui/Text"; import { View } from "react-native"; import SegmentedControl from "../ui/SegmentedControl"; -export default React.forwardRef( - (props, ref): React.ReactElement => { - const MIN_WEIGHT = 40; - const MAX_WEIGHT = 200; +const MIN_WEIGHT = 40; +const MAX_WEIGHT = 200; + +export interface WeightQuestionRef { + getAnswer: () => number; +} + +const WeightQuestion = forwardRef( + (props, ref): ReactElement => { const UNITS = ["kg", "lb"]; - const [weight, setWeight] = React.useState(MIN_WEIGHT); - const [unit, setUnit] = React.useState("kg"); + const [answer, setAnswer] = useState(MIN_WEIGHT); + const [unit, setUnit] = useState("kg"); + + useImperativeHandle(ref, () => ({ + getAnswer: () => answer, + })); + return ( - + - {weight <= MIN_WEIGHT ? ( + {answer <= MIN_WEIGHT && ( - de - ) : null} - {weight >= MAX_WEIGHT ? ( + )} + {answer >= MAX_WEIGHT && ( + de - ) : null} + )} - {weight} + {answer} {unit} @@ -40,9 +55,11 @@ export default React.forwardRef( ); } ); + +export default WeightQuestion; diff --git a/components/ui/Button.tsx b/components/ui/Button.tsx index 5b9a0c9..6d53996 100644 --- a/components/ui/Button.tsx +++ b/components/ui/Button.tsx @@ -8,7 +8,7 @@ import { Size } from "../Constants"; export type ButtonStyle = "default" | "outline" | "secondary"; //@ts-ignore -interface Props extends TouchableOpacityProps { +export interface ButtonProps extends TouchableOpacityProps { size?: Size; style?: ButtonStyle; insideClassName?: string; @@ -16,9 +16,9 @@ interface Props extends TouchableOpacityProps { afterIcon?: AntDesignIconNames; } -export default React.forwardRef( - (props, ref): React.ReactElement => { - const { +export default React.forwardRef( + ( + { size, style, beforeIcon, @@ -27,9 +27,10 @@ export default React.forwardRef( className, insideClassName, children, - ...rest - } = props; - + ...props + }, + ref + ): React.ReactElement => { const getButtonStyle = (): string => { switch (style ?? "default") { case "default": @@ -83,7 +84,7 @@ export default React.forwardRef( }; return ( - + ( - (props, ref): React.ReactElement => { - const { children, ...rest } = props; + ({ children, ...props }, ref): React.ReactElement => { return ( - + {children} ); diff --git a/components/ui/Slider.tsx b/components/ui/Slider.tsx index 3e336dc..2af3987 100644 --- a/components/ui/Slider.tsx +++ b/components/ui/Slider.tsx @@ -2,8 +2,7 @@ import React from "react"; import Slider, { SliderProps } from "@react-native-community/slider"; export default React.forwardRef( - (props, ref): React.ReactElement => { - const { ...rest } = props; + ({ ...props }, ref): React.ReactElement => { return ( ( minimumTrackTintColor="#F97316" maximumTrackTintColor="#F97316" {...ref} - {...rest} + {...props} /> ); } diff --git a/components/ui/Text.tsx b/components/ui/Text.tsx index f37b73b..667d79e 100644 --- a/components/ui/Text.tsx +++ b/components/ui/Text.tsx @@ -20,18 +20,10 @@ export interface ExtendedTextProps extends TextProps { } export default React.forwardRef( - (props, ref): React.ReactElement => { - const { - position, - color, - size, - weight, - isLink, - className, - children, - ...rest - } = props; - + ( + { position, color, size, weight, isLink, className, children, ...props }, + ref + ): React.ReactElement => { const buildClassName = () => { const textSize = toTextSize(size ?? "lg"); const textColor = toTextColor(color ?? "black"); @@ -54,7 +46,7 @@ export default React.forwardRef( }; return ( - + {children} ); diff --git a/model/User.ts b/model/User.ts new file mode 100644 index 0000000..d671765 --- /dev/null +++ b/model/User.ts @@ -0,0 +1,146 @@ +import { + EHealthProblem, + ESleepLevel, + ESport, + ESportLevel, +} from "./enums/Enums"; + +export class User { + private _name: string; + private _age: number; + private _height: number; + private _weight: number; + private _sexe: boolean; // true = Male, false = Female + private _logo: string; + private _nbSessionPerWeek: number; + private _goal: string; + private _healthProblems: EHealthProblem[]; + private _sport: ESport; + private _sleepLevel: ESleepLevel; + private _sportLevel: ESportLevel; + + constructor( + name: string, + age: number, + height: number, + weight: number, + sexe: boolean, + logo: string, + nbSessionPerWeek: number, + goal: string, + healthProblems: EHealthProblem[], + sport: ESport, + sleepLevel: ESleepLevel, + sportLevel: ESportLevel + ) { + this._name = name; + this._age = age; + this._height = height; + this._weight = weight; + this._sexe = sexe; + this._logo = logo; + this._nbSessionPerWeek = nbSessionPerWeek; + this._goal = goal; + this._healthProblems = healthProblems; + this._sport = sport; + this._sleepLevel = sleepLevel; + this._sportLevel = sportLevel; + } + + get name(): string { + return this._name; + } + + get age(): number { + return this._age; + } + + get height(): number { + return this._height; + } + + get weight(): number { + return this._weight; + } + + get sexe(): boolean { + return this._sexe; + } + + get logo(): string { + return this._logo; + } + + get nbSessionPerWeek(): number { + return this._nbSessionPerWeek; + } + + get goals(): string { + return this._goal; + } + + get healthProblems(): EHealthProblem[] { + return this._healthProblems; + } + + get sports(): ESport { + return this._sport; + } + + get sleepLevel(): ESleepLevel { + return this._sleepLevel; + } + + get sportLevel(): ESportLevel { + return this._sportLevel; + } + + // Setters + set name(value: string) { + this._name = value; + } + + set age(value: number) { + this._age = value; + } + + set height(value: number) { + this._height = value; + } + + set weight(value: number) { + this._weight = value; + } + + set sexe(value: boolean) { + this._sexe = value; + } + + set logo(value: string) { + this._logo = value; + } + + set nbSessionPerWeek(value: number) { + this._nbSessionPerWeek = value; + } + + set goals(value: string) { + this._goal = value; + } + + set healthProblems(value: EHealthProblem[]) { + this._healthProblems = value; + } + + set sports(value: ESport) { + this._sport = value; + } + + set sleepLevel(value: ESleepLevel) { + this._sleepLevel = value; + } + + set sportLevel(value: ESportLevel) { + this._sportLevel = value; + } +} diff --git a/model/enums/Enums.ts b/model/enums/Enums.ts new file mode 100644 index 0000000..f147943 --- /dev/null +++ b/model/enums/Enums.ts @@ -0,0 +1,42 @@ +export const Goals = [ + "WEIGHT_LOSE", + "IMPROVE_MUSCLE", + "WEIGHT_GAIN", + "IMPROVE_STAMINA", + "KEEP_FIT", +] as const; + +export const SportLevels = [ + "NOT_SPORTY", + "BEGINNER", + "SPORTY", + "VERY_SPORTY", + "PERFORMER", +] as const; + +export const Sports = [ + "RUNNING", + "WALKING", + "RANDO", + "SKATEBOARD", + "BIKING", + "BASKETBALL", + "CARDIO", + "YOGA", + "ELSE", +] as const; + +export const SleepLevels = [ + "TERRIBLE", + "VERY_BAD", + "BAD", + "GOOD", + "EXCELLENT", +] as const; + +export type EGoal = (typeof Goals)[number]; +export type ESportLevel = (typeof SportLevels)[number]; +export type ESport = (typeof Sports)[number]; +export type ESleepLevel = (typeof SleepLevels)[number]; + +export type EHealthProblem = "ARTHROSE" | "MIGRAINE"; diff --git a/package-lock.json b/package-lock.json index 7abaa8c..923d197 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "react-dom": "18.3.1", "react-hook-form": "^7.54.2", "react-native": "0.76.6", + "react-native-element-dropdown": "^2.12.4", "react-native-gesture-handler": "^2.20.2", "react-native-gifted-charts": "^1.4.54", "react-native-reanimated": "^3.16.7", @@ -12247,6 +12248,22 @@ "node": ">=10" } }, + "node_modules/react-native-element-dropdown": { + "version": "2.12.4", + "resolved": "https://registry.npmjs.org/react-native-element-dropdown/-/react-native-element-dropdown-2.12.4.tgz", + "integrity": "sha512-abZc5SVji9FIt7fjojRYrbuvp03CoeZJrgvezQoDoSOrpiTqkX69ix5m+j06W2AVncA0VWvbT+vCMam8SoVadw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-gesture-handler": { "version": "2.22.0", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.22.0.tgz", diff --git a/package.json b/package.json index d413f18..9bb52a4 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "react-dom": "18.3.1", "react-hook-form": "^7.54.2", "react-native": "0.76.6", + "react-native-element-dropdown": "^2.12.4", "react-native-gesture-handler": "^2.20.2", "react-native-gifted-charts": "^1.4.54", "react-native-reanimated": "^3.16.7", -- 2.36.3