Files
cv/app/client/screens/Pdf.tsx
T

80 lines
2.5 KiB
TypeScript

import { useState } from "react";
import type { GeneratedResume } from "../App";
import { ApiRequestError, compilePdf } from "../api";
interface PdfScreenProps {
result: GeneratedResume;
onBack: () => void;
onRecompiled: (result: GeneratedResume) => void;
}
export function PdfScreen({ result, onBack, onRecompiled }: PdfScreenProps) {
const [latex, setLatex] = useState(result.latex);
const [busy, setBusy] = useState(false);
const [error, setError] = useState("");
const dirty = latex !== result.latex;
async function recompile(): Promise<void> {
if (busy) return;
setBusy(true);
setError("");
try {
const blob = await compilePdf(latex);
URL.revokeObjectURL(result.pdfUrl);
onRecompiled({ ...result, latex, pdfUrl: URL.createObjectURL(blob) });
} catch (err) {
if (err instanceof ApiRequestError && err.log) {
setError(`${err.message}\n\n${err.log}`);
} else {
setError(err instanceof Error ? err.message : String(err));
}
} finally {
setBusy(false);
}
}
return (
<div className="pdf-screen">
<header className="topbar">
<button type="button" className="btn ghost" onClick={onBack}>
Back to workspace
</button>
<div className="topbar-title">
<strong>Tailored résumé</strong>
<span className="muted">
plan source: {result.source}
{result.note ? ` (${result.note})` : ""}
</span>
</div>
<div className="topbar-actions">
<button type="button" className="btn" onClick={() => void recompile()} disabled={busy || !dirty}>
{busy ? "Compiling…" : "Recompile"}
</button>
<a className="btn primary" href={result.pdfUrl} download="prad-nukala-resume.pdf">
Download PDF
</a>
</div>
</header>
{error && <pre className="error banner">{error}</pre>}
<div className="pdf-grid">
<section className="panel">
<h2>LaTeX source {dirty && <span className="muted">(edited recompile to refresh preview)</span>}</h2>
<textarea
className="latex-editor"
value={latex}
onChange={(e) => setLatex(e.target.value)}
spellCheck={false}
/>
</section>
<section className="panel">
<h2>Preview</h2>
<iframe className="preview-frame" title="PDF preview" src={result.pdfUrl} />
</section>
</div>
</div>
);
}