From 0656e92a7e94094565fad12dca03db60db7d8157 Mon Sep 17 00:00:00 2001 From: Dovile Date: Thu, 18 Jan 2024 17:19:01 +0100 Subject: [PATCH 1/3] filter fishType list --- package.json | 3 +- src/components/forms/Done.tsx | 159 ++++++++++++-------------- src/components/forms/Registration.tsx | 77 +++++++------ src/components/other/FishRow.tsx | 10 +- src/utils/options.ts | 12 ++ src/utils/types.ts | 6 +- 6 files changed, 130 insertions(+), 137 deletions(-) create mode 100644 src/utils/options.ts diff --git a/package.json b/package.json index 7494730..0307c89 100644 --- a/package.json +++ b/package.json @@ -109,8 +109,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ - "prettier --write", - "eslint" + "prettier --write" ], "*.{md,html,css}": "prettier --write" } diff --git a/src/components/forms/Done.tsx b/src/components/forms/Done.tsx index bf0ffc3..951c6b5 100644 --- a/src/components/forms/Done.tsx +++ b/src/components/forms/Done.tsx @@ -1,110 +1,105 @@ -import { useMediaQuery } from "@material-ui/core"; -import { format } from "date-fns"; -import { isEmpty } from "lodash"; -import { useNavigate } from "react-router"; -import { createSearchParams } from "react-router-dom"; -import styled from "styled-components"; -import { device } from "../../styles"; -import { FishStockingStatus } from "../../utils/constants"; -import { slugs } from "../../utils/routes"; -import { buttonsTitles } from "../../utils/texts"; -import { FishStocking } from "../../utils/types"; -import Button from "../buttons/Button"; -import PhotoUploadField from "../fields/PhotoUploadField"; -import FishStockingInfo from "../other/Info"; -import InfoColumn from "../other/InfoColumn"; -import FishStockingPageTitle from "../other/PageTitle"; -import PreviewMap from "../other/PreviewMap"; -import SignatureList from "../other/SignatureList"; -import FishStockingTable from "../other/Table"; -import { fishOrigins } from "./Registration"; +import { useMediaQuery } from '@material-ui/core'; +import { format } from 'date-fns'; +import { isEmpty } from 'lodash'; +import { useNavigate } from 'react-router'; +import { createSearchParams } from 'react-router-dom'; +import styled from 'styled-components'; +import { device } from '../../styles'; +import { FishStockingStatus } from '../../utils/constants'; +import { slugs } from '../../utils/routes'; +import { buttonsTitles } from '../../utils/texts'; +import { FishStocking } from '../../utils/types'; +import Button from '../buttons/Button'; +import PhotoUploadField from '../fields/PhotoUploadField'; +import FishStockingInfo from '../other/Info'; +import InfoColumn from '../other/InfoColumn'; +import FishStockingPageTitle from '../other/PageTitle'; +import PreviewMap from '../other/PreviewMap'; +import SignatureList from '../other/SignatureList'; +import FishStockingTable from '../other/Table'; +import { fishOriginOptions } from '../../utils/options'; export interface FishStockingCompletedProps { fishStocking: FishStocking; disabled?: boolean; } const locale = { - vet_no_0: "Vet. patvirtinimo nr.", - vet_no_1: "Vet. patvirtinimo įsakymo nr.", - waybill_no: "Važtaraščio nr.", - fish_origin_company: "Žuvivaisos įmonės pavadinimas", - fish_origin_reservoir: "Vandens telkinio pavadinimas" + vet_no_0: 'Vet. patvirtinimo nr.', + vet_no_1: 'Vet. patvirtinimo įsakymo nr.', + waybill_no: 'Važtaraščio nr.', + fish_origin_company: 'Žuvivaisos įmonės pavadinimas', + fish_origin_reservoir: 'Vandens telkinio pavadinimas', }; -const FishStockingCompleted = ({ - fishStocking -}: FishStockingCompletedProps) => { - const status = fishStocking?.status; +const FishStockingCompleted = ({ fishStocking }: FishStockingCompletedProps) => { + const status = fishStocking.status; const navigate = useNavigate(); const isMobile = useMediaQuery(device.mobileL); - + if (!fishStocking) { + return null; + } const showAdditionalInfo = ![ FishStockingStatus.NOT_FINISHED, - FishStockingStatus.CANCELED + FishStockingStatus.CANCELED, ].includes(status!); - const fishStocker = - fishStocking.reviewedBy || - fishStocking.assignedTo || - fishStocking.createdBy; + const fishStocker = fishStocking.reviewedBy || fishStocking.assignedTo || fishStocking.createdBy; const info = [ [ { - type: "location", + type: 'location', value: fishStocking?.location?.municipality?.name, - label: "Įžuvinimo vieta" + label: 'Įžuvinimo vieta', }, { - type: "date", + type: 'date', value: format( new Date(fishStocking?.reviewTime || fishStocking.eventTime!), - "yyyy-MM-dd HH:mm" + 'yyyy-MM-dd HH:mm', ), - label: "Data" + label: 'Data', }, { - type: "phone", + type: 'phone', value: fishStocking.phone, - label: "Telefonas" - } + label: 'Telefonas', + }, ], [ { - type: "info", + type: 'info', value: `${fishStocking.location?.name}, ${fishStocking.location?.cadastral_id}`, - label: "Telkinys" + label: 'Telkinys', }, { - type: "user", + type: 'user', value: `${fishStocker?.firstName} ${fishStocker?.lastName}`, - label: "Atsakingas asmuo" - } - ] + label: 'Atsakingas asmuo', + }, + ], ]; if (showAdditionalInfo) { info.push([ { - type: "temp", + type: 'temp', value: fishStocking.containerWaterTemp - ? fishStocking.containerWaterTemp + "\u00b0C" - : "Nežinoma temperatūra", - label: "Vandens temperatūra taroje" + ? fishStocking.containerWaterTemp + '\u00b0C' + : 'Nežinoma temperatūra', + label: 'Vandens temperatūra taroje', }, { - type: "water", - value: fishStocking.waterTemp - ? fishStocking.waterTemp + "\u00b0C" - : "Nežinoma temperatūra", - label: "Vandens temperatūra telkinyje" - } + type: 'water', + value: fishStocking.waterTemp ? fishStocking.waterTemp + '\u00b0C' : 'Nežinoma temperatūra', + label: 'Vandens temperatūra telkinyje', + }, ]); } return ( - + - {fishStocking?.fishOrigin === fishOrigins[0].value ? ( + {fishStocking.fishOrigin === fishOriginOptions[0].value ? ( ) : ( )} - + - + )} - {fishStocking?.batches && ( - - )} + {fishStocking?.batches && } {fishStocking?.comment && ( - + )} {!isEmpty(fishStocking.images) && ( `${photo?.url}`} disabled={true} /> )} - {!isEmpty(fishStocking?.signatures) && ( + {!isEmpty(fishStocking.signatures) && ( - + )} @@ -180,8 +163,8 @@ const FishStockingCompleted = ({ navigate({ pathname: slugs.newFishStockings, search: createSearchParams({ - repeat: fishStocking?.id!.toString() - }).toString() + repeat: fishStocking?.id!.toString(), + }).toString(), }); }} > diff --git a/src/components/forms/Registration.tsx b/src/components/forms/Registration.tsx index 23655f9..b71f9c4 100644 --- a/src/components/forms/Registration.tsx +++ b/src/components/forms/Registration.tsx @@ -1,7 +1,7 @@ import { useMediaQuery } from '@material-ui/core'; import { FieldArray, Form, Formik } from 'formik'; import { useRef, useState } from 'react'; -import { useMutation } from 'react-query'; +import { useMutation, useQuery } from 'react-query'; import { useParams } from 'react-router'; import { useSearchParams } from 'react-router-dom'; import styled from 'styled-components'; @@ -10,7 +10,7 @@ import { useAppSelector } from '../../state/hooks'; import { device } from '../../styles'; import api from '../../utils/api'; import { FishOriginTypes } from '../../utils/constants'; -import { getLocationList, getTenantsList, isNew } from '../../utils/functions'; +import { getLocationList, getTenantsList, handleAlert, isNew } from '../../utils/functions'; import { useAssignedToUsers, useFishAges, @@ -20,7 +20,7 @@ import { useSettings, } from '../../utils/hooks'; import { buttonsTitles, formLabels, queryStrings } from '../../utils/texts'; -import { FishStocking } from '../../utils/types'; +import { FishStocking, FishType } from '../../utils/types'; import { validateFishStocking, validateFreelancerFishStocking } from '../../utils/validations'; import Button, { ButtonColors } from '../buttons/Button'; import RadioOptions from '../buttons/RadioOptionts'; @@ -37,27 +37,9 @@ import LoaderComponent from '../other/LoaderComponent'; import Modal from '../other/Modal'; import FishStockingPageTitle from '../other/PageTitle'; import Map from '../other/RegistrationMap'; - +import { fishOriginOptions } from '../../utils/options'; const cookies = new Cookies(); -export interface FishRow { - type: { label: string; id: string }; - age: { label: string; id: string }; - amount: string | number; - weight: string | number; -} - -export const fishOrigins = [ - { - value: FishOriginTypes.GROWN, - label: 'Užaugintos žuvivaisos įmonėje', - }, - { - label: 'Sugautos vandens telkinyje', - value: FishOriginTypes.CAUGHT, - }, -]; - const RegistrationForm = ({ fishStocking, renderTabs, @@ -71,7 +53,7 @@ const RegistrationForm = ({ const [queryString, setQueryString] = useState(''); const isMobile = useMediaQuery(device.mobileL); const fishAges = useFishAges(); - const fishTypes = useFishTypes(); + // const fishTypes = useFishTypes(); const { minTime, loading } = useSettings(); const isFreelancer = useIsFreelancer(); const iframeRef = useRef(null); @@ -81,6 +63,13 @@ const RegistrationForm = ({ const [searchParams] = useSearchParams(); const { repeat } = Object.fromEntries([...Array.from(searchParams)]); + const { data, isLoading: fihTypesLoading } = useQuery('fishTypes', () => api.getFishTypes(), { + onError: () => { + handleAlert(); + }, + }); + const fishTypesFullList = data?.rows; + const callBacks = useFishStockingCallbacks(); const createFishStockingMutation = useMutation( @@ -112,7 +101,7 @@ const RegistrationForm = ({ const { id } = useParams(); - if (loading) return ; + if (loading || fihTypesLoading) return ; const assignedTo = fishStocking?.assignedTo || fishStocking?.createdBy || null; @@ -128,9 +117,10 @@ const RegistrationForm = ({ location: fishStocking?.location || undefined, batches: fishStocking?.batches || [{}], geom: fishStocking?.geom || undefined, + fishTypes: fishTypesFullList || [], }; - const handleSubmit = async (values: FishStocking) => { + const handleSubmit = async (values: any) => { const { eventTime, phone, @@ -208,6 +198,14 @@ const RegistrationForm = ({ const validationSchema = isFreelancer ? validateFreelancerFishStocking : validateFishStocking; + const filterFishTypes = (batches: any[]) => { + const batchesFishTypesIds = batches.filter((b) => !!b.fishType?.id).map((b) => b.fishType?.id); + return (fishTypesFullList || []).filter((fishType) => { + const inBatches = batchesFishTypesIds.includes(fishType.id); + return !inBatches; + }); + }; + return ( <> {({ values, errors, handleSubmit, handleChange, setFieldValue }) => { + const filteredFistTypes: FishType[] = filterFishTypes(values.batches || []); return ( setFieldValue('eventTime', e)} disabled={disabled} @@ -262,17 +261,17 @@ const RegistrationForm = ({ label="Laikas" minDate={new Date(new Date().setDate(new Date().getDate() + minTime))} onChange={(e: Date) => setFieldValue('eventTime', e)} - error={errors.eventTime} + error={errors.eventTime as string} value={values.eventTime} disabled={disabled} /> { setFieldValue('fishOrigin', e); setFieldValue('fishOriginCompanyName', ''); @@ -286,7 +285,7 @@ const RegistrationForm = ({ label="Žuvivaisos įmonė" name="fishOriginCompanyName" value={values.fishOriginCompanyName} - error={errors.fishOriginCompanyName} + error={errors.fishOriginCompanyName as string} onChange={(value) => setFieldValue('fishOriginCompanyName', value)} disabled={disabled} /> @@ -295,7 +294,7 @@ const RegistrationForm = ({ label="Vandens telkinys" name="fishOriginReservoir" value={values.fishOriginReservoir} - error={errors.fishOriginReservoir} + error={errors.fishOriginReservoir as string} onChange={(value) => setFieldValue('fishOriginReservoir', value)} hasOptionKey={false} getOptionValue={(option) => option?.cadastral_id} @@ -317,7 +316,7 @@ const RegistrationForm = ({ name="assignedTo" getOptionLabel={(option: any) => `${option.firstName} ${option.lastName}`} value={values.assignedTo} - error={errors.assignedTo} + error={errors.assignedTo as string} onChange={(value: any) => { setFieldValue('assignedTo', value); setFieldValue('phone', value?.phone || ''); @@ -331,7 +330,7 @@ const RegistrationForm = ({ name="phone" value={values.phone} placeholder="" - error={errors.phone} + error={errors.phone as string} onChange={(e: any) => { if (/^\+?[0-9\s]{0,11}$/.test(e)) { setFieldValue('phone', e); @@ -353,7 +352,7 @@ const RegistrationForm = ({ } getOptionLabel={(option: any) => option?.name} value={values.stockingCustomer} - error={errors.stockingCustomer} + error={errors.stockingCustomer as string} onChange={(value: any) => setFieldValue('stockingCustomer', value)} disabled={disabled} /> @@ -369,10 +368,14 @@ const RegistrationForm = ({ return ( { + setFieldValue(key, value); + }} + handleDelete={(e) => { + arrayHelpers.remove(e); + }} arrayHelpers={arrayHelpers} showDelete={values.batches.length > 1} index={index} diff --git a/src/components/other/FishRow.tsx b/src/components/other/FishRow.tsx index 548f866..79df3ed 100644 --- a/src/components/other/FishRow.tsx +++ b/src/components/other/FishRow.tsx @@ -19,12 +19,7 @@ export interface FishStickingRegistrationFishRowProps { fishAges: { label: string; id: string }[]; item: FishRow; setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void; - handleChange: { - (e: React.ChangeEvent): void; - >(field: T): T extends React.ChangeEvent - ? void - : (e: string | React.ChangeEvent) => void; - }; + handleDelete: (index: number) => void; arrayHelpers: ArrayHelpers; showDelete: boolean; index: number; @@ -44,6 +39,7 @@ const FishStickingRegistrationFishRow = ({ fishAges, item, setFieldValue, + handleDelete, arrayHelpers, showDelete, index, @@ -157,7 +153,7 @@ const FishStickingRegistrationFishRow = ({ disabled={disabled} /> {showDelete && !disabled && ( - arrayHelpers.remove(index)}> + handleDelete(index)}> )} diff --git a/src/utils/options.ts b/src/utils/options.ts new file mode 100644 index 0000000..b78b4a1 --- /dev/null +++ b/src/utils/options.ts @@ -0,0 +1,12 @@ +import { FishOriginTypes } from './constants'; + +export const fishOriginOptions = [ + { + value: FishOriginTypes.GROWN, + label: 'Užaugintos žuvivaisos įmonėje', + }, + { + label: 'Sugautos vandens telkinyje', + value: FishOriginTypes.CAUGHT, + }, +]; diff --git a/src/utils/types.ts b/src/utils/types.ts index c862419..ad670cc 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1,4 +1,4 @@ -import { FishOriginTypes, FishStockingStatus, RolesTypes } from "./constants"; +import { FishOriginTypes, FishStockingStatus, RolesTypes } from './constants'; export interface User { id?: string; firstName?: string; @@ -32,7 +32,7 @@ export interface TenantUser { user: User; } -export type ProfileId = "freelancer" | string; +export type ProfileId = 'freelancer' | string; export interface Profile { id: ProfileId; @@ -121,7 +121,7 @@ export interface FishStocking { name: string; municipality: { id: string; name: string }; }; - batches: Array; + batches: Array; //TODO: type needs to be defined assignedTo?: User; phone: string; reviewedBy?: User; From fabb60b4263bf49f96823c3c5458378bcefa5e9f Mon Sep 17 00:00:00 2001 From: Dovile Date: Fri, 19 Jan 2024 14:54:40 +0100 Subject: [PATCH 2/3] variuos fixes --- src/components/forms/Registration.tsx | 52 +++------ src/components/other/FishRow.tsx | 98 ++--------------- src/components/other/RegistrationMap.tsx | 74 ++++++------- src/utils/types.ts | 29 ++++- src/utils/validations.ts | 133 ++++++++++++----------- 5 files changed, 159 insertions(+), 227 deletions(-) diff --git a/src/components/forms/Registration.tsx b/src/components/forms/Registration.tsx index b71f9c4..1fb52c4 100644 --- a/src/components/forms/Registration.tsx +++ b/src/components/forms/Registration.tsx @@ -20,7 +20,7 @@ import { useSettings, } from '../../utils/hooks'; import { buttonsTitles, formLabels, queryStrings } from '../../utils/texts'; -import { FishStocking, FishType } from '../../utils/types'; +import { FishStocking, FishType, RegistrationFormValues } from '../../utils/types'; import { validateFishStocking, validateFreelancerFishStocking } from '../../utils/validations'; import Button, { ButtonColors } from '../buttons/Button'; import RadioOptions from '../buttons/RadioOptionts'; @@ -32,7 +32,7 @@ import SelectField from '../fields/SelectField'; import TextField from '../fields/TextField'; import TimePicker from '../fields/TimePicker'; import DeleteCard from '../other/DeleteCard'; -import FishStickingRegistrationFishRow from '../other/FishRow'; +import FishRow from '../other/FishRow'; import LoaderComponent from '../other/LoaderComponent'; import Modal from '../other/Modal'; import FishStockingPageTitle from '../other/PageTitle'; @@ -53,7 +53,6 @@ const RegistrationForm = ({ const [queryString, setQueryString] = useState(''); const isMobile = useMediaQuery(device.mobileL); const fishAges = useFishAges(); - // const fishTypes = useFishTypes(); const { minTime, loading } = useSettings(); const isFreelancer = useIsFreelancer(); const iframeRef = useRef(null); @@ -68,7 +67,8 @@ const RegistrationForm = ({ handleAlert(); }, }); - const fishTypesFullList = data?.rows; + + const fishTypesFullList = data?.rows || []; const callBacks = useFishStockingCallbacks(); @@ -105,8 +105,8 @@ const RegistrationForm = ({ const assignedTo = fishStocking?.assignedTo || fishStocking?.createdBy || null; - const initialValues: any = { - eventTime: fishStocking?.eventTime && !repeat ? new Date(fishStocking.eventTime) : null, + const initialValues: RegistrationFormValues = { + eventTime: fishStocking?.eventTime && !repeat ? new Date(fishStocking.eventTime) : undefined, fishOriginCompanyName: fishStocking?.fishOriginCompanyName || '', assignedTo: fishStocking?.assignedTo || user || undefined, fishOriginReservoir: fishStocking?.fishOriginReservoir || undefined, @@ -117,7 +117,6 @@ const RegistrationForm = ({ location: fishStocking?.location || undefined, batches: fishStocking?.batches || [{}], geom: fishStocking?.geom || undefined, - fishTypes: fishTypesFullList || [], }; const handleSubmit = async (values: any) => { @@ -148,7 +147,7 @@ const RegistrationForm = ({ batches: batches.map((batch) => { return { amount: batch.amount, - weight: batch.weight, + weight: batch.weight || undefined, fishType: batch?.fishType?.id, fishAge: batch?.fishAge?.id, }; @@ -200,7 +199,7 @@ const RegistrationForm = ({ const filterFishTypes = (batches: any[]) => { const batchesFishTypesIds = batches.filter((b) => !!b.fishType?.id).map((b) => b.fishType?.id); - return (fishTypesFullList || []).filter((fishType) => { + return fishTypesFullList.filter((fishType) => { const inBatches = batchesFishTypesIds.includes(fishType.id); return !inBatches; }); @@ -214,12 +213,12 @@ const RegistrationForm = ({ validationSchema={validationSchema} validateOnChange={false} > - {({ values, errors, handleSubmit, handleChange, setFieldValue }) => { + {({ values, errors, handleSubmit, handleChange, setFieldValue }: any) => { const filteredFistTypes: FishType[] = filterFishTypes(values.batches || []); return ( { if (e.key === 'Enter') { @@ -242,7 +241,6 @@ const RegistrationForm = ({ onChange={(location: any) => { const { geom, ...rest } = location; iframeRef?.current?.contentWindow?.postMessage(JSON.stringify({ geom }), '*'); - setFieldValue('geom', geom); setFieldValue('location', rest); }} @@ -281,7 +279,7 @@ const RegistrationForm = ({ /> {values.fishOrigin === FishOriginTypes.GROWN ? ( - - { const fishErrors = errors.batches?.[index]; return ( - { setFieldValue(key, value); @@ -376,32 +376,16 @@ const RegistrationForm = ({ handleDelete={(e) => { arrayHelpers.remove(e); }} - arrayHelpers={arrayHelpers} showDelete={values.batches.length > 1} - index={index} errors={fishErrors} - allFishSelections={values.batches} disabled={disabled} - fishAges={fishAges} /> ); })} {!disabled && ( { - arrayHelpers.push({ - type: { - label: '', - id: '', - }, - age: { - label: '', - id: '', - }, - amount: '', - weight: '', - error: false, - }); + arrayHelpers.push({}); }} > {buttonsTitles.addFish} @@ -460,11 +444,11 @@ const RegistrationForm = ({ ); }; -const StyledForm = styled(Form)<{ display: boolean }>` +const StyledForm = styled(Form)<{ $display: boolean }>` padding: 32px; flex-direction: column; gap: 12px; - display: ${({ display }) => (display ? 'flex' : 'none')}; + display: ${({ $display }) => ($display ? 'flex' : 'none')}; overflow-y: auto; @media ${device.mobileL} { diff --git a/src/components/other/FishRow.tsx b/src/components/other/FishRow.tsx index 79df3ed..2e0e187 100644 --- a/src/components/other/FishRow.tsx +++ b/src/components/other/FishRow.tsx @@ -1,117 +1,43 @@ -import { ArrayHelpers } from 'formik'; -import { differenceWith, filter } from 'lodash'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useState } from 'react'; import styled from 'styled-components'; import { device } from '../../styles'; import { default as NumericTextField } from '../fields/NumericTextField'; import SelectField from '../fields/SelectField'; import Icon from '../other/Icon'; +import { RegistrationFormFishRow } from '../../utils/types'; -export interface FishRow { - fishType: { label: string; id: string }; - fishAge: { label: string; id: string }; - amount: string | number; - weight: string | number; -} - -export interface FishStickingRegistrationFishRowProps { +export interface FishRowProps { fishTypes: { label: string; id: string }[]; fishAges: { label: string; id: string }[]; - item: FishRow; + item: RegistrationFormFishRow; setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void; handleDelete: (index: number) => void; - arrayHelpers: ArrayHelpers; showDelete: boolean; index: number; errors?: any; - allFishSelections?: { - fishType: any; - fishAge: any; - amount: string | number; - weight: string | number; - }[]; disabled?: boolean; key?: string; } -const FishStickingRegistrationFishRow = ({ +const FishRow = ({ fishTypes, fishAges, item, setFieldValue, handleDelete, - arrayHelpers, showDelete, index, errors, - allFishSelections, disabled, - key, -}: FishStickingRegistrationFishRowProps) => { +}: FishRowProps) => { const { fishType, fishAge, weight, amount } = item; - const getAvailableFishTypes = useCallback(() => { - if (item?.fishAge?.id) { - const batchesWithTheSameAge = filter(allFishSelections, (batch) => { - if (batch?.fishAge?.id === item?.fishAge?.id && batch?.fishType?.id) { - return batch; - } - }); - - const typesWithTheSameAge = batchesWithTheSameAge.map((b: any) => b.type); - - return differenceWith( - fishTypes, - typesWithTheSameAge, - (type1: any, type2: any) => type1?.id === type2?.id, - ); - } - return fishTypes; - }, [fishTypes, allFishSelections, item?.fishAge?.id]); - - const getAvailableFishAges = useCallback(() => { - if (item?.fishType?.id) { - const batchesWithTheSameAge = filter(allFishSelections, (batch) => { - if (batch.fishType?.id === item.fishType?.id && batch.fishAge?.value) { - return batch; - } - }); - const agesWithTheSameType = batchesWithTheSameAge.map((b: any) => b.age); - return differenceWith( - fishAges, - agesWithTheSameType, - (type1: any, type2: any) => type1?.id === type2?.id, - ); - } - return fishAges; - }, [fishAges, allFishSelections, item.fishType?.id]); - - const [availableFishTypes, setAvailableFishTypes] = useState(getAvailableFishTypes()); - const [availableFishAges, setAvailableFishAges] = useState(getAvailableFishAges()); - - useEffect(() => { - setAvailableFishTypes(getAvailableFishTypes()); - setAvailableFishAges(getAvailableFishAges()); - }, [getAvailableFishAges, getAvailableFishTypes]); - - useEffect(() => { - setAvailableFishTypes(getAvailableFishTypes()); - setAvailableFishAges(getAvailableFishAges()); - }, [ - fishType, - fishAge, - allFishSelections, - fishTypes, - getAvailableFishAges, - getAvailableFishTypes, - ]); - return ( - + setFieldValue(`batches.${index}.fishType`, e)} - options={availableFishTypes} + options={fishTypes} getOptionLabel={(option: any) => option?.label || ''} label="Žuvų rūšis" error={errors?.fishType} @@ -124,7 +50,7 @@ const FishStickingRegistrationFishRow = ({ onChange={(e: any) => { setFieldValue(`batches.${index}.fishAge`, e); }} - options={availableFishAges} + options={fishAges} getOptionLabel={(option: any) => option?.label || ''} label="Amžius" error={errors?.fishAge} @@ -161,10 +87,10 @@ const FishStickingRegistrationFishRow = ({ ); }; -const Row = styled.div<{ showDelete: boolean }>` +const Row = styled.div<{ $showDelete: boolean }>` display: grid; align-items: center; - grid-template-columns: 1fr 1fr 1fr 1fr ${({ showDelete }) => (showDelete ? '50px' : '')}; + grid-template-columns: 1fr 1fr 1fr 1fr ${({ $showDelete }) => ($showDelete ? '50px' : '')}; margin-bottom: 12px; gap: 12px; width: 100%; @@ -200,4 +126,4 @@ const InputInnerLabel = styled.div` color: ${({ theme }) => theme.colors.primary + '8F'}; `; -export default FishStickingRegistrationFishRow; +export default FishRow; diff --git a/src/components/other/RegistrationMap.tsx b/src/components/other/RegistrationMap.tsx index a6ce504..9998aeb 100644 --- a/src/components/other/RegistrationMap.tsx +++ b/src/components/other/RegistrationMap.tsx @@ -1,15 +1,15 @@ -import { useMediaQuery } from "@material-ui/core"; -import { isEmpty } from "lodash"; -import { useCallback, useEffect, useState } from "react"; -import { useMutation } from "react-query"; -import styled from "styled-components"; -import { device } from "../../styles"; -import api from "../../utils/api"; -import { handleAlert } from "../../utils/functions"; -import { buttonsTitles, Url } from "../../utils/texts"; -import Button from "../buttons/Button"; -import Icon from "./Icon"; -import LoaderComponent from "./LoaderComponent"; +import { useMediaQuery } from '@material-ui/core'; +import { isEmpty } from 'lodash'; +import { useCallback, useEffect, useState } from 'react'; +import { useMutation } from 'react-query'; +import styled from 'styled-components'; +import { device } from '../../styles'; +import api from '../../utils/api'; +import { handleAlert } from '../../utils/functions'; +import { buttonsTitles, Url } from '../../utils/texts'; +import Button from '../buttons/Button'; +import Icon from './Icon'; +import LoaderComponent from './LoaderComponent'; export interface MapProps { height?: string; @@ -22,14 +22,7 @@ export interface MapProps { iframeRef: any; } -const Map = ({ - height, - onSave, - onClose, - value, - display, - iframeRef -}: MapProps) => { +const Map = ({ height, onSave, onClose, value, display, iframeRef }: MapProps) => { const [showModal, setShowModal] = useState(false); const [geom, setGeom] = useState(); const [loading, setLoading] = useState(true); @@ -40,22 +33,19 @@ const Map = ({ const handleLoadMap = () => { setLoading(false); - iframeRef?.current?.contentWindow?.postMessage( - JSON.stringify({ geom: value }), - "*" - ); + iframeRef?.current?.contentWindow?.postMessage(JSON.stringify({ geom: value }), '*'); }; const locationMutation = useMutation( (location: any) => api.getLocations({ - geom: JSON.stringify(location) + geom: JSON.stringify(location), }), { onError: () => { handleAlert(); - } - } + }, + }, ); const locationMutationMutateAsync = locationMutation.mutateAsync; const handleGetLocations = useCallback( @@ -63,7 +53,7 @@ const Map = ({ setGeom(location); locationMutationMutateAsync(location); }, - [locationMutationMutateAsync] + [locationMutationMutateAsync], ); const handleSaveGeom = useCallback( @@ -77,18 +67,18 @@ const Map = ({ handleGetLocations(userObjects); }, - [handleGetLocations] + [handleGetLocations], ); useEffect(() => { - window.addEventListener("message", handleSaveGeom); - return () => window.removeEventListener("message", handleSaveGeom); + window.addEventListener('message', handleSaveGeom); + return () => window.removeEventListener('message', handleSaveGeom); }, [handleSaveGeom]); return ( <> {loading ? : null} - + {isMobile && ( - + )} @@ -125,8 +115,8 @@ const Map = ({ {!isEmpty(locationMutation.data) - ? locationMutation?.data?.map((location) => ( - + ? locationMutation?.data?.map((location, index) => ( + {location?.name} {`${location?.cadastral_id}, ${location?.municipality?.name}`} @@ -141,7 +131,7 @@ const Map = ({ )) - : "Nerastas telkinys"} + : 'Nerastas telkinys'} )} @@ -153,8 +143,8 @@ const Map = ({ allow="geolocation *" ref={iframeRef} src={src} - width={"100%"} - height={showModal ? "100%" : `${height || "230px"}`} + width={'100%'} + height={showModal ? '100%' : `${height || '230px'}`} style={{ border: 0 }} allowFullScreen={true} onLoad={handleLoadMap} @@ -167,10 +157,10 @@ const Map = ({ ); }; -const Container = styled.div<{ display: boolean }>` +const Container = styled.div<{ $display: boolean }>` width: 100%; height: 100%; - display: ${({ display }) => (display ? "flex" : "none")}; + display: ${({ $display }) => ($display ? 'flex' : 'none')}; `; const IconContainer = styled.div` @@ -241,15 +231,13 @@ const ModalContainer = styled.div<{ width?: string }>` background-color: white; flex-basis: auto; margin: auto; - display:flex + display: flex; flex-direction: column; gap: 12px; @media ${device.mobileL} { min-width: 100%; } - - `; const ItemContainer = styled.div` diff --git a/src/utils/types.ts b/src/utils/types.ts index ad670cc..a8e719e 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -101,6 +101,16 @@ export interface Municipality { name: string; } +export interface FishBatch { + id: number; + fishType: number | FishType; + fishAge: number | FishAge; + amount: number; + weight?: number; + reviewWeight?: number; + reviewAmount?: number; +} + export interface FishStocking { id: number; geom: any; @@ -121,7 +131,7 @@ export interface FishStocking { name: string; municipality: { id: string; name: string }; }; - batches: Array; //TODO: type needs to be defined + batches: Array; assignedTo?: User; phone: string; reviewedBy?: User; @@ -160,6 +170,11 @@ export interface FishType { label: string; } +export interface FishAge { + id: number; + label: number; +} + export interface FishStockingFilters { eventTimeFrom?: string; eventTimeTo?: string; @@ -176,3 +191,15 @@ export interface FishStockingParams { fishTypes?: Array; status?: string[]; } + +export interface RegistrationFormFishRow { + fishType?: FishType; + fishAge?: FishAge; + amount?: number; + weight?: number; +} + +export type RegistrationFormValues = Omit & { + eventTime?: Date; + batches: Array<{} | RegistrationFormFishRow>; +}; diff --git a/src/utils/validations.ts b/src/utils/validations.ts index 3bf9cdd..1081f02 100644 --- a/src/utils/validations.ts +++ b/src/utils/validations.ts @@ -1,30 +1,27 @@ -import { personalCode } from "lt-codes"; -import * as Yup from "yup"; -import { FishOriginTypes } from "./constants"; -import { validationTexts } from "./texts"; +import { personalCode } from 'lt-codes'; +import * as Yup from 'yup'; +import { FishOriginTypes } from './constants'; +import { validationTexts } from './texts'; +import { FishBatch, FishType } from './types'; export const loginSchema = Yup.object().shape({ - email: Yup.string() - .required(validationTexts.requireText) - .email(validationTexts.badEmailFormat), - password: Yup.string().required(validationTexts.requireText) + email: Yup.string().required(validationTexts.requireText).email(validationTexts.badEmailFormat), + password: Yup.string().required(validationTexts.requireText), }); export const validateNewTenantUser = Yup.object().shape({ - email: Yup.string() - .required(validationTexts.requireText) - .email(validationTexts.badEmailFormat), + email: Yup.string().required(validationTexts.requireText).email(validationTexts.badEmailFormat), firstName: Yup.string() .required(validationTexts.requireText) - .test("validFirstName", validationTexts.validFirstName, (values) => { - if (/\d/.test(values || "")) return false; + .test('validFirstName', validationTexts.validFirstName, (values) => { + if (/\d/.test(values || '')) return false; return true; }), lastName: Yup.string() .required(validationTexts.requireText) - .test("validLastName", validationTexts.validLastName, (values) => { - if (/\d/.test(values || "")) return false; + .test('validLastName', validationTexts.validLastName, (values) => { + if (/\d/.test(values || '')) return false; return true; }), @@ -35,78 +32,88 @@ export const validateNewTenantUser = Yup.object().shape({ personalCode: Yup.string() .required(validationTexts.requireText) .trim() - .test("validatePersonalCode", validationTexts.personalCode, (value) => { + .test('validatePersonalCode', validationTexts.personalCode, (value) => { return personalCode.validate(value!).isValid; - }) + }), }); export const validateUpdateTenantUser = Yup.object().shape({}); export const validateMyProfile = Yup.object().shape({ - email: Yup.string() - .required(validationTexts.requireText) - .email(validationTexts.badEmailFormat), + email: Yup.string().required(validationTexts.requireText).email(validationTexts.badEmailFormat), phone: Yup.string() .required(validationTexts.requireText) .trim() - .matches(/^(86|\+3706)\d{7}$/, validationTexts.badPhoneFormat) + .matches(/^(86|\+3706)\d{7}$/, validationTexts.badPhoneFormat), }); export const validateFishStocking = Yup.object().shape({ location: Yup.object().required(validationTexts.requireText), - eventTime: Yup.date().required(validationTexts.requireText).typeError(validationTexts.requireText), - assignedTo: Yup.object().required(validationTexts.requireText).nullable(), + eventTime: Yup.date() + .required(validationTexts.requireText) + .typeError(validationTexts.requireText), + assignedTo: Yup.object().required(validationTexts.requireText).nullable(), phone: Yup.string() .required(validationTexts.requireText) .trim() .matches(/^(86|\+3706)\d{7}$/, validationTexts.badPhoneFormat), batches: Yup.array().of( Yup.object().shape({ - fishType: Yup.object().required(validationTexts.requireSelect).nullable(), - fishAge: Yup.object().required(validationTexts.requireSelect).nullable(), - amount: Yup.string().required(validationTexts.requireText) - }) + fishType: Yup.object() + .required(validationTexts.requireSelect) + .shape({ + id: Yup.number().required(validationTexts.requireText), + }), + fishAge: Yup.object() + .required(validationTexts.requireSelect) + .shape({ + id: Yup.number().required(validationTexts.requireText), + }), + amount: Yup.string().required(validationTexts.requireText), + }), ), - fishOriginCompanyName: Yup.string().when( - "fishOrigin", - (fishOrigin: any, schema: any) => - fishOrigin?.[0] === FishOriginTypes.GROWN - ? schema.required(validationTexts.requireText) - : schema + fishOriginCompanyName: Yup.string().when('fishOrigin', (fishOrigin: any, schema: any) => + fishOrigin?.[0] === FishOriginTypes.GROWN + ? schema.required(validationTexts.requireText) + : schema, + ), + fishOriginReservoir: Yup.object().when('fishOrigin', (fishOrigin: any, schema: any) => + fishOrigin?.[0] === FishOriginTypes.CAUGHT + ? schema.required(validationTexts.requireText) + : schema, ), - fishOriginReservoir: Yup.object().when( - "fishOrigin", - (fishOrigin: any, schema: any) => - fishOrigin?.[0] === FishOriginTypes.CAUGHT - ? schema.required(validationTexts.requireText) - : schema - ) }); export const validateFreelancerFishStocking = Yup.object().shape({ location: Yup.object().required(validationTexts.requireText), - eventTime: Yup.date().required(validationTexts.requireText).typeError(validationTexts.requireText), + eventTime: Yup.date() + .required(validationTexts.requireText) + .typeError(validationTexts.requireText), batches: Yup.array().of( Yup.object().shape({ - fishType: Yup.object().required(validationTexts.requireSelect).nullable(), - fishAge: Yup.object().required(validationTexts.requireSelect).nullable(), - amount: Yup.string().required(validationTexts.requireText) - }) + fishType: Yup.object() + .required(validationTexts.requireSelect) + .shape({ + id: Yup.number().required(validationTexts.requireText), + }), + fishAge: Yup.object() + .required(validationTexts.requireSelect) + .shape({ + id: Yup.number().required(validationTexts.requireText), + }), + amount: Yup.string().required(validationTexts.requireText), + }), + ), + fishOriginCompanyName: Yup.string().when('fishOrigin', (fishOrigin: any, schema: any) => + fishOrigin?.[0] === FishOriginTypes.GROWN + ? schema.required(validationTexts.requireText) + : schema, ), - fishOriginCompanyName: Yup.string().when( - "fishOrigin", - (fishOrigin: any, schema: any) => - fishOrigin?.[0] === FishOriginTypes.GROWN - ? schema.required(validationTexts.requireText) - : schema + fishOriginReservoir: Yup.object().when('fishOrigin', (fishOrigin: any, schema: any) => + fishOrigin?.[0] === FishOriginTypes.CAUGHT + ? schema.required(validationTexts.requireText) + : schema, ), - fishOriginReservoir: Yup.object().when( - "fishOrigin", - (fishOrigin: any, schema: any) => - fishOrigin?.[0] === FishOriginTypes.CAUGHT - ? schema.required(validationTexts.requireText) - : schema - ) }); export const validateFishStockingReview = Yup.object().shape({ @@ -116,13 +123,13 @@ export const validateFishStockingReview = Yup.object().shape({ veterinaryApprovalNo: Yup.string().required(validationTexts.requireText), batches: Yup.array().of( Yup.object().shape({ - reviewAmount: Yup.string().required(validationTexts.requireText) - }) + reviewAmount: Yup.string().required(validationTexts.requireText), + }), ), signatures: Yup.array().of( Yup.object().shape({ organization: Yup.string().required(validationTexts.requireText), - signedBy: Yup.string().required(validationTexts.requireText) - }) - ) + signedBy: Yup.string().required(validationTexts.requireText), + }), + ), }); From 84b8fc25df7556c051d480b45ed78580299d91e1 Mon Sep 17 00:00:00 2001 From: Dovile Date: Fri, 19 Jan 2024 15:01:17 +0100 Subject: [PATCH 3/3] unnecessary string cast removed --- src/components/forms/Registration.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/forms/Registration.tsx b/src/components/forms/Registration.tsx index 1fb52c4..04322e9 100644 --- a/src/components/forms/Registration.tsx +++ b/src/components/forms/Registration.tsx @@ -250,7 +250,7 @@ const RegistrationForm = ({ label="Data" minDate={new Date(new Date().setDate(new Date().getDate() + minTime))} name="eventTime" - error={errors.eventTime as string} + error={errors.eventTime} value={values.eventTime} onChange={(e: any) => setFieldValue('eventTime', e)} disabled={disabled} @@ -259,7 +259,7 @@ const RegistrationForm = ({ label="Laikas" minDate={new Date(new Date().setDate(new Date().getDate() + minTime))} onChange={(e: Date) => setFieldValue('eventTime', e)} - error={errors.eventTime as string} + error={errors.eventTime} value={values.eventTime} disabled={disabled} /> @@ -269,7 +269,7 @@ const RegistrationForm = ({ label="Žuvų kilmė" name="fishOrigin" value={values.fishOrigin} - error={errors.fishOrigin as string} + error={errors.fishOrigin} onChange={(e: any) => { setFieldValue('fishOrigin', e); setFieldValue('fishOriginCompanyName', ''); @@ -283,7 +283,7 @@ const RegistrationForm = ({ label="Žuvivaisos įmonė" name="fishOriginCompanyName" value={values.fishOriginCompanyName} - error={errors.fishOriginCompanyName as string} + error={errors.fishOriginCompanyName} onChange={(value) => setFieldValue('fishOriginCompanyName', value)} disabled={disabled} /> @@ -292,7 +292,7 @@ const RegistrationForm = ({ label="Vandens telkinys" name="fishOriginReservoir" value={values.fishOriginReservoir} - error={errors.fishOriginReservoir as string} + error={errors.fishOriginReservoir} onChange={(value) => setFieldValue('fishOriginReservoir', value)} hasOptionKey={false} getOptionValue={(option) => option?.cadastral_id} @@ -314,7 +314,7 @@ const RegistrationForm = ({ name="assignedTo" getOptionLabel={(option: any) => `${option.firstName} ${option.lastName}`} value={values.assignedTo} - error={errors.assignedTo as string} + error={errors.assignedTo} onChange={(value: any) => { setFieldValue('assignedTo', value); setFieldValue('phone', value?.phone || ''); @@ -328,7 +328,7 @@ const RegistrationForm = ({ name="phone" value={values.phone} placeholder="" - error={errors.phone as string} + error={errors.phone} onChange={(e: any) => { if (/^\+?[0-9\s]{0,11}$/.test(e)) { setFieldValue('phone', e); @@ -350,7 +350,7 @@ const RegistrationForm = ({ } getOptionLabel={(option: any) => option?.name} value={values.stockingCustomer} - error={errors.stockingCustomer as string} + error={errors.stockingCustomer} onChange={(value: any) => setFieldValue('stockingCustomer', value)} disabled={disabled} />