diff --git a/src/components/FeatureCardsGrid.tsx b/src/components/FeatureCardsGrid.tsx
new file mode 100644
index 0000000..d8a6e4e
--- /dev/null
+++ b/src/components/FeatureCardsGrid.tsx
@@ -0,0 +1,58 @@
+import type { Service } from '../data/Service';
+
+interface FeatureCardsGridProps {
+ featureCards: Service[];
+}
+
+export default function FeatureCardsGrid({ featureCards }: FeatureCardsGridProps) {
+ return (
+
+
My Areas of Expertise
+
+
+ {featureCards.map((card, index) => {
+ const IconComponent = card.icon;
+ const cardId = card.title.toLowerCase().replaceAll(/\s+/g, '-');
+ return (
+
+
+
+
+ {card.description}
+
+
+
+ {/* Status indicator for screen readers */}
+
+ Expertise area {index + 1} of {featureCards.length}
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/components/sections/AboutSection.tsx b/src/components/sections/AboutSection.tsx
index 2ada3d9..faf3f93 100644
--- a/src/components/sections/AboutSection.tsx
+++ b/src/components/sections/AboutSection.tsx
@@ -1,5 +1,6 @@
import { Code, Palette, ShieldCheck, Eye } from 'lucide-react';
import { useLanguage } from '../../contexts/LanguageContext';
+import FeatureCardsGrid from '../FeatureCardsGrid';
import type { Service } from '../../data/Service';
import saschaImage from '../../assets/sascha.png';
@@ -28,7 +29,7 @@ export default function AboutSection(props: AboutSectionProps = {}) {
icon: [Code, Palette, ShieldCheck, Eye][index] || Code,
title: card.title,
description: card.description,
- colorClass: ["primary", "secondary", "tertiary", "quaternary"][index] || "primary"
+ colorClass: (["primary", "secondary", "tertiary", "quaternary"][index] || "primary") as "primary" | "secondary" | "tertiary" | "quaternary"
}))
} = props;
@@ -79,54 +80,7 @@ export default function AboutSection(props: AboutSectionProps = {}) {
{/* Feature Cards Grid */}
-
-
My Areas of Expertise
-
-
- {featureCards.map((card, index) => {
- const IconComponent = card.icon;
- const cardId = card.title.toLowerCase().replaceAll(/\s+/g, '-');
- return (
-
-
-
-
- {card.description}
-
-
-
- {/* Status indicator for screen readers */}
-
- Expertise area {index + 1} of {featureCards.length}
-
-
- );
- })}
-
-
+
);
diff --git a/src/components/sections/CertificationsSection.tsx b/src/components/sections/CertificationsSection.tsx
index a04aea4..36c4640 100644
--- a/src/components/sections/CertificationsSection.tsx
+++ b/src/components/sections/CertificationsSection.tsx
@@ -1,5 +1,6 @@
import { Award } from 'lucide-react';
import { useLanguage } from '../../contexts/LanguageContext';
+import { certificationsData } from '../../config/certifications-config';
import type { Certification } from '../../data/Certification';
interface CertificationsSectionProps {
@@ -17,12 +18,7 @@ export default function CertificationsSection(props: CertificationsSectionProps
const {
title = texts.title,
subtitle = texts.subtitle,
- certifications = texts.certificationItems.map((cert, index) => ({
- name: cert.name,
- issuer: cert.issuer,
- year: ["2025", "2025", "2020", "2020", "2015"][index] || "2025",
- icon: ""
- }))
+ certifications = certificationsData
} = props;
// Sort certifications by year in descending order (newest first)
diff --git a/src/config/certifications-config.ts b/src/config/certifications-config.ts
new file mode 100644
index 0000000..b58b17d
--- /dev/null
+++ b/src/config/certifications-config.ts
@@ -0,0 +1,46 @@
+import { certifications } from './locales/en/certifications';
+import type { Certification } from '../data/Certification';
+
+const getCertificationText = (id: number) => {
+ const item = certifications.certificationItems.find(c => c.id === id);
+ if (!item) throw new Error(`Certification with id ${id} not found`);
+ return item;
+};
+
+export const certificationsData: Certification[] = [
+ {
+ id: 1,
+ name: getCertificationText(1).name,
+ issuer: getCertificationText(1).issuer,
+ year: '2025',
+ icon: '',
+ },
+ {
+ id: 2,
+ name: getCertificationText(2).name,
+ issuer: getCertificationText(2).issuer,
+ year: '2025',
+ icon: '',
+ },
+ {
+ id: 3,
+ name: getCertificationText(3).name,
+ issuer: getCertificationText(3).issuer,
+ year: '2020',
+ icon: '',
+ },
+ {
+ id: 4,
+ name: getCertificationText(4).name,
+ issuer: getCertificationText(4).issuer,
+ year: '2020',
+ icon: '',
+ },
+ {
+ id: 5,
+ name: getCertificationText(5).name,
+ issuer: getCertificationText(5).issuer,
+ year: '2015',
+ icon: '',
+ },
+].sort((a, b) => Number.parseInt(b.year) - Number.parseInt(a.year));
diff --git a/src/config/locales/de/certifications.ts b/src/config/locales/de/certifications.ts
index 5227ecc..39bb08c 100644
--- a/src/config/locales/de/certifications.ts
+++ b/src/config/locales/de/certifications.ts
@@ -3,22 +3,27 @@ export const certifications = {
subtitle: 'Meine beruflichen Qualifikationen und kontinuierliche Weiterbildung',
certificationItems: [
{
+ id: 1,
name: 'Practical Prompt Engineering Masterclass: Hands-On Learning',
issuer: 'Udemy Kurs - Asif Farooqi, Abdullah Dar',
},
{
+ id: 2,
name: 'Understanding Typescript',
issuer: 'Udemy Kurs - Maximilian Schwarzmüller',
},
{
+ id: 3,
name: 'Angular Step by Step',
issuer: 'Udemy Kurs - Shivprasad Koirala',
},
{
+ id: 4,
name: 'Angular and Typescript',
issuer: 'LinkedIn TestDome',
},
{
+ id: 5,
name: 'Bachelor of Science in Informatik',
issuer: 'TU Darmstadt',
},
diff --git a/src/config/locales/en/certifications.ts b/src/config/locales/en/certifications.ts
index 5591266..7b9db80 100644
--- a/src/config/locales/en/certifications.ts
+++ b/src/config/locales/en/certifications.ts
@@ -3,22 +3,27 @@ export const certifications = {
subtitle: 'My professional qualifications and continuous learning',
certificationItems: [
{
+ id: 1,
name: 'Practical Prompt Engineering Masterclass: Hands-On Learning',
issuer: 'Udemy Lecture - Asif Farooqi, Abdullah Dar',
},
{
+ id: 2,
name: 'Understanding Typescript',
issuer: 'Udemy Lecture - Maximilian Schwarzmüller',
},
{
+ id: 3,
name: 'Angular Step by Step',
issuer: 'Udemy Lecture - Shivprasad Koirala',
},
{
+ id: 4,
name: 'Angular and Typescript',
issuer: 'LinkedIn TestDome',
},
{
+ id: 5,
name: 'Bachelor of Science in Computer Science',
issuer: 'TU Darmstadt',
},