import React from 'react'; import { Document, Page, StyleSheet, Text, View } from '@react-pdf/renderer'; import type { IReportData } from '../service/ai-readiness/ai-readiness.interface'; const humanizeIssue = (issue: string): string => { switch (issue) { case 'short_title': return 'Short Titles'; case 'short_description': return 'Short Descriptions'; case 'missing_image': case 'missing_images': return 'Missing Images'; case 'insufficient_attribute_fields': return 'Insufficient Attributes'; case 'incomplete_structured_attributes': return 'Incomplete Attributes'; case 'missing_price': return 'Missing Prices'; case 'missing_category': return 'Missing Categories'; default: return issue; } }; // Define styles const styles = StyleSheet.create({ page: { padding: 30, fontSize: 10, fontFamily: 'Helvetica', backgroundColor: '#ffffff', }, headerPage: { padding: 40, backgroundColor: '#b7007c', minHeight: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', }, logo: { fontSize: 18, fontWeight: 'bold', color: '#ffffff', letterSpacing: 3, marginBottom: 20, opacity: 0.9, }, title: { fontSize: 32, fontWeight: 'bold', color: '#ffffff', marginBottom: 10, textAlign: 'center', }, subtitle: { fontSize: 14, color: '#ffffff', opacity: 0.9, marginBottom: 25, textAlign: 'center', maxWidth: 400, }, scoreCircle: { width: 140, height: 140, borderRadius: 70, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', marginBottom: 20, }, scoreGreen: { backgroundColor: '#28a745', }, scoreYellow: { backgroundColor: '#f9a825', }, scoreRed: { backgroundColor: '#dc3545', }, scoreValue: { fontSize: 42, fontWeight: 'bold', color: '#ffffff', }, scoreLabel: { fontSize: 16, color: '#ffffff', opacity: 0.85, }, status: { fontSize: 16, fontWeight: 'bold', color: '#ffffff', marginBottom: 15, textAlign: 'center', }, insight: { fontSize: 12, color: '#ffffff', opacity: 0.9, marginBottom: 15, textAlign: 'center', maxWidth: 450, }, date: { fontSize: 10, color: '#ffffff', opacity: 0.7, }, sectionHeader: { marginBottom: 15, paddingBottom: 8, borderBottomWidth: 2, borderBottomColor: '#b7007c', borderBottomStyle: 'solid', }, sectionTitle: { fontSize: 20, fontWeight: 'bold', color: '#92005e', marginBottom: 4, }, sectionSubtitle: { fontSize: 10, color: '#666666', }, // Blockers blockerCard: { backgroundColor: '#ffffff', borderLeftWidth: 4, borderLeftColor: '#dc3545', borderLeftStyle: 'solid', borderRadius: 4, padding: 12, marginBottom: 10, }, blockerCardHigh: { borderLeftColor: '#ffc107', }, blockerHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, }, blockerTitle: { fontSize: 13, fontWeight: 'bold', color: '#1a1a2e', }, priorityBadge: { paddingHorizontal: 8, paddingVertical: 3, borderRadius: 3, fontSize: 9, fontWeight: 'bold', }, priorityUrgent: { backgroundColor: '#fdecea', color: '#dc3545', }, priorityHigh: { backgroundColor: '#fff8e6', color: '#d97706', }, blockerStats: { flexDirection: 'row', gap: 20, marginBottom: 8, fontSize: 10, }, blockerImpact: { fontSize: 10, color: '#555555', padding: 8, backgroundColor: '#fff8e6', borderRadius: 4, marginBottom: 10, }, examplesRow: { flexDirection: 'row', gap: 10, }, example: { flex: 1, padding: 8, borderRadius: 4, fontSize: 9, }, exampleBad: { backgroundColor: '#fdecea', borderLeftWidth: 3, borderLeftColor: '#dc3545', borderLeftStyle: 'solid', }, exampleGood: { backgroundColor: '#e8f5e9', borderLeftWidth: 3, borderLeftColor: '#28a745', borderLeftStyle: 'solid', }, exampleLabel: { fontWeight: 'bold', marginBottom: 3, }, // Categories categoriesGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 10, }, categoryCard: { width: '31%', backgroundColor: '#ffffff', borderWidth: 1, borderColor: '#e0e0e0', borderStyle: 'solid', borderRadius: 4, padding: 10, marginBottom: 10, }, categoryHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, }, categoryTitle: { fontSize: 11, fontWeight: 'bold', color: '#1a1a2e', maxWidth: 80, }, gradeBadge: { paddingHorizontal: 6, paddingVertical: 3, borderRadius: 3, fontSize: 9, fontWeight: 'bold', }, gradeA: { backgroundColor: '#e8f5e9', color: '#28a745' }, gradeB: { backgroundColor: '#e3f2fd', color: '#0d6efd' }, gradeC: { backgroundColor: '#fff8e6', color: '#856404' }, gradeD: { backgroundColor: '#fdecea', color: '#dc3545' }, categoryMeta: { fontSize: 9, color: '#888888', marginBottom: 6, }, weaknesses: { fontSize: 9, marginBottom: 6, }, weaknessItem: { color: '#666666', marginLeft: 8, marginBottom: 2, }, categoryPriority: { fontSize: 9, padding: 6, backgroundColor: '#fff8e6', borderRadius: 3, }, // Action Plan actionItem: { flexDirection: 'row', gap: 10, padding: 12, backgroundColor: '#f8f9fa', borderLeftWidth: 4, borderLeftColor: '#b7007c', borderLeftStyle: 'solid', borderRadius: 4, marginBottom: 8, }, actionNumber: { width: 26, height: 26, borderRadius: 13, backgroundColor: '#b7007c', display: 'flex', alignItems: 'center', justifyContent: 'center', }, actionNumberText: { color: '#ffffff', fontSize: 12, fontWeight: 'bold', }, actionContent: { flex: 1, }, actionTitle: { fontSize: 12, fontWeight: 'bold', color: '#1a1a2e', marginBottom: 4, }, actionImpact: { fontSize: 10, color: '#555555', marginBottom: 3, }, actionEffort: { fontSize: 9, color: '#888888', }, // Stats statsRow: { flexDirection: 'row', gap: 15, marginBottom: 20, }, statBox: { flex: 1, backgroundColor: '#667eea', padding: 15, borderRadius: 6, alignItems: 'center', }, statValue: { fontSize: 28, fontWeight: 'bold', color: '#ffffff', }, statLabel: { fontSize: 10, color: '#ffffff', opacity: 0.9, }, // Performance performanceSection: { backgroundColor: '#f8f9fa', borderRadius: 6, padding: 15, marginBottom: 15, }, performanceTitle: { fontSize: 14, fontWeight: 'bold', marginBottom: 10, }, performanceGrid: { flexDirection: 'row', gap: 20, marginBottom: 10, }, performanceMain: { flex: 1, alignItems: 'center', }, performanceTime: { fontSize: 28, fontWeight: 'bold', marginBottom: 4, }, performanceLabel: { fontSize: 10, color: '#666666', marginBottom: 6, }, performanceRating: { paddingHorizontal: 8, paddingVertical: 3, borderRadius: 3, fontSize: 9, fontWeight: 'bold', }, ratingGood: { backgroundColor: '#e8f5e9', color: '#28a745' }, ratingWarning: { backgroundColor: '#fff8e6', color: '#d97706' }, performanceDetails: { flex: 1, fontSize: 10, color: '#555555', }, performanceExplanation: { fontSize: 10, padding: 10, backgroundColor: '#ffffff', borderRadius: 4, }, // Missing pages missingPagesSection: { marginTop: 15, }, missingPagesTitle: { fontSize: 12, fontWeight: 'bold', marginBottom: 8, }, missingPagesList: { flexDirection: 'row', flexWrap: 'wrap', gap: 6, marginBottom: 8, }, missingPageTag: { backgroundColor: '#fdecea', color: '#dc3545', paddingHorizontal: 10, paddingVertical: 4, borderRadius: 3, fontSize: 10, fontWeight: 'bold', }, missingPagesNote: { fontSize: 9, color: '#888888', }, // AI Section aiSection: { marginBottom: 20, }, successRateBox: { backgroundColor: '#667eea', padding: 18, borderRadius: 6, alignItems: 'center', marginBottom: 12, }, successRateValue: { fontSize: 36, fontWeight: 'bold', color: '#ffffff', marginBottom: 6, }, successRateLabel: { fontSize: 12, color: '#ffffff', opacity: 0.9, textAlign: 'center', }, explanation: { fontSize: 10, padding: 12, backgroundColor: '#f8f9fa', borderRadius: 4, }, // Simulation examples examplesList: { flexDirection: 'row', flexWrap: 'wrap', gap: 10, marginBottom: 15, }, simulationExample: { width: '48%', backgroundColor: '#ffffff', borderWidth: 1, borderColor: '#e0e0e0', borderStyle: 'solid', borderRadius: 4, padding: 10, marginBottom: 10, }, question: { fontSize: 11, fontWeight: 'bold', marginBottom: 6, }, aiResponse: { fontSize: 9, padding: 8, backgroundColor: '#f8f9fa', borderRadius: 3, marginBottom: 6, }, missingData: { fontSize: 9, padding: 6, backgroundColor: '#fff8e6', borderLeftWidth: 2, borderLeftColor: '#ffc107', borderLeftStyle: 'solid', borderRadius: 3, marginBottom: 6, }, impactRow: { fontSize: 9, color: '#666666', flexDirection: 'row', alignItems: 'center', gap: 4, }, impactBadge: { paddingHorizontal: 6, paddingVertical: 2, borderRadius: 2, fontSize: 8, fontWeight: 'bold', }, impactHigh: { backgroundColor: '#fdecea', color: '#dc3545' }, impactMedium: { backgroundColor: '#fff8e6', color: '#d97706' }, impactLow: { backgroundColor: '#e3f2fd', color: '#0d6efd' }, improvements: { backgroundColor: '#f8f9fa', borderLeftWidth: 4, borderLeftColor: '#b7007c', borderLeftStyle: 'solid', borderRadius: 4, padding: 12, }, improvementsTitle: { fontSize: 12, fontWeight: 'bold', marginBottom: 8, }, improvementItem: { fontSize: 10, color: '#555555', marginLeft: 10, marginBottom: 4, }, // Products productsGrid: { flexDirection: 'row', gap: 20, }, productsColumn: { flex: 1, }, productsTitle: { fontSize: 13, fontWeight: 'bold', marginBottom: 10, paddingBottom: 6, borderBottomWidth: 2, borderBottomStyle: 'solid', }, productsTitleGood: { color: '#28a745', borderBottomColor: '#28a745', }, productsTitleBad: { color: '#dc3545', borderBottomColor: '#dc3545', }, productCard: { padding: 8, borderRadius: 3, marginBottom: 6, borderLeftWidth: 3, borderLeftStyle: 'solid', }, productCardGood: { backgroundColor: '#e8f5e9', borderLeftColor: '#28a745', }, productCardBad: { backgroundColor: '#fdecea', borderLeftColor: '#dc3545', }, productName: { fontSize: 10, fontWeight: 'bold', color: '#1a1a2e', marginBottom: 2, }, productSku: { fontSize: 9, color: '#888888', }, // Footer footer: { textAlign: 'center', padding: 15, backgroundColor: '#f8f9fa', borderTopWidth: 1, borderTopColor: '#e0e0e0', borderTopStyle: 'solid', fontSize: 10, color: '#888888', }, }); const getScoreStyle = (score: number) => { if (score >= 70) return styles.scoreGreen; if (score >= 50) return styles.scoreYellow; return styles.scoreRed; }; const getGradeStyle = (grade: string) => { const g = grade[0].toLowerCase(); if (g === 'a') return styles.gradeA; if (g === 'b') return styles.gradeB; if (g === 'c') return styles.gradeC; return styles.gradeD; }; export const AiReadinessPdfDocument = ({ reportData, }: { reportData: IReportData; }) => { const { overall_assessment, sample_info } = reportData; const insightSummary = overall_assessment.insight_summary || reportData.ai_conversation_scenarios?.explanation; return ( {/* Page 1: Header */} RECOMAZE AI Discoverability Report {overall_assessment.headline} {overall_assessment.score} /100 {overall_assessment.ready_for_ai ? 'Your catalog is AI-ready!' : 'Improvements needed for optimal AI performance'} {insightSummary && {insightSummary}} {sample_info && ( Products Analyzed: {sample_info.products_analyzed} {sample_info.total_products ? ` of ${sample_info.total_products} (${sample_info.sample_percentage}%)` : ''} )} Generated:{' '} {new Date(overall_assessment.generated_at).toLocaleDateString()} {/* Page 2: Critical Blockers */} {reportData.critical_blockers && reportData.critical_blockers.length > 0 && ( Critical Blockers Issues preventing AI from answering customer questions effectively {reportData.critical_blockers.map((blocker, idx) => ( {humanizeIssue(blocker.issue)} {blocker.priority} Affected: {blocker.affected_percentage}% Effort: {blocker.effort} {blocker.impact} Bad: {blocker.example_bad} Good: {blocker.example_good} ))} )} {/* Page 3: Category Analysis */} {reportData.category_analysis && Object.keys(reportData.category_analysis).length > 0 && ( Category Analysis Per-category breakdown of AI readiness {Object.entries(reportData.category_analysis).map( ([category, analysis]) => ( {category} {analysis.score}/100 {analysis.total_products} products {analysis.weaknesses && analysis.weaknesses.length > 0 && ( Issues: {analysis.weaknesses.slice(0, 2).map((w, i) => ( • {w} ))} )} Priority: {analysis.top_priority} ) )} )} {/* Page 4: Action Plan */} {reportData.action_plan?.top_priorities && reportData.action_plan.top_priorities.length > 0 && ( Action Plan Prioritized tasks to improve your AI readiness {reportData.action_plan.top_priorities.map((priority, idx) => ( {idx + 1} {priority.task} {priority.impact} Effort: {priority.effort} ))} )} {/* Page 5: Website Analysis */} {reportData.website_content_analysis && ( Website Content Analysis {reportData.website_content_analysis.pages_found} Pages Analyzed {reportData.website_content_analysis.missing_pages.length} Missing Pages {reportData.website_content_analysis.performance && ( Page Load Performance { reportData.website_content_analysis.performance .average_load_time } s Average Load Time {reportData.website_content_analysis.performance.rating.toUpperCase()} Min:{' '} { reportData.website_content_analysis.performance .min_load_time } s Max:{' '} { reportData.website_content_analysis.performance .max_load_time } s Slow pages:{' '} { reportData.website_content_analysis.performance .slow_pages_count } Impact:{' '} {reportData.website_content_analysis.performance.explanation} )} {reportData.website_content_analysis.missing_pages.length > 0 && ( Missing Critical Pages: {reportData.website_content_analysis.missing_pages.map( (p, i) => ( {p} ) )} AI cannot answer questions about these topics without this content. )} )} {/* Page 6: AI Conversation */} {(reportData.ai_conversation_scenarios || reportData.ai_response_simulation) && ( {reportData.ai_conversation_scenarios && ( AI Conversation Success Rate {reportData.ai_conversation_scenarios.success_rate} of typical customer questions can be answered by AI {reportData.ai_conversation_scenarios.explanation} )} {reportData.ai_response_simulation && ( AI Response Simulation How well can AI answer customer questions? {reportData.ai_response_simulation.overall_answerability} of questions can be answered with current data Summary: {reportData.ai_response_simulation.summary} )} )} {/* Page 7: Simulation Examples */} {reportData.ai_response_simulation?.simulation_examples && reportData.ai_response_simulation.simulation_examples.length > 0 && ( Example Questions & AI Responses {reportData.ai_response_simulation.simulation_examples.map( (ex, idx) => ( Q: {ex.question} AI: {ex.sample_response} {ex.missing_data && ( Missing: {ex.missing_data} )} Impact: {ex.improvement_impact.toUpperCase()} ) )} {reportData.ai_response_simulation.key_improvements && reportData.ai_response_simulation.key_improvements.length > 0 && ( Key Improvements to Boost AI Responses {reportData.ai_response_simulation.key_improvements.map( (imp, i) => ( • {imp} ) )} )} )} {/* Page 8: Product Examples */} {reportData.product_examples && ( Product Examples Well-Optimized Products {reportData.product_examples.good_examples.map((ex, idx) => ( {ex.name} SKU: {ex.sku} ))} Needs Improvement {reportData.product_examples.bad_examples.map((ex, idx) => ( {ex.name} SKU: {ex.sku} ))} Generated by Recomaze AI Discoverability Analysis www.recomaze.ai )} ); }; export default AiReadinessPdfDocument;