efril #6
7
src/app/[lang]/(dashboard)/(private)/apps/vendor/detail/page.tsx
vendored
Normal file
7
src/app/[lang]/(dashboard)/(private)/apps/vendor/detail/page.tsx
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import VendorView from '@/views/apps/vendor/detail'
|
||||
|
||||
const VendorViewPage = async () => {
|
||||
return <VendorView />
|
||||
}
|
||||
|
||||
export default VendorViewPage
|
||||
@ -1,4 +1,4 @@
|
||||
import { VendorType } from '@/types/apps/vendorTypes'
|
||||
import { VendorDebsPayedType, VendorTransactionType, VendorType } from '@/types/apps/vendorTypes'
|
||||
|
||||
export const vendorDummyData: VendorType[] = [
|
||||
{
|
||||
@ -202,3 +202,283 @@ export const vendorDummyData: VendorType[] = [
|
||||
theyPayable: 23600000
|
||||
}
|
||||
]
|
||||
|
||||
// Dummy data untuk VendorDebsPayedType
|
||||
export const vendorDebsPayedData: VendorDebsPayedType[] = [
|
||||
{
|
||||
date: '2024-08-15',
|
||||
transaction: 'Hutang ke PT Supplier Bahan Kimia',
|
||||
reference: 'DEBT-001-2024',
|
||||
total: 4500000
|
||||
},
|
||||
{
|
||||
date: '2024-08-22',
|
||||
transaction: 'Invoice Belum Dibayar #INV-2024-789',
|
||||
reference: 'DEBT-002-2024',
|
||||
total: 2750000
|
||||
},
|
||||
{
|
||||
date: '2024-08-30',
|
||||
transaction: 'Tagihan CV Mitra Sejahtera',
|
||||
reference: 'DEBT-003-2024',
|
||||
total: 1850000
|
||||
},
|
||||
{
|
||||
date: '2024-09-05',
|
||||
transaction: 'Hutang Pembelian Peralatan Kantor',
|
||||
reference: 'DEBT-004-2024',
|
||||
total: 3200000
|
||||
},
|
||||
{
|
||||
date: '2024-09-08',
|
||||
transaction: 'Tagihan Listrik & Utilities Bulan Lalu',
|
||||
reference: 'DEBT-005-2024',
|
||||
total: 950000
|
||||
},
|
||||
{
|
||||
date: '2024-09-10',
|
||||
transaction: 'Hutang ke PT Konstruksi Prima',
|
||||
reference: 'DEBT-006-2024',
|
||||
total: 12500000
|
||||
},
|
||||
{
|
||||
date: '2024-09-12',
|
||||
transaction: 'Invoice Jasa Konsultasi IT',
|
||||
reference: 'DEBT-007-2024',
|
||||
total: 6800000
|
||||
},
|
||||
{
|
||||
date: '2024-09-15',
|
||||
transaction: 'Tagihan Bahan Baku Produksi',
|
||||
reference: 'DEBT-008-2024',
|
||||
total: 8900000
|
||||
},
|
||||
{
|
||||
date: '2024-09-18',
|
||||
transaction: 'Hutang ke Supplier Packaging',
|
||||
reference: 'DEBT-009-2024',
|
||||
total: 2100000
|
||||
},
|
||||
{
|
||||
date: '2024-09-20',
|
||||
transaction: 'Invoice Maintenance Equipment',
|
||||
reference: 'DEBT-010-2024',
|
||||
total: 4300000
|
||||
},
|
||||
{
|
||||
date: '2024-09-22',
|
||||
transaction: 'Tagihan Jasa Logistik & Pengiriman',
|
||||
reference: 'DEBT-011-2024',
|
||||
total: 1650000
|
||||
},
|
||||
{
|
||||
date: '2024-09-25',
|
||||
transaction: 'Hutang Pembelian Software License',
|
||||
reference: 'DEBT-012-2024',
|
||||
total: 5400000
|
||||
},
|
||||
{
|
||||
date: '2024-09-28',
|
||||
transaction: 'Invoice Jasa Cleaning Service',
|
||||
reference: 'DEBT-013-2024',
|
||||
total: 750000
|
||||
},
|
||||
{
|
||||
date: '2024-09-30',
|
||||
transaction: 'Tagihan Sewa Gedung Bulan September',
|
||||
reference: 'DEBT-014-2024',
|
||||
total: 15000000
|
||||
},
|
||||
{
|
||||
date: '2024-10-01',
|
||||
transaction: 'Hutang ke CV Digital Marketing',
|
||||
reference: 'DEBT-015-2024',
|
||||
total: 3800000
|
||||
}
|
||||
]
|
||||
|
||||
export const vendorReceivablesData: VendorDebsPayedType[] = [
|
||||
{
|
||||
date: '2024-08-20',
|
||||
transaction: 'Piutang dari PT Mitra Sejahtera Abadi',
|
||||
reference: 'RCV-001-2024',
|
||||
total: 5500000
|
||||
},
|
||||
{
|
||||
date: '2024-08-25',
|
||||
transaction: 'Invoice Jual Produk #INV-2024-456',
|
||||
reference: 'RCV-002-2024',
|
||||
total: 3250000
|
||||
},
|
||||
{
|
||||
date: '2024-09-02',
|
||||
transaction: 'Tagihan ke CV Berkah Mandiri',
|
||||
reference: 'RCV-003-2024',
|
||||
total: 2800000
|
||||
},
|
||||
{
|
||||
date: '2024-09-05',
|
||||
transaction: 'Piutang Penjualan Barang Jadi',
|
||||
reference: 'RCV-004-2024',
|
||||
total: 4200000
|
||||
},
|
||||
{
|
||||
date: '2024-09-08',
|
||||
transaction: 'Invoice Jasa Konsultasi',
|
||||
reference: 'RCV-005-2024',
|
||||
total: 1750000
|
||||
},
|
||||
{
|
||||
date: '2024-09-10',
|
||||
transaction: 'Tagihan ke PT Digital Solutions',
|
||||
reference: 'RCV-006-2024',
|
||||
total: 8900000
|
||||
},
|
||||
{
|
||||
date: '2024-09-12',
|
||||
transaction: 'Piutang dari Toko Elektronik Prima',
|
||||
reference: 'RCV-007-2024',
|
||||
total: 2450000
|
||||
},
|
||||
{
|
||||
date: '2024-09-15',
|
||||
transaction: 'Invoice Penjualan Software License',
|
||||
reference: 'RCV-008-2024',
|
||||
total: 12500000
|
||||
},
|
||||
{
|
||||
date: '2024-09-18',
|
||||
transaction: 'Tagihan Jasa Maintenance Equipment',
|
||||
reference: 'RCV-009-2024',
|
||||
total: 3600000
|
||||
},
|
||||
{
|
||||
date: '2024-09-20',
|
||||
transaction: 'Piutang dari CV Kreatif Media',
|
||||
reference: 'RCV-010-2024',
|
||||
total: 1950000
|
||||
},
|
||||
{
|
||||
date: '2024-09-22',
|
||||
transaction: 'Invoice Jual Material Konstruksi',
|
||||
reference: 'RCV-011-2024',
|
||||
total: 7200000
|
||||
},
|
||||
{
|
||||
date: '2024-09-25',
|
||||
transaction: 'Tagihan Jasa Pelatihan IT',
|
||||
reference: 'RCV-012-2024',
|
||||
total: 4800000
|
||||
},
|
||||
{
|
||||
date: '2024-09-28',
|
||||
transaction: 'Piutang dari PT Logistik Nusantara',
|
||||
reference: 'RCV-013-2024',
|
||||
total: 5300000
|
||||
},
|
||||
{
|
||||
date: '2024-09-30',
|
||||
transaction: 'Invoice Penjualan Peralatan Kantor',
|
||||
reference: 'RCV-014-2024',
|
||||
total: 2100000
|
||||
},
|
||||
{
|
||||
date: '2024-10-02',
|
||||
transaction: 'Tagihan ke Supplier Packaging',
|
||||
reference: 'RCV-015-2024',
|
||||
total: 3850000
|
||||
}
|
||||
]
|
||||
|
||||
export const vendorTransactionData: VendorTransactionType[] = [
|
||||
{
|
||||
date: '2024-08-15',
|
||||
transaction: 'Pembelian Bahan Baku Produksi',
|
||||
none: 'PO-001-2024',
|
||||
total: 4500000
|
||||
},
|
||||
{
|
||||
date: '2024-08-18',
|
||||
transaction: 'Pembayaran Invoice Supplier',
|
||||
none: 'PAY-001-2024',
|
||||
total: 2750000
|
||||
},
|
||||
{
|
||||
date: '2024-08-22',
|
||||
transaction: 'Penjualan Produk ke Klien',
|
||||
none: 'INV-001-2024',
|
||||
total: 6200000
|
||||
},
|
||||
{
|
||||
date: '2024-08-25',
|
||||
transaction: 'Pembelian Peralatan Kantor',
|
||||
none: 'PO-002-2024',
|
||||
total: 1850000
|
||||
},
|
||||
{
|
||||
date: '2024-08-28',
|
||||
transaction: 'Pembayaran Jasa Konsultasi',
|
||||
none: 'PAY-002-2024',
|
||||
total: 3200000
|
||||
},
|
||||
{
|
||||
date: '2024-09-02',
|
||||
transaction: 'Penjualan Software License',
|
||||
none: 'INV-002-2024',
|
||||
total: 8900000
|
||||
},
|
||||
{
|
||||
date: '2024-09-05',
|
||||
transaction: 'Pembelian Material Konstruksi',
|
||||
none: 'PO-003-2024',
|
||||
total: 12500000
|
||||
},
|
||||
{
|
||||
date: '2024-09-08',
|
||||
transaction: 'Pembayaran Maintenance Equipment',
|
||||
none: 'PAY-003-2024',
|
||||
total: 2450000
|
||||
},
|
||||
{
|
||||
date: '2024-09-12',
|
||||
transaction: 'Penjualan Jasa Pelatihan',
|
||||
none: 'INV-003-2024',
|
||||
total: 4800000
|
||||
},
|
||||
{
|
||||
date: '2024-09-15',
|
||||
transaction: 'Pembelian Bahan Kimia',
|
||||
none: 'PO-004-2024',
|
||||
total: 3600000
|
||||
},
|
||||
{
|
||||
date: '2024-09-18',
|
||||
transaction: 'Pembayaran Sewa Gedung',
|
||||
none: 'PAY-004-2024',
|
||||
total: 15000000
|
||||
},
|
||||
{
|
||||
date: '2024-09-22',
|
||||
transaction: 'Penjualan Peralatan Elektronik',
|
||||
none: 'INV-004-2024',
|
||||
total: 7200000
|
||||
},
|
||||
{
|
||||
date: '2024-09-25',
|
||||
transaction: 'Pembelian Packaging Materials',
|
||||
none: 'PO-005-2024',
|
||||
total: 1950000
|
||||
},
|
||||
{
|
||||
date: '2024-09-28',
|
||||
transaction: 'Pembayaran Jasa Logistik',
|
||||
none: 'PAY-005-2024',
|
||||
total: 2100000
|
||||
},
|
||||
{
|
||||
date: '2024-10-01',
|
||||
transaction: 'Penjualan Produk Digital',
|
||||
none: 'INV-005-2024',
|
||||
total: 5300000
|
||||
}
|
||||
]
|
||||
|
||||
@ -8,3 +8,16 @@ export type VendorType = {
|
||||
youPayable: number
|
||||
theyPayable: number
|
||||
}
|
||||
|
||||
export type VendorDebsPayedType = {
|
||||
date: string
|
||||
transaction: string
|
||||
reference: string
|
||||
total: number
|
||||
}
|
||||
export type VendorTransactionType = {
|
||||
date: string
|
||||
transaction: string
|
||||
none: string
|
||||
total: number
|
||||
}
|
||||
|
||||
20
src/views/apps/vendor/detail/index.tsx
vendored
Normal file
20
src/views/apps/vendor/detail/index.tsx
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import VendorOverview from '@/views/apps/vendor/detail/vendor-overview'
|
||||
import Grid from '@mui/material/Grid2'
|
||||
import VendorContent from './vendor-content'
|
||||
|
||||
const VendorView = async () => {
|
||||
// Vars
|
||||
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid size={{ xs: 12, lg: 4, md: 5 }}>
|
||||
<VendorOverview />
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, lg: 8, md: 7 }}>
|
||||
<VendorContent />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorView
|
||||
157
src/views/apps/vendor/detail/vendor-content/VendorMoneyInOutChart.tsx
vendored
Normal file
157
src/views/apps/vendor/detail/vendor-content/VendorMoneyInOutChart.tsx
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
'use client'
|
||||
|
||||
// Next Imports
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// MUI Imports
|
||||
import Card from '@mui/material/Card'
|
||||
import CardHeader from '@mui/material/CardHeader'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// Third Party Imports
|
||||
import type { ApexOptions } from 'apexcharts'
|
||||
|
||||
// Components Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
|
||||
// Styled Component Imports
|
||||
const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))
|
||||
|
||||
// Styles Imports
|
||||
import './styles.css'
|
||||
|
||||
// Vars
|
||||
const colors = {
|
||||
uangMasuk: '#28C76F',
|
||||
uangKeluar: '#EA5455'
|
||||
}
|
||||
|
||||
const labelColor = 'var(--mui-palette-text-disabled)'
|
||||
const bodyColor = 'var(--mui-palette-text-secondary)'
|
||||
const borderColor = 'var(--mui-palette-divider)'
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'Uang Masuk',
|
||||
type: 'column',
|
||||
data: [850, 920, 780, 1150, 980, 1250, 1080, 950, 1300, 1100, 890, 1400]
|
||||
},
|
||||
{
|
||||
name: 'Uang Keluar',
|
||||
type: 'column',
|
||||
data: [650, 720, 580, 850, 780, 950, 880, 750, 1000, 900, 690, 1100]
|
||||
}
|
||||
]
|
||||
|
||||
const VendorMoneyInOutChart = () => {
|
||||
const options: ApexOptions = {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
stacked: false,
|
||||
toolbar: {
|
||||
show: false
|
||||
},
|
||||
zoom: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
y: {
|
||||
formatter: function (val) {
|
||||
return 'Rp ' + val.toLocaleString('id-ID') + '.000'
|
||||
}
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '60%',
|
||||
borderRadius: 4
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'],
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400
|
||||
}
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 5,
|
||||
max: 1500,
|
||||
min: 0,
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400
|
||||
},
|
||||
formatter(val: number) {
|
||||
return 'Rp ' + val + 'rb'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
markers: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
offsetX: -3,
|
||||
radius: 12
|
||||
},
|
||||
height: 33,
|
||||
offsetY: 10,
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 0
|
||||
},
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400,
|
||||
labels: {
|
||||
colors: bodyColor,
|
||||
useSeriesColors: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
borderColor,
|
||||
strokeDashArray: 6
|
||||
},
|
||||
colors: [colors.uangMasuk, colors.uangKeluar],
|
||||
fill: {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className='mt-5'>
|
||||
<CardHeader title='Keluar Masuk Uang' action={<OptionMenu options={['View More', 'Delete']} />} />
|
||||
<CardContent>
|
||||
<AppReactApexCharts
|
||||
id='keluar-masuk-uang'
|
||||
type='bar'
|
||||
height={360}
|
||||
width='100%'
|
||||
series={series}
|
||||
options={options}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorMoneyInOutChart
|
||||
144
src/views/apps/vendor/detail/vendor-content/VendorSalesChart.tsx
vendored
Normal file
144
src/views/apps/vendor/detail/vendor-content/VendorSalesChart.tsx
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
'use client'
|
||||
|
||||
// Next Imports
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
// MUI Imports
|
||||
import Card from '@mui/material/Card'
|
||||
import CardHeader from '@mui/material/CardHeader'
|
||||
import CardContent from '@mui/material/CardContent'
|
||||
|
||||
// Third Party Imports
|
||||
import type { ApexOptions } from 'apexcharts'
|
||||
|
||||
// Components Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
|
||||
// Styled Component Imports
|
||||
const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts'))
|
||||
|
||||
// Styles Imports
|
||||
import './styles.css'
|
||||
|
||||
// Vars
|
||||
const colors = {
|
||||
penjualan: '#7367F0'
|
||||
}
|
||||
|
||||
const labelColor = 'var(--mui-palette-text-disabled)'
|
||||
const bodyColor = 'var(--mui-palette-text-secondary)'
|
||||
const borderColor = 'var(--mui-palette-divider)'
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'Penjualan',
|
||||
type: 'column',
|
||||
data: [1250, 1420, 980, 1650, 1380, 1750, 1580, 1350, 1900, 1600, 1290, 2100]
|
||||
}
|
||||
]
|
||||
|
||||
const VendorSalesChart = () => {
|
||||
const options: ApexOptions = {
|
||||
chart: {
|
||||
parentHeightOffset: 0,
|
||||
stacked: false,
|
||||
toolbar: {
|
||||
show: false
|
||||
},
|
||||
zoom: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
y: {
|
||||
formatter: function (val) {
|
||||
return 'Rp ' + val.toLocaleString('id-ID') + '.000'
|
||||
}
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '50%',
|
||||
borderRadius: 4
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'],
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400
|
||||
}
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 5,
|
||||
max: 2200,
|
||||
min: 0,
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400
|
||||
},
|
||||
formatter(val: number) {
|
||||
return 'Rp ' + val + 'rb'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
markers: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
offsetX: -3,
|
||||
radius: 12
|
||||
},
|
||||
height: 33,
|
||||
offsetY: 10,
|
||||
itemMargin: {
|
||||
horizontal: 10,
|
||||
vertical: 0
|
||||
},
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans',
|
||||
fontWeight: 400,
|
||||
labels: {
|
||||
colors: bodyColor,
|
||||
useSeriesColors: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
borderColor,
|
||||
strokeDashArray: 6
|
||||
},
|
||||
colors: [colors.penjualan],
|
||||
fill: {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className='mt-5'>
|
||||
<CardHeader title='Penjualan' action={<OptionMenu options={['View More', 'Delete']} />} />
|
||||
<CardContent>
|
||||
<AppReactApexCharts id='penjualan' type='bar' height={360} width='100%' series={series} options={options} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorSalesChart
|
||||
63
src/views/apps/vendor/detail/vendor-content/VendorStatistic.tsx
vendored
Normal file
63
src/views/apps/vendor/detail/vendor-content/VendorStatistic.tsx
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
// MUI Imports
|
||||
import Grid from '@mui/material/Grid2'
|
||||
|
||||
// Types Imports
|
||||
import type { CardStatsHorizontalWithAvatarProps } from '@/types/pages/widgetTypes'
|
||||
|
||||
// Component Imports
|
||||
import CardStatsHorizontalWithAvatar from '@components/card-statistics/HorizontalWithAvatar'
|
||||
|
||||
const data: CardStatsHorizontalWithAvatarProps[] = [
|
||||
{
|
||||
stats: 'Rp 542.340.000',
|
||||
title: 'Hutang Anda',
|
||||
avatarIcon: 'tabler-credit-card',
|
||||
avatarColor: 'error'
|
||||
},
|
||||
{
|
||||
stats: 'Rp 387.250.000',
|
||||
title: 'Piutang Anda',
|
||||
avatarIcon: 'tabler-wallet',
|
||||
avatarColor: 'success'
|
||||
},
|
||||
{
|
||||
stats: 'Rp 156.800.000',
|
||||
title: 'Pembayaran Diterima',
|
||||
avatarIcon: 'tabler-arrow-down-circle',
|
||||
avatarColor: 'success'
|
||||
},
|
||||
{
|
||||
stats: 'Rp 89.450.000',
|
||||
title: 'Pembayaran Dikirim',
|
||||
avatarIcon: 'tabler-arrow-up-circle',
|
||||
avatarColor: 'warning'
|
||||
},
|
||||
{
|
||||
stats: 'Rp 67.890.000',
|
||||
title: 'Hutang Jatuh Tempo',
|
||||
avatarIcon: 'tabler-clock-exclamation',
|
||||
avatarColor: 'error'
|
||||
},
|
||||
{
|
||||
stats: 'Rp 134.560.000',
|
||||
title: 'Piutang Tertunda',
|
||||
avatarIcon: 'tabler-clock-dollar',
|
||||
avatarColor: 'info'
|
||||
}
|
||||
]
|
||||
|
||||
const VendorStatistic = () => {
|
||||
return (
|
||||
data && (
|
||||
<Grid container spacing={6}>
|
||||
{data.map((item, index) => (
|
||||
<Grid size={{ xs: 12, sm: 6, md: 4 }} key={index}>
|
||||
<CardStatsHorizontalWithAvatar {...item} avatarSkin='light' />
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorStatistic
|
||||
21
src/views/apps/vendor/detail/vendor-content/index.tsx
vendored
Normal file
21
src/views/apps/vendor/detail/vendor-content/index.tsx
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import VendorDebsPayed from './vendor-debs-payed-table'
|
||||
import VendorReceivablesPayment from './vendor-receivables-payment-table'
|
||||
import VendorTransaction from './vendor-transaction-table'
|
||||
import VendorMoneyInOutChart from './VendorMoneyInOutChart'
|
||||
import VendorSalesChart from './VendorSalesChart'
|
||||
import VendorStatistic from './VendorStatistic'
|
||||
|
||||
const VendorContent = () => {
|
||||
return (
|
||||
<>
|
||||
<VendorStatistic />
|
||||
<VendorMoneyInOutChart />
|
||||
<VendorSalesChart />
|
||||
<VendorReceivablesPayment />
|
||||
<VendorDebsPayed />
|
||||
<VendorTransaction />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorContent
|
||||
7
src/views/apps/vendor/detail/vendor-content/styles.css
vendored
Normal file
7
src/views/apps/vendor/detail/vendor-content/styles.css
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#keluar-masuk-uang .apexcharts-legend .apexcharts-legend-series {
|
||||
border: 1px solid var(--mui-palette-divider);
|
||||
border-radius: var(--mui-shape-borderRadius);
|
||||
block-size: 83%;
|
||||
padding-block: 4px;
|
||||
padding-inline: 16px;
|
||||
}
|
||||
334
src/views/apps/vendor/detail/vendor-content/vendor-debs-payed-table/VendorDebsPayedTable.tsx
vendored
Normal file
334
src/views/apps/vendor/detail/vendor-content/vendor-debs-payed-table/VendorDebsPayedTable.tsx
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
'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 { Locale } from '@configs/i18n'
|
||||
|
||||
// Component Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
import TablePaginationComponent from '@components/TablePaginationComponent'
|
||||
import CustomTextField from '@core/components/mui/TextField'
|
||||
|
||||
// Util Imports
|
||||
import { getLocalizedUrl } from '@/utils/i18n'
|
||||
|
||||
// Style Imports
|
||||
import tableStyles from '@core/styles/table.module.css'
|
||||
import { formatCurrency } from '@/utils/transform'
|
||||
|
||||
// Type Definition
|
||||
export type VendorDebsPayedType = {
|
||||
date: string
|
||||
transaction: string
|
||||
reference: string
|
||||
total: number
|
||||
}
|
||||
|
||||
declare module '@tanstack/table-core' {
|
||||
interface FilterFns {
|
||||
fuzzy: FilterFn<unknown>
|
||||
}
|
||||
interface FilterMeta {
|
||||
itemRank: RankingInfo
|
||||
}
|
||||
}
|
||||
|
||||
type VendorDebsPayedTypeWithAction = VendorDebsPayedType & {
|
||||
action?: string
|
||||
}
|
||||
|
||||
// Styled Components
|
||||
const Icon = styled('i')({})
|
||||
|
||||
const fuzzyFilter: FilterFn<any> = (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<TextFieldProps, 'onChange'>) => {
|
||||
// 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 <CustomTextField {...props} value={value} onChange={e => setValue(e.target.value)} />
|
||||
}
|
||||
|
||||
// Column Definitions
|
||||
const columnHelper = createColumnHelper<VendorDebsPayedTypeWithAction>()
|
||||
|
||||
const VendorDebsPayedTable = ({ tableData }: { tableData?: VendorDebsPayedType[] }) => {
|
||||
// States
|
||||
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<ColumnDef<VendorDebsPayedTypeWithAction, any>[]>(
|
||||
() => [
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: table.getIsAllRowsSelected(),
|
||||
indeterminate: table.getIsSomeRowsSelected(),
|
||||
onChange: table.getToggleAllRowsSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: row.getIsSelected(),
|
||||
disabled: !row.getCanSelect(),
|
||||
indeterminate: row.getIsSomeSelected(),
|
||||
onChange: row.getToggleSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
)
|
||||
},
|
||||
columnHelper.accessor('date', {
|
||||
header: 'Tanggal',
|
||||
cell: ({ row }) => <Typography color='text.primary'>{row.original.date}</Typography>
|
||||
}),
|
||||
columnHelper.accessor('transaction', {
|
||||
header: 'Keterangan Transaksi',
|
||||
cell: ({ row }) => (
|
||||
<div className='flex flex-col max-w-xs'>
|
||||
<Typography color='text.primary' className='font-medium'>
|
||||
{row.original.transaction}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
}),
|
||||
columnHelper.accessor('reference', {
|
||||
header: 'Referensi',
|
||||
cell: ({ row }) => <Chip label={row.original.reference} color='primary' variant='outlined' size='small' />
|
||||
}),
|
||||
columnHelper.accessor('total', {
|
||||
header: () => <div className='text-right'>Jumlah Hutang</div>,
|
||||
cell: ({ row }) => (
|
||||
<div className='text-right'>
|
||||
<Typography color='error' className='font-medium'>
|
||||
{formatCurrency(row.original.total)}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
],
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[data, filteredData]
|
||||
)
|
||||
|
||||
const table = useReactTable({
|
||||
data: filteredData as VendorDebsPayedType[],
|
||||
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()
|
||||
})
|
||||
|
||||
// Calculate total debt
|
||||
const totalDebt = useMemo(() => {
|
||||
return filteredData?.reduce((sum, item) => sum + item.total, 0) || 0
|
||||
}, [filteredData])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader title='Hutang yang Perlu Anda Bayar' className='pbe-4' />
|
||||
<div className='flex justify-between flex-col items-start md:flex-row md:items-center p-6 border-bs gap-4'>
|
||||
<CustomTextField
|
||||
select
|
||||
value={table.getState().pagination.pageSize}
|
||||
onChange={e => table.setPageSize(Number(e.target.value))}
|
||||
className='max-sm:is-full sm:is-[70px]'
|
||||
>
|
||||
<MenuItem value='10'>10</MenuItem>
|
||||
<MenuItem value='25'>25</MenuItem>
|
||||
<MenuItem value='50'>50</MenuItem>
|
||||
</CustomTextField>
|
||||
<div className='flex flex-col sm:flex-row max-sm:is-full items-start sm:items-center gap-4'>
|
||||
<DebouncedInput
|
||||
value={globalFilter ?? ''}
|
||||
onChange={value => setGlobalFilter(String(value))}
|
||||
placeholder='Cari Hutang'
|
||||
className='max-sm:is-full'
|
||||
/>
|
||||
<Button
|
||||
color='secondary'
|
||||
variant='tonal'
|
||||
startIcon={<i className='tabler-upload' />}
|
||||
className='max-sm:is-full'
|
||||
>
|
||||
Ekspor
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='overflow-x-auto'>
|
||||
<table className={tableStyles.table}>
|
||||
<thead>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => (
|
||||
<th key={header.id}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<>
|
||||
<div
|
||||
className={classnames({
|
||||
'flex items-center': header.column.getIsSorted(),
|
||||
'cursor-pointer select-none': header.column.getCanSort()
|
||||
})}
|
||||
onClick={header.column.getToggleSortingHandler()}
|
||||
>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{{
|
||||
asc: <i className='tabler-chevron-up text-xl' />,
|
||||
desc: <i className='tabler-chevron-down text-xl' />
|
||||
}[header.column.getIsSorted() as 'asc' | 'desc'] ?? null}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
{table.getFilteredRowModel().rows.length === 0 ? (
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colSpan={table.getVisibleFlatColumns().length} className='text-center'>
|
||||
<div className='flex flex-col items-center gap-2 py-8'>
|
||||
<Icon className='tabler-database-off text-4xl text-gray-400' />
|
||||
<Typography variant='h6' color='text.secondary'>
|
||||
Tidak ada hutang ditemukan
|
||||
</Typography>
|
||||
<Typography variant='body2' color='text.disabled'>
|
||||
Cobalah mengubah filter pencarian
|
||||
</Typography>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
) : (
|
||||
<tbody>
|
||||
{table
|
||||
.getRowModel()
|
||||
.rows.slice(0, table.getState().pagination.pageSize)
|
||||
.map(row => {
|
||||
return (
|
||||
<tr key={row.id} className={classnames({ selected: row.getIsSelected() })}>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
|
||||
))}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
)}
|
||||
</table>
|
||||
</div>
|
||||
<TablePaginationComponent
|
||||
pageIndex={table.getState().pagination.pageIndex}
|
||||
pageSize={table.getState().pagination.pageSize}
|
||||
totalCount={table.getFilteredRowModel().rows.length}
|
||||
onPageChange={(_, page) => {
|
||||
table.setPageIndex(page)
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorDebsPayedTable
|
||||
21
src/views/apps/vendor/detail/vendor-content/vendor-debs-payed-table/index.tsx
vendored
Normal file
21
src/views/apps/vendor/detail/vendor-content/vendor-debs-payed-table/index.tsx
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// MUI Imports
|
||||
import Grid from '@mui/material/Grid2'
|
||||
|
||||
// Type Imports
|
||||
import type { VendorType } from '@/types/apps/vendorTypes'
|
||||
|
||||
// Component Imports
|
||||
import VendorDebsPayedTable from './VendorDebsPayedTable'
|
||||
import { vendorDebsPayedData } from '@/data/dummy/vendor'
|
||||
|
||||
const VendorDebsPayed = () => {
|
||||
return (
|
||||
<Grid container spacing={6} className='mt-5'>
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<VendorDebsPayedTable tableData={vendorDebsPayedData} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorDebsPayed
|
||||
@ -0,0 +1,327 @@
|
||||
'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 { Locale } from '@configs/i18n'
|
||||
|
||||
// Component Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
import TablePaginationComponent from '@components/TablePaginationComponent'
|
||||
import CustomTextField from '@core/components/mui/TextField'
|
||||
|
||||
// Util Imports
|
||||
import { getLocalizedUrl } from '@/utils/i18n'
|
||||
|
||||
// Style Imports
|
||||
import tableStyles from '@core/styles/table.module.css'
|
||||
import { formatCurrency } from '@/utils/transform'
|
||||
import { VendorDebsPayedType } from '../vendor-debs-payed-table/VendorDebsPayedTable'
|
||||
|
||||
declare module '@tanstack/table-core' {
|
||||
interface FilterFns {
|
||||
fuzzy: FilterFn<unknown>
|
||||
}
|
||||
interface FilterMeta {
|
||||
itemRank: RankingInfo
|
||||
}
|
||||
}
|
||||
|
||||
type VendorDebsPayedTypeWithAction = VendorDebsPayedType & {
|
||||
action?: string
|
||||
}
|
||||
|
||||
// Styled Components
|
||||
const Icon = styled('i')({})
|
||||
|
||||
const fuzzyFilter: FilterFn<any> = (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<TextFieldProps, 'onChange'>) => {
|
||||
// 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 <CustomTextField {...props} value={value} onChange={e => setValue(e.target.value)} />
|
||||
}
|
||||
|
||||
// Column Definitions
|
||||
const columnHelper = createColumnHelper<VendorDebsPayedTypeWithAction>()
|
||||
|
||||
const VendorReceivablesPaymentTable = ({ tableData }: { tableData?: VendorDebsPayedType[] }) => {
|
||||
// States
|
||||
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<ColumnDef<VendorDebsPayedTypeWithAction, any>[]>(
|
||||
() => [
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: table.getIsAllRowsSelected(),
|
||||
indeterminate: table.getIsSomeRowsSelected(),
|
||||
onChange: table.getToggleAllRowsSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: row.getIsSelected(),
|
||||
disabled: !row.getCanSelect(),
|
||||
indeterminate: row.getIsSomeSelected(),
|
||||
onChange: row.getToggleSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
)
|
||||
},
|
||||
columnHelper.accessor('date', {
|
||||
header: 'Tanggal',
|
||||
cell: ({ row }) => <Typography color='text.primary'>{row.original.date}</Typography>
|
||||
}),
|
||||
columnHelper.accessor('transaction', {
|
||||
header: 'Keterangan Transaksi',
|
||||
cell: ({ row }) => (
|
||||
<div className='flex flex-col max-w-xs'>
|
||||
<Typography color='text.primary' className='font-medium'>
|
||||
{row.original.transaction}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
}),
|
||||
columnHelper.accessor('reference', {
|
||||
header: 'Referensi',
|
||||
cell: ({ row }) => <Chip label={row.original.reference} color='primary' variant='outlined' size='small' />
|
||||
}),
|
||||
columnHelper.accessor('total', {
|
||||
header: () => <div className='text-right'>Jumlah Hutang</div>,
|
||||
cell: ({ row }) => (
|
||||
<div className='text-right'>
|
||||
<Typography color='error' className='font-medium'>
|
||||
{formatCurrency(row.original.total)}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
],
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[data, filteredData]
|
||||
)
|
||||
|
||||
const table = useReactTable({
|
||||
data: filteredData as VendorDebsPayedType[],
|
||||
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()
|
||||
})
|
||||
|
||||
// Calculate total debt
|
||||
const totalDebt = useMemo(() => {
|
||||
return filteredData?.reduce((sum, item) => sum + item.total, 0) || 0
|
||||
}, [filteredData])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader title='Piutang menunggu pembayaran' className='pbe-4' />
|
||||
<div className='flex justify-between flex-col items-start md:flex-row md:items-center p-6 border-bs gap-4'>
|
||||
<CustomTextField
|
||||
select
|
||||
value={table.getState().pagination.pageSize}
|
||||
onChange={e => table.setPageSize(Number(e.target.value))}
|
||||
className='max-sm:is-full sm:is-[70px]'
|
||||
>
|
||||
<MenuItem value='10'>10</MenuItem>
|
||||
<MenuItem value='25'>25</MenuItem>
|
||||
<MenuItem value='50'>50</MenuItem>
|
||||
</CustomTextField>
|
||||
<div className='flex flex-col sm:flex-row max-sm:is-full items-start sm:items-center gap-4'>
|
||||
<DebouncedInput
|
||||
value={globalFilter ?? ''}
|
||||
onChange={value => setGlobalFilter(String(value))}
|
||||
placeholder='Cari'
|
||||
className='max-sm:is-full'
|
||||
/>
|
||||
<Button
|
||||
color='secondary'
|
||||
variant='tonal'
|
||||
startIcon={<i className='tabler-upload' />}
|
||||
className='max-sm:is-full'
|
||||
>
|
||||
Ekspor
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='overflow-x-auto'>
|
||||
<table className={tableStyles.table}>
|
||||
<thead>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => (
|
||||
<th key={header.id}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<>
|
||||
<div
|
||||
className={classnames({
|
||||
'flex items-center': header.column.getIsSorted(),
|
||||
'cursor-pointer select-none': header.column.getCanSort()
|
||||
})}
|
||||
onClick={header.column.getToggleSortingHandler()}
|
||||
>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{{
|
||||
asc: <i className='tabler-chevron-up text-xl' />,
|
||||
desc: <i className='tabler-chevron-down text-xl' />
|
||||
}[header.column.getIsSorted() as 'asc' | 'desc'] ?? null}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
{table.getFilteredRowModel().rows.length === 0 ? (
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colSpan={table.getVisibleFlatColumns().length} className='text-center'>
|
||||
<div className='flex flex-col items-center gap-2 py-8'>
|
||||
<Icon className='tabler-database-off text-4xl text-gray-400' />
|
||||
<Typography variant='h6' color='text.secondary'>
|
||||
Tidak ada hutang ditemukan
|
||||
</Typography>
|
||||
<Typography variant='body2' color='text.disabled'>
|
||||
Cobalah mengubah filter pencarian
|
||||
</Typography>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
) : (
|
||||
<tbody>
|
||||
{table
|
||||
.getRowModel()
|
||||
.rows.slice(0, table.getState().pagination.pageSize)
|
||||
.map(row => {
|
||||
return (
|
||||
<tr key={row.id} className={classnames({ selected: row.getIsSelected() })}>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
|
||||
))}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
)}
|
||||
</table>
|
||||
</div>
|
||||
<TablePaginationComponent
|
||||
pageIndex={table.getState().pagination.pageIndex}
|
||||
pageSize={table.getState().pagination.pageSize}
|
||||
totalCount={table.getFilteredRowModel().rows.length}
|
||||
onPageChange={(_, page) => {
|
||||
table.setPageIndex(page)
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorReceivablesPaymentTable
|
||||
18
src/views/apps/vendor/detail/vendor-content/vendor-receivables-payment-table/index.tsx
vendored
Normal file
18
src/views/apps/vendor/detail/vendor-content/vendor-receivables-payment-table/index.tsx
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// MUI Imports
|
||||
import Grid from '@mui/material/Grid2'
|
||||
|
||||
// Component Imports
|
||||
import VendorReceivablesPaymentTable from './VendorReceivablesPaymentTable'
|
||||
import { vendorReceivablesData } from '@/data/dummy/vendor'
|
||||
|
||||
const VendorReceivablesPayment = () => {
|
||||
return (
|
||||
<Grid container spacing={6} className='mt-5'>
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<VendorReceivablesPaymentTable tableData={vendorReceivablesData} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorReceivablesPayment
|
||||
355
src/views/apps/vendor/detail/vendor-content/vendor-transaction-table/VendorTransactionTable.tsx
vendored
Normal file
355
src/views/apps/vendor/detail/vendor-content/vendor-transaction-table/VendorTransactionTable.tsx
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
'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 { Locale } from '@configs/i18n'
|
||||
|
||||
// Component Imports
|
||||
import OptionMenu from '@core/components/option-menu'
|
||||
import TablePaginationComponent from '@components/TablePaginationComponent'
|
||||
import CustomTextField from '@core/components/mui/TextField'
|
||||
|
||||
// Util Imports
|
||||
import { getLocalizedUrl } from '@/utils/i18n'
|
||||
|
||||
// Style Imports
|
||||
import tableStyles from '@core/styles/table.module.css'
|
||||
import { formatCurrency } from '@/utils/transform'
|
||||
|
||||
// Type Definition
|
||||
export type VendorTransactionType = {
|
||||
date: string
|
||||
transaction: string
|
||||
none: string
|
||||
total: number
|
||||
}
|
||||
|
||||
declare module '@tanstack/table-core' {
|
||||
interface FilterFns {
|
||||
fuzzy: FilterFn<unknown>
|
||||
}
|
||||
interface FilterMeta {
|
||||
itemRank: RankingInfo
|
||||
}
|
||||
}
|
||||
|
||||
type VendorTransactionTypeWithAction = VendorTransactionType & {
|
||||
action?: string
|
||||
}
|
||||
|
||||
// Styled Components
|
||||
const Icon = styled('i')({})
|
||||
|
||||
const fuzzyFilter: FilterFn<any> = (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<TextFieldProps, 'onChange'>) => {
|
||||
// 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 <CustomTextField {...props} value={value} onChange={e => setValue(e.target.value)} />
|
||||
}
|
||||
|
||||
// Format date helper
|
||||
const formatDate = (dateString: string): string => {
|
||||
return new Date(dateString).toLocaleDateString('id-ID', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
}
|
||||
|
||||
// Column Definitions
|
||||
const columnHelper = createColumnHelper<VendorTransactionTypeWithAction>()
|
||||
|
||||
const VendorTransactionTable = ({ tableData }: { tableData?: VendorTransactionType[] }) => {
|
||||
// States
|
||||
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<ColumnDef<VendorTransactionTypeWithAction, any>[]>(
|
||||
() => [
|
||||
{
|
||||
id: 'select',
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: table.getIsAllRowsSelected(),
|
||||
indeterminate: table.getIsSomeRowsSelected(),
|
||||
onChange: table.getToggleAllRowsSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<Checkbox
|
||||
{...{
|
||||
checked: row.getIsSelected(),
|
||||
disabled: !row.getCanSelect(),
|
||||
indeterminate: row.getIsSomeSelected(),
|
||||
onChange: row.getToggleSelectedHandler()
|
||||
}}
|
||||
/>
|
||||
)
|
||||
},
|
||||
columnHelper.accessor('date', {
|
||||
header: 'Tanggal',
|
||||
cell: ({ row }) => <Typography color='text.primary'>{row.original.date}</Typography>
|
||||
}),
|
||||
columnHelper.accessor('transaction', {
|
||||
header: 'Keterangan Transaksi',
|
||||
cell: ({ row }) => (
|
||||
<div className='flex flex-col max-w-xs'>
|
||||
<Typography color='text.primary' className='font-medium'>
|
||||
{row.original.transaction}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
}),
|
||||
columnHelper.accessor('none', {
|
||||
header: 'Referensi',
|
||||
cell: ({ row }) => <Chip label={row.original.none} color='primary' variant='outlined' size='small' />
|
||||
}),
|
||||
columnHelper.accessor('total', {
|
||||
header: () => <div className='text-right'>Jumlah</div>,
|
||||
cell: ({ row }) => (
|
||||
<div className='text-right'>
|
||||
<Typography color='text.primary' className='font-medium'>
|
||||
{formatCurrency(row.original.total)}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
],
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[data, filteredData]
|
||||
)
|
||||
|
||||
const table = useReactTable({
|
||||
data: filteredData as VendorTransactionType[],
|
||||
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()
|
||||
})
|
||||
|
||||
// Calculate total amount
|
||||
const totalAmount = useMemo(() => {
|
||||
return filteredData?.reduce((sum, item) => sum + item.total, 0) || 0
|
||||
}, [filteredData])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardHeader
|
||||
title='Riwayat Transaksi Vendor'
|
||||
className='pbe-4'
|
||||
action={
|
||||
<Chip
|
||||
label={`Total: ${formatCurrency(totalAmount)}`}
|
||||
color='primary'
|
||||
variant='filled'
|
||||
size='medium'
|
||||
className='font-semibold'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<div className='flex justify-between flex-col items-start md:flex-row md:items-center p-6 border-bs gap-4'>
|
||||
<CustomTextField
|
||||
select
|
||||
value={table.getState().pagination.pageSize}
|
||||
onChange={e => table.setPageSize(Number(e.target.value))}
|
||||
className='max-sm:is-full sm:is-[70px]'
|
||||
>
|
||||
<MenuItem value='10'>10</MenuItem>
|
||||
<MenuItem value='25'>25</MenuItem>
|
||||
<MenuItem value='50'>50</MenuItem>
|
||||
</CustomTextField>
|
||||
<div className='flex flex-col sm:flex-row max-sm:is-full items-start sm:items-center gap-4'>
|
||||
<DebouncedInput
|
||||
value={globalFilter ?? ''}
|
||||
onChange={value => setGlobalFilter(String(value))}
|
||||
placeholder='Cari Transaksi'
|
||||
className='max-sm:is-full'
|
||||
/>
|
||||
<Button
|
||||
color='secondary'
|
||||
variant='tonal'
|
||||
startIcon={<i className='tabler-upload' />}
|
||||
className='max-sm:is-full'
|
||||
>
|
||||
Ekspor
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='overflow-x-auto'>
|
||||
<table className={tableStyles.table}>
|
||||
<thead>
|
||||
{table.getHeaderGroups().map(headerGroup => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map(header => (
|
||||
<th key={header.id}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<>
|
||||
<div
|
||||
className={classnames({
|
||||
'flex items-center': header.column.getIsSorted(),
|
||||
'cursor-pointer select-none': header.column.getCanSort()
|
||||
})}
|
||||
onClick={header.column.getToggleSortingHandler()}
|
||||
>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{{
|
||||
asc: <i className='tabler-chevron-up text-xl' />,
|
||||
desc: <i className='tabler-chevron-down text-xl' />
|
||||
}[header.column.getIsSorted() as 'asc' | 'desc'] ?? null}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
{table.getFilteredRowModel().rows.length === 0 ? (
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colSpan={table.getVisibleFlatColumns().length} className='text-center'>
|
||||
<div className='flex flex-col items-center gap-2 py-8'>
|
||||
<Icon className='tabler-database-off text-4xl text-gray-400' />
|
||||
<Typography variant='h6' color='text.secondary'>
|
||||
Tidak ada transaksi ditemukan
|
||||
</Typography>
|
||||
<Typography variant='body2' color='text.disabled'>
|
||||
Cobalah mengubah filter pencarian
|
||||
</Typography>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
) : (
|
||||
<tbody>
|
||||
{table
|
||||
.getRowModel()
|
||||
.rows.slice(0, table.getState().pagination.pageSize)
|
||||
.map(row => {
|
||||
return (
|
||||
<tr key={row.id} className={classnames({ selected: row.getIsSelected() })}>
|
||||
{row.getVisibleCells().map(cell => (
|
||||
<td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
|
||||
))}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
)}
|
||||
</table>
|
||||
</div>
|
||||
<TablePaginationComponent
|
||||
pageIndex={table.getState().pagination.pageIndex}
|
||||
pageSize={table.getState().pagination.pageSize}
|
||||
totalCount={table.getFilteredRowModel().rows.length}
|
||||
onPageChange={(_, page) => {
|
||||
table.setPageIndex(page)
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorTransactionTable
|
||||
18
src/views/apps/vendor/detail/vendor-content/vendor-transaction-table/index.tsx
vendored
Normal file
18
src/views/apps/vendor/detail/vendor-content/vendor-transaction-table/index.tsx
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// MUI Imports
|
||||
import Grid from '@mui/material/Grid2'
|
||||
|
||||
// Component Imports
|
||||
import { vendorTransactionData } from '@/data/dummy/vendor'
|
||||
import VendorTransactionTable from './VendorTransactionTable'
|
||||
|
||||
const VendorTransaction = () => {
|
||||
return (
|
||||
<Grid container spacing={6} className='mt-5'>
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<VendorTransactionTable tableData={vendorTransactionData} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorTransaction
|
||||
134
src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx
vendored
Normal file
134
src/views/apps/vendor/detail/vendor-overview/VendorDetails.tsx
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
// 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'
|
||||
|
||||
// Vars
|
||||
const userData = {
|
||||
firstName: 'Wadi Adika Adrian',
|
||||
lastName: 'Firgantoro',
|
||||
userName: '@wadiAdika',
|
||||
perusahaan: 'Yayasan Pertiwi Tb',
|
||||
email: 'labuh87@napitupu',
|
||||
status: 'active',
|
||||
role: 'Vendor',
|
||||
telepon: '622301190560',
|
||||
alamatPenagihan: 'Gg. Sentot Alibasa 381, Cimahi 66726 Sulbar',
|
||||
akunHutang: '2-20100 Hutang U',
|
||||
akunPiutang: '',
|
||||
kenaPajak: 'Kena Pajak'
|
||||
}
|
||||
|
||||
const VendorDetails = () => {
|
||||
// Vars
|
||||
const buttonProps = (children: string, color: ThemeColor, variant: ButtonProps['variant']): ButtonProps => ({
|
||||
children,
|
||||
color,
|
||||
variant
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<CardContent className='flex flex-col pbs-12 gap-6'>
|
||||
<div className='flex flex-col gap-6'>
|
||||
<div className='flex items-center justify-center flex-col gap-4'>
|
||||
<div className='flex flex-col items-center gap-4'>
|
||||
<CustomAvatar alt='user-profile' src='/images/avatars/1.png' variant='rounded' size={120} />
|
||||
<Typography variant='h5'>{`${userData.firstName} ${userData.lastName}`}</Typography>
|
||||
</div>
|
||||
<Chip label='Vendor' color='primary' size='small' variant='tonal' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Detail Kontak Section */}
|
||||
<div>
|
||||
<Typography variant='h5'>Detail Kontak</Typography>
|
||||
<Divider className='mlb-4' />
|
||||
<div className='flex flex-col gap-2'>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Nama:
|
||||
</Typography>
|
||||
<Typography>{`${userData.firstName} ${userData.lastName}`}</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Perusahaan:
|
||||
</Typography>
|
||||
<Typography>{userData.perusahaan}</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Email:
|
||||
</Typography>
|
||||
<Typography color='primary' sx={{ textDecoration: 'none', cursor: 'pointer' }}>
|
||||
{userData.email}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Telepon:
|
||||
</Typography>
|
||||
<Typography color='primary' sx={{ textDecoration: 'none', cursor: 'pointer' }}>
|
||||
{userData.telepon}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Alamat Penagihan:
|
||||
</Typography>
|
||||
<Typography color='primary' sx={{ textDecoration: 'none', cursor: 'pointer' }}>
|
||||
{userData.alamatPenagihan}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pemetaan Akun Section */}
|
||||
<div>
|
||||
<Typography variant='h5'>Pemetaan Akun</Typography>
|
||||
<Divider className='mlb-4' />
|
||||
<div className='flex flex-col gap-2'>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Akun Hutang:
|
||||
</Typography>
|
||||
<Typography color='primary' sx={{ textDecoration: 'none', cursor: 'pointer' }}>
|
||||
{userData.akunHutang}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Akun Piutang:
|
||||
</Typography>
|
||||
<Typography color='text.secondary'>{userData.akunPiutang || '-'}</Typography>
|
||||
</div>
|
||||
<div className='flex items-center flex-wrap gap-x-1.5'>
|
||||
<Typography className='font-medium' color='text.primary'>
|
||||
Kena Pajak:
|
||||
</Typography>
|
||||
<Typography color='text.primary'>{userData.kenaPajak}</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorDetails
|
||||
17
src/views/apps/vendor/detail/vendor-overview/index.tsx
vendored
Normal file
17
src/views/apps/vendor/detail/vendor-overview/index.tsx
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// MUI Imports
|
||||
import Grid from '@mui/material/Grid2'
|
||||
|
||||
// Component Imports
|
||||
import VendorDetails from './VendorDetails'
|
||||
|
||||
const VendorOverview = () => {
|
||||
return (
|
||||
<Grid container spacing={6}>
|
||||
<Grid size={{ xs: 12 }}>
|
||||
<VendorDetails />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
export default VendorOverview
|
||||
@ -161,7 +161,7 @@ const VendorListTable = ({ tableData }: { tableData?: VendorType[] }) => {
|
||||
<div className='flex items-center gap-4'>
|
||||
{getAvatar({ photo: row.original.photo, name: row.original.name })}
|
||||
<div className='flex flex-col'>
|
||||
<Link href={getLocalizedUrl(`/apps/vendor/view/${row.original.id}`, locale as Locale)}>
|
||||
<Link href={getLocalizedUrl(`/apps/vendor/detail`, locale as Locale)}>
|
||||
<Typography color='primary' className='font-medium cursor-pointer hover:underline'>
|
||||
{row.original.name}
|
||||
</Typography>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user