mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
fix: adjust ProjectFlockForm styling and create ProjectFlockFormConfirmationTable component
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
|||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { FormikErrors, useFormik } from 'formik';
|
import { FormikErrors, useFormik } from 'formik';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { ReactNode, useEffect, useMemo, useState } from 'react';
|
||||||
import useSWR, { KeyedMutator } from 'swr';
|
import useSWR, { KeyedMutator } from 'swr';
|
||||||
import {
|
import {
|
||||||
ProjectFlockBudgetsSchemaType,
|
ProjectFlockBudgetsSchemaType,
|
||||||
@@ -47,6 +47,13 @@ import { useUiStore } from '@/stores/ui/ui.store';
|
|||||||
import RequirePermission from '@/components/helper/RequirePermission';
|
import RequirePermission from '@/components/helper/RequirePermission';
|
||||||
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
|
import DrawerHeader from '@/components/helper/drawer/DrawerHeader';
|
||||||
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
|
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
|
||||||
|
import { cn, formatCurrency, formatDate } from '@/lib/helper';
|
||||||
|
import Tooltip from '@/components/Tooltip';
|
||||||
|
import Table from '@/components/Table';
|
||||||
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
|
import StatusBadge from '@/components/helper/StatusBadge';
|
||||||
|
import { getUniqueFormikErrors } from '@/lib/formik-helper';
|
||||||
|
import ProjectFlockConfirmationModal from '../ProjectFlockConfirmationModal';
|
||||||
|
|
||||||
interface ProjectFlockFormProps {
|
interface ProjectFlockFormProps {
|
||||||
formType?: 'add' | 'edit' | 'detail';
|
formType?: 'add' | 'edit' | 'detail';
|
||||||
@@ -56,6 +63,150 @@ interface ProjectFlockFormProps {
|
|||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ProjectFlockFormConfirmationTableType {
|
||||||
|
label: string;
|
||||||
|
value: ReactNode;
|
||||||
|
subRows?: ProjectFlockFormConfirmationTableType[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ProjectFlockFormConfirmationTable = ({
|
||||||
|
projectFlockForm,
|
||||||
|
kandangs,
|
||||||
|
}: {
|
||||||
|
projectFlockForm?: ProjectFlockFormValues;
|
||||||
|
kandangs: Kandang[];
|
||||||
|
}) => {
|
||||||
|
const confirmationTableColumns: ColumnDef<ProjectFlockFormConfirmationTableType>[] =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
header: 'Label',
|
||||||
|
accessorKey: 'label',
|
||||||
|
enableSorting: false,
|
||||||
|
cell: ({ row }) => {
|
||||||
|
const isSubRow = row.depth > 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!isSubRow && row.original.label}
|
||||||
|
|
||||||
|
{isSubRow && (
|
||||||
|
<div
|
||||||
|
className={cn('w-full min-h-full flex items-stretch gap-0')}
|
||||||
|
>
|
||||||
|
<div className='w-px mx-4 bg-base-content/10' />
|
||||||
|
<span className='p-3'>{row.original.label}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Value',
|
||||||
|
accessorKey: 'value',
|
||||||
|
enableSorting: false,
|
||||||
|
cell: ({ row }) => row.original.value,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const productsData: ProjectFlockFormConfirmationTableType[] =
|
||||||
|
projectFlockForm?.project_budgets?.map((product) => ({
|
||||||
|
label: 'Jenis Produk',
|
||||||
|
value: product.nonstock?.label ?? '-',
|
||||||
|
subRows: [
|
||||||
|
{
|
||||||
|
label: 'Jumlah Pembelian',
|
||||||
|
value: String(product.qty),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Harga Satuan',
|
||||||
|
value: String(formatCurrency(Number(product.price))),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Total Harga',
|
||||||
|
value: String(formatCurrency(Number(product.total_price))),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})) ?? [];
|
||||||
|
|
||||||
|
const confirmationTableData: ProjectFlockFormConfirmationTableType[] = [
|
||||||
|
{
|
||||||
|
label: 'Tanggal',
|
||||||
|
value: formatDate(Date.now(), 'DD MMMM YYYY'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Area',
|
||||||
|
value: projectFlockForm?.area?.label ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Lokasi',
|
||||||
|
value: projectFlockForm?.location?.label ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Flock',
|
||||||
|
value: projectFlockForm?.flock?.label ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Kategori',
|
||||||
|
value: projectFlockForm?.category ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Standar Produksi',
|
||||||
|
value: projectFlockForm?.production_standard?.label ?? '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Informasi Kandang',
|
||||||
|
value: '',
|
||||||
|
subRows:
|
||||||
|
projectFlockForm?.kandang_ids?.map((kandang_id) => {
|
||||||
|
const kandang = kandangs.find((kandang) => kandang.id === kandang_id);
|
||||||
|
|
||||||
|
const kandangName = kandang?.name ?? '-';
|
||||||
|
const kandangAvailability = kandang?.status;
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: kandangName,
|
||||||
|
value: (
|
||||||
|
<StatusBadge
|
||||||
|
color={
|
||||||
|
kandangAvailability === 'NON_ACTIVE' ? 'info' : 'neutral'
|
||||||
|
}
|
||||||
|
text={
|
||||||
|
kandangAvailability === 'NON_ACTIVE'
|
||||||
|
? 'Tersedia'
|
||||||
|
: 'Tidak Tersedia'
|
||||||
|
}
|
||||||
|
className={{ badge: 'text-nowrap' }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}) ?? [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Estimasi Anggaran per Kandang',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
...productsData,
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table<ProjectFlockFormConfirmationTableType>
|
||||||
|
columns={confirmationTableColumns}
|
||||||
|
data={confirmationTableData}
|
||||||
|
withPagination={false}
|
||||||
|
pageSize={10000}
|
||||||
|
expanded={true}
|
||||||
|
getSubRows={(row) => row.subRows}
|
||||||
|
className={{
|
||||||
|
headerRowClassName: 'border-b border-base-content/10',
|
||||||
|
bodyRowClassName: 'border-none',
|
||||||
|
bodySubRowClassName: () => 'border-none',
|
||||||
|
bodySubRowColumnClassName: () => 'first:p-0',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const ProjectFlockForm = ({
|
const ProjectFlockForm = ({
|
||||||
formType = 'add',
|
formType = 'add',
|
||||||
initialValues,
|
initialValues,
|
||||||
@@ -64,6 +215,8 @@ const ProjectFlockForm = ({
|
|||||||
// State
|
// State
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [formStep, setFormStep] = useState<'form' | 'confirmation'>('form');
|
||||||
|
|
||||||
const [projectFlockFormErrorMessage, setProjectFlockFormErrorMessage] =
|
const [projectFlockFormErrorMessage, setProjectFlockFormErrorMessage] =
|
||||||
useState('');
|
useState('');
|
||||||
const [selectedArea, setSelectedArea] = useState('');
|
const [selectedArea, setSelectedArea] = useState('');
|
||||||
@@ -87,6 +240,7 @@ const ProjectFlockForm = ({
|
|||||||
const subscribeValidate = useUiStore((s) => s.subscribeValidate);
|
const subscribeValidate = useUiStore((s) => s.subscribeValidate);
|
||||||
const setIsValid = useUiStore((s) => s.setIsValid);
|
const setIsValid = useUiStore((s) => s.setIsValid);
|
||||||
|
|
||||||
|
const successModal = useModal();
|
||||||
const deleteModal = useModal();
|
const deleteModal = useModal();
|
||||||
|
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
@@ -285,7 +439,7 @@ const ProjectFlockForm = ({
|
|||||||
if (isResponseSuccess(createProjectFlockRes)) {
|
if (isResponseSuccess(createProjectFlockRes)) {
|
||||||
toast.success(createProjectFlockRes?.message as string);
|
toast.success(createProjectFlockRes?.message as string);
|
||||||
handleReset();
|
handleReset();
|
||||||
router.push('/production/project-flock');
|
successModal.openModal();
|
||||||
}
|
}
|
||||||
if (isResponseError(createProjectFlockRes)) {
|
if (isResponseError(createProjectFlockRes)) {
|
||||||
setProjectFlockFormErrorMessage(createProjectFlockRes?.message as string);
|
setProjectFlockFormErrorMessage(createProjectFlockRes?.message as string);
|
||||||
@@ -303,7 +457,7 @@ const ProjectFlockForm = ({
|
|||||||
if (isResponseSuccess(updateProjectFlockRes)) {
|
if (isResponseSuccess(updateProjectFlockRes)) {
|
||||||
toast.success(updateProjectFlockRes?.message as string);
|
toast.success(updateProjectFlockRes?.message as string);
|
||||||
handleReset();
|
handleReset();
|
||||||
router.push('/production/project-flock');
|
successModal.openModal();
|
||||||
}
|
}
|
||||||
if (isResponseError(updateProjectFlockRes)) {
|
if (isResponseError(updateProjectFlockRes)) {
|
||||||
setProjectFlockFormErrorMessage(updateProjectFlockRes?.message as string);
|
setProjectFlockFormErrorMessage(updateProjectFlockRes?.message as string);
|
||||||
@@ -320,6 +474,10 @@ const ProjectFlockForm = ({
|
|||||||
formikSetValues(formikInitialValues);
|
formikSetValues(formikInitialValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [formikLastValues, setFormikLastValues] = useState<
|
||||||
|
ProjectFlockFormValues | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
// Formik InitialValue
|
// Formik InitialValue
|
||||||
const formikInitialValues = useMemo<ProjectFlockFormValues>(() => {
|
const formikInitialValues = useMemo<ProjectFlockFormValues>(() => {
|
||||||
const trimFlock =
|
const trimFlock =
|
||||||
@@ -429,6 +587,8 @@ const ProjectFlockForm = ({
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setFormikLastValues(values);
|
||||||
|
|
||||||
switch (formType) {
|
switch (formType) {
|
||||||
case 'add':
|
case 'add':
|
||||||
await createProjectFlockHandler(payload);
|
await createProjectFlockHandler(payload);
|
||||||
@@ -654,21 +814,67 @@ const ProjectFlockForm = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ===== Formik Error List =====
|
// ===== Formik Error List =====
|
||||||
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
const { formErrorList, close, setFormErrorList, handleFormSubmit } =
|
||||||
|
useFormikErrorList(formik);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section className='w-full h-full sm:w-[446px] overflow-y-auto'>
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const submitHandler = async () => {
|
||||||
|
const validateFormErrorResult = await formik.validateForm();
|
||||||
|
const isFormError = Object.keys(validateFormErrorResult).length > 0;
|
||||||
|
|
||||||
|
if (isFormError) {
|
||||||
|
const errorMessages = getUniqueFormikErrors(
|
||||||
|
validateFormErrorResult
|
||||||
|
);
|
||||||
|
setFormErrorList(errorMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFormError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formStep === 'form') {
|
||||||
|
setFormStep('confirmation');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFormSubmit(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
submitHandler();
|
||||||
|
}}
|
||||||
|
onReset={formik.handleReset}
|
||||||
|
className='w-full h-full sm:w-[446px] flex flex-col'
|
||||||
|
>
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<DrawerHeader
|
<DrawerHeader
|
||||||
leftIcon={
|
leftIcon={
|
||||||
formType == 'add' ? 'heroicons:chevron-left' : 'mdi:arrow-left'
|
formType == 'add' ? 'heroicons:chevron-left' : 'mdi:arrow-left'
|
||||||
}
|
}
|
||||||
leftIconHref={
|
// leftIconHref={
|
||||||
formType == 'add'
|
// formType == 'add'
|
||||||
? '/production/project-flock'
|
// ? '/production/project-flock'
|
||||||
: `/production/project-flock/detail?projectFlockId=${initialValues?.id}`
|
// : `/production/project-flock/detail?projectFlockId=${initialValues?.id}`
|
||||||
|
// }
|
||||||
|
leftIconOnClick={() => {
|
||||||
|
if (formStep === 'confirmation') {
|
||||||
|
setFormStep('form');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (formType == 'add') {
|
||||||
|
router.push('/production/project-flock');
|
||||||
|
} else {
|
||||||
|
router.push(
|
||||||
|
`/production/project-flock/detail?projectFlockId=${initialValues?.id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
leftIconClassName='hover:text-gray-400'
|
leftIconClassName='hover:text-gray-400'
|
||||||
subtitle={formType == 'add' ? 'Add List Flock' : 'Update Flock'}
|
subtitle={formType == 'add' ? 'Add List Flock' : 'Update Flock'}
|
||||||
className='sticky top-0 z-10 bg-base-100'
|
className='sticky top-0 z-10 bg-base-100'
|
||||||
@@ -685,7 +891,9 @@ const ProjectFlockForm = ({
|
|||||||
}}
|
}}
|
||||||
className='p-0 text-error'
|
className='p-0 text-error'
|
||||||
>
|
>
|
||||||
|
<Tooltip content='Hapus' position='bottom'>
|
||||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||||
|
</Tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -699,36 +907,16 @@ const ProjectFlockForm = ({
|
|||||||
}}
|
}}
|
||||||
className='p-0 text-error'
|
className='p-0 text-error'
|
||||||
>
|
>
|
||||||
|
<Tooltip content='Hapus' position='bottom'>
|
||||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||||
|
</Tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
{projectFlockFormErrorMessage && (
|
|
||||||
<div className='my-4'>
|
|
||||||
<div role='alert' className='alert alert-error'>
|
|
||||||
<Icon
|
|
||||||
icon='material-symbols:error-outline'
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
<span>{projectFlockFormErrorMessage}</span>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setProjectFlockFormErrorMessage('');
|
|
||||||
}}
|
|
||||||
variant='link'
|
|
||||||
>
|
|
||||||
<Icon icon='material-symbols:close' width={24} height={24} />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<form
|
<div className='w-auto h-full overflow-y-auto'>
|
||||||
className='w-auto h-auto'
|
{formStep === 'form' && (
|
||||||
onSubmit={handleFormSubmit}
|
<div className='h-full'>
|
||||||
onReset={formik.handleReset}
|
|
||||||
>
|
|
||||||
{/* Form Informasi Umum */}
|
{/* Form Informasi Umum */}
|
||||||
<div className='flex flex-col p-4'>
|
<div className='flex flex-col p-4'>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto'>
|
||||||
@@ -743,7 +931,9 @@ const ProjectFlockForm = ({
|
|||||||
onChange={areaChangeHandler}
|
onChange={areaChangeHandler}
|
||||||
options={optionsArea}
|
options={optionsArea}
|
||||||
isLoading={isLoadingAreas}
|
isLoading={isLoadingAreas}
|
||||||
isError={formik.touched.area_id && Boolean(formik.errors.area_id)}
|
isError={
|
||||||
|
formik.touched.area_id && Boolean(formik.errors.area_id)
|
||||||
|
}
|
||||||
errorMessage={formik.errors.area_id as string}
|
errorMessage={formik.errors.area_id as string}
|
||||||
onInputChange={setInputValueArea}
|
onInputChange={setInputValueArea}
|
||||||
onMenuScrollToBottom={loadMoreArea}
|
onMenuScrollToBottom={loadMoreArea}
|
||||||
@@ -763,7 +953,8 @@ const ProjectFlockForm = ({
|
|||||||
}
|
}
|
||||||
isLoading={isLoadingLocations}
|
isLoading={isLoadingLocations}
|
||||||
isError={
|
isError={
|
||||||
formik.touched.location_id && Boolean(formik.errors.location_id)
|
formik.touched.location_id &&
|
||||||
|
Boolean(formik.errors.location_id)
|
||||||
}
|
}
|
||||||
onInputChange={setInputValueLocation}
|
onInputChange={setInputValueLocation}
|
||||||
onMenuScrollToBottom={loadMoreLocation}
|
onMenuScrollToBottom={loadMoreLocation}
|
||||||
@@ -788,14 +979,18 @@ const ProjectFlockForm = ({
|
|||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
optionChangeHandler(val, 'flock');
|
optionChangeHandler(val, 'flock');
|
||||||
setSelectedFlock((val as OptionType)?.label);
|
setSelectedFlock((val as OptionType)?.label);
|
||||||
formik.setFieldValue('flock_name', (val as OptionType)?.label);
|
formik.setFieldValue(
|
||||||
|
'flock_name',
|
||||||
|
(val as OptionType)?.label
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
options={optionsFlock}
|
options={optionsFlock}
|
||||||
onInputChange={setInputValueFlock}
|
onInputChange={setInputValueFlock}
|
||||||
onMenuScrollToBottom={loadMoreFlock}
|
onMenuScrollToBottom={loadMoreFlock}
|
||||||
isLoading={isLoadingFlocks}
|
isLoading={isLoadingFlocks}
|
||||||
isError={
|
isError={
|
||||||
formik.touched.flock_name && Boolean(formik.errors.flock_name)
|
formik.touched.flock_name &&
|
||||||
|
Boolean(formik.errors.flock_name)
|
||||||
}
|
}
|
||||||
errorMessage={formik.errors.flock_name as string}
|
errorMessage={formik.errors.flock_name as string}
|
||||||
isClearable
|
isClearable
|
||||||
@@ -813,7 +1008,9 @@ const ProjectFlockForm = ({
|
|||||||
onMenuScrollToBottom={loadMoreFcr}
|
onMenuScrollToBottom={loadMoreFcr}
|
||||||
options={optionsFcr}
|
options={optionsFcr}
|
||||||
isLoading={isLoadingFcrs}
|
isLoading={isLoadingFcrs}
|
||||||
isError={formik.touched.fcr_id && Boolean(formik.errors.fcr_id)}
|
isError={
|
||||||
|
formik.touched.fcr_id && Boolean(formik.errors.fcr_id)
|
||||||
|
}
|
||||||
errorMessage={formik.errors.fcr_id as string}
|
errorMessage={formik.errors.fcr_id as string}
|
||||||
isClearable
|
isClearable
|
||||||
isDisabled={formType != 'add'}
|
isDisabled={formType != 'add'}
|
||||||
@@ -887,32 +1084,28 @@ const ProjectFlockForm = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Card Estimasi Budget */}
|
{/* Card Estimasi Budget */}
|
||||||
<div className='flex flex-col p-4'>
|
<div className='flex flex-col'>
|
||||||
<div className='flex flex-col gap-4'>
|
<div className='flex flex-col'>
|
||||||
{formik.values.project_budgets &&
|
{formik.values.project_budgets &&
|
||||||
formik.values.project_budgets.length > 0 ? (
|
formik.values.project_budgets.length > 0 ? (
|
||||||
formik.values.project_budgets.map((budget, index) => (
|
formik.values.project_budgets.map((budget, index) => {
|
||||||
<div key={index} className='flex flex-col'>
|
const nonstockUomName = isResponseSuccess(nonstocks)
|
||||||
{/* <div className='flex flex-row justify-between items-center mb-2'>
|
? (nonstocks.data.find(
|
||||||
<Button
|
(ns) => ns.id === budget.nonstock_id
|
||||||
type='button'
|
)?.uom?.name ?? '')
|
||||||
color='error'
|
: '';
|
||||||
onClick={() =>
|
|
||||||
onDeleteBudgetRowHandler(
|
|
||||||
budget.nonstock_id as number,
|
|
||||||
index
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Icon icon='mdi:trash' width={16} height={16} />
|
|
||||||
</Button>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className='flex flex-col p-4 border-b border-base-content/10'
|
||||||
|
>
|
||||||
<div className='flex flex-row justify-between items-center'>
|
<div className='flex flex-row justify-between items-center'>
|
||||||
<h2 className='text-base font-medium text-base-content/50 font-roboto'>
|
<h2 className='text-base font-medium text-base-content/50 font-roboto'>
|
||||||
Estimasi Anggaran Per Flock
|
Estimasi Anggaran Per Flock
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
{formik.values.project_budgets.length > 1 && (
|
||||||
<Button
|
<Button
|
||||||
type='button'
|
type='button'
|
||||||
variant='ghost'
|
variant='ghost'
|
||||||
@@ -925,8 +1118,13 @@ const ProjectFlockForm = ({
|
|||||||
}
|
}
|
||||||
className='p-0 text-error'
|
className='p-0 text-error'
|
||||||
>
|
>
|
||||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
<Icon
|
||||||
|
icon='heroicons:trash'
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-row justify-between items-center'>
|
<div className='flex flex-row justify-between items-center'>
|
||||||
@@ -936,16 +1134,21 @@ const ProjectFlockForm = ({
|
|||||||
options={filteredNonStockOptions ?? []}
|
options={filteredNonStockOptions ?? []}
|
||||||
isLoading={isLoadingNonstocks}
|
isLoading={isLoadingNonstocks}
|
||||||
placeholder='Pilih Jenis Produk'
|
placeholder='Pilih Jenis Produk'
|
||||||
value={formik.values.project_budgets[index].nonstock}
|
value={
|
||||||
|
formik.values.project_budgets[index].nonstock
|
||||||
|
}
|
||||||
onInputChange={setInputValueNonstock}
|
onInputChange={setInputValueNonstock}
|
||||||
onMenuScrollToBottom={loadMoreNonstock}
|
onMenuScrollToBottom={loadMoreNonstock}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
const updatedBudgets = [
|
const updatedBudgets = [
|
||||||
...formik.values.project_budgets,
|
...formik.values.project_budgets,
|
||||||
];
|
];
|
||||||
updatedBudgets[index].nonstock = val as OptionType;
|
updatedBudgets[index].nonstock =
|
||||||
|
val as OptionType;
|
||||||
updatedBudgets[index].nonstock_id =
|
updatedBudgets[index].nonstock_id =
|
||||||
(val as OptionType) ? (val as OptionType).value : 0;
|
(val as OptionType)
|
||||||
|
? (val as OptionType).value
|
||||||
|
: 0;
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
'project_budgets',
|
'project_budgets',
|
||||||
updatedBudgets
|
updatedBudgets
|
||||||
@@ -987,17 +1190,17 @@ const ProjectFlockForm = ({
|
|||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
allowNegative={false}
|
allowNegative={false}
|
||||||
inputPrefix={
|
inputPrefix={
|
||||||
|
<>
|
||||||
|
{nonstockUomName && (
|
||||||
<div className='w-full h-full py-1 flex flex-row items-stretch justify-between gap-3'>
|
<div className='w-full h-full py-1 flex flex-row items-stretch justify-between gap-3'>
|
||||||
<span className='text-sm text-base-content/60 self-center text-nowrap truncate'>
|
<span className='text-sm text-base-content/60 self-center text-nowrap truncate'>
|
||||||
{isResponseSuccess(nonstocks)
|
{nonstockUomName}
|
||||||
? (nonstocks.data.find(
|
|
||||||
(ns) => ns.id === budget.nonstock_id
|
|
||||||
)?.uom?.name ?? '')
|
|
||||||
: ''}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div className='w-px bg-base-content/10' />
|
<div className='w-px bg-base-content/10' />
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
errorMessage={
|
errorMessage={
|
||||||
(
|
(
|
||||||
@@ -1019,7 +1222,11 @@ const ProjectFlockForm = ({
|
|||||||
className={{
|
className={{
|
||||||
inputPrefix:
|
inputPrefix:
|
||||||
'py-0 px-0 pl-3 text-base-content/50 bg-transparent border-r-0',
|
'py-0 px-0 pl-3 text-base-content/50 bg-transparent border-r-0',
|
||||||
inputWrapper: 'border-l-0 pl-5',
|
inputWrapper: cn('border-l-0 pl-0', {
|
||||||
|
'pl-5':
|
||||||
|
isResponseSuccess(nonstocks) &&
|
||||||
|
budget.nonstock_id,
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1029,7 +1236,11 @@ const ProjectFlockForm = ({
|
|||||||
label='Harga Satuan (Rp)'
|
label='Harga Satuan (Rp)'
|
||||||
value={formik.values.project_budgets[index].price}
|
value={formik.values.project_budgets[index].price}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleBudgetChange(index, 'price', e.target.value)
|
handleBudgetChange(
|
||||||
|
index,
|
||||||
|
'price',
|
||||||
|
e.target.value
|
||||||
|
)
|
||||||
}
|
}
|
||||||
onBlur={formik.handleBlur}
|
onBlur={formik.handleBlur}
|
||||||
placeholder='Masukkan Harga Satuan (Rp)'
|
placeholder='Masukkan Harga Satuan (Rp)'
|
||||||
@@ -1051,7 +1262,8 @@ const ProjectFlockForm = ({
|
|||||||
)?.price as string
|
)?.price as string
|
||||||
}
|
}
|
||||||
isError={
|
isError={
|
||||||
formik.touched.project_budgets?.[index]?.price &&
|
formik.touched.project_budgets?.[index]
|
||||||
|
?.price &&
|
||||||
Boolean(
|
Boolean(
|
||||||
(
|
(
|
||||||
formik.errors.project_budgets?.[
|
formik.errors.project_budgets?.[
|
||||||
@@ -1071,7 +1283,9 @@ const ProjectFlockForm = ({
|
|||||||
<NumberInput
|
<NumberInput
|
||||||
name={`project_budgets[${index}].total_price`}
|
name={`project_budgets[${index}].total_price`}
|
||||||
label='Total Harga'
|
label='Total Harga'
|
||||||
value={formik.values.project_budgets[index].total_price}
|
value={
|
||||||
|
formik.values.project_budgets[index].total_price
|
||||||
|
}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleBudgetChange(
|
handleBudgetChange(
|
||||||
index,
|
index,
|
||||||
@@ -1117,29 +1331,77 @@ const ProjectFlockForm = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
);
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className='text-center py-4 text-gray-400'>
|
<div className='text-center py-4 text-gray-400'>
|
||||||
Tidak ada data estimasi anggaran.
|
Tidak ada data estimasi anggaran.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<div className='w-full p-4'>
|
||||||
<Button
|
<Button
|
||||||
type='button'
|
type='button'
|
||||||
|
color='primary'
|
||||||
|
variant='outline'
|
||||||
onClick={onAddBudgetRowHandler}
|
onClick={onAddBudgetRowHandler}
|
||||||
disabled={filteredNonStockOptions.length == 0}
|
disabled={filteredNonStockOptions.length == 0}
|
||||||
color='success'
|
className='w-full p-3 rounded-lg text-sm font-semibold hover:text-base-100 focus-visible:text-base-100'
|
||||||
className='w-fit self-center'
|
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:plus' width={16} height={16} /> Add Budget
|
Tambah Produk
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='p-4'>
|
|
||||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-row justify-center gap-2 flex-wrap my-6 px-4'>
|
{(formErrorList.length > 0 || projectFlockFormErrorMessage) && (
|
||||||
|
<div className='p-4'>
|
||||||
|
<AlertErrorList
|
||||||
|
formErrorList={formErrorList}
|
||||||
|
onClose={close}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{projectFlockFormErrorMessage && (
|
||||||
|
<div className='my-4'>
|
||||||
|
<div role='alert' className='alert alert-error'>
|
||||||
|
<Icon
|
||||||
|
icon='material-symbols:error-outline'
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<span>{projectFlockFormErrorMessage}</span>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
onClick={() => {
|
||||||
|
setProjectFlockFormErrorMessage('');
|
||||||
|
}}
|
||||||
|
variant='link'
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon='material-symbols:close'
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{formStep === 'confirmation' && (
|
||||||
|
<div className='p-4'>
|
||||||
|
<ProjectFlockFormConfirmationTable
|
||||||
|
projectFlockForm={formik.values}
|
||||||
|
kandangs={optionsKandang}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='p-4 flex-1 flex flex-row justify-center gap-2 flex-wrap shadow-bg'>
|
||||||
{formType !== 'detail' && (
|
{formType !== 'detail' && (
|
||||||
<RequirePermission
|
<RequirePermission
|
||||||
permissions={
|
permissions={
|
||||||
@@ -1150,19 +1412,29 @@ const ProjectFlockForm = ({
|
|||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
type='submit'
|
type='submit'
|
||||||
color='primary'
|
|
||||||
isLoading={formik.isSubmitting}
|
isLoading={formik.isSubmitting}
|
||||||
disabled={formik.isSubmitting}
|
disabled={formik.isSubmitting}
|
||||||
className='px-4 w-full'
|
className='w-full p-3 rounded-lg text-sm font-semibold text-base-100'
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:plus' width={24} height={24} />
|
Submit
|
||||||
{formType == 'add' ? 'Add Flock' : 'Update Flock'}
|
|
||||||
</Button>
|
</Button>
|
||||||
</RequirePermission>
|
</RequirePermission>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
|
||||||
|
<ProjectFlockConfirmationModal
|
||||||
|
ref={successModal.ref}
|
||||||
|
type='success'
|
||||||
|
text='Data Berhasil Ditambahkan'
|
||||||
|
subtitleText='Data project flock telah berhasil disimpan.'
|
||||||
|
projectFlockForm={formikLastValues}
|
||||||
|
onClose={() => {
|
||||||
|
router.push('/production/project-flock');
|
||||||
|
setFormikLastValues(undefined);
|
||||||
|
}}
|
||||||
|
secondaryButton={undefined}
|
||||||
|
/>
|
||||||
|
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
ref={deleteModal.ref}
|
ref={deleteModal.ref}
|
||||||
|
|||||||
Reference in New Issue
Block a user