diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index e991578..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.woodpecker
-.dockerignore
-.gitignore
-.git
-docker-compose.build.yml
-node_modules/
-.env.example
-LICENSE.md
-docker-compose.yml
-README.md
\ No newline at end of file
diff --git a/index.html b/index.html
deleted file mode 100644
index e8d901b..0000000
--- a/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
- Pianello
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/components/bottom-app-bar.js b/src/components/bottom-app-bar.js
deleted file mode 100644
index b1701eb..0000000
--- a/src/components/bottom-app-bar.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import homeIconUrl from '../../static/images/home-icon.png';
-import routesIconUrl from '../../static/images/routes-icon.png';
-import settingsIconUrl from '../../static/images/settings-icon.png';
-
-const template = `
-
-
-
-
-
-
-
-
-
-`;
-const style = `
- :host {
- display: flex;
- height: 68px;
- width: 90%;
- border-radius: 90px;
- box-shadow: 0 0 50px #ccc;
- background-color: var(--card-background-color);
- }
-
- :host > div {
- flex: 1;
- display: grid;
- place-items: center;
- }
-
- img {
- display: block;
- height: 32px;
- width: auto;
- }
-`;
-
-/**
- * Bottom app bar custom element.
- */
-class BottomAppBar extends HTMLElement {
- #elements = {};
-
- /**
- * @constructor
- */
- constructor() {
- super();
-
- this.#createShadowDOM();
- this.#setElements();
- this.#addEventListeners();
- }
-
- /**
- * Create shadow DOM.
- */
- #createShadowDOM() {
- this.attachShadow({mode: 'open'});
- this.shadowRoot.innerHTML = `
-
- ${template}
- `;
- }
-
- /**
- * Set all shadow dom selectors.
- */
- #setElements() {
- this.elements = {};
- }
-
- #addEventListeners() {}
-}
-
-customElements.define('bottom-app-bar', BottomAppBar);
-
-export default BottomAppBar;
-
diff --git a/src/components/wd-loader.js b/src/components/wd-loader.js
deleted file mode 100644
index d801547..0000000
--- a/src/components/wd-loader.js
+++ /dev/null
@@ -1,223 +0,0 @@
-const template = `
-
-`;
-const style = `
- * {
- box-sizing: border-box;
- }
-
- :host {
- display: none;
- }
-
- .background {
- position: fixed;
- top: 0px;
- left: 0px;
- width: 100%;
- height: 100%;
- opacity: 0;
- background-color: rgba(0, 0, 0, 0.6);
- z-index: 99999;
- transition: opacity 0.333s cubic-bezier(0, 0, 0.21, 1);
- }
-
- .loader {
- left: 50%;
- top: 50%;
- position: fixed;
- transform: translate(-50%, -50%);
- z-index: -1;
- }
-
- #spinner {
- box-sizing: border-box;
- stroke: var(--accent-color);
- stroke-width: 3px;
- transform-origin: 50%;
- animation: line 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite, rotate 1.6s linear infinite;
- }
-
- @keyframes rotate {
- from {
- -webkit-transform: rotate(0);
- transform: rotate(0);
- }
-
- to {
- -webkit-transform: rotate(450deg);
- transform: rotate(450deg);
- }
- }
-
- @keyframes line {
- 0% {
- stroke-dasharray: 2, 85.964;
- -webkit-transform: rotate(0);
- transform: rotate(0);
- }
-
- 50% {
- stroke-dasharray: 65.973, 21.9911;
- stroke-dashoffset: 0;
- }
-
- 100% {
- stroke-dasharray: 2, 85.964;
- stroke-dashoffset: -65.973;
- -webkit-transform: rotate(90deg);
- transform: rotate(90deg);
- }
- }
-
- #message {
- position: absolute;
- height: 20%;
- bottom: 0px;
- width: 100%;
- background-color: #212121;
- border-bottom-left-radius: 8px;
- border-bottom-right-radius: 8px;
- color: #eee;
- place-items: center;
- display: none;
- padding: 6px;
- }
-
- #message.show {
- display: grid !important;
- }
-
- :host(.contained) .background {
- position: absolute;
- width: 250px;
- height: 250px;
- border-radius: 8px;
- }
-
- :host(.contained) .loader {
- position: absolute;
- }
-`;
-
-/**
- * Spinner-style loader ce.
- */
-class WDLoader extends HTMLElement {
- #elements = {};
- isVisible = false;
- #counter = 0;
-
- /**
- * @constructor
- */
- constructor() {
- super();
-
- this.#createShadowDOM();
- this.#setElements();
- getComputedStyle(this.#elements.background).opacity;
- }
-
- /**
- * Set message.
- * @param {String} value
- */
- set message(value) {
- if (value && value !== '') {
- this.#elements.message.innerHTML = value;
- this.#elements.message.classList.add('show');
- } else {
- this.#elements.message.classList.remove('show');
- }
- }
-
- /**
- * @return {WDLoader}
- */
- static get instance() {
- let loader = document.querySelector('wd-loader');
-
- if (loader) {
- return loader;
- }
-
- loader = new WDLoader();
- document.body.appendChild(loader);
- return loader;
- }
-
- /**
- * Create shadow DOM.
- */
- #createShadowDOM() {
- this.attachShadow({mode: 'open'});
- this.shadowRoot.innerHTML = `
-
- ${template}
- `;
- }
-
- /**
- * Set all shadow dom selectors.
- */
- #setElements() {
- this.#elements = {
- background: this.shadowRoot.querySelector('.background'),
- message: this.shadowRoot.querySelector('#message'),
- };
- }
-
- /**
- * Show loader.
- * @param {String} message
- */
- show(message = '') {
- this.#counter++;
- this.style.display = 'block';
- this.isVisible = true;
- this.#elements.background.style.opacity = 1;
- this.message = message;
- getComputedStyle(this.#elements.background).opacity;
- }
-
- /**
- * Hide loader.
- */
- hide() {
- this.#counter--;
-
- if (this.#counter > 0) {
- return;
- }
-
- const onLoaderTransitionEnd = (evt) => {
- this.style.display = 'none';
- };
-
- this.#elements.background.addEventListener(
- 'transitionend',
- onLoaderTransitionEnd.bind(this),
- {once: true});
-
- this.isVisible = false;
- this.message = '';
-
- requestAnimationFrame(() => {
- requestAnimationFrame(() => {
- this.#elements.background.style.opacity = 0;
- });
- });
- }
-}
-
-customElements.define('wd-loader', WDLoader);
-
-export default WDLoader;
diff --git a/src/css/app.css b/src/css/app.css
deleted file mode 100644
index 99af787..0000000
--- a/src/css/app.css
+++ /dev/null
@@ -1,42 +0,0 @@
-
-:root {
- --footer-height: calc(68px + 20px + 20px);
- --accent-color: #213c8b;
- --pianello-red: #de0e1b;
- --pianello-yellow: #f6ae04;
- --pianello-blue: #213c8b;
- --card-background-color: #f9f4f1;
-}
-
-* {
- box-sizing: border-box;
-}
-
-html {
- width: 100%;
- height: 100%;
-}
-
-body {
- width: 100%;
- height: 100%;
- margin: 0px;
- background-color: #fff;
- font-family: 'Roboto-Regular';
- display: grid;
- place-items: center;
- grid-template-rows: var(--footer-height) auto var(--footer-height);
-}
-
-header,
-main,
-footer {
- height: 100%;
- width: 100%;
- display: grid;
- place-items: center;
-}
-
-.bold {
- font-weight: bold;
-}
diff --git a/src/css/home-page.css b/src/css/home-page.css
deleted file mode 100644
index 4ebbd96..0000000
--- a/src/css/home-page.css
+++ /dev/null
@@ -1,76 +0,0 @@
-/* @import './app.css'; */
-
-#welcome-message {
- font-size: 18px;
-}
-
-#route-cards {
- display: flex;
- flex-direction: column;
- height: 100%;
- width: 100%;
- align-items: center;
-}
-
-.route-card {
- flex: 1;
- --route-card-radius: 45px;
- border-radius: var(--route-card-radius);
- box-shadow: 0 0 27px #ccc;
- margin-top: 10px;
- margin-bottom: 10px;
- width: 90%;
- display: flex;
- background-color: var(--card-background-color);
-}
-
-.route-card > * {
- flex: 1;
-}
-
-.route-card-left {
- flex: 0 1 20%;
- border-top-left-radius: var(--route-card-radius);
- border-bottom-left-radius: var(--route-card-radius);
- display: grid;
- place-items: center;
-}
-
-.route-card-left img {
- display: block;
- width: 80%;
- height: auto;
-}
-
-.route-card-right {
- flex: 0 1 20%;
- border-top-right-radius: var(--route-card-radius);
- border-bottom-right-radius: var(--route-card-radius);
- background-image: url('/images/test-1.jpg');
- background-position: center;
- background-size: cover;
-}
-
-#route-cards .route-card:nth-child(1) .route-card-left {
- background-color: var(--pianello-red);
-}
-
-#route-cards .route-card:nth-child(2) .route-card-left {
- background-color: var(--pianello-yellow);
-}
-
-#route-cards .route-card:nth-child(3) .route-card-left {
- background-color: var(--pianello-blue);
-}
-
-.route-card .name {
- display: grid;
- height: 100%;
- align-content: center;
- padding: 20px;
- font-size: 20px;
-}
-
-.route-card .name > * {
- flex: 1;
-}
diff --git a/src/css/index.css b/src/css/index.css
deleted file mode 100644
index 8138f6f..0000000
--- a/src/css/index.css
+++ /dev/null
@@ -1 +0,0 @@
-@import './app.css';
diff --git a/src/css/roboto.css b/src/css/roboto.css
deleted file mode 100644
index 8b13789..0000000
--- a/src/css/roboto.css
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/js/app.js b/src/js/app.js
deleted file mode 100644
index 9b57d1c..0000000
--- a/src/js/app.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Router from './router.js';
-import WDLoader from '../components/wd-loader.js';
-import robotoFontStyle from '../css/roboto.css?raw';
-import appStyle from '../css/app.css?raw';
-const appIconURL = new URL('../../static/images/home-icon.png', import.meta.url).href;
-
-const app = {
- title: 'Pianello',
- meta: {
- charset: 'utf-8',
- viewport: 'width=device-width',
- },
- link: {
- icon: appIconURL,
- },
- page: null,
- router: new Router(),
- loader: WDLoader.instance,
- init: () => {
- document.head.innerHTML = `
-
-
-
- `;
- document.title = app.title;
- document.adoptedStyleSheets = [robotoFontStyle, appStyle]
- .map((rawSheet) => {
- const sheet = new CSSStyleSheet();
- sheet.replaceSync(rawSheet);
- return sheet;
- });
- },
-};
-
-export default app;
diff --git a/src/js/home-page.js b/src/js/home-page.js
deleted file mode 100644
index 1d01f85..0000000
--- a/src/js/home-page.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import app from './app.js';
-import pageStyle from '../css/home-page.css?raw';
-import BottomAppBar from '../components/bottom-app-bar.js';
-
-class HomePage {
- /**
- * An object containing useful HTMLElement references.
- * @type {Object}
- */
- #elements = {};
-
- constructor() {
- this.#addPageStyle();
- this.#setElements();
- this.#addEventListeners();
- }
-
- /**
- * @return {Object}
- */
- get elements() {
- return this.#elements;
- }
-
- #addPageStyle() {
- const sheet = new CSSStyleSheet();
- sheet.replaceSync(pageStyle);
- document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
- }
-
- /**
- * Init `#elements` field that holds element references.
- */
- #setElements() {
- this.#elements = {};
- }
-
- /**
- */
- #addEventListeners() {}
-}
-
-export default HomePage;
-
-app.init();
-app.page = new HomePage();
diff --git a/src/js/index.js b/src/js/index.js
deleted file mode 100644
index 72d6a75..0000000
--- a/src/js/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import app from './app.js';
-import homePageURL from '../pages/home-page.html?url';
-
-app.init();
-
-window.addEventListener('load', () => {
- if ('serviceWorker' in navigator) {
- // Service worker build output path.
- navigator.serviceWorker.register('/service-worker.js');
- }
-
- app.router.navigate(homePageURL);
-});
diff --git a/src/js/router.js b/src/js/router.js
deleted file mode 100644
index 6939d5e..0000000
--- a/src/js/router.js
+++ /dev/null
@@ -1,158 +0,0 @@
-import app from './app.js';
-
-/**
- * Router
- */
-class Router {
- /**
- * @constructor
- */
- constructor() {
- this.host = location.host;
- this.previousURL = null;
-
- this.initListeners();
- }
-
- /**
- * Add all event listeners handles.
- */
- initListeners() {
- document.addEventListener('click', this.onLinkClick.bind(this));
- window.addEventListener('popstate', this.onPopState.bind(this));
- }
-
- /**
- * window popstate event handler.
- * @param {Event} event
- */
- onPopState(event) {
- this.navigate(location.href, event.state.scrollTop, false);
- }
-
- /**
- * HTMLAnchorElement click event handler.
- * @param {Event} event
- */
- async onLinkClick(event) {
- const anchor = event.target.closest('a');
- if (!anchor) {
- return;
- }
-
- if (anchor.dataset.hasOwnProperty('external')) {
- return;
- }
-
- const {href} = anchor;
- const link = new URL(href);
-
- // If it’s an external link, just navigate.
- if (link.host !== this.host) {
- return;
- }
-
- event.preventDefault();
- this.navigate(link.toString())
- .catch((error) => console.error(error));
- }
-
- /**
- * Handle the navigation.
- * @param {string} link
- * @param {number} scrollTop
- * @param {boolean} pushState
- * @return {Promise} Fetch fragment status
- */
- async navigate(link, scrollTop = 0, pushState = true) {
- if (!link) {
- return;
- }
-
- // Save current route for history pop event.
- this.previousURL = location.href;
- // Manually handle the scroll restoration.
- history.scrollRestoration = 'manual';
-
- if (pushState) {
- history.replaceState({
- scrollTop: document.scrollingElement.scrollTop,
- }, '');
- history.pushState({scrollTop}, '', link);
- }
-
- const linkUrl = new URL((link.startsWith('http')) ?
- link :
- `${location.origin}${link}`);
-
- // Fetch new page and switch.
- const oldHeader = document.querySelector('header');
- const oldMain = document.querySelector('main');
- const oldFooter = document.querySelector('footer');
- const {
- status,
- header,
- main,
- footer,
- script: newPageScript,
- } = await this.fetchFragment(link);
-
- if (status === 200) {
- // Replace elements.
- oldHeader?.parentNode?.replaceChild(header, oldHeader);
- oldMain?.parentNode?.replaceChild(main, oldMain);
- oldFooter?.parentNode?.replaceChild(footer, oldFooter);
- const newScriptFilename = newPageScript?.src.split('/').slice(-1)[0];
- app.loader.show();
- try {
- await app.page?.clear?.();
- // String manipulation from static analysis.
- const script = await import(
- `../js/${newScriptFilename.replace('.js', '')}.js`);
- // Enable current page re-navigation and avoid double page init.
- // Check only on url.origin+url.pathname to allow
- // re-navigation on same page with different url parameters.
- const prevLinkUrl = new URL(this.previousURL);
- if (!(app.page instanceof script.default) ||
- (linkUrl.origin + linkUrl.pathname ===
- prevLinkUrl.origin + prevLinkUrl.pathname)) {
- // eslint-disable-next-line new-cap
- app.page = new script.default();
- }
- } catch (ex) {
- console.error(ex);
- } finally {
- app.loader.hide();
- }
-
- document.scrollingElement.scrollTop = scrollTop;
- }
-
- // Set to auto in case user hits page refresh.
- history.scrollRestoration = 'auto';
- return status;
- }
-
- /**
- * Fetch page and get main element;
- * @param {string} link
- * @return {*}
- */
- async fetchFragment(link) {
- const url = (link.startsWith('http')) ? link : `${location.origin}${link}`;
- link = (new URL(url)).pathname;
-
- const response = await fetch(link);
- const template = document.createElement('template');
- template.innerHTML = await response.text();
- return {
- status: response.status,
- header: template.content.querySelector('header')?.cloneNode(true),
- main: template.content.querySelector('main')?.cloneNode(true),
- footer: template.content.querySelector('footer')?.cloneNode(true),
- script: template.content.querySelector('#page-script')?.cloneNode(true),
- };
- }
-}
-
-export default Router;
diff --git a/src/js/service-worker.js b/src/js/service-worker.js
deleted file mode 100644
index ee2ecad..0000000
--- a/src/js/service-worker.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import {precacheAndRoute} from 'workbox-precaching';
-
-precacheAndRoute(self.__WB_MANIFEST);
-
diff --git a/src/pages/home-page.html b/src/pages/home-page.html
deleted file mode 100644
index a70abcf..0000000
--- a/src/pages/home-page.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
Percorsi
-
naturalistici
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Percorsi
-
tradizionalistici
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pages/offline.html b/src/pages/offline.html
deleted file mode 100644
index e69de29..0000000