From be174f39e5cdb8f596bd9db99525e150d82618b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Roig?= Date: Fri, 18 Mar 2022 10:50:12 +0100 Subject: [PATCH] feat(createTracker): add objectives creation --- src/app/App.tsx | 36 +++-- .../TrackerForm/CompletionsForm.tsx | 140 ++++++++++++++++++ src/components/TrackerForm/TrackerForm.tsx | 74 ++++++++- src/components/TrackerForm/types.ts | 7 + src/index.css | 6 + 5 files changed, 242 insertions(+), 21 deletions(-) create mode 100644 src/components/TrackerForm/CompletionsForm.tsx create mode 100644 src/components/TrackerForm/types.ts diff --git a/src/app/App.tsx b/src/app/App.tsx index 7a469d69..54676be7 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/jsx-no-undef */ import { useState } from 'react'; import { Container } from '@mui/material'; import styled from '@emotion/styled'; @@ -7,6 +8,9 @@ import { ThemeProvider, responsiveFontSizes } from '@mui/material/styles'; +import DateAdapter from '@mui/lab/AdapterDateFns'; +import frLocale from 'date-fns/locale/fr'; +import { LocalizationProvider } from '@mui/lab'; import { palette, typography } from '../config/CustomTheme'; import { DRAWER_MENU_WIDTH } from '../config/Constants'; import AppBar from './AppBar'; @@ -33,21 +37,23 @@ function App() { }; return ( - - - - - - - - - - - + + + + + + + + + + + + + ); } diff --git a/src/components/TrackerForm/CompletionsForm.tsx b/src/components/TrackerForm/CompletionsForm.tsx new file mode 100644 index 00000000..b8c26731 --- /dev/null +++ b/src/components/TrackerForm/CompletionsForm.tsx @@ -0,0 +1,140 @@ +import { FC } from 'react'; +import { Button, Grid, GridProps, IconButton, TextField, Typography } from '@mui/material'; +import styled from '@emotion/styled'; +import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { + Control, + Controller, + FieldArrayWithId, + UseFieldArrayAppend, + UseFieldArrayRemove +} from 'react-hook-form'; +import { FormValues } from './types'; + +export const FieldsetGrid = styled(Grid)` + border: 1px solid rgba(0, 0, 0, 0.23); + border-radius: 4px; + padding: 8px; +`; + +export const CompletionUnitTextField = styled(TextField)` + fieldset { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +`; + +export const CompletionQuantityTextField = styled(TextField)` + fieldset { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +`; + +interface Props { + append: UseFieldArrayAppend; + control: Control /* eslint-disable-line @typescript-eslint/no-explicit-any */; + fields: FieldArrayWithId[]; + gridProps?: GridProps; + remove: UseFieldArrayRemove; +} + +const CompletionsForm: FC = ({ append, control, fields, gridProps, remove }) => { + return ( + <> + {fields.map((field, index) => ( + + + Objectif n°{index + 1} + remove(index)} sx={{ p: 0 }}> + + + + + { + let errorText = ''; + if (error) { + switch (error.type) { + case 'min': + errorText = 'La quantité doit être supérieure à 0.'; + break; + + case 'pattern': + errorText = 'La quantité doit être un nombre.'; + break; + + case 'required': + errorText = 'La quantité est requise'; + break; + } + } + return ( + + ); + }} + /> + + + ( + + )} + /> + + + ))} + + + ); +}; + +export default CompletionsForm; diff --git a/src/components/TrackerForm/TrackerForm.tsx b/src/components/TrackerForm/TrackerForm.tsx index e35bdc08..320ed8d0 100644 --- a/src/components/TrackerForm/TrackerForm.tsx +++ b/src/components/TrackerForm/TrackerForm.tsx @@ -1,20 +1,42 @@ -import { useForm, Controller } from 'react-hook-form'; +import { useForm, Controller, useFieldArray } from 'react-hook-form'; import { Box, Button, TextField, Stack } from '@mui/material'; +import DatePicker from '@mui/lab/DatePicker'; import { v4 } from 'uuid'; -import Tracker from '../../models/Tracker'; +import styled from '@emotion/styled'; + +import { FormValues } from './types'; import TrackerStatus from '../../models/TrackerStatus'; import { useAppDispatch } from '../../app/hooks'; import { createTracker } from '../../store/trackers/trackersSlice'; -type FormValues = Omit & { duration: string }; // duration is used as a string for input control here +import CompletionsForm from './CompletionsForm'; + +export const CompletionUnitTextField = styled(TextField)` + fieldset { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } +`; + +export const CompletionQuantityTextField = styled(TextField)` + fieldset { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +`; -const getDefaultValues = () => ({ +const getDefaultValues = (): FormValues => ({ id: v4(), beginDate: new Date().toString(), duration: '', entries: [], name: '', - requiredCompletions: [], + requiredCompletions: [ + { + quantity: '1', + unit: 'fois' + } + ], status: TrackerStatus.active }); @@ -22,6 +44,10 @@ function TrackerForm() { const { control, handleSubmit, reset } = useForm({ defaultValues: getDefaultValues() }); + const { fields, append, remove } = useFieldArray({ + control, // control props comes from useForm + name: 'requiredCompletions' + }); const dispatch = useAppDispatch(); @@ -33,7 +59,14 @@ function TrackerForm() { dispatch( createTracker({ ...data, - duration: parseInt(data.duration) + beginDate: data.beginDate.toString(), + duration: parseInt(data.duration), + requiredCompletions: [ + ...data.requiredCompletions.map((c) => ({ + quantity: parseInt(c.quantity), + unit: c.unit + })) + ] }) ); resetToDefault(); @@ -48,14 +81,39 @@ function TrackerForm() { render={({ field: { onChange, value }, fieldState: { error } }) => ( )} /> + + ( + ( + + )} + /> + )} + /> + + + +