feat(signup+admin): aliniere formular signup la landing + plan cerut, GDPR, control tier/trial in panou

Signup:
- /signup aliniat ca format la formularul din landing (campuri, etichete,
  placeholder-uri, select plan, checkbox GDPR, buton). Eticheta `name` = "Companie"
  (corecta: backendul salveaza nume de firma), uniform si in landing.
- Consimtamant GDPR validat server-side (functional, nu doar client-side) + salvat
  cu marca temporala (accounts.consent_at).
- Plan ales la signup salvat in accounts.requested_plan (intentie, NU drept): tier
  ramane sursa de adevar pentru gate-ul API; coloana pregateste integrarea platilor.
- landing: valorile `plan` = coduri tier (free/standard/pro/premium), data-plan
  sincronizat pe butoanele de pret; checkbox consimtamant primeste name.

Schema/DB:
- accounts: coloane noi requested_plan + consent_at (cu migrare aditiva in db.py).

Panou admin:
- Coloane noi: Plan curent (plan EFECTIV acum + zile trial ramase) si Plan cerut.
- Buton "Aplica" (POST /admin/set-tier): aloca plan real si INCHEIE trial-ul
  (efect imediat; altfel trial-ul Pro universal de 30z masca alegerea).
- Control "Trial Pro N zile" (POST /admin/set-trial via accounts.set_trial):
  acorda/prelungeste trial fara a schimba tier-ul de baza.

Teste: signup (consent obligatoriu, requested_plan persistat, tier ramane free),
panou admin (set-tier incheie trial, free opreste Pro imediat, set-trial, validari
+ CSRF). Call-site-urile existente POST /signup actualizate cu consent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-29 16:02:37 +00:00
parent a29896a790
commit 851f76ca16
14 changed files with 528 additions and 42 deletions

View File

@@ -37,33 +37,53 @@
});
</script>
{% else %}
<h2 style="margin-top:0;">Inregistrare cont nou</h2>
<h2 style="margin-top:0;">Creează cont nou</h2>
{% if error %}
<div class="banner" style="margin-bottom:12px;padding:8px 12px;">{{ error }}</div>
{% endif %}
{# Format aliniat la formularul de inregistrare din landing (#inregistrare): aceleasi campuri,
etichete, placeholder-uri si stil. Valorile `plan` = coduri tier (free/standard/pro/premium),
normalizate server-side. #}
<form method="post" action="/signup">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<p>
<label>Companie <span style="color:var(--err)">*</span></label><br>
<input type="text" name="name" value="{{ name or '' }}" required style="width:100%;">
</p>
<p>
<label>CUI <span style="color:var(--err)">*</span></label><br>
<input type="text" name="cui" value="{{ cui or '' }}" required style="width:100%;">
</p>
<p>
<label>Email <span style="color:var(--err)">*</span></label><br>
<input type="email" name="email" value="{{ email or '' }}" required style="width:100%;">
</p>
<p>
<label>Parola <span style="color:var(--err)">*</span>
<span style="color:var(--muted);font-size:12px;">(minim 10 caractere)</span>
</label><br>
<input type="password" name="parola" required style="width:100%;">
</p>
<button type="submit" style="width:100%;margin-top:8px;">Creeaza cont</button>
<label style="display:block;margin-bottom:14px;">
<span style="display:block;margin-bottom:6px;font:500 13px var(--font-ui);color:var(--muted);">Companie</span>
<input type="text" name="name" value="{{ name or '' }}" required placeholder="SC Service Auto SRL"
style="width:100%;height:44px;padding:0 12px;border:1px solid var(--line);border-radius:6px;background:var(--card2);color:var(--ink);font:400 14px var(--font-ui);outline:none;">
</label>
<label style="display:block;margin-bottom:14px;">
<span style="display:block;margin-bottom:6px;font:500 13px var(--font-ui);color:var(--muted);">CUI</span>
<input type="text" name="cui" value="{{ cui or '' }}" required placeholder="RO12345678"
style="width:100%;height:44px;padding:0 12px;border:1px solid var(--line);border-radius:6px;background:var(--card2);color:var(--ink);font:400 14px var(--font-mono);outline:none;">
</label>
<label style="display:block;margin-bottom:14px;">
<span style="display:block;margin-bottom:6px;font:500 13px var(--font-ui);color:var(--muted);">Email</span>
<input type="email" name="email" value="{{ email or '' }}" required placeholder="nume@service.ro"
style="width:100%;height:44px;padding:0 12px;border:1px solid var(--line);border-radius:6px;background:var(--card2);color:var(--ink);font:400 14px var(--font-ui);outline:none;">
</label>
<label style="display:block;margin-bottom:14px;">
<span style="display:block;margin-bottom:6px;font:500 13px var(--font-ui);color:var(--muted);">Parolă</span>
<input type="password" name="parola" required minlength="10" placeholder="Minim 10 caractere"
style="width:100%;height:44px;padding:0 12px;border:1px solid var(--line);border-radius:6px;background:var(--card2);color:var(--ink);font:400 14px var(--font-ui);outline:none;">
</label>
<label style="display:block;margin-bottom:16px;">
<span style="display:block;margin-bottom:6px;font:500 13px var(--font-ui);color:var(--muted);">Pachet ales</span>
<select name="plan"
style="width:100%;height:44px;padding:0 10px;border:1px solid var(--line);border-radius:6px;background:var(--card2);color:var(--ink);font:400 14px var(--font-ui);outline:none;cursor:pointer;">
<option value="free"{% if not plan or plan == 'free' %} selected{% endif %}>Gratuit — 0 lei/lună</option>
<option value="standard"{% if plan == 'standard' %} selected{% endif %}>Standard — 39 lei/lună</option>
<option value="pro"{% if plan == 'pro' %} selected{% endif %}>Pro — 59 lei/lună</option>
<option value="premium"{% if plan == 'premium' %} selected{% endif %}>Premium — la cerere</option>
</select>
</label>
<label style="display:flex;gap:9px;align-items:flex-start;margin-bottom:18px;font:400 13px/1.5 var(--font-ui);color:var(--muted);cursor:pointer;">
<input type="checkbox" name="consent" value="1" required style="margin-top:2px;accent-color:var(--accent);width:16px;height:16px;flex-shrink:0;">
Sunt de acord cu Termenii și cu prelucrarea datelor conform politicii de confidențialitate (GDPR).
</label>
<button type="submit"
style="width:100%;height:48px;border-radius:6px;background:#1F9D5C;border:1px solid #1F9D5C;color:#fff;font:700 15px var(--font-ui);cursor:pointer;">Creează cont gratuit</button>
</form>
<p style="text-align:center;font-size:13px;margin-top:16px;">
Ai deja cont? <a href="/login">Autentificare</a>