mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE): Add project flock closing modal and zustand store
This commit is contained in:
@@ -37,6 +37,7 @@ import ProjectFlockConfirmationModal from './ProjectFlockConfirmationModal';
|
||||
import { useProjectFlockStore } from '@/stores/production/project-flock/project-flock.store';
|
||||
import { ProjectFlockFormValues } from './form/ProjectFlockForm.schema';
|
||||
import { useChickinStore } from '@/stores/production/chickin/chickin.store';
|
||||
import { useProjectFlockClosingStore } from '@/stores/production/project-flock-closing/project-flock-closing.store';
|
||||
|
||||
const RowOptionsMenu = ({
|
||||
props,
|
||||
@@ -195,6 +196,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
||||
const confirmModal = useModal();
|
||||
const successModal = useModal();
|
||||
const chickinApproveModal = useModal();
|
||||
const closingModal = useModal();
|
||||
const [approvalAction, setApprovalAction] = useState<'APPROVED' | 'REJECTED'>(
|
||||
'APPROVED'
|
||||
);
|
||||
@@ -210,6 +212,15 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
||||
setChickinApproveLoading,
|
||||
} = useChickinStore();
|
||||
|
||||
const {
|
||||
isClosingModalOpen,
|
||||
isKandangClosed,
|
||||
isClosingLoading,
|
||||
closingCallback,
|
||||
closeClosingModal,
|
||||
setClosingLoading,
|
||||
} = useProjectFlockClosingStore();
|
||||
|
||||
// ===== Fetch Data =====
|
||||
const {
|
||||
data: projectFlocks,
|
||||
@@ -309,6 +320,14 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
||||
}
|
||||
}, [isChickinApproveModalOpen, chickinApproveModal]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isClosingModalOpen) {
|
||||
closingModal.openModal();
|
||||
} else {
|
||||
closingModal.closeModal();
|
||||
}
|
||||
}, [isClosingModalOpen, closingModal]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
successModal.openModal();
|
||||
@@ -1025,6 +1044,45 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => {
|
||||
isLoading: isChickinApproveLoading,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Project Flock Closing Modal */}
|
||||
<ConfirmationModal
|
||||
ref={closingModal.ref}
|
||||
type='error'
|
||||
text={
|
||||
!isKandangClosed
|
||||
? 'Apakah kamu yakin ingin mengakhiri project ini ? *Pastikan persediaan produk di gudang terkait sudah kosong, dan BOP sudah selesai'
|
||||
: 'Apakah kamu yakin ingin membuka kembali project ini ? *Project ini akan kembali ke status aktif'
|
||||
}
|
||||
className={{
|
||||
modal: 'z-9999',
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
onClick: () => {
|
||||
closeClosingModal();
|
||||
closingModal.closeModal();
|
||||
},
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'error',
|
||||
isLoading: isClosingLoading,
|
||||
onClick: async () => {
|
||||
if (closingCallback) {
|
||||
setClosingLoading(true);
|
||||
try {
|
||||
await closingCallback(!isKandangClosed ? 'close' : 'unclose');
|
||||
} finally {
|
||||
setClosingLoading(false);
|
||||
closeClosingModal();
|
||||
closingModal.closeModal();
|
||||
refreshProjectFlocks();
|
||||
}
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,9 +17,8 @@ import { Icon } from '@iconify/react';
|
||||
import useSWR from 'swr';
|
||||
import { ProjectFlockKandangApi } from '@/services/api/production/project-flock-kandang';
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import ConfirmationModal from '@/components/modal/ConfirmationModal';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useProjectFlockClosingStore } from '@/stores/production/project-flock-closing/project-flock-closing.store';
|
||||
import { useMemo } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { ApprovalApi } from '@/services/api/approval';
|
||||
@@ -53,9 +52,8 @@ const ProjectFlockClosingForm = ({
|
||||
projectFlockKandang: ProjectFlockKandang;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const closeModal = useModal();
|
||||
|
||||
const [isClosingLoading, setIsClosingLoading] = useState(false);
|
||||
const { openClosingModal } = useProjectFlockClosingStore();
|
||||
|
||||
const { data: closingData, isLoading } = useSWR(
|
||||
`${ProjectFlockKandangApi.basePath}/${projectFlockKandang.id}/closing`,
|
||||
@@ -80,29 +78,34 @@ const ProjectFlockClosingForm = ({
|
||||
: true;
|
||||
}, [projectFlockKandangApprovals]);
|
||||
|
||||
const confirmationModalCloseClickHandler = async () => {
|
||||
setIsClosingLoading(true);
|
||||
const deleteProjectFlockRes = await ProjectFlockKandangApi.closing(
|
||||
projectFlockKandang?.id as number,
|
||||
{
|
||||
closed_date: !isKandangClosed
|
||||
? formatDate(new Date(), 'YYYY-MM-DD')
|
||||
: '',
|
||||
action: !isKandangClosed ? 'close' : 'unclose',
|
||||
}
|
||||
);
|
||||
|
||||
if (isResponseSuccess(deleteProjectFlockRes)) {
|
||||
toast.success(deleteProjectFlockRes?.message as string);
|
||||
router.push(
|
||||
`/production/project-flock/detail?projectFlockId=${projectFlock.id}`
|
||||
const handleCloseClick = () => {
|
||||
const closingCallback = async (action: 'close' | 'unclose') => {
|
||||
const deleteProjectFlockRes = await ProjectFlockKandangApi.closing(
|
||||
projectFlockKandang?.id as number,
|
||||
{
|
||||
closed_date:
|
||||
action === 'close' ? formatDate(new Date(), 'YYYY-MM-DD') : '',
|
||||
action,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (isResponseError(deleteProjectFlockRes)) {
|
||||
toast.error(deleteProjectFlockRes?.message as string);
|
||||
}
|
||||
setIsClosingLoading(false);
|
||||
closeModal.closeModal();
|
||||
|
||||
if (isResponseSuccess(deleteProjectFlockRes)) {
|
||||
toast.success(deleteProjectFlockRes?.message as string);
|
||||
router.push(
|
||||
`/production/project-flock/detail?projectFlockId=${projectFlock.id}`
|
||||
);
|
||||
}
|
||||
if (isResponseError(deleteProjectFlockRes)) {
|
||||
toast.error(deleteProjectFlockRes?.message as string);
|
||||
}
|
||||
};
|
||||
|
||||
openClosingModal(
|
||||
projectFlockKandang,
|
||||
projectFlock.id,
|
||||
isKandangClosed,
|
||||
closingCallback
|
||||
);
|
||||
};
|
||||
|
||||
// const errorStock = useMemo(() => {
|
||||
@@ -334,7 +337,7 @@ const ProjectFlockClosingForm = ({
|
||||
color='error'
|
||||
isLoading={isLoading}
|
||||
disabled={!isCanCloseValid}
|
||||
onClick={() => closeModal.openModal()}
|
||||
onClick={handleCloseClick}
|
||||
>
|
||||
<Icon
|
||||
icon={
|
||||
@@ -347,25 +350,6 @@ const ProjectFlockClosingForm = ({
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
</div>
|
||||
|
||||
<ConfirmationModal
|
||||
ref={closeModal.ref}
|
||||
type='error'
|
||||
text={
|
||||
!isKandangClosed
|
||||
? 'Apakah kamu yakin ingin mengakhiri project ini ? *Pastikan persediaan produk di gudang terkait sudah kosong, dan BOP sudah selesai'
|
||||
: 'Apakah kamu yakin ingin membuka kembali project ini ? *Project ini akan kembali ke status aktif'
|
||||
}
|
||||
secondaryButton={{
|
||||
text: 'Tidak',
|
||||
}}
|
||||
primaryButton={{
|
||||
text: 'Ya',
|
||||
color: 'error',
|
||||
isLoading: isClosingLoading,
|
||||
onClick: confirmationModalCloseClickHandler,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
'use client';
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { createProjectFlockClosingSlice } from '@/stores/production/project-flock-closing/slices/project-flock-closing.slice';
|
||||
import { ProjectFlockClosingSlice } from '@/stores/production/project-flock-closing/slices/project-flock-closing.slice';
|
||||
|
||||
export type ProjectFlockClosingStore = ProjectFlockClosingSlice;
|
||||
|
||||
export const useProjectFlockClosingStore = create<ProjectFlockClosingStore>()(
|
||||
devtools(
|
||||
(...args) => ({
|
||||
...createProjectFlockClosingSlice(...args),
|
||||
}),
|
||||
{
|
||||
name: 'ProjectFlockClosingStore',
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,70 @@
|
||||
import { StateCreator } from 'zustand';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
|
||||
export type ProjectFlockClosingSlice = {
|
||||
// State
|
||||
isClosingModalOpen: boolean;
|
||||
selectedProjectFlockKandang: ProjectFlockKandang | null;
|
||||
projectFlockId: number | null;
|
||||
isKandangClosed: boolean;
|
||||
isClosingLoading: boolean;
|
||||
closingCallback: ((action: 'close' | 'unclose') => Promise<void>) | null;
|
||||
|
||||
// Actions
|
||||
openClosingModal: (
|
||||
data: ProjectFlockKandang,
|
||||
projectFlockId: number,
|
||||
isClosed: boolean,
|
||||
callback: (action: 'close' | 'unclose') => Promise<void>
|
||||
) => void;
|
||||
closeClosingModal: () => void;
|
||||
setClosingLoading: (loading: boolean) => void;
|
||||
resetClosing: () => void;
|
||||
};
|
||||
|
||||
export const createProjectFlockClosingSlice: StateCreator<
|
||||
ProjectFlockClosingSlice,
|
||||
[],
|
||||
[],
|
||||
ProjectFlockClosingSlice
|
||||
> = (set) => ({
|
||||
// Initial state
|
||||
isClosingModalOpen: false,
|
||||
selectedProjectFlockKandang: null,
|
||||
projectFlockId: null,
|
||||
isKandangClosed: false,
|
||||
isClosingLoading: false,
|
||||
closingCallback: null,
|
||||
|
||||
// Actions
|
||||
openClosingModal: (data, projectFlockId, isClosed, callback) =>
|
||||
set({
|
||||
isClosingModalOpen: true,
|
||||
selectedProjectFlockKandang: data,
|
||||
projectFlockId,
|
||||
isKandangClosed: isClosed,
|
||||
closingCallback: callback,
|
||||
}),
|
||||
|
||||
closeClosingModal: () =>
|
||||
set({
|
||||
isClosingModalOpen: false,
|
||||
selectedProjectFlockKandang: null,
|
||||
projectFlockId: null,
|
||||
isKandangClosed: false,
|
||||
closingCallback: null,
|
||||
}),
|
||||
|
||||
setClosingLoading: (loading) =>
|
||||
set({ isClosingLoading: loading }),
|
||||
|
||||
resetClosing: () =>
|
||||
set({
|
||||
isClosingModalOpen: false,
|
||||
selectedProjectFlockKandang: null,
|
||||
projectFlockId: null,
|
||||
isKandangClosed: false,
|
||||
isClosingLoading: false,
|
||||
closingCallback: null,
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user