@@ -18,8 +18,6 @@ import { toast } from "sonner";
1818import { motion } from "framer-motion" ;
1919import { useTranslations } from "@/i18n/compat/client" ;
2020import { useRouter } from "@/lib/navigation" ;
21- import { exportResumeToBrowserPrint } from "@/utils/print" ;
22- import { exportResumeAsJson , exportResumeAsMarkdown , exportToPdf } from "@/utils/export" ;
2321import { Dock , DockIcon } from "@/components/magicui/dock" ;
2422import { Button } from "@/components/ui/button" ;
2523import {
@@ -28,12 +26,6 @@ import {
2826 TooltipProvider ,
2927 TooltipTrigger
3028} from "@/components/ui/tooltip" ;
31- import {
32- DropdownMenu ,
33- DropdownMenuContent ,
34- DropdownMenuItem ,
35- DropdownMenuTrigger
36- } from "@/components/ui/dropdown-menu" ;
3729import TemplateSheet from "@/components/shared/TemplateSheet" ;
3830import { GITHUB_REPO_URL , PDF_EXPORT_CONFIG } from "@/config" ;
3931import { cn } from "@/lib/utils" ;
@@ -43,6 +35,7 @@ import { AI_MODEL_CONFIGS } from "@/config/ai";
4335import { useResumeStore } from "@/store/useResumeStore" ;
4436import { useAIConfiguration } from "@/hooks/useAIConfiguration" ;
4537import { FAQDialog } from "./FAQDialog" ;
38+ import PdfExport from "@/components/shared/PdfExport" ;
4639
4740export type IconProps = React . HTMLAttributes < SVGElement > ;
4841
@@ -98,12 +91,7 @@ const PreviewDock = ({
9891} : PreviewDockProps ) => {
9992 const router = useRouter ( ) ;
10093 const t = useTranslations ( "previewDock" ) ;
101- const tPdf = useTranslations ( "pdfExport" ) ;
102- const tBasicField = useTranslations ( "workbench.basicPanel.basicFields" ) ;
10394 const { checkGrammar, isChecking } = useGrammarCheck ( ) ;
104- const [ isExporting , setIsExporting ] = useState ( false ) ;
105- const [ isExportingJson , setIsExportingJson ] = useState ( false ) ;
106- const [ isExportingMarkdown , setIsExportingMarkdown ] = useState ( false ) ;
10795
10896 const {
10997 selectedModel,
@@ -117,67 +105,7 @@ const PreviewDock = ({
117105 } = useAIConfigStore ( ) ;
118106
119107 const { duplicateResume, setActiveResume, activeResumeId, activeResume, updateGlobalSettings } = useResumeStore ( ) ;
120- const { globalSettings = { } , title } = activeResume || { } ;
121-
122- const handleExportPdf = async ( ) => {
123- await exportToPdf ( {
124- elementId : "resume-preview" ,
125- title : title || "resume" ,
126- pagePadding : globalSettings ?. pagePadding || 0 ,
127- fontFamily : globalSettings ?. fontFamily ,
128- onStart : ( ) => setIsExporting ( true ) ,
129- onEnd : ( ) => setIsExporting ( false ) ,
130- successMessage : tPdf ( "toast.success" ) ,
131- errorMessage : tPdf ( "toast.error" )
132- } ) ;
133- } ;
134-
135- const handleExportJson = ( ) => {
136- exportResumeAsJson ( {
137- resume : activeResume ,
138- title,
139- onStart : ( ) => setIsExportingJson ( true ) ,
140- onEnd : ( ) => setIsExportingJson ( false ) ,
141- successMessage : tPdf ( "toast.jsonSuccess" ) ,
142- errorMessage : tPdf ( "toast.jsonError" )
143- } ) ;
144- } ;
145-
146- const handleExportMarkdown = ( ) => {
147- exportResumeAsMarkdown ( {
148- resume : activeResume ,
149- title,
150- onStart : ( ) => setIsExportingMarkdown ( true ) ,
151- onEnd : ( ) => setIsExportingMarkdown ( false ) ,
152- successMessage : tPdf ( "toast.markdownSuccess" ) ,
153- errorMessage : tPdf ( "toast.markdownError" ) ,
154- markdownOptions : {
155- basicFieldLabels : {
156- name : tBasicField ( "name" ) ,
157- title : tBasicField ( "title" ) ,
158- employementStatus : tBasicField ( "employementStatus" ) ,
159- birthDate : tBasicField ( "birthDate" ) ,
160- email : tBasicField ( "email" ) ,
161- phone : tBasicField ( "phone" ) ,
162- location : tBasicField ( "location" )
163- }
164- }
165- } ) ;
166- } ;
167-
168- const handlePrint = ( ) => {
169- const resumeContent = document . getElementById ( "resume-preview" ) ;
170- if ( ! resumeContent ) {
171- console . error ( "Resume content not found" ) ;
172- return ;
173- }
174- const pagePadding = globalSettings ?. pagePadding || 0 ;
175- exportResumeToBrowserPrint (
176- resumeContent ,
177- pagePadding ,
178- globalSettings ?. fontFamily
179- ) ;
180- } ;
108+ const { globalSettings = { } } = activeResume || { } ;
181109
182110 const { checkConfiguration } = useAIConfiguration ( ) ;
183111
@@ -231,8 +159,6 @@ const PreviewDock = ({
231159 }
232160 } , [ activeResumeId , duplicateResume , router , setActiveResume , t ] ) ;
233161
234- const isLoading = isExporting || isExportingJson || isExportingMarkdown ;
235-
236162 return (
237163 < >
238164 < div className = "hidden md:flex flex-col items-center fixed top-1/2 right-3 transform -translate-y-1/2 z-[50]" >
@@ -314,61 +240,24 @@ const PreviewDock = ({
314240 </ Tooltip >
315241 </ DockIcon >
316242 < DockIcon >
317- < DropdownMenu >
318- < Tooltip >
243+ < Tooltip >
244+ < PdfExport >
319245 < TooltipTrigger asChild >
320- < DropdownMenuTrigger asChild >
321- < div
322- className = { cn (
323- "flex cursor-pointer h-7 w-7 items-center justify-center rounded-lg" ,
324- "hover:bg-gray-100/50 dark:hover:bg-neutral-800/50" ,
325- "transition-all duration-200" ,
326- isLoading && "animate-pulse"
327- ) }
328- >
329- { isLoading ? (
330- < Loader2 className = "h-4 w-4 animate-spin" />
331- ) : (
332- < Download className = "h-4 w-4" />
333- ) }
334- </ div >
335- </ DropdownMenuTrigger >
246+ < button
247+ className = { cn (
248+ "flex cursor-pointer h-7 w-7 items-center justify-center rounded-lg" ,
249+ "hover:bg-gray-100/50 dark:hover:bg-neutral-800/50" ,
250+ "transition-all duration-200"
251+ ) }
252+ >
253+ < Download className = "h-4 w-4" />
254+ </ button >
336255 </ TooltipTrigger >
337- < TooltipContent side = "left" sideOffset = { 10 } >
338- < p > { t ( "export.tooltip" ) } </ p >
339- </ TooltipContent >
340- </ Tooltip >
341- < DropdownMenuContent align = "end" side = "left" >
342- < DropdownMenuItem
343- onClick = { handleExportPdf }
344- disabled = { isLoading }
345- >
346- < Download className = "w-4 h-4 mr-2" />
347- { t ( "export.pdf" ) }
348- </ DropdownMenuItem >
349- < DropdownMenuItem
350- onClick = { handlePrint }
351- disabled = { isLoading }
352- >
353- < Printer className = "w-4 h-4 mr-2" />
354- { t ( "export.print" ) }
355- </ DropdownMenuItem >
356- < DropdownMenuItem
357- onClick = { handleExportJson }
358- disabled = { isLoading }
359- >
360- < FileJson className = "w-4 h-4 mr-2" />
361- { t ( "export.json" ) }
362- </ DropdownMenuItem >
363- < DropdownMenuItem
364- onClick = { handleExportMarkdown }
365- disabled = { isLoading }
366- >
367- < RiMarkdownLine className = "w-4 h-4 mr-2" />
368- { t ( "export.markdown" ) }
369- </ DropdownMenuItem >
370- </ DropdownMenuContent >
371- </ DropdownMenu >
256+ </ PdfExport >
257+ < TooltipContent side = "left" sideOffset = { 10 } >
258+ < p > { t ( "export.tooltip" ) } </ p >
259+ </ TooltipContent >
260+ </ Tooltip >
372261 </ DockIcon >
373262 < DockIcon >
374263 < Tooltip >
0 commit comments