Private
Public Access
1
0

feat: add projects component

- add projects section to data.json
- add projects types
- add css variables
- update headline styles
- rename intro to profile
This commit is contained in:
2026-01-25 17:11:35 +01:00
parent bc680f6870
commit 8ce5bb4fb5
8 changed files with 215 additions and 23 deletions

View File

@@ -76,7 +76,7 @@
div { div {
font-size: 0.875rem; font-size: 0.875rem;
color: var(--color-text-secondary); color: var(--color-text-tertiary);
text-align: center; text-align: center;
} }
</style> </style>

View File

@@ -1,18 +1,18 @@
<script lang="ts"> <script lang="ts">
import type { Intro } from '$lib/types/data'; import type { Profile } from '$lib/types/data';
import profileImage from '$lib/assets/images/profile_picture.png'; import profileImage from '$lib/assets/images/profile_picture.png';
let { name, title, text }: Intro = $props(); let { name, title, anchorId, text }: Profile = $props();
</script> </script>
<section> <section id={anchorId}>
<div> <div>
<div class="image-wrapper"> <div class="image-wrapper">
<img src={profileImage} alt=""> <img src={profileImage} alt="">
</div> </div>
<h1>{name}</h1> <h1>{name}</h1>
<h2>{title}</h2> <p class="title">{title}</p>
<p>{text}</p> <p class="text">{text}</p>
</div> </div>
</section> </section>
@@ -33,7 +33,7 @@
div { div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: stretch;
justify-content: center; justify-content: center;
gap: 1rem; gap: 1rem;
@@ -65,11 +65,7 @@
margin: unset; margin: unset;
color: transparent; color: transparent;
font-size: 2.25rem; font-size: 2.25rem;
background-image: linear-gradient( background-image: var(--color-headline-background-image);
to right,
var(--color-intro-subtitle-text-primary) 0%,
var(--color-intro-subtitle-text-secondary) 60%,
var(--color-intro-subtitle-text-tertiary) 100%);
background-clip: text; background-clip: text;
@media (min-width: 768px) { @media (min-width: 768px) {
@@ -77,7 +73,7 @@
} }
} }
h2 { .title {
margin: unset; margin: unset;
margin-bottom: 1rem; margin-bottom: 1rem;
@@ -89,7 +85,7 @@
} }
} }
p { .text {
margin: unset; margin: unset;
color: var(--color-intro-text); color: var(--color-intro-text);
font-size: 1.125rem; font-size: 1.125rem;

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import type { ProjectEntry } from '$lib/types/data';
let {
title,
description,
taskHeadline,
tasks,
toolsHeadline,
tools
}: ProjectEntry = $props();
</script>
<article>
</article>
<style>
</style>

View File

@@ -0,0 +1,63 @@
<script lang="ts">
import type { Projects } from '$lib/types/data';
import ProjectEntry from '$lib/components/ProjectEntry.svelte';
let { title, anchorId, subtitle, entries }: Projects = $props();
</script>
<section id={anchorId}>
<h2>{title}</h2>
{#if (subtitle)}
<p>{subtitle}</p>
{/if}
<div>
{#each entries as entry, i (i)}
<ProjectEntry {...entry} />
{/each}
</div>
</section>
<style>
section {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: center;
gap: 1rem;
padding: 5rem 1rem;
@media (min-width: 768px) {
padding: 6rem 2.5rem;
}
}
h2 {
margin: unset;
font-size: 1.875rem;
text-align: center;
color: transparent;
background-image: var(--color-headline-background-image);
background-clip: text;
@media (min-width: 768px) {
font-size: 3rem;
}
}
p {
margin: unset;
margin-bottom: 2rem;
font-size: 1.125rem;
text-align: center;
color: var(--color-text-secondary);
@media (min-width: 768px) {
font-size: 1.25rem;
}
}
</style>

View File

@@ -26,9 +26,93 @@
}, },
"copyright": "© 2026 Adrian Fennert. Alle Rechte vorbehalten." "copyright": "© 2026 Adrian Fennert. Alle Rechte vorbehalten."
}, },
"intro": { "profile": {
"name": "Adrian Fennert", "name": "Adrian Fennert",
"title": "Senior Fullstack Engineer", "title": "Senior Fullstack Engineer",
"anchorId": "profile",
"text": "Erfahrener Full-Stack Developer mit Fokus auf moderne Web-Technologien. Spezialisiert auf skalierbare Anwendungen, Teamführung und Integration komplexer Systeme. Leidenschaft für sauberen Code und benutzerzentrierte Lösungen." "text": "Erfahrener Full-Stack Developer mit Fokus auf moderne Web-Technologien. Spezialisiert auf skalierbare Anwendungen, Teamführung und Integration komplexer Systeme. Leidenschaft für sauberen Code und benutzerzentrierte Lösungen."
},
"projects": {
"title": "Projekte",
"anchorId": "projects",
"subtitle": "Aktuelle und Vergangenne Projekte and denen ich erfolgreich mitgewirkt habe",
"entries": [
{
"title": "Custom Frontend für GPT-Anwendung mit Dokumentenverwaltung",
"description": "Entwicklung einer modernen Single-Page-Application für die interne KI-Nutzung mit umfassender Dokumentenverwaltung.",
"taskHeadline": "Tätigkeiten",
"tasks": "Konzeption und Implementierung benutzerspezifischer Dokument-Kollektionen, Integration von MSAL für SSO.",
"toolsHeadline": "Tools",
"tools": [
"Next.JS",
"assistant-ui",
"Microsoft Authentication Library",
"Typescript",
"Model Context Protocol - MCP"
]
},
{
"title": "B2B-Customer-Portal Erweiterung",
"description": "Erweiterung eines Portals für Produktregistrierungen und Garantieabwicklungen.",
"taskHeadline": "Tätigkeiten",
"tasks": "Umsetzung kundenspezifischer Prozesse, Optimierung der User Journeys in Zusammenarbeit mit Fachbereichen.",
"toolsHeadline": "Tools",
"tools": [
"SAP Commerce Cloud",
"SAP Composable Storefront",
"Smartedit",
"Angular",
"Typescript"
]
},
{
"title": "Frontend Lead für B2B-Portal",
"description": "Fachliche Führung und Entwicklung eines Customer-Portals.",
"taskHeadline": "Tätigkeiten",
"tasks": "Coaching des Teams, Know-how-Aufbau in Angular und Spartacus, Integration von Such- und IAM-Diensten.",
"toolsHeadline": "Tools",
"tools": [
"SAP Commerce Cloud",
"SAP Composable Storefront",
"Smartedit",
"Angular",
"Typescript",
"Keyloak",
"Coveo"
]
},
{
"title": "Backend-Migrationen und Testframework upgrades",
"description": "Migration von Testumgebungen und Integrations-Frameworks.",
"taskHeadline": "Tätigkeiten",
"tasks": "Upgrade Unit- und Integrationstests, Migration Apache Camel zu Spring Integration.",
"toolsHeadline": "Tools",
"tools": [
"SAP Commerce Cloud",
"Spring Boot",
"Spring Integration",
"SAP Integration Suite",
"Typescript",
"OData",
"SAP ERP"
]
},
{
"title": "Storefront-Migration zu SPA",
"description": "Rolling-Release-Migration und Neuentwicklung eines Online-Shops.",
"taskHeadline": "Tätigkeiten",
"tasks": "Integration Suchdienst und Headless CMS.",
"toolsHeadline": "Tools",
"tools": [
"SAP Commerce Cloud",
"Spring Boot",
"React",
"Next.JS",
"Typescript",
"Algolia",
"Contentful"
]
}
]
} }
} }

