e5d7ca1293
User-facing rename across 20 files: - Layout title/meta: "CapaKraken — Resource & Capacity Planning" - Sidebar logo: "CapaKraken" with "RESOURCE & CAPACITY PLANNING" - Sign-in page: "CapaKraken Control Center", "Sign in to CapaKraken" - PWA manifest: name + short_name - PDF reports: footer text - Install prompt: "Install CapaKraken" - AI assistant system prompt - Webhooks test payload - Email subject lines - Tooltips, descriptions, empty states NOT changed (technical identifiers): - Package names (@planarchy/*) - Import paths - Database names - Docker container names - localStorage keys - Domain URLs - CLAUDE.md Co-Authored-By: claude-flow <ruv@ruv.net>
71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
// @react-pdf/renderer runs server-side only — no "use client" directive
|
|
import { Document, Page, StyleSheet, Text, View } from "@react-pdf/renderer";
|
|
|
|
const styles = StyleSheet.create({
|
|
page: { padding: 30, fontFamily: "Helvetica", fontSize: 10 },
|
|
title: { fontSize: 18, marginBottom: 4, fontFamily: "Helvetica-Bold" },
|
|
subtitle: { fontSize: 11, color: "#6b7280", marginBottom: 20 },
|
|
table: { marginTop: 10 },
|
|
tableHeader: { flexDirection: "row", backgroundColor: "#f3f4f6", padding: "6 8", borderBottom: "1 solid #e5e7eb" },
|
|
tableRow: { flexDirection: "row", padding: "5 8", borderBottom: "1 solid #f3f4f6" },
|
|
col1: { width: "25%" },
|
|
col2: { width: "20%" },
|
|
col3: { width: "15%" },
|
|
col4: { width: "15%" },
|
|
col5: { width: "15%" },
|
|
col6: { width: "10%" },
|
|
headerText: { fontFamily: "Helvetica-Bold", color: "#374151", fontSize: 9 },
|
|
cellText: { color: "#4b5563", fontSize: 9 },
|
|
footer: { position: "absolute", bottom: 20, left: 30, right: 30, textAlign: "center", color: "#9ca3af", fontSize: 8 },
|
|
});
|
|
|
|
interface AllocationRow {
|
|
resourceName: string;
|
|
projectName: string;
|
|
role?: string | null;
|
|
startDate: string;
|
|
endDate: string;
|
|
hoursPerDay: number;
|
|
dailyCostCents: number;
|
|
}
|
|
|
|
interface AllocationReportProps {
|
|
title: string;
|
|
generatedAt: string;
|
|
rows: AllocationRow[];
|
|
}
|
|
|
|
export function AllocationReport({ title, generatedAt, rows }: AllocationReportProps) {
|
|
return (
|
|
<Document>
|
|
<Page size="A4" orientation="landscape" style={styles.page}>
|
|
<Text style={styles.title}>{title}</Text>
|
|
<Text style={styles.subtitle}>Generated: {generatedAt}</Text>
|
|
|
|
<View style={styles.table}>
|
|
<View style={styles.tableHeader}>
|
|
<Text style={[styles.col1, styles.headerText]}>Resource</Text>
|
|
<Text style={[styles.col2, styles.headerText]}>Project</Text>
|
|
<Text style={[styles.col3, styles.headerText]}>Role</Text>
|
|
<Text style={[styles.col4, styles.headerText]}>Start</Text>
|
|
<Text style={[styles.col5, styles.headerText]}>End</Text>
|
|
<Text style={[styles.col6, styles.headerText]}>h/day</Text>
|
|
</View>
|
|
{rows.map((row, i) => (
|
|
<View key={i} style={[styles.tableRow, i % 2 === 1 ? { backgroundColor: "#f9fafb" } : {}]}>
|
|
<Text style={[styles.col1, styles.cellText]}>{row.resourceName}</Text>
|
|
<Text style={[styles.col2, styles.cellText]}>{row.projectName}</Text>
|
|
<Text style={[styles.col3, styles.cellText]}>{row.role ?? "—"}</Text>
|
|
<Text style={[styles.col4, styles.cellText]}>{row.startDate}</Text>
|
|
<Text style={[styles.col5, styles.cellText]}>{row.endDate}</Text>
|
|
<Text style={[styles.col6, styles.cellText]}>{row.hoursPerDay}h</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
|
|
<Text style={styles.footer}>CapaKraken · Confidential · {rows.length} allocations</Text>
|
|
</Page>
|
|
</Document>
|
|
);
|
|
}
|