From e989f02c9fcddce78a6c0f8da1e7154971f8b3ea Mon Sep 17 00:00:00 2001 From: alexandre-kakal-akarah Date: Tue, 18 Jun 2024 22:15:24 +0200 Subject: [PATCH] WIP: add difficulties fields to journey form --- package-lock.json | 64 ++++++++++++++ package.json | 1 + src/components/Icons.tsx | 10 +++ src/components/form/StepCounter.tsx | 4 +- .../form/journey/BottomSheetModal.tsx | 10 ++- src/components/form/journey/JourneyForm.tsx | 10 ++- .../form/journey/steps/FirstStep.tsx | 6 +- .../form/journey/steps/SecondStep.tsx | 85 ++++++++++++++++++- .../form/journey/steps/ThirdStep.tsx | 13 ++- src/components/ui/button.tsx | 15 +--- src/components/ui/radio-group.tsx | 44 ++++++++++ src/validators/journeyFormSchema.ts | 12 +-- 12 files changed, 241 insertions(+), 33 deletions(-) create mode 100644 src/components/ui/radio-group.tsx diff --git a/package-lock.json b/package-lock.json index 6fb1893..b25a092 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@prisma/client": "^5.14.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", "bcrypt": "^5.1.1", @@ -1902,6 +1903,69 @@ } } }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", + "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", + "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-select": { "version": "2.0.0", "license": "MIT", diff --git a/package.json b/package.json index b85e1af..7c088a6 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@prisma/client": "^5.14.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-slot": "^1.0.2", "bcrypt": "^5.1.1", diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index 0bc9d86..dd0dde9 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -291,4 +291,14 @@ export const Icons = { ), + close: (props: LucideProps) => ( + + + + ), }; diff --git a/src/components/form/StepCounter.tsx b/src/components/form/StepCounter.tsx index 120300b..c8e3720 100644 --- a/src/components/form/StepCounter.tsx +++ b/src/components/form/StepCounter.tsx @@ -12,11 +12,11 @@ const StepCounter = ({ step, totalSteps }: StepCounterProps) => {
))} -

+

Étape {step + 1}/{totalSteps}

