Gestisci le scadenze alimentari, riduci gli sprechi. Installabile su qualsiasi dispositivo.
Una Progressive Web App completa per il tracciamento delle scadenze alimentari, con scansione barcode, liste condivise in tempo reale e conformità GDPR. Pensata per famiglie e coinquilini che vogliono sprecare meno cibo.
Entro is an open-source Italian PWA for tracking food expiry dates, reducing waste and sharing a household food list in real time. It is built as a production app and as a public portfolio project.
| Dashboard (dark mode) | Filtri e ricerca (light mode) |
|---|---|
![]() |
![]() |
| Aggiunta alimento | Vista mobile |
|---|---|
![]() |
![]() |
Ho sviluppato entro per risolvere un problema concreto: gestire le scadenze alimentari in modo collaborativo. Volevo esplorare un'architettura full-stack moderna con autenticazione, database relazionale, sync real-time e distribuzione come PWA — tutto partendo da un singolo repository.
Il progetto copre l'intero ciclo di vita di un'applicazione web: dal design del database alla compliance GDPR, dalla CI/CD alla gestione di un dominio personalizzato in produzione.
- CRUD completo — Aggiungi, modifica, elimina alimenti con immagini, categorie, luogo di conservazione e note
- Scansione barcode — Riconosce EAN-13, UPC e QR Code tramite la fotocamera; auto-compila i dati da Open Food Facts
- Liste condivise — Un codice invito a 6 caratteri (es.
ABC123) permette a più utenti di condividere una lista in tempo reale - Sync multi-device — Aggiornamenti istantanei su desktop, iOS e Android tramite Supabase Realtime
- Supporto offline completo — Cache persistente in IndexedDB, CRUD offline con coda mutazioni e sync automatica al ritorno della connessione
- Push notifications — Avvisi giornalieri per alimenti in scadenza, personalizzabili per anticipo, ore silenziose e limite giornaliero
- Vista calendario — Agenda verticale dei prossimi 7 giorni: l'intera settimana a colpo d'occhio, ogni giorno con conteggio e urgenza delle scadenze
- Swipe gestures — Swipe destro per la modifica rapida della quantità (con accesso alla modifica completa), sinistro per eliminare (mobile)
- Feedback aptico — Vibrazione tattile su swipe, creazione, modifica ed eliminazione alimenti (su Android con browser basati su Chromium che implementano la Vibration API; non disponibile su iOS/Safari, e Firefox non la attiva)
- Dark mode — Light, dark e automatico (segue il sistema)
- PWA installabile — Installabile da browser su iOS e Android con esperienza offline nativa
- GDPR compliant — Export dati personali (Art. 20), cancellazione account (Art. 17), Privacy Policy e T&C integrati
- Feature flags — Barcode scanner, swipe gestures e liste condivise attivabili via variabili d'ambiente
| Categoria | Tecnologia |
|---|---|
| Frontend | React 19, TypeScript 5.6 |
| Build Tool | Vite 8 (SWC) |
| Styling | Tailwind CSS 3, shadcn/ui |
| State Management | Zustand (client), TanStack Query (server) |
| Offline | IndexedDB (idb-keyval), PersistQueryClient, mutation queue |
| Backend | Supabase (PostgreSQL, Auth, Storage, Realtime, Edge Functions) |
| Push Notifications | Web Push API (VAPID), @negrel/webpush (Deno) |
| Forms | React Hook Form + Zod |
| Barcode | @zxing/browser + Open Food Facts API |
| Date | date-fns |
| PWA | vite-plugin-pwa (Workbox), custom service worker |
| Deploy | Netlify |
src/
├── components/
│ ├── auth/ # Login, signup, route protection
│ ├── barcode/ # Scanner modale con ZXing
│ ├── calendar/ # (cartella placeholder)
│ ├── foods/ # Card, form, lista, vista calendario (agenda), swipe gestures
│ ├── guide/ # Guida rapida e help in-app
│ ├── layout/ # Header, navigation, app shell
│ ├── settings/ # Account, notifiche, export dati, eliminazione
│ ├── sharing/ # Inviti, codici, accettazione
│ ├── pwa/ # Banner offline, prompt notifiche
│ └── ui/ # Primitivi shadcn/ui
├── hooks/ # Custom hooks (auth, foods, theme, network, push)
├── stores/ # Zustand stores (auth, session)
├── types/ # TypeScript types
├── utils/ # Utility functions
├── pages/ # Route pages
├── lib/ # Config Supabase, persistenza offline, push notifications
├── sw.ts # Service worker custom (cache, push handlers)
└── supabase/functions/ # Edge Functions + helper condivisi (_shared)
- Zustand + TanStack Query — Zustand per lo stato UI globale (auth, sessione), React Query per lo stato server (foods, categorie) con cache e invalidazione automatica
- Offline-first — Cache React Query persistita in IndexedDB via
idb-keyval; mutazioni offline accodate e riprese automaticamente al ritorno della connessione, anche dopo ricaricamento della pagina - Supabase Realtime — LISTEN/NOTIFY di PostgreSQL per sync multi-device, con deduplicazione per evitare flash di aggiornamenti locali
- Push notifications — Web Push API con VAPID; Edge Function cron giornaliera per invio notifiche scadenza;
@negrel/webpush(JSR) per compatibilità Deno - Code splitting — Pagine lazy-loaded, chunk separati per React, Supabase, ZXing e form libraries
- RLS (Row Level Security) — Policy multi-livello per isolare i dati tra utenti e gestire l'accesso alle liste condivise
- Service worker custom — Precaching Workbox per bundle, CacheFirst per font e immagini Supabase (normalizzazione signed URL, 200 entry, 7 giorni), fallback SPA per navigazione offline
Il database PostgreSQL su Supabase include tabelle per utenti, alimenti, categorie, liste, membri e inviti, con 16+ migration incrementali. Le policy RLS garantiscono l'isolamento dei dati. La cancellazione account usa una funzione RPC con cascade delete manuale.
- Node.js 18+
- Account Supabase (gratuito)
git clone https://github.com/E-Lop/entro.git
cd entro
npm install
cp .env.example .env.local- Crea un progetto su supabase.com
- Vai in Settings → API e copia
Project URLeanon/public key - Incollali in
.env.local:
VITE_SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key-here
VITE_APP_URL=http://localhost:5173-
Esegui le migration del database (vedi
supabase/migrations/) -
Avvia il server di sviluppo:
npm run devL'app sarà disponibile su http://localhost:5173
Nel file .env.local puoi attivare o disattivare le funzionalità opzionali:
VITE_ENABLE_BARCODE_SCANNER=true
VITE_ENABLE_SWIPE_GESTURES=true
VITE_ENABLE_SHARED_LISTS=trueL'integrazione con Open Food Facts è gratuita e non richiede API key.
npm run build # TypeScript check + Vite build → dist/
npm run preview # Anteprima locale della buildIl deploy avviene su Netlify con build automatica ad ogni push su main:
- Build command:
npm run build - Publish directory:
dist - Variabili d'ambiente configurate nella dashboard Netlify
| Documento | Contenuto |
|---|---|
| User Guide | Guida utente completa |
| Changelog | Storico delle versioni e modifiche |
| Deploy Guide | Istruzioni di deploy |
| Privacy Policy | Policy privacy e gestione dati |
- Fai un fork del progetto
- Crea un branch (
git checkout -b feature/NuovaFunzionalita) - Committa le modifiche (
git commit -m 'feat: aggiungi nuova funzionalita') - Pusha il branch (
git push origin feature/NuovaFunzionalita) - Apri una Pull Request
Distribuito sotto licenza MIT.
Edmondo Domenico Lopez — @E-Lop
- Open Food Facts — Database prodotti alimentari
- Supabase — Backend as a Service
- shadcn/ui — Componenti UI