View File

@@ -2,7 +2,9 @@
--color-body-background: oklch(0.21 0.034 264.665); --color-body-background: oklch(0.21 0.034 264.665);
--color-text-primary: oklch(0.872 0.01 258.338); --color-text-primary: oklch(0.872 0.01 258.338);
--color-text-secondary: oklch(0.551 0.027 264.364); --color-text-secondary: oklch(0.707 0.022 261.325);
--color-text-tertiary: oklch(0.551 0.027 264.364);
--color-header-border: oklab(0.623 -0.0378409 -0.210628 / 0.3); --color-header-border: oklab(0.623 -0.0378409 -0.210628 / 0.3);
--color-header-background: oklab(0.21 -0.00316128 -0.0338527 / 0.95); --color-header-background: oklab(0.21 -0.00316128 -0.0338527 / 0.95);
@@ -16,9 +18,15 @@
--color-intro-image-background-secondary: oklch(0.511 0.262 276.966); --color-intro-image-background-secondary: oklch(0.511 0.262 276.966);
--color-intro-text: oklch(0.967 0.003 264.542); --color-intro-text: oklch(0.967 0.003 264.542);
--color-intro-title-text: oklch(0.809 0.105 251.813); --color-intro-title-text: oklch(0.809 0.105 251.813);
--color-intro-subtitle-text-primary: oklch(0.707 0.165 254.624);
--color-intro-subtitle-text-secondary: oklch(0.673 0.182 276.935); --color-headline-primary: oklch(0.707 0.165 254.624);
--color-intro-subtitle-text-tertiary: oklch(0.714 0.203 305.504); --color-headline-secondary: oklch(0.673 0.182 276.935);
--color-headline-tertiary: oklch(0.714 0.203 305.504);
--color-headline-background-image: linear-gradient(
to right,
var(--color-headline-primary) 0%,
var(--color-headline-secondary) 60%,
var(--color-headline-tertiary) 100%);
--z-index-header: 50; --z-index-header: 50;
} }
@@ -37,4 +45,5 @@ html, body {
margin: unset; margin: unset;
background-color: var(--color-body-background); background-color: var(--color-body-background);
font-family: 'AdwaitaSans', 'AdwaitaMono', sans-serif; font-family: 'AdwaitaSans', 'AdwaitaMono', sans-serif;
scroll-behavior: smooth;
} }

View File

@@ -1,7 +1,8 @@
export type Data = { export type Data = {
header: Header; header: Header;
footer: Footer; footer: Footer;
intro: Intro; profile: Profile;
projects: Projects;
}; };
export type Header = { export type Header = {
@@ -24,8 +25,25 @@ export type FooterLink = {
export type FooterLinkKey = 'git' | 'linkedin'; export type FooterLinkKey = 'git' | 'linkedin';
export type Intro = { export type Profile = {
name: string; name: string;
title: string; title: string;
anchorId: string;
text: string; text: string;
} }
export type Projects = {
title: string;
anchorId: string;
subtitle?: string;
entries: ProjectEntry[];
};
export type ProjectEntry = {
title: string;
description: string;
taskHeadline: string;
tasks: string;
toolsHeadline: string;
tools: string[];
}

View File

@@ -1,9 +1,11 @@
<script lang="ts"> <script lang="ts">
import content from '$lib/data/data.json'; import content from '$lib/data/data.json';
import type { Data } from '$lib/types/data'; import type { Data } from '$lib/types/data';
import Intro from '$lib/components/Intro.svelte'; import Profile from '$lib/components/Profile.svelte';
import Projects from '$lib/components/Projects.svelte';
let data: Data = content; let data: Data = content;
</script> </script>
<Intro {...data.intro} /> <Profile {...data.profile} />
<Projects {...data.projects} />