Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Blocks

Settings Page

Blocks

Settings Page React block for Tailwind CSS v4

Register PageUsers Admin Page
Live props
State
defaultSection
defaultTwoFactorEnabled
defaultDialog
loading
Content
twoFactorSecret
twoFactorUri
loginAlerts
Layout
nav
saveBarPosition
Behavior
saveShortcut
confirmLeave
resendSeconds
paymentMethodHref
locale
currency
animateIn
failNextSave
Appearance
tone
radius
Code
import { SettingsPage } from "@/components/blocks/settings-page"

<SettingsPage />
  1. Home
  2. Components
  3. Blocks
  4. Settings Page
Pro

Settings Page React block for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React account settings page for a back office: profile, account, notifications, billing, security and a danger zone, with a save bar.

Pick a section in the left column (arrow keys move between them) or, with nav="tabs", in the tabs on top; on phones the sections are an iOS style list that pushes the section in with a back button and swipe back. Profile: upload a photo (crop, progress ring, remove), edit the name, title and a bio with a counter, the phone with its country, the language, a searchable time zone and the date format. Account: the email is read only with Verified; Change opens a dialog (a bottom sheet on phones) that asks for the new address and the current password, sends a 6 digit code (123456 passes, the sixth digit submits, Resend code waits 30 s) and then changes it. The workspace address checks itself when you leave the field (Checking…, then Available or Taken; "acme software" gets "Lowercase letters, digits and hyphens only"). Notifications: a switch per event and channel with a column toggle for all (one group per event on phones); switches save at once and flip back with a toast if the save fails. Quiet hours turn on with a switch and take two times (22:00 to 08:00 reads "next day"); the digest is a segmented choice. Billing: the plan with Change plan (a dialog to pick Start, Pro or Business with the monthly total) and Cancel (a confirmation; the plan then shows its end date and a way to resume it), the usage of users, AI tokens and storage, the card with Update, the company details with a CUI check and the address, and the invoices (cards on phones) with a download link each. Security: Change password opens a dialog with the strength meter and rules; Turn on starts a three step wizard: scan the QR code or copy the key, type the code (123456), then copy or download the ten backup codes; the badge On pops in and Turn off asks first. Revoke any other session or all of them at once; the current one cannot be revoked. Danger zone: Export counts up in a toast and then offers the file; Delete account asks you to type DELETE first. Any text change slides up the save bar with Discard and Save (mod+s); a failed save keeps the draft, shakes the bar and shows why, invalid fields turn red and the first one takes focus. Switching sections with unsaved changes asks first.

Settings Page is a Pro React block in the React blocks category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add settings-page, together with Settings Layout, Avatar Upload, Address Input, QR Code, Input and 31 more and the npm packages motion, lucide-react, react-hook-form and zod.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add settings-page

Settings Page is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import SettingsPage from @/components/blocks/settings-page.

// app/(admin)/settings/page.tsx (the shell lives in app/(admin)/layout.tsx: <AdminShell>{children}</AdminShell>)
"use client"

import { SettingsPage } from "@/components/blocks/settings-page"

export default function SettingsRoute() {
  return (
    <SettingsPage
      onSave={async (section, values) => {
        const res = await fetch(`/api/settings/${section}`, { method: "PUT", body: JSON.stringify(values) })
        if (!res.ok) throw new Error("We could not save. Please try again.")
      }}
      onPreferenceChange={async (preference, value) => {
        await fetch("/api/settings/preferences", { method: "PATCH", body: JSON.stringify({ preference, value }) })
      }}
      onTwoFactorChange={async (enabled) => {
        await fetch("/api/security/2fa", { method: enabled ? "POST" : "DELETE" })
      }}
    />
  )
}

