This commit is contained in:
2026-09-03 21:57:48 +02:00
parent 496e8bdb27
commit 6d31656ce4
13 changed files with 1090 additions and 51 deletions
+130
View File
@@ -0,0 +1,130 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 344" role="img" aria-labelledby="t-akad">
<title id="t-akad">Akademia Wodociągowca - obieg kompetencji: praktyka wdrożeniowa i doradcza zasila platformę kursową, a wyszkolone zespoły wracają z pytaniami z rynku</title>
<defs>
<pattern id="akad-grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M20 0H0v20" fill="none" stroke="#5980a6" stroke-opacity=".13" stroke-width="1"/>
</pattern>
<marker id="akad-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 10 5 0 10z" fill="#5980a6"/>
</marker>
<style><![CDATA[
/* Rysunek powstaje jak na ploterze: linie same się kreślą.
pathLength="1" sprawia, że długość ścieżki nie ma znaczenia. */
.draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: akad-draw 1.1s ease-out forwards; }
.d1 { animation-delay: .05s } .d2 { animation-delay: .3s }
.d3 { animation-delay: .55s } .d4 { animation-delay: .8s }
@keyframes akad-draw { to { stroke-dashoffset: 0 } }
.fade { opacity: 0; animation: akad-fade .5s ease-out forwards; }
.f1 { animation-delay: .5s } .f2 { animation-delay: .75s }
.f3 { animation-delay: 1s } .f4 { animation-delay: 1.25s }
@keyframes akad-fade { to { opacity: 1 } }
/* Przepływ wiedzy - kreska sunie w stronę odbiorcy. */
.flow { stroke-dasharray: 7 7; animation: akad-flow 1.4s linear infinite; }
@keyframes akad-flow { to { stroke-dashoffset: -14 } }
.pulse { animation: akad-pulse 2s ease-in-out infinite; }
@keyframes akad-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@media (prefers-reduced-motion: reduce) {
.draw, .fade, .flow, .pulse {
animation: none; stroke-dashoffset: 0; stroke-dasharray: none; opacity: 1;
}
}
]]></style>
</defs>
<rect width="720" height="344" fill="#eaeef2"/>
<rect width="720" height="344" fill="url(#akad-grid)"/>
<!-- ── Źródła wiedzy ─────────────────────────────────────────────────── -->
<g stroke="#416180" stroke-width="1.5" fill="#f2f2f3">
<rect class="draw d1" pathLength="1" x="40" y="66" width="150" height="44"/>
<rect class="draw d1" pathLength="1" x="40" y="124" width="150" height="44"/>
<rect class="draw d1" pathLength="1" x="40" y="182" width="150" height="44"/>
</g>
<g fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif" font-size="10.5"
text-anchor="middle" class="fade f1">
<text x="115" y="92" textLength="120" lengthAdjust="spacingAndGlyphs">WDROŻENIA U KLIENTÓW</text>
<text x="115" y="150" textLength="112" lengthAdjust="spacingAndGlyphs">PROJEKTY DORADCZE</text>
<text x="115" y="208" textLength="120" lengthAdjust="spacingAndGlyphs">PYTANIA CZYTELNIKÓW</text>
</g>
<text x="40" y="46" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="11" textLength="90" lengthAdjust="spacingAndGlyphs" opacity=".72" class="fade f1">CO ROBIMY</text>
<!-- zbiorczy przepływ do Akademii -->
<g stroke="#5980a6" stroke-width="1.8" fill="none">
<path class="draw d2" pathLength="1" d="M190 88 H228 V146"/>
<path class="draw d2" pathLength="1" d="M190 146 H228"/>
<path class="draw d2" pathLength="1" d="M190 204 H228 V146"/>
<path class="flow" d="M228 146 H266" marker-end="url(#akad-arrow)"/>
</g>
<!-- ── Akademia Wodociągowca ─────────────────────────────────────────── -->
<rect class="draw d3" pathLength="1" x="270" y="96" width="200" height="150"
fill="#5980a6" stroke="#416180" stroke-width="1.5"/>
<rect x="270" y="96" width="200" height="34" fill="#1d2d3d" class="fade f2"/>
<text x="370" y="119" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="14" font-weight="600" text-anchor="middle"
textLength="164" lengthAdjust="spacingAndGlyphs" class="fade f2">AKADEMIA WODOCIĄGOWCA</text>
<!-- znacznik transmisji na żywo -->
<g class="fade f3">
<rect x="286" y="144" width="46" height="15" fill="#1d2d3d"/>
<circle cx="295" cy="151.5" r="3" fill="#f2f2f3" class="pulse"/>
<text x="303" y="155" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" textLength="24" lengthAdjust="spacingAndGlyphs">LIVE</text>
</g>
<!-- ekran kursu -->
<g stroke="#f2f2f3" stroke-width="1.6" fill="none" class="fade f3">
<rect x="286" y="170" width="52" height="36"/>
<path d="M352 178h102M352 188h74M352 198h102"/>
</g>
<path d="m305 182 12 6-12 6z" fill="#f2f2f3" class="fade f3"/>
<text x="370" y="230" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="10" text-anchor="middle" opacity=".92"
textLength="176" lengthAdjust="spacingAndGlyphs" class="fade f3">WEBINARIA · KURSY · CERTYFIKATY</text>
<!-- ── Zespoły w przedsiębiorstwach ──────────────────────────────────── -->
<path class="flow" d="M470 171 H516" stroke="#5980a6" stroke-width="1.8" fill="none" marker-end="url(#akad-arrow)"/>
<text x="493" y="160" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" text-anchor="middle" textLength="44" lengthAdjust="spacingAndGlyphs" class="fade f3">WIEDZA</text>
<rect class="draw d4" pathLength="1" x="520" y="96" width="160" height="150" fill="#f2f2f3" stroke="#416180" stroke-width="1.5"/>
<rect x="520" y="96" width="160" height="30" fill="#5980a6" fill-opacity=".2" class="fade f4"/>
<text x="600" y="116" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="11" font-weight="600" text-anchor="middle"
textLength="132" lengthAdjust="spacingAndGlyphs" class="fade f4">ZESPOŁY W FIRMACH</text>
<g stroke="#416180" stroke-width="1.5" fill="none" class="fade f4">
<circle cx="558" cy="152" r="11"/><path d="M542 182v-12a16 16 0 0 1 32 0v12"/>
<circle cx="600" cy="152" r="11"/><path d="M584 182v-12a16 16 0 0 1 32 0v12"/>
<circle cx="642" cy="152" r="11"/><path d="M626 182v-12a16 16 0 0 1 32 0v12"/>
</g>
<g fill="#5980a6" fill-opacity=".24" class="fade f4">
<circle cx="558" cy="152" r="11"/><circle cx="600" cy="152" r="11"/><circle cx="642" cy="152" r="11"/>
</g>
<!-- certyfikat -->
<g class="fade f4">
<rect x="556" y="200" width="88" height="26" fill="#f2f2f3" stroke="#416180" stroke-width="1.4"/>
<path d="m566 213 5 5 9-11" stroke="#5980a6" stroke-width="2" fill="none"/>
<text x="608" y="217" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" text-anchor="middle" textLength="46" lengthAdjust="spacingAndGlyphs">CERTYFIKAT</text>
</g>
<!-- ── Pętla zwrotna: rynek podpowiada tematy ────────────────────────── -->
<path class="draw d4" pathLength="1" d="M600 246 V310 H115 V232" stroke="#5980a6" stroke-width="1.8"
fill="none" marker-end="url(#akad-arrow)"/>
<rect x="276" y="298" width="172" height="22" fill="#eaeef2" class="fade f4"/>
<text x="362" y="314" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="10.5" text-anchor="middle" textLength="158" lengthAdjust="spacingAndGlyphs" class="fade f4">PYTANIA WRACAJĄ DO PROGRAMU</text>
<!-- ── krzyżyki rejestracyjne ────────────────────────────────────────── -->
<g stroke="#1d1f20" stroke-width="1" opacity=".45">
<path d="M263 89v13M257 95h13"/>
<path d="M477 89v13M471 95h13"/>
<path d="M263 241v13M257 247h13"/>
<path d="M477 241v13M471 247h13"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

