refactor(FE): Refactor PDF table components to simplify imports

This commit is contained in:
rstubryan
2026-02-11 10:39:37 +07:00
parent 70b63f7773
commit 0f1d2ce477
6 changed files with 973 additions and 885 deletions
@@ -9,11 +9,7 @@ import { ProductionResult } from '@/types/api/report/production-result';
import { PdfTypography } from '@/components/helper/pdf/typography/PdfTypography';
import { PdfParamBadge } from '@/components/helper/pdf/badge/PdfParamBadge';
import { PdfPageNumber } from '@/components/helper/pdf/layout/PdfPageNumber';
import {
PdfTable,
PdfColumn,
PdfTbodyCell,
} from '@/components/helper/pdf/table';
import { PdfTable, PdfColumn } from '@/components/helper/pdf/table';
type MappedProductionResultsItem = {
projectFlockKandang: BaseProjectFlockKandang;
@@ -64,246 +60,339 @@ function valueText(v: unknown) {
// ========================================
// TABLE 1: WOA & BW
// ========================================
const getBwTableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'woa', header: 'Week of Age', flex: 0.8, align: 'center' },
{ key: 'bw', header: 'Body Weight', flex: 1, align: 'right' },
{ key: 'std_bw', header: 'Std Body Weight', flex: 1, align: 'right' },
{ key: 'uniformity', header: 'Uniformity', flex: 1.2, align: 'right' },
const getBwTableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'woa',
header: 'Week of Age',
flex: 0.8,
align: 'center',
cell: ({ row }) => valueText(row.woa),
},
{
key: 'bw',
header: 'Body Weight',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.bw),
},
{
key: 'std_bw',
header: 'Std Body Weight',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.std_bw),
},
{
key: 'uniformity',
header: 'Uniformity',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.uniformity),
},
{
key: 'std_uniformity',
header: 'Std Uniformity',
flex: 1.3,
align: 'right',
cell: ({ row }) => valueText(row.std_uniformity),
},
];
const getBwTableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{ key: 'woa', value: valueText(pr.woa) },
{ key: 'bw', value: valueText(pr.bw), align: 'right' },
{ key: 'std_bw', value: valueText(pr.std_bw), align: 'right' },
{ key: 'uniformity', value: valueText(pr.uniformity), align: 'right' },
{
key: 'std_uniformity',
value: valueText(pr.std_uniformity),
align: 'right',
},
];
});
};
// ========================================
// TABLE 2: DEPLESI
// ========================================
const getDepTableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
const getDepTableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'dep_kum',
header: 'Depletion Cummulative',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.dep_kum),
},
{
key: 'dep_std',
header: 'Depletion Std',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.dep_std),
},
{ key: 'dep_std', header: 'Depletion Std', flex: 1.5, align: 'right' },
];
const getDepTableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{ key: 'dep_kum', value: valueText(pr.dep_kum), align: 'right' },
{ key: 'dep_std', value: valueText(pr.dep_std), align: 'right' },
];
});
};
// ========================================
// TABLE 3: BUTIRAN
// ========================================
const getButiranTableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'butiran_utuh', header: 'Utuh', flex: 1.2, align: 'right' },
{ key: 'butiran_putih', header: 'Putih', flex: 1.2, align: 'right' },
{ key: 'butiran_retak', header: 'Retak', flex: 1.2, align: 'right' },
{ key: 'butiran_pecah', header: 'Pecah', flex: 1.2, align: 'right' },
{ key: 'butiran_jumlah', header: 'Jumlah', flex: 1.2, align: 'right' },
{ key: 'total_butir', header: 'Total Butir', flex: 1.3, align: 'right' },
const getButiranTableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'butiran_utuh',
header: 'Utuh',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.butiran_utuh),
},
{
key: 'butiran_putih',
header: 'Putih',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.butiran_putih),
},
{
key: 'butiran_retak',
header: 'Retak',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.butiran_retak),
},
{
key: 'butiran_pecah',
header: 'Pecah',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.butiran_pecah),
},
{
key: 'butiran_jumlah',
header: 'Jumlah',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.butiran_jumlah),
},
{
key: 'total_butir',
header: 'Total Butir',
flex: 1.3,
align: 'right',
cell: ({ row }) => valueText(row.total_butir),
},
];
const getButiranTableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{
key: 'butiran_utuh',
value: valueText(pr.butiran_utuh),
align: 'right',
},
{
key: 'butiran_putih',
value: valueText(pr.butiran_putih),
align: 'right',
},
{
key: 'butiran_retak',
value: valueText(pr.butiran_retak),
align: 'right',
},
{
key: 'butiran_pecah',
value: valueText(pr.butiran_pecah),
align: 'right',
},
{
key: 'butiran_jumlah',
value: valueText(pr.butiran_jumlah),
align: 'right',
},
{
key: 'total_butir',
value: valueText(pr.total_butir),
align: 'right',
},
];
});
};
// ========================================
// TABLE 4: BERAT (KG)
// ========================================
const getKgTableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'kg_utuh', header: 'Utuh (Kg)', flex: 1.2, align: 'right' },
{ key: 'kg_putih', header: 'Putih (Kg)', flex: 1.2, align: 'right' },
{ key: 'kg_retak', header: 'Retak (Kg)', flex: 1.2, align: 'right' },
{ key: 'kg_pecah', header: 'Pecah (Kg)', flex: 1.2, align: 'right' },
{ key: 'kg_jumlah', header: 'Jumlah (Kg)', flex: 1.3, align: 'right' },
{ key: 'total_kg', header: 'Total (Kg)', flex: 1.3, align: 'right' },
const getKgTableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'kg_utuh',
header: 'Utuh (Kg)',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.kg_utuh),
},
{
key: 'kg_putih',
header: 'Putih (Kg)',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.kg_putih),
},
{
key: 'kg_retak',
header: 'Retak (Kg)',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.kg_retak),
},
{
key: 'kg_pecah',
header: 'Pecah (Kg)',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.kg_pecah),
},
{
key: 'kg_jumlah',
header: 'Jumlah (Kg)',
flex: 1.3,
align: 'right',
cell: ({ row }) => valueText(row.kg_jumlah),
},
{
key: 'total_kg',
header: 'Total (Kg)',
flex: 1.3,
align: 'right',
cell: ({ row }) => valueText(row.total_kg),
},
];
const getKgTableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{ key: 'kg_utuh', value: valueText(pr.kg_utuh), align: 'right' },
{ key: 'kg_putih', value: valueText(pr.kg_putih), align: 'right' },
{ key: 'kg_retak', value: valueText(pr.kg_retak), align: 'right' },
{ key: 'kg_pecah', value: valueText(pr.kg_pecah), align: 'right' },
{ key: 'kg_jumlah', value: valueText(pr.kg_jumlah), align: 'right' },
{ key: 'total_kg', value: valueText(pr.total_kg), align: 'right' },
];
});
};
// ========================================
// TABLE 5: PERSENTASE
// ========================================
const getPersenTableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'persen_utuh', header: 'Utuh (%)', flex: 1.5, align: 'right' },
{ key: 'persen_putih', header: 'Putih (%)', flex: 1.5, align: 'right' },
{ key: 'persen_retak', header: '% Retak (%)', flex: 1.5, align: 'right' },
{ key: 'persen_pecah', header: '% Pecah (%)', flex: 1.5, align: 'right' },
const getPersenTableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'persen_utuh',
header: 'Utuh (%)',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.persen_utuh),
},
{
key: 'persen_putih',
header: 'Putih (%)',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.persen_putih),
},
{
key: 'persen_retak',
header: '% Retak (%)',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.persen_retak),
},
{
key: 'persen_pecah',
header: '% Pecah (%)',
flex: 1.5,
align: 'right',
cell: ({ row }) => valueText(row.persen_pecah),
},
];
const getPersenTableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{
key: 'persen_utuh',
value: valueText(pr.persen_utuh),
align: 'right',
},
{
key: 'persen_putih',
value: valueText(pr.persen_putih),
align: 'right',
},
{
key: 'persen_retak',
value: valueText(pr.persen_retak),
align: 'right',
},
{
key: 'persen_pecah',
value: valueText(pr.persen_pecah),
align: 'right',
},
];
});
};
// ========================================
// TABLE 6: PRODUKSI (HD, FI, EM, EW)
// ========================================
const getProduksi1TableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'hd', header: 'Hen Day', flex: 0.8, align: 'right' },
{ key: 'hd_std', header: 'Hen Day Std', flex: 1, align: 'right' },
{ key: 'fi', header: 'Feed Intake', flex: 0.8, align: 'right' },
{ key: 'fi_std', header: 'Feed Intake Std', flex: 1, align: 'right' },
{ key: 'em', header: 'Egg Mass', flex: 0.8, align: 'right' },
{ key: 'em_std', header: 'Egg Mass Std', flex: 1, align: 'right' },
{ key: 'ew', header: 'Egg Weight', flex: 0.8, align: 'right' },
{ key: 'ew_std', header: 'Egg Weight Std', flex: 1, align: 'right' },
const getProduksi1TableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'hd',
header: 'Hen Day',
flex: 0.8,
align: 'right',
cell: ({ row }) => valueText(row.hd),
},
{
key: 'hd_std',
header: 'Hen Day Std',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.hd_std),
},
{
key: 'fi',
header: 'Feed Intake',
flex: 0.8,
align: 'right',
cell: ({ row }) => valueText(row.fi),
},
{
key: 'fi_std',
header: 'Feed Intake Std',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.fi_std),
},
{
key: 'em',
header: 'Egg Mass',
flex: 0.8,
align: 'right',
cell: ({ row }) => valueText(row.em),
},
{
key: 'em_std',
header: 'Egg Mass Std',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.em_std),
},
{
key: 'ew',
header: 'Egg Weight',
flex: 0.8,
align: 'right',
cell: ({ row }) => valueText(row.ew),
},
{
key: 'ew_std',
header: 'Egg Weight Std',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.ew_std),
},
];
const getProduksi1TableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{ key: 'hd', value: valueText(pr.hd), align: 'right' },
{ key: 'hd_std', value: valueText(pr.hd_std), align: 'right' },
{ key: 'fi', value: valueText(pr.fi), align: 'right' },
{ key: 'fi_std', value: valueText(pr.fi_std), align: 'right' },
{ key: 'em', value: valueText(pr.em), align: 'right' },
{ key: 'em_std', value: valueText(pr.em_std), align: 'right' },
{ key: 'ew', value: valueText(pr.ew), align: 'right' },
{ key: 'ew_std', value: valueText(pr.ew_std), align: 'right' },
];
});
};
// ========================================
// TABLE 7: PRODUKSI (FCR, HH)
// ========================================
const getProduksi2TableColumns = (): PdfColumn[] => [
{ key: 'no', header: 'No', flex: 0.5, align: 'center' },
{ key: 'fcr', header: 'FCR', flex: 1, align: 'right' },
{ key: 'fcr_std', header: 'FCR Std', flex: 1.2, align: 'right' },
{ key: 'hh', header: 'Hen House', flex: 1, align: 'right' },
{ key: 'hh_std', header: 'Hen House Std', flex: 1.2, align: 'right' },
const getProduksi2TableColumns = (): PdfColumn<ProductionResult>[] => [
{
key: 'no',
header: 'No',
flex: 0.5,
align: 'center',
cell: ({ row, index }) => index + 1,
},
{
key: 'fcr',
header: 'FCR',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.fcr),
},
{
key: 'fcr_std',
header: 'FCR Std',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.fcr_std),
},
{
key: 'hh',
header: 'Hen House',
flex: 1,
align: 'right',
cell: ({ row }) => valueText(row.hh),
},
{
key: 'hh_std',
header: 'Hen House Std',
flex: 1.2,
align: 'right',
cell: ({ row }) => valueText(row.hh_std),
},
];
const getProduksi2TableData = (
productionResults: ProductionResult[]
): PdfTbodyCell[][] => {
return productionResults.map((pr, index) => {
return [
{ key: 'no', value: index + 1 },
{ key: 'fcr', value: valueText(pr.fcr), align: 'right' },
{ key: 'fcr_std', value: valueText(pr.fcr_std), align: 'right' },
{ key: 'hh', value: valueText(pr.hh), align: 'right' },
{ key: 'hh_std', value: valueText(pr.hh_std), align: 'right' },
];
});
};
/**
* ✅ Main PDF Component
*/
@@ -383,7 +472,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>1. WOA & Body Weight</Text>
<PdfTable
columns={getBwTableColumns()}
data={getBwTableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -392,7 +481,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>2. Deplesi</Text>
<PdfTable
columns={getDepTableColumns()}
data={getDepTableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -401,7 +490,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>3. Butiran</Text>
<PdfTable
columns={getButiranTableColumns()}
data={getButiranTableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -410,7 +499,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>4. Berat (Kg)</Text>
<PdfTable
columns={getKgTableColumns()}
data={getKgTableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -419,7 +508,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>5. Persentase</Text>
<PdfTable
columns={getPersenTableColumns()}
data={getPersenTableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -430,7 +519,7 @@ const ProductionResultReportPDF = ({
</Text>
<PdfTable
columns={getProduksi1TableColumns()}
data={getProduksi1TableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
@@ -439,7 +528,7 @@ const ProductionResultReportPDF = ({
<Text style={styles.tableTitle}>7. Produksi (FCR, HH)</Text>
<PdfTable
columns={getProduksi2TableColumns()}
data={getProduksi2TableData(item.productionResult!)}
data={item.productionResult!}
/>
</View>
</>