Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Robert Eggl - Personal Website

A modern, responsive personal portfolio website built with Next.js 15, showcasing my work as a Software Engineer and Master's Student specializing in Cloud Computing, Full-Stack Development, and AI.
A modern, responsive personal portfolio website built with Next.js 15, showcasing my work as a Fullstack Developer and Business Process Consultant at SAP.

## 🚀 Features

Expand Down
3 changes: 2 additions & 1 deletion app/blog/[slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { allBlogs } from 'contentlayer/generated'
import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { PERSON_JOB_TITLE } from '@/lib/structured-data'

interface BlogPostLayoutProps {
children: React.ReactNode
Expand Down Expand Up @@ -84,7 +85,7 @@ const generateJsonLd = (post: (typeof allBlogs)[0]) => ({
'@type': 'Person',
name: 'Robert Eggl',
url: 'https://eggl.dev',
jobTitle: "Software Engineer & Master's Student"
jobTitle: PERSON_JOB_TITLE
},
publisher: {
'@type': 'Person',
Expand Down
3 changes: 2 additions & 1 deletion app/blog/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Metadata } from 'next'
import { PERSON_JOB_TITLE } from '@/lib/structured-data'

export const metadata: Metadata = {
title: 'The Blog. - Robert Eggl',
Expand Down Expand Up @@ -48,7 +49,7 @@ const jsonLd = {
'@type': 'Person',
name: 'Robert Eggl',
url: 'https://eggl.dev',
jobTitle: "Software Engineer & Master's Student"
jobTitle: PERSON_JOB_TITLE
},
publisher: {
'@type': 'Person',
Expand Down
32 changes: 17 additions & 15 deletions app/components/sections/about-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,25 @@ const AboutSection = () => {
const aboutCards = [
{
icon: <Code size={24} className="text-foreground" />,
title: 'Cloud Engineering',
title: 'Enterprise Software',
description:
'Building scalable systems with Rust, Kubernetes, and modern architecture patterns.',
'Developing fullstack solutions at SAP with modern architectures and cloud-native technologies.',
bgColor: '#0090ce',
gradient: 'from-[#0090ce]/20 to-[#0090ce]/5'
},
{
icon: <GraduationCap size={24} className="text-foreground" />,
title: 'AI & Security',
title: 'Business Consulting',
description:
'Combining AI knowledge with security engineering principles.',
'Bridging business processes and technology as a business process consultant.',
bgColor: '#00a2a2',
gradient: 'from-[#00a2a2]/20 to-[#00a2a2]/5'
},
{
icon: <Laptop size={24} className="text-foreground" />,
title: 'Web Development',
title: 'Full-Stack Development',
description:
'Creating responsive applications with React, Next.js, and GraphQL.',
'Creating responsive applications with React, Next.js, TypeScript, and GraphQL.',
bgColor: '#ea3e94',
gradient: 'from-[#ea3e94]/20 to-[#ea3e94]/5'
},
Expand Down Expand Up @@ -210,21 +210,23 @@ const AboutSection = () => {

<div className="space-y-6 text-base md:text-lg">
<p>
Cloud Engineering specialist with expertise in Data Science and
modern web technologies. Currently pursuing an M.Sc. in Cloud
Applications and Security Engineering.
Fullstack Developer and Business Process Consultant at SAP, with
a background in cloud engineering, AI, and enterprise software.
I hold an M.Sc. in Cloud Applications and Security Engineering
and a B.Sc. in Artificial Intelligence from Technische
Hochschule Ingolstadt.
</p>

<p>
I build scalable solutions ranging from cloud-native
applications to data pipelines, focusing on robust architectures
and security principles.
I build scalable solutions—from enterprise business processes to
cloud-native applications—with a focus on robust architectures
and practical delivery.
</p>

<p>
Beyond my professional roles, I'm an active open-source
contributor and community builder through the Neuland Ingolstadt
e.V. student association.
Beyond my professional role, I'm an active open-source
contributor and helped build the Neuland Campus App, used by
thousands of students at TH Ingolstadt.
</p>
</div>

Expand Down
93 changes: 90 additions & 3 deletions app/components/sections/education-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { motion, useScroll, useTransform } from 'framer-motion'
import {
Award,
BookOpen,
Briefcase,
Calendar,
ChevronRight,
GraduationCap
Expand Down Expand Up @@ -47,9 +48,9 @@ const EducationSection = () => {
{
degree: 'M.Sc. Cloud Applications and Security Engineering',
institution: 'Technische Hochschule Ingolstadt',
period: '10/2024 - Present',
period: '10/2024 - 06/2026',
description:
'Specializing in Security Engineering, Cloud-Native Development, and practical industry projects.',
'Specialized in Security Engineering, Cloud-Native Development, and practical industry projects. Completed with a master thesis on simulation-based optimization at MBDA Deutschland.',
achievements: [
'IT Security: Focus on Security Engineering, Computer Forensics, and Network Security',
'Cloud-Native Development: Experience with Software Architectures, Virtualization, CI/CD, and Orchestration'
Expand All @@ -72,6 +73,22 @@ const EducationSection = () => {
}
]

const experience = [
{
role: 'Fullstack Developer & Business Process Consultant',
company: 'SAP',
period: '03/2026 - Present',
description:
'Working in Service & Delivery, building enterprise fullstack solutions and consulting on business processes with a focus on cloud-native development and AI.',
achievements: [
'Fullstack development for enterprise software and service delivery',
'Business process consulting bridging technology and customer needs'
],
icon: Briefcase,
color: '#0070f2'
}
]

return (
<section
id="education"
Expand Down Expand Up @@ -172,9 +189,79 @@ const EducationSection = () => {
</div>

<div className="container-custom relative z-10">
<SectionHeader number="04" title="Education" />
<SectionHeader number="04" title="Experience & Education" />

<div className="mt-20 space-y-12">
{experience.map((item, index) => (
<motion.div
key={`experience-${index}`}
className="relative backdrop-blur-md bg-background/50 p-8 border-2 border-foreground shadow-[8px_8px_0px_0px_rgba(250,250,250,0.8)] group hover:shadow-[12px_12px_0px_0px_rgba(250,250,250,0.8)]"
variants={cardVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-100px' }}
custom={index}
>
<div className="flex flex-col md:flex-row md:items-center justify-between pb-6 mb-6 border-b border-foreground/20">
<div className="flex items-start md:items-center">
<div
className="p-3 mr-4 hidden md:flex"
style={{ backgroundColor: item.color }}
>
<item.icon size={24} className="text-foreground" />
</div>
<h3 className="font-mono text-2xl font-bold">{item.role}</h3>
</div>
<div className="flex items-center mt-2 md:mt-0 font-mono text-sm bg-foreground text-background py-1 px-3 self-start">
<Calendar size={16} className="mr-2" />
<span>{item.period}</span>
</div>
</div>

<div className="mb-6">
<p className="font-bold text-xl">{item.company}</p>
</div>

<div className="mb-8">
<p className="text-foreground/70 text-lg">{item.description}</p>
</div>

<div className="relative">
<div className="absolute -left-4 top-0 bottom-0 w-1 bg-accent" />
<h4 className="font-mono font-bold text-lg mb-4 flex items-center">
<Award
size={18}
className="mr-2"
style={{ color: item.color }}
/>
Key Responsibilities
</h4>
<ul className="space-y-4">
{item.achievements.map((achievement, achieveIndex) => (
<motion.li
key={achieveIndex}
className="flex items-start"
variants={listItemVariants}
initial="hidden"
whileInView="visible"
custom={achieveIndex}
viewport={{ once: true }}
>
<ChevronRight
size={16}
className="mr-2 mt-1"
style={{ color: item.color }}
/>
<span>{achievement}</span>
</motion.li>
))}
</ul>
</div>

<div className="absolute inset-0 bg-gradient-to-r from-accent/0 via-accent/10 to-accent/0 opacity-0 group-hover:opacity-100 transition-opacity" />
</motion.div>
))}

{education.map((item, index) => (
<motion.div
key={index}
Expand Down
5 changes: 2 additions & 3 deletions app/components/sections/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Github, GithubIcon, Linkedin, Mail } from 'lucide-react'
import Link from 'next/link'
import { PERSON_TAGLINE } from '@/lib/structured-data'

const Footer = () => {
const currentYear = new Date().getFullYear()
Expand All @@ -11,9 +12,7 @@ const Footer = () => {
<div className="flex flex-col md:flex-row items-center justify-between">
<div className="mb-6 md:mb-0">
<p className="font-mono font-bold text-xl">Robert Eggl</p>
<p className="text-muted-foreground">
Software Engineer & Master's Student
</p>
<p className="text-muted-foreground">{PERSON_TAGLINE}</p>
</div>

<div className="flex gap-4">
Expand Down
16 changes: 7 additions & 9 deletions app/components/sections/hero-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,13 @@ const HeroSection = () => {
transition={{ delay: 2, duration: 1 }}
>
<p className="text-xl text-foreground/90 max-w-2xl mb-12 leading-relaxed font-light">
Full Stack Developer focusing on{' '}
Fullstack Developer and Business Process Consultant at{' '}
<span className="text-accent font-normal">SAP</span>, building
enterprise solutions with a focus on{' '}
<span className="text-accent font-normal">
Cloud Computing
Cloud-Native Development
</span>{' '}
and{' '}
<span className="text-accent font-normal">
Software Development
</span>{' '}
with a passion for{' '}
<span className="text-accent font-normal">
Artificial Intelligence
</span>
Expand Down Expand Up @@ -335,7 +333,7 @@ const HeroSection = () => {
className="text-accent group-hover:scale-110 transition-transform"
/>
</div>
<span className="font-mono">Cloud Native</span>
<span className="font-mono">SAP</span>
</div>
<div className="absolute inset-0 bg-gradient-to-r from-accent/0 via-accent/10 to-accent/0 opacity-0 group-hover:opacity-100 transition-opacity" />
</motion.div>
Expand All @@ -354,7 +352,7 @@ const HeroSection = () => {
className="text-accent group-hover:scale-110 transition-transform"
/>
</div>
<span className="font-mono">AI/ML</span>
<span className="font-mono">Enterprise AI</span>
</div>
<div className="absolute inset-0 bg-gradient-to-r from-accent/0 via-accent/10 to-accent/0 opacity-0 group-hover:opacity-100 transition-opacity" />
</motion.div>
Expand All @@ -373,7 +371,7 @@ const HeroSection = () => {
className="text-accent group-hover:scale-110 transition-transform"
/>
</div>
<span className="font-mono">App Dev</span>
<span className="font-mono">Consulting</span>
</div>
<div className="absolute inset-0 bg-gradient-to-r from-accent/0 via-accent/10 to-accent/0 opacity-0 group-hover:opacity-100 transition-opacity" />
</motion.div>
Expand Down
18 changes: 10 additions & 8 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ import { JsonLd } from './components/json-ld'
import Navbar from './components/neo-navbar'
import Footer from './components/sections/footer'
import Provider from './contexts/provider'
import { createWebsiteJsonLd } from './lib/structured-data'
import {
createWebsiteJsonLd,
PERSON_DESCRIPTION,
PERSON_TAGLINE
} from './lib/structured-data'

export const metadata: Metadata = {
title: "Robert Eggl - Software Engineer & Master's Student",
description:
"Portfolio of Robert Eggl, Software Engineer and Master's Student specializing in Cloud Computing, Full-Stack Development, and AI.",
title: `Robert Eggl - ${PERSON_TAGLINE}`,
description: PERSON_DESCRIPTION,
keywords:
'Robert Eggl, Software Engineer, Cloud Computing, Full-Stack Development, Artificial Intelligence, Cloud Engineering, Open Source, Portfolio',
'Robert Eggl, SAP, Fullstack Developer, Business Process Consultant, Enterprise Software, Cloud Computing, Full-Stack Development, Artificial Intelligence, Open Source, Portfolio',
authors: [{ name: 'Robert Eggl' }],
robots: 'index, follow',
openGraph: {
title: "Robert Eggl - Software Engineer & Master's Student",
description:
"Portfolio of Robert Eggl, Software Engineer and Master's Student specializing in Cloud Computing, Full-Stack Development, and AI.",
title: `Robert Eggl - ${PERSON_TAGLINE}`,
description: PERSON_DESCRIPTION,
type: 'website',
url: 'https://eggl.dev'
},
Expand Down
17 changes: 11 additions & 6 deletions app/lib/structured-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ export const SITE_URL = 'https://eggl.dev'
export const PERSON_ID = `${SITE_URL}/#person`
export const WEBSITE_ID = `${SITE_URL}/#website`

const PERSON_DESCRIPTION =
"Portfolio of Robert Eggl, Software Engineer and Master's Student specializing in Cloud Computing, Full-Stack Development, and AI."
export const PERSON_JOB_TITLE =
'Fullstack Developer & Business Process Consultant'

export const PERSON_TAGLINE = `${PERSON_JOB_TITLE} @ SAP`

export const PERSON_DESCRIPTION =
'Portfolio of Robert Eggl, Fullstack Developer and Business Process Consultant at SAP, specializing in enterprise software, cloud-native development, and AI.'

export const personSameAs = [
'https://www.linkedin.com/in/roberteggl',
Expand Down Expand Up @@ -86,11 +91,11 @@ export function createProfilePageJsonLd({
url: SITE_URL,
image: 'https://github.com/Robert27.png',
description: PERSON_DESCRIPTION,
jobTitle: "Software Engineer & Master's Student",
jobTitle: PERSON_JOB_TITLE,
sameAs: personSameAs,
worksFor: {
'@type': 'CollegeOrUniversity',
name: 'Technische Hochschule Ingolstadt'
'@type': 'Organization',
name: 'SAP'
},
alumniOf: {
'@type': 'CollegeOrUniversity',
Expand All @@ -115,7 +120,7 @@ export function createProfilePageJsonLd({
'@type': 'ProfilePage',
'@id': `${SITE_URL}/#profilepage`,
url: SITE_URL,
name: "Robert Eggl - Software Engineer & Master's Student",
name: `Robert Eggl - ${PERSON_TAGLINE}`,
dateCreated: '2020-10-01T00:00:00Z',
dateModified,
isPartOf: { '@id': WEBSITE_ID },
Expand Down
6 changes: 3 additions & 3 deletions app/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { MetadataRoute } from 'next'
import { PERSON_DESCRIPTION, PERSON_TAGLINE } from '@/lib/structured-data'

export default function manifest(): MetadataRoute.Manifest {
return {
name: "Robert Eggl - Software Engineer & Master's Student",
name: `Robert Eggl - ${PERSON_TAGLINE}`,
short_name: 'Robert Eggl',
description:
"Portfolio of Robert Eggl, Software Engineer and Master's Student specializing in Cloud Computing, Full-Stack Development, and AI.",
description: PERSON_DESCRIPTION,
start_url: '/',
display: 'standalone',
background_color: '#000000',
Expand Down
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { createProfilePageJsonLd } from '@/lib/structured-data'

export default async function HomePage() {
const NEO_MARQUEE_TEXT =
'Full-Stack Development • Cloud Engineering • Artificial IntelligenceOpen Source • Cloud Native Technologies • Software DevelopmentData EngineeringMobile Development'
'Full-Stack Development • SAP • Enterprise AIBusiness Process Consulting • Cloud Engineering • Open SourceSoftware DevelopmentArtificial Intelligence'

const posts = allBlogs.sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
Expand Down
Loading