Skip to content

Commit b327175

Browse files
committed
0.2.0 cover letter, expression, suggestion
1 parent 444355a commit b327175

File tree

4 files changed

+153
-74
lines changed

4 files changed

+153
-74
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
# Changelog
1+
# Bounteer Changelog
2+
3+
## [0.2.0] - 2025-09-25
4+
### Modified
5+
- landing page fix
6+
- ### Added
7+
- cover letter generation
8+
- expression card
29

310
## [0.1.5] - 2025-09-20
411
### Added

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"use client";
2+
3+
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
4+
import { Button } from "@/components/ui/button";
5+
import { Download, ArrowUp } from "lucide-react";
6+
7+
type Report = {
8+
cover_letter?: string;
9+
submission?: {
10+
job_description?: {
11+
role_name?: string;
12+
company_name?: string;
13+
};
14+
user_created?: { first_name?: string; last_name?: string };
15+
};
16+
};
17+
18+
interface CoverLetterCardProps {
19+
report: Report;
20+
candidateName: string;
21+
roleName: string;
22+
companyName: string;
23+
}
24+
25+
export default function CoverLetterCard({ report, candidateName, roleName, companyName }: CoverLetterCardProps) {
26+
const generateCoverLetterPDF = () => {
27+
if (!report?.cover_letter) return;
28+
29+
// Create a temporary div for the cover letter content
30+
const tempDiv = document.createElement('div');
31+
tempDiv.style.position = 'absolute';
32+
tempDiv.style.left = '-9999px';
33+
tempDiv.style.width = '210mm';
34+
tempDiv.style.padding = '20mm';
35+
tempDiv.style.fontFamily = 'Arial, sans-serif';
36+
tempDiv.style.fontSize = '12px';
37+
tempDiv.style.lineHeight = '1.6';
38+
tempDiv.style.color = 'black';
39+
tempDiv.style.backgroundColor = 'white';
40+
41+
tempDiv.innerHTML = `
42+
<div style="text-align: center; margin-bottom: 40px; border-bottom: 2px solid #000; padding-bottom: 20px;">
43+
<h1 style="margin: 0; font-size: 24px; font-weight: bold;">Cover Letter</h1>
44+
<p style="margin: 10px 0 0 0; font-size: 14px; color: #666;">${candidateName} - ${roleName} @ ${companyName}</p>
45+
</div>
46+
<div style="white-space: pre-wrap; text-align: justify;">${report.cover_letter}</div>
47+
`;
48+
49+
document.body.appendChild(tempDiv);
50+
51+
const printWindow = window.open('', '_blank');
52+
if (printWindow) {
53+
printWindow.document.write(`
54+
<html>
55+
<head>
56+
<title>Cover Letter - ${candidateName}</title>
57+
<style>
58+
@media print {
59+
body { margin: 0; }
60+
@page { margin: 20mm; }
61+
}
62+
</style>
63+
</head>
64+
<body>
65+
${tempDiv.innerHTML}
66+
</body>
67+
</html>
68+
`);
69+
printWindow.document.close();
70+
printWindow.print();
71+
}
72+
73+
// Clean up
74+
document.body.removeChild(tempDiv);
75+
};
76+
77+
if (!report.cover_letter) return null;
78+
79+
return (
80+
<Card className="w-full">
81+
<CardHeader>
82+
<CardTitle className="text-center text-lg">
83+
Cover Letter
84+
</CardTitle>
85+
</CardHeader>
86+
<CardContent className="space-y-6">
87+
<div className="text-center">
88+
<p className="text-sm text-gray-600 mb-4">
89+
Personalized cover letter generated based on your profile and the job requirements.
90+
</p>
91+
</div>
92+
93+
{/* Cover Letter Preview */}
94+
<h3 className="text-sm font-medium text-gray-900 mb-3">Preview</h3>
95+
<div className="bg-gray-50 rounded-lg p-4 max-h-64 overflow-y-auto">
96+
<div className="text-sm text-gray-800 whitespace-pre-wrap leading-relaxed">
97+
{report.cover_letter}
98+
</div>
99+
</div>
100+
101+
{/* Prompt Section */}
102+
<div className="filter grayscale opacity-50 pointer-events-none">
103+
<p className="text-sm text-gray-800 mb-3">
104+
Want to personalize your cover letter further? Use the prompt below to regenerate it with specific requirements or tone adjustments.
105+
</p>
106+
<div className="relative">
107+
<input
108+
type="text"
109+
placeholder="Coming soon... (e.g., 'Make it more formal', 'Add emphasis on leadership experience')"
110+
className="w-full px-4 py-3 pr-12 text-sm border rounded-full focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent"
111+
disabled
112+
/>
113+
<button className="absolute right-2 top-1/2 -translate-y-1/2 p-2 bg-primary-600 hover:bg-primary-700 text-white rounded-full focus:outline-none focus:ring-offset-2" disabled>
114+
<ArrowUp className="h-4 w-4" />
115+
</button>
116+
</div>
117+
<div className="absolute inset-0 flex items-center justify-center">
118+
<span className="bg-white px-4 py-2 rounded-full text-sm font-bold text-gray-800 shadow-lg border">
119+
Coming Soon
120+
</span>
121+
</div>
122+
</div>
123+
124+
<Button
125+
onClick={generateCoverLetterPDF}
126+
className="flex items-center gap-2 mx-auto"
127+
>
128+
<Download className="h-4 w-4" />
129+
Download Cover Letter PDF
130+
</Button>
131+
</CardContent>
132+
</Card>
133+
);
134+
}

