feat(settings): one look for every user and admin settings page

The settings pages had grown into a mix of styles: folds, dialogs behind
rows, full-width rows next to boxed ones, pills for every figure and buttons
in four sizes. Every page now uses the same kit.

- Cards keep their tinted head band; every part of a card is a rounded block
  with its own small head (SettingsBlock), and rows sit in rounded boxes.
- Nothing folds and nothing hides behind a dialog: the MCP config, OAuth
  scopes, mail how-to, AI privacy note and addon sub-options are all shown.
- Each page is split into two columns balanced by length (SettingsColumns).
- Long explanations moved into an info mark next to the label (HintMark).
- One button size everywhere (text-control); tab names are one word.
- Admin: the old Settings tab is split into Security and Services
  (?tab=settings still opens Security, and the phone keeps its single
  Settings section for both); the Integration group is gone, live flights
  and mail import sit next to the addons they configure.
- Addons: one card per type with rows, no search, filter or fold.
- Quota, TREK API facts, mail import status and Google's daily limit are
  compact lines and strips instead of tiles and pills.
- Language is a select; routing has its own card under the defaults;
  storage saves from the foot of its categories card.
- Unused keys, FoldSummary and the page-width wrapper are removed.
This commit is contained in:
Maurice
2026-11-13 23:18:28 +01:00
parent 5fe3dea4cc
commit 94ac7673a5
138 changed files with 1299 additions and 2188 deletions
+8 -6
View File
@@ -9,22 +9,24 @@ interface SectionProps {
* standing in for a glyph gets sized by the same utilities.
*/
icon: LucideIcon | React.ComponentType<{ className?: string }>
/** The icon is a brand badge that fills its tile instead of a glyph in it. */
iconFill?: boolean
badge?: React.ReactNode
/** One line under the title in the head band. */
hint?: React.ReactNode
/** A control on the right of the head band. */
action?: React.ReactNode
/** Where a link lands and, for a collapsible card, what it is remembered by. */
/** Where a link lands: `#id` scrolls to the card, or opens it from an overview. */
id?: string
/** Shut until its head is clicked, the badge saying its state meanwhile (see settingsKit). */
collapsible?: boolean
children: React.ReactNode
}
/** A settings group: the planner's card with a head band (see settingsKit). */
export default function Section({ title, icon, badge, hint, action, id, collapsible, children }: SectionProps): React.ReactElement {
/**
* A settings group: the planner's card with a head band (see settingsKit).
*/
export default function Section({ title, icon, iconFill, badge, hint, action, id, children }: SectionProps): React.ReactElement {
return (
<SettingsCard icon={icon} title={title} badge={badge} hint={hint} action={action} id={id} collapsible={collapsible}>
<SettingsCard icon={icon} iconFill={iconFill} title={title} badge={badge} hint={hint} action={action} id={id}>
{children}
</SettingsCard>
)