refactor: simplify sign-up form #146
Inga granskare
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-web!146
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "refactor/sign-up"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
Makes the sign-up form quicker to get through, and turns the trial from a
side-option into the main choice.
What changed
Country of residence is no longer asked at sign-up. It is only needed for
payment processing, and no account type on the form is a purchase yet, so it
was asking for data we cannot use — the one field that made people stop and
think. It is not hardcoded to
SEeither:requiresCountry()insrc/lib/eligibility.tsis the single place that decides which account typesmust declare a country, and it is deliberately empty today. Adding
paidtherewhen that type lands is the whole change needed to bring the field back, and
the eligibility check runs again automatically for it.
signups.country_codeand.regionare now nullable (migration0005_furry_iron_lad.sql, twoDROP NOT NULLstatements, no data touched).NULL means "we did not ask", which is distinguishable from "they declared
Sweden". The previous hardcode wrote a value nobody had declared into the table
the schema describes as the legal and banking record.
Account type is one control instead of two. The trial used to be an opt-in
checkbox below the form, easy to fill past without noticing. It is now a radio
group — trial or free — so choosing is an explicit step.
The trial kill switch works again.
showTrialwas computed and then neverused, so with
TRIAL_OPEN=falsethe trial option still rendered and was stillpre-selected, while the API fell back to a participant account: a user could
deliberately pick the trial, accept its separate terms, and quietly get a free
account. The option is now
disabledwhen the trial is retired, and the freeoption becomes the pre-selected one. Disabled rather than hidden, so the page
stays honest about what existed — and it is what the
:has(:disabled)stylingalready in
forms.scsswas written for.The step indicator is horizontal. Four stacked lines sat directly above the
form and pushed the first field down; it is now a wrapping trail with counter
numbers and separators, so narrow screens still get everything on as many rows
as they need.
The form uses two columns on wide displays. Username and email share a row;
the account-type fieldset, consent row, anti-spam widget, notices and submit
button stay full width, where line length still matters. Scoped to a
.two-colmodifier rather than
form.stack, because the resend form in the samecomponent is also a
form.stackand should keep its narrow measure. Explicitcolumn spans rather than auto-placement, so the tab order cannot drift from the
visual order.
Less on the page otherwise. The intro paragraph and the standalone trial
hint block are gone; the trial explanation sits with the option it describes.
Accessibility fix. The trial radio's
aria-describedbypointed at an idthat did not exist, so screen-reader users got a description on the free option
and nothing on the trial one.
Still open
was deliberately left unticked because selecting the trial accepts a separate
set of terms, and a pre-ticked consent control is not consent. A radio group
is arguably a product choice rather than a consent tick, but the trial terms
are still a distinct document. Left as-is pending a decision.
signup.country,signup.countryOtherandsignup.countryPlaceholderareunused in both languages, as are
ELIGIBLE_COUNTRIESand the country<select>markup. Kept rather than deleted because the paid path needs them back, and
re-translating is worse than leaving them. Worth a decision either way.
ineligiblestatus is reachable again, but only oncerequiresCountry()returns true for something — so nothing exercises it yet.
guide.
Typecheck, lint, build and 177 tests are clean. The migration is generated but
not applied — the container's
scripts/migrate.mjsruns it on deploy.0b4ea3f3fb3a8b956c0cThe English description broke the pattern its siblings set: they are imperative ("Create repositories…"), this one switched to third person ("Lets you clone…") and split the cost into a two-word fragment. The Swedish already folds cost into the sentence, so the two languages were not parallel either. Leads with "Free of charge", which is the distinguishing feature of this option and the thing a reader scanning a radio list needs first, then matches the sibling strings' imperative voice. Also drops the serial comma, which its own sibling and the Swedish both omit. English only — the Swedish is already the version this now matches.264d4ccbfaf44cfc2b37WIP: simplify the sign-up formtill refactor: simplify sign-up form