mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 07:45:47 +00:00
refactor(FE): Refactor PdfTable components to support generic data types
This commit is contained in:
@@ -1,22 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Text, View, StyleSheet } from '@react-pdf/renderer';
|
||||
|
||||
export interface PdfColumn {
|
||||
key: string;
|
||||
header: string;
|
||||
flex: number;
|
||||
align?: 'left' | 'center' | 'right';
|
||||
}
|
||||
|
||||
export interface PdfTbodyCell {
|
||||
key: string;
|
||||
value: string | number | React.ReactNode;
|
||||
align?: 'left' | 'center' | 'right';
|
||||
color?: string;
|
||||
formatAs?: 'text' | 'date' | 'currency' | 'number';
|
||||
formatDate?: string;
|
||||
}
|
||||
import { ReactNode } from 'react';
|
||||
import type { PdfColumn } from './types';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tableRow: {
|
||||
@@ -71,21 +57,22 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
interface PdfTbodyProps {
|
||||
columns: PdfColumn[];
|
||||
rows: PdfTbodyCell[][];
|
||||
interface PdfTbodyProps<TData = Record<string, unknown>> {
|
||||
columns: PdfColumn<TData>[];
|
||||
data: TData[];
|
||||
firstRow?: {
|
||||
valueKey: string;
|
||||
value: number;
|
||||
align?: 'right';
|
||||
color?: string;
|
||||
};
|
||||
formatDate?: (date: string, format: string) => string;
|
||||
formatNumber?: (num: number) => string;
|
||||
formatCurrency?: (num: number) => string;
|
||||
}
|
||||
|
||||
export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
export const PdfTbody = <TData = Record<string, unknown>,>({
|
||||
columns,
|
||||
data,
|
||||
firstRow,
|
||||
}: PdfTbodyProps<TData>) => {
|
||||
return (
|
||||
<>
|
||||
{/* First Row */}
|
||||
@@ -93,17 +80,17 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
<View style={[styles.tableRow, styles.tableBorderBottom]}>
|
||||
{columns.map((column, index) => {
|
||||
const isLastColumn = index === columns.length - 1;
|
||||
const isfirstRowColumn = column.key === firstRow.valueKey;
|
||||
const align = column.align || 'center';
|
||||
const isFirstRowColumn = column.key === firstRow.valueKey;
|
||||
const align = column.align || 'left';
|
||||
|
||||
const cellStyle =
|
||||
column.key === 'no'
|
||||
? [styles.tableCellNo, { flex: column.flex }]
|
||||
: isfirstRowColumn
|
||||
? [styles.tableCellNo, { flex: column.flex || 1 }]
|
||||
: isFirstRowColumn
|
||||
? [
|
||||
styles.tableCellRight,
|
||||
{
|
||||
flex: column.flex,
|
||||
flex: column.flex || 1,
|
||||
color: firstRow.color || 'black',
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
@@ -112,7 +99,7 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
? [
|
||||
styles.tableCellRight,
|
||||
{
|
||||
flex: column.flex,
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
]
|
||||
@@ -120,7 +107,7 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
? [
|
||||
styles.tableCellCenter,
|
||||
{
|
||||
flex: column.flex,
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
]
|
||||
@@ -128,15 +115,15 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
? [
|
||||
styles.tableCellLast,
|
||||
{
|
||||
flex: column.flex,
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: 0,
|
||||
},
|
||||
]
|
||||
: [styles.tableCell, { flex: column.flex }];
|
||||
: [styles.tableCell, { flex: column.flex || 1 }];
|
||||
|
||||
return (
|
||||
<View key={column.key} style={cellStyle}>
|
||||
<Text>{isfirstRowColumn ? firstRow.value : ''}</Text>
|
||||
<Text>{isFirstRowColumn ? firstRow.value : ''}</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
@@ -144,8 +131,8 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
)}
|
||||
|
||||
{/* Data Rows */}
|
||||
{rows.map((row, rowIndex) => {
|
||||
const isLastRow = rowIndex === rows.length - 1;
|
||||
{data.map((row, rowIndex) => {
|
||||
const isLastRow = rowIndex === data.length - 1;
|
||||
|
||||
return (
|
||||
<View
|
||||
@@ -156,19 +143,27 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
]}
|
||||
>
|
||||
{columns.map((column, colIndex) => {
|
||||
const cell = row.find((c) => c.key === column.key);
|
||||
const isLastColumn = colIndex === columns.length - 1;
|
||||
const align = cell?.align || column.align || 'center';
|
||||
const align = column.align || 'left';
|
||||
|
||||
// Get cell content from column.cell function or fallback to row value
|
||||
let cellContent: ReactNode;
|
||||
if (column.cell) {
|
||||
cellContent = column.cell({ row, index: rowIndex });
|
||||
} else {
|
||||
cellContent =
|
||||
((row as Record<string, unknown>)[column.key] as ReactNode) ??
|
||||
'-';
|
||||
}
|
||||
|
||||
const cellStyle =
|
||||
column.key === 'no'
|
||||
? [styles.tableCellNo, { flex: column.flex }]
|
||||
? [styles.tableCellNo, { flex: column.flex || 1 }]
|
||||
: align === 'right'
|
||||
? [
|
||||
styles.tableCellRight,
|
||||
{
|
||||
flex: column.flex,
|
||||
color: cell?.color || 'black',
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
]
|
||||
@@ -176,37 +171,30 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
? [
|
||||
styles.tableCellCenter,
|
||||
{
|
||||
flex: column.flex,
|
||||
color: cell?.color || 'black',
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
]
|
||||
: isLastColumn
|
||||
? [
|
||||
styles.tableCellLast,
|
||||
{ flex: column.flex, borderRightWidth: 0 },
|
||||
{ flex: column.flex || 1, borderRightWidth: 0 },
|
||||
]
|
||||
: [
|
||||
styles.tableCell,
|
||||
{
|
||||
flex: column.flex,
|
||||
color: cell?.color || 'black',
|
||||
flex: column.flex || 1,
|
||||
borderRightWidth: isLastColumn ? 0 : 1,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<View key={column.key} style={cellStyle}>
|
||||
{cell?.value !== undefined &&
|
||||
cell?.value !== null &&
|
||||
cell?.value !== '' ? (
|
||||
typeof cell.value === 'object' ? (
|
||||
cell.value
|
||||
) : (
|
||||
<Text>{String(cell.value)}</Text>
|
||||
)
|
||||
{typeof cellContent === 'string' ||
|
||||
typeof cellContent === 'number' ? (
|
||||
<Text>{String(cellContent)}</Text>
|
||||
) : (
|
||||
<Text>-</Text>
|
||||
cellContent
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
@@ -217,3 +205,5 @@ export const PdfTbody = ({ columns, rows, firstRow }: PdfTbodyProps) => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export type { PdfColumn };
|
||||
|
||||
Reference in New Issue
Block a user