mirror of
https://github.com/arthur-pbty/calculatrice.git
synced 2026-06-03 23:36:29 +02:00
Refactor Dockerfile, update README, and enhance Calculator component
- Refactored Dockerfile for improved multi-stage builds and added development and production configurations. - Updated README with clearer project description, local development instructions, and added contact information. - Enhanced Calculator component to manage theme and history using localStorage, improving user experience. - Added new pages for legal mentions and privacy policy, including relevant metadata. - Updated docker-compose.yml for better service management and added environment variables. - Introduced a new LICENSE file outlining usage rights and responsibilities.
This commit is contained in:
+16
-24
@@ -1,34 +1,26 @@
|
||||
# === Étape 1 : Build ===
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
FROM node:22-alpine AS calculatrice-base
|
||||
WORKDIR /app
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
# Copier les fichiers de dépendances pour profiter du cache Docker
|
||||
COPY package*.json ./
|
||||
|
||||
# Installer uniquement ce qu'il faut pour le build
|
||||
FROM calculatrice-base AS calculatrice-deps
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
# Copier tout le code
|
||||
FROM calculatrice-deps AS calculatrice-dev
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "run", "dev", "--", "--hostname", "0.0.0.0", "--port", "3000"]
|
||||
|
||||
# Build Next.js pour la production
|
||||
FROM calculatrice-deps AS calculatrice-builder
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# === Étape 2 : Runner léger ===
|
||||
FROM node:20-alpine AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copier uniquement ce qui est nécessaire pour la prod
|
||||
COPY --from=builder /app/package*.json ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Mode production
|
||||
FROM calculatrice-base AS calculatrice-runner
|
||||
ENV NODE_ENV=production
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
ENV PORT=3000
|
||||
COPY --from=calculatrice-builder /app/.next/standalone ./
|
||||
COPY --from=calculatrice-builder /app/.next/static ./.next/static
|
||||
COPY --from=calculatrice-builder /app/public ./public
|
||||
EXPOSE 3000
|
||||
|
||||
# Lancer le serveur Next.js
|
||||
CMD ["npm", "start"]
|
||||
CMD ["node", "server.js"]
|
||||
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2026 Arthur
|
||||
|
||||
Licence pour tous les projets Arthur
|
||||
|
||||
1. Définition
|
||||
Cette licence définit les droits et obligations concernant l'utilisation, la modification et la redistribution du code fourni par l'auteur.
|
||||
|
||||
2. Autorisation d'utilisation
|
||||
Vous êtes libre d'utiliser ce code pour vos projets personnels ou commerciaux. L'utilisation doit inclure une mention de l'auteur d’une manière libre (ex: "inspiré de ArthurP").
|
||||
|
||||
3. Modification
|
||||
Vous pouvez modifier, adapter ou améliorer le code pour vos besoins. Les modifications doivent être identifiées comme telles et ne doivent pas être présentées comme l'original.
|
||||
|
||||
4. Redistribution
|
||||
- Le code original **ne peut pas être redistribué tel quel**.
|
||||
- Les versions modifiées peuvent être partagées, sous réserve de mentionner l'auteur original.
|
||||
|
||||
5. Usage commercial
|
||||
L’usage commercial des versions modifiées est autorisé. Vous pouvez générer des revenus avec votre version modifiée.
|
||||
|
||||
6. Attribution
|
||||
L'auteur original doit être cité d’une manière libre, mais visible, sur tout projet utilisant ce code ou ses dérivés.
|
||||
|
||||
7. Responsabilité
|
||||
Le code est fourni "tel quel", sans garantie d’aucune sorte. L’auteur décline toute responsabilité pour tout dommage direct ou indirect résultant de l’utilisation du code.
|
||||
@@ -1,33 +1,32 @@
|
||||
# Calculatrice
|
||||
|
||||
Application web de calculatrice réalisée avec Next.js.
|
||||
Calculatrice web (simple + scientifique) construite avec Next.js.
|
||||
|
||||
## Site en ligne
|
||||
## Liens
|
||||
|
||||
- Projet: https://calculatrice.arthurp.fr
|
||||
- Site: https://calculatrice.arthurp.fr
|
||||
- Site principal: https://arthurp.fr
|
||||
- Contact: https://contact.arthurp.fr
|
||||
- Email: contact@arthurp.fr
|
||||
|
||||
## Objectif
|
||||
|
||||
Proposer une calculatrice simple, rapide et responsive, utilisable sur desktop et mobile.
|
||||
|
||||
## Stack technique
|
||||
## Stack
|
||||
|
||||
- Next.js 16
|
||||
- React 19
|
||||
- TypeScript
|
||||
|
||||
## Lancement en local
|
||||
## Developpement local
|
||||
|
||||
Prerequis: Node.js 20+
|
||||
Prerequis: Node.js 22+
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm ci
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Application accessible sur http://localhost:3000
|
||||
Application: http://localhost:3000
|
||||
|
||||
## Scripts utiles
|
||||
## Scripts
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
@@ -36,21 +35,24 @@ npm run start
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## Deploiement
|
||||
## Docker
|
||||
|
||||
Build de production:
|
||||
Mode dev:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
docker compose --profile dev up --build
|
||||
```
|
||||
|
||||
Ensuite deployer sur votre plateforme cible (Vercel, VPS, etc.).
|
||||
Mode production:
|
||||
|
||||
## Backlinks
|
||||
```bash
|
||||
docker compose --profile prod up --build -d
|
||||
```
|
||||
|
||||
- Calculatrice en ligne: https://calculatrice.arthurp.fr
|
||||
- Site principal: https://arthurp.fr
|
||||
- Dev: http://localhost:3000
|
||||
- Prod: http://localhost:3014
|
||||
|
||||
## Licence
|
||||
## Pages legales
|
||||
|
||||
Projet personnel.
|
||||
- /mentions-legales
|
||||
- /politique-de-confidentialite
|
||||
|
||||
+142
-107
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
|
||||
/* ══════════════════════════════════════════════
|
||||
@@ -151,39 +152,37 @@ export default function Calculator() {
|
||||
const [error, setError] = useState(""); // Message d'erreur
|
||||
const [steps, setSteps] = useState<string[]>([]); // Étapes de calcul
|
||||
const [showSteps, setShowSteps] = useState(false); // Afficher les étapes
|
||||
const [history, setHistory] = useState<HistoryEntry[]>([]); // Historique
|
||||
const [history, setHistory] = useState<HistoryEntry[]>(() => {
|
||||
if (typeof window === "undefined") return [];
|
||||
try {
|
||||
const savedHistory = localStorage.getItem(HISTORY_KEY);
|
||||
return savedHistory ? JSON.parse(savedHistory) : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}); // Historique
|
||||
const [showHistory, setShowHistory] = useState(false); // Panneau historique visible
|
||||
const [isScientific, setIsScientific] = useState(false); // Mode scientifique
|
||||
const [isDark, setIsDark] = useState(false); // Thème sombre
|
||||
const [isDark, setIsDark] = useState(() => {
|
||||
if (typeof window === "undefined") return false;
|
||||
try {
|
||||
const savedTheme = localStorage.getItem(THEME_KEY);
|
||||
if (savedTheme === "dark") return true;
|
||||
if (savedTheme === "light") return false;
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}); // Thème sombre
|
||||
const [copied, setCopied] = useState(false); // Feedback copie
|
||||
const [lastKey, setLastKey] = useState(""); // Dernière touche pressée (feedback visuel)
|
||||
|
||||
const displayRef = useRef<HTMLDivElement>(null);
|
||||
const simpleRef = useRef<HTMLButtonElement>(null);
|
||||
const sciRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
// ── Chargement initial depuis localStorage ──
|
||||
// ── Synchroniser la classe de thème avec l'état courant ──
|
||||
useEffect(() => {
|
||||
try {
|
||||
const savedHistory = localStorage.getItem(HISTORY_KEY);
|
||||
if (savedHistory) setHistory(JSON.parse(savedHistory));
|
||||
|
||||
const savedTheme = localStorage.getItem(THEME_KEY);
|
||||
if (savedTheme === "dark") {
|
||||
setIsDark(true);
|
||||
document.documentElement.classList.add("dark");
|
||||
} else if (savedTheme === "light") {
|
||||
setIsDark(false);
|
||||
document.documentElement.classList.remove("dark");
|
||||
} else {
|
||||
// Détecter la préférence système
|
||||
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
setIsDark(prefersDark);
|
||||
}
|
||||
} catch {
|
||||
// localStorage non disponible
|
||||
}
|
||||
}, []);
|
||||
document.documentElement.classList.toggle("dark", isDark);
|
||||
}, [isDark]);
|
||||
|
||||
// ── Sauvegarder l'historique dans localStorage ──
|
||||
useEffect(() => {
|
||||
@@ -430,7 +429,7 @@ export default function Calculator() {
|
||||
════════════════════════════════════════════ */
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col items-center justify-center p-4 sm:p-8 transition-colors duration-300">
|
||||
<div className="min-h-screen flex flex-col items-center p-4 sm:p-8 transition-colors duration-300">
|
||||
{/* Lien d'accessibilité : aller au contenu principal */}
|
||||
<a
|
||||
href="#calculatrice"
|
||||
@@ -463,23 +462,16 @@ export default function Calculator() {
|
||||
<div
|
||||
className="mode-slider"
|
||||
style={{
|
||||
left: isScientific
|
||||
? (simpleRef.current?.offsetWidth ?? 80) + 2 + "px"
|
||||
: "2px",
|
||||
width: isScientific
|
||||
? (sciRef.current?.offsetWidth ?? 100) + "px"
|
||||
: (simpleRef.current?.offsetWidth ?? 80) + "px",
|
||||
transform: isScientific ? "translateX(100%)" : "translateX(0)",
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
ref={simpleRef}
|
||||
className={!isScientific ? "active" : ""}
|
||||
onClick={() => setIsScientific(false)}
|
||||
>
|
||||
Simple
|
||||
</button>
|
||||
<button
|
||||
ref={sciRef}
|
||||
className={isScientific ? "active" : ""}
|
||||
onClick={() => setIsScientific(true)}
|
||||
>
|
||||
@@ -747,102 +739,145 @@ export default function Calculator() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ── Footer SEO avec contenu sémantique ── */}
|
||||
<footer className="mt-12 w-full max-w-2xl animate-fade-in" style={{ animationDelay: "0.3s" }}>
|
||||
{/* Contenu textuel riche pour le SEO */}
|
||||
<article className="mb-8 px-4">
|
||||
<h2 className="text-xl font-bold mb-3" style={{ color: "var(--foreground)" }}>
|
||||
Calculatrice en ligne gratuite
|
||||
{/* ── Contenu SEO ── */}
|
||||
<section className="mt-10 w-full max-w-3xl space-y-5" aria-labelledby="seo-content-heading">
|
||||
<h2 id="seo-content-heading" className="text-xl font-bold" style={{ color: "var(--foreground)" }}>
|
||||
Calculatrice en ligne simple et scientifique
|
||||
</h2>
|
||||
<p className="text-sm leading-relaxed mb-4" style={{ color: "var(--muted)" }}>
|
||||
Notre calculatrice en ligne gratuite vous permet d'effectuer tous vos calculs
|
||||
directement dans votre navigateur, sans installation ni inscription. Que vous ayez
|
||||
besoin d'une simple addition ou d'un calcul scientifique complexe avec des
|
||||
fonctions trigonométriques, notre outil s'adapte à vos besoins.
|
||||
<p className="text-sm leading-relaxed" style={{ color: "var(--muted)" }}>
|
||||
Cette calculatrice en ligne gratuite permet de faire vos opérations du quotidien et vos calculs plus avances,
|
||||
directement depuis votre navigateur. Aucun compte, aucune installation et une interface rapide sur mobile comme
|
||||
sur ordinateur.
|
||||
</p>
|
||||
<p className="text-sm leading-relaxed" style={{ color: "var(--muted)" }}>
|
||||
Le mode simple couvre addition, soustraction, multiplication et division. Le mode scientifique ajoute sin, cos,
|
||||
tan, logarithmes, racine carree, puissances, factorielle et constantes pi / e. L'historique est conserve
|
||||
localement pour retrouver vos derniers calculs.
|
||||
</p>
|
||||
|
||||
<h2 className="text-lg font-semibold mb-2" style={{ color: "var(--foreground)" }}>
|
||||
Mode simple : les opérations essentielles
|
||||
</h2>
|
||||
<p className="text-sm leading-relaxed mb-4" style={{ color: "var(--muted)" }}>
|
||||
Le mode simple couvre les quatre opérations fondamentales : addition (+),
|
||||
soustraction (−), multiplication (×) et division (÷). Vous pouvez utiliser
|
||||
des parenthèses pour structurer vos expressions et obtenir des résultats
|
||||
précis. La gestion des erreurs vous avertit automatiquement en cas de
|
||||
division par zéro.
|
||||
</p>
|
||||
|
||||
<h2 className="text-lg font-semibold mb-2" style={{ color: "var(--foreground)" }}>
|
||||
Mode scientifique : des fonctions avancées
|
||||
</h2>
|
||||
<p className="text-sm leading-relaxed mb-4" style={{ color: "var(--muted)" }}>
|
||||
Basculez en mode scientifique pour accéder aux fonctions trigonométriques
|
||||
(sinus, cosinus, tangente), aux logarithmes (log décimal, logarithme naturel),
|
||||
à la racine carrée, aux puissances, à la factorielle, ainsi qu'aux
|
||||
constantes mathématiques π et e. Idéal pour les étudiants, ingénieurs et
|
||||
professionnels.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
{/* Section FAQ pour le SEO */}
|
||||
<section className="mb-8 px-4" aria-labelledby="faq-heading">
|
||||
<h2 id="faq-heading" className="text-lg font-semibold mb-3" style={{ color: "var(--foreground)" }}>
|
||||
Questions fréquentes
|
||||
</h2>
|
||||
<div className="space-y-3">
|
||||
<div className="rounded-xl border p-4" style={{ borderColor: "var(--border-color)", background: "var(--surface)" }}>
|
||||
<h3 className="text-base font-semibold" style={{ color: "var(--foreground)" }}>
|
||||
Questions frequentes
|
||||
</h3>
|
||||
<div className="mt-3 space-y-2 text-sm" style={{ color: "var(--muted)" }}>
|
||||
{[
|
||||
{
|
||||
q: "Comment utiliser la calculatrice en ligne ?",
|
||||
a: "Cliquez sur les boutons ou utilisez votre clavier pour saisir une expression mathématique, puis appuyez sur « = » ou Entrée pour obtenir le résultat.",
|
||||
q: "Comment faire un calcul rapidement ?",
|
||||
a: "Saisissez votre expression puis appuyez sur Entree ou sur le bouton =.",
|
||||
},
|
||||
{
|
||||
q: "Quelles fonctions scientifiques sont disponibles ?",
|
||||
a: "Sinus, cosinus, tangente, logarithme décimal, logarithme naturel, racine carrée, puissances, factorielle, et les constantes π et e.",
|
||||
q: "Puis-je utiliser le clavier ?",
|
||||
a: "Oui. Les chiffres et operateurs sont pris en charge. Entree calcule, Echap efface et Retour arriere supprime le dernier caractere.",
|
||||
},
|
||||
{
|
||||
q: "L'historique des calculs est-il sauvegardé ?",
|
||||
a: "Oui, vos 50 derniers calculs sont sauvegardés automatiquement dans votre navigateur et persistent même après fermeture de la page.",
|
||||
q: "A quoi sert le mode scientifique ?",
|
||||
a: "Il ajoute les fonctions avancees: sin, cos, tan, log, ln, racine carree, puissances et factorielle.",
|
||||
},
|
||||
{
|
||||
q: "La calculatrice est-elle vraiment gratuite ?",
|
||||
a: "Oui, 100 % gratuite, sans publicité et sans inscription. Utilisez-la autant que vous le souhaitez.",
|
||||
q: "Est-ce que l'historique est conserve ?",
|
||||
a: "Oui, les 50 derniers calculs sont stockes localement dans votre navigateur.",
|
||||
},
|
||||
{
|
||||
q: "Puis-je utiliser des raccourcis clavier ?",
|
||||
a: "Oui ! Chiffres et opérateurs au clavier, Entrée pour calculer, Échap pour effacer, Retour arrière pour supprimer, Ctrl+C pour copier.",
|
||||
q: "Puis-je reutiliser un ancien calcul ?",
|
||||
a: "Oui, ouvrez l'historique puis cliquez sur une ligne pour recharger l'expression et le resultat.",
|
||||
},
|
||||
].map((faq, i) => (
|
||||
{
|
||||
q: "La calculatrice fonctionne-t-elle sur mobile ?",
|
||||
a: "Oui, l'interface est adaptee aux ecrans mobiles et ordinateurs.",
|
||||
},
|
||||
{
|
||||
q: "Dois-je creer un compte ?",
|
||||
a: "Non, aucun compte n'est necessaire pour utiliser la calculatrice.",
|
||||
},
|
||||
{
|
||||
q: "Comment contacter le proprietaire du site ?",
|
||||
a: "Via contact.arthurp.fr ou par email a contact@arthurp.fr.",
|
||||
},
|
||||
].map((item, i) => (
|
||||
<details
|
||||
key={i}
|
||||
className="rounded-lg overflow-hidden transition-all"
|
||||
style={{
|
||||
background: "var(--surface)",
|
||||
border: "1px solid var(--border-color)",
|
||||
}}
|
||||
className="rounded-lg border px-3 py-2"
|
||||
style={{ borderColor: "var(--border-color)", background: "var(--background)" }}
|
||||
>
|
||||
<summary
|
||||
className="px-4 py-3 cursor-pointer text-sm font-medium select-none hover:bg-[var(--surface-hover)] transition-colors"
|
||||
style={{ color: "var(--foreground)" }}
|
||||
>
|
||||
{faq.q}
|
||||
<summary className="cursor-pointer font-medium" style={{ color: "var(--foreground)" }}>
|
||||
{item.q}
|
||||
</summary>
|
||||
<p
|
||||
className="px-4 pb-3 text-sm leading-relaxed"
|
||||
style={{ color: "var(--muted)" }}
|
||||
>
|
||||
{faq.a}
|
||||
</p>
|
||||
<p className="mt-2 leading-relaxed">{item.a}</p>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Copyright */}
|
||||
<div className="text-center text-xs pb-4" style={{ color: "var(--muted)" }}>
|
||||
<p>© {new Date().getFullYear()} Calculatrice en ligne gratuite — Simple & Scientifique</p>
|
||||
<p className="mt-1 opacity-60">
|
||||
Outil de calcul en ligne rapide, gratuit et sans inscription.
|
||||
</p>
|
||||
{/* ── Footer normal en bas de page ── */}
|
||||
<footer className="mt-auto w-full px-3 pt-10 pb-3">
|
||||
<div
|
||||
className="mx-auto w-full max-w-5xl rounded-2xl border p-4 sm:p-6 backdrop-blur-xl"
|
||||
style={{
|
||||
background: "color-mix(in srgb, var(--surface) 88%, transparent)",
|
||||
borderColor: "var(--border-color)",
|
||||
boxShadow: "var(--shadow-lg)",
|
||||
}}
|
||||
>
|
||||
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<section>
|
||||
<h2 className="text-sm font-semibold tracking-wide uppercase" style={{ color: "var(--foreground)" }}>
|
||||
Navigation
|
||||
</h2>
|
||||
<nav className="mt-3 flex flex-col gap-2 text-sm" aria-label="Navigation du site">
|
||||
<Link href="/" className="hover:underline" style={{ color: "var(--muted)" }}>Accueil</Link>
|
||||
<a href="https://arthurp.fr/projets" target="_blank" rel="noreferrer" className="hover:underline" style={{ color: "var(--muted)" }}>Projets</a>
|
||||
<a href="https://contact.arthurp.fr" target="_blank" rel="noreferrer" className="hover:underline" style={{ color: "var(--muted)" }}>Contact</a>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-sm font-semibold tracking-wide uppercase" style={{ color: "var(--foreground)" }}>
|
||||
Liens
|
||||
</h2>
|
||||
<div className="mt-3 flex flex-col gap-2 text-sm">
|
||||
<a href="https://arthurp.fr" target="_blank" rel="noreferrer" className="hover:underline" style={{ color: "var(--muted)" }}>
|
||||
arthurp.fr
|
||||
</a>
|
||||
<a href="https://github.com/arthur-pbty" target="_blank" rel="noreferrer" className="hover:underline" style={{ color: "var(--muted)" }}>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-sm font-semibold tracking-wide uppercase" style={{ color: "var(--foreground)" }}>
|
||||
Légal
|
||||
</h2>
|
||||
<div className="mt-3 flex flex-col gap-2 text-sm">
|
||||
<Link href="/mentions-legales" className="hover:underline" style={{ color: "var(--muted)" }}>
|
||||
Mentions légales
|
||||
</Link>
|
||||
<Link href="/politique-de-confidentialite" className="hover:underline" style={{ color: "var(--muted)" }}>
|
||||
Politique de confidentialité
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="text-sm font-semibold tracking-wide uppercase" style={{ color: "var(--foreground)" }}>
|
||||
Contact
|
||||
</h2>
|
||||
<div className="mt-3 flex flex-col gap-2 text-sm" style={{ color: "var(--muted)" }}>
|
||||
<a href="https://contact.arthurp.fr" target="_blank" rel="noreferrer" className="hover:underline">
|
||||
contact.arthurp.fr
|
||||
</a>
|
||||
<a href="mailto:contact@arthurp.fr" className="hover:underline">
|
||||
contact@arthurp.fr
|
||||
</a>
|
||||
<p className="text-xs opacity-80">Fait avec ❤️ et auto-hébergé sur Proxmox.</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 border-t pt-3 text-center text-xs" style={{ color: "var(--muted)", borderColor: "var(--border-color)" }}>
|
||||
© {new Date().getFullYear()} Arthur P. Tous droits réservés.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
+6
-1
@@ -285,6 +285,7 @@ body {
|
||||
.mode-toggle {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-width: 210px;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 10px;
|
||||
@@ -292,9 +293,11 @@ body {
|
||||
}
|
||||
|
||||
.mode-toggle button {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 6px 16px;
|
||||
text-align: center;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
@@ -311,10 +314,12 @@ body {
|
||||
.mode-slider {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
width: calc(50% - 2px);
|
||||
border-radius: 8px;
|
||||
background: var(--primary);
|
||||
transition: left 0.3s ease, width 0.3s ease;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* ══════════════════════════════════════════════
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Mentions legales",
|
||||
description: "Mentions legales du site calculatrice.arthurp.fr",
|
||||
};
|
||||
|
||||
export default function MentionsLegalesPage() {
|
||||
return (
|
||||
<main className="min-h-screen px-4 py-12 sm:px-8">
|
||||
<div className="mx-auto w-full max-w-3xl rounded-2xl border p-6 sm:p-8" style={{ background: "var(--surface)", borderColor: "var(--border-color)" }}>
|
||||
<h1 className="text-2xl font-bold sm:text-3xl">Mentions legales</h1>
|
||||
|
||||
<section className="mt-6 space-y-3 text-sm leading-relaxed" style={{ color: "var(--muted)" }}>
|
||||
<p>
|
||||
Site: calculatrice.arthurp.fr
|
||||
</p>
|
||||
<p>
|
||||
Proprietaire et editeur: Arthur P.
|
||||
</p>
|
||||
<p>
|
||||
Contact principal: <a href="https://contact.arthurp.fr" className="hover:underline">contact.arthurp.fr</a>
|
||||
</p>
|
||||
<p>
|
||||
Email: <a href="mailto:contact@arthurp.fr" className="hover:underline">contact@arthurp.fr</a>
|
||||
</p>
|
||||
<p>
|
||||
Hebergement: infrastructure auto-hebergee sur Proxmox.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Politique de confidentialite",
|
||||
description: "Politique de confidentialite du site calculatrice.arthurp.fr",
|
||||
};
|
||||
|
||||
export default function PolitiqueConfidentialitePage() {
|
||||
return (
|
||||
<main className="min-h-screen px-4 py-12 sm:px-8">
|
||||
<div className="mx-auto w-full max-w-3xl rounded-2xl border p-6 sm:p-8" style={{ background: "var(--surface)", borderColor: "var(--border-color)" }}>
|
||||
<h1 className="text-2xl font-bold sm:text-3xl">Politique de confidentialite</h1>
|
||||
|
||||
<section className="mt-6 space-y-3 text-sm leading-relaxed" style={{ color: "var(--muted)" }}>
|
||||
<p>
|
||||
Cette application ne requiert pas de compte et ne collecte pas de donnees personnelles cote serveur pour son fonctionnement courant.
|
||||
</p>
|
||||
<p>
|
||||
L'historique de calcul est stocke localement dans votre navigateur (localStorage) pour ameliorer l'experience utilisateur.
|
||||
</p>
|
||||
<p>
|
||||
Vous pouvez supprimer ces donnees a tout moment depuis le bouton "Tout effacer" dans l'historique ou via les reglages de votre navigateur.
|
||||
</p>
|
||||
<p>
|
||||
Pour toute demande, vous pouvez utiliser <a href="https://contact.arthurp.fr" className="hover:underline">contact.arthurp.fr</a> ou <a href="mailto:contact@arthurp.fr" className="hover:underline">contact@arthurp.fr</a>.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -15,5 +15,17 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||
changeFrequency: "monthly",
|
||||
priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/mentions-legales`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.4,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/politique-de-confidentialite`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.4,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
+25
-5
@@ -1,11 +1,31 @@
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
calculatrice-dev:
|
||||
profiles: ["dev"]
|
||||
build:
|
||||
context: .
|
||||
target: calculatrice-dev
|
||||
container_name: calculatrice-dev
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./:/app
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
command: npm run dev
|
||||
NEXT_TELEMETRY_DISABLED: "1"
|
||||
NODE_ENV: development
|
||||
|
||||
calculatrice-prod:
|
||||
profiles: ["prod"]
|
||||
build:
|
||||
context: .
|
||||
target: calculatrice-runner
|
||||
container_name: calculatrice-prod
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3014:3000"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NEXT_TELEMETRY_DISABLED: "1"
|
||||
NODE_ENV: production
|
||||
Reference in New Issue
Block a user