Toglie la foto tessera dal profilo (DD-044)
Il Profilo non chiede più la foto tessera e la scheda admin non la mostra. Il completamento diventa dati personali 34%, documento 33%, certificato 33%. La migration m29 elimina la colonna profili_giocatore.foto_path; le 4 foto già caricate sono state cancellate dal bucket profili-giocatore. Migration applicata in produzione. Test: pesi e sezioni di profili-core, rendering di CampiProfilo, colonna rimossa sul database locale. Documentati DD-044, modulo profilo-giocatore, DATABASE, ROADMAP e changelog. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e822e4574b
commit
de78431090
21 files changed
+164
-79
No files matched your search
@@ -120,14 +120,12 @@ export function CampiProfilo({
|
||||
sezioni,
|
||||
fileDocumento,
|
||||
fileCertificato,
|
||||
fileFoto,
|
||||
}: {
|
||||
corrente: Profilo;
|
||||
aggiorna: (patch: Partial<Profilo>) => void;
|
||||
sezioni: Record<Sezione, boolean>;
|
||||
fileDocumento?: React.ReactNode;
|
||||
fileCertificato?: React.ReactNode;
|
||||
fileFoto?: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
@@ -241,14 +239,13 @@ export function CampiProfilo({
|
||||
/>
|
||||
</Campo>
|
||||
{fileCertificato}
|
||||
{fileFoto}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* I dati personali dell'allenatore (DD-034): gli stessi campi di `profili_giocatore`, meno
|
||||
* indirizzo, documento, certificato e foto tessera. Condivisi tra Profilo e dashboard admin.
|
||||
* indirizzo, documento e certificato. Condivisi tra Profilo e dashboard admin.
|
||||
*/
|
||||
export function CampiAllenatore({
|
||||
corrente,
|
||||
@@ -469,18 +466,6 @@ export function ProfiloAmministrativo({
|
||||
onCaricato={caricato("certificatoPath")}
|
||||
/>
|
||||
}
|
||||
fileFoto={
|
||||
<>
|
||||
<Intestazione titolo="Foto tessera" completa={sezioni.foto} />
|
||||
<CampoFile
|
||||
label="Foto tessera"
|
||||
path={corrente.fotoPath}
|
||||
sezione="foto"
|
||||
giocatoreId={giocatoreId}
|
||||
onCaricato={caricato("fotoPath")}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<button
|
||||
@@ -550,7 +535,7 @@ export function CompletaProfilo({
|
||||
<p className="mt-2 text-[13px] text-muted-foreground">
|
||||
{allenatore
|
||||
? "Data e luogo di nascita, telefono ed email."
|
||||
: "Documento, certificato medico e foto tessera servono per il tesseramento CSI."}
|
||||
: "Documento e certificato medico servono per il tesseramento CSI."}
|
||||
</p>
|
||||
</Link>
|
||||
</Reveal>
|
||||
|
||||
@@ -375,7 +375,6 @@ export type Database = {
|
||||
documento_scadenza: string | null;
|
||||
documento_tipo: string | null;
|
||||
email: string | null;
|
||||
foto_path: string | null;
|
||||
giocatore_id: string;
|
||||
indirizzo: string | null;
|
||||
luogo_nascita: string | null;
|
||||
@@ -395,7 +394,6 @@ export type Database = {
|
||||
documento_scadenza?: string | null;
|
||||
documento_tipo?: string | null;
|
||||
email?: string | null;
|
||||
foto_path?: string | null;
|
||||
giocatore_id: string;
|
||||
indirizzo?: string | null;
|
||||
luogo_nascita?: string | null;
|
||||
@@ -415,7 +413,6 @@ export type Database = {
|
||||
documento_scadenza?: string | null;
|
||||
documento_tipo?: string | null;
|
||||
email?: string | null;
|
||||
foto_path?: string | null;
|
||||
giocatore_id?: string;
|
||||
indirizzo?: string | null;
|
||||
luogo_nascita?: string | null;
|
||||
|
||||
+4
-10
@@ -21,7 +21,6 @@ export type Profilo = {
|
||||
documentoRetroPath: string | null;
|
||||
certificatoScadenza: string | null;
|
||||
certificatoPath: string | null;
|
||||
fotoPath: string | null;
|
||||
};
|
||||
|
||||
export type RigaProfilo = {
|
||||
@@ -40,11 +39,10 @@ export type RigaProfilo = {
|
||||
documento_retro_path: string | null;
|
||||
certificato_scadenza: string | null;
|
||||
certificato_path: string | null;
|
||||
foto_path: string | null;
|
||||
};
|
||||
|
||||
export const COLONNE_PROFILO =
|
||||
"giocatore_id, data_nascita, luogo_nascita, indirizzo, telefono, email, documento_tipo, documento_numero, documento_rilasciato_da, documento_emissione, documento_scadenza, documento_fronte_path, documento_retro_path, certificato_scadenza, certificato_path, foto_path";
|
||||
"giocatore_id, data_nascita, luogo_nascita, indirizzo, telefono, email, documento_tipo, documento_numero, documento_rilasciato_da, documento_emissione, documento_scadenza, documento_fronte_path, documento_retro_path, certificato_scadenza, certificato_path";
|
||||
|
||||
export function profiloVuoto(giocatoreId: string): Profilo {
|
||||
return {
|
||||
@@ -63,7 +61,6 @@ export function profiloVuoto(giocatoreId: string): Profilo {
|
||||
documentoRetroPath: null,
|
||||
certificatoScadenza: null,
|
||||
certificatoPath: null,
|
||||
fotoPath: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -84,7 +81,6 @@ export function daRigaProfilo(r: RigaProfilo): Profilo {
|
||||
documentoRetroPath: r.documento_retro_path,
|
||||
certificatoScadenza: r.certificato_scadenza,
|
||||
certificatoPath: r.certificato_path,
|
||||
fotoPath: r.foto_path,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -111,12 +107,11 @@ export function aRigaProfilo(p: Profilo): RigaProfilo {
|
||||
documento_retro_path: oNull(p.documentoRetroPath),
|
||||
certificato_scadenza: oNull(p.certificatoScadenza),
|
||||
certificato_path: oNull(p.certificatoPath),
|
||||
foto_path: oNull(p.fotoPath),
|
||||
};
|
||||
}
|
||||
|
||||
/** Pesi delle sezioni del profilo (docs/modules/profilo-giocatore.md). */
|
||||
export const PESI = { dati: 30, documento: 30, certificato: 30, foto: 10 } as const;
|
||||
export const PESI = { dati: 34, documento: 33, certificato: 33 } as const;
|
||||
|
||||
export type Sezione = keyof typeof PESI;
|
||||
|
||||
@@ -131,7 +126,6 @@ export function sezioniComplete(p: Profilo | null | undefined): Record<Sezione,
|
||||
p.documentoRetroPath
|
||||
),
|
||||
certificato: !!(p?.certificatoScadenza && p.certificatoPath),
|
||||
foto: !!p?.fotoPath,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -145,8 +139,8 @@ export function completamento(p: Profilo | null | undefined): number {
|
||||
}
|
||||
|
||||
/**
|
||||
* L'allenatore compila solo i dati personali ridotti (DD-034): niente indirizzo, documento,
|
||||
* certificato né foto tessera, che servono al tesseramento dei giocatori.
|
||||
* L'allenatore compila solo i dati personali ridotti (DD-034): niente indirizzo, documento
|
||||
* né certificato, che servono al tesseramento dei giocatori.
|
||||
*/
|
||||
export const CAMPI_ALLENATORE = ["dataNascita", "luogoNascita", "telefono", "email"] as const;
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ export function useSalvaProfilo() {
|
||||
});
|
||||
}
|
||||
|
||||
export type SezioneFile = "documento-fronte" | "documento-retro" | "certificato" | "foto";
|
||||
export type SezioneFile = "documento-fronte" | "documento-retro" | "certificato";
|
||||
|
||||
const MAX_BYTE = 8 * 1024 * 1024;
|
||||
const TIPI_AMMESSI = ["image/jpeg", "image/png", "image/webp", "application/pdf"];
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
Download,
|
||||
FileText,
|
||||
IdCard,
|
||||
Image,
|
||||
Loader2,
|
||||
Lock,
|
||||
Send,
|
||||
@@ -487,12 +486,6 @@ function SchedaGiocatore({
|
||||
stato={certificato}
|
||||
path={profilo?.certificatoPath ?? null}
|
||||
/>
|
||||
<Documento
|
||||
icona={<Image className="h-3.5 w-3.5" />}
|
||||
label="Foto"
|
||||
stato={sezioni.foto ? "presente" : "assente"}
|
||||
path={profilo?.fotoPath ?? null}
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
"flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold uppercase",
|
||||
|
||||
Reference in new issue
Block a user