diff --git a/src/app/[lang]/(dashboard)/(private)/apps/vendor/list/page.tsx b/src/app/[lang]/(dashboard)/(private)/apps/vendor/list/page.tsx new file mode 100644 index 0000000..d9efb5c --- /dev/null +++ b/src/app/[lang]/(dashboard)/(private)/apps/vendor/list/page.tsx @@ -0,0 +1,8 @@ +import { vendorDummyData } from '@/data/dummy/vendor' +import VendorList from '@/views/apps/vendor/list' + +const VendorListTablePage = async () => { + return +} + +export default VendorListTablePage diff --git a/src/components/layout/vertical/VerticalMenu.tsx b/src/components/layout/vertical/VerticalMenu.tsx index e235783..648248d 100644 --- a/src/components/layout/vertical/VerticalMenu.tsx +++ b/src/components/layout/vertical/VerticalMenu.tsx @@ -120,9 +120,7 @@ const VerticalMenu = ({ dictionary, scrollMenu }: Props) => { {dictionary['navigation'].list} - - {dictionary['navigation'].restock} - + {dictionary['navigation'].restock} {/* {dictionary['navigation'].settings} */} @@ -140,6 +138,10 @@ const VerticalMenu = ({ dictionary, scrollMenu }: Props) => { {dictionary['navigation'].list} {/* {dictionary['navigation'].view} */} + }> + {dictionary['navigation'].list} + {/* {dictionary['navigation'].view} */} + diff --git a/src/data/dictionaries/en.json b/src/data/dictionaries/en.json index 2b821c4..9904156 100644 --- a/src/data/dictionaries/en.json +++ b/src/data/dictionaries/en.json @@ -111,6 +111,7 @@ "menuLevel2": "Menu Level 2", "menuLevel3": "Menu Level 3", "disabledMenu": "Disabled Menu", - "dailyReport": "Daily Report" + "dailyReport": "Daily Report", + "vendor": "Vendor" } } diff --git a/src/data/dictionaries/id.json b/src/data/dictionaries/id.json index e2fb3ff..af683c1 100644 --- a/src/data/dictionaries/id.json +++ b/src/data/dictionaries/id.json @@ -111,6 +111,7 @@ "menuLevel2": "Level Menu 2", "menuLevel3": "Level Menu 3", "disabledMenu": "Menu Nonaktif", - "dailyReport": "Laporan Harian" + "dailyReport": "Laporan Harian", + "vendor": "Vendor" } } diff --git a/src/data/dummy/vendor.ts b/src/data/dummy/vendor.ts new file mode 100644 index 0000000..d95ddcd --- /dev/null +++ b/src/data/dummy/vendor.ts @@ -0,0 +1,204 @@ +import { VendorType } from '@/types/apps/vendorTypes' + +export const vendorDummyData: VendorType[] = [ + { + id: 1, + photo: '', + name: 'Budi Santoso', + company: 'PT Maju Bersama Sejahtera', + email: 'budi.santoso@majubersama.co.id', + telephone: '+62 21 5551234', + youPayable: 25500000, + theyPayable: 12300000 + }, + { + id: 2, + photo: '', + name: 'Siti Nurhaliza', + company: 'CV Berkah Mandiri', + email: 'siti.nurhaliza@berkahmandiri.com', + telephone: '+62 22 8887654', + youPayable: 18750000, + theyPayable: 8950000 + }, + { + id: 3, + photo: '', + name: 'Ahmad Wijaya', + company: 'PT Teknologi Nusantara', + email: 'ahmad.wijaya@teknusantara.co.id', + telephone: '+62 24 3332211', + youPayable: 42100000, + theyPayable: 15600000 + }, + { + id: 4, + photo: '', + name: 'Dewi Sartika', + company: 'UD Sumber Rejeki', + email: 'dewi.sartika@sumberrejeki.net', + telephone: '+62 31 4445566', + youPayable: 9800000, + theyPayable: 22100000 + }, + { + id: 5, + photo: '', + name: 'Rudi Hermawan', + company: 'PT Indah Karya Persada', + email: 'rudi.hermawan@indahkarya.co.id', + telephone: '+62 274 7778899', + youPayable: 33250000, + theyPayable: 5400000 + }, + { + id: 6, + photo: '', + name: 'Maya Sari', + company: 'CV Harapan Jaya', + email: 'maya.sari@harapanjaya.com', + telephone: '+62 261 1112233', + youPayable: 16900000, + theyPayable: 28750000 + }, + { + id: 7, + photo: '', + name: 'Andi Prasetyo', + company: 'PT Cipta Mandiri Utama', + email: 'andi.prasetyo@ciptamandiri.co.id', + telephone: '+62 411 5556677', + youPayable: 21400000, + theyPayable: 11850000 + }, + { + id: 8, + photo: '', + name: 'Fitri Ramadhani', + company: 'UD Barokah Sukses', + email: 'fitri.ramadhani@barokahsukses.net', + telephone: '+62 751 9998877', + youPayable: 12650000, + theyPayable: 19300000 + }, + { + id: 9, + photo: '', + name: 'Agus Setiawan', + company: 'PT Nusantara Prima', + email: 'agus.setiawan@nusantaraprima.co.id', + telephone: '+62 541 3334455', + youPayable: 38800000, + theyPayable: 7200000 + }, + { + id: 10, + photo: '', + name: 'Rina Sulastri', + company: 'CV Mitra Sejati', + email: 'rina.sulastri@mitrasejati.com', + telephone: '+62 778 6667788', + youPayable: 14300000, + theyPayable: 24950000 + }, + { + id: 11, + photo: '', + name: 'Bambang Kurniawan', + company: 'PT Harmoni Bersama', + email: 'bambang.kurniawan@harmonibersama.co.id', + telephone: '+62 21 7779900', + youPayable: 29150000, + theyPayable: 13750000 + }, + { + id: 12, + photo: '', + name: 'Indah Permatasari', + company: 'UD Cahaya Abadi', + email: 'indah.permatasari@cahayaabadi.net', + telephone: '+62 361 2223344', + youPayable: 8900000, + theyPayable: 31200000 + }, + { + id: 13, + photo: '', + name: 'Dodi Supriadi', + company: 'PT Karya Gemilang', + email: 'dodi.supriadi@karyagemilang.co.id', + telephone: '+62 721 8889911', + youPayable: 36700000, + theyPayable: 9100000 + }, + { + id: 14, + photo: '', + name: 'Lestari Wulandari', + company: 'CV Anugrah Sentosa', + email: 'lestari.wulandari@anugrahsentosa.com', + telephone: '+62 741 4445566', + youPayable: 19850000, + theyPayable: 16400000 + }, + { + id: 15, + photo: '', + name: 'Hendra Gunawan', + company: 'PT Surya Mandala', + email: 'hendra.gunawan@suryamandala.co.id', + telephone: '+62 511 7778800', + youPayable: 27300000, + theyPayable: 21650000 + }, + { + id: 16, + photo: '', + name: 'Nurul Hidayah', + company: 'UD Rezeki Barokah', + email: 'nurul.hidayah@rezekibarokah.net', + telephone: '+62 431 1112200', + youPayable: 15200000, + theyPayable: 26800000 + }, + { + id: 17, + photo: '', + name: 'Teguh Prasetyo', + company: 'PT Dinamika Persada', + email: 'teguh.prasetyo@dinamikapersada.co.id', + telephone: '+62 62 5556600', + youPayable: 32900000, + theyPayable: 12150000 + }, + { + id: 18, + photo: '', + name: 'Sri Mulyani', + company: 'CV Berkah Mulia', + email: 'sri.mulyani@berkahmulia.com', + telephone: '+62 771 3337799', + youPayable: 11700000, + theyPayable: 29400000 + }, + { + id: 19, + photo: '', + name: 'Joko Widodo', + company: 'PT Makmur Sejahtera', + email: 'joko.widodo@makmursejahtera.co.id', + telephone: '+62 341 8882211', + youPayable: 24800000, + theyPayable: 18350000 + }, + { + id: 20, + photo: '', + name: 'Ratna Sari', + company: 'UD Sari Indah', + email: 'ratna.sari@sariindah.net', + telephone: '+62 717 9990011', + youPayable: 17950000, + theyPayable: 23600000 + } +] diff --git a/src/types/apps/vendorTypes.ts b/src/types/apps/vendorTypes.ts new file mode 100644 index 0000000..33de981 --- /dev/null +++ b/src/types/apps/vendorTypes.ts @@ -0,0 +1,10 @@ +export type VendorType = { + id: number + photo: string + name: string + company: string + email: string + telephone: string + youPayable: number + theyPayable: number +} diff --git a/src/views/apps/vendor/list/AddVendorDrawer.tsx b/src/views/apps/vendor/list/AddVendorDrawer.tsx new file mode 100644 index 0000000..5980159 --- /dev/null +++ b/src/views/apps/vendor/list/AddVendorDrawer.tsx @@ -0,0 +1,595 @@ +// React Imports +import { useState } from 'react' + +// MUI Imports +import Button from '@mui/material/Button' +import Drawer from '@mui/material/Drawer' +import IconButton from '@mui/material/IconButton' +import MenuItem from '@mui/material/MenuItem' +import Typography from '@mui/material/Typography' +import Divider from '@mui/material/Divider' +import Grid from '@mui/material/Grid2' +import Box from '@mui/material/Box' + +// Third-party Imports +import { useForm, Controller } from 'react-hook-form' + +// Types Imports +import type { VendorType } from '@/types/apps/vendorTypes' + +// Component Imports +import CustomTextField from '@core/components/mui/TextField' + +type Props = { + open: boolean + handleClose: () => void + vendorData?: VendorType[] + setData: (data: VendorType[]) => void +} + +type FormValidateType = { + name: string + company: string + email: string + telephone: string +} + +// Vars +const initialData = { + name: '', + company: '', + email: '', + telephone: '' +} + +const AddVendorDrawer = (props: Props) => { + // Props + const { open, handleClose, vendorData, setData } = props + + // States + const [showMore, setShowMore] = useState(false) + const [alamatPengiriman, setAlamatPengiriman] = useState(['']) + const [rekeningBank, setRekeningBank] = useState([ + { + bank: '', + cabang: '', + namaPemilik: '', + nomorRekening: '' + } + ]) + + // Hooks + const { + control, + reset: resetForm, + handleSubmit, + formState: { errors } + } = useForm({ + defaultValues: initialData + }) + + // Functions untuk alamat + const handleTambahAlamat = () => { + setAlamatPengiriman([...alamatPengiriman, '']) + } + + const handleHapusAlamat = (index: number) => { + if (alamatPengiriman.length > 1) { + const newAlamat = alamatPengiriman.filter((_, i) => i !== index) + setAlamatPengiriman(newAlamat) + } + } + + const handleChangeAlamat = (index: number, value: string) => { + const newAlamat = [...alamatPengiriman] + newAlamat[index] = value + setAlamatPengiriman(newAlamat) + } + + // Functions untuk rekening bank + const handleTambahRekening = () => { + setRekeningBank([ + ...rekeningBank, + { + bank: '', + cabang: '', + namaPemilik: '', + nomorRekening: '' + } + ]) + } + + const handleHapusRekening = (index: number) => { + if (rekeningBank.length > 1) { + const newRekening = rekeningBank.filter((_, i) => i !== index) + setRekeningBank(newRekening) + } + } + + const handleChangeRekening = (index: number, field: string, value: string) => { + const newRekening = [...rekeningBank] + newRekening[index] = { ...newRekening[index], [field]: value } + setRekeningBank(newRekening) + } + + const onSubmit = (data: FormValidateType) => { + const newVendor: VendorType = { + id: (vendorData?.length && vendorData?.length + 1) || 1, + photo: '', + name: data.name, + company: data.company, + email: data.email, + telephone: data.telephone, + youPayable: 0, + theyPayable: 0 + } + + setData([...(vendorData ?? []), newVendor]) + handleClose() + resetForm(initialData) + setAlamatPengiriman(['']) + setRekeningBank([ + { + bank: '', + cabang: '', + namaPemilik: '', + nomorRekening: '' + } + ]) + setShowMore(false) + } + + const handleReset = () => { + handleClose() + resetForm(initialData) + setAlamatPengiriman(['']) + setRekeningBank([ + { + bank: '', + cabang: '', + namaPemilik: '', + nomorRekening: '' + } + ]) + setShowMore(false) + } + + return ( + + {/* Sticky Header */} + +
+ Tambah Vendor Baru + + + +
+
+ + {/* Scrollable Content */} + +
onSubmit(data))}> +
+ {/* Tampilkan Foto */} +
+ + + Tampilkan Foto + +
+ + {/* Nama */} +
+ + Nama * + + + + + Tuan + Nyonya + Nona + Bapak + Ibu + + + + ( + + )} + /> + + +
+ + {/* Perusahaan dan Telepon */} + + + ( + + )} + /> + + + ( + + )} + /> + + + + {/* Email */} + ( + + )} + /> + + {/* Tampilkan selengkapnya */} + {!showMore && ( +
setShowMore(true)}> + + + Tampilkan selengkapnya + +
+ )} + + {/* Konten tambahan yang muncul saat showMore true */} + {showMore && ( + <> + {/* Alamat Penagihan */} +
+ + Alamat Penagihan + + +
+ + {/* Negara */} +
+ + Negara + + + Indonesia + +
+ + {/* Provinsi dan Kota */} + + + + Provinsi + + + Pilih Provinsi + DKI Jakarta + Jawa Barat + Jawa Tengah + Jawa Timur + + + + + Kota + + + Pilih Kota + Jakarta + Bandung + Surabaya + + + + + {/* Kecamatan dan Kelurahan */} + + + + Kecamatan + + + Pilih Kecamatan + + + + + Kelurahan + + + Pilih Kelurahan + + + + + {/* Tipe Kartu Identitas dan ID */} + + + + Tipe Kartu Identitas + + + Pilih Tipe Kartu Identitas + KTP + SIM + Paspor + + + + + ID Kartu Identitas + + + + + + {/* NPWP */} +
+ + NPWP + + +
+ + {/* Alamat Pengiriman */} +
+ + Alamat Pengiriman + + {alamatPengiriman.map((alamat, index) => ( +
+ handleChangeAlamat(index, e.target.value)} + sx={{ + '& .MuiOutlinedInput-root': { + borderColor: index === 1 ? 'primary.main' : 'default' + } + }} + /> + {alamatPengiriman.length > 1 && ( + handleHapusAlamat(index)} + sx={{ + color: 'error.main', + border: 1, + borderColor: 'error.main', + '&:hover': { + backgroundColor: 'error.light', + borderColor: 'error.main' + } + }} + > + + + )} +
+ ))} +
+ + {/* Tambah Alamat Pengiriman */} +
+ + + Tambah Alamat Pengiriman + +
+ + {/* Rekening Bank */} +
+ + Rekening Bank + + {rekeningBank.map((rekening, index) => ( +
+
+
+ {/* Baris pertama: Bank & Cabang */} + + + handleChangeRekening(index, 'bank', e.target.value)} + > + Pilih Bank + BCA + Mandiri + BNI + BRI + + + + handleChangeRekening(index, 'cabang', e.target.value)} + /> + + + + {/* Baris kedua: Nama Pemilik & Nomor Rekening */} + + + handleChangeRekening(index, 'namaPemilik', e.target.value)} + /> + + + handleChangeRekening(index, 'nomorRekening', e.target.value)} + /> + + +
+ + {/* Tombol hapus di samping, sejajar dengan tengah kedua baris */} + {rekeningBank.length > 1 && ( +
+ handleHapusRekening(index)} + sx={{ + color: 'error.main', + border: 1, + borderColor: 'error.main', + '&:hover': { + backgroundColor: 'error.light', + borderColor: 'error.main' + } + }} + > + + +
+ )} +
+
+ ))} + +
+ + + Tambah Rekening Bank + +
+ + + + + Nomor + + + + + + Tanggal Lahir + + + + + +
+ + Deskripsi + + +
+ + {/* Button Sembunyikan di dalam konten */} +
setShowMore(false)}> + + + Sembunyikan + +
+
+ + )} +
+ +
+ + {/* Sticky Footer */} + +
+ + +
+
+
+ ) +} + +export default AddVendorDrawer diff --git a/src/views/apps/vendor/list/TableFilters.tsx b/src/views/apps/vendor/list/TableFilters.tsx new file mode 100644 index 0000000..c5e4da6 --- /dev/null +++ b/src/views/apps/vendor/list/TableFilters.tsx @@ -0,0 +1,109 @@ +// React Imports +import { useState, useEffect } from 'react' + +// MUI Imports +import CardContent from '@mui/material/CardContent' +import Grid from '@mui/material/Grid2' +import MenuItem from '@mui/material/MenuItem' + +// Type Imports +import type { VendorType } from '@/types/apps/vendorTypes' + +// Component Imports +import CustomTextField from '@core/components/mui/TextField' + +const TableFilters = ({ setData, tableData }: { setData: (data: VendorType[]) => void; tableData?: VendorType[] }) => { + // States + const [company, setCompany] = useState('') + const [payableRange, setPayableRange] = useState('') + const [searchTerm, setSearchTerm] = useState('') + + useEffect(() => { + const filteredData = tableData?.filter(vendor => { + // Filter by company type + if (company && !vendor.company.toLowerCase().includes(company.toLowerCase())) return false + + // Filter by payable range (You Payable) + if (payableRange) { + const payable = vendor.youPayable + switch (payableRange) { + case 'low': + if (payable >= 20000000) return false + break + case 'medium': + if (payable < 20000000 || payable >= 35000000) return false + break + case 'high': + if (payable < 35000000) return false + break + } + } + + // Filter by search term (name, company, email) + if (searchTerm) { + const search = searchTerm.toLowerCase() + const matchesName = vendor.name.toLowerCase().includes(search) + const matchesCompany = vendor.company.toLowerCase().includes(search) + const matchesEmail = vendor.email.toLowerCase().includes(search) + + if (!matchesName && !matchesCompany && !matchesEmail) return false + } + + return true + }) + + setData(filteredData || []) + }, [company, payableRange, searchTerm, tableData, setData]) + + return ( + + + + setCompany(e.target.value)} + slotProps={{ + select: { displayEmpty: true } + }} + > + Pilih Jenis Perusahaan + PT (Perseroan Terbatas) + CV (Commanditaire Vennootschap) + UD (Usaha Dagang) + + + + setPayableRange(e.target.value)} + slotProps={{ + select: { displayEmpty: true } + }} + > + Pilih Rentang Hutang + Rendah (< 20M) + Sedang (20M - 35M) + Tinggi (> 35M) + + + + setSearchTerm(e.target.value)} + /> + + + + ) +} + +export default TableFilters diff --git a/src/views/apps/vendor/list/VendorListCards.tsx b/src/views/apps/vendor/list/VendorListCards.tsx new file mode 100644 index 0000000..d88ffe8 --- /dev/null +++ b/src/views/apps/vendor/list/VendorListCards.tsx @@ -0,0 +1,80 @@ +// MUI Imports +import Grid from '@mui/material/Grid2' + +// Type Imports +import type { UserDataType } from '@components/card-statistics/HorizontalWithSubtitle' + +// Component Imports +import HorizontalWithSubtitle from '@components/card-statistics/HorizontalWithSubtitle' + +// Vars +const data: UserDataType[] = [ + { + title: 'Hutang Anda', + stats: 'Rp 542.340.000', + avatarIcon: 'tabler-credit-card', + avatarColor: 'error', + trend: 'positive', + trendNumber: '12%', + subtitle: 'Total yang harus dibayar' + }, + { + title: 'Piutang Anda', + stats: 'Rp 387.250.000', + avatarIcon: 'tabler-wallet', + avatarColor: 'success', + trend: 'positive', + trendNumber: '8%', + subtitle: 'Total yang harus dibayar vendor' + }, + { + title: 'Pembayaran Diterima', + stats: 'Rp 156.800.000', + avatarIcon: 'tabler-arrow-down-circle', + avatarColor: 'success', + trend: 'positive', + trendNumber: '23%', + subtitle: 'Bulan ini' + }, + { + title: 'Pembayaran Dikirim', + stats: 'Rp 89.450.000', + avatarIcon: 'tabler-arrow-up-circle', + avatarColor: 'warning', + trend: 'negative', + trendNumber: '5%', + subtitle: 'Bulan ini' + }, + { + title: 'Hutang Jatuh Tempo', + stats: 'Rp 67.890.000', + avatarIcon: 'tabler-clock-exclamation', + avatarColor: 'error', + trend: 'negative', + trendNumber: '15%', + subtitle: 'Pembayaran terlambat' + }, + { + title: 'Piutang Tertunda', + stats: 'Rp 134.560.000', + avatarIcon: 'tabler-clock-dollar', + avatarColor: 'info', + trend: 'positive', + trendNumber: '28%', + subtitle: 'Menunggu dari vendor' + } +] + +const VendorListCards = () => { + return ( + + {data.map((item, i) => ( + + + + ))} + + ) +} + +export default VendorListCards diff --git a/src/views/apps/vendor/list/VendorListTable.tsx b/src/views/apps/vendor/list/VendorListTable.tsx new file mode 100644 index 0000000..284b160 --- /dev/null +++ b/src/views/apps/vendor/list/VendorListTable.tsx @@ -0,0 +1,365 @@ +'use client' + +// React Imports +import { useEffect, useState, useMemo } from 'react' + +// Next Imports +import Link from 'next/link' +import { useParams } from 'next/navigation' + +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import Button from '@mui/material/Button' +import Typography from '@mui/material/Typography' +import Chip from '@mui/material/Chip' +import Checkbox from '@mui/material/Checkbox' +import IconButton from '@mui/material/IconButton' +import { styled } from '@mui/material/styles' +import TablePagination from '@mui/material/TablePagination' +import type { TextFieldProps } from '@mui/material/TextField' +import MenuItem from '@mui/material/MenuItem' + +// Third-party Imports +import classnames from 'classnames' +import { rankItem } from '@tanstack/match-sorter-utils' +import { + createColumnHelper, + flexRender, + getCoreRowModel, + useReactTable, + getFilteredRowModel, + getFacetedRowModel, + getFacetedUniqueValues, + getFacetedMinMaxValues, + getPaginationRowModel, + getSortedRowModel +} from '@tanstack/react-table' +import type { ColumnDef, FilterFn } from '@tanstack/react-table' +import type { RankingInfo } from '@tanstack/match-sorter-utils' + +// Type Imports +import type { ThemeColor } from '@core/types' +import type { VendorType } from '@/types/apps/vendorTypes' +import type { Locale } from '@configs/i18n' + +// Component Imports +import TableFilters from './TableFilters' +import AddVendorDrawer from './AddVendorDrawer' +import OptionMenu from '@core/components/option-menu' +import TablePaginationComponent from '@components/TablePaginationComponent' +import CustomTextField from '@core/components/mui/TextField' +import CustomAvatar from '@core/components/mui/Avatar' + +// Util Imports +import { getInitials } from '@/utils/getInitials' +import { getLocalizedUrl } from '@/utils/i18n' + +// Style Imports +import tableStyles from '@core/styles/table.module.css' +import { formatCurrency } from '@/utils/transform' + +declare module '@tanstack/table-core' { + interface FilterFns { + fuzzy: FilterFn + } + interface FilterMeta { + itemRank: RankingInfo + } +} + +type VendorTypeWithAction = VendorType & { + action?: string +} + +// Styled Components +const Icon = styled('i')({}) + +const fuzzyFilter: FilterFn = (row, columnId, value, addMeta) => { + // Rank the item + const itemRank = rankItem(row.getValue(columnId), value) + + // Store the itemRank info + addMeta({ + itemRank + }) + + // Return if the item should be filtered in/out + return itemRank.passed +} + +const DebouncedInput = ({ + value: initialValue, + onChange, + debounce = 500, + ...props +}: { + value: string | number + onChange: (value: string | number) => void + debounce?: number +} & Omit) => { + // States + const [value, setValue] = useState(initialValue) + + useEffect(() => { + setValue(initialValue) + }, [initialValue]) + + useEffect(() => { + const timeout = setTimeout(() => { + onChange(value) + }, debounce) + + return () => clearTimeout(timeout) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [value]) + + return setValue(e.target.value)} /> +} + +// Column Definitions +const columnHelper = createColumnHelper() + +const VendorListTable = ({ tableData }: { tableData?: VendorType[] }) => { + // States + const [addVendorOpen, setAddVendorOpen] = useState(false) + const [rowSelection, setRowSelection] = useState({}) + const [data, setData] = useState(...[tableData]) + const [filteredData, setFilteredData] = useState(data) + const [globalFilter, setGlobalFilter] = useState('') + + // Hooks + const { lang: locale } = useParams() + + const columns = useMemo[]>( + () => [ + { + id: 'select', + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ) + }, + columnHelper.accessor('name', { + header: 'Vendor', + cell: ({ row }) => ( +
+ {getAvatar({ photo: row.original.photo, name: row.original.name })} +
+ + + {row.original.name} + + + {row.original.email} +
+
+ ) + }), + columnHelper.accessor('company', { + header: 'Perusahaan', + cell: ({ row }) => ( +
+ + {row.original.company} +
+ ) + }), + columnHelper.accessor('telephone', { + header: 'Telepon', + cell: ({ row }) => {row.original.telephone} + }), + columnHelper.accessor('youPayable', { + header: () =>
Anda Hutang
, + cell: ({ row }) => ( +
+ + {formatCurrency(row.original.youPayable)} + +
+ ) + }), + columnHelper.accessor('theyPayable', { + header: () =>
Mereka Hutang
, + cell: ({ row }) => ( +
+ + {formatCurrency(row.original.theyPayable)} + +
+ ) + }) + ], + // eslint-disable-next-line react-hooks/exhaustive-deps + [data, filteredData] + ) + + const table = useReactTable({ + data: filteredData as VendorType[], + columns, + filterFns: { + fuzzy: fuzzyFilter + }, + state: { + rowSelection, + globalFilter + }, + initialState: { + pagination: { + pageSize: 10 + } + }, + enableRowSelection: true, + globalFilterFn: fuzzyFilter, + onRowSelectionChange: setRowSelection, + getCoreRowModel: getCoreRowModel(), + onGlobalFilterChange: setGlobalFilter, + getFilteredRowModel: getFilteredRowModel(), + getSortedRowModel: getSortedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + getFacetedMinMaxValues: getFacetedMinMaxValues() + }) + + const getAvatar = (params: Pick) => { + const { photo, name } = params + + if (photo) { + return + } else { + return {getInitials(name as string)} + } + } + + return ( + <> + + + +
+ table.setPageSize(Number(e.target.value))} + className='max-sm:is-full sm:is-[70px]' + > + 10 + 25 + 50 + +
+ setGlobalFilter(String(value))} + placeholder='Cari Vendor' + className='max-sm:is-full' + /> + + +
+
+
+ + + {table.getHeaderGroups().map(headerGroup => ( + + {headerGroup.headers.map(header => ( + + ))} + + ))} + + {table.getFilteredRowModel().rows.length === 0 ? ( + + + + + + ) : ( + + {table + .getRowModel() + .rows.slice(0, table.getState().pagination.pageSize) + .map(row => { + return ( + + {row.getVisibleCells().map(cell => ( + + ))} + + ) + })} + + )} +
+ {header.isPlaceholder ? null : ( + <> +
+ {flexRender(header.column.columnDef.header, header.getContext())} + {{ + asc: , + desc: + }[header.column.getIsSorted() as 'asc' | 'desc'] ?? null} +
+ + )} +
+ Tidak ada data tersedia +
{flexRender(cell.column.columnDef.cell, cell.getContext())}
+
+ { + table.setPageIndex(page) + }} + /> +
+ setAddVendorOpen(!addVendorOpen)} + vendorData={data} + setData={setData} + /> + + ) +} + +export default VendorListTable diff --git a/src/views/apps/vendor/list/index.tsx b/src/views/apps/vendor/list/index.tsx new file mode 100644 index 0000000..482bbf7 --- /dev/null +++ b/src/views/apps/vendor/list/index.tsx @@ -0,0 +1,24 @@ +// MUI Imports +import Grid from '@mui/material/Grid2' + +// Type Imports +import type { VendorType } from '@/types/apps/vendorTypes' + +// Component Imports +import VendorListTable from './VendorListTable' +import VendorListCards from './VendorListCards' + +const VendorList = ({ vendorData }: { vendorData?: VendorType[] }) => { + return ( + + + + + + + + + ) +} + +export default VendorList