Compare commits
8
Commits
ba1ba57fa5
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81271544c6 | ||
|
|
f932ecb060 | ||
|
|
2a5954e8e9 | ||
|
|
fd6735ba93 | ||
|
|
fcd91f443f | ||
|
|
551f351ce1 | ||
|
|
249776b536 | ||
|
|
5452fb8680 |
No files matched your search
@@ -54,9 +54,20 @@ pnpm install
|
|||||||
|
|
||||||
### Build et exécution locale
|
### Build et exécution locale
|
||||||
|
|
||||||
|
Avec Docker Compose (recommandé) :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Le port peut être changé via la variable d'environnement `PORT` (par défaut 8080) :
|
||||||
|
`PORT=9090 docker compose up -d`.
|
||||||
|
|
||||||
|
Ou avec les commandes Docker :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t notes .
|
docker build -t notes .
|
||||||
docker run -d --name notes -p 8080:80 notes
|
docker run -d --rm --name notes -p 8080:80 notes
|
||||||
```
|
```
|
||||||
|
|
||||||
L'app sera accessible sur http://localhost:8080.
|
L'app sera accessible sur http://localhost:8080.
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
services:
|
||||||
|
notes:
|
||||||
|
build: .
|
||||||
|
image: notes
|
||||||
|
container_name: notes
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${PORT:-8080}:80"
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Notes
|
||||||
|
|
||||||
|
Application de prise de notes personnelle sous forme de SPA PWA (React + TypeScript + Tailwind CSS).
|
||||||
|
Installable, utilisable hors connexion, et 100 % privée : les données restent dans le **localStorage** du navigateur, sans partage ni transmission à un serveur externe.
|
||||||
|
|
||||||
|
## Fonctionnalités
|
||||||
|
|
||||||
|
- Créer, lire, modifier et supprimer des notes
|
||||||
|
- Données stockées localement (localStorage) — aucune donnée partagée ni transmise
|
||||||
|
- PWA installable avec mode hors connexion
|
||||||
|
- Design responsive mobile-first
|
||||||
|
- Modale RGPD, confirmation avant suppression, page d'erreur 404
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
L'image est servie par nginx et exposée sur le port 80.
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d --rm --name notes -p 8080:80 devcodetools/notes:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Accédez ensuite à l'application sur http://localhost:8080.
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
notes:
|
||||||
|
image: devcodetools/notes:latest
|
||||||
|
container_name: notes
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Construction depuis les sources
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t devcodetools/notes:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Confidentialité
|
||||||
|
|
||||||
|
Vos notes ne quittent jamais votre appareil : stockage uniquement dans le localStorage de votre navigateur, aucune donnée partagée avec des tiers, aucune transmission vers un serveur.
|
||||||
+1
-1
@@ -39,7 +39,7 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto flex w-full max-w-2xl min-h-dvh flex-col pb-[calc(env(safe-area-inset-bottom)+7rem)]">
|
<main className="mx-auto flex w-full max-w-3xl min-h-dvh flex-col pb-[calc(env(safe-area-inset-bottom)+7rem)]">
|
||||||
<header className="sticky top-0 z-10 border-b border-gray-200 bg-white/95 px-4 pb-3 pt-[calc(env(safe-area-inset-top)+0.75rem)] backdrop-blur">
|
<header className="sticky top-0 z-10 border-b border-gray-200 bg-white/95 px-4 pb-3 pt-[calc(env(safe-area-inset-top)+0.75rem)] backdrop-blur">
|
||||||
<div className="flex h-11 items-center gap-1">
|
<div className="flex h-11 items-center gap-1">
|
||||||
{creating || selectedNote ? (
|
{creating || selectedNote ? (
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function ErrorPage({
|
|||||||
message = "Désolé, la page que vous cherchez n'existe pas.",
|
message = "Désolé, la page que vous cherchez n'existe pas.",
|
||||||
}: ErrorPageProps) {
|
}: ErrorPageProps) {
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto flex w-full max-w-2xl min-h-dvh flex-col items-center justify-center gap-6 px-4 text-center">
|
<main className="mx-auto flex w-full max-w-3xl min-h-dvh flex-col items-center justify-center gap-6 px-4 text-center">
|
||||||
<p className="text-6xl font-bold text-blue-700">{code}</p>
|
<p className="text-6xl font-bold text-blue-700">{code}</p>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-semibold">{title}</h1>
|
<h1 className="text-2xl font-semibold">{title}</h1>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe('RgpdInfo', () => {
|
|||||||
render(<RgpdInfo open onClose={vi.fn()} />)
|
render(<RgpdInfo open onClose={vi.fn()} />)
|
||||||
|
|
||||||
expect(screen.getByRole('dialog', { name: 'Protection des données (RGPD)' })).toBeInTheDocument()
|
expect(screen.getByRole('dialog', { name: 'Protection des données (RGPD)' })).toBeInTheDocument()
|
||||||
expect(screen.getByText('localStorage', { exact: false })).toBeInTheDocument()
|
expect(screen.getByText(/stockage local/i)).toBeInTheDocument()
|
||||||
expect(
|
expect(
|
||||||
screen.getByText(/ne sont jamais partagées avec des tiers/i),
|
screen.getByText(/ne sont jamais partagées avec des tiers/i),
|
||||||
).toBeInTheDocument()
|
).toBeInTheDocument()
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@ export default defineConfig({
|
|||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
includeAssets: ['icon.svg', 'apple-touch-icon-180x180.png'],
|
includeAssets: ['icon.svg', 'apple-touch-icon-180x180.png'],
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'new',
|
name: 'Notes',
|
||||||
short_name: 'new',
|
short_name: 'Notes',
|
||||||
description: 'Application web SPA PWA installable et utilisable hors connexion.',
|
description: 'Application web SPA PWA installable et utilisable hors connexion.',
|
||||||
lang: 'fr',
|
lang: 'fr',
|
||||||
start_url: '/',
|
start_url: '/',
|
||||||
|
|||||||
Reference in new issue
Block a user