GG
This commit is contained in:
parent
63a63b444c
commit
0bfe88ddf2
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
node_modules
|
||||
outputs
|
||||
pid
|
||||
|
15
README.md
Normal file
15
README.md
Normal 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.
|
211
cv.tsx
211
cv.tsx
@ -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`);
|
||||
|
||||
|
14
flake.nix
14
flake.nix
@ -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;
|
||||
|
19
package.json
19
package.json
@ -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
22
tsconfig.json
Normal 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
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user