+130
View File
@@ -0,0 +1,130 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 344" role="img" aria-labelledby="t-akad">
<title id="t-akad">Akademia Wodociagowca - the competence loop: our delivery and advisory practice feeds the course platform, and trained teams come back with questions from the market</title>
<defs>
<pattern id="akad-grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M20 0H0v20" fill="none" stroke="#5980a6" stroke-opacity=".13" stroke-width="1"/>
</pattern>
<marker id="akad-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 10 5 0 10z" fill="#5980a6"/>
</marker>
<style><![CDATA[
/* Rysunek powstaje jak na ploterze: linie same sie kresla.
pathLength="1" sprawia, ze dlugosc sciezki nie ma znaczenia. */
.draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: akad-draw 1.1s ease-out forwards; }
.d1 { animation-delay: .05s } .d2 { animation-delay: .3s }
.d3 { animation-delay: .55s } .d4 { animation-delay: .8s }
@keyframes akad-draw { to { stroke-dashoffset: 0 } }
.fade { opacity: 0; animation: akad-fade .5s ease-out forwards; }
.f1 { animation-delay: .5s } .f2 { animation-delay: .75s }
.f3 { animation-delay: 1s } .f4 { animation-delay: 1.25s }
@keyframes akad-fade { to { opacity: 1 } }
/* Przeplyw wiedzy - kreska sunie w strone odbiorcy. */
.flow { stroke-dasharray: 7 7; animation: akad-flow 1.4s linear infinite; }
@keyframes akad-flow { to { stroke-dashoffset: -14 } }
.pulse { animation: akad-pulse 2s ease-in-out infinite; }
@keyframes akad-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@media (prefers-reduced-motion: reduce) {
.draw, .fade, .flow, .pulse {
animation: none; stroke-dashoffset: 0; stroke-dasharray: none; opacity: 1;
}
}
]]></style>
</defs>
<rect width="720" height="344" fill="#eaeef2"/>
<rect width="720" height="344" fill="url(#akad-grid)"/>
<!-- ── Zrodla wiedzy ─────────────────────────────────────────────────── -->
<g stroke="#416180" stroke-width="1.5" fill="#f2f2f3">
<rect class="draw d1" pathLength="1" x="40" y="66" width="150" height="44"/>
<rect class="draw d1" pathLength="1" x="40" y="124" width="150" height="44"/>
<rect class="draw d1" pathLength="1" x="40" y="182" width="150" height="44"/>
</g>
<g fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif" font-size="10.5"
text-anchor="middle" class="fade f1">
<text x="115" y="92" textLength="120" lengthAdjust="spacingAndGlyphs">CLIENT ROLLOUTS</text>
<text x="115" y="150" textLength="112" lengthAdjust="spacingAndGlyphs">ADVISORY PROJECTS</text>
<text x="115" y="208" textLength="120" lengthAdjust="spacingAndGlyphs">READER QUESTIONS</text>
</g>
<text x="40" y="46" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="11" textLength="90" lengthAdjust="spacingAndGlyphs" opacity=".72" class="fade f1">WHAT WE DO</text>
<!-- zbiorczy przepływ do Akademii -->
<g stroke="#5980a6" stroke-width="1.8" fill="none">
<path class="draw d2" pathLength="1" d="M190 88 H228 V146"/>
<path class="draw d2" pathLength="1" d="M190 146 H228"/>
<path class="draw d2" pathLength="1" d="M190 204 H228 V146"/>
<path class="flow" d="M228 146 H266" marker-end="url(#akad-arrow)"/>
</g>
<!-- ── Akademia Wodociągowca ─────────────────────────────────────────── -->
<rect class="draw d3" pathLength="1" x="270" y="96" width="200" height="150"
fill="#5980a6" stroke="#416180" stroke-width="1.5"/>
<rect x="270" y="96" width="200" height="34" fill="#1d2d3d" class="fade f2"/>
<text x="370" y="119" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="14" font-weight="600" text-anchor="middle"
textLength="164" lengthAdjust="spacingAndGlyphs" class="fade f2">AKADEMIA WODOCIAGOWCA</text>
<!-- znacznik transmisji na żywo -->
<g class="fade f3">
<rect x="286" y="144" width="46" height="15" fill="#1d2d3d"/>
<circle cx="295" cy="151.5" r="3" fill="#f2f2f3" class="pulse"/>
<text x="303" y="155" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" textLength="24" lengthAdjust="spacingAndGlyphs">LIVE</text>
</g>
<!-- ekran kursu -->
<g stroke="#f2f2f3" stroke-width="1.6" fill="none" class="fade f3">
<rect x="286" y="170" width="52" height="36"/>
<path d="M352 178h102M352 188h74M352 198h102"/>
</g>
<path d="m305 182 12 6-12 6z" fill="#f2f2f3" class="fade f3"/>
<text x="370" y="230" fill="#f2f2f3" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="10" text-anchor="middle" opacity=".92"
textLength="176" lengthAdjust="spacingAndGlyphs" class="fade f3">WEBINARS · COURSES · CERTIFICATES</text>
<!-- ── Zespoly w przedsiebiorstwach ──────────────────────────────────── -->
<path class="flow" d="M470 171 H516" stroke="#5980a6" stroke-width="1.8" fill="none" marker-end="url(#akad-arrow)"/>
<text x="493" y="160" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" text-anchor="middle" textLength="38" lengthAdjust="spacingAndGlyphs" class="fade f3">KNOW-HOW</text>
<rect class="draw d4" pathLength="1" x="520" y="96" width="160" height="150" fill="#f2f2f3" stroke="#416180" stroke-width="1.5"/>
<rect x="520" y="96" width="160" height="30" fill="#5980a6" fill-opacity=".2" class="fade f4"/>
<text x="600" y="116" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="11" font-weight="600" text-anchor="middle"
textLength="132" lengthAdjust="spacingAndGlyphs" class="fade f4">TEAMS AT UTILITIES</text>
<g stroke="#416180" stroke-width="1.5" fill="none" class="fade f4">
<circle cx="558" cy="152" r="11"/><path d="M542 182v-12a16 16 0 0 1 32 0v12"/>
<circle cx="600" cy="152" r="11"/><path d="M584 182v-12a16 16 0 0 1 32 0v12"/>
<circle cx="642" cy="152" r="11"/><path d="M626 182v-12a16 16 0 0 1 32 0v12"/>
</g>
<g fill="#5980a6" fill-opacity=".24" class="fade f4">
<circle cx="558" cy="152" r="11"/><circle cx="600" cy="152" r="11"/><circle cx="642" cy="152" r="11"/>
</g>
<!-- certyfikat -->
<g class="fade f4">
<rect x="556" y="200" width="88" height="26" fill="#f2f2f3" stroke="#416180" stroke-width="1.4"/>
<path d="m566 213 5 5 9-11" stroke="#5980a6" stroke-width="2" fill="none"/>
<text x="608" y="217" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="9.5" text-anchor="middle" textLength="46" lengthAdjust="spacingAndGlyphs">CERTIFICATE</text>
</g>
<!-- ── Petla zwrotna: rynek podpowiada tematy ────────────────────────── -->
<path class="draw d4" pathLength="1" d="M600 246 V310 H115 V232" stroke="#5980a6" stroke-width="1.8"
fill="none" marker-end="url(#akad-arrow)"/>
<rect x="276" y="298" width="172" height="22" fill="#eaeef2" class="fade f4"/>
<text x="362" y="314" fill="#416180" font-family="'Barlow Condensed','Arial Narrow',sans-serif"
font-size="10.5" text-anchor="middle" textLength="158" lengthAdjust="spacingAndGlyphs" class="fade f4">QUESTIONS FEED THE PROGRAMME</text>
<!-- ── krzyzyki rejestracyjne ────────────────────────────────────────── -->
<g stroke="#1d1f20" stroke-width="1" opacity=".45">
<path d="M263 89v13M257 95h13"/>
<path d="M477 89v13M471 95h13"/>
<path d="M263 241v13M257 247h13"/>
<path d="M477 241v13M471 247h13"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

