mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
refactor(FE-114): rearrange code for better readability
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { FormikProps, useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { toast } from 'react-hot-toast';
|
|
||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
import TextInput from '@/components/input/TextInput';
|
import TextInput from '@/components/input/TextInput';
|
||||||
import NumberInput from '@/components/input/NumberInput';
|
import NumberInput from '@/components/input/NumberInput';
|
||||||
@@ -42,8 +41,8 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
const [selectedWeight, setSelectedWeight] = useState<number[]>([]);
|
const [selectedWeight, setSelectedWeight] = useState<number[]>([]);
|
||||||
const [selectedVaccine, setSelectedVaccine] = useState<number[]>([]);
|
const [selectedVaccine, setSelectedVaccine] = useState<number[]>([]);
|
||||||
const [selectedMortality, setSelectedMortality] = useState<number[]>([]);
|
const [selectedMortality, setSelectedMortality] = useState<number[]>([]);
|
||||||
|
|
||||||
const [, setRecordingFormErrorMessage] = useState('');
|
const [, setRecordingFormErrorMessage] = useState('');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
deleteModal,
|
deleteModal,
|
||||||
recordingFormErrorMessage,
|
recordingFormErrorMessage,
|
||||||
@@ -107,15 +106,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Locations
|
||||||
const locationsUrl = `${LocationApi.basePath}?${new URLSearchParams({ search: locationSelectInputValue }).toString()}`;
|
const locationsUrl = `${LocationApi.basePath}?${new URLSearchParams({ search: locationSelectInputValue }).toString()}`;
|
||||||
const { data: locations, isLoading: isLoadingLocations } = useSWR(
|
const { data: locations, isLoading: isLoadingLocations } = useSWR(
|
||||||
locationsUrl,
|
locationsUrl,
|
||||||
LocationApi.getAllFetcher
|
LocationApi.getAllFetcher
|
||||||
);
|
);
|
||||||
const locationOptions = isResponseSuccess(locations)
|
|
||||||
? locations.data.map((loc) => ({ value: loc.id, label: loc.name }))
|
|
||||||
: [];
|
|
||||||
|
|
||||||
|
// Project Flocks
|
||||||
const projectFlocksUrl = useMemo(() => {
|
const projectFlocksUrl = useMemo(() => {
|
||||||
if (!formik.values.location_id) return null;
|
if (!formik.values.location_id) return null;
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
@@ -130,13 +128,39 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
ProjectFlockApi.getAllFetcher
|
ProjectFlockApi.getAllFetcher
|
||||||
);
|
);
|
||||||
|
|
||||||
const flockOptions = isResponseSuccess(projectFlocks)
|
// Pakan Products
|
||||||
? projectFlocks.data.map((flock) => ({
|
const pakanUrl = useMemo(() => {
|
||||||
value: flock.id,
|
if (!formik.values.location_id) return null;
|
||||||
label: flock.flock.name,
|
const params = new URLSearchParams({
|
||||||
}))
|
flag: 'PAKAN',
|
||||||
: [];
|
search: '',
|
||||||
|
location_id: formik.values.location_id.toString(),
|
||||||
|
});
|
||||||
|
return `${ProductWarehouseApi.basePath}?${params.toString()}`;
|
||||||
|
}, [formik.values.location_id]);
|
||||||
|
|
||||||
|
const { data: pakanProducts, isLoading: isLoadingPakan } = useSWR(
|
||||||
|
pakanUrl,
|
||||||
|
ProductWarehouseApi.getAllFetcher
|
||||||
|
);
|
||||||
|
|
||||||
|
// OVK Products
|
||||||
|
const ovkUrl = useMemo(() => {
|
||||||
|
if (!formik.values.location_id) return null;
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
flag: 'OVK',
|
||||||
|
search: '',
|
||||||
|
location_id: formik.values.location_id.toString(),
|
||||||
|
});
|
||||||
|
return `${ProductWarehouseApi.basePath}?${params.toString()}`;
|
||||||
|
}, [formik.values.location_id]);
|
||||||
|
|
||||||
|
const { data: ovkProducts, isLoading: isLoadingOvk } = useSWR(
|
||||||
|
ovkUrl,
|
||||||
|
ProductWarehouseApi.getAllFetcher
|
||||||
|
);
|
||||||
|
|
||||||
|
// COMPUTED VALUES
|
||||||
const buildWarehouseLabel = useCallback((warehouse: Warehouse) => {
|
const buildWarehouseLabel = useCallback((warehouse: Warehouse) => {
|
||||||
const parts: string[] = [warehouse.name];
|
const parts: string[] = [warehouse.name];
|
||||||
|
|
||||||
@@ -155,20 +179,24 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return parts.join(' - ');
|
return parts.join(' - ');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const pakanUrl = useMemo(() => {
|
const locationOptions = isResponseSuccess(locations)
|
||||||
if (!formik.values.location_id) return null;
|
? locations.data.map((loc) => ({ value: loc.id, label: loc.name }))
|
||||||
const params = new URLSearchParams({
|
: [];
|
||||||
flag: 'PAKAN',
|
|
||||||
search: '',
|
|
||||||
location_id: formik.values.location_id.toString(),
|
|
||||||
});
|
|
||||||
return `${ProductWarehouseApi.basePath}?${params.toString()}`;
|
|
||||||
}, [formik.values.location_id]);
|
|
||||||
|
|
||||||
const { data: pakanProducts, isLoading: isLoadingPakan } = useSWR(
|
const flockOptions = isResponseSuccess(projectFlocks)
|
||||||
pakanUrl,
|
? projectFlocks.data.map((flock) => ({
|
||||||
ProductWarehouseApi.getAllFetcher
|
value: flock.id,
|
||||||
);
|
label: flock.flock.name,
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const coopOptions = useMemo(() => {
|
||||||
|
if (!selectedProjectFlock || !selectedProjectFlock.kandangs) return [];
|
||||||
|
return selectedProjectFlock.kandangs.map((kandang) => ({
|
||||||
|
value: kandang.id,
|
||||||
|
label: kandang.name,
|
||||||
|
}));
|
||||||
|
}, [selectedProjectFlock]);
|
||||||
|
|
||||||
const filteredPakanProducts = useMemo(() => {
|
const filteredPakanProducts = useMemo(() => {
|
||||||
if (!isResponseSuccess(pakanProducts) || !formik.values.location_id)
|
if (!isResponseSuccess(pakanProducts) || !formik.values.location_id)
|
||||||
@@ -181,8 +209,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return warehouse.location.id === formik.values.location_id;
|
return warehouse.location.id === formik.values.location_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If warehouse only has area, include it if area matches the location's area
|
|
||||||
// Note: This might need adjustment based on your business logic
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}, [pakanProducts, formik.values.location_id]);
|
}, [pakanProducts, formik.values.location_id]);
|
||||||
@@ -204,21 +230,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return map;
|
return map;
|
||||||
}, [filteredPakanProducts]);
|
}, [filteredPakanProducts]);
|
||||||
|
|
||||||
const ovkUrl = useMemo(() => {
|
|
||||||
if (!formik.values.location_id) return null;
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
flag: 'OVK',
|
|
||||||
search: '',
|
|
||||||
location_id: formik.values.location_id.toString(),
|
|
||||||
});
|
|
||||||
return `${ProductWarehouseApi.basePath}?${params.toString()}`;
|
|
||||||
}, [formik.values.location_id]);
|
|
||||||
|
|
||||||
const { data: ovkProducts, isLoading: isLoadingOvk } = useSWR(
|
|
||||||
ovkUrl,
|
|
||||||
ProductWarehouseApi.getAllFetcher
|
|
||||||
);
|
|
||||||
|
|
||||||
const filteredOvkProducts = useMemo(() => {
|
const filteredOvkProducts = useMemo(() => {
|
||||||
if (!isResponseSuccess(ovkProducts) || !formik.values.location_id)
|
if (!isResponseSuccess(ovkProducts) || !formik.values.location_id)
|
||||||
return [];
|
return [];
|
||||||
@@ -230,8 +241,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return warehouse.location.id === formik.values.location_id;
|
return warehouse.location.id === formik.values.location_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If warehouse only has area, include it if area matches the location's area
|
|
||||||
// Note: This might need adjustment based on your business logic
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}, [ovkProducts, formik.values.location_id]);
|
}, [ovkProducts, formik.values.location_id]);
|
||||||
@@ -253,14 +262,19 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
return map;
|
return map;
|
||||||
}, [filteredOvkProducts]);
|
}, [filteredOvkProducts]);
|
||||||
|
|
||||||
const coopOptions = useMemo(() => {
|
// EFFECTS
|
||||||
if (!selectedProjectFlock || !selectedProjectFlock.kandangs) return [];
|
useEffect(() => {
|
||||||
return selectedProjectFlock.kandangs.map((kandang) => ({
|
if (initialValues?.flock && isResponseSuccess(projectFlocks)) {
|
||||||
value: kandang.id,
|
const flock = projectFlocks.data.find(
|
||||||
label: kandang.name,
|
(f) => f.id === initialValues.flock.id
|
||||||
}));
|
);
|
||||||
}, [selectedProjectFlock]);
|
if (flock) {
|
||||||
|
setSelectedProjectFlock(flock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [initialValues, projectFlocks]);
|
||||||
|
|
||||||
|
// EVENT HANDLERS - Select Inputs
|
||||||
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
|
||||||
const locationValue = (val as OptionType)?.value;
|
const locationValue = (val as OptionType)?.value;
|
||||||
|
|
||||||
@@ -298,17 +312,120 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
formik.setFieldValue('coop_id', coopValue || 0, false);
|
formik.setFieldValue('coop_id', coopValue || 0, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
// EVENT HANDLERS - Feed Data
|
||||||
if (initialValues?.flock && isResponseSuccess(projectFlocks)) {
|
const addFeedData = () => {
|
||||||
const flock = projectFlocks.data.find(
|
const newFeedData = [
|
||||||
(f) => f.id === initialValues.flock.id
|
...(formik.values.feed_data || []),
|
||||||
);
|
{
|
||||||
if (flock) {
|
feed: null,
|
||||||
setSelectedProjectFlock(flock);
|
feed_id: '',
|
||||||
}
|
feed_qty: '',
|
||||||
}
|
feed_stock: 0,
|
||||||
}, [initialValues, projectFlocks]);
|
},
|
||||||
|
];
|
||||||
|
formik.setFieldValue('feed_data', newFeedData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeFeedData = (idx: number) => {
|
||||||
|
const updatedFeedData = formik.values.feed_data?.filter(
|
||||||
|
(_, i) => i !== idx
|
||||||
|
);
|
||||||
|
formik.setFieldValue('feed_data', updatedFeedData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSelectedFeedData = () => {
|
||||||
|
const updatedFeedData = formik.values.feed_data?.filter(
|
||||||
|
(_, idx) => !selectedFeed.includes(idx)
|
||||||
|
);
|
||||||
|
formik.setFieldValue('feed_data', updatedFeedData);
|
||||||
|
setSelectedFeed([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// EVENT HANDLERS - Body Weight
|
||||||
|
const addBodyWeight = () => {
|
||||||
|
const newBodyWeight = [
|
||||||
|
...(formik.values.body_weight || []),
|
||||||
|
{
|
||||||
|
chicken_weight: 0,
|
||||||
|
chicken_count: 0,
|
||||||
|
average_chicken_weight: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
formik.setFieldValue('body_weight', newBodyWeight);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeBodyWeight = (idx: number) => {
|
||||||
|
const updatedBodyWeight = formik.values.body_weight?.filter(
|
||||||
|
(_, i) => i !== idx
|
||||||
|
);
|
||||||
|
formik.setFieldValue('body_weight', updatedBodyWeight);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSelectedBodyWeight = () => {
|
||||||
|
const updatedBodyWeight = formik.values.body_weight?.filter(
|
||||||
|
(_, idx) => !selectedWeight.includes(idx)
|
||||||
|
);
|
||||||
|
formik.setFieldValue('body_weight', updatedBodyWeight);
|
||||||
|
setSelectedWeight([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// EVENT HANDLERS - Vaccination
|
||||||
|
const addVaccination = () => {
|
||||||
|
const newVaccination = [
|
||||||
|
...(formik.values.vaccination || []),
|
||||||
|
{
|
||||||
|
vaccine: null,
|
||||||
|
vaccine_id: '',
|
||||||
|
total_stock: '',
|
||||||
|
used_stock: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
formik.setFieldValue('vaccination', newVaccination);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeVaccination = (idx: number) => {
|
||||||
|
const updatedVaccination = formik.values.vaccination?.filter(
|
||||||
|
(_, i) => i !== idx
|
||||||
|
);
|
||||||
|
formik.setFieldValue('vaccination', updatedVaccination);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSelectedVaccination = () => {
|
||||||
|
const updatedVaccination = formik.values.vaccination?.filter(
|
||||||
|
(_, idx) => !selectedVaccine.includes(idx)
|
||||||
|
);
|
||||||
|
formik.setFieldValue('vaccination', updatedVaccination);
|
||||||
|
setSelectedVaccine([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// EVENT HANDLERS - Mortality
|
||||||
|
const addMortality = () => {
|
||||||
|
const newMortality = [
|
||||||
|
...(formik.values.mortality || []),
|
||||||
|
{
|
||||||
|
condition: RECORDING_FLAG_OPTIONS[0].value,
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
formik.setFieldValue('mortality', newMortality);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeMortality = (idx: number) => {
|
||||||
|
const updatedMortality = formik.values.mortality?.filter(
|
||||||
|
(_, i) => i !== idx
|
||||||
|
);
|
||||||
|
formik.setFieldValue('mortality', updatedMortality);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeSelectedMortality = () => {
|
||||||
|
const updatedMortality = formik.values.mortality?.filter(
|
||||||
|
(_, idx) => !selectedMortality.includes(idx)
|
||||||
|
);
|
||||||
|
formik.setFieldValue('mortality', updatedMortality);
|
||||||
|
setSelectedMortality([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// HELPER FUNCTIONS
|
||||||
const isRepeaterInputError = <T extends keyof CreateRecordingPayload>(
|
const isRepeaterInputError = <T extends keyof CreateRecordingPayload>(
|
||||||
arrayName: T,
|
arrayName: T,
|
||||||
field: T extends 'feed_data'
|
field: T extends 'feed_data'
|
||||||
@@ -350,115 +467,6 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFeedData = () => {
|
|
||||||
const newFeedData = [
|
|
||||||
...(formik.values.feed_data || []),
|
|
||||||
{
|
|
||||||
feed: null,
|
|
||||||
feed_id: '',
|
|
||||||
feed_qty: '',
|
|
||||||
feed_stock: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
formik.setFieldValue('feed_data', newFeedData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeFeedData = (idx: number) => {
|
|
||||||
const updatedFeedData = formik.values.feed_data?.filter(
|
|
||||||
(_, i) => i !== idx
|
|
||||||
);
|
|
||||||
formik.setFieldValue('feed_data', updatedFeedData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeSelectedFeedData = () => {
|
|
||||||
const updatedFeedData = formik.values.feed_data?.filter(
|
|
||||||
(_, idx) => !selectedFeed.includes(idx)
|
|
||||||
);
|
|
||||||
formik.setFieldValue('feed_data', updatedFeedData);
|
|
||||||
setSelectedFeed([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addBodyWeight = () => {
|
|
||||||
const newBodyWeight = [
|
|
||||||
...(formik.values.body_weight || []),
|
|
||||||
{
|
|
||||||
chicken_weight: 0,
|
|
||||||
chicken_count: 0,
|
|
||||||
average_chicken_weight: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
formik.setFieldValue('body_weight', newBodyWeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeBodyWeight = (idx: number) => {
|
|
||||||
const updatedBodyWeight = formik.values.body_weight?.filter(
|
|
||||||
(_, i) => i !== idx
|
|
||||||
);
|
|
||||||
formik.setFieldValue('body_weight', updatedBodyWeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeSelectedBodyWeight = () => {
|
|
||||||
const updatedBodyWeight = formik.values.body_weight?.filter(
|
|
||||||
(_, idx) => !selectedWeight.includes(idx)
|
|
||||||
);
|
|
||||||
formik.setFieldValue('body_weight', updatedBodyWeight);
|
|
||||||
setSelectedWeight([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addVaccination = () => {
|
|
||||||
const newVaccination = [
|
|
||||||
...(formik.values.vaccination || []),
|
|
||||||
{
|
|
||||||
vaccine: null,
|
|
||||||
vaccine_id: '',
|
|
||||||
total_stock: '',
|
|
||||||
used_stock: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
formik.setFieldValue('vaccination', newVaccination);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeVaccination = (idx: number) => {
|
|
||||||
const updatedVaccination = formik.values.vaccination?.filter(
|
|
||||||
(_, i) => i !== idx
|
|
||||||
);
|
|
||||||
formik.setFieldValue('vaccination', updatedVaccination);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeSelectedVaccination = () => {
|
|
||||||
const updatedVaccination = formik.values.vaccination?.filter(
|
|
||||||
(_, idx) => !selectedVaccine.includes(idx)
|
|
||||||
);
|
|
||||||
formik.setFieldValue('vaccination', updatedVaccination);
|
|
||||||
setSelectedVaccine([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addMortality = () => {
|
|
||||||
const newMortality = [
|
|
||||||
...(formik.values.mortality || []),
|
|
||||||
{
|
|
||||||
condition: RECORDING_FLAG_OPTIONS[0].value,
|
|
||||||
count: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
formik.setFieldValue('mortality', newMortality);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeMortality = (idx: number) => {
|
|
||||||
const updatedMortality = formik.values.mortality?.filter(
|
|
||||||
(_, i) => i !== idx
|
|
||||||
);
|
|
||||||
formik.setFieldValue('mortality', updatedMortality);
|
|
||||||
};
|
|
||||||
|
|
||||||
const removeSelectedMortality = () => {
|
|
||||||
const updatedMortality = formik.values.mortality?.filter(
|
|
||||||
(_, idx) => !selectedMortality.includes(idx)
|
|
||||||
);
|
|
||||||
formik.setFieldValue('mortality', updatedMortality);
|
|
||||||
setSelectedMortality([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section className='w-full max-w-5xl'>
|
<section className='w-full max-w-5xl'>
|
||||||
|
|||||||
Reference in New Issue
Block a user