diff --git a/package-lock.json b/package-lock.json index 752078f..9afaff2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "cimaprogetti", "version": "1.0.0", + "dependencies": { + "svelte-spa-router": "^4.0.0" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^7.0.0", "svelte": "^5.55.5", @@ -970,6 +973,15 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/regexparam": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.2.tgz", + "integrity": "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/rolldown": { "version": "1.0.0-rc.17", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz", @@ -1042,6 +1054,18 @@ "node": ">=18" } }, + "node_modules/svelte-spa-router": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-4.0.2.tgz", + "integrity": "sha512-T1WYYk+ymwCr5m5U+n91k4dRAT6cw5HgmoPaI/TpKgAmuugymFoSBlfzkcKIK83QH4H8gUMn4tdQ0B9enFBM6g==", + "license": "MIT", + "dependencies": { + "regexparam": "2.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ItalyPaleAle" + } + }, "node_modules/tinyglobby": { "version": "0.2.16", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", diff --git a/src/App.svelte b/src/App.svelte index c5f0096..8cfb4d9 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -3,30 +3,80 @@ import Hero from "./components/Hero/Hero.svelte"; import Services from "./components/Services/Services.svelte"; import Footer from "./components/Footer/Footer.svelte"; - import "./styles/App.css"; import Header from "./components/Header/Header.svelte"; + import Contacts from "./pages/Contacts.svelte"; + import Forbidden from "./pages/403.svelte"; + import ServerError from "./pages/500.svelte"; + import ErrorGeneric from "./pages/errore.svelte"; + import NotFound from "./pages/404.svelte"; + + let pathname = '/' + + const normalizePath = (path) => { + if (!path) return '/' + const trimmed = path.trim() + return trimmed.endsWith('/') && trimmed.length > 1 + ? trimmed.slice(0, -1) + : trimmed + } + + const getRoute = (path) => { + const normalized = normalizePath(path) + + if (normalized === '/') return 'home' + if (normalized === '/contatti' || normalized === '/contacts') return 'contacts' + if (normalized === '/403') return '403' + if (normalized === '/500') return '500' + if (normalized === '/errore') return 'error' + return '404' + } + + $: currentRoute = getRoute(pathname) + $: isCenteredMain = ['403', '404', '500', 'error'].includes(currentRoute) onMount(() => { try { const saved = localStorage.getItem('theme') if (saved) { document.documentElement.setAttribute('data-theme', saved) - return + } else { + const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches + const theme = prefersDark ? 'dark' : 'light' + document.documentElement.setAttribute('data-theme', theme) + localStorage.setItem('theme', theme) } - const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches - const theme = prefersDark ? 'dark' : 'light' - document.documentElement.setAttribute('data-theme', theme) - localStorage.setItem('theme', theme) } catch (e) { document.documentElement.setAttribute('data-theme', 'light') } + + pathname = window.location.pathname + + const handlePopstate = () => { + pathname = window.location.pathname + } + + window.addEventListener('popstate', handlePopstate) + return () => window.removeEventListener('popstate', handlePopstate) })