src/components/interactive/ReportCard.tsx

Lines changed: 10 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { getUserProfile, getLoginUrl, type UserProfile } from '@/lib/utils';
1111
import { Checkbox } from "@/components/ui/checkbox";
1212
import LoginMask from './LoginMask';
1313
import PrintableReport from './PrintableReport';
14+
import CoverLetterCard from './CoverLetterCard';
1415

1516
type Report = {
1617
id: string;
@@ -91,56 +92,6 @@ export default function ReportCard() {
9192
documentTitle: `Role-Fit-Report-${reportId || 'unknown'}`,
9293
});
9394

94-
const generateCoverLetterPDF = () => {
95-
if (!report?.cover_letter) return;
96-
97-
// Create a temporary div for the cover letter content
98-
const tempDiv = document.createElement('div');
99-
tempDiv.style.position = 'absolute';
100-
tempDiv.style.left = '-9999px';
101-
tempDiv.style.width = '210mm';
102-
tempDiv.style.padding = '20mm';
103-
tempDiv.style.fontFamily = 'Arial, sans-serif';
104-
tempDiv.style.fontSize = '12px';
105-
tempDiv.style.lineHeight = '1.6';
106-
tempDiv.style.color = 'black';
107-
tempDiv.style.backgroundColor = 'white';
108-
109-
tempDiv.innerHTML = `
110-
<div style="text-align: center; margin-bottom: 40px; border-bottom: 2px solid #000; padding-bottom: 20px;">
111-
<h1 style="margin: 0; font-size: 24px; font-weight: bold;">Cover Letter</h1>
112-
<p style="margin: 10px 0 0 0; font-size: 14px; color: #666;">${candidateName()} - ${roleName} @ ${companyName}</p>
113-
</div>
114-
<div style="white-space: pre-wrap; text-align: justify;">${report.cover_letter}</div>
115-
`;
116-
117-
document.body.appendChild(tempDiv);
118-
119-
const printWindow = window.open('', '_blank');
120-
if (printWindow) {
121-
printWindow.document.write(`
122-
<html>
123-
<head>
124-
<title>Cover Letter - ${candidateName()}</title>
125-
<style>
126-
@media print {
127-
body { margin: 0; }
128-
@page { margin: 20mm; }
129-
}
130-
</style>
131-
</head>
132-
<body>
133-
${tempDiv.innerHTML}
134-
</body>
135-
</html>
136-
`);
137-
printWindow.document.close();
138-
printWindow.print();
139-
}
140-
141-
// Clean up
142-
document.body.removeChild(tempDiv);
143-
};
14495

14596
const handleTalentPoolOptIn = async () => {
14697
if (!report || !currentUser) return;
@@ -729,28 +680,15 @@ export default function ReportCard() {
729680
</CardContent>
730681
</Card>
731682

732-
{/* Cover Letter Card - Separate from report */}
733-
{report.cover_letter && (
734-
<Card className="w-full mt-6">
735-
<CardHeader>
736-
<CardTitle className="text-center text-lg">
737-
Cover Letter
738-
</CardTitle>
739-
</CardHeader>
740-
<CardContent className="text-center">
741-
<p className="text-sm text-gray-600 mb-4">
742-
Personalized cover letter generated based on your profile and the job requirements.
743-
</p>
744-
<Button
745-
onClick={generateCoverLetterPDF}
746-
className="flex items-center gap-2 mx-auto"
747-
>
748-
<Download className="h-4 w-4" />
749-
Download Cover Letter PDF
750-
</Button>
751-
</CardContent>
752-
</Card>
753-
)}
683+
{/* Cover Letter Card - Separate component */}
684+
<div className="mt-6">
685+
<CoverLetterCard
686+
report={report}
687+
candidateName={candidateName()}
688+
roleName={roleName}
689+
companyName={companyName}
690+
/>
691+
</div>
754692

755693
{/* Hidden printable component */}
756694
<div style={{ display: 'none' }}>

0 commit comments

Comments
 (0)