diff --git a/package-lock.json b/package-lock.json index face2eb..56cb2c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "puppeteer": "^24.37.3", "svelte": "^5.51.0", "svelte-check": "^4.1.0", + "svelte-feather-icons": "^4.2.0", "tailwindcss": "^4.1.18", "tslib": "^2.8.1", "typescript": "^5.9.3", @@ -3964,6 +3965,26 @@ "typescript": ">=5.0.0" } }, + "node_modules/svelte-feather-icons": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/svelte-feather-icons/-/svelte-feather-icons-4.2.0.tgz", + "integrity": "sha512-KuMTDrL6sA8aCxBv3RMgmmnnyIaAXaYcmWkmNa2r2Qj70vi+An2T6ZBAdiZr6wjx+a3eZJy+FRseeRkzQFGHPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "svelte": "^3.38.2" + } + }, + "node_modules/svelte-feather-icons/node_modules/svelte": { + "version": "3.59.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", + "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/tailwindcss": { "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", diff --git a/package.json b/package.json index 22451f2..9aa5acb 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "puppeteer": "^24.37.3", "svelte": "^5.51.0", "svelte-check": "^4.1.0", + "svelte-feather-icons": "^4.2.0", "tailwindcss": "^4.1.18", "tslib": "^2.8.1", "typescript": "^5.9.3", diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index 586632c..47b41a7 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -8,12 +8,19 @@
-

- {profile.name} -

-

- {profile.title} -

+
+ {#if profile.avatar} + {profile.name} + {/if} +
+

+ {profile.name} +

+

+ {profile.title} +

+
+

{profile.summary}

diff --git a/src/lib/components/PDFContent.svelte b/src/lib/components/PDFContent.svelte index 5bceb3e..a02b2db 100644 --- a/src/lib/components/PDFContent.svelte +++ b/src/lib/components/PDFContent.svelte @@ -4,6 +4,8 @@ import PDFSection from './PDFSection.svelte'; import PDFTags from './PDFTags.svelte'; import PDFTimelineItem from './PDFTimelineItem.svelte'; + import profilePicture from '$lib/media/profile-picture.jpg'; + import { MailIcon, MapPinIcon, GithubIcon, GlobeIcon } from 'svelte-feather-icons'; let { profile, @@ -26,54 +28,44 @@ class="font-sans max-w-[210mm] mx-auto px-[20mm] py-[18mm] bg-pdf-bg text-pdf-fg leading-relaxed text-sm" > -
-
-

- {profile.name} -

-

{profile.title}

-
-
- {#if profile.email} - - - - - - {profile.email} - - {/if} - - - - - - {profile.location} - -
-
- {#if profile.github} - github.com/{profile.github} - {/if} - {#if profile.website} - {profile.website.replace(/^https?:\/\//, '')} - {/if} +
+
+
+

+ {profile.name} +

+

{profile.title}

+
+ {#if profile.email} + + + {profile.email} + + {/if} + + + {profile.location} + + {#if profile.github} + + + github.com/{profile.github} + + {/if} + {#if profile.website} + + + {profile.website.replace(/^https?:\/\//, '')} + + {/if} +
+
+
+ {profile.name} +
diff --git a/src/lib/components/PDFSection.svelte b/src/lib/components/PDFSection.svelte index 22f979d..c74a702 100644 --- a/src/lib/components/PDFSection.svelte +++ b/src/lib/components/PDFSection.svelte @@ -9,7 +9,7 @@ let { title, children }: Props = $props(); -
+

{title}

diff --git a/src/lib/content/profile.json b/src/lib/content/profile.json index f76a5ae..c44b38c 100644 --- a/src/lib/content/profile.json +++ b/src/lib/content/profile.json @@ -5,5 +5,7 @@ "location": "Espoo - Finnland", "website": "https://joakim.repomaa.com", "github": "repomaa", + "avatar": "src/lib/media/avatar.jpg", + "profilePicture": "src/lib/media/profile-picture.jpg", "summary": "Senior Full-Stack Engineer with deep expertise in Ruby on Rails backends, React/TypeScript frontends, and GraphQL/REST API design. Experienced in AI integration, third-party API integrations, and analyzing large-scale data systems. Fluent in German, Finnish, and English. Passionate about system architecture, performance optimization, clean code, and pragmatic technical decision-making in fast-paced product environments." } diff --git a/src/lib/content/types.ts b/src/lib/content/types.ts index c1086e2..cb26dfc 100644 --- a/src/lib/content/types.ts +++ b/src/lib/content/types.ts @@ -9,6 +9,8 @@ export interface Profile { website?: string; github: string; summary: string; + avatar?: string; + profilePicture?: string; } export interface Experience { diff --git a/src/lib/media/avatar.jpg b/src/lib/media/avatar.jpg new file mode 100644 index 0000000..ab69657 Binary files /dev/null and b/src/lib/media/avatar.jpg differ diff --git a/src/lib/media/profile-picture.jpg b/src/lib/media/profile-picture.jpg new file mode 100644 index 0000000..3f8b131 Binary files /dev/null and b/src/lib/media/profile-picture.jpg differ diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte index e12c3c6..1d71334 100644 --- a/src/routes/admin/+page.svelte +++ b/src/routes/admin/+page.svelte @@ -31,6 +31,13 @@ { name: 'location', label: 'Location', widget: 'string' }, { name: 'website', label: 'Website', widget: 'string', required: false }, { name: 'github', label: 'GitHub', widget: 'string' }, + { name: 'avatar', label: 'Avatar', widget: 'image', required: false }, + { + name: 'profilePicture', + label: 'Profile Picture (for PDF)', + widget: 'image', + required: false, + }, { name: 'summary', label: 'Summary', widget: 'text' }, ], },