diff --git a/README.md b/README.md new file mode 100644 index 0000000..228a52b --- /dev/null +++ b/README.md @@ -0,0 +1,115 @@ +## 1. Opis Projekta + +**Prosberry.si** je profesionalna spletna stran za podjetje **PROSBERRY, Amra Kurešepi Zulji s.p.** Stran služi kot digitalna vizitka in informacijska točka za storitve, ki jih podjetje ponuja. Glavni cilj projekta je predstaviti strokovnost in osebni pristop Amre Kurešepi Zulji na področju jezikovnega izobraževanja in medkulturnega posredovanja. + +Spletna stran je zasnovana kot statična stran (HTML, CSS, JavaScript), kar zagotavlja hitro nalaganje in enostavno vzdrževanje. Za funkcionalnost kontaktnega obrazca se uporablja PHP. Projekt vključuje tudi nabor skript za avtomatizacijo (Python in Shell), ki poenostavljajo procese, kot so optimizacija slik in posodabljanje ponavljajočih se elementov (glava, noga). + +### Glavne funkcionalnosti in vsebine: +- **Predstavitev storitev:** Podroben opis jezikovnih tečajev (angleščina, albanščina, slovenščina), medkulturnega posredovanja in specializiranih delavnic. +- **Osebna predstavitev:** Stran "Kdo sem" z osebno zgodbo in kvalifikacijami izvajalke. +- **Cenik in reference:** Pregled cen storitev in mnenja zadovoljnih strank. +- **Kontaktni obrazec:** Enostaven način za pošiljanje povpraševanj. +- **Pogosta vprašanja (FAQ):** Odgovori na najpogostejša vprašanja za lažje informiranje obiskovalcev. +- **Odziven dizajn:** Stran je prilagojena za optimalen prikaz na različnih napravah (mobilni telefoni, tablice, namizni računalniki). + +## 2. Struktura Projekta (Zemljevid) + +``` +. +├── assets +│ ├── favicon +│ │ └── site.webmanifest +│ ├── images/ +│ └── pdf/ +├── cene-in-reference +│ └── index.html +├── cene-in-sodelovanja +│ └── index.html +├── css +│ ├── animations.css +│ └── style.css +├── delavnice +│ └── index.html +├── js +│ └── main.js +├── kdo-sem +│ └── index.html +├── kontakt +│ ├── index.html +│ └── process_form.php +│── politika-zasebnosti +│ └── index.html +├── pogosta-vprasanja +│ └── index.html +├── ponudba +│ └── index.html +├── skupaj-za-vkljucevanje +│ ├── delavnica-od-tujca-do-sosolca +│ │ └── index.html +│ ├── delavnica-sola-in-starsi +│ │ └── index.html +│ ├── delavnica-vrtec-novi-zacetki +│ │ └── index.html +│ ├── delavnica-zakaj-znati-slovensko +│ │ └── index.html +│ └── medkulturno-posredovanje +│ └── index.html +├── error_log +├── footer-template.html +├── header-template.html +├── generate_responsive_images.py +├── index.html +├── minify_js.py +├── optimize_images.py +├── robots.txt +├── sitemap.xml +├── update-footer.sh +└── update-menus.sh +``` + +## 3. Opis Datotek in Map + +### 📁 Korenske datoteke in mape + +- **`index.html`**: Glavna vstopna stran (domača stran), ki pozdravi obiskovalca in na kratko predstavi ključne storitve ter ga usmeri na podstrani. +- **`kdo-sem/index.html`**: Stran "Kdo sem", ki vsebuje podrobnejšo osebno predstavitev Amre Kurešepi Zulji, njeno zgodbo in strokovno ozadje. +- **`ponudba/index.html`**: Stran, ki podrobno predstavlja ponudbo jezikovnih tečajev in medkulturnega posredovanja. +- **`cene-in-reference/index.html`**: Stran s cenikom za posamezne storitve in referencami (mnenji) strank. +- **`cene-in-sodelovanja/index.html`**: Alternativna ali starejša stran za cene, ki uporabnika preusmeri na kontaktno stran za več informacij. +- **`kontakt/index.html`**: Stran s kontaktnimi podatki in obrazcem za pošiljanje sporočil. +- **`pogosta-vprasanja/index.html`**: Stran z zbranimi pogostimi vprašanji in odgovori (FAQ). +- **`politika-zasebnosti/index.html`**: Pravna stran, ki opisuje politiko varovanja osebnih podatkov v skladu z GDPR. +- **`delavnice/index.html`**: Pregledna stran, ki deluje kot kazalo za vse razpoložljive delavnice in vodi do njihovih podstrani. +- **`skupaj-za-vkljucevanje/`**: Mapa, ki združuje vsebine, povezane s programom "Skupaj za vključevanje". Vsebuje podstrani za medkulturno posredovanje in posamezne delavnice. + +### 📁 `assets/` +Mapa za vse statične vire, kot so slike, ikone in dokumenti. +- **`favicon/site.webmanifest`**: Manifest datoteka, ki brskalnikom omogoča, da spletno stran prikažejo z lastnostmi spletne aplikacije (npr. ikona na domačem zaslonu). +- **`images/`**: Mapa, kjer so shranjene vse slike, uporabljene na spletni strani. +- **`pdf/`**: Mapa za PDF dokumente, ki ponujajo podrobnejše opise delavnic. + +### 📁 `css/` +Mapa za stilsko oblikovanje spletne strani. +- **`style.css`**: Glavna in obsežna CSS datoteka, ki vsebuje vse stile za celotno spletno stran, vključno z odzivnostjo in oblikovanjem posameznih sekcij. +- **`animations.css`**: Ločena CSS datoteka, namenjena izključno animacijam. + +### 📁 `js/` +Mapa za JavaScript kodo, ki skrbi za interaktivnost. +- **`main.js`**: Osrednja JavaScript datoteka, ki upravlja: + - Delovanje navigacije (mobilni meni, večnivojski dropdown meniji). + - Interaktivne elemente, kot so "harmonika" (accordion) na straneh s pogostimi vprašanji. + - Inicializacijo knjižnice AOS (Animate On Scroll) za animacije ob drsenju. + - Logiko za pošiljanje podatkov iz kontaktnega obrazca. + +### ⚙️ Backend in konfiguracija +- **`kontakt/process_form.php`**: PHP skripta, ki na strežniški strani obdela podatke, poslane preko kontaktnega obrazca, in jih pošlje na e-poštni naslov. +- **`robots.txt`**: Datoteka, ki spletnim iskalnikom (npr. Google) daje navodila, katere dele spletne strani naj indeksirajo in katerih ne. +- **`sitemap.xml`**: Zemljevid spletnega mesta v XML formatu, ki iskalnikom pomaga pri lažjem in učinkovitejšem odkrivanju vseh podstrani. +- **`error_log`**: Samodejno generirana datoteka s strani strežnika, ki beleži morebitne PHP napake. + +### 🛠️ Orodja za avtomatizacijo in vzdrževanje +- **`header-template.html`** in **`footer-template.html`**: Predlogi za glavo in nogo spletne strani. Uporabljata se za centralno upravljanje teh elementov, da jih ni treba ročno urejati na vsaki strani posebej. +- **`update-menus.sh`** in **`update-footer.sh`**: Shell skripti, ki avtomatizirata posodabljanje glave in noge. Skripta prebere vsebino iz predloge in jo vstavi v vse `.html` datoteke v projektu. +- **`optimize_images.py`**: Python skripta za optimizacijo slik. Slike pretvori v sodoben in učinkovit `.webp` format, jih po potrebi pomanjša in originale shrani v varnostno kopijo. +- **`generate_responsive_images.py`**: Python skripta, ki iz originalnih slik ustvari več manjših različic za odziven prikaz na različnih velikostih zaslonov. +- **`minify_js.py`**: Preprosta Python skripta, ki iz datoteke `main.js` odstrani komentarje in odvečne presledke ter tako zmanjša njeno velikost za hitrejše nalaganje. \ No newline at end of file diff --git a/cene-in-reference/index.html b/cene-in-reference/index.html index f5d7b42..1a00fd0 100644 --- a/cene-in-reference/index.html +++ b/cene-in-reference/index.html @@ -236,7 +236,18 @@
- +
+
+

