This commit is contained in:
Ivan Dimitrov 2023-11-13 13:33:50 +02:00
parent 63a63b444c
commit 0bfe88ddf2
8 changed files with 260 additions and 25 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules
outputs
pid

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# react-cv
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.0.7. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.

BIN
bun.lockb

Binary file not shown.

211
cv.tsx
View File

@ -1,29 +1,196 @@
import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
import ReactPDF from '@react-pdf/renderer';
import fs from "fs"
import { Page, Text, View, Document, Link } from "@react-pdf/renderer";
import ReactPDF from "@react-pdf/renderer";
import fs from "fs";
import { createTw } from "react-pdf-tailwind";
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
type Experience = {
company: string
position: string
location: string
from: Date
to: Date
description: string
technologies: string[]
}
const tw = createTw({
});
const MyDocument = () => (
const link = "no-underline text-red-50"
const section = "w-full flex flex-col m-4"
const divider =
<View style={tw("w-full mt-4")}>
<View style={tw("w-full border-slate-50 border-b-[.02px]")}></View>
</View>
const github =
<Link src="https://github.com/ivandimitrov8080" style={tw(link)}>github/ivandimitrov8080</Link>
const upwork =
<Link src="https://www.upwork.com/freelancers/idimitrov" style={tw(link)}>upwork/freelancers/idimitrov</Link>
const resume =
<Link src="https://www.idimitrov.dev" style={tw(link)}>idimitrov.dev</Link>
const email =
<Link src="mailto:ivan@idimitrov.dev" style={tw(link)}>ivan@idimitrov.dev</Link>
const tech = {
android: [
"Android",
"Android Studio",
],
java: [
"Java",
"JPA",
"Hibernate",
"Spring Framework",
"Spring Boot",
"Lombok",
"Spring MVC",
"Thymeleaf",
"JSP",
"JSTL",
"XML",
"Spring Security",
"OAuth2",
"H2",
"Spring Boot Actuator",
],
web: [
"JavaScript",
"TypeScript",
"React",
"HTML",
"CSS"
],
api: [
"REST",
"SOAP",
],
db: [
"MySQL",
"PostgreSQL"
],
linux: [
"Linux",
"Bash",
"coreutils",
"Ubuntu",
"CentOS",
"RHEL",
"SSH",
"iptables",
"systemd",
"vim",
"Monit",
"CLI",
],
hybris: [
"SAP hybris",
"ZK Framework",
],
payment: [
"PayPal",
"Adyen",
"V12",
"Wells Fargo Open Banking APIs",
]
}
const techKeys = [...Object.keys(tech)] as const
const cnetTech: string[] = techKeys
.filter(e => !e.includes("hybris"))
.filter(e => !e.includes("payment"))
// @ts-ignore
.map(e => tech[e]).flat()
const raTech: string[] = techKeys
// @ts-ignore
.map(e => tech[e]).flat()
const experience = ({
company,
position,
location,
from,
to,
description,
technologies
}: Experience) => (
<View style={tw("w-full flex flex-col mt-2 border-2 border-slate-50 p-4 rounded-2xl")}>
<View style={tw("flex flex-row flex-wrap gap-1")}>
<Text>{position}</Text>
<Text>at</Text>
<Text>{company}, {location}</Text>
<Text>from</Text>
<Text>{from.toDateString()}</Text>
<Text>to</Text>
<Text>{to.toDateString()}</Text>
</View>
<View style={tw("m-4")}>
<Text>{description}</Text>
</View>
<View style={tw("flex flex-row flex-wrap")}>
{technologies.map(t => (
<View key={t} style={tw("flex flex-row items-center")}>
<View style={tw("border-2 border-teal-200 h-1 mx-1 mb-1 rounded-full")}></View>
<Text style={tw("text-sm")}>{t}</Text>
</View>
))}
</View>
</View>
)
const Links = () => (
<View style={tw("flex flex-row gap-4 w-full text-sm justify-center p-4")}>
{github}
{upwork}
{email}
{resume}
</View>
)
const Experience = () => (
<View style={tw(section)}>
<Text style={tw("text-3xl")}>Experience</Text>
{experience({
company: "Central Net",
position: "Software Developer",
location: "Blagoevgrad, Bulgaria",
from: new Date("May 2016"),
to: new Date("May 2020"),
description: "Developed a full-stack web app helping students book exams, browse resources, see events, news and more.",
technologies: cnetTech
})}
{experience({
company: "RA Creative",
position: "Software Developer",
location: "Nottingham, UK",
from: new Date("Dec 2020"),
to: new Date("20 Jan 2023"),
description: "Worked on seven international eCommerce web apps serving customers in the US and Europe.",
technologies: raTech
})}
</View>
)
const Intro = () => (
<View style={tw("text-center border-2 border-slate-50 rounded-full")}>
<Text style={tw("text-5xl")}>Ivan K. Dimitrov</Text>
<Text style={tw("text-sm")}>Software Developer</Text>
<Links />
</View>
)
const CV = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
</View>
<Page
size="A4"
style={tw("w-full h-full text-slate-50 bg-slate-950 flex flex-col p-12 text-base")}>
<Intro />
{divider}
<Experience />
</Page>
</Document>
);
@ -35,5 +202,5 @@ if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir, { recursive: true })
}
ReactPDF.render(<MyDocument />, `${outDir}/${pname}.pdf`);
ReactPDF.render(<CV />, `${outDir}/${pname}.pdf`);

View File

@ -22,11 +22,23 @@
nativeBuildInputs = with pkgs; [
nodejs_20
bun
inotify-tools
];
shellHook = ''
echo "$$" > ./pid
monitor() {
while true; do
inotifywait -e modify ${pname}.tsx > /dev/null 2>&1
make
pkill -HUP mupdf
done
}
monitor > /dev/null 2>&1 &
'';
in
{
devShells.default = pkgs.mkShell {
inherit pname buildInputs nativeBuildInputs;
inherit pname buildInputs nativeBuildInputs shellHook;
};
packages.default = pkgs.stdenv.mkDerivation {
inherit buildInputs nativeBuildInputs pname version src;

1
index.ts Normal file
View File

@ -0,0 +1 @@
console.log("Hello via Bun!");

View File

@ -1 +1,18 @@
{ "dependencies": { "@react-pdf/renderer": "^3.1.14", "@types/node": "^20.9.0", "@types/react": "^18.2.37", "react": "^18.2.0" } }
{
"name": "cv",
"module": "cv.tsx",
"type": "module",
"devDependencies": {
"bun-types": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"@react-pdf/renderer": "^3.1.14",
"@types/node": "^20.9.0",
"@types/react": "^18.2.37",
"react": "^18.2.0",
"react-pdf-tailwind": "^2.1.0"
}
}

22
tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"allowImportingTsExtensions": true,
"noEmit": true,
"composite": true,
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"types": [
"bun-types" // add Bun global
]
}
}