CRMPanel
Clienti, progetti, attività, magazzino e offerte nello stesso spazio
Cosa fa
Uno spazio di lavoro per piccole aziende che tiene insieme clienti, progetti, compiti, magazzino e offerte commerciali.
Come guadagna
Il progetto è stato messo in vendita su SideProjectors a circa 7.000 $. Come guadagna non è indicato pubblicamente.
Rendilo tuo
- Su misura per un mestiere: fotografi, organizzatori di eventi, falegnami.
- Semplicità prima di tutto: i CRM generici sono troppo complicati per i piccoli.
Le frasi da scrivere all'AI
1. Base del sito e grafica
Crea un'app web in italiano chiamata "Officina Ufficio": uno spazio di lavoro per piccole aziende che vendono prodotti e servizi: clienti, offerte, progetti con compiti e magazzino collegati, così un'offerta accettata impegna il materiale e diventa un progetto. Usa React, Vite, TypeScript e Tailwind CSS.
Pagine da creare:
1. Pagina iniziale con le funzioni e il prezzo
2. Clienti con storico di offerte e progetti
3. Offerte: righe di prodotti e servizi, stato, PDF
4. Progetti con compiti a colonne e scadenze
5. Magazzino: disponibile, impegnato, da ordinare
Stile: professionale e moderno: sfondo grigio chiaro #F8FAFC, indaco #4F46E5, verde #16A34A, ambra #D97706 per il materiale impegnato, carattere "Inter". 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:
- "clienti", "offerte", "righe_offerta"
- "articoli": codice, nome, giacenza, impegnato
- "progetti" e "compiti": collegati all'offerta accettata
Regole di sicurezza obbligatorie:
- ogni azienda vede solo i suoi dati
- non si può impegnare più materiale di quello disponibile: lo controlla il database
- un'offerta accettata non si modifica più
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. Dall'offerta al progetto, con il materiale
L'offerta ha righe di articoli di magazzino e di servizi, con sconti e totali. Quando il cliente accetta, un solo pulsante: la funzione del database impegna gli articoli (disponibile = giacenza − impegnato), crea il progetto con i compiti standard e blocca l'offerta (codice nei Dettagli tecnici).
Se un articolo non basta, l'accettazione si ferma e mostra cosa manca e quanto ordinarne. Tutto avviene in un'unica operazione: o riesce tutto, o non cambia niente.
PDF dell'offerta con logo, inviato via email con il link per accettarla online.
4. Progetti e magazzino
Progetti con compiti a colonne (da fare, in corso, fatto), assegnatari e scadenze; alla chiusura del progetto il materiale impegnato si scarica dalla giacenza.
Magazzino con giacenza, impegnato, disponibile e scorta minima, e un elenco "da ordinare". Statistiche: offerte inviate e accettate, valore dei progetti aperti.
5. Pagamenti con Stripe
Aggiungi un abbonamento a 24 € al mese. Gratis l'utente ha: 2 utenti, 50 articoli e 10 offerte al mese. Con il piano Pro sblocca: utenti, articoli e offerte illimitati, accettazione online e statistiche.
A pagamento riuscito il webhook porta l'utente al piano Pro; se l'abbonamento viene disdetto o non rinnovato lo riporta al piano gratuito.
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. Disponibilità: accetta due offerte che insieme richiedono più materiale di quello disponibile: la seconda deve fermarsi e dire cosa manca.
Correggi quello che non va e scrivimi cosa hai cambiato.
Dettagli tecnici
Accettare un'offerta impegnando il materiale
In un'unica operazione: controlla la disponibilità di ogni articolo bloccandone le righe, impegna il materiale, crea il progetto e chiude l'offerta. Se qualcosa manca, non cambia niente.
create table articoli (
id uuid primary key default gen_random_uuid(),
azienda_id uuid not null,
codice text not null,
nome text not null,
giacenza numeric not null default 0,
impegnato numeric not null default 0,
check (impegnato <= giacenza) -- ultima difesa: mai impegnare più del disponibile
);
create function accetta_offerta(offerta uuid) returns uuid
language plpgsql security definer set search_path = public as $
declare manca text; progetto uuid;
begin
-- Prima blocca gli articoli coinvolti, poi controlla la disponibilità
perform 1 from articoli a join righe_offerta r on r.articolo_id = a.id
where r.offerta_id = offerta for update of a;
select string_agg(a.nome || ': servono ' || r.quantita || ', disponibili ' || (a.giacenza - a.impegnato), '; ')
into manca
from righe_offerta r join articoli a on a.id = r.articolo_id
where r.offerta_id = offerta and r.quantita > a.giacenza - a.impegnato;
if manca is not null then raise exception 'Materiale insufficiente: %', manca; end if;
update articoli a set impegnato = a.impegnato + r.quantita
from righe_offerta r where r.offerta_id = offerta and r.articolo_id = a.id;
update offerte set stato = 'accettata', accettata_il = now()
where id = offerta and stato = 'inviata';
if not found then raise exception 'Offerta non trovata o già chiusa'; end if;
insert into progetti (azienda_id, offerta_id, nome)
select azienda_id, id, 'Progetto ' || numero from offerte where id = offerta
returning id into progetto;
return progetto;
end $;
Pezzi comuni a tutti i progetti
Glossario
- Transazione
- Un gruppo di operazioni sul database che riesce tutto insieme o non succede per niente.
- Materiale impegnato
- Merce ancora in magazzino ma già promessa a un cliente: non si può vendere ad altri.