85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import * as React from 'react';
|
|
import { Document, Image, Page, Text, View } from '@react-pdf/renderer';
|
|
|
|
import type { DatasheetModel, DatasheetVoltageTable } from '../model/types';
|
|
import { styles } from './styles';
|
|
import { Header } from './components/Header';
|
|
import { Footer } from './components/Footer';
|
|
import { Section } from './components/Section';
|
|
import { KeyValueGrid } from './components/KeyValueGrid';
|
|
import { DenseTable } from './components/DenseTable';
|
|
|
|
type Assets = {
|
|
logoDataUrl: string | null;
|
|
heroDataUrl: string | null;
|
|
qrDataUrl: string | null;
|
|
};
|
|
|
|
function chunk<T>(arr: T[], size: number): T[][] {
|
|
if (size <= 0) return [arr];
|
|
const out: T[][] = [];
|
|
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
|
|
return out;
|
|
}
|
|
|
|
export function DatasheetDocument(props: { model: DatasheetModel; assets: Assets }): React.ReactElement {
|
|
const { model, assets } = props;
|
|
const headerTitle = model.labels.datasheet;
|
|
const footerLeft = `${model.labels.sku}: ${model.product.sku}`;
|
|
|
|
const firstColLabel = model.locale === 'de' ? 'Adern & Querschnitt' : 'Cores & cross-section';
|
|
|
|
const tablePages: Array<{ table: DatasheetVoltageTable; rows: DatasheetVoltageTable['rows'] }> =
|
|
model.voltageTables.flatMap(t => {
|
|
const perPage = 30;
|
|
const chunks = chunk(t.rows, perPage);
|
|
return chunks.map(rows => ({ table: t, rows }));
|
|
});
|
|
|
|
return (
|
|
<Document>
|
|
<Page size="A4" style={styles.page}>
|
|
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
|
|
<Footer leftText={footerLeft} locale={model.locale} />
|
|
|
|
<Text style={styles.h1}>{model.product.name}</Text>
|
|
{model.product.categoriesLine ? <Text style={styles.subhead}>{model.product.categoriesLine}</Text> : null}
|
|
|
|
<View style={styles.heroBox}>
|
|
{assets.heroDataUrl ? (
|
|
<Image src={assets.heroDataUrl} style={styles.heroImage} />
|
|
) : (
|
|
<Text style={styles.noImage}>{model.labels.noImage}</Text>
|
|
)}
|
|
</View>
|
|
|
|
{model.product.descriptionText ? (
|
|
<Section title={model.labels.description}>
|
|
<Text style={styles.body}>{model.product.descriptionText}</Text>
|
|
</Section>
|
|
) : null}
|
|
|
|
{model.technicalItems.length ? (
|
|
<Section title={model.labels.technicalData}>
|
|
<KeyValueGrid items={model.technicalItems} />
|
|
</Section>
|
|
) : null}
|
|
</Page>
|
|
|
|
{tablePages.map((p, index) => (
|
|
<Page key={`${p.table.voltageLabel}-${index}`} size="A4" style={styles.page}>
|
|
<Header title={headerTitle} logoDataUrl={assets.logoDataUrl} qrDataUrl={assets.qrDataUrl} />
|
|
<Footer leftText={footerLeft} locale={model.locale} />
|
|
|
|
<Section title={`${model.labels.crossSection} — ${p.table.voltageLabel}`}>
|
|
{p.table.metaItems.length ? <KeyValueGrid items={p.table.metaItems} /> : null}
|
|
</Section>
|
|
|
|
<DenseTable table={{ columns: p.table.columns, rows: p.rows }} firstColLabel={firstColLabel} />
|
|
</Page>
|
|
))}
|
|
</Document>
|
|
);
|
|
}
|
|
|