Files
civitai__civitai/docs/auth
Manuel Emilio Urena 169e918a8c feat(account): finish the /user/account redesign behind accountSettingsV2 (#4727)
## What

Completes the `/user/account` redesign behind the `accountSettingsV2` flag. The earlier commits on this branch built the two-pane shell and converted three panes; this finishes the other five, then polishes the result against the Pencil canvas (`designs/user-account.pen`).

**OFF serves the legacy single-column page byte-identically.** See "Rollout" below.

## Panes

| Pane | Change |
|---|---|
| Overview | Tier badge art in the Membership tile (links `/user/membership`); Standing replaces the creator-score figure; username renders its nameplate + badge cosmetics; identity card stacks on mobile |
| Profile & Account | `ProfileCard` / `SocialProfileCard` flattened; Account standing shows the exact score; session refresh and delete are pointer rows, grouped |
| Preferences | Regrouped to Media playback / Generation / File preferences / Features; image format moved to File preferences; assistant folded into Features |
| Content & Browsing | Eye callout; mature-content rows; Topics as chips; hidden tags/users flattened |
| Creator | Placement, remix and metric-visibility sections; sticker inventory pointer moved inside Stickers |
| Membership & Billing | Subscription / payment methods / payouts flattened; gifts point at `/pricing/gift`; membership row stacks on mobile; empty states when the user has neither a membership nor a Creator Program payout config |
| Security & Apps | Sign-in methods, API keys, OAuth apps, connected apps flattened; create buttons on the section heading |
| Notifications | Delivery section; per-category icons; more room in an open category; `Other` sorted last |

## Decisions worth a reviewer's attention

- **Cards take a `flat` prop rather than being forked.** The legacy page mounts the same components while the flag is alive; two copies of a settings form is how one of them silently loses a field.
- **One rule per section.** Eight rows had nine dividers and read as a table. Rows are spaced instead.
- **`/user/account/overview` is a new URL.** On mobile the index renders the section *menu*, so an overview reachable only at the index has no way in. `AccountLayout` takes `isIndex` from the route now; inferring it from `section.path` rendered the menu at both URLs. Covered by a test — deleting the alias 404s that URL.
- **Standing thresholds moved to `accountStandingFromPoints`** (`strike.schema.ts`). Two surfaces show standing and it derives from active *points*, not the strike count.
- **The sticker-inventory pointer survives its host section's bail paths.** It is not gated on placement, so nesting it inside that section would drop it whenever the placement controls cannot render (flag off, or a failed spaces read).
- **`BrowsingCategories` switched to chips outright**, including the legacy card, rather than growing a variant prop — one rendering, no fork.
- **First use of a Tailwind `has-[…]` variant in this repo** (`SettingRow`, to keep switch rows inline at every width). Tailwind is 3.4.17, so it is supported.
- **Billing empty states are `flat`-only.** `SubscriptionCard` and `UserPaymentConfigurationCard` both returned `null` with nothing to show, which left the whole pane blank. They now offer the plans / the Creator Program instead — but only in the flat panes, so the legacy page keeps hiding them and stays byte-identical. Both reuse the metric-visibility upsell, extracted as `UpsellPanel`.

## Verification

Typecheck clean; no new lint warnings. Covering suites green: `account-sections` (17), `strike.service` + `process-strikes` (75), the four Account browser suites (24), and the notification suites (79).

`SettingsCard.earlyAdopter.browser` needed one assertion updated — it pinned the literal early-adopter copy. Kept its intent (the opt-in must explain itself) and split it into the promise and the caveat rather than loosening it.

Walked every pane at 1440px and 390px as a subscribed Creator Program account, and the billing/notification changes on a free account with no Creator Program.

## Not in this PR

- `designs/user-account.pen` has uncommitted local changes that predate this work; left alone deliberately.

## Rollout

`accountSettingsV2` → Flipt key `account-settings-v2`.

`availability: ['mod']` is the STATIC FALLBACK only — it decides nothing while Flipt answers, so it matters solely during a Flipt outage, where mods get the new shell and everyone else keeps the legacy page. The Flipt rollout is the on-switch: `account-settings-v2` is `enabled: false` with no rollouts today, so the page is off for everyone until a segment or threshold rollout is merged in `flipt-state`. Instant rollback = drop that rollout / set the threshold to 0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_013NnY26APwddt5dySmmubkZ

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013NnY26APwddt5dySmmubkZ
2026-09-09 16:08:19 -04:00
..
2026-06-26 16:22:36 -06:00