cv/cv.tsx

166 lines
4.3 KiB
TypeScript
Raw Normal View History

import { Page, Text, View, Document } from "@react-pdf/renderer";
2023-11-13 12:33:50 +01:00
import ReactPDF from "@react-pdf/renderer";
import fs from "fs";
import { svg, tw } from "./theme/lib";
import SvgLink from "./theme/link";
import Experience, { Exp } from "./theme/experience";
import Education, { Edu } from "./theme/education";
import Certificate, { Cert } from "./theme/certificate";
2023-11-13 12:33:50 +01:00
2023-11-13 19:45:59 +01:00
const divider = (
2023-11-13 19:45:09 +01:00
<View style={tw("w-full mt-4")}>
<View style={tw("w-full border-slate-50 border-b-[.2px]")}></View>
</View>
2023-11-13 19:45:59 +01:00
);
2023-11-13 19:45:09 +01:00
type CV = {
name: string;
description: string;
title: string;
email: string;
github?: string;
website?: string;
upwork?: string;
phone?: string;
experience?: Exp[];
education?: Edu[];
certificates?: Cert[];
};
let data: CV = {} as CV;
const Cv = () => (
2023-11-13 14:10:39 +01:00
<Document
title="CV"
author={data.name}
2023-11-13 14:10:39 +01:00
subject="My professional resume"
creator={`${data.name} with react-pdf`}
producer={`${data.name} with react-pdf`}
keywords={`${data.name} ${data.title}`}
2023-11-13 14:10:39 +01:00
>
<Page
size="A4"
style={tw(
"w-full h-full text-slate-50 bg-gray-900 flex flex-col p-12 text-base"
)}
>
<View style={tw("text-center border-2 border-slate-50 rounded-full")}>
<Text style={tw("text-5xl")}>{data.name}</Text>
<Text>{data.title}</Text>
<View
style={tw("flex flex-row gap-4 w-full text-sm justify-center p-4")}
>
{data.github && (
<SvgLink
text="GitHub"
href={`https://github.com/${data.github}`}
icon={svg.github as any}
/>
)}
{data.upwork && (
<SvgLink
text="Upwork"
href={`https://www.upwork.com/freelancers/${data.upwork}`}
icon={svg.link as any}
/>
)}
<SvgLink
text={data.email}
href={`mailto:${data.email}`}
icon={svg.email as any}
/>
{data.phone && (
<SvgLink
text={data.phone}
href={`tel:${data.phone}`}
icon={svg.phone as any}
/>
)}
{data.website && (
<SvgLink
text={data.website}
href={`https://${data.website}`}
icon={svg.globe as any}
/>
)}
</View>
2023-11-17 09:39:33 +01:00
</View>
<View style={tw("my-auto")}>
{divider}
<Text style={tw("text-2xl mt-2 text-violet-500")}>Experience</Text>
{data.experience?.map((e, i) => (
<Experience
key={i}
to={e.to}
from={e.from}
links={e.links}
company={e.company}
location={e.location}
position={e.position}
feedback={e.feedback}
description={e.description}
/>
))}
2023-11-13 16:58:00 +01:00
{divider}
2023-11-29 12:06:05 +01:00
<Text style={tw("text-2xl mt-2 text-violet-500")}>Education</Text>
{data.education?.map((e, i) => (
<Education
key={i}
to={e.to}
from={e.from}
links={e.links}
institution={e.institution}
location={e.location}
field={e.field}
degree={e.degree}
summary={e.summary}
/>
))}
2023-11-15 17:06:03 +01:00
{divider}
2023-11-29 12:06:05 +01:00
<Text style={tw("text-2xl mt-2 text-violet-500")}>Certificates</Text>
{data.certificates?.map((c, i) => (
<Certificate
key={i}
date={c.date}
links={c.links}
name={c.name}
description={c.description}
issuer={c.issuer}
/>
))}
2023-11-13 16:58:00 +01:00
</View>
</Page>
2023-11-12 18:07:31 +01:00
</Document>
);
const parseData = () => {
const d = fs.readFileSync("./cv.json", { encoding: "utf8" });
const json: CV = JSON.parse(d);
json.experience = json.experience?.map((e) => ({
...e,
from: new Date(e.from),
to: new Date(e.to),
}));
json.education = json.education?.map((e) => ({
...e,
from: new Date(e.from),
to: new Date(e.to),
}));
json.certificates = json.certificates?.map((c) => ({
...c,
date: new Date(c.date),
}));
data = json;
};
2023-11-13 19:45:59 +01:00
const outDir = process.env.out || "./";
const pname = process.env.pname || "cv";
2023-11-12 18:07:31 +01:00
if (!fs.existsSync(outDir)) {
2023-11-13 19:45:59 +01:00
fs.mkdirSync(outDir, { recursive: true });
2023-11-12 18:07:31 +01:00
}
parseData();
ReactPDF.render(<Cv />, `${outDir}/${pname}.pdf`);