mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 06:45:46 +00:00
refactor(FE-239-238): Refactor UI & API Integration For Form Chickin & Chickin Details
This commit is contained in:
@@ -12,9 +12,12 @@ export default function AddChickinKandang() {
|
||||
const projectFlockId = searchParams.get('projectFlockId');
|
||||
const router = useRouter();
|
||||
|
||||
const { data: projectFlockKandang, isLoading: isLoading } = useSWR(
|
||||
projectFlockKandangId,
|
||||
(id: number) => ProjectFlockKandangApi.getSingle(id)
|
||||
const {
|
||||
data: projectFlockKandang,
|
||||
isLoading: isLoading,
|
||||
mutate: refreshProjectFlockKandang,
|
||||
} = useSWR(projectFlockKandangId, (id: number) =>
|
||||
ProjectFlockKandangApi.getSingle(id)
|
||||
);
|
||||
|
||||
if (!projectFlockKandangId) {
|
||||
@@ -31,6 +34,10 @@ export default function AddChickinKandang() {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleAfterSubmit = () => {
|
||||
refreshProjectFlockKandang();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className='w-full p-4'>
|
||||
@@ -38,7 +45,10 @@ export default function AddChickinKandang() {
|
||||
{!isLoading &&
|
||||
isResponseSuccess(projectFlockKandang) &&
|
||||
projectFlockId && (
|
||||
<ChickinForm initialValues={projectFlockKandang.data} />
|
||||
<ChickinForm
|
||||
initialValues={projectFlockKandang.data}
|
||||
afterSubmit={handleAfterSubmit}
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
|
||||
@@ -6,7 +6,7 @@ import Modal, { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import ChickinForm from '@/components/pages/production/chickin/form/ChickinForm';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { ChickinApi } from '@/services/api/production';
|
||||
import { ChickinApi } from '@/services/api/production/chickin';
|
||||
import { BaseApiResponse } from '@/types/api/api-general';
|
||||
import {
|
||||
Chickin,
|
||||
|
||||
@@ -57,7 +57,7 @@ const ProjectFlockDetail = () => {
|
||||
flock: flock.data.find(
|
||||
(flock) =>
|
||||
flock.name ==
|
||||
projectFlock.data.flock_name
|
||||
projectFlock?.data?.flock_name
|
||||
.trim()
|
||||
.split(/\s+/)
|
||||
.slice(0, -1)
|
||||
|
||||
@@ -13,7 +13,7 @@ import { TableRowSizeSelector } from '@/components/table/TableRowSizeSelector';
|
||||
import { ROWS_OPTIONS } from '@/config/constant';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { cn, formatNumber } from '@/lib/helper';
|
||||
import { ChickinApi } from '@/services/api/production';
|
||||
import { ChickinApi } from '@/services/api/production/chickin';
|
||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||
import { Chickin } from '@/types/api/production/chickin';
|
||||
import { Icon } from '@iconify/react';
|
||||
|
||||
@@ -1,33 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import Card from '@/components/Card';
|
||||
import { FormHeader } from '@/components/helper/form/FormHeader';
|
||||
import DateInput from '@/components/input/DateInput';
|
||||
import FileInput from '@/components/input/FileInput';
|
||||
import NumberInput from '@/components/input/NumberInput';
|
||||
import SelectInput, { OptionType } from '@/components/input/SelectInput';
|
||||
import TextInput from '@/components/input/TextInput';
|
||||
import Table from '@/components/Table';
|
||||
import { formatNumber } from '@/lib/helper';
|
||||
import { Kandang } from '@/types/api/master-data/kandang';
|
||||
import {
|
||||
AvailableQty,
|
||||
ProjectFlockKandang,
|
||||
} from '@/types/api/production/project-flock-kandang';
|
||||
import { useFormik } from 'formik';
|
||||
import {
|
||||
ChickinFormValues,
|
||||
ChickinRequestFormValues,
|
||||
ChickinSchema,
|
||||
} from './ChickinForm.schema';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { CreateChickinPayload } from '@/types/api/production/chickin';
|
||||
import { ChickinApi } from '@/services/api/production';
|
||||
import { isResponseError } from '@/lib/api-helper';
|
||||
import toast from 'react-hot-toast';
|
||||
import { flushSync } from 'react-dom';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
import Tabs from '@/components/Tabs';
|
||||
import ChickinFormView from './tabs/ChickinFormView';
|
||||
import ChickinLogsView from './tabs/ChickLogsView';
|
||||
import { useState } from 'react';
|
||||
const ChickinFormKandang = ({
|
||||
formType = 'add',
|
||||
initialValues,
|
||||
@@ -37,91 +19,13 @@ const ChickinFormKandang = ({
|
||||
initialValues: ProjectFlockKandang;
|
||||
afterSubmit?: () => void;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const [chickinErrorMessage, setChickinErrorMessage] = useState('');
|
||||
const [activeTabId, setActiveTabId] = useState<string>('formChickIn');
|
||||
|
||||
const createChickin = useCallback(
|
||||
async (payload: CreateChickinPayload) => {
|
||||
const createChickinRes = await ChickinApi.create(payload);
|
||||
if (isResponseError(createChickinRes)) {
|
||||
setChickinErrorMessage(createChickinRes.message);
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success(createChickinRes?.message as string);
|
||||
router.push(
|
||||
`/production/project-flock/chickin/add?projectFlockId=${initialValues?.project_flock?.id}`
|
||||
);
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const handleReset = async () => {
|
||||
flushSync(() => {
|
||||
formik.resetForm({
|
||||
values: {
|
||||
project_flock_kandang_id: initialValues?.id,
|
||||
chickin_requests: initialValues?.available_qtys
|
||||
? initialValues.available_qtys.map((availableQty) => ({
|
||||
chick_in_date: '',
|
||||
product_warehouse_id: availableQty.product_warehouse.id,
|
||||
available_qty: availableQty.available_qty,
|
||||
note: `Chickin project-flock-kandang-${initialValues?.id} product-warehouse-${availableQty.product_warehouse.id}`,
|
||||
}))
|
||||
: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
formik.setTouched({
|
||||
chickin_requests: initialValues?.available_qtys?.map(() => ({
|
||||
chick_in_date: true,
|
||||
})),
|
||||
});
|
||||
|
||||
const errors = await formik.validateForm();
|
||||
formik.setErrors(errors);
|
||||
const afterSubmitFormChickin = () => {
|
||||
setActiveTabId('logsChickIn');
|
||||
afterSubmit && afterSubmit();
|
||||
};
|
||||
|
||||
const formik = useFormik<ChickinFormValues>({
|
||||
enableReinitialize: true,
|
||||
validationSchema: ChickinSchema,
|
||||
initialValues: {
|
||||
project_flock_kandang_id: initialValues?.id,
|
||||
chickin_requests: initialValues?.available_qtys
|
||||
? initialValues.available_qtys.map((availableQty) => ({
|
||||
chick_in_date: '',
|
||||
product_warehouse_id: availableQty.product_warehouse.id,
|
||||
available_qty: availableQty.available_qty,
|
||||
note: `Chickin project-flock-kandang-${initialValues?.id} product-warehouse-${availableQty.product_warehouse.id}`,
|
||||
}))
|
||||
: [],
|
||||
},
|
||||
onSubmit: (values) => {
|
||||
setChickinErrorMessage('');
|
||||
createChickin(values as CreateChickinPayload);
|
||||
if (afterSubmit) {
|
||||
afterSubmit();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const { setValues: formikSetValues } = formik;
|
||||
|
||||
useEffect(() => {
|
||||
formikSetValues({
|
||||
project_flock_kandang_id: initialValues?.id,
|
||||
chickin_requests: initialValues?.available_qtys
|
||||
? initialValues.available_qtys.map((availableQty) => ({
|
||||
chick_in_date: '',
|
||||
product_warehouse_id: availableQty.product_warehouse.id,
|
||||
available_qty: availableQty.available_qty,
|
||||
note: `Chickin project-flock-kandang-${initialValues?.id} product-warehouse-${availableQty.product_warehouse.id}`,
|
||||
}))
|
||||
: [],
|
||||
});
|
||||
}, [formikSetValues, initialValues]);
|
||||
|
||||
return (
|
||||
<div className='flex flex-col gap-4'>
|
||||
<FormHeader
|
||||
@@ -129,172 +33,91 @@ const ChickinFormKandang = ({
|
||||
title='Chick In DOC'
|
||||
backUrl={`/production/project-flock/chickin/add?projectFlockId=${initialValues?.project_flock?.id}`}
|
||||
/>
|
||||
<form
|
||||
className='flex flex-col gap-4'
|
||||
onReset={(e) => {
|
||||
handleReset();
|
||||
<Card
|
||||
title='Informasi Kandang'
|
||||
className={{
|
||||
wrapper: 'w-full bg-white mt-4',
|
||||
}}
|
||||
onSubmit={formik.handleSubmit}
|
||||
>
|
||||
<Card
|
||||
title='Informasi Kandang'
|
||||
<Table<Kandang>
|
||||
emptyContent={
|
||||
<div className='w-full p-5 text-center'>
|
||||
<span className='text-lg opacity-50'>
|
||||
Informasi Kandang belum tersedia...
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
data={[initialValues?.kandang]}
|
||||
columns={[
|
||||
{
|
||||
header: 'Area',
|
||||
accessorFn: () => initialValues?.project_flock?.area.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Lokasi',
|
||||
accessorFn: () =>
|
||||
initialValues?.project_flock?.location.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Flock',
|
||||
accessorFn: () => initialValues?.project_flock?.flock_name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Kandang',
|
||||
accessorFn: (row) => row?.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Kapasitas',
|
||||
accessorFn: (row) =>
|
||||
(row?.capacity && formatNumber(row?.capacity)) || '-',
|
||||
},
|
||||
{
|
||||
header: 'Penanggung Jawab',
|
||||
accessorFn: (row) => row?.pic?.name || '-',
|
||||
},
|
||||
]}
|
||||
className={{
|
||||
wrapper: 'w-full bg-white mt-4',
|
||||
tableWrapperClassName: 'overflow-x-auto min-h-full!',
|
||||
tableClassName: 'font-inter w-full table-auto min-h-full!',
|
||||
headerRowClassName: 'border-b border-b-gray-200',
|
||||
headerColumnClassName:
|
||||
'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
|
||||
bodyRowClassName: 'border-b border-b-gray-200',
|
||||
bodyColumnClassName:
|
||||
'px-6 py-3 last:flex last:flex-row last:justify-end',
|
||||
paginationClassName: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Table<Kandang>
|
||||
emptyContent={
|
||||
<div className='w-full p-5 text-center'>
|
||||
<span className='text-lg opacity-50'>
|
||||
Informasi Kandang belum tersedia...
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
data={[initialValues?.kandang]}
|
||||
columns={[
|
||||
{
|
||||
header: 'Area',
|
||||
accessorFn: () =>
|
||||
initialValues?.project_flock?.area.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Lokasi',
|
||||
accessorFn: () =>
|
||||
initialValues?.project_flock?.location.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Flock',
|
||||
accessorFn: () =>
|
||||
initialValues?.project_flock?.flock_name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Kandang',
|
||||
accessorFn: (row) => row?.name || '-',
|
||||
},
|
||||
{
|
||||
header: 'Kapasitas',
|
||||
accessorFn: (row) =>
|
||||
(row?.capacity && formatNumber(row?.capacity)) || '-',
|
||||
},
|
||||
{
|
||||
header: 'Penanggung Jawab',
|
||||
accessorFn: (row) => row?.pic?.name || '-',
|
||||
},
|
||||
]}
|
||||
className={{
|
||||
tableWrapperClassName: 'overflow-x-auto min-h-full!',
|
||||
tableClassName: 'font-inter w-full table-auto min-h-full!',
|
||||
headerRowClassName: 'border-b border-b-gray-200',
|
||||
headerColumnClassName:
|
||||
'px-6 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
|
||||
bodyRowClassName: 'border-b border-b-gray-200',
|
||||
bodyColumnClassName:
|
||||
'px-6 py-3 last:flex last:flex-row last:justify-end',
|
||||
paginationClassName: 'hidden',
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
<Card
|
||||
title='Informasi Chick In DOC'
|
||||
className={{
|
||||
wrapper: 'w-full bg-white',
|
||||
}}
|
||||
>
|
||||
<Table<ChickinRequestFormValues>
|
||||
data={formik.values.chickin_requests || []}
|
||||
columns={[
|
||||
{
|
||||
accessorFn: (row) => row.chick_in_date,
|
||||
header: 'Tanggal Chick In',
|
||||
cell(props) {
|
||||
return (
|
||||
<DateInput
|
||||
name={`chickin_requests[${props.row.index}].chick_in_date`}
|
||||
value={
|
||||
formik.values.chickin_requests[props.row.index]
|
||||
?.chick_in_date as string
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorFn: (row) => row.product_warehouse_id,
|
||||
header: 'Produk',
|
||||
cell(props) {
|
||||
const availableQty = initialValues?.available_qtys?.find(
|
||||
(availableQty) =>
|
||||
availableQty.product_warehouse.id ===
|
||||
props.row.original.product_warehouse_id
|
||||
);
|
||||
return (
|
||||
<SelectInput
|
||||
value={
|
||||
{
|
||||
label: availableQty?.product_warehouse?.product?.name,
|
||||
value: availableQty?.product_warehouse?.product?.id,
|
||||
} as OptionType
|
||||
}
|
||||
options={[]}
|
||||
isDisabled
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorFn: (row) => row.product_warehouse_id,
|
||||
header: 'Jumlah (ekor)',
|
||||
cell(props) {
|
||||
const availableQty = initialValues?.available_qtys?.find(
|
||||
(availableQty) =>
|
||||
availableQty.product_warehouse.id ===
|
||||
props.row.original.product_warehouse_id
|
||||
);
|
||||
return (
|
||||
<NumberInput
|
||||
name='qty[]'
|
||||
value={availableQty?.available_qty}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
className={{
|
||||
tableWrapperClassName: 'overflow-x-auto min-h-full!',
|
||||
tableClassName: 'font-inter w-full table-auto min-h-full!',
|
||||
headerRowClassName: 'border-b border-b-gray-200',
|
||||
headerColumnClassName:
|
||||
'px-2 py-3 text-xs font-semibold text-gray-500 last:flex last:flex-row last:justify-end',
|
||||
bodyRowClassName: 'border-b border-b-gray-200',
|
||||
bodyColumnClassName:
|
||||
'px-2 py-2 last:flex last:flex-row last:justify-end',
|
||||
paginationClassName: 'hidden',
|
||||
}}
|
||||
emptyContent={
|
||||
<div className='w-full p-5 text-center'>
|
||||
<span className='text-lg opacity-50'>
|
||||
Isi persediaan DOC untuk kandang belum tersedia...
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
{JSON.stringify(formik.values)}
|
||||
<div className='flex flex-row justify-center gap-3'>
|
||||
<Button type='reset' color='warning' disabled={formik.isSubmitting}>
|
||||
Reset
|
||||
</Button>
|
||||
<Button
|
||||
type='submit'
|
||||
color='primary'
|
||||
disabled={!formik.isValid || formik.isSubmitting}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
{JSON.stringify(formik.errors)}
|
||||
</form>
|
||||
/>
|
||||
</Card>
|
||||
<Tabs
|
||||
className='bg-white p-2'
|
||||
onTabChange={setActiveTabId}
|
||||
activeTabId={activeTabId}
|
||||
tabs={[
|
||||
{
|
||||
id: 'formChickIn',
|
||||
label: 'Form Chick In',
|
||||
content: (
|
||||
<ChickinFormView
|
||||
initialValues={initialValues}
|
||||
formType={formType}
|
||||
afterSubmit={afterSubmitFormChickin}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
content: (
|
||||
<ChickinLogsView
|
||||
initialValues={initialValues}
|
||||
afterSubmit={afterSubmit}
|
||||
/>
|
||||
),
|
||||
id: 'logsChickIn',
|
||||
label: 'Riwayat Chick In',
|
||||
},
|
||||
]}
|
||||
variant='lifted'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -573,7 +573,7 @@ const ProjectFlockTable = () => {
|
||||
<ConfirmationModal
|
||||
ref={confirmModal.ref}
|
||||
type='success'
|
||||
text={`Apakah anda yakin ingin reject data transfer ke laying ini (${selectedRowIds.length} data)?`}
|
||||
text={`Apakah anda yakin ingin approve data Project Flock ini (${selectedRowIds.length} data)?`}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
|
||||
@@ -284,8 +284,8 @@ const ProjectFlockChickinDetail = ({
|
||||
) {
|
||||
case 'DISETUJUI':
|
||||
return 'green';
|
||||
case 'DITOLAK':
|
||||
return 'red';
|
||||
case 'PENGAJUAN':
|
||||
return 'yellow';
|
||||
default:
|
||||
return 'gray';
|
||||
}
|
||||
|
||||
@@ -688,7 +688,6 @@ const ProjectFlockForm = ({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{JSON.stringify(formik.errors)}
|
||||
</form>
|
||||
{formType != 'add' && (
|
||||
<div className='flex flex-row gap-2 mb-6'>
|
||||
|
||||
@@ -9,11 +9,6 @@ import {
|
||||
Recording,
|
||||
UpdateRecordingPayload,
|
||||
} from '@/types/api/production/recording';
|
||||
import {
|
||||
Chickin,
|
||||
CreateChickinPayload,
|
||||
UpdateChickinPayload,
|
||||
} from '@/types/api/production/chickin';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
|
||||
export const ProjectFlockApi = new BaseApiService<
|
||||
@@ -31,8 +26,3 @@ export const RecordingApi = new BaseApiService<
|
||||
CreateRecordingPayload,
|
||||
UpdateRecordingPayload
|
||||
>('/flock/recordings');
|
||||
export const ChickinApi = new BaseApiService<
|
||||
Chickin,
|
||||
CreateChickinPayload,
|
||||
UpdateChickinPayload
|
||||
>('/production/chickins');
|
||||
|
||||
@@ -11,6 +11,7 @@ export type BaseProjectFlockKandang = {
|
||||
kandang: Kandang;
|
||||
project_flock: ProjectFlock;
|
||||
available_qtys?: AvailableQty[];
|
||||
chickins?: Chickin[];
|
||||
approval: BaseApproval;
|
||||
};
|
||||
|
||||
@@ -21,6 +22,17 @@ export type AvailableQty = {
|
||||
note?: string;
|
||||
};
|
||||
|
||||
export type Chickin = {
|
||||
id: number;
|
||||
project_flock_kandang_id: number;
|
||||
chick_in_date: string;
|
||||
product_warehouse_id: number;
|
||||
product_warehouse: ProductWarehouse;
|
||||
usage_qty: number;
|
||||
pending_usage_qty: number;
|
||||
note: string;
|
||||
};
|
||||
|
||||
export type ProjectFlockKandang = BaseProjectFlockKandang;
|
||||
|
||||
export type LookupProjectFlockKandangPayload = {
|
||||
|
||||
Reference in New Issue
Block a user