mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
210 lines
6.1 KiB
TypeScript
210 lines
6.1 KiB
TypeScript
'use client';
|
|
|
|
import { Text, View, StyleSheet } from '@react-pdf/renderer';
|
|
import { ReactNode } from 'react';
|
|
import type { PdfColumn } from './types';
|
|
|
|
const styles = StyleSheet.create({
|
|
tableRow: {
|
|
flexDirection: 'row',
|
|
},
|
|
tableBorderBottom: {
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: '#000000',
|
|
borderBottomStyle: 'solid',
|
|
},
|
|
tableCell: {
|
|
flex: 1,
|
|
borderRightWidth: 1,
|
|
borderRightColor: '#000000',
|
|
borderRightStyle: 'solid',
|
|
padding: 4,
|
|
fontSize: 7,
|
|
textAlign: 'left',
|
|
},
|
|
tableCellLast: {
|
|
flex: 1,
|
|
padding: 4,
|
|
fontSize: 7,
|
|
borderRightWidth: 0,
|
|
},
|
|
tableCellRight: {
|
|
flex: 1,
|
|
borderRightWidth: 1,
|
|
borderRightColor: '#000000',
|
|
borderRightStyle: 'solid',
|
|
padding: 4,
|
|
fontSize: 7,
|
|
textAlign: 'right',
|
|
},
|
|
tableCellCenter: {
|
|
flex: 1,
|
|
borderRightWidth: 1,
|
|
borderRightColor: '#000000',
|
|
borderRightStyle: 'solid',
|
|
padding: 4,
|
|
fontSize: 7,
|
|
textAlign: 'center',
|
|
},
|
|
tableCellNo: {
|
|
flex: 0.5,
|
|
borderRightWidth: 1,
|
|
borderRightColor: '#000000',
|
|
borderRightStyle: 'solid',
|
|
padding: 4,
|
|
fontSize: 7,
|
|
textAlign: 'center',
|
|
},
|
|
});
|
|
|
|
interface PdfTbodyProps<TData = Record<string, unknown>> {
|
|
columns: PdfColumn<TData>[];
|
|
data: TData[];
|
|
firstRow?: {
|
|
valueKey: string;
|
|
value: number;
|
|
align?: 'right';
|
|
color?: string;
|
|
};
|
|
}
|
|
|
|
export const PdfTbody = <TData = Record<string, unknown>,>({
|
|
columns,
|
|
data,
|
|
firstRow,
|
|
}: PdfTbodyProps<TData>) => {
|
|
return (
|
|
<>
|
|
{/* First Row */}
|
|
{firstRow && (
|
|
<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 || 'left';
|
|
|
|
const cellStyle =
|
|
column.key === 'no'
|
|
? [styles.tableCellNo, { flex: column.flex || 1 }]
|
|
: isFirstRowColumn
|
|
? [
|
|
styles.tableCellRight,
|
|
{
|
|
flex: column.flex || 1,
|
|
color: firstRow.color || 'black',
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
]
|
|
: align === 'right'
|
|
? [
|
|
styles.tableCellRight,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
]
|
|
: align === 'center'
|
|
? [
|
|
styles.tableCellCenter,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
]
|
|
: isLastColumn
|
|
? [
|
|
styles.tableCellLast,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: 0,
|
|
},
|
|
]
|
|
: [styles.tableCell, { flex: column.flex || 1 }];
|
|
|
|
return (
|
|
<View key={column.key} style={cellStyle}>
|
|
<Text>{isFirstRowColumn ? firstRow.value : ''}</Text>
|
|
</View>
|
|
);
|
|
})}
|
|
</View>
|
|
)}
|
|
|
|
{/* Data Rows */}
|
|
{data.map((row, rowIndex) => {
|
|
const isLastRow = rowIndex === data.length - 1;
|
|
|
|
return (
|
|
<View
|
|
key={rowIndex}
|
|
style={[
|
|
styles.tableRow,
|
|
!isLastRow ? styles.tableBorderBottom : {},
|
|
]}
|
|
>
|
|
{columns.map((column, colIndex) => {
|
|
const isLastColumn = colIndex === columns.length - 1;
|
|
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 || 1 }]
|
|
: align === 'right'
|
|
? [
|
|
styles.tableCellRight,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
]
|
|
: align === 'center'
|
|
? [
|
|
styles.tableCellCenter,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
]
|
|
: isLastColumn
|
|
? [
|
|
styles.tableCellLast,
|
|
{ flex: column.flex || 1, borderRightWidth: 0 },
|
|
]
|
|
: [
|
|
styles.tableCell,
|
|
{
|
|
flex: column.flex || 1,
|
|
borderRightWidth: isLastColumn ? 0 : 1,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<View key={column.key} style={cellStyle}>
|
|
{typeof cellContent === 'string' ||
|
|
typeof cellContent === 'number' ? (
|
|
<Text>{String(cellContent)}</Text>
|
|
) : (
|
|
cellContent
|
|
)}
|
|
</View>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
})}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export type { PdfColumn };
|