import React, { useState } from "react";
import { useTranslations } from "@/i18n/compat/client";
import { Download, Loader2, ChevronDown, ShieldCheck } from "lucide-react";
import { useResumeStore } from "@/store/useResumeStore";
import { Button } from "@/components/ui/button";
import { exportResumeAsJson, exportResumeAsMarkdown, exportToPdf } from "@/utils/export";
import { exportResumeToBrowserPrint } from "@/utils/print";
import { cn } from "@/lib/utils";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import {
PdfGlassIcon,
PrintGlassIcon,
JsonGlassIcon,
MarkdownGlassIcon,
} from "./GlassIcons";
const ExportCard = ({
icon: Icon,
title,
description,
onClick,
isLoading,
bgGradientClass,
hoverBorderClass,
}: {
icon: React.ElementType | any,
title: string,
description: string,
onClick: () => void,
isLoading: boolean,
bgGradientClass?: string,
hoverBorderClass?: string,
}) => {
return (
{
if (!isLoading) onClick();
}}
className={cn(
"group relative flex flex-col justify-center overflow-hidden p-6 pl-[136px] min-h-[130px] rounded-3xl border border-border/50 bg-card text-card-foreground shadow-sm transition-all duration-500",
isLoading ? "opacity-70 cursor-not-allowed" : cn("cursor-pointer hover:shadow-2xl active:scale-[0.98] hover:-translate-y-1 hover:bg-muted/10", hoverBorderClass)
)}
>
{/* 顶部内发光高光,增加卡片立体感 */}
{/* 底部环境光晕,让图标色渗入背景 */}
{/* 调整后的图标层:完全收入卡片内部,尺寸克制 */}
{/* 文本内容说明 */}
);
};
const PdfExport = ({ children }: { children?: React.ReactNode }) => {
const [isOpen, setIsOpen] = useState(false);
const [isExporting, setIsExporting] = useState(false);
const [isPrinting, setIsPrinting] = useState(false);
const [isExportingJson, setIsExportingJson] = useState(false);
const [isExportingMarkdown, setIsExportingMarkdown] = useState(false);
const { activeResume } = useResumeStore();
const { globalSettings = {}, title } = activeResume || {};
const t = useTranslations("pdfExport");
const tBasicField = useTranslations("workbench.basicPanel.basicFields");
const handleExport = async () => {
await exportToPdf({
elementId: "resume-preview",
title: title || "resume",
pagePadding: globalSettings?.pagePadding || 0,
fontFamily: globalSettings?.fontFamily,
onStart: () => setIsExporting(true),
onEnd: () => setIsExporting(false),
successMessage: t("toast.success"),
errorMessage: t("toast.error")
});
};
const handleJsonExport = () => {
exportResumeAsJson({
resume: activeResume,
title,
onStart: () => setIsExportingJson(true),
onEnd: () => setIsExportingJson(false),
successMessage: t("toast.jsonSuccess"),
errorMessage: t("toast.jsonError")
});
};
const handleMarkdownExport = () => {
exportResumeAsMarkdown({
resume: activeResume,
title,
onStart: () => setIsExportingMarkdown(true),
onEnd: () => setIsExportingMarkdown(false),
successMessage: t("toast.markdownSuccess"),
errorMessage: t("toast.markdownError"),
markdownOptions: {
basicFieldLabels: {
name: tBasicField("name"),
title: tBasicField("title"),
employementStatus: tBasicField("employementStatus"),
birthDate: tBasicField("birthDate"),
email: tBasicField("email"),
phone: tBasicField("phone"),
location: tBasicField("location")
}
}
});
};
const handlePrint = async () => {
const resumeContent = document.getElementById("resume-preview");
if (!resumeContent) {
console.error("Resume content not found");
return;
}
try {
setIsPrinting(true);
const pagePadding = globalSettings?.pagePadding || 0;
await exportResumeToBrowserPrint(
resumeContent,
pagePadding,
globalSettings?.fontFamily
);
} finally {
setIsPrinting(false);
}
};
const isLoading = isExporting || isExportingJson || isExportingMarkdown || isPrinting;
const loadingText = isExporting
? t("button.exporting")
: isExportingJson
? t("button.exportingJson")
: isExportingMarkdown
? t("button.exportingMarkdown")
: isPrinting
? t("button.exporting")
: "";
return (
);
};
export default PdfExport;