@@ -5,11 +5,12 @@ import JSZip from 'jszip';
55import { saveAs } from 'file-saver' ;
66import { marked } from 'marked' ;
77import { Document as DocxDocument , Paragraph , Packer } from 'docx' ;
8- import { jsPDF } from 'jspdf' ;
98// Add these imports for UTF-8 font support
109import 'jspdf-autotable' ;
1110import pdfMake from 'pdfmake/build/pdfmake' ;
1211import pdfFonts from 'pdfmake/build/vfs_fonts' ;
12+ import { Input } from './ui/input' ;
13+ import { Label } from './ui/label' ;
1314
1415interface TranscriptionResultProps {
1516 transcription : string ;
@@ -20,7 +21,19 @@ export function TranscriptionResult({ transcription }: TranscriptionResultProps)
2021 const [ isGeneratingPdf , setIsGeneratingPdf ] = useState ( false ) ;
2122 const [ isGeneratingDocx , setIsGeneratingDocx ] = useState ( false ) ;
2223 const [ fontsLoaded , setFontsLoaded ] = useState ( false ) ;
23- const [ pdfTitle , setPdfTitle ] = useState ( "Transcription" ) ;
24+
25+ // Set default title with timestamp
26+ const getDefaultTitle = ( ) => {
27+ const now = new Date ( ) ;
28+ return `Transcription ${ now . toLocaleDateString ( 'en-US' , {
29+ weekday : 'short' ,
30+ month : 'short' ,
31+ day : 'numeric' ,
32+ year : 'numeric'
33+ } ) } ${ now . toLocaleTimeString ( 'en-US' ) } `;
34+ } ;
35+
36+ const [ pdfTitle , setPdfTitle ] = useState ( getDefaultTitle ( ) ) ;
2437
2538 useEffect ( ( ) => {
2639 // Initialize pdfMake with default fonts
@@ -154,15 +167,82 @@ export function TranscriptionResult({ transcription }: TranscriptionResultProps)
154167 saveAs ( content , "transcription-files.zip" ) ;
155168 } ;
156169
157- const handlePrinterzExport = ( ) => {
158- const printerzData = {
159- title : pdfTitle , // Use the custom title from your state
160- content : transcription
161- } ;
170+ const handlePrinterzExport = async ( ) => {
171+ try {
172+ // Get current date and time in a readable format
173+ const now = new Date ( ) ;
174+ const formattedDate = now . toLocaleString ( 'en-US' , {
175+ weekday : 'short' ,
176+ month : 'short' ,
177+ day : 'numeric' ,
178+ year : 'numeric' ,
179+ hour : '2-digit' ,
180+ minute : '2-digit' ,
181+ second : '2-digit'
182+ } ) ;
183+
184+ // Default title includes timestamp if user hasn't changed it
185+ if ( pdfTitle === "Transcription" ) {
186+ setPdfTitle ( `Transcription ${ formattedDate } ` ) ;
187+ }
188+
189+ // Prepare data for Printerz
190+ const printerzData = {
191+ variables : {
192+ title : pdfTitle ,
193+ content : transcription ,
194+ timestamp : formattedDate
195+ } ,
196+ options : {
197+ printBackground : true
198+ }
199+ } ;
200+
201+ const templateId = '9fa3ff8e-c6dc-49b5-93ba-3532638cfe47' ;
202+
203+ // Show loading indicator
204+ setIsGeneratingPdf ( true ) ;
205+
206+ // Use our proxy server instead of calling Printerz directly
207+ const isNetlify = typeof window !== 'undefined' &&
208+ ( window . location . hostname . includes ( 'netlify.app' ) ||
209+ process . env . DEPLOY_ENV === 'netlify' ) ;
210+
211+ const apiUrl = isNetlify
212+ ? '/.netlify/functions/printerz-proxy'
213+ : '/api/printerz/render' ;
214+
215+ const response = await fetch ( apiUrl , {
216+ method : 'POST' ,
217+ headers : {
218+ 'Content-Type' : 'application/json'
219+ } ,
220+ body : JSON . stringify ( {
221+ templateId,
222+ printerzData
223+ } )
224+ } ) ;
162225
163- console . log ( "Sending to Printerz:" , printerzData ) ;
164- // Integration with Printerz API would go here
165- // For example: window.open("https://app.printerz.app/generate?template=your-template-id&data=" + encodeURIComponent(JSON.stringify(printerzData)), "_blank");
226+ if ( ! response . ok ) {
227+ throw new Error ( `Proxy error: ${ response . status } ${ response . statusText } ` ) ;
228+ }
229+
230+ // Get PDF as blob
231+ const pdfBuffer = await response . arrayBuffer ( ) ;
232+ const blob = new Blob ( [ pdfBuffer ] , { type : 'application/pdf' } ) ;
233+
234+ // Save the file
235+ saveAs ( blob , `${ pdfTitle . replace ( / [ / \\ ? % * : | " < > ] / g, '-' ) } .pdf` ) ;
236+
237+ // Clear loading state
238+ setIsGeneratingPdf ( false ) ;
239+
240+ } catch ( error ) {
241+ console . error ( 'Error generating PDF with Printerz:' , error ) ;
242+ setIsGeneratingPdf ( false ) ;
243+ // Show error message to user
244+ alert ( 'Error generating PDF. Please try again later.' ) ;
245+ }
166246 } ;
167247
168248 const renderMarkdown = ( ) => {
@@ -207,35 +287,59 @@ export function TranscriptionResult({ transcription }: TranscriptionResultProps)
207287 </ TabsContent >
208288
209289 < TabsContent value = "pdf" className = "mt-4" >
210- < div className = "bg-gray-50 dark:bg-gray-900 rounded-md border border-gray-200 dark:border-gray-800 p-4 min-h-80 flex flex-col items-center" >
211- { isGeneratingPdf ? (
212- < div className = "flex items-center justify-center h-80" >
213- < div className = "animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary" > </ div >
214- </ div >
215- ) : pdfUrl ? (
216- < div className = "w-full h-80 overflow-auto" >
217- < iframe
218- src = { pdfUrl }
219- className = "w-full h-full border-0"
220- title = "PDF Preview"
221- />
222- </ div >
223- ) : (
224- < div className = "flex flex-col items-center justify-center h-80 space-y-4" >
225- < p className = "text-gray-500" > Preview your PDF before downloading</ p >
226- < Button onClick = { generatePdf } disabled = { ! fontsLoaded } >
227- Generate PDF Preview
228- </ Button >
229- </ div >
230- ) }
290+ < div className = "bg-gray-50 dark:bg-gray-900 rounded-md border border-gray-200 dark:border-gray-800 p-4" >
291+ { /* Add title customization field */ }
292+ < div className = "mb-4" >
293+ < Label htmlFor = "pdf-title" className = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >
294+ Choose a title for your PDF
295+ </ Label >
296+ < Input
297+ id = "pdf-title"
298+ type = "text"
299+ value = { pdfTitle }
300+ onChange = { ( e ) => setPdfTitle ( e . target . value ) }
301+ className = "block w-full rounded-md border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
302+ placeholder = "Transcription with timestamp will be added automatically"
303+ />
304+ </ div >
305+
306+ < div className = "min-h-80 flex flex-col items-center" >
307+ { isGeneratingPdf ? (
308+ < div className = "flex items-center justify-center h-80" >
309+ < div className = "animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary" > </ div >
310+ </ div >
311+ ) : pdfUrl ? (
312+ < div className = "w-full h-80 overflow-auto" >
313+ < iframe
314+ src = { pdfUrl }
315+ className = "w-full h-full border-0"
316+ title = "PDF Preview"
317+ />
318+ </ div >
319+ ) : (
320+ < div className = "flex flex-col items-center justify-center h-80 space-y-4" >
321+ < p className = "text-gray-500" > Preview your PDF before downloading</ p >
322+ < Button onClick = { generatePdf } disabled = { ! fontsLoaded } >
323+ Generate PDF Preview
324+ </ Button >
325+ </ div >
326+ ) }
327+ </ div >
231328 </ div >
232- < div className = "mt-4 flex justify-end" >
329+ < div className = "mt-4 flex justify-end space-x-2 " >
233330 < Button
234331 onClick = { ( ) => handleDownload ( 'pdf' ) }
235332 disabled = { isGeneratingPdf || ! fontsLoaded }
236333 >
237334 { isGeneratingPdf ? 'Generating...' : 'Download as PDF' }
238335 </ Button >
336+ < Button
337+ onClick = { handlePrinterzExport }
338+ disabled = { isGeneratingPdf }
339+ className = "bg-emerald-600 hover:bg-emerald-700"
340+ >
341+ { isGeneratingPdf ? 'Generating...' : 'Generate with Printerz' }
342+ </ Button >
239343 </ div >
240344 </ TabsContent >
241345
0 commit comments