@@ -2,21 +2,23 @@ import React from 'react';
22import ReactMarkdown from 'react-markdown' ;
33import remarkGfm from 'remark-gfm' ;
44import { Microscope } from 'lucide-react' ;
5+ import type { Structure } from '../../lib/structuresService' ;
56
67interface LabReportTemplateProps {
78 title : string ;
89 content : string ;
910 date : string ;
1011 author : string ;
1112 id : string ;
13+ allStructures ?: Structure [ ] ;
1214}
1315
1416/**
1517 * LabReportTemplate component for multi-page PDF generation.
1618 * Separated into Cover Page and Content Page.
1719 */
1820export const LabReportTemplate = React . forwardRef < HTMLDivElement , LabReportTemplateProps > (
19- ( { title, content, date, author, id } , ref ) => {
21+ ( { title, content, date, author, id, allStructures = [ ] } , ref ) => {
2022 return (
2123 < div
2224 ref = { ref }
@@ -42,15 +44,24 @@ export const LabReportTemplate = React.forwardRef<HTMLDivElement, LabReportTempl
4244 .pdf-page * {
4345 box-sizing: border-box !important;
4446 }
47+ .pdf-structure-link {
48+ color: #2563eb !important;
49+ text-decoration: underline !important;
50+ font-weight: 600 !important;
51+ cursor: pointer !important;
52+ }
4553 ` } } />
4654
55+ { /* ... (rest of the component) ... */ }
56+
4757 { /* PAGE 1: COVER PAGE */ }
4858 < div id = "report-page-1" className = "pdf-page" style = { {
4959 display : 'flex' ,
5060 flexDirection : 'column' ,
5161 justifyContent : 'center' ,
5262 textAlign : 'center'
5363 } } >
64+ { /* ... (Cover Page content) ... */ }
5465 < div style = { { marginBottom : '4rem' , display : 'flex' , justifyContent : 'center' } } >
5566 < div style = { { backgroundColor : '#0f172a' , padding : '1.5rem' , borderRadius : '1rem' , display : 'inline-flex' } } >
5667 < Microscope size = { 64 } color = "#ffffff" />
@@ -114,7 +125,6 @@ export const LabReportTemplate = React.forwardRef<HTMLDivElement, LabReportTempl
114125
115126 { /* PAGE 2: CONTENT PAGE */ }
116127 < div id = "report-page-2" className = "pdf-page" >
117- { /* Header on page 2 */ }
118128 < div style = { {
119129 display : 'flex' ,
120130 justifyContent : 'space-between' ,
@@ -139,7 +149,36 @@ export const LabReportTemplate = React.forwardRef<HTMLDivElement, LabReportTempl
139149 h1 : ( { node, ...props } ) => < h1 style = { { fontSize : '1.875rem' , fontWeight : 'bold' , color : '#0f172a' , marginBottom : '1rem' , marginTop : '1rem' } } { ...props } /> ,
140150 h2 : ( { node, ...props } ) => < h2 style = { { fontSize : '1.5rem' , fontWeight : 'bold' , color : '#0f172a' , marginTop : '2rem' , marginBottom : '0.75rem' } } { ...props } /> ,
141151 h3 : ( { node, ...props } ) => < h3 style = { { fontSize : '1.25rem' , fontWeight : 'bold' , color : '#0f172a' , marginTop : '1.5rem' , marginBottom : '0.5rem' } } { ...props } /> ,
142- p : ( { node, ...props } ) => < p style = { { marginBottom : '1rem' , lineHeight : '1.6' } } { ...props } /> ,
152+ p : ( { children} ) => {
153+ const processed = React . Children . map ( children , child => {
154+ if ( typeof child === 'string' ) {
155+ const parts = child . split ( / ( \[ \[ s t r u c t u r e : [ a - f 0 - 9 - ] { 36 } \] \] ) / g) ;
156+ return parts . map ( ( part , i ) => {
157+ const match = part . match ( / \[ \[ s t r u c t u r e : ( [ a - f 0 - 9 - ] { 36 } ) \] \] / ) ;
158+ if ( match ) {
159+ const sid = match [ 1 ] ;
160+ const s = allStructures . find ( st => st . id === sid ) ;
161+ const name = s ?. name || sid . substring ( 0 , 8 ) ;
162+ const url = `${ window . location . origin } /?struct=${ sid } ` ;
163+ return (
164+ < a
165+ key = { i }
166+ href = { url }
167+ className = "pdf-structure-link"
168+ data-structure-id = { sid }
169+ style = { { color : '#2563eb' , textDecoration : 'underline' , fontWeight : 'bold' } }
170+ >
171+ @{ name }
172+ </ a >
173+ ) ;
174+ }
175+ return part ;
176+ } ) ;
177+ }
178+ return child ;
179+ } ) ;
180+ return < p style = { { marginBottom : '1rem' , lineHeight : '1.6' } } > { processed } </ p > ;
181+ } ,
143182 ul : ( { node, ...props } ) => < ul style = { { listStyleType : 'disc' , paddingLeft : '1.5rem' , marginBottom : '1rem' } } { ...props } /> ,
144183 ol : ( { node, ...props } ) => < ol style = { { listStyleType : 'decimal' , paddingLeft : '1.5rem' , marginBottom : '1rem' } } { ...props } /> ,
145184 li : ( { node, ...props } ) => < li style = { { marginBottom : '0.5rem' } } { ...props } /> ,
@@ -158,7 +197,6 @@ export const LabReportTemplate = React.forwardRef<HTMLDivElement, LabReportTempl
158197 </ ReactMarkdown >
159198 </ div >
160199
161- { /* Footer on page 2 */ }
162200 < div
163201 style = { {
164202 position : 'absolute' ,
0 commit comments