Merge advisor profiles

integration/ernaehrung-review
3015418 2026-09-28 12:28:44 +02:00
commit fa74f8bf61
6 changed files with 275 additions and 0 deletions

139
css/berater.css 100644
View File

@ -0,0 +1,139 @@
/* Ahmad: Styles bleiben in .berater-section; Karten passen auch auf Mobilgeraete. */
/* Globale Design-Variablen */
.berater-section {
--bg-dark-1: #0d0d1a;
--bg-dark-2: #1a1a2e;
--accent-teal: #00B3C2;
--text-white: #ffffff;
--text-lightgray: #F8FAFC;
--text-muted: #94A3B8;
--font-display: 'Inter', system-ui, sans-serif;
--font-body: 'Inter', system-ui, sans-serif;
}
.berater-section {
margin: 0;
padding: 0;
font-family: var(--font-body);
background-color: var(--bg-dark-1);
color: var(--text-white);
}
.berater-section {
padding: 80px 20px;
display: flex;
justify-content: center;
}
.berater-section .berater-container {
display: flex;
gap: 30px;
width: 100%;
max-width: 1000px;
flex-wrap: wrap;
justify-content: center;
}
.berater-section .berater-card {
background-color: var(--bg-dark-2);
border-radius: 24px;
padding: 24px;
width: min(380px, 100%);
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.berater-section .berater-image-wrapper {
background-color: var(--bg-dark-1);
border-radius: 20px;
padding: 10px;
margin-bottom: 24px;
}
.berater-section .berater-image-wrapper img {
width: 100%;
height: 350px;
object-fit: cover;
border-radius: 16px;
display: block;
}
.berater-section .berater-name {
margin: 0 0 8px 0;
font-family: var(--font-display);
font-size: 32px;
font-weight: 700;
color: var(--text-white);
}
.berater-section .berater-rolle {
margin: 0 0 24px 0;
font-family: var(--font-body);
font-size: 14px;
color: var(--accent-teal);
text-transform: uppercase;
letter-spacing: 1.5px;
font-weight: 600;
}
.berater-section .berater-bio-box {
background-color: var(--bg-dark-1);
border-radius: 16px;
padding: 24px;
flex-grow: 1;
}
.berater-section .bio-title {
margin: 0 0 16px 0;
font-size: 16px;
font-weight: 600;
color: var(--text-lightgray);
}
.berater-section .bio-text {
margin: 0;
font-size: 15px;
line-height: 1.6;
color: var(--text-muted);
}
/* Styling für dynamische Listen (Zertifikate) */
.berater-section .berater-liste {
margin: 8px 0 0 0;
padding-left: 20px;
color: var(--text-muted);
font-size: 14px;
line-height: 1.6;
}
.berater-section .berater-liste li {
margin-bottom: 4px;
}
/* Styling für dynamische Links (Buttons) */
.berater-section .berater-links {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.berater-section .berater-link-btn {
display: inline-block;
background-color: var(--accent-teal);
color: var(--bg-dark-1);
text-decoration: none;
padding: 8px 16px;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
transition: background-color 0.3s ease;
}
.berater-section .berater-link-btn:hover {
background-color: #0d9668;
color: #ffffff;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

View File

@ -11,7 +11,9 @@
<link rel="stylesheet" href="css/site.css"> <link rel="stylesheet" href="css/site.css">
<link rel="stylesheet" href="css/produktuebersicht.css"> <link rel="stylesheet" href="css/produktuebersicht.css">
<link rel="stylesheet" href="css/leistungen.css"> <link rel="stylesheet" href="css/leistungen.css">
<link rel="stylesheet" href="css/berater.css">
<script src="js/leistungen.js" defer></script> <script src="js/leistungen.js" defer></script>
<script src="js/berater.js" defer></script>
</head> </head>
<body> <body>
@ -88,6 +90,12 @@
<div class="pakete__grid"></div> <div class="pakete__grid"></div>
</section> </section>
<!-- Ahmad: Berater und Qualifikationen -->
<section class="berater-section" id="berater" aria-label="Berater und Qualifikationen">
<!-- Container wird durch berater.js befüllt -->
<div class="berater-container" id="berater-container"></div>
</section>
</main> </main>
</body> </body>

82
js/berater.js 100644
View File

@ -0,0 +1,82 @@
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('berater-container');
fetch('json/berater.json')
.then(response => {
if (!response.ok) throw new Error('Fehler beim Laden der JSON');
return response.json();
})
.then(beraterDaten => {
beraterDaten.forEach(berater => {
const card = document.createElement('div');
card.className = 'berater-card';
// 1. Bekannte Listen und Zusätze verarbeiten
let zertifikateHtml = '';
if (berater.zertifikate && berater.zertifikate.length > 0) {
zertifikateHtml = `<h4 class="bio-title" style="margin-top: 16px;">Zertifikate</h4><ul class="berater-liste">`;
berater.zertifikate.forEach(zert => {
zertifikateHtml += `<li>${zert}</li>`;
});
zertifikateHtml += `</ul>`;
}
let linksHtml = '';
if (berater.links && berater.links.length > 0) {
linksHtml = `<div class="berater-links">`;
berater.links.forEach(link => {
linksHtml += `<a href="${link.url}" target="_blank" class="berater-link-btn">${link.text}</a>`;
});
linksHtml += `</div>`;
}
let zusatzHtml = '';
if (berater.zusatzInfo) {
zusatzHtml = `<p class="berater-zusatz">${berater.zusatzInfo}</p>`;
}
// 2. NEU: Alle eigenen/unbekannten Felder automatisch generieren
// Wir definieren zuerst, welche Felder Standard sind und ignoriert werden sollen
const standardFelder = ['id', 'name', 'role', 'image', 'bioTitle', 'bioText', 'zertifikate', 'links', 'zusatzInfo'];
let eigeneFelderHtml = '';
// Wir durchlaufen jeden Eintrag in der JSON für diesen Berater
for (const [schluessel, wert] of Object.entries(berater)) {
// Wenn das Feld kein Standardfeld ist, bauen wir daraus Überschrift + Text
if (!standardFelder.includes(schluessel)) {
eigeneFelderHtml += `
<h4 class="bio-title" style="margin-top: 16px; text-transform: capitalize;">${schluessel}</h4>
<p class="bio-text">${wert}</p>
`;
}
}
// 3. Die Karte zusammenbauen
card.innerHTML = `
<div class="berater-image-wrapper">
<img src="${berater.image}" alt="${berater.name} Profilbild">
</div>
<h2 class="berater-name">${berater.name}</h2>
<h3 class="berater-rolle">${berater.role}</h3>
<div class="berater-bio-box">
<h4 class="bio-title">${berater.bioTitle}</h4>
<p class="bio-text">${berater.bioText}</p>
<!-- Hier werden deine eigenen JSON-Einträge wie "bla bla bla" platziert -->
${eigeneFelderHtml}
${zusatzHtml}
${zertifikateHtml}
${linksHtml}
</div>
`;
container.appendChild(card);
});
})
.catch(error => {
console.error('Fehler:', error);
container.innerHTML = '<p style="color: #94A3B8;">Daten konnten nicht geladen werden.</p>';
});
});

46
json/berater.json 100644
View File

@ -0,0 +1,46 @@
[
{
"id": 1,
"name": "Relindis Agethen ",
"role": "TRIATHLET UND ERNÄHRUNGSBERATERIN",
"image": "img/relindis_agethen.png",
"bioTitle": "Kurzbiografie",
"bioText": "Relindis Agethen, genannt Lilli, ist seit 16 Jahren im Triathlon aktiv und bringt starke sportliche Erfolge mit: Vize-Europameisterin, Deutsche Meisterin und mehrfache Baden-Württembergische Meisterin. Als zertifizierte Ernährungsberaterin für Sportler B-Lizenz ergänzt sie das Team um Leistungsentwicklung und Ernährungswissen.",
"zertifikate": [
"Zertifizierter Triathlon-Trainer",
"Ernährungscoach B-Lizenz"
],
"links": [
{
"text": "Instagram Profil",
"url": "https://instagram.com/lili"
},
{
"text": "Trainingsplan buchen",
"url": "https://tri-hub.de/booking"
}
]
},
{
"id": 2,
"name": "Relindis Agethen ",
"role": "TRIATHLET UND ERNÄHRUNGSBERATERIN",
"image": "img/relindis_agethen_1.jpg",
"bioTitle": "Kurzbiografie",
"bioText": "Relindis Agethen, genannt Lilli, ist seit 16 Jahren im Triathlon aktiv und bringt starke sportliche Erfolge mit: Vize-Europameisterin, Deutsche Meisterin und mehrfache Baden-Württembergische Meisterin. Als zertifizierte Ernährungsberaterin für Sportler B-Lizenz ergänzt sie das Team um Leistungsentwicklung und Ernährungswissen.",
"zertifikate": [
"Zertifizierter Triathlon-Trainer",
"Ernährungscoach B-Lizenz"
],
"links": [
{
"text": "Instagram Profil",
"url": "https://instagram.com/lili"
},
{
"text": "Trainingsplan buchen",
"url": "https://tri-hub.de/booking"
}
]
}
]