Props

  • section
    "profil" | "cont" | "notificari" | "facturare" | "securitate" | "pericol"

    The open section, controlled; pair it with onSectionChange (a route per section).

  • defaultSectiondefault "profil"
    "profil" | "cont" | "notificari" | "facturare" | "securitate" | "pericol"

    The section open on mount.

  • onSectionChange
    (section: SettingsPageSection) => void

    Called when another section opens (after the unsaved changes question).

  • sectionsdefault "all six"
    SettingsPageSection[]

    Which sections exist, in this order.

  • profile
    SettingsProfile

    Emma Carter's profile: photo, name, title, bio, phone, language, time zone, date format (SETTINGS_PAGE_SAMPLE.profile).

  • account
    SettingsAccount

    The email with its verified flag and the workspace name and address (SETTINGS_PAGE_SAMPLE.account).

  • notifications
    SettingsNotificationPrefs

    Event by channel switches, quiet hours and the digest (SETTINGS_PAGE_SAMPLE.notifications).

  • notificationEvents
    { id: string; label: string; description?: string }[]

    The rows of the notifications grid: Overdue invoice, Payment received, Deal won, Mention, Task assigned, Weekly report.

  • channelsdefault "all three"
    ("email" | "push" | "sms")[]

    The notification columns.

  • billing
    SettingsBilling

    Plan, renewal, seats, AI tokens, storage, the card, the company details and the invoices (SETTINGS_PAGE_SAMPLE.billing).

  • plans
    SettingsPlan[]

    The plans offered by Change plan: Start, Pro, Business with the price per user (SETTINGS_PAGE_SAMPLE.plans).

  • sessions
    SettingsSession[]

    Signed in devices: MacBook Pro (current), iPhone 14, Windows (SETTINGS_PAGE_SAMPLE.sessions).

  • timeZones
    { value: string; label: string; suggested?: boolean; keywords?: string[] }[]

    The time zone picker's options, suggested ones first (SETTINGS_PAGE_SAMPLE.timeZones).

  • takenSlugs
    string[]

    Workspace addresses already in use, for the default availability check.

  • twoFactorEnabled
    boolean

    Two-step verification, controlled; pair it with onTwoFactorChange.

  • defaultTwoFactorEnableddefault false
    boolean

    Two-step verification on at mount (On instead of Turn on).

  • onTwoFactorChange
    (enabled: boolean) => (void | Promise<unknown>)

    Turns two-step verification on (after the code checks out) or off (after the confirmation). Default: a simulated request.

  • twoFactorSecretdefault "JBSWY3DPEHPK3PXP"
    string

    The base32 key shown under the QR code, in groups of four, with a copy button.

  • twoFactorUridefault "otpauth://totp/Acme%20CRM:ana.pop%40acme.com?secret=JBSWY3DPEHPK3PXP&issuer=Acme%20CRM"
    string

    The otpauth:// address the QR code encodes.

  • backupCodes
    string[]

    The ten backup codes of the last step (generated with a fixed seed in the sample).

  • verifyTwoFactorCode
    (code: string) => (boolean | Promise<boolean>)

    Checks the authenticator code. Default: 123456 passes.

  • passwordChangedAt
    Date | number

    When the password last changed ("Last changed on Jun 12, 2026").

  • loginAlertsdefault true
    boolean

    The starting state of Alerte la autentificare.

  • verifyEmailCode
    (email: string, code: string) => (boolean | Promise<boolean>)

    Checks the code sent to the new email. Default: 123456 passes.

  • checkWorkspaceAddress
    (slug: string) => (boolean | Promise<boolean>)

    Whether a workspace address is free; runs when the field loses focus and before a save. Default: takenSlugs after 600 ms.

  • navdefault "sidebar"
    "sidebar" | "tabs"

    The section navigation from 768px: a left column or tabs on top.

  • saveBarPositiondefault "sticky"
    "sticky" | "fixed"

    Where the save bar sits: at the bottom of the content column, or pinned to the window. Phones always pin it.

  • saveShortcutdefault "mod+s"
    string

    Saves the open section while it has changes; "" turns the key off.

  • confirmLeavedefault true
    boolean

    Asks before switching sections with unsaved changes.

  • resendSecondsdefault 30
    number

    How long Retrimite codul waits in the email dialog.

  • defaultDialogdefault "none"
    "none" | "email" | "password" | "two-factor" | "plan" | "cancel-plan" | "delete"

    Opens with this dialog on desktop; the section that owns it has to be the one open (email in cont, password and two-factor in securitate, plan and cancel-plan in facturare, delete in pericol).

  • defaultProfileDraft
    Partial<SettingsProfileDraft>

    Edits applied to the profile form on mount, so it opens with unsaved changes.

  • onSave
    (section: SettingsFormSection, values: SettingsSaveValues[SettingsFormSection]) => (void | Promise<unknown>)

    Saves the open section's text fields from the save bar (profil, cont, notificari, facturare). A rejection keeps the draft and shows its message in the bar. Default: a simulated request.

  • onPreferenceChange
    (preference: string, value: boolean) => (void | Promise<unknown>)

    Switches that save on their own: "notificari.matrix.<event>.<channel>", "notificari.matrix.*.<channel>", "notificari.quietHours", "securitate.loginAlerts". A rejection flips the switch back with a toast.

  • onUpload
    (blob: Blob, context: { file; signal; onProgress }) => Promise<string | void>

    Uploads the cropped photo; resolve the new url. Default: a pretend upload with progress that keeps the local preview.

  • onEmailChange
    (email: string, currentPassword: string) => (void | Promise<unknown>)

    Runs after the code for the new address checks out.

  • onPasswordChange
    (values: { currentPassword: string; newPassword: string }) => (void | Promise<unknown>)

    The password dialog's submit; a rejection shows its message in the dialog.

  • onSessionRevoke
    (session: SettingsSession) => (void | Promise<unknown>)

    Signs a device out (once per device for Sign out all others).

  • onExport
    () => (void | Promise<unknown>)

    Export your data. Default: a toast that counts up, then offers a JSON download.

  • onDeleteAccount
    () => (void | Promise<unknown>)

    Runs after the typed confirmation.

  • onPlanChange
    (planId: string | null) => (void | Promise<unknown>)

    A plan id switches (or resumes); null cancels at the end of the period.

  • onDirtyChange
    (dirty: boolean) => void

    The open section has unsaved changes (hide a phone tab bar while true, one bar per edge).

  • paymentMethodHrefdefault "/settings/billing/card"
    string

    Where Update on the card goes.

  • labelsdefault "DEFAULT_SETTINGS_PAGE_LABELS"
    Partial<SettingsPageLabels>

    Every visible string, merged over the English DEFAULT_SETTINGS_PAGE_LABELS. Nested keys carry the composed items' strings (validation, avatarUpload, cropper, phoneInput, timePicker, select, addressInput, qrCode, table, list, usageMeter).

  • localedefault "en-US"
    string

    Intl locale for numbers, money, dates and relative times.

  • currencydefault "USD"
    string

    The currency of the plan prices and the invoices.

  • now
    Date | number

    The reference time for the sessions and the date format sample; default the live clock.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Accent of the section navigation, the switches, the primary buttons and the save button.

  • radiusdefault "md"
    "sm" | "md" | "lg"

    Corner size of the settings groups (12 / 16 / 24px).

  • loadingdefault false
    boolean

    The open section as skeleton rows in the real layout.

  • animateIndefault true
    boolean

    The page rises in once when it mounts on the client; off in thumbnails and under reduced motion.

  • linkComponentdefault "<a>"
    (props: LinkComponentProps) => ReactNode

    The router link for the card and invoice links; default the surrounding LinkProvider's (the admin shell's).

  • className
    string

    Classes for the root.

  • classNames
    Partial<Record<"layout" | "section" | "saveBar", string>>

    Classes for the settings layout, every settings group and the save bar.

  • failNextSavedefault false
    boolean

    The built-in pretend save (no onSave) fails once, so the error in the bar and the kept draft can be seen and tested.

