From b11fe56993c2cccaba6057d0ce1ecf95ec1a4da7 Mon Sep 17 00:00:00 2001 From: "Adrien W." Date: Sun, 11 Oct 2026 10:19:41 +0200 Subject: [PATCH] More UI / UX changes Added about page --- .env.example | 2 +- PRODUCTION.md | 8 +++- README.md | 1 + docker/Caddyfile | 2 + src/App.svelte | 3 ++ src/app.css | 35 +++++++++++--- src/components/AboutLink.svelte | 19 ++++++++ src/lib/router.svelte.js | 2 +- src/routes/About.svelte | 83 +++++++++++++++++++++++++++++++++ src/routes/Automations.svelte | 4 +- src/routes/Resume.svelte | 8 ++-- src/routes/Settings.svelte | 13 +++++- src/routes/SyncSettings.svelte | 48 +++++++++++++++++-- src/routes/Today.svelte | 6 ++- 14 files changed, 210 insertions(+), 24 deletions(-) create mode 100644 src/components/AboutLink.svelte create mode 100644 src/routes/About.svelte diff --git a/.env.example b/.env.example index 226c914..80d08de 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,7 @@ # reachable from the internet — port 80 is what the ACME challenge uses. SITE_ADDRESS=pardis.example.com -# Notified by Let's Encrypt before a certificate expires. Optional but advised. +# Required contact address for Let's Encrypt certificate management. ACME_EMAIL=you@example.com # Adresse locale d’écoute ; laisser 0.0.0.0 pour toutes les interfaces. diff --git a/PRODUCTION.md b/PRODUCTION.md index 2962911..2ba98bd 100644 --- a/PRODUCTION.md +++ b/PRODUCTION.md @@ -54,8 +54,12 @@ Commandes : `npx playwright install chromium` puis `npm run validate:all`. Un navigateur installé peut être choisi avec `PARDIS_CHROME_PATH`. La CI installe Chromium avec ses dépendances et lance les mêmes parcours. `docker compose config --quiet` a été validé avec des variables d’exemple. -Le build et le lancement de l’image Docker n’ont pas été exécutés ici (accès au -socket Docker indisponible dans le bac à sable). +Cette sandbox ne pouvait pas lancer les conteneurs (socket Docker indisponible), +mais l'opérateur confirme que le déploiement Docker de production et son job +CI/CD fonctionnent et sont en service depuis plusieurs commits. La VM qui héberge +l'instance reçoit une sauvegarde quotidienne. Celle-ci protège l'hébergement et +le service de synchronisation, mais pas les données locales conservées dans les +navigateurs des utilisateurs. ## Vérifications sur appareils réels à terminer avant publication diff --git a/README.md b/README.md index 5f8b7f0..1e338ae 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,7 @@ docker compose up -d --build Requirements: - `SITE_ADDRESS` must already resolve to the server. +- `ACME_EMAIL` is required and must be a valid contact address. - Ports **80 and 443** must be reachable from the internet. Port 80 is not optional — it is what the ACME challenge uses to prove domain ownership. diff --git a/docker/Caddyfile b/docker/Caddyfile index cac7bdc..f03af1a 100644 --- a/docker/Caddyfile +++ b/docker/Caddyfile @@ -62,6 +62,8 @@ http://{$SITE_ADDRESS} { header { Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'" + # Apply HSTS to this site address only; deliberately omit includeSubDomains. + Strict-Transport-Security "max-age=31536000" X-Content-Type-Options nosniff X-Frame-Options DENY Referrer-Policy strict-origin-when-cross-origin diff --git a/src/App.svelte b/src/App.svelte index d91b9d6..6660308 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -14,6 +14,7 @@ import Stats from './routes/Stats.svelte'; import DataSettings from './routes/DataSettings.svelte'; import SyncSettings from './routes/SyncSettings.svelte'; + import About from './routes/About.svelte'; import { liveQuery } from 'dexie'; import { loadSyncStatus, synchronize, takeAutomationRole } from './lib/sync/client.js'; import { syncState } from './lib/sync/state.svelte.js'; @@ -120,6 +121,8 @@ {:else if view === 'sync'} + {:else if view === 'about'} + {:else if ['settings', 'automations', 'non-working'].includes(view)} {:else if view === 'today'} diff --git a/src/app.css b/src/app.css index 957d395..9112bd4 100644 --- a/src/app.css +++ b/src/app.css @@ -8,6 +8,27 @@ * - Nothing tappable is under 64px; primary actions are 88px. */ +/* + * When the font files are ready, add their @font-face declarations here and + * place them under public/fonts/ (for example, /fonts/pardis-text.woff2). + * Keeping these declarations commented avoids requests for files not yet shipped. + * + * @font-face { + * font-family: 'Pardis Text'; + * src: url('/fonts/pardis-text.woff2') format('woff2'); + * font-style: normal; + * font-weight: 400; + * font-display: swap; + * } + * @font-face { + * font-family: 'Pardis Headings'; + * src: url('/fonts/pardis-headings.woff2') format('woff2'); + * font-style: normal; + * font-weight: 400; + * font-display: swap; + * } + */ + :root { --bg: #ffffff; --fg: #000000; @@ -31,9 +52,10 @@ --radius: 10px; --border: 3px; - --sans: system-ui, 'Segoe UI', Roboto, sans-serif; + --font-body: 'Pardis Text', system-ui, 'Segoe UI', Roboto, sans-serif; + --font-heading: 'Pardis Headings', system-ui, 'Segoe UI', Roboto, sans-serif; - font-family: var(--sans); + font-family: var(--font-body); font-size: 20px; line-height: 1.35; color: var(--fg); @@ -44,12 +66,12 @@ :root[data-theme='nuit'] { --bg: #000000; - --fg: #ffffff; - --fg-dim: #cccccc; + --fg: #e2bfbf; + --fg-dim: #dba7a7; --surface: #1a1a1a; - --line: #ffffff; + --line: #774a4a; - --accent: #ffb000; /* amber reads well at night and preserves dark adaptation */ + --accent: #e63100; /* amber reads well at night and preserves dark adaptation */ --accent-fg: #000000; --accent-soft: #3a2a00; @@ -89,6 +111,7 @@ body { h1, h2, h3 { + font-family: var(--font-heading); margin: 0; font-weight: 800; letter-spacing: -0.01em; diff --git a/src/components/AboutLink.svelte b/src/components/AboutLink.svelte new file mode 100644 index 0000000..c2bf3c2 --- /dev/null +++ b/src/components/AboutLink.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/router.svelte.js b/src/lib/router.svelte.js index 22b0dd2..6a15241 100644 --- a/src/lib/router.svelte.js +++ b/src/lib/router.svelte.js @@ -6,7 +6,7 @@ * worker should land on. */ -const ROUTES = ['resume', 'today', 'settings', 'stats', 'details', 'automations', 'non-working', 'data', 'sync']; +const ROUTES = ['resume', 'today', 'settings', 'stats', 'details', 'automations', 'non-working', 'data', 'sync', 'about']; function fromHash() { const [path, query = ''] = location.hash.replace(/^#\/?/, '').split('?'); diff --git a/src/routes/About.svelte b/src/routes/About.svelte new file mode 100644 index 0000000..e28c864 --- /dev/null +++ b/src/routes/About.svelte @@ -0,0 +1,83 @@ + + +
+ +

