mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 23:05:46 +00:00
feat(FE): Add skeleton components for closing pages
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import DataStateSkeleton from '@/components/helper/skeleton/DataStateSkeleton';
|
||||
import Table from '@/components/Table';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const ClosingTabSkeleton = <T extends object>({
|
||||
columns,
|
||||
icon,
|
||||
title,
|
||||
subtitle,
|
||||
}: {
|
||||
columns: ColumnDef<T>[];
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
}) => {
|
||||
return (
|
||||
<div className='relative size-full'>
|
||||
<Table
|
||||
data={[]}
|
||||
columns={columns as ColumnDef<T>[]}
|
||||
isLoading={true}
|
||||
className={{
|
||||
skeletonCellClassName: 'animate-none w-full h-5 bg-base-content/4',
|
||||
headerColumnClassName: 'whitespace-nowrap',
|
||||
containerClassName: 'mb-0 overflow-hidden',
|
||||
tableWrapperClassName: 'overflow-hidden',
|
||||
}}
|
||||
/>
|
||||
<div className='absolute inset-0 flex items-center justify-center'>
|
||||
<DataStateSkeleton icon={icon} title={title} description={subtitle} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClosingTabSkeleton;
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import Card from '@/components/Card';
|
||||
import DataStateSkeleton from '@/components/helper/skeleton/DataStateSkeleton';
|
||||
|
||||
const FinanceClosingSkeleton = ({
|
||||
title = 'Data Keuangan Belum Tersedia',
|
||||
subtitle = 'Tidak ada data keuangan untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
return (
|
||||
<Card
|
||||
variant='bordered'
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-8',
|
||||
}}
|
||||
>
|
||||
<div className='flex items-center justify-center p-8'>
|
||||
<DataStateSkeleton
|
||||
icon={
|
||||
<Icon
|
||||
icon={iconName}
|
||||
className='text-white'
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
}
|
||||
title={title}
|
||||
description={subtitle}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default FinanceClosingSkeleton;
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import ClosingTabSkeleton from './ClosingTabSkeleton';
|
||||
import { BaseExpeditionCost } from '@/types/api/closing';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const HppExpeditionClosingSkeleton = ({
|
||||
columns,
|
||||
title = 'Data HPP Ekspedisi Belum Tersedia',
|
||||
subtitle = 'Tidak ada data HPP ekspedisi untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
columns?: ColumnDef<BaseExpeditionCost>[];
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
const defaultColumns: ColumnDef<BaseExpeditionCost>[] = [
|
||||
{
|
||||
id: 'id',
|
||||
header: 'No',
|
||||
},
|
||||
{
|
||||
id: 'expedition_vendor_name',
|
||||
header: 'Nama Ekspedisi',
|
||||
},
|
||||
{
|
||||
id: 'hpp_amount',
|
||||
header: 'HPP Ekspedisi',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ClosingTabSkeleton<BaseExpeditionCost>
|
||||
columns={columns || defaultColumns}
|
||||
icon={
|
||||
<Icon icon={iconName} className='text-white' width={20} height={20} />
|
||||
}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default HppExpeditionClosingSkeleton;
|
||||
@@ -0,0 +1,72 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import ClosingTabSkeleton from './ClosingTabSkeleton';
|
||||
import { Overhead } from '@/types/api/closing';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const OverheadClosingSkeleton = ({
|
||||
columns,
|
||||
title = 'Data Overhead Belum Tersedia',
|
||||
subtitle = 'Tidak ada data overhead untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
columns?: ColumnDef<Overhead>[];
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
const defaultColumns: ColumnDef<Overhead>[] = [
|
||||
{
|
||||
id: 'name',
|
||||
header: 'Nama Overhead',
|
||||
},
|
||||
{
|
||||
id: 'budget_quantity',
|
||||
header: 'Budget Pengajuan - Jumlah',
|
||||
},
|
||||
{
|
||||
id: 'budget_unit_price',
|
||||
header: 'Budget Pengajuan - Harga Satuan',
|
||||
},
|
||||
{
|
||||
id: 'budget_total_amount',
|
||||
header: 'Budget Pengajuan - Total',
|
||||
},
|
||||
{
|
||||
id: 'actual_quantity',
|
||||
header: 'Realisasi - Jumlah',
|
||||
},
|
||||
{
|
||||
id: 'actual_unit_price',
|
||||
header: 'Realisasi - Harga Satuan',
|
||||
},
|
||||
{
|
||||
id: 'actual_total_amount',
|
||||
header: 'Realisasi - Total',
|
||||
},
|
||||
{
|
||||
id: 'difference_quantity',
|
||||
header: 'Selisih - Jumlah',
|
||||
},
|
||||
{
|
||||
id: 'difference_unit_price',
|
||||
header: 'Selisih - Harga Satuan',
|
||||
},
|
||||
{
|
||||
id: 'difference_total_amount',
|
||||
header: 'Selisih - Total',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ClosingTabSkeleton<Overhead>
|
||||
columns={columns || defaultColumns}
|
||||
icon={
|
||||
<Icon icon={iconName} className='text-white' width={20} height={20} />
|
||||
}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default OverheadClosingSkeleton;
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import DataStateSkeleton from '@/components/helper/skeleton/DataStateSkeleton';
|
||||
|
||||
const ProductionDataClosingSkeleton = ({
|
||||
title = 'Data Produksi Belum Tersedia',
|
||||
subtitle = 'Tidak ada data produksi untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
return (
|
||||
<div className='w-full rounded-xl p-8 shadow-sm'>
|
||||
<div className='flex items-center justify-center p-12'>
|
||||
<DataStateSkeleton
|
||||
icon={
|
||||
<Icon
|
||||
icon={iconName}
|
||||
className='text-white'
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
}
|
||||
title={title}
|
||||
description={subtitle}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductionDataClosingSkeleton;
|
||||
@@ -0,0 +1,84 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import ClosingTabSkeleton from './ClosingTabSkeleton';
|
||||
import { BaseSales } from '@/types/api/closing';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const SalesClosingSkeleton = ({
|
||||
columns,
|
||||
title = 'Data Penjualan Belum Tersedia',
|
||||
subtitle = 'Tidak ada data penjualan untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
columns?: ColumnDef<BaseSales>[];
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
const defaultColumns: ColumnDef<BaseSales>[] = [
|
||||
{
|
||||
id: 'realization_date',
|
||||
header: 'Tanggal Realisasi',
|
||||
},
|
||||
{
|
||||
id: 'age',
|
||||
header: 'Umur',
|
||||
},
|
||||
{
|
||||
id: 'do_number',
|
||||
header: 'No. DO',
|
||||
},
|
||||
{
|
||||
id: 'product',
|
||||
header: 'Produk',
|
||||
},
|
||||
{
|
||||
id: 'customer',
|
||||
header: 'Customer',
|
||||
},
|
||||
{
|
||||
id: 'qty',
|
||||
header: 'Kuantitas',
|
||||
},
|
||||
{
|
||||
id: 'weight',
|
||||
header: 'Kg',
|
||||
},
|
||||
{
|
||||
id: 'avg_weight',
|
||||
header: 'AVG (Kg)',
|
||||
},
|
||||
{
|
||||
id: 'sales_price',
|
||||
header: 'Harga Sales (Rp)',
|
||||
},
|
||||
{
|
||||
id: 'total_sales_price',
|
||||
header: 'Total Sales (Rp)',
|
||||
},
|
||||
{
|
||||
id: 'actual_price',
|
||||
header: 'Harga Act (Rp)',
|
||||
},
|
||||
{
|
||||
id: 'total_actual_price',
|
||||
header: 'Total Act (Rp)',
|
||||
},
|
||||
{
|
||||
id: 'kandang',
|
||||
header: 'Kandang',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ClosingTabSkeleton<BaseSales>
|
||||
columns={columns || defaultColumns}
|
||||
icon={
|
||||
<Icon icon={iconName} className='text-white' width={20} height={20} />
|
||||
}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default SalesClosingSkeleton;
|
||||
@@ -0,0 +1,72 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import ClosingTabSkeleton from './ClosingTabSkeleton';
|
||||
import { RowSapronakCalculation } from '@/types/api/closing';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const SapronakCalculationClosingSkeleton = ({
|
||||
columns,
|
||||
title = 'Data Perhitungan Sapronak Belum Tersedia',
|
||||
subtitle = 'Tidak ada data perhitungan sapronak untuk periode ini.',
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
columns?: ColumnDef<RowSapronakCalculation>[];
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
const defaultColumns: ColumnDef<RowSapronakCalculation>[] = [
|
||||
{
|
||||
id: 'date',
|
||||
header: 'Tanggal',
|
||||
},
|
||||
{
|
||||
id: 'reference_number',
|
||||
header: 'No. Referensi',
|
||||
},
|
||||
{
|
||||
id: 'qty_in',
|
||||
header: 'QTY Masuk',
|
||||
},
|
||||
{
|
||||
id: 'qty_out',
|
||||
header: 'QTY Keluar',
|
||||
},
|
||||
{
|
||||
id: 'qty_used',
|
||||
header: 'QTY Pakai',
|
||||
},
|
||||
{
|
||||
id: 'balance',
|
||||
header: 'Saldo',
|
||||
},
|
||||
{
|
||||
id: 'unit_price_in',
|
||||
header: 'Harga Masuk',
|
||||
},
|
||||
{
|
||||
id: 'unit_price_out',
|
||||
header: 'Harga Keluar',
|
||||
},
|
||||
{
|
||||
id: 'total_price_in',
|
||||
header: 'Total Harga Masuk',
|
||||
},
|
||||
{
|
||||
id: 'total_price_out',
|
||||
header: 'Total Harga Keluar',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ClosingTabSkeleton<RowSapronakCalculation>
|
||||
columns={columns || defaultColumns}
|
||||
icon={
|
||||
<Icon icon={iconName} className='text-white' width={20} height={20} />
|
||||
}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default SapronakCalculationClosingSkeleton;
|
||||
@@ -0,0 +1,126 @@
|
||||
import { Icon } from '@iconify/react';
|
||||
import ClosingTabSkeleton from './ClosingTabSkeleton';
|
||||
import { ClosingIncomingSapronak } from '@/types/api/closing';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
const SapronakClosingSkeleton = ({
|
||||
columns,
|
||||
type = 'incoming',
|
||||
title,
|
||||
subtitle,
|
||||
iconName = 'heroicons:chart-bar',
|
||||
}: {
|
||||
columns?: ColumnDef<ClosingIncomingSapronak>[];
|
||||
type?: 'incoming' | 'outgoing';
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
iconName?: string;
|
||||
}) => {
|
||||
const defaultIncomingColumns: ColumnDef<ClosingIncomingSapronak>[] = [
|
||||
{
|
||||
id: '#',
|
||||
header: '#',
|
||||
},
|
||||
{
|
||||
id: 'date',
|
||||
header: 'Tanggal',
|
||||
},
|
||||
{
|
||||
id: 'reference_number',
|
||||
header: 'No. Referensi',
|
||||
},
|
||||
{
|
||||
id: 'transaction_type',
|
||||
header: 'Jenis Transaksi',
|
||||
},
|
||||
{
|
||||
id: 'product_name',
|
||||
header: 'Produk',
|
||||
},
|
||||
{
|
||||
id: 'product_category',
|
||||
header: 'Kategori Produk',
|
||||
},
|
||||
{
|
||||
id: 'source_warehouse',
|
||||
header: 'Gudang Asal',
|
||||
},
|
||||
{
|
||||
id: 'destination_warehouse',
|
||||
header: 'Gudang Tujuan',
|
||||
},
|
||||
{
|
||||
id: 'quantity',
|
||||
header: 'Kuantitas',
|
||||
},
|
||||
{
|
||||
id: 'notes',
|
||||
header: 'Keterangan',
|
||||
},
|
||||
];
|
||||
|
||||
const defaultOutgoingColumns: ColumnDef<ClosingIncomingSapronak>[] = [
|
||||
{
|
||||
id: '#',
|
||||
header: '#',
|
||||
},
|
||||
{
|
||||
id: 'date',
|
||||
header: 'Tanggal',
|
||||
},
|
||||
{
|
||||
id: 'reference_number',
|
||||
header: 'No. Referensi',
|
||||
},
|
||||
{
|
||||
id: 'transaction_type',
|
||||
header: 'Jenis Transaksi',
|
||||
},
|
||||
{
|
||||
id: 'product_name',
|
||||
header: 'Produk',
|
||||
},
|
||||
{
|
||||
id: 'product_category',
|
||||
header: 'Kategori Produk',
|
||||
},
|
||||
{
|
||||
id: 'source_warehouse',
|
||||
header: 'Gudang Asal',
|
||||
},
|
||||
{
|
||||
id: 'quantity',
|
||||
header: 'Kuantitas',
|
||||
},
|
||||
{
|
||||
id: 'notes',
|
||||
header: 'Keterangan',
|
||||
},
|
||||
];
|
||||
|
||||
const defaultTitle =
|
||||
type === 'incoming'
|
||||
? 'Data Sapronak Masuk Belum Tersedia'
|
||||
: 'Data Sapronak Keluar Belum Tersedia';
|
||||
|
||||
const defaultSubtitle =
|
||||
type === 'incoming'
|
||||
? 'Silakan pilih periode atau filter untuk melihat data sapronak masuk.'
|
||||
: 'Silakan pilih periode atau filter untuk melihat data sapronak keluar.';
|
||||
|
||||
return (
|
||||
<ClosingTabSkeleton<ClosingIncomingSapronak>
|
||||
columns={
|
||||
columns ||
|
||||
(type === 'incoming' ? defaultIncomingColumns : defaultOutgoingColumns)
|
||||
}
|
||||
icon={
|
||||
<Icon icon={iconName} className='text-white' width={20} height={20} />
|
||||
}
|
||||
title={title || defaultTitle}
|
||||
subtitle={subtitle || defaultSubtitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default SapronakClosingSkeleton;
|
||||
Reference in New Issue
Block a user