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:
@@ -10,6 +10,9 @@
|
||||
'delete': ('Sterge', '/admin/delete', 'danger')
|
||||
} %}
|
||||
|
||||
{# Tier-uri selectabile in panou (cod, eticheta). Aliniat cu app/plans.py#PLANS. #}
|
||||
{% set TIERS = [('free', 'Gratuit'), ('standard', 'Standard'), ('pro', 'Pro'), ('premium', 'Premium')] %}
|
||||
|
||||
{% macro lifecycle_block(title, rows, block_id, bulk_verbs, row_verbs) %}
|
||||
<div class="card">
|
||||
<h3 style="margin-top:0;">{{ title }} ({{ rows|length }})</h3>
|
||||
@@ -34,7 +37,7 @@
|
||||
<thead><tr>
|
||||
<th style="width:28px;"><input type="checkbox" class="master-check" data-block="{{ block_id }}"
|
||||
aria-label="Selecteaza tot"></th>
|
||||
<th>ID</th><th>Companie</th><th>CUI</th><th>Email</th><th>Stare</th><th>Inregistrat</th><th>Actiuni</th>
|
||||
<th>ID</th><th>Companie</th><th>CUI</th><th>Email</th><th>Plan curent</th><th>Plan cerut</th><th>Stare</th><th>Inregistrat</th><th>Actiuni</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{% for acct in rows %}
|
||||
@@ -46,6 +49,45 @@
|
||||
<td>{{ acct.name }}</td>
|
||||
<td class="muted">{{ acct.cui or "—" }}</td>
|
||||
<td>{{ acct.email or "—" }}</td>
|
||||
<td style="white-space:nowrap;">
|
||||
{# Plan EFECTIV acum (prominent): trial Pro activ ridica free->pro. #}
|
||||
<div style="margin-bottom:5px;">
|
||||
<span class="pill" style="font-weight:600;">{{ acct.tier_efectiv_label }}</span>
|
||||
{% if acct.trial_activ %}
|
||||
<span class="muted" style="font-size:11px;">
|
||||
trial{% if acct.trial_zile %} · {{ acct.trial_zile }} {{ 'zi' if acct.trial_zile == 1 else 'zile' }} ramase{% endif %}
|
||||
→ apoi {{ acct.tier_label }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{# Schimbare plan inline: select tier de baza + Aplica. Form propriu (nu imbricat in bulk-form).
|
||||
Aplica INCHEIE trial-ul si seteaza planul ales ca real, cu efect imediat. #}
|
||||
<form method="post" action="/admin/set-tier" class="tier-form"
|
||||
style="display:flex;align-items:center;gap:6px;">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<input type="hidden" name="account_id" value="{{ acct.id }}">
|
||||
<select name="tier" aria-label="Plan pentru {{ acct.name }}"
|
||||
style="padding:4px 8px;min-height:32px;max-width:130px;">
|
||||
{% for code, label in TIERS %}
|
||||
<option value="{{ code }}"{% if acct.tier == code %} selected{% endif %}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit" class="btn-sm"
|
||||
title="Aplica planul ales ca plan real (incheie trial-ul daca e activ)">Aplica</button>
|
||||
</form>
|
||||
{# Acorda/prelungeste trial Pro de N zile, fara a schimba tier-ul de baza. #}
|
||||
<form method="post" action="/admin/set-trial" class="trial-form"
|
||||
style="display:flex;align-items:center;gap:6px;margin-top:5px;">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<input type="hidden" name="account_id" value="{{ acct.id }}">
|
||||
<input type="number" name="trial_days" value="30" min="1" max="3650"
|
||||
aria-label="Zile trial Pro pentru {{ acct.name }}"
|
||||
style="padding:4px 8px;min-height:32px;width:64px;">
|
||||
<button type="submit" class="btn-sm"
|
||||
title="Acorda/prelungeste trial Pro de la acum (nu schimba tier-ul de baza)">Trial Pro</button>
|
||||
</form>
|
||||
</td>
|
||||
<td class="muted">{{ acct.requested_plan_label }}</td>
|
||||
<td><span class="pill">{{ acct.status }}</span></td>
|
||||
<td class="muted">{{ acct.created_at or "—" }}</td>
|
||||
<td style="white-space:nowrap;">
|
||||
|
||||
Reference in New Issue
Block a user