mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
refactor(FE): refactor UI Sales Order and Delivery Order
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||
import RequirePermission from '@/components/helper/RequirePermission';
|
||||
import DateInput from '@/components/input/DateInput';
|
||||
import DebouncedTextArea from '@/components/input/DebouncedTextArea';
|
||||
import NumberInput from '@/components/input/NumberInput';
|
||||
@@ -9,9 +10,15 @@ import { OptionType, useSelect } from '@/components/input/SelectInput';
|
||||
import SelectInputRadio from '@/components/input/SelectInputRadio';
|
||||
import Modal, { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import {
|
||||
DeliveryProductToFieldValues,
|
||||
mergeSOwithDO,
|
||||
SalesProductToFieldValues,
|
||||
} from '@/components/pages/marketing/form/MarketingForm';
|
||||
import {
|
||||
DeliveryOrderFormValues,
|
||||
DeliveryOrderSchema,
|
||||
getFilledMarketingFormInitialValues,
|
||||
SalesOrderFormValues,
|
||||
SalesOrderSchema,
|
||||
} from '@/components/pages/marketing/form/MarketingForm.schema';
|
||||
@@ -20,7 +27,7 @@ import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/r
|
||||
import SalesOrderProductForm from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProductForm';
|
||||
import SalesOrderProductTable from '@/components/pages/marketing/form/table-view/SalesOrderProductTable';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { formatCurrency, formatDate } from '@/lib/helper';
|
||||
import { formatDate } from '@/lib/helper';
|
||||
import {
|
||||
MarketingApi,
|
||||
SalesOrderApi,
|
||||
@@ -30,8 +37,6 @@ import { UserApi } from '@/services/api/user';
|
||||
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
|
||||
import { CreatedUser } from '@/types/api/api-general';
|
||||
import {
|
||||
BaseDeliveryOrder,
|
||||
BaseSalesOrder,
|
||||
CreateSalesOrderPayload,
|
||||
CreateSalesOrderProductPayload,
|
||||
Marketing,
|
||||
@@ -49,112 +54,22 @@ import useSWR, { useSWRConfig } from 'swr';
|
||||
const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable);
|
||||
const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm);
|
||||
|
||||
const SalesProductToFieldValues = (
|
||||
product: BaseSalesOrder
|
||||
): SalesOrderProductFormValues => {
|
||||
return {
|
||||
id: product.id,
|
||||
vehicle_number: product.vehicle_number,
|
||||
kandang_id: product.product_warehouse.warehouse.id,
|
||||
kandang: {
|
||||
value: product.product_warehouse.warehouse.id,
|
||||
label: product.product_warehouse.warehouse.name,
|
||||
},
|
||||
product_warehouse: {
|
||||
value: product.product_warehouse.id,
|
||||
label: product.product_warehouse.product.name,
|
||||
},
|
||||
product_warehouse_id: product.product_warehouse.id,
|
||||
unit_price: product.unit_price,
|
||||
total_weight: product.total_weight,
|
||||
qty: product.qty,
|
||||
avg_weight: product.avg_weight,
|
||||
total_price: product.total_price,
|
||||
};
|
||||
};
|
||||
const DeliveryProductToFieldValues = (
|
||||
salesOrders: BaseSalesOrder[],
|
||||
delivery: BaseDeliveryOrder
|
||||
): DeliveryOrderProductFormValues[] => {
|
||||
const data = delivery.deliveries.map((item) => {
|
||||
const soId = salesOrders.find(
|
||||
(so) => so.product_warehouse.id === item.product_warehouse.id
|
||||
)?.id;
|
||||
return {
|
||||
id: soId,
|
||||
unit_price: item.unit_price,
|
||||
total_weight: item.total_weight,
|
||||
qty: item.qty,
|
||||
avg_weight: item.avg_weight,
|
||||
total_price: item.total_price,
|
||||
vehicle_number: item.vehicle_number,
|
||||
delivery_date: formatDate(delivery.delivery_date, 'yyyy-MM-DD'),
|
||||
do_number: delivery.do_number,
|
||||
marketing_product_id: soId,
|
||||
marketing_product: {
|
||||
id: soId,
|
||||
vehicle_number: item.vehicle_number,
|
||||
kandang_id: item.product_warehouse.warehouse.id,
|
||||
kandang: {
|
||||
value: item.product_warehouse.warehouse.id,
|
||||
label: item.product_warehouse.warehouse.name,
|
||||
},
|
||||
product_warehouse: {
|
||||
value: item.product_warehouse.id,
|
||||
label: item.product_warehouse.product.name,
|
||||
},
|
||||
product_warehouse_id: item.product_warehouse.id,
|
||||
unit_price: item.unit_price,
|
||||
total_weight: item.total_weight,
|
||||
qty: item.qty,
|
||||
avg_weight: item.avg_weight,
|
||||
total_price: item.total_price,
|
||||
},
|
||||
} as DeliveryOrderProductFormValues;
|
||||
});
|
||||
return data;
|
||||
};
|
||||
const mergeSOwithDO = (
|
||||
salesOrders: SalesOrderProductFormValues[],
|
||||
deliveryOrders: DeliveryOrderProductFormValues[]
|
||||
): DeliveryOrderProductFormValues[] => {
|
||||
return salesOrders.map((so) => {
|
||||
const delivery = deliveryOrders.find(
|
||||
(d) => d?.marketing_product_id === so.id
|
||||
);
|
||||
|
||||
return {
|
||||
...so, // nilai dasar dari sales order
|
||||
marketing_product_id: so.id,
|
||||
delivery_date: delivery?.delivery_date || undefined,
|
||||
do_number: delivery?.do_number || undefined,
|
||||
vehicle_number: delivery?.vehicle_number || so.vehicle_number,
|
||||
unit_price: delivery?.unit_price,
|
||||
total_weight: delivery?.total_weight,
|
||||
qty: delivery?.qty,
|
||||
avg_weight: delivery?.avg_weight,
|
||||
total_price: delivery?.total_price,
|
||||
marketing_product: so, // jika ada, override
|
||||
} as DeliveryOrderProductFormValues;
|
||||
});
|
||||
};
|
||||
|
||||
const SalesOrderFormModal = ({
|
||||
initialValues,
|
||||
afterSubmit,
|
||||
formType,
|
||||
}: {
|
||||
initialValues?: Marketing;
|
||||
afterSubmit?: () => void;
|
||||
formType: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const modalAction = searchParams.get('action');
|
||||
const MarketingId = searchParams.get('id');
|
||||
const marketingId = searchParams.get('id');
|
||||
|
||||
const isModalActionForForm = modalAction === 'add' || modalAction === 'edit';
|
||||
const isModalActionForForm =
|
||||
modalAction === 'add' ||
|
||||
modalAction === 'edit' ||
|
||||
modalAction === 'add_delivery' ||
|
||||
modalAction === 'edit_delivery';
|
||||
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
@@ -164,11 +79,11 @@ const SalesOrderFormModal = ({
|
||||
);
|
||||
};
|
||||
|
||||
const { data: Marketing, isLoading: isLoadingMarketing } = useSWR(
|
||||
isModalActionForForm && MarketingId
|
||||
? ['detail-marketing', MarketingId]
|
||||
const { data: marketing, isLoading: isLoadingMarketing } = useSWR(
|
||||
isModalActionForForm && marketingId
|
||||
? `detail-marketing-${marketingId}`
|
||||
: undefined,
|
||||
([, id]) => MarketingApi.getSingle(Number(id))
|
||||
() => MarketingApi.getSingle(Number(marketingId))
|
||||
);
|
||||
|
||||
// ================== FETCH OPTIONS ==================
|
||||
@@ -194,6 +109,7 @@ const SalesOrderFormModal = ({
|
||||
|
||||
const formModal = useModal();
|
||||
const successModal = useModal();
|
||||
const deleteModal = useModal();
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
@@ -257,13 +173,13 @@ const SalesOrderFormModal = ({
|
||||
enableReinitialize: true,
|
||||
initialValues: formikInitialValues,
|
||||
validationSchema:
|
||||
formType == 'add_deliver' || formType == 'edit_deliver'
|
||||
modalAction == 'add_deliver' || modalAction == 'edit_deliver'
|
||||
? DeliveryOrderSchema
|
||||
: SalesOrderSchema,
|
||||
validateOnMount: true,
|
||||
onSubmit: async (values) => {
|
||||
const payload =
|
||||
formType != 'add_deliver' && formType != 'edit_deliver'
|
||||
modalAction != 'add_deliver' && modalAction != 'edit_deliver'
|
||||
? ({
|
||||
customer_id: values.customer_id as number,
|
||||
sales_person_id: values.sales_person_id as number,
|
||||
@@ -305,7 +221,7 @@ const SalesOrderFormModal = ({
|
||||
})
|
||||
.filter((item) => Boolean(item)),
|
||||
} as UpdateDeliveryOrderPayload);
|
||||
switch (formType) {
|
||||
switch (modalAction) {
|
||||
case 'add':
|
||||
await createMarketingHandler(payload as CreateSalesOrderPayload);
|
||||
break;
|
||||
@@ -315,19 +231,16 @@ const SalesOrderFormModal = ({
|
||||
default:
|
||||
break;
|
||||
}
|
||||
afterSubmit?.();
|
||||
},
|
||||
});
|
||||
|
||||
// ===== Formik Error List =====
|
||||
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(
|
||||
formik,
|
||||
{
|
||||
const { formErrorList, setFormErrorList, close, handleFormSubmit } =
|
||||
useFormikErrorList(formik, {
|
||||
onAfterSubmit: () => {
|
||||
router.push('/marketing');
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// ================== FORM REPEATER HANDLER ==================
|
||||
const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
||||
@@ -336,6 +249,7 @@ const SalesOrderFormModal = ({
|
||||
if (isResponseSuccess(createMarketingRes)) {
|
||||
closeModalHandler(false);
|
||||
successModal.openModal();
|
||||
refreshMarketing();
|
||||
}
|
||||
if (isResponseError(createMarketingRes)) {
|
||||
toast.error(createMarketingRes?.message as string);
|
||||
@@ -344,13 +258,19 @@ const SalesOrderFormModal = ({
|
||||
};
|
||||
const updateMarketingHandler = async (values: UpdateSalesOrderPayload) => {
|
||||
setIsLoading(true);
|
||||
if (!marketingId) {
|
||||
toast.error('Marketing ID is required');
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
const updateMarketingRes = await SalesOrderApi.update(
|
||||
initialValues?.id as number,
|
||||
Number(marketingId),
|
||||
values
|
||||
);
|
||||
if (isResponseSuccess(updateMarketingRes)) {
|
||||
closeModalHandler(false);
|
||||
successModal.openModal();
|
||||
refreshMarketing();
|
||||
}
|
||||
if (isResponseError(updateMarketingRes)) {
|
||||
toast.error(updateMarketingRes?.message as string);
|
||||
@@ -382,6 +302,26 @@ const SalesOrderFormModal = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const deleteClickHandler = () => {
|
||||
deleteModal.openModal();
|
||||
};
|
||||
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
if (!marketingId) {
|
||||
toast.error(`Tidak ada data yang valid untuk di hapus.`);
|
||||
deleteModal.closeModal();
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
const res = await MarketingApi.delete(Number(marketingId));
|
||||
deleteModal.closeModal();
|
||||
toast.success(res?.message as string);
|
||||
setIsLoading(false);
|
||||
refreshMarketing();
|
||||
closeModalHandler();
|
||||
router.replace('/marketing');
|
||||
};
|
||||
|
||||
// ================== SALES ORDER HANDLER ==================
|
||||
const handleDeleteSO = useCallback(
|
||||
(id: number) => {
|
||||
@@ -393,11 +333,15 @@ const SalesOrderFormModal = ({
|
||||
},
|
||||
[memoSalesOrder]
|
||||
);
|
||||
const handleDeleteAllSO = useCallback(() => {
|
||||
formik.setFieldValue('sales_order', []);
|
||||
}, [memoSalesOrder]);
|
||||
const handleEditSO = useCallback(
|
||||
(id: number) => {
|
||||
const currentProducts = formik.values.sales_order;
|
||||
const selectedProduct = currentProducts.find((p) => p.id == id);
|
||||
setSelectedMarketingProduct(selectedProduct ?? null);
|
||||
setStep(2);
|
||||
},
|
||||
[memoSalesOrder]
|
||||
);
|
||||
@@ -457,6 +401,7 @@ const SalesOrderFormModal = ({
|
||||
}, [modalAction]);
|
||||
|
||||
const closeModalHandler = (shouldPushToRoute: boolean = true) => {
|
||||
refreshMarketing();
|
||||
if (shouldPushToRoute) {
|
||||
formik.resetForm();
|
||||
textareaRef.current?.setAttribute('value', '');
|
||||
@@ -477,6 +422,39 @@ const SalesOrderFormModal = ({
|
||||
);
|
||||
}, [memoSalesOrder]);
|
||||
|
||||
useEffect(() => {
|
||||
const getFilledInitialValues = async () => {
|
||||
if (marketingId && isResponseSuccess(marketing)) {
|
||||
const filledInitialValues = await getFilledMarketingFormInitialValues(
|
||||
marketing.data
|
||||
);
|
||||
|
||||
formik.setValues(filledInitialValues);
|
||||
setStep(3);
|
||||
}
|
||||
|
||||
if (isResponseError(marketing)) {
|
||||
router.push('/marketing');
|
||||
closeModalHandler();
|
||||
toast.error(marketing.message);
|
||||
}
|
||||
};
|
||||
|
||||
getFilledInitialValues();
|
||||
}, [marketingId, marketing]);
|
||||
|
||||
// Reset error message when step changes
|
||||
useEffect(() => {
|
||||
setFormErrorList([]);
|
||||
setFormErrorMessage('');
|
||||
}, [step]);
|
||||
|
||||
useEffect(() => {
|
||||
if (memoSalesOrder.length === 0) {
|
||||
setStep(1);
|
||||
}
|
||||
}, [memoSalesOrder]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
@@ -492,137 +470,144 @@ const SalesOrderFormModal = ({
|
||||
}}
|
||||
className='w-full min-h-full flex flex-col sm:flex-row items-stretch bg-base-100 rounded-xl overflow-y-auto'
|
||||
>
|
||||
<div className='w-full sm:w-[446px]'>
|
||||
<div className='w-full p-4 flex flex-row items-stretch gap-3 border-b border-base-content/10'>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={() => closeModalHandler()}
|
||||
className='p-0 text-black hover:text-base-content'
|
||||
>
|
||||
<Icon icon='heroicons:x-mark' width={20} height={20} />
|
||||
</Button>
|
||||
|
||||
<div className='w-px border-none bg-base-content/10' />
|
||||
|
||||
<h4 className='text-sm font-medium text-base-content/50'>
|
||||
{modalAction === 'add' ? 'Add' : 'Edit'} Sales Order
|
||||
</h4>
|
||||
</div>
|
||||
<form
|
||||
className='w-full p-4 flex flex-col border-b border-base-content/10'
|
||||
ref={formRef}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<h4 className='text-base font-medium text-base-content/50 font-roboto'>
|
||||
Informasi Umum
|
||||
</h4>
|
||||
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Pelanggan'
|
||||
options={customerOptions}
|
||||
isLoading={isLoadingCustomerOptions}
|
||||
value={formik.values.customer}
|
||||
onChange={handleChangeCustomer}
|
||||
onInputChange={setInputCustomerValue}
|
||||
onMenuScrollToBottom={loadMoreCustomer}
|
||||
isError={
|
||||
formik.touched.customer_id &&
|
||||
Boolean(formik.errors.customer_id)
|
||||
}
|
||||
errorMessage={formik.errors.customer_id}
|
||||
isClearable
|
||||
placeholder='Pilih Pelanggan'
|
||||
isDisabled={
|
||||
formType === 'add_deliver' ||
|
||||
formType === 'edit_deliver' ||
|
||||
formType === 'edit'
|
||||
}
|
||||
/>
|
||||
<DateInput
|
||||
required
|
||||
name='so_date'
|
||||
label='Tanggal'
|
||||
value={formik.values.so_date}
|
||||
onChange={formik.handleChange}
|
||||
isError={
|
||||
formik.touched.so_date && Boolean(formik.errors.so_date)
|
||||
}
|
||||
errorMessage={formik.errors.so_date}
|
||||
placeholder='Pilih Tanggal'
|
||||
readOnly={
|
||||
formType == 'add_deliver' || formType == 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Sales'
|
||||
options={salesOptions}
|
||||
isLoading={isLoadingSalesOptions}
|
||||
value={formik.values.sales_person}
|
||||
onChange={handleChangeSalesPerson}
|
||||
onInputChange={setInputSalesValue}
|
||||
onMenuScrollToBottom={loadMoreSales}
|
||||
isError={
|
||||
formik.touched.sales_person_id &&
|
||||
Boolean(formik.errors.sales_person_id)
|
||||
}
|
||||
errorMessage={formik.errors.sales_person_id}
|
||||
isClearable
|
||||
placeholder='Pilih Sales'
|
||||
isDisabled={
|
||||
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<DebouncedTextArea
|
||||
ref={textareaRef}
|
||||
required
|
||||
name='notes'
|
||||
label='Catatan'
|
||||
rows={3}
|
||||
placeholder='Masukan catatan penjualan'
|
||||
value={formik.values.notes || ''}
|
||||
onChange={formik.handleChange}
|
||||
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
||||
errorMessage={formik.errors.notes}
|
||||
disabled={
|
||||
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<NumberInput
|
||||
name='total_price'
|
||||
label='Total Penjualan'
|
||||
placeholder='Tambah produk terlebih dahulu'
|
||||
value={grandTotal || ''}
|
||||
readOnly
|
||||
startAdornment={
|
||||
<span className='font-semibold py-1 text-xs'>Rp</span>
|
||||
}
|
||||
/>
|
||||
<AlertErrorList
|
||||
className={{
|
||||
alert: 'w-full mt-4',
|
||||
}}
|
||||
formErrorList={formErrorList}
|
||||
onClose={close}
|
||||
/>
|
||||
</form>
|
||||
|
||||
<div className='w-full p-4'>
|
||||
{step === 1 && (
|
||||
{step <= 3 && (
|
||||
<div className='w-full sm:w-[446px]'>
|
||||
<div className='w-full p-4 flex flex-row items-stretch gap-3 border-b border-base-content/10'>
|
||||
<Button
|
||||
type='button'
|
||||
onClick={nextButtonHandler}
|
||||
disabled={isNextButtonDisabled}
|
||||
className='w-full p-3 rounded-lg text-sm text-base-100'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={() => closeModalHandler()}
|
||||
className='p-0 text-black hover:text-base-content'
|
||||
>
|
||||
Tambah Produk
|
||||
<Icon icon='heroicons:x-mark' width={20} height={20} />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<div className='w-px border-none bg-base-content/10' />
|
||||
|
||||
<h4 className='text-sm font-medium text-base-content/50'>
|
||||
{modalAction === 'add' ? 'Add' : 'Edit'} Sales Order
|
||||
</h4>
|
||||
</div>
|
||||
<form
|
||||
className='w-full p-4 flex flex-col border-b border-base-content/10'
|
||||
ref={formRef}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<h4 className='text-base font-medium text-base-content/50 font-roboto'>
|
||||
Informasi Order
|
||||
</h4>
|
||||
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Pelanggan'
|
||||
options={customerOptions}
|
||||
isLoading={isLoadingCustomerOptions}
|
||||
value={formik.values.customer}
|
||||
onChange={handleChangeCustomer}
|
||||
onInputChange={setInputCustomerValue}
|
||||
onMenuScrollToBottom={loadMoreCustomer}
|
||||
isError={
|
||||
formik.touched.customer_id &&
|
||||
Boolean(formik.errors.customer_id)
|
||||
}
|
||||
errorMessage={formik.errors.customer_id}
|
||||
isClearable
|
||||
placeholder='Pilih Pelanggan'
|
||||
isDisabled={
|
||||
modalAction === 'add_deliver' ||
|
||||
modalAction === 'edit_deliver' ||
|
||||
modalAction === 'edit'
|
||||
}
|
||||
/>
|
||||
<DateInput
|
||||
required
|
||||
name='so_date'
|
||||
label='Tanggal'
|
||||
value={formik.values.so_date}
|
||||
onChange={formik.handleChange}
|
||||
isError={
|
||||
formik.touched.so_date && Boolean(formik.errors.so_date)
|
||||
}
|
||||
errorMessage={formik.errors.so_date}
|
||||
placeholder='Pilih Tanggal'
|
||||
readOnly={
|
||||
modalAction == 'add_deliver' ||
|
||||
modalAction == 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Sales'
|
||||
options={salesOptions}
|
||||
isLoading={isLoadingSalesOptions}
|
||||
value={formik.values.sales_person}
|
||||
onChange={handleChangeSalesPerson}
|
||||
onInputChange={setInputSalesValue}
|
||||
onMenuScrollToBottom={loadMoreSales}
|
||||
isError={
|
||||
formik.touched.sales_person_id &&
|
||||
Boolean(formik.errors.sales_person_id)
|
||||
}
|
||||
errorMessage={formik.errors.sales_person_id}
|
||||
isClearable
|
||||
placeholder='Pilih Sales'
|
||||
isDisabled={
|
||||
modalAction === 'add_deliver' ||
|
||||
modalAction === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<DebouncedTextArea
|
||||
ref={textareaRef}
|
||||
required
|
||||
name='notes'
|
||||
label='Catatan'
|
||||
rows={3}
|
||||
placeholder='Masukan catatan penjualan'
|
||||
value={formik.values.notes || ''}
|
||||
onChange={formik.handleChange}
|
||||
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
||||
errorMessage={formik.errors.notes}
|
||||
disabled={
|
||||
modalAction === 'add_deliver' ||
|
||||
modalAction === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<NumberInput
|
||||
name='total_price'
|
||||
label='Total Penjualan'
|
||||
value={grandTotal}
|
||||
disabled={
|
||||
grandTotal === 0 && formik.values.sales_order.length === 0
|
||||
}
|
||||
readOnly
|
||||
startAdornment={
|
||||
<span className='font-semibold py-1 text-xs'>Rp</span>
|
||||
}
|
||||
/>
|
||||
<AlertErrorList
|
||||
className={{
|
||||
alert: 'w-full mt-4',
|
||||
}}
|
||||
formErrorList={formErrorList}
|
||||
onClose={close}
|
||||
/>
|
||||
</form>
|
||||
|
||||
<div className='w-full p-4'>
|
||||
{step === 1 && (
|
||||
<Button
|
||||
type='button'
|
||||
onClick={nextButtonHandler}
|
||||
disabled={isNextButtonDisabled}
|
||||
className='w-full rounded-lg text-sm text-base-100'
|
||||
>
|
||||
Tambah Produk
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 2 && (
|
||||
<div className='w-full min-h-full flex flex-col sm:w-[446px] border-l border-base-content/10'>
|
||||
<div className='w-full p-4 flex flex-row items-center justify-between gap-3 border-b border-base-content/10'>
|
||||
@@ -639,7 +624,7 @@ const SalesOrderFormModal = ({
|
||||
className='p-0 text-black hover:text-base-content'
|
||||
>
|
||||
<Icon
|
||||
icon='heroicons:arrow-left'
|
||||
icon='heroicons:chevron-left'
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
@@ -650,20 +635,22 @@ const SalesOrderFormModal = ({
|
||||
)}
|
||||
|
||||
<h4 className='text-sm font-medium text-base-content/50'>
|
||||
Tambah Produk
|
||||
{selectedMarketingProduct?.id ? 'Ubah' : 'Tambah'} Produk
|
||||
</h4>
|
||||
</div>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={() => closeModalHandler()}
|
||||
className='p-0 text-error hover:text-base-content'
|
||||
>
|
||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||
</Button>
|
||||
<RequirePermission permissions='lti.marketing.sales_order.delete'>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={deleteClickHandler}
|
||||
className='p-0 text-error hover:text-base-content'
|
||||
>
|
||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
</div>
|
||||
<div className='flex flex-1 flex-col'>
|
||||
<div className='flex flex-1 flex-col p-4'>
|
||||
<MemoizedSalesOrderProductForm
|
||||
onSubmitForm={handleAddSubmitSO}
|
||||
initialValues={selectedMarketingProduct ?? undefined}
|
||||
@@ -678,21 +665,23 @@ const SalesOrderFormModal = ({
|
||||
<h4 className='text-sm font-medium text-base-content/50'>
|
||||
Informasi Produk
|
||||
</h4>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={() => closeModalHandler()}
|
||||
className='p-0 text-error hover:text-base-content'
|
||||
>
|
||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||
</Button>
|
||||
<RequirePermission permissions='lti.marketing.sales_order.delete'>
|
||||
<Button
|
||||
type='button'
|
||||
variant='ghost'
|
||||
color='none'
|
||||
onClick={deleteClickHandler}
|
||||
className='p-0 text-error hover:text-base-content'
|
||||
>
|
||||
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
</div>
|
||||
<div className='flex flex-1 flex-col'>
|
||||
{memoSalesOrder.length > 0 && (
|
||||
<div className='p-4'>
|
||||
<div className='px-4 pt-4'>
|
||||
<MemoizedSalesOrderProductTable
|
||||
formType={formType}
|
||||
formType={(modalAction || 'add') as 'add' | 'edit'}
|
||||
data={memoSalesOrder}
|
||||
onDelete={handleDeleteSO}
|
||||
onEdit={handleEditSO}
|
||||
@@ -703,7 +692,7 @@ const SalesOrderFormModal = ({
|
||||
<div className='p-4 w-full'>
|
||||
<Button
|
||||
type='button'
|
||||
className='justify-center w-full rounded-lg text-center text-sm text-base-100'
|
||||
className='justify-center w-full p-3 rounded-lg text-center text-sm text-base-100'
|
||||
onClick={() => formRef.current?.requestSubmit()}
|
||||
>
|
||||
Submit
|
||||
@@ -718,8 +707,8 @@ const SalesOrderFormModal = ({
|
||||
ref={successModal.ref}
|
||||
iconPosition='left'
|
||||
type='success'
|
||||
text='Data Berhasil Ditambahkan'
|
||||
subtitleText='Data sales order telah berhasil disimpan.'
|
||||
text={`${modalAction === 'add' ? 'Data Berhasil Ditambahkan' : 'Data Berhasil Diubah'}`}
|
||||
subtitleText={`${modalAction === 'add' ? 'Data sales order telah berhasil disimpan.' : 'Data sales order telah berhasil diubah.'}`}
|
||||
primaryButton={{
|
||||
text: 'Oke',
|
||||
color: 'primary',
|
||||
@@ -737,6 +726,21 @@ const SalesOrderFormModal = ({
|
||||
onAddProductClick={handleAddSOClick}
|
||||
/>
|
||||
</ConfirmationModal>
|
||||
|
||||
<ConfirmationModal
|
||||
ref={deleteModal.ref}
|
||||
type='error'
|
||||
text={`Apakah anda yakin ingin menghapus data penjualan ini?`}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'error',
|
||||
isLoading: isLoading,
|
||||
onClick: confirmationModalDeleteClickHandler,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user