Parts

  • DEFAULT_SETTINGS_PAGE_LABELS

    constant

    Every English string of the page, including the nested strings of the composed items (validation, avatar upload, cropper, phone input, time picker, table). Spread it and override what you translate.

  • SETTINGS_PAGE_LABELS_EN

    constant

    An alias of DEFAULT_SETTINGS_PAGE_LABELS, kept so imports that name the English set keep working.

  • ProfileSection

    component

    The Profile section on its own: photo, name, title, bio, phone, language, time zone and date format. Takes { ctx: SettingsSectionContext }, the state SettingsPage builds; use it when you compose your own page.

  • AccountSection

    component

    The Account section on its own: the verified email with its change dialog and the workspace address check. Takes { ctx }.

  • NotificationsSection

    component

    The Notifications section on its own: a switch per event and channel, quiet hours and the digest. Takes { ctx }.

  • BillingSection

    component

    The Billing section on its own: the plan with change and cancel dialogs, usage meters, the card, company details and invoices. Takes { ctx }.

  • SecuritySection

    component

    The Security section on its own: password change, the two-factor setup wizard with backup codes, and the session list. Takes { ctx }.

  • DangerSection

    component

    The danger zone on its own: data export with progress and account deletion that asks you to type DELETE. Takes { ctx }.

  • SectionSkeleton

    component

    The loading rows of a section in its real layout, the same ones loading shows. Takes { ctx, section }.

  • SETTINGS_PAGE_SAMPLE

    constant

    The demo data the page renders without props: a profile, account, notification preferences, plans, billing, sessions, time zones and two-factor setup. Replace each piece with your own through the matching prop.

  • SETTINGS_PAGE_SAMPLE_EN

    constant

    An alias of SETTINGS_PAGE_SAMPLE, kept for imports that name the English sample.

  • SETTINGS_PAGE_NOW

    constant

    The fixed clock of the sample (Thursday, Sep 24, 2026, 4:40 PM), so session times and screenshots never drift.

  • SETTINGS_PAGE_SECTIONS

    constant

    The section ids in order: profil, cont, notificari, facturare, securitate, pericol. Use them for section and onSectionChange.

  • SETTINGS_CHANNELS

    constant

    The notification channels of the sample, as columns of the preferences grid: email, push and sms.

  • generateBackupCodes

    function

    Seeded demo backup codes in the XXXX-XXXX format, the same on every render. For screenshots and tests only; generate real codes on your server.

    • countdefault 10
      number

      How many codes.

    • seeddefault 2026
      number

      The random seed; the same seed gives the same codes.

    • returns
      string[]

      The codes.

  • totpUri

    function

    Builds the otpauth:// URI the two-factor QR code encodes, for an account, a base32 secret and an issuer.

    • account*
      string

      The account name shown in the authenticator app, usually the email.

    • secret
      string

      The base32 secret; defaults to the sample's.

    • issuer
      string

      The app name shown in the authenticator; defaults to the sample's.

    • returns
      string

      The otpauth://totp/... URI.

  • SettingsSectionContext

    type

    The state a section receives as ctx: labels, locale, currency, tone, the data and the save handlers.