diff --git a/src/components/form/journey/BottomSheetModal.tsx b/src/components/form/journey/BottomSheetModal.tsx index 70f999e..552f131 100644 --- a/src/components/form/journey/BottomSheetModal.tsx +++ b/src/components/form/journey/BottomSheetModal.tsx @@ -18,6 +18,7 @@ import { Sheet } from "react-modal-sheet"; import "leaflet/dist/leaflet.css"; import { useEffect, useState } from "react"; import LeafletMap from "@/components/map/LeafletMap"; +import { Icons } from "@/components/Icons"; type AddStepFormValues = z.infer; @@ -102,8 +103,8 @@ const BottomSheetModal = () => { disableDrag={dragDisabled} > - - + +
@@ -188,7 +189,10 @@ const BottomSheetModal = () => { /> diff --git a/src/components/form/journey/JourneyForm.tsx b/src/components/form/journey/JourneyForm.tsx index 499c8c4..aeefdf5 100644 --- a/src/components/form/journey/JourneyForm.tsx +++ b/src/components/form/journey/JourneyForm.tsx @@ -15,6 +15,7 @@ import { Button } from "@/components/ui/button"; import { zodResolver } from "@hookform/resolvers/zod"; import StepCounter from "../StepCounter"; import Steps from "./steps/Steps"; +import { Icons } from "@/components/Icons"; export type JourneyFormValues = z.infer; type FieldName = keyof JourneyFormValues; @@ -98,8 +99,13 @@ const JourneyForm = () => { if (!isVisible) return null; return ( -
- +
+
+ +
{!form.formState.isSubmitSuccessful && formStatus === "idle" && ( diff --git a/src/components/form/journey/steps/FirstStep.tsx b/src/components/form/journey/steps/FirstStep.tsx index ed2f824..2fed688 100644 --- a/src/components/form/journey/steps/FirstStep.tsx +++ b/src/components/form/journey/steps/FirstStep.tsx @@ -10,6 +10,7 @@ import { import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; +import { Icons } from "@/components/Icons"; type FirstStepProps = { next: () => Promise; @@ -57,7 +58,10 @@ const FirstStep = ({ form, next }: FirstStepProps) => { /> {/* TODO: add image file input */} - +
); }; diff --git a/src/components/form/journey/steps/SecondStep.tsx b/src/components/form/journey/steps/SecondStep.tsx index 144fba6..47eee24 100644 --- a/src/components/form/journey/steps/SecondStep.tsx +++ b/src/components/form/journey/steps/SecondStep.tsx @@ -5,6 +5,7 @@ import { FormControl, FormField, FormItem, + FormLabel, FormMessage, } from "@/components/ui/form"; import { Textarea } from "@/components/ui/textarea"; @@ -17,6 +18,8 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { Icons } from "@/components/Icons"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; type SecondStepProps = { prev: () => void; @@ -48,7 +51,77 @@ const SecondStep = ({ form, next, prev }: SecondStepProps) => { )} /> - {/* TO DO: radio fields on physical difficulty and clues difficulty */} + ( + + + + + + + + Facile + + + + + + Intermédiaire + + + + + + Difficile + + + + + + )} + /> + + ( + + + + + + + + Facile + + + + + + Intermédiaire + + + + + + Difficile + + + + + + )} + /> { )} /> -
- +
+
diff --git a/src/components/form/journey/steps/ThirdStep.tsx b/src/components/form/journey/steps/ThirdStep.tsx index 40e8e60..38d411e 100644 --- a/src/components/form/journey/steps/ThirdStep.tsx +++ b/src/components/form/journey/steps/ThirdStep.tsx @@ -12,6 +12,7 @@ import { FormMessage, } from "@/components/ui/form"; import { useEffect } from "react"; +import { Icons } from "@/components/Icons"; type ThirdStepProps = { prev: () => void; @@ -57,18 +58,22 @@ const ThirdStep = ({ form, next, prev }: ThirdStepProps) => { /> -
- +
+
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 92dafb0..98ddd8b 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -5,22 +5,15 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/tailwindUtils"; const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center whitespace-nowrap text-sm font-medium uppercase disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", + default: "rounded-full border border-beige text-foreground", + link: "text-foreground underline-offset-4 hover:underline", }, size: { - default: "h-10 px-4 py-2", + default: "px-[9px] py-[5px]", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "size-10", diff --git a/src/components/ui/radio-group.tsx b/src/components/ui/radio-group.tsx new file mode 100644 index 0000000..9a9a2d1 --- /dev/null +++ b/src/components/ui/radio-group.tsx @@ -0,0 +1,44 @@ +"use client"; + +import * as React from "react"; +import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"; +import { Circle } from "lucide-react"; + +import { cn } from "@/lib/tailwindUtils"; + +const RadioGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + ); +}); +RadioGroup.displayName = RadioGroupPrimitive.Root.displayName; + +const RadioGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + + + + + ); +}); +RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName; + +export { RadioGroup, RadioGroupItem }; diff --git a/src/validators/journeyFormSchema.ts b/src/validators/journeyFormSchema.ts index 791e900..aafdd04 100644 --- a/src/validators/journeyFormSchema.ts +++ b/src/validators/journeyFormSchema.ts @@ -14,12 +14,12 @@ export const secondStepSchema = z.object({ requirement: z.string({ required_error: "Ce champ est requis" }).min(1, { message: "Ce champ est requis", }), - // physicalDifficulty: z.enum(["easy", "medium", "hard"], { - // required_error: "Vous devez sélectionner une option", - // }), - // cluesDifficulty: z.enum(["easy", "medium", "hard"], { - // required_error: "Vous devez sélectionner une option", - // }), + physicalDifficulty: z.enum(["facile", "intermediaire", "difficile"], { + required_error: "Vous devez sélectionner une option", + }), + cluesDifficulty: z.enum(["facile", "intermediaire", "difficile"], { + required_error: "Vous devez sélectionner une option", + }), mobilityImpaired: z.enum( ["undefined", "unaccessible", "partiallyAccessible", "accessible"], {