From 40c417ec72894cc9b8edeeb017704c48fbe3ea84 Mon Sep 17 00:00:00 2001 From: efrilm Date: Fri, 12 Sep 2025 15:23:19 +0700 Subject: [PATCH] Delete and Edit Vendor --- .../apps/vendor/{ => [id]}/detail/page.tsx | 0 src/services/queries/vendor.ts | 12 +- .../detail/vendor-overview/VendorDetails.tsx | 239 +++++++++++------- .../apps/vendor/list/AddVendorDrawer.tsx | 94 +++++-- .../apps/vendor/list/VendorListTable.tsx | 4 +- 5 files changed, 237 insertions(+), 112 deletions(-) rename src/app/[lang]/(dashboard)/(private)/apps/vendor/{ => [id]}/detail/page.tsx (100%) diff --git a/src/app/[lang]/(dashboard)/(private)/apps/vendor/detail/page.tsx b/src/app/[lang]/(dashboard)/(private)/apps/vendor/[id]/detail/page.tsx similarity index 100% rename from src/app/[lang]/(dashboard)/(private)/apps/vendor/detail/page.tsx rename to src/app/[lang]/(dashboard)/(private)/apps/vendor/[id]/detail/page.tsx diff --git a/src/services/queries/vendor.ts b/src/services/queries/vendor.ts index ce35d99..33dff13 100644 --- a/src/services/queries/vendor.ts +++ b/src/services/queries/vendor.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query' import { api } from '../api' -import { Vendors } from '@/types/services/vendor' +import { Vendor, Vendors } from '@/types/services/vendor' interface VendorQueryParams { page?: number @@ -34,3 +34,13 @@ export function useVendors(params: VendorQueryParams = {}) { } }) } + +export function useVendorById(id: string) { + return useQuery({ + queryKey: ['vendors', id], + queryFn: async () => { + const res = await api.get(`/vendors/${id}`) + return res.data.data + } + }) +} diff --git a/src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx b/src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx index f0f4615..c9e3b6a 100644 --- a/src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx +++ b/src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx @@ -1,20 +1,28 @@ +'use client' + // MUI Imports import Card from '@mui/material/Card' import CardContent from '@mui/material/CardContent' import Typography from '@mui/material/Typography' import Chip from '@mui/material/Chip' import Divider from '@mui/material/Divider' -import Button from '@mui/material/Button' -import type { ButtonProps } from '@mui/material/Button' - -// Type Imports -import type { ThemeColor } from '@core/types' // Component Imports -import EditUserInfo from '@components/dialogs/edit-user-info' -import ConfirmationDialog from '@components/dialogs/confirmation-dialog' -import OpenDialogOnElementClick from '@components/dialogs/OpenDialogOnElementClick' import CustomAvatar from '@core/components/mui/Avatar' +import { useParams } from 'next/navigation' +import { useVendorById } from '@/services/queries/vendor' +import Loading from '@/components/layout/shared/Loading' +import { getInitials } from '@/utils/getInitials' +import OpenDialogOnElementClick from '@/components/dialogs/OpenDialogOnElementClick' +import { Box, Button, ButtonProps, CircularProgress } from '@mui/material' +import ConfirmationDialog from '@/components/dialogs/confirmation-dialog' +import EditUserInfo from '@/components/dialogs/edit-user-info' +import { ThemeColor } from '@/@core/types' +import { useState } from 'react' +import AddVendorDrawer from '../../list/AddVendorDrawer' +import ConfirmDeleteDialog from '@/components/dialogs/confirm-delete' +import { useRouter } from 'next/router' +import { useVendorsMutation } from '@/services/mutations/vendor' // Vars const userData = { @@ -33,7 +41,25 @@ const userData = { } const VendorDetails = () => { - // Vars + const [editVendorOpen, setEditVendorOpen] = useState(false) + const [openConfirm, setOpenConfirm] = useState(false) + + const params = useParams() + const id = params?.id ?? '' + + const { data: vendor, isLoading, error } = useVendorById(id as string) + + const { deleteVendor } = useVendorsMutation() + + const handleDelete = () => { + deleteVendor.mutate(id as string, { + onSuccess: () => { + setOpenConfirm(false) + window.history.back() + } + }) + } + const buttonProps = (children: string, color: ThemeColor, variant: ButtonProps['variant']): ButtonProps => ({ children, color, @@ -42,91 +68,132 @@ const VendorDetails = () => { return ( <> - - -
-
-
- - {`${userData.firstName} ${userData.lastName}`} + {isLoading ? ( + + + + ) : ( + + +
+
+
+ {/* + {getInitials(vendor?.name as string)} + */} + {vendor?.name} +
+
-
-
- {/* Detail Kontak Section */} -
- Detail Kontak - -
-
- - Nama: - - {`${userData.firstName} ${userData.lastName}`} -
-
- - Perusahaan: - - {userData.perusahaan} -
-
- - Email: - - - {userData.email} - -
-
- - Telepon: - - - {userData.telepon} - -
-
- - Alamat Penagihan: - - - {userData.alamatPenagihan} - + {/* Detail Kontak Section */} +
+ Detail Kontak + +
+
+ + Contact Person: + + {vendor?.contact_person} +
+
+ + Perusahaan: + + {vendor?.name} +
+
+ + Email: + + + {vendor?.email} + +
+
+ + Telepon: + + + {vendor?.phone_number} + +
+
+ + Alamat Penagihan: + + + {vendor?.address ?? '-'} + +
-
- {/* Pemetaan Akun Section */} -
- Pemetaan Akun - -
-
- - Akun Hutang: - - - {userData.akunHutang} - -
-
- - Akun Piutang: - - {userData.akunPiutang || '-'} -
-
- - Kena Pajak: - - {userData.kenaPajak} + {/* Pemetaan Akun Section */} +
+ Pemetaan Akun + +
+
+ + Akun Hutang: + + + {userData.akunHutang} + +
+
+ + Akun Piutang: + + {userData.akunPiutang || '-'} +
+
+ + Kena Pajak: + + {userData.kenaPajak} +
-
- - +
+ + +
+ + + )} + setEditVendorOpen(!editVendorOpen)} data={vendor} /> + setOpenConfirm(false)} + onConfirm={handleDelete} + isLoading={deleteVendor.isPending} + title='Delete Vendor' + message='Are you sure you want to delete this Vendor? This action cannot be undone.' + /> ) } diff --git a/src/views/apps/vendor/list/AddVendorDrawer.tsx b/src/views/apps/vendor/list/AddVendorDrawer.tsx index c867682..3c8a7b3 100644 --- a/src/views/apps/vendor/list/AddVendorDrawer.tsx +++ b/src/views/apps/vendor/list/AddVendorDrawer.tsx @@ -1,5 +1,5 @@ // React Imports -import { useState } from 'react' +import { useState, useEffect } from 'react' // MUI Imports import Button from '@mui/material/Button' @@ -18,12 +18,13 @@ import { useForm, Controller } from 'react-hook-form' // Component Imports import CustomTextField from '@core/components/mui/TextField' -import { VendorRequest } from '@/types/services/vendor' +import { Vendor, VendorRequest } from '@/types/services/vendor' import { useVendorsMutation } from '@/services/mutations/vendor' type Props = { open: boolean handleClose: () => void + data?: Vendor // Data vendor untuk edit (jika ada) } type FormValidateType = { @@ -51,9 +52,9 @@ const initialData: FormValidateType = { is_active: true } -const AddVendorDrawer = (props: Props) => { +const AddEditVendorDrawer = (props: Props) => { // Props - const { open, handleClose } = props + const { open, handleClose, data } = props // States const [showMore, setShowMore] = useState(false) @@ -61,6 +62,9 @@ const AddVendorDrawer = (props: Props) => { const { createVendor, updateVendor } = useVendorsMutation() + // Determine if this is edit mode + const isEditMode = Boolean(data?.id) + // Hooks const { control, @@ -71,29 +75,73 @@ const AddVendorDrawer = (props: Props) => { defaultValues: initialData }) - const handleFormSubmit = async (data: FormValidateType) => { + // Effect to populate form when editing + useEffect(() => { + if (isEditMode && data) { + // Populate form with existing data + const formData: FormValidateType = { + name: data.name || '', + email: data.email || '', + phone_number: data.phone_number || '', + address: data.address || '', + contact_person: data.contact_person || '', + tax_number: data.tax_number || '', + payment_terms: data.payment_terms || '', + notes: data.notes || '', + is_active: data.is_active ?? true + } + + resetForm(formData) + + // Show more fields if any optional field has data + const hasOptionalData = data.address || data.tax_number || data.payment_terms || data.notes + if (hasOptionalData) { + setShowMore(true) + } + } else { + // Reset to initial data for add mode + resetForm(initialData) + setShowMore(false) + } + }, [data, isEditMode, resetForm]) + + const handleFormSubmit = async (formData: FormValidateType) => { try { setIsSubmitting(true) // Create VendorRequest object const vendorRequest: VendorRequest = { - name: data.name, - email: data.email || undefined, - phone_number: data.phone_number || undefined, - address: data.address || undefined, - contact_person: data.contact_person || undefined, - tax_number: data.tax_number || undefined, - payment_terms: data.payment_terms || undefined, - notes: data.notes || undefined, - is_active: data.is_active + name: formData.name, + email: formData.email || undefined, + phone_number: formData.phone_number || undefined, + address: formData.address || undefined, + contact_person: formData.contact_person || undefined, + tax_number: formData.tax_number || undefined, + payment_terms: formData.payment_terms || undefined, + notes: formData.notes || undefined, + is_active: formData.is_active } - createVendor.mutate(vendorRequest, { - onSuccess: () => { - handleReset() - handleClose() - } - }) + if (isEditMode && data?.id) { + // Update existing vendor + updateVendor.mutate( + { id: data.id, payload: vendorRequest }, + { + onSuccess: () => { + handleReset() + handleClose() + } + } + ) + } else { + // Create new vendor + createVendor.mutate(vendorRequest, { + onSuccess: () => { + handleReset() + handleClose() + } + }) + } } catch (error) { console.error('Error submitting vendor:', error) // Handle error (show toast, etc.) @@ -136,7 +184,7 @@ const AddVendorDrawer = (props: Props) => { }} >
- Tambah Vendor Baru + {isEditMode ? 'Edit Vendor' : 'Tambah Vendor Baru'} @@ -359,7 +407,7 @@ const AddVendorDrawer = (props: Props) => { >