+55
View File
@@ -0,0 +1,55 @@
/* ============================================================================
SoftSPM - wejście bloków i liczniki
Delikatne pojawianie się sekcji przy przewijaniu oraz naliczanie liczb
w pasku Akademii. Wszystko wyłącza się przy prefers-reduced-motion,
a bez JavaScriptu treść i tak jest widoczna - styl startowy nakładamy
dopiero po dodaniu klasy js-reveal.
========================================================================= */
(function () {
'use strict';
var supported = 'IntersectionObserver' in window && 'classList' in document.documentElement;
var reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!supported || reduced) {
return;
}
document.documentElement.classList.add('js-reveal');
function countUp(node) {
var target = parseInt(node.getAttribute('data-count'), 10);
if (isNaN(target)) { return; }
var suffix = node.getAttribute('data-suffix') || '';
var duration = 900;
var started = null;
function step(now) {
if (started === null) { started = now; }
var progress = Math.min(1, (now - started) / duration);
// wyhamowanie na końcu - liczba dobija do wartości, nie przeskakuje
var eased = 1 - Math.pow(1 - progress, 3);
node.textContent = Math.round(target * eased) + suffix;
if (progress < 1) { requestAnimationFrame(step); }
}
node.textContent = '0' + suffix;
requestAnimationFrame(step);
}
var observer = new IntersectionObserver(function (entries) {
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (!entry.isIntersecting) { continue; }
var node = entry.target;
node.classList.add('is-in');
observer.unobserve(node);
var counters = node.querySelectorAll('[data-count]');
for (var c = 0; c < counters.length; c++) { countUp(counters[c]); }
}
}, { rootMargin: '0px 0px -12% 0px', threshold: 0.12 });
var blocks = document.querySelectorAll('[data-reveal]');
for (var i = 0; i < blocks.length; i++) { observer.observe(blocks[i]); }
})();
+208
View File
@@ -0,0 +1,208 @@
/* ============================================================================
SoftSPM - harmonogram z Akademii Wodociągowca
Podmienia wiersze tabeli terminów danymi z api/schedule.php.
Gdy API nie odpowiada albo nie ma pozycji, statyczne wiersze z HTML-a
zostają nietknięte - strona nigdy nie pokazuje pustej tabeli.
========================================================================= */
(function () {
'use strict';
var DICT = {
pl: {
dateHead: 'Data',
webinar: 'Webinar',
training: 'Szkolenie',
online: 'Online',
elearning: 'Online · e-learning',
onDemand: 'Na żądanie',
signUp: 'Zapisz się →',
viewCourse: 'Zobacz kurs →',
soldOut: 'Brak miejsc',
soon: 'Zapisy wkrótce',
note: 'Terminy pobierane na bieżąco z platformy kursowej Akademia Wodociągowca. Zapisy prowadzi Akademia.',
plateTitle: 'Terminy i kursy otwarte',
heading: 'Najbliższe szkolenia i webinaria',
intro: 'Poniżej pozycje otwarte w tej chwili na naszej platformie kursowej. Zapisy prowadzi Akademia Wodociągowca.',
locale: 'pl-PL',
levels: { BASIC: 'podstawowy', INTERMEDIATE: 'średni', ADVANCED: 'zaawansowany' }
},
en: {
dateHead: 'Date',
webinar: 'Webinar',
training: 'Training',
online: 'Online',
elearning: 'Online · e-learning',
onDemand: 'On demand',
signUp: 'Sign up →',
viewCourse: 'View course →',
soldOut: 'Fully booked',
soon: 'Registration soon',
note: 'Dates are pulled live from our Akademia Wodociagowca course platform, which also handles registration.',
plateTitle: 'Open dates and courses',
heading: 'Upcoming training and webinars',
intro: 'Everything currently open on our course platform. Registration is handled by Akademia Wodociagowca.',
locale: 'en-GB',
levels: { BASIC: 'basic', INTERMEDIATE: 'intermediate', ADVANCED: 'advanced' }
}
};
var lang = (document.documentElement.getAttribute('lang') || 'pl').slice(0, 2).toLowerCase();
var t = DICT[lang] || DICT.pl;
function el(tag, className, text) {
var node = document.createElement(tag);
if (className) { node.className = className; }
if (text !== undefined && text !== null) { node.textContent = text; }
return node;
}
function formatDate(iso, timezone) {
var date = new Date(iso);
if (isNaN(date.getTime())) { return null; }
var zone = timezone || 'Europe/Warsaw';
var opts = { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: zone };
var timeOpts = { hour: '2-digit', minute: '2-digit', timeZone: zone };
try {
return {
day: new Intl.DateTimeFormat(t.locale, opts).format(date),
hour: new Intl.DateTimeFormat(t.locale, timeOpts).format(date)
};
} catch (e) {
// Nieznana strefa albo stary silnik - pokazujemy datę bez strefy.
return { day: date.toLocaleDateString(t.locale), hour: date.toLocaleTimeString(t.locale) };
}
}
function actionCell(item) {
var cell = el('td', 's-act');
if (item.kind === 'webinar' && item.soldOut) {
cell.appendChild(el('span', 'text-muted', t.soldOut));
return cell;
}
if (item.kind === 'webinar' && item.open === false) {
cell.appendChild(el('span', 'text-muted', t.soon));
return cell;
}
if (!item.url) {
cell.appendChild(el('span', 'text-muted', item.kind === 'webinar' ? t.soon : ''));
return cell;
}
var link = el('a', 'sign', item.kind === 'webinar' ? t.signUp : t.viewCourse);
link.href = item.url;
link.target = '_blank';
link.rel = 'noopener';
cell.appendChild(link);
return cell;
}
function buildRow(item) {
var row = document.createElement('tr');
var date = el('td', 's-date');
if (item.kind === 'webinar') {
var parts = formatDate(item.startsAt, item.timezone);
if (parts) {
date.appendChild(document.createTextNode(parts.day));
date.appendChild(el('span', 's-hour', parts.hour));
} else {
date.appendChild(el('span', 'tag tag-soon', t.onDemand));
}
} else {
date.appendChild(el('span', 'tag tag-soon', t.onDemand));
}
row.appendChild(date);
// textContent, nie innerHTML - tytuły przychodzą z innego systemu.
row.appendChild(el('td', 's-topic', item.title));
var form = el('td', 's-form');
form.appendChild(el(
'span',
item.kind === 'webinar' ? 'tag tag-outline' : 'tag tag-accent',
item.kind === 'webinar' ? t.webinar : t.training
));
row.appendChild(form);
var place = item.kind === 'webinar' ? t.online : t.elearning;
if (item.kind === 'course' && item.level && t.levels[item.level]) {
place = t.elearning + ' · ' + t.levels[item.level];
}
row.appendChild(el('td', 's-place', place));
row.appendChild(actionCell(item));
return row;
}
function render(table, items) {
var body = table.querySelector('tbody');
if (!body) { return; }
var fresh = document.createDocumentFragment();
for (var i = 0; i < items.length; i++) {
fresh.appendChild(buildRow(items[i]));
}
body.innerHTML = '';
body.appendChild(fresh);
// Mamy realne daty, więc nagłówek kolumny wraca z "Termin" na "Data".
var head = table.querySelector('[data-schedule-datehead]');
if (head) { head.textContent = t.dateHead; }
// Przy realnych terminach nagłówki mówiące "ustalamy terminy" przestają
// być prawdziwe, więc lecą razem z wierszami.
var section = table.closest ? table.closest('section') : null;
if (section) {
var heading = section.querySelector('[data-schedule-heading]');
if (heading) { heading.textContent = t.heading; }
var intro = section.querySelector('[data-schedule-intro]');
if (intro) { intro.textContent = t.intro; }
}
var plate = table.closest ? table.closest('.plate') : null;
var plateTitle = plate ? plate.querySelector('[data-schedule-title]') : null;
if (plateTitle) { plateTitle.textContent = t.plateTitle; }
var note = plate ? plate.querySelector('[data-schedule-note]') : null;
if (note) {
note.textContent = t.note + ' ';
var link = el('a', null, 'akademiawodociagowca.pl');
link.href = 'https://akademiawodociagowca.pl/';
link.target = '_blank';
link.rel = 'noopener';
note.appendChild(link);
}
table.setAttribute('data-schedule-state', 'live');
}
function boot() {
var tables = document.querySelectorAll('table[data-schedule]');
if (!tables.length) { return; }
var limit = 0;
for (var i = 0; i < tables.length; i++) {
limit = Math.max(limit, parseInt(tables[i].getAttribute('data-schedule-limit'), 10) || 12);
}
fetch('api/schedule.php?limit=' + limit, {
credentials: 'same-origin',
headers: { 'Accept': 'application/json' }
})
.then(function (response) { return response.json(); })
.then(function (data) {
if (!data || data.source !== 'api' || !data.items || !data.items.length) { return; }
for (var i = 0; i < tables.length; i++) {
var own = parseInt(tables[i].getAttribute('data-schedule-limit'), 10) || data.items.length;
render(tables[i], data.items.slice(0, own));
}
})
.catch(function () {
// Cisza jest właściwą reakcją: w tabeli zostają statyczne wiersze.
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();
+36
View File
@@ -272,6 +272,11 @@ textarea.input { min-height: 110px; resize: vertical; }
.s-prop { font-weight: 500; }
.s-rem { font-size: 14px; color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.s-date { white-space: nowrap; font-weight: 500; width: 1%; }
/* godzina webinaru pod datą - pobierana z Akademii Wodociągowca */
.s-hour {
display: block; font-weight: 400; font-size: 12.5px;
color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.s-topic { font-family: var(--font-heading); font-weight: 600; font-size: 18px; }
.s-act { text-align: right; white-space: nowrap; }
.sign {
@@ -475,6 +480,35 @@ textarea.input { min-height: 110px; resize: vertical; }
color: var(--color-accent-700);
}
/* -- pasek liczb (Akademia) --------------------------------------------- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: calc(1.5 * var(--leading)); }
@media (max-width: 820px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { padding-top: var(--space-4); border-top: 2px solid var(--color-accent); }
.stat-num {
display: block;
font-family: var(--font-heading); font-weight: 700;
font-size: clamp(38px, 4.4vw, 52px); line-height: 1;
color: var(--color-accent-700);
font-feature-settings: "tnum" 1;
}
.stat-label {
display: block; margin-top: var(--space-3);
font-size: 13.5px; line-height: var(--half);
color: color-mix(in srgb, var(--color-text) 62%, transparent);
}
/* -- wejście bloków przy przewijaniu -----------------------------------
Styl startowy nakładamy dopiero, gdy skrypt zgłosi gotowość (klasa
js-reveal na <html>). Bez JavaScriptu treść jest widoczna od razu. */
.js-reveal [data-reveal] {
opacity: 0; transform: translateY(16px);
transition: opacity .55s ease-out, transform .55s ease-out;
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
.js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
}
/* -- newsletter / CTA --------------------------------------------------- */
.cta-band {
position: relative; padding: calc(2 * var(--leading)) var(--space-8);
@@ -608,6 +642,8 @@ textarea.input { min-height: 110px; resize: vertical; }
}
.table.sched td { border: 0; padding: 0; }
.table.sched .s-date { order: 1; font-size: 14px; color: var(--color-accent-700); }
/* w karcie mobilnej data i godzina mieszczą się w jednej linii */
.table.sched .s-hour { display: inline; font-size: 13px; margin-left: var(--space-2); }
.table.sched .s-form { order: 2; text-align: right; }
.table.sched .s-topic { grid-column: 1 / -1; order: 3; }
.table.sched .s-place { order: 4; font-size: 13.5px; color: color-mix(in srgb, var(--color-text) 60%, transparent); }