From 11743d345b2f585104287f615b30087bbe6b8bde Mon Sep 17 00:00:00 2001 From: JeanM65 Date: Mon, 11 Mar 2024 17:28:21 +0800 Subject: [PATCH 1/4] add create estimate form --- src/config/i18n/locales/en/user.json | 3 ++- src/pages/estimates/Estimates.tsx | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/config/i18n/locales/en/user.json b/src/config/i18n/locales/en/user.json index 9a5fbafa..18286794 100644 --- a/src/config/i18n/locales/en/user.json +++ b/src/config/i18n/locales/en/user.json @@ -143,5 +143,6 @@ }, "addEmployee": "Add employee", "employeeCooperativeExists": "This employee works already in your cooperative", - "sendMail": "send email" + "sendMail": "send email", + "pasteUrlHere": "Paste URL here" } \ No newline at end of file diff --git a/src/pages/estimates/Estimates.tsx b/src/pages/estimates/Estimates.tsx index aa0c27d4..fa81aa9f 100644 --- a/src/pages/estimates/Estimates.tsx +++ b/src/pages/estimates/Estimates.tsx @@ -5,11 +5,23 @@ import Head from '@/components/Head'; import Dialog from '@/components/Dialog'; import AddFab from '@/components/AddFab'; import { createEstimate } from '@/redux/actions/estimate.action'; +// import TextField from '@/components/form/fields/TextField'; +import { useNavigate } from '@tanstack/react-router'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { TextField } from '@mui/material'; + +type Props = { + onSubmit: (values: ISignUpInput) => void; + from?: 'signUp' | 'invitation'; // invitation from someone + formId?: string; +}; const Estimates = () => { const { t } = useTranslation(); const dispatch = useDispatch(); + const [openFormDialog, setOpenFormDialog] = useState(false); const toggleDialog = () => setOpenFormDialog(!openFormDialog); @@ -31,7 +43,13 @@ const Estimates = () => { title={t('createEstimate')} open={openFormDialog} toggle={toggleDialog}> - Form here + ); From 7de7943068c66351903ca6a544e62bcfebdffe7c Mon Sep 17 00:00:00 2001 From: JeanM65 Date: Tue, 12 Mar 2024 01:01:47 +0800 Subject: [PATCH 2/4] revised add create estimate form --- src/containers/auth/LoginForm.tsx | 2 - src/containers/auth/SignUpForm.tsx | 4 -- src/containers/estimate/EstimateForm.tsx | 57 ++++++++++++++++++++++++ src/pages/estimates/Estimates.tsx | 31 ++++++------- src/types/auth.types.ts | 2 +- src/types/estimate.types.ts | 6 +++ src/utils/constants.ts | 1 + src/validations/auth.validation.ts | 3 ++ src/validations/estimate.validation.ts | 8 ++++ 9 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 src/containers/estimate/EstimateForm.tsx create mode 100644 src/types/estimate.types.ts create mode 100644 src/validations/estimate.validation.ts diff --git a/src/containers/auth/LoginForm.tsx b/src/containers/auth/LoginForm.tsx index d313588c..f26b337f 100644 --- a/src/containers/auth/LoginForm.tsx +++ b/src/containers/auth/LoginForm.tsx @@ -16,8 +16,6 @@ import { COLORS } from '@/utils/constants'; import { ILoginInput } from '@/types/auth.types'; import { loginSchema } from '@/validations/auth.validation'; import { Typography } from '@mui/material'; -import Head from '@/components/Head'; -import Logo from '@/components/Logo'; const LoginForm = () => { const { t } = useTranslation(['user']); diff --git a/src/containers/auth/SignUpForm.tsx b/src/containers/auth/SignUpForm.tsx index 0769aae7..5b8b462c 100644 --- a/src/containers/auth/SignUpForm.tsx +++ b/src/containers/auth/SignUpForm.tsx @@ -3,7 +3,6 @@ import { useForm, SubmitHandler } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; -import { Typography } from '@mui/material'; import PasswordField from '@/components/form/fields/PasswordField'; import TextField from '@/components/form/fields/TextField'; import Form from '@/components/form/Form'; @@ -14,9 +13,6 @@ import { getUserLoadingSelector } from '@/redux/reducers/user.reducer'; import { COLORS } from '@/utils/constants'; import { ISignUpInput } from '@/types/auth.types'; import { signUpSchema } from '@/validations/auth.validation'; -import Logo from '@/components/Logo'; -import Layout from '@/components/layouts/Layout'; -import AuthHead from '@/components/Title'; type Props = { diff --git a/src/containers/estimate/EstimateForm.tsx b/src/containers/estimate/EstimateForm.tsx new file mode 100644 index 00000000..23ecc7bd --- /dev/null +++ b/src/containers/estimate/EstimateForm.tsx @@ -0,0 +1,57 @@ +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm, SubmitHandler } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { Box } from '@mui/material'; +import Form from '@/components/form/Form'; + +import { getAppErrorSelector } from '@/redux/reducers/app.reducer'; +import { getUserLoadingSelector } from '@/redux/reducers/user.reducer'; + +import { IEstimateInput } from '@/types/estimate.types'; +import { estimateSchema } from '@/validations/estimate.validation'; +import TextField from '@/components/form/fields/TextField'; + + +type Props = { + formId: string; + onSubmit: () => SubmitHandler; +}; + +const EstimateForm = ( { formId, onSubmit } : Props ) => { + const { t } = useTranslation(['user']); + const loading = useSelector(getUserLoadingSelector); + const error = useSelector(getAppErrorSelector); + + + const form = useForm({ + resolver: zodResolver(estimateSchema) + }); + + return ( + +
+ + +
+ +); +}; + +export default EstimateForm; diff --git a/src/pages/estimates/Estimates.tsx b/src/pages/estimates/Estimates.tsx index fa81aa9f..3ca6cbf8 100644 --- a/src/pages/estimates/Estimates.tsx +++ b/src/pages/estimates/Estimates.tsx @@ -10,26 +10,29 @@ import { useNavigate } from '@tanstack/react-router'; import { SubmitHandler, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { TextField } from '@mui/material'; +import EstimateForm from '@/containers/estimate/EstimateForm'; +import { IEstimateInput } from '@/types/estimate.types'; -type Props = { - onSubmit: (values: ISignUpInput) => void; - from?: 'signUp' | 'invitation'; // invitation from someone - formId?: string; -}; const Estimates = () => { const { t } = useTranslation(); const dispatch = useDispatch(); + const ESTIMATE_FORM_ID = 'estimate-form-id'; const [openFormDialog, setOpenFormDialog] = useState(false); - const toggleDialog = () => setOpenFormDialog(!openFormDialog); + const toggleDialog = () => setOpenFormDialog((prev: boolean): boolean => !prev); const handleSave = () => { dispatch(createEstimate()) } + const onSubmitHandler: SubmitHandler = async () => { + await dispatch(createEstimate()); + }; + + return (
@@ -38,18 +41,16 @@ const Estimates = () => { onSubmitHandler} primaryButtonText={t('save')} title={t('createEstimate')} open={openFormDialog} - toggle={toggleDialog}> - + toggle={toggleDialog} + > + onSubmitHandler} + />
); diff --git a/src/types/auth.types.ts b/src/types/auth.types.ts index b5062f23..ea3d15ca 100644 --- a/src/types/auth.types.ts +++ b/src/types/auth.types.ts @@ -1,5 +1,5 @@ import { z } from 'zod'; -import { changePasswordSchema, emailSchema, loginSchema, resetPasswordSchema, signUpSchema } from '@/validations/auth.validation'; +import { changePasswordSchema, emailSchema, estimateSchema, loginSchema, resetPasswordSchema, signUpSchema } from '@/validations/auth.validation'; export type ISignUpInput = z.infer; export type ILoginInput = z.infer; diff --git a/src/types/estimate.types.ts b/src/types/estimate.types.ts new file mode 100644 index 00000000..b59b9e45 --- /dev/null +++ b/src/types/estimate.types.ts @@ -0,0 +1,6 @@ +import { z } from "zod"; +import { estimateSchema } from "@/validations/estimate.validation"; + + + +export type IEstimateInput = z.infer; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c195ddf0..d83857f3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -36,6 +36,7 @@ export const IMAGES = { export const COLORS = { authBackground: "#000", authTextFieldPlaceholder: '#fff', + estimateBackground: '#fff', }; export const HIGHEST_LEVEL_DEFAULT_ROLES = ['Owner', 'Administrator']; diff --git a/src/validations/auth.validation.ts b/src/validations/auth.validation.ts index 93d2af56..3faa86cc 100644 --- a/src/validations/auth.validation.ts +++ b/src/validations/auth.validation.ts @@ -22,6 +22,9 @@ export const loginSchema = userSchema.pick({ email: true, password: true }); export const emailSchema = loginSchema.pick({ email: true }); + + + const passwordConfirmationSchema = string().min( 1, i18n.t('form.error.required', { field: i18n.t('user:passwordConfirmation') }), diff --git a/src/validations/estimate.validation.ts b/src/validations/estimate.validation.ts new file mode 100644 index 00000000..329f459b --- /dev/null +++ b/src/validations/estimate.validation.ts @@ -0,0 +1,8 @@ +import { object, string } from 'zod'; +import i18n from '@/config/i18n'; + + + +export const estimateSchema = object({ + estimate: string().url({ message: i18n.t('invalid.url') }).startsWith("https://", { message: "Must provide secure URL" }) +}); From 1204c5e6d9e85531753f6e2afb3fd6dadee90152 Mon Sep 17 00:00:00 2001 From: JeanM65 Date: Tue, 12 Mar 2024 01:21:16 +0800 Subject: [PATCH 3/4] review 2 add create estimate form --- src/containers/estimate/EstimateForm.tsx | 4 ++-- src/pages/estimates/Estimates.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/containers/estimate/EstimateForm.tsx b/src/containers/estimate/EstimateForm.tsx index 23ecc7bd..1dbbb1ae 100644 --- a/src/containers/estimate/EstimateForm.tsx +++ b/src/containers/estimate/EstimateForm.tsx @@ -16,7 +16,7 @@ import TextField from '@/components/form/fields/TextField'; type Props = { formId: string; - onSubmit: () => SubmitHandler; + onSubmit?: () => void; }; const EstimateForm = ( { formId, onSubmit } : Props ) => { @@ -36,7 +36,7 @@ const EstimateForm = ( { formId, onSubmit } : Props ) => { onSubmit={onSubmit} loading={loading} error={error} - isDisabled={false} + isDisabled={true} formId={formId} > { onSubmitHandler} primaryButtonText={t('save')} title={t('createEstimate')} open={openFormDialog} toggle={toggleDialog} + formId={ESTIMATE_FORM_ID} > onSubmitHandler} + onSubmit={()=> onSubmitHandler} /> From 354d7b04f208ae486a148b419ecbd2db6858cbda Mon Sep 17 00:00:00 2001 From: JeanM65 Date: Tue, 12 Mar 2024 01:24:31 +0800 Subject: [PATCH 4/4] review2 add create estimate form --- src/containers/estimate/EstimateForm.tsx | 4 ++-- src/pages/estimates/Estimates.tsx | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/containers/estimate/EstimateForm.tsx b/src/containers/estimate/EstimateForm.tsx index 1dbbb1ae..55b8a9a7 100644 --- a/src/containers/estimate/EstimateForm.tsx +++ b/src/containers/estimate/EstimateForm.tsx @@ -1,5 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod'; -import { useForm, SubmitHandler } from 'react-hook-form'; +import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; @@ -16,7 +16,7 @@ import TextField from '@/components/form/fields/TextField'; type Props = { formId: string; - onSubmit?: () => void; + onSubmit: () => void; }; const EstimateForm = ( { formId, onSubmit } : Props ) => { diff --git a/src/pages/estimates/Estimates.tsx b/src/pages/estimates/Estimates.tsx index 3e3ccffe..8b943c0a 100644 --- a/src/pages/estimates/Estimates.tsx +++ b/src/pages/estimates/Estimates.tsx @@ -24,10 +24,7 @@ const Estimates = () => { const toggleDialog = () => setOpenFormDialog((prev: boolean): boolean => !prev); - const handleSave = () => { - dispatch(createEstimate()) - } - + const onSubmitHandler: SubmitHandler = async () => { await dispatch(createEstimate()); };