Imaš vprašanje? Pokliči ali piši!

+ +

Skupaj ustvariva prostor za učenje in povezovanje.

+
+
+ + - - - + + """ @@ -6044,568 +1327,7 @@ footer { "./js/main.js" : """ -document.addEventListener('DOMContentLoaded', function() { - - // --- Mobile Menu Toggle --- - const mobileMenuBtn = document.querySelector('.mobile-menu-btn'); - const navLinks = document.querySelector('.nav-links'); - let closeMobileMenu = () => {}; - let resetMobileSubmenus = () => {}; - - const normalizePath = (value) => { - if (!value) { - return '/'; - } - let clean = value.split('?')[0].split('#')[0]; - clean = clean.replace(/index\.html$/i, ''); - clean = clean.replace(/\/+$/, ''); - if (clean === '') { - clean = '/'; - } - return clean; - }; - - const applyActiveNavState = () => { - const navRoot = document.querySelector('.nav-links'); - if (!navRoot) { - return; - } - - navRoot.querySelectorAll('a.active, .dropbtn.active').forEach(el => { - el.classList.remove('active'); - }); - - const currentPath = normalizePath(window.location.pathname); - const navAnchors = navRoot.querySelectorAll('a[href]'); - let matchedLink = null; - - navAnchors.forEach(anchor => { - const href = anchor.getAttribute('href'); - if (!href || href.startsWith('http') || href.startsWith('mailto:') || href.startsWith('tel:') || href.startsWith('#')) { - return; - } - - const linkPath = normalizePath(href); - if (linkPath === currentPath) { - matchedLink = anchor; - } - }); - - if (!matchedLink) { - return; - } - - matchedLink.classList.add('active'); - - const highlightDropdownParents = (element) => { - let parentContent = element.closest('.dropdown-submenu-content, .dropdown-content'); - while (parentContent) { - const trigger = parentContent.previousElementSibling; - if (trigger && (trigger.tagName === 'A' || trigger.classList.contains('dropbtn'))) { - trigger.classList.add('active'); - } - parentContent = parentContent.parentElement ? parentContent.parentElement.closest('.dropdown-submenu-content, .dropdown-content') : null; - } - }; - - highlightDropdownParents(matchedLink); - - const topLevelDropdown = matchedLink.closest('.dropdown'); - if (topLevelDropdown) { - const trigger = topLevelDropdown.querySelector('.dropbtn'); - if (trigger) { - trigger.classList.add('active'); - } - } - }; - - if (mobileMenuBtn && navLinks) { - resetMobileSubmenus = () => { - navLinks.querySelectorAll('.dropdown-content, .dropdown-submenu-content').forEach(submenu => { - submenu.style.display = 'none'; - }); - navLinks.querySelectorAll('.dropbtn, .dropdown-submenu > a').forEach(link => { - link.classList.remove('active'); - }); - applyActiveNavState(); - }; - - closeMobileMenu = () => { - mobileMenuBtn.classList.remove('active'); - navLinks.classList.remove('active'); - document.body.classList.remove('no-scroll'); - resetMobileSubmenus(); - }; - - mobileMenuBtn.addEventListener('click', (event) => { - event.stopPropagation(); // Prepreči, da bi se dogodek takoj prenesel na 'document' - const willOpen = !navLinks.classList.contains('active'); - if (willOpen) { - mobileMenuBtn.classList.add('active'); - navLinks.classList.add('active'); - document.body.classList.add('no-scroll'); - resetMobileSubmenus(); - } else { - closeMobileMenu(); - } - }); - } - - // --- Active Navigation Highlight --- - applyActiveNavState(); - - // --- Mobile Dropdown Logic --- - // Logika za odpiranje podmenijev na klik na mobilnih napravah - const dropdowns = document.querySelectorAll('.nav-links .dropdown-submenu > a, .nav-links .dropdown > .dropbtn'); - - dropdowns.forEach(item => { - item.addEventListener('click', function(event) { - // Preveri, ali smo na mobilni napravi (ujema se z CSS @media query) - if (window.innerWidth <= 768) { - // Prepreči navigacijo, če je to link, saj želimo samo odpreti podmeni - if (item.tagName === 'A') { - event.preventDefault(); - } - event.stopPropagation(); - - const submenu = item.nextElementSibling; - if (!submenu) { - return; - } - - const isTopLevelTrigger = item.classList.contains('dropbtn'); - - if (isTopLevelTrigger) { - navLinks.querySelectorAll('.dropdown-content').forEach(panel => { - if (panel !== submenu) { - panel.style.display = 'none'; - const trigger = panel.parentElement.querySelector('.dropbtn'); - if (trigger) { - trigger.classList.remove('active'); - } - panel.querySelectorAll('.dropdown-submenu-content').forEach(child => { - child.style.display = 'none'; - const childTrigger = child.parentElement.querySelector(':scope > a'); - if (childTrigger) { - childTrigger.classList.remove('active'); - } - }); - } - }); - } else { - const siblingsWrapper = item.parentElement && item.parentElement.parentElement; - if (siblingsWrapper) { - siblingsWrapper.querySelectorAll(':scope > .dropdown-submenu > .dropdown-submenu-content').forEach(panel => { - if (panel !== submenu) { - panel.style.display = 'none'; - const trigger = panel.parentElement.querySelector(':scope > a'); - if (trigger) { - trigger.classList.remove('active'); - } - panel.querySelectorAll('.dropdown-submenu-content').forEach(child => { - child.style.display = 'none'; - const childTrigger = child.parentElement.querySelector(':scope > a'); - if (childTrigger) { - childTrigger.classList.remove('active'); - } - }); - } - }); - } - } - - const shouldOpen = submenu.style.display !== 'block'; - - if (shouldOpen) { - submenu.style.display = 'block'; - item.classList.add('active'); - submenu.querySelectorAll('.dropdown-submenu-content').forEach(child => { - child.style.display = 'none'; - const childTrigger = child.parentElement.querySelector(':scope > a'); - if (childTrigger) { - childTrigger.classList.remove('active'); - } - }); - } else { - submenu.style.display = 'none'; - item.classList.remove('active'); - submenu.querySelectorAll('.dropdown-submenu-content').forEach(child => { - child.style.display = 'none'; - const childTrigger = child.parentElement.querySelector(':scope > a'); - if (childTrigger) { - childTrigger.classList.remove('active'); - } - }); - } - } - }); - }); - - // --- Close mobile menu when clicking outside --- - document.addEventListener('click', function(event) { - if (window.innerWidth <= 768 && navLinks && navLinks.classList.contains('active')) { - // Preveri, ali klik ni bil znotraj navigacije ali na gumb za meni - const isClickInsideNav = navLinks.contains(event.target); - const isClickOnBtn = mobileMenuBtn && mobileMenuBtn.contains(event.target); - - if (!isClickInsideNav && !isClickOnBtn) { - closeMobileMenu(); - } - } - }); - - // --- Close mobile menu when a link is clicked --- - const navLinkItems = document.querySelectorAll('.nav-links a'); - navLinkItems.forEach(link => { - link.addEventListener('click', (event) => { - // Preprečimo zapiranje, če ima link podmeni in smo na mobilni napravi - const hasSubmenu = link.parentElement.classList.contains('dropdown-submenu') || link.classList.contains('dropbtn'); - if (window.innerWidth <= 768) { - if (hasSubmenu) { - // To je že obdelano v zgornji logiki, tukaj samo preprečimo, da bi se meni takoj zaprl - return; - } - closeMobileMenu(); - } - }); - }); - - // --- Accordion Logic for "Več" buttons --- - const accordions = document.querySelectorAll('.accordion-toggle'); - accordions.forEach(accordion => { - accordion.addEventListener('click', function() { - const accordionItem = this.closest('.mediation-accordion-item'); - const content = accordionItem ? accordionItem.querySelector('.accordion-content') : null; - - if (!content) { - return; - } - - this.classList.toggle('active'); - const isOpen = this.classList.contains('active'); - this.setAttribute('aria-expanded', String(isOpen)); - content.setAttribute('aria-hidden', String(!isOpen)); - - if (isOpen) { - content.style.maxHeight = content.scrollHeight + "px"; - this.textContent = 'Manj'; - } else { - content.style.maxHeight = null; - this.textContent = 'Več'; - } - }); - accordion.textContent = 'Več'; - accordion.setAttribute('aria-expanded', 'false'); - const initialContent = accordion.closest('.mediation-accordion-item')?.querySelector('.accordion-content'); - if (initialContent) { - initialContent.setAttribute('aria-hidden', 'true'); - } - }); - - // --- Header Scroll Effect --- - const header = document.querySelector('.main-header'); - if (header) { - let lastScroll = 0; - window.addEventListener('scroll', () => { - const currentScroll = window.pageYOffset; - - if (currentScroll <= 0) { - header.classList.remove('scroll-up'); - return; - } - - if (currentScroll > lastScroll && !header.classList.contains('scroll-down')) { - // Scroll Down - header.classList.remove('scroll-up'); - header.classList.add('scroll-down'); - } else if (currentScroll < lastScroll && header.classList.contains('scroll-down')) { - // Scroll Up - header.classList.remove('scroll-down'); - header.classList.add('scroll-up'); - } - lastScroll = currentScroll; - }); - } - - // --- Accordion Logic for Mediation Page --- - const mediationSections = document.querySelectorAll('.mediation-section'); - if (mediationSections.length) { - const mediationTitles = document.querySelectorAll('.mediation-section h2'); - - const closeAllSections = () => { - mediationSections.forEach(section => { - section.classList.remove('active'); - }); - }; - - mediationTitles.forEach(title => { - title.addEventListener('click', () => { - const parentSection = title.parentElement; - const isAlreadyActive = parentSection.classList.contains('active'); - - closeAllSections(); - - if (!isAlreadyActive) { - parentSection.classList.add('active'); - } - }); - }); - - const openSectionFromHash = () => { - const hash = window.location.hash; - if (hash) { - const targetSection = document.querySelector(hash); - if (targetSection && targetSection.classList.contains('mediation-section')) { - closeAllSections(); - targetSection.classList.add('active'); - } - } - }; - - window.addEventListener('hashchange', openSectionFromHash); - openSectionFromHash(); - - if (!document.querySelector('.mediation-section.active') && mediationSections[0]) { - mediationSections[0].classList.add('active'); - } - } - - // --- POPRAVLJENA in ZANESLJIVA logika za meni --- - const dropdownContainers = document.querySelectorAll('.nav-links .dropdown'); - if (dropdownContainers.length) { - const closeAllDropdowns = () => { - dropdownContainers.forEach(container => { - const dropdownContent = container.querySelector('.dropdown-content'); - if (!dropdownContent) { - return; - } - container.classList.remove('is-open'); - dropdownContent.style.display = 'none'; - dropdownContent.querySelectorAll('.dropdown-submenu-content').forEach(submenu => { - submenu.style.display = 'none'; - }); - }); - }; - - dropdownContainers.forEach(container => { - const dropBtn = container.querySelector('.dropbtn'); - const dropdownContent = container.querySelector('.dropdown-content'); - if (!dropBtn || !dropdownContent) { - return; - } - - const closeDropdown = () => { - container.classList.remove('is-open'); - dropdownContent.style.display = 'none'; - dropdownContent.querySelectorAll('.dropdown-submenu-content').forEach(submenu => { - submenu.style.display = 'none'; - }); - }; - - const openDropdown = () => { - container.classList.add('is-open'); - dropdownContent.style.display = 'block'; - }; - - dropBtn.addEventListener('click', (event) => { - if (window.innerWidth <= 768) { - return; // mobilna logika že upravlja - } - event.preventDefault(); - const isOpen = container.classList.contains('is-open'); - closeAllDropdowns(); - if (!isOpen) { - openDropdown(); - } - }); - - const submenuLinks = container.querySelectorAll('.dropdown-submenu > a'); - submenuLinks.forEach(link => { - const submenu = link.nextElementSibling; - if (!submenu) { - return; - } - - link.addEventListener('click', (event) => { - if (window.innerWidth <= 768) { - return; // mobilna logika že upravlja - } - - const parentList = link.parentElement.parentElement; - parentList.querySelectorAll(':scope > .dropdown-submenu > .dropdown-submenu-content').forEach(sm => { - if (sm !== submenu) { - sm.style.display = 'none'; - } - }); - - const isOpen = submenu.style.display === 'block'; - const href = link.getAttribute('href') || ''; - - if (href === '#' || href.trim() === '') { - event.preventDefault(); - submenu.style.display = isOpen ? 'none' : 'block'; - return; - } - - if (!isOpen) { - event.preventDefault(); - submenu.style.display = 'block'; - } else { - closeDropdown(); - } - }); - }); - - container.querySelectorAll('.dropdown-submenu-content a').forEach(link => { - if (link.nextElementSibling) { - return; - } - link.addEventListener('click', () => { - if (window.innerWidth <= 768) { - return; - } - closeAllDropdowns(); - closeMobileMenu(); - }); - }); - }); - - document.addEventListener('click', (event) => { - if (window.innerWidth <= 768) { - return; - } - const clickedInside = Array.from(dropdownContainers).some(container => container.contains(event.target)); - if (!clickedInside) { - closeAllDropdowns(); - } - }); - - window.addEventListener('resize', () => { - if (window.innerWidth <= 768) { - closeAllDropdowns(); - closeMobileMenu(); - } - }); - } - - window.addEventListener('resize', () => { - if (window.innerWidth > 768) { - closeMobileMenu(); - } - }); - - // --- Initialize AOS (Animate on Scroll) --- - if (typeof AOS !== 'undefined') { - AOS.init({ - duration: 600, - easing: 'ease-out', - once: true, // Animacija se zgodi samo enkrat - offset: 50, - delay: 100, - disable: 'mobile' - }); - } - - // --- "Read More" Button Logic for Kdo Sem Page --- - const readMoreBtn = document.querySelector('.read-more-btn'); - const moreStoryContent = document.querySelector('.more-story-content'); - - if (readMoreBtn && moreStoryContent) { - if (moreStoryContent.id) { - readMoreBtn.setAttribute('aria-controls', moreStoryContent.id); - } - - const applyStoryState = (isVisible) => { - readMoreBtn.textContent = isVisible ? 'Skrij zgodbo' : 'Moja zgodba'; - readMoreBtn.setAttribute('aria-expanded', isVisible ? 'true' : 'false'); - moreStoryContent.setAttribute('aria-hidden', isVisible ? 'false' : 'true'); - }; - - let isExpanded = moreStoryContent.classList.contains('visible'); - applyStoryState(isExpanded); - moreStoryContent.style.height = isExpanded ? 'auto' : '0px'; - - const openStory = () => { - moreStoryContent.classList.add('visible'); - const targetHeight = moreStoryContent.scrollHeight; - moreStoryContent.classList.add('is-animating'); - moreStoryContent.style.height = '0px'; - - requestAnimationFrame(() => { - moreStoryContent.style.height = `${targetHeight}px`; - }); - }; - - const closeStory = () => { - const currentHeight = moreStoryContent.scrollHeight; - moreStoryContent.style.height = `${currentHeight}px`; - moreStoryContent.classList.add('is-animating'); - - requestAnimationFrame(() => { - moreStoryContent.style.height = '0px'; - }); - }; - - moreStoryContent.addEventListener('transitionend', (event) => { - if (event.propertyName !== 'height') { - return; - } - - moreStoryContent.classList.remove('is-animating'); - - if (isExpanded) { - moreStoryContent.style.height = 'auto'; - } else { - moreStoryContent.classList.remove('visible'); - moreStoryContent.style.height = ''; - } - }); - - readMoreBtn.addEventListener('click', () => { - if (moreStoryContent.classList.contains('is-animating')) { - return; - } - - isExpanded = !isExpanded; - applyStoryState(isExpanded); - - if (isExpanded) { - openStory(); - } else { - closeStory(); - } - }); - } -}); - -// --- Legacy form validation functions (can be kept for potential future use) --- -// Note: The main form submission logic is now handled via fetch in kontakt/index.html - -function showError(input, message) { - const formControl = input.parentElement; - const errorDiv = formControl.querySelector('.error-message') || document.createElement('div'); - errorDiv.className = 'error-message'; - errorDiv.textContent = message; - if (!formControl.querySelector('.error-message')) { - formControl.appendChild(errorDiv); - } - formControl.classList.add('error'); -} - -function removeError(input) { - const formControl = input.parentElement; - const errorDiv = formControl.querySelector('.error-message'); - if (errorDiv) { - formControl.removeChild(errorDiv); - } - formControl.classList.remove('error'); -} - -function isValidEmail(email) { - const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(String(email).toLowerCase()); -} -""" +document.addEventListener('DOMContentLoaded', function() { const mobileMenuBtn = document.querySelector('.mobile-menu-btn'); const navLinks = document.querySelector('.nav-links'); let closeMobileMenu = () => {}; let resetMobileSubmenus = () => {}; const normalizePath = (value) => { if (!value) { return '/'; } let clean = value.split('?')[0].split('#')[0]; clean = clean.replace(/index\.html$/i, ''); clean = clean.replace(/\/+$/, ''); if (clean === '') { clean = '/'; } return clean; }; const applyActiveNavState = () => { const navRoot = document.querySelector('.nav-links'); if (!navRoot) { return; } navRoot.querySelectorAll('a.active, .dropbtn.active').forEach(el => { el.classList.remove('active'); }); const currentPath = normalizePath(window.location.pathname); const navAnchors = navRoot.querySelectorAll('a[href]'); let matchedLink = null; navAnchors.forEach(anchor => { const href = anchor.getAttribute('href'); if (!href || href.startsWith('http') || href.startsWith('mailto:') || href.startsWith('tel:') || href.startsWith('#')) { return; } const linkPath = normalizePath(href); if (linkPath === currentPath) { matchedLink = anchor; } }); if (!matchedLink) { return; } matchedLink.classList.add('active'); const highlightDropdownParents = (element) => { let parentContent = element.closest('.dropdown-submenu-content, .dropdown-content'); while (parentContent) { const trigger = parentContent.previousElementSibling; if (trigger && (trigger.tagName === 'A' || trigger.classList.contains('dropbtn'))) { trigger.classList.add('active'); } parentContent = parentContent.parentElement ? parentContent.parentElement.closest('.dropdown-submenu-content, .dropdown-content') : null; } }; highlightDropdownParents(matchedLink); const topLevelDropdown = matchedLink.closest('.dropdown'); if (topLevelDropdown) { const trigger = topLevelDropdown.querySelector('.dropbtn'); if (trigger) { trigger.classList.add('active'); } } }; if (mobileMenuBtn && navLinks) { resetMobileSubmenus = () => { navLinks.querySelectorAll('.dropdown-content, .dropdown-submenu-content').forEach(submenu => { submenu.style.display = 'none'; }); navLinks.querySelectorAll('.dropbtn, .dropdown-submenu > a').forEach(link => { link.classList.remove('active'); }); applyActiveNavState(); }; closeMobileMenu = () => { mobileMenuBtn.classList.remove('active'); navLinks.classList.remove('active'); document.body.classList.remove('no-scroll'); resetMobileSubmenus(); }; mobileMenuBtn.addEventListener('click', (event) => { event.stopPropagation(); const willOpen = !navLinks.classList.contains('active'); if (willOpen) { mobileMenuBtn.classList.add('active'); navLinks.classList.add('active'); document.body.classList.add('no-scroll'); resetMobileSubmenus(); } else { closeMobileMenu(); } }); } applyActiveNavState(); const dropdowns = document.querySelectorAll('.nav-links .dropdown-submenu > a, .nav-links .dropdown > .dropbtn'); dropdowns.forEach(item => { item.addEventListener('click', function(event) { if (window.innerWidth <= 768) { if (item.tagName === 'A') { event.preventDefault(); } event.stopPropagation(); const submenu = item.nextElementSibling; if (!submenu) { return; } const isTopLevelTrigger = item.classList.contains('dropbtn'); if (isTopLevelTrigger) { navLinks.querySelectorAll('.dropdown-content').forEach(panel => { if (panel !== submenu) { panel.style.display = 'none'; const trigger = panel.parentElement.querySelector('.dropbtn'); if (trigger) { trigger.classList.remove('active'); } panel.querySelectorAll('.dropdown-submenu-content').forEach(child => { child.style.display = 'none'; const childTrigger = child.parentElement.querySelector(':scope > a'); if (childTrigger) { childTrigger.classList.remove('active'); } }); } }); } else { const siblingsWrapper = item.parentElement && item.parentElement.parentElement; if (siblingsWrapper) { siblingsWrapper.querySelectorAll(':scope > .dropdown-submenu > .dropdown-submenu-content').forEach(panel => { if (panel !== submenu) { panel.style.display = 'none'; const trigger = panel.parentElement.querySelector(':scope > a'); if (trigger) { trigger.classList.remove('active'); } panel.querySelectorAll('.dropdown-submenu-content').forEach(child => { child.style.display = 'none'; const childTrigger = child.parentElement.querySelector(':scope > a'); if (childTrigger) { childTrigger.classList.remove('active'); } }); } }); } } const shouldOpen = submenu.style.display !== 'block'; if (shouldOpen) { submenu.style.display = 'block'; item.classList.add('active'); submenu.querySelectorAll('.dropdown-submenu-content').forEach(child => { child.style.display = 'none'; const childTrigger = child.parentElement.querySelector(':scope > a'); if (childTrigger) { childTrigger.classList.remove('active'); } }); } else { submenu.style.display = 'none'; item.classList.remove('active'); submenu.querySelectorAll('.dropdown-submenu-content').forEach(child => { child.style.display = 'none'; const childTrigger = child.parentElement.querySelector(':scope > a'); if (childTrigger) { childTrigger.classList.remove('active'); } }); } } }); }); document.addEventListener('click', function(event) { if (window.innerWidth <= 768 && navLinks && navLinks.classList.contains('active')) { const isClickInsideNav = navLinks.contains(event.target); const isClickOnBtn = mobileMenuBtn && mobileMenuBtn.contains(event.target); if (!isClickInsideNav && !isClickOnBtn) { closeMobileMenu(); } } }); const navLinkItems = document.querySelectorAll('.nav-links a'); navLinkItems.forEach(link => { link.addEventListener('click', (event) => { const hasSubmenu = link.parentElement.classList.contains('dropdown-submenu') || link.classList.contains('dropbtn'); if (window.innerWidth <= 768) { if (hasSubmenu) { return; } closeMobileMenu(); } }); }); const accordions = document.querySelectorAll('.accordion-toggle'); accordions.forEach(accordion => { accordion.addEventListener('click', function() { const accordionItem = this.closest('.mediation-accordion-item'); const content = accordionItem ? accordionItem.querySelector('.accordion-content') : null; if (!content) { return; } this.classList.toggle('active'); const isOpen = this.classList.contains('active'); this.setAttribute('aria-expanded', String(isOpen)); content.setAttribute('aria-hidden', String(!isOpen)); if (isOpen) { content.style.maxHeight = content.scrollHeight + "px"; this.textContent = 'Manj'; } else { content.style.maxHeight = null; this.textContent = 'Več'; } }); accordion.textContent = 'Več'; accordion.setAttribute('aria-expanded', 'false'); const initialContent = accordion.closest('.mediation-accordion-item')?.querySelector('.accordion-content'); if (initialContent) { initialContent.setAttribute('aria-hidden', 'true'); } }); const header = document.querySelector('.main-header'); if (header) { let lastScroll = 0; window.addEventListener('scroll', () => { const currentScroll = window.pageYOffset; if (currentScroll <= 0) { header.classList.remove('scroll-up'); return; } if (currentScroll > lastScroll && !header.classList.contains('scroll-down')) { header.classList.remove('scroll-up'); header.classList.add('scroll-down'); } else if (currentScroll < lastScroll && header.classList.contains('scroll-down')) { header.classList.remove('scroll-down'); header.classList.add('scroll-up'); } lastScroll = currentScroll; }); } const mediationSections = document.querySelectorAll('.mediation-section'); if (mediationSections.length) { const mediationTitles = document.querySelectorAll('.mediation-section h2'); const closeAllSections = () => { mediationSections.forEach(section => { section.classList.remove('active'); }); }; mediationTitles.forEach(title => { title.addEventListener('click', () => { const parentSection = title.parentElement; const isAlreadyActive = parentSection.classList.contains('active'); closeAllSections(); if (!isAlreadyActive) { parentSection.classList.add('active'); } }); }); const openSectionFromHash = () => { const hash = window.location.hash; if (hash) { const targetSection = document.querySelector(hash); if (targetSection && targetSection.classList.contains('mediation-section')) { closeAllSections(); targetSection.classList.add('active'); } } }; window.addEventListener('hashchange', openSectionFromHash); openSectionFromHash(); if (!document.querySelector('.mediation-section.active') && mediationSections[0]) { mediationSections[0].classList.add('active'); } } const dropdownContainers = document.querySelectorAll('.nav-links .dropdown'); if (dropdownContainers.length) { const closeAllDropdowns = () => { dropdownContainers.forEach(container => { const dropdownContent = container.querySelector('.dropdown-content'); if (!dropdownContent) { return; } container.classList.remove('is-open'); dropdownContent.style.display = 'none'; dropdownContent.querySelectorAll('.dropdown-submenu-content').forEach(submenu => { submenu.style.display = 'none'; }); }); }; dropdownContainers.forEach(container => { const dropBtn = container.querySelector('.dropbtn'); const dropdownContent = container.querySelector('.dropdown-content'); if (!dropBtn || !dropdownContent) { return; } const closeDropdown = () => { container.classList.remove('is-open'); dropdownContent.style.display = 'none'; dropdownContent.querySelectorAll('.dropdown-submenu-content').forEach(submenu => { submenu.style.display = 'none'; }); }; const openDropdown = () => { container.classList.add('is-open'); dropdownContent.style.display = 'block'; }; dropBtn.addEventListener('click', (event) => { if (window.innerWidth <= 768) { return; } event.preventDefault(); const isOpen = container.classList.contains('is-open'); closeAllDropdowns(); if (!isOpen) { openDropdown(); } }); const submenuLinks = container.querySelectorAll('.dropdown-submenu > a'); submenuLinks.forEach(link => { const submenu = link.nextElementSibling; if (!submenu) { return; } link.addEventListener('click', (event) => { if (window.innerWidth <= 768) { return; } const parentList = link.parentElement.parentElement; parentList.querySelectorAll(':scope > .dropdown-submenu > .dropdown-submenu-content').forEach(sm => { if (sm !== submenu) { sm.style.display = 'none'; } }); const isOpen = submenu.style.display === 'block'; const href = link.getAttribute('href') || ''; if (href === '#' || href.trim() === '') { event.preventDefault(); submenu.style.display = isOpen ? 'none' : 'block'; return; } if (!isOpen) { event.preventDefault(); submenu.style.display = 'block'; } else { closeDropdown(); } }); }); container.querySelectorAll('.dropdown-submenu-content a').forEach(link => { if (link.nextElementSibling) { return; } link.addEventListener('click', () => { if (window.innerWidth <= 768) { return; } closeAllDropdowns(); closeMobileMenu(); }); }); }); document.addEventListener('click', (event) => { if (window.innerWidth <= 768) { return; } const clickedInside = Array.from(dropdownContainers).some(container => container.contains(event.target)); if (!clickedInside) { closeAllDropdowns(); } }); window.addEventListener('resize', () => { if (window.innerWidth <= 768) { closeAllDropdowns(); closeMobileMenu(); } }); } window.addEventListener('resize', () => { if (window.innerWidth > 768) { closeMobileMenu(); } }); if (typeof AOS !== 'undefined') { AOS.init({ duration: 600, easing: 'ease-out', once: true, offset: 50, delay: 100, disable: 'mobile' }); } const readMoreBtn = document.querySelector('.read-more-btn'); const moreStoryContent = document.querySelector('.more-story-content'); if (readMoreBtn && moreStoryContent) { if (moreStoryContent.id) { readMoreBtn.setAttribute('aria-controls', moreStoryContent.id); } const applyStoryState = (isVisible) => { readMoreBtn.textContent = isVisible ? 'Skrij zgodbo' : 'Moja zgodba'; readMoreBtn.setAttribute('aria-expanded', isVisible ? 'true' : 'false'); moreStoryContent.setAttribute('aria-hidden', isVisible ? 'false' : 'true'); }; let isExpanded = moreStoryContent.classList.contains('visible'); applyStoryState(isExpanded); moreStoryContent.style.height = isExpanded ? 'auto' : '0px'; const openStory = () => { moreStoryContent.classList.add('visible'); const targetHeight = moreStoryContent.scrollHeight; moreStoryContent.classList.add('is-animating'); moreStoryContent.style.height = '0px'; requestAnimationFrame(() => { moreStoryContent.style.height = `${targetHeight}px`; }); }; const closeStory = () => { const currentHeight = moreStoryContent.scrollHeight; moreStoryContent.style.height = `${currentHeight}px`; moreStoryContent.classList.add('is-animating'); requestAnimationFrame(() => { moreStoryContent.style.height = '0px'; }); }; moreStoryContent.addEventListener('transitionend', (event) => { if (event.propertyName !== 'height') { return; } moreStoryContent.classList.remove('is-animating'); if (isExpanded) { moreStoryContent.style.height = 'auto'; } else { moreStoryContent.classList.remove('visible'); moreStoryContent.style.height = ''; } }); readMoreBtn.addEventListener('click', () => { if (moreStoryContent.classList.contains('is-animating')) { return; } isExpanded = !isExpanded; applyStoryState(isExpanded); if (isExpanded) { openStory(); } else { closeStory(); } }); } }); function showError(input, message) { const formControl = input.parentElement; const errorDiv = formControl.querySelector('.error-message') || document.createElement('div'); errorDiv.className = 'error-message'; errorDiv.textContent = message; if (!formControl.querySelector('.error-message')) { formControl.appendChild(errorDiv); } formControl.classList.add('error'); } function removeError(input) { const formControl = input.parentElement; const errorDiv = formControl.querySelector('.error-message'); if (errorDiv) { formControl.removeChild(errorDiv); } formControl.classList.remove('error'); } function isValidEmail(email) { const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(String(email).toLowerCase()); }""" "./kdo-sem/index.html" : @@ -6616,9 +1338,26 @@ function isValidEmail(email) { Kdo sem - Prosberry + + + + + + + + + + + + + + + + +
@@ -6626,8 +1365,8 @@ function isValidEmail(email) { @@ -6745,7 +1484,7 @@ function isValidEmail(email) {
- Amra Kurešepi Zulji + Amra Kurešepi Zulji
@@ -6790,7 +1529,18 @@ function isValidEmail(email) { - +
+
+

Imaš vprašanje? Pokliči ali piši!

+ +

Skupaj ustvariva prostor za učenje in povezovanje.

+
+
+ + - + - - - + + - - + + - - + + """ @@ -7650,18 +2754,34 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { Ponudba - Prosberry + + + + + + + + + + - + + + + + + +