Examples

Open

Notifications

Events by channel with a toggle per column, quiet hours from 22:00 to 08:00 and the digest.

Open

Billing

The Pro plan with its usage, the card, the company details with the address and the invoices.

Open

Two-step verification setup

defaultDialog="two-factor": step 1 of the wizard with the QR code and the key; 123456 passes step 2.

Open

Unsaved profile

defaultProfileDraft changes the name and the title: the save bar offers Discard and Save (mod+s).

Open

Delete the account

defaultDialog="delete": the button unlocks once you type DELETE.

Open

Loading

loading: the section as skeleton rows under the navigation.

Open

Brand tone, tabs

tone="brand", radius="lg", nav="tabs" on Security with two-step verification on.

Open

British English

locale="en-GB": dates and numbers follow the locale.

Dependencies

motionlucide-reactreact-hook-formzodsettings-layoutavatar-uploadaddress-inputqr-codeinputtextareaphone-inputselectswitchsegmented-controltime-pickerinput-grouppassword-inputotp-inputcopy-buttonbadgebuttontablelistusage-meteralert-dialogdialogalerttoastform-validationuse-cooldownuse-controllable-statecommercedate-utilsfile-exportmotionnavigationnumber-formatrelative-timetonesui-config

Files

  • components/blocks/settings-page.tsx
  • components/blocks/settings-page-sections.tsx
  • components/blocks/settings-page-data.ts

FAQ

Is the React Settings Page block free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Settings Page?

Run npx wingo-ui@latest add settings-page. It also adds the Wingo UI items it builds on (Settings Layout, Avatar Upload, Address Input, QR Code, Input and 31 more) and the npm packages motion, lucide-react, react-hook-form and zod. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/settings-page.

How does Settings Page behave on phones?

Pick a section in the left column (arrow keys move between them) or, with nav="tabs", in the tabs on top; on phones the sections are an iOS style list that pushes the section in with a back button and swipe back.

See also

Settings LayoutAdmin ShellAvatar UploadPassword InputOTP InputUsers Admin Page

More React blocks

Onboarding FlowLogin PageMarketplace Home PageMobile App HomeAdmin Dashboard PageAI Chat Page
All 26 React blocks

Articles using this component

  • Shadcn Profile Page in React: Follow, Tabs and Edit Sheet

    Build it: screens and apps · Nov 6, 2026 · 9 min read

  • React Settings Page: Section Nav, Save Bar, Danger Zone

    Build it: screens and apps · Oct 16, 2026 · 11 min read

  • Codex MCP Setup: Build React UI With Real Components

    Building UI with AI agents · Oct 13, 2026 · 11 min read

  • Nextjs Admin Dashboard Tutorial: 5 Screens, Phone-Ready

    Build it: screens and apps · Oct 9, 2026 · 23 min read

PreviousRegister PageNext Users Admin Page