20-0
Gira la ruota e componi la squadra più forte di sempre
Incasso mensile: 880 USD (fonte indicata nella scheda)
Cosa fa
Gioco web gratuito sul football americano: una ruota assegna a caso una squadra e un'epoca, e tu scegli il miglior giocatore disponibile per ogni ruolo. Alla fine ottieni un punteggio e lo condividi.
Come guadagna
Pubblicità e versioni premium del gioco.
Rendilo tuo
- La versione per il calcio: Serie A, Premier League o la Nazionale, con i campioni di ogni epoca.
- Una sfida giornaliera uguale per tutti, con classifica: fa tornare i giocatori ogni giorno.
Le frasi da scrivere all'AI
1. Base del sito e grafica
Crea un'app web in italiano chiamata "Undici dei Sogni": un gioco web gratuito sul calcio: una ruota assegna a caso una squadra e una stagione, e tu scegli il miglior giocatore disponibile per ogni ruolo. Alla fine ottieni il voto della tua formazione e lo condividi. Usa React, Vite, TypeScript e Tailwind CSS.
Pagine da creare:
1. Pagina iniziale con "Gioca la sfida di oggi" e la classifica
2. Partita: ruota, scelta del giocatore per il ruolo, campo che si riempie
3. Risultato: formazione, voto, confronto con gli altri e condivisione
4. Classifica del giorno e di sempre
5. Pannello amministratori per rose e voti dei giocatori
Stile: da gioco di calcio: campo verde #15803D con le linee bianche, oro #EAB308 per i voti alti, carattere "Oswald" per i nomi, animazione della ruota veloce e scattante. Nessuna immagine generica di stock.
Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.
2. Database, account e sicurezza
Collega il progetto a Supabase e attiva la registrazione con email e password.
Crea queste tabelle:
- "squadre_stagioni": squadra, stagione, giocatori con ruolo e voto (inseriti dagli amministratori da fonti pubbliche)
- "partite": giocatore che ha giocato, data della sfida, formazione scelta, voto totale
Regole di sicurezza obbligatorie:
- rose e voti sono pubblici, li modificano solo gli amministratori
- ogni utente salva le sue partite; la classifica mostra solo il nome scelto
- il voto lo calcola il database, non il browser
Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.
3. La sfida del giorno
Ogni giorno c'è una sfida uguale per tutti: la sequenza delle ruote si genera da un numero legato alla data (codice nei Dettagli tecnici), così tutti hanno le stesse squadre nello stesso ordine e la classifica è giusta.
Per 11 ruoli (portiere, 4 difensori, 3 centrocampisti, 3 attaccanti) la ruota gira e assegna una squadra e una stagione; il giocatore sceglie un calciatore di quella rosa adatto al ruolo. Un "giro extra" a partita per cambiare una ruota sfortunata.
Si gioca anche senza account; per entrare in classifica basta un nome. Nomi e statistiche dei calciatori sono dati pubblici: non usare loghi delle squadre né foto dei giocatori.
4. Voto, condivisione e classifica
Alla fine il database calcola il voto (somma dei voti dei giocatori, con un bonus se i giocatori scelti sono nel ruolo giusto) e mostra la posizione rispetto agli altri giocatori di oggi.
Pulsante "Condividi" che crea un'immagine verticale con il campo e la formazione, e un testo tipo "Ho fatto 87/100 nell'Undici dei Sogni di oggi". Pubblicità discreta solo fuori dalla partita, dopo il consenso ai cookie.
5. Pagamenti con Stripe
Aggiungi un pagamento singolo di 2,99 € una volta sola. Il pagamento toglie la pubblicità e sblocca le partite libere illimitate e lo storico delle sfide passate.
A pagamento riuscito il webhook imposta "piano" a "pro" nella tabella "profili", sulla riga dell'utente indicata in client_reference_id.
Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.
6. Controlli specifici di questo progetto
Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Equità: gioca la sfida di oggi da due dispositivi diversi: le ruote devono uscire uguali e nello stesso ordine.
Correggi quello che non va e scrivimi cosa hai cambiato.
Dettagli tecnici
Stessa sfida per tutti, ogni giorno
Un generatore di numeri casuali che parte dalla data: ogni giorno produce la stessa sequenza su tutti i telefoni, ma diversa dal giorno prima.
// mulberry32: piccolo generatore di numeri "casuali" ripetibili
function generatore(seme: number) {
return () => {
seme = (seme + 0x6d2b79f5) | 0;
let t = Math.imul(seme ^ (seme >>> 15), 1 | seme);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
function semeDelGiorno(data = new Date()): number {
const giorno = data.toISOString().slice(0, 10); // "2026-10-23"
let h = 0;
for (const c of giorno) h = (Math.imul(31, h) + c.charCodeAt(0)) | 0;
return h;
}
// Le 11 ruote di oggi: indici nell'elenco delle squadre-stagioni
export function ruoteDiOggi(quanteSquadre: number): number[] {
const caso = generatore(semeDelGiorno());
return Array.from({ length: 11 }, () => Math.floor(caso() * quanteSquadre));
}Voto calcolato dal database
Il browser invia solo le scelte; il voto lo calcola il database leggendo i voti ufficiali dei giocatori, così nessuno può barare.
create table squadre_stagioni (
id serial primary key,
squadra text not null,
stagione text not null, -- es. '2005-06'
giocatori jsonb not null -- [{ nome, ruolo, voto }]
);
alter table squadre_stagioni enable row level security;
create policy "rose pubbliche" on squadre_stagioni for select using (true);
create table partite (
id uuid primary key default gen_random_uuid(),
utente_id uuid references auth.users(id) on delete set null,
nome text not null check (length(nome) between 2 and 20),
giorno date not null default current_date,
scelte jsonb not null, -- [{ ruolo, squadra_id, giocatore }]
voto int
);
alter table partite enable row level security;
create policy "classifica pubblica" on partite for select using (true);
create function salva_partita(nome_giocatore text, scelte jsonb) returns int
language plpgsql security definer set search_path = public as $
declare totale int := 0; s jsonb; g jsonb;
begin
for s in select * from jsonb_array_elements(scelte) loop
select x into g
from squadre_stagioni ss, jsonb_array_elements(ss.giocatori) x
where ss.id = (s->>'squadra_id')::int and x->>'nome' = s->>'giocatore';
if g is null then raise exception 'Giocatore non valido'; end if;
totale := totale + (g->>'voto')::int + case when g->>'ruolo' = s->>'ruolo' then 1 else 0 end;
end loop;
insert into partite (utente_id, nome, scelte, voto) values (auth.uid(), nome_giocatore, scelte, totale);
return totale;
end $;
Pezzi comuni a tutti i progetti
Glossario
- JSONB
- Un tipo di colonna che contiene dati strutturati flessibili, come un piccolo documento.
- Seme
- Il numero di partenza di un generatore casuale: con lo stesso seme esce sempre la stessa sequenza.