Dashboard amministratore e profilo per il tesseramento

Implementa la voce "Dashboard amministratore" della roadmap v1.1, come descritta
in docs/modules/profilo-giocatore.md, insieme alla parte di profilo che la
alimenta.

- /admin: stato dei profili della squadra, download di documento, certificato e
  foto tessera, export CSV con i 12 campi del tesseramento CSI. Un certificato
  scaduto non conta come valido.
- Profilo giocatore: dati personali, documento (fronte e retro), certificato e
  foto tessera, con widget di completamento in Home che sparisce al 100%.
- I permessi di amministrazione arrivano da user_roles (DD-011) e non più dalla
  lista di nomi in crapp-data.ts, che resta come ponte finché
  VITE_AUTH_OBBLIGATORIA non viene acceso in produzione.
- Login Google via Supabase Auth: al primo accesso l'account si collega a uno
  slot libero di giocatori_squadra, e il vincolo lo fa rispettare il trigger di
  M1 (DD-016 regola 2).

Migration additive: M2 crea profili_giocatore, M3 il bucket privato
profili-giocatore. Nessuna tabella v1.0 viene toccata, quindi si possono
applicare senza cambiare il comportamento attuale dell'app.

supabase/config.toml e seed.sql configurano lo stack locale: serve perché il
progetto Supabase è uno solo, condiviso tra sviluppo e produzione.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 17:57:59 +02:00
co-authored by Claude Opus 5
parent ea29f053e3
commit da51517ffc
23 changed files with 1635 additions and 63 deletions
+21
View File
@@ -10,6 +10,7 @@
import { Route as rootRouteImport } from './routes/__root'
import { Route as IndexRouteImport } from './routes/index'
import { Route as AdminRouteImport } from './routes/admin'
import { Route as BenvenutoRouteImport } from './routes/benvenuto'
import { Route as CalendarioRouteImport } from './routes/calendario'
import { Route as ClassificaRouteImport } from './routes/classifica'
@@ -31,6 +32,11 @@ const IndexRoute = IndexRouteImport.update({
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
const AdminRoute = AdminRouteImport.update({
id: '/admin',
path: '/admin',
getParentRoute: () => rootRouteImport,
} as any)
const BenvenutoRoute = BenvenutoRouteImport.update({
id: '/benvenuto',
path: '/benvenuto',
@@ -111,6 +117,7 @@ const ApiPublicSollecitaPresenzeRoute =
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/admin': typeof AdminRoute
'/benvenuto': typeof BenvenutoRoute
'/calendario': typeof CalendarioRoute
'/classifica': typeof ClassificaRoute
@@ -129,6 +136,7 @@ export interface FileRoutesByFullPath {
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/admin': typeof AdminRoute
'/benvenuto': typeof BenvenutoRoute
'/calendario': typeof CalendarioRoute
'/classifica': typeof ClassificaRoute
@@ -148,6 +156,7 @@ export interface FileRoutesByTo {
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/admin': typeof AdminRoute
'/benvenuto': typeof BenvenutoRoute
'/calendario': typeof CalendarioRoute
'/classifica': typeof ClassificaRoute
@@ -168,6 +177,7 @@ export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/admin'
| '/benvenuto'
| '/calendario'
| '/classifica'
@@ -186,6 +196,7 @@ export interface FileRouteTypes {
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/admin'
| '/benvenuto'
| '/calendario'
| '/classifica'
@@ -204,6 +215,7 @@ export interface FileRouteTypes {
id:
| '__root__'
| '/'
| '/admin'
| '/benvenuto'
| '/calendario'
| '/classifica'
@@ -223,6 +235,7 @@ export interface FileRouteTypes {
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
AdminRoute: typeof AdminRoute
BenvenutoRoute: typeof BenvenutoRoute
CalendarioRoute: typeof CalendarioRoute
ClassificaRoute: typeof ClassificaRoute
@@ -249,6 +262,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
'/admin': {
id: '/admin'
path: '/admin'
fullPath: '/admin'
preLoaderRoute: typeof AdminRouteImport
parentRoute: typeof rootRouteImport
}
'/benvenuto': {
id: '/benvenuto'
path: '/benvenuto'
@@ -359,6 +379,7 @@ declare module '@tanstack/react-router' {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
AdminRoute: AdminRoute,
BenvenutoRoute: BenvenutoRoute,
CalendarioRoute: CalendarioRoute,
ClassificaRoute: ClassificaRoute,