À propos de Pardis

+

+ Pardis est une application hors ligne de suivi des heures de chantier. Elle + enregistre les journées, les tâches, les clients, les repas et les pauses, + puis prépare un récapitulatif à consulter ou à copier. +

+ +
+

Fonctionnement

+

+ Les données sont enregistrées dans le stockage du navigateur sur cet + appareil. L’application fonctionne hors ligne après son premier chargement. + Elle n’exécute pas les automatismes lorsque le navigateur ou la PWA est + fermé ou suspendu ; elle rattrape les étapes prévues à la prochaine + ouverture. +

+

+ Les horaires automatiques sont des estimations. Vérifiez les journées + entièrement déduites avant de vous servir de leur récapitulatif. +

+
+ +
+

Données et confidentialité

+

+ Pardis ne demande ni compte, ni adresse e-mail, ni mot de passe. Aucun + service d’analyse ou de suivi publicitaire n’est chargé. Les statistiques + sont calculées sur l’appareil. +

+

+ L’historique local reste dans le navigateur jusqu’à sa suppression par + l’utilisateur ou à l’effacement du stockage du site. Le réglage de + conservation détermine quelles journées peuvent être purgées ; la purge + est manuelle. Le stockage du navigateur n’est pas chiffré par Pardis et + reste accessible à cette origine sur un navigateur déverrouillé. Un export + peut être conservé ailleurs, mais il n’est pas chiffré. +

+

+ La synchronisation entre appareils est facultative. Lorsqu’elle est + activée, le contenu des journées et des réglages synchronisés est chiffré + de bout en bout. Le serveur ne peut pas lire cet historique, mais reçoit + des métadonnées nécessaires au service : adresse IP, identifiants et clés + publiques des appareils, liens entre révisions, tailles et dates de + connexion. Ces données sont conservées un an, conformément à la loi. +

+

+ Supprimer une journée de l’historique synchronisé ne supprime pas ses + anciennes révisions chiffrées du coffre. Elles y restent jusqu’à la + suppression du coffre. Les sauvegardes de l’hébergement peuvent aussi + conserver des données supprimées jusqu’à l’expiration de leur rétention. +

+
+ +
+

Opérateur de cette instance

+

+ Le service de synchronisation de cette instance est hébergé sur un serveur + sauvegardé quotidiennement. Les sauvegardes de ce serveur + protègent le service en ligne ; elles ne sauvegardent pas les données + conservées uniquement dans le navigateur de chaque utilisateur. +

+

+ L'application est développée par Adrien Weiskopff. + L'application et son serveur de production sont hébergés en France par + clawd.fr (EI Adrien Weiskopff). + Pour plus d'informations rendez-vous sur le site https://clawd.fr ou écrivez + à l'adresse pardis@clawd.fr. +

+
+
+ + diff --git a/src/routes/Automations.svelte b/src/routes/Automations.svelte index 8df5944..468f296 100644 --- a/src/routes/Automations.svelte +++ b/src/routes/Automations.svelte @@ -5,10 +5,10 @@ import { go } from '../lib/router.svelte.js';
-

Réglages

+

Automatismes

+ {#if settingsError.message}

{settingsError.message}

{/if}
-

Automatismes

{#each AUTOMATION_OPTIONS as option (option.key)}
+ + +