Settings Page
Tabbed account settings — Profile, Security, and Notifications — all on one page.
Components used​
Layout · Header · Section · Card · Input · Toggle · Select · Button · UserProfile
Code​
- HTML · @primus/ui-core
- React
- Angular
<div style="background:var(--background);width:100%;padding:1.25rem;box-sizing:border-box">
<div style="margin-bottom:1.25rem">
<h1 style="margin:0;font-size:1.25rem;font-weight:700">Settings</h1>
<p style="margin:0;font-size:0.8rem;color:var(--muted-foreground)">Manage your account preferences</p>
</div>
<!-- Tab nav -->
<div style="display:flex;gap:0;border-bottom:2px solid var(--border);margin-bottom:1.5rem">
<button style="padding:0.625rem 1.25rem;font-size:0.875rem;font-weight:600;background:none;border:none;border-bottom:2px solid var(--primary);color:var(--primary);margin-bottom:-2px;cursor:pointer">Profile</button>
<button style="padding:0.625rem 1.25rem;font-size:0.875rem;background:none;border:none;color:var(--muted-foreground);cursor:pointer">Security</button>
<button style="padding:0.625rem 1.25rem;font-size:0.875rem;background:none;border:none;color:var(--muted-foreground);cursor:pointer">Notifications</button>
</div>
<!-- Profile tab content -->
<div style="display:grid;grid-template-columns:1fr 260px;gap:1rem;align-items:start">
<div class="vstack">
<div class="card" style="padding:1.5rem">
<h3 style="margin:0 0 1.25rem;font-size:1rem;font-weight:600;padding-bottom:0.75rem;border-bottom:1px solid var(--border)">Personal Information</h3>
<div class="vstack" style="gap:1rem">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0.75rem">
<div data-field>
<label for="s-fname">First name</label>
<input id="s-fname" type="text" value="Jane" />
</div>
<div data-field>
<label for="s-lname">Last name</label>
<input id="s-lname" type="text" value="Doe" />
</div>
</div>
<div data-field>
<label for="s-email">Email address</label>
<input id="s-email" type="email" value="jane@acme.com" />
</div>
<div data-field>
<label for="s-role">Job title</label>
<input id="s-role" type="text" value="CTO" />
</div>
</div>
<div style="margin-top:1.25rem;display:flex;justify-content:flex-end">
<button class="small">Save changes</button>
</div>
</div>
<div class="card" style="padding:1.5rem">
<h3 style="margin:0 0 1.25rem;font-size:1rem;font-weight:600;padding-bottom:0.75rem;border-bottom:1px solid var(--border)">Preferences</h3>
<div class="vstack" style="gap:0.875rem">
<div data-field style="margin:0">
<label for="s-lang">Language</label>
<select id="s-lang"><option>English</option><option>French</option><option>German</option></select>
</div>
<div data-field style="margin:0">
<label for="s-tz">Timezone</label>
<select id="s-tz"><option>UTC+0 London</option><option>UTC+1 Paris</option><option>UTC-5 New York</option></select>
</div>
<label style="display:flex;align-items:center;justify-content:space-between;font-size:0.875rem">
Dark mode
<input type="checkbox" role="switch" />
</label>
</div>
</div>
</div>
<!-- Profile card -->
<div class="card" style="padding:1.25rem;text-align:center">
<div style="width:64px;height:64px;border-radius:50%;background:color-mix(in srgb,var(--primary) 15%,transparent);display:flex;align-items:center;justify-content:center;margin:0 auto 0.875rem;font-size:1.25rem;font-weight:700;color:var(--primary)">JD</div>
<p style="margin:0 0 0.25rem;font-weight:600">Jane Doe</p>
<p style="margin:0 0 0.75rem;font-size:0.8rem;color:var(--muted-foreground)">jane@acme.com</p>
<span class="badge accent" style="margin-bottom:1rem;display:inline-block">Super Admin</span>
<button class="outline small" style="width:100%;display:block">Change avatar</button>
<button class="ghost small" style="width:100%;display:block;margin-top:0.5rem;color:var(--danger)">Sign out</button>
</div>
</div>
</div>
import {
PrimusLayout, PrimusHeader,
PrimusInput, PrimusSelect, PrimusToggle,
PrimusButton, PrimusSection,
} from 'primus-react-ui';
import { useState } from 'react';
const TABS = ['Profile', 'Security', 'Notifications'];
export function SettingsPage() {
const [tab, setTab] = useState('Profile');
const [form, setForm] = useState({ firstName: 'Jane', lastName: 'Doe', email: 'jane@acme.com' });
const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
return (
<PrimusLayout>
<PrimusHeader title="Settings" subtitle="Manage your account preferences" />
{/* Tab navigation */}
<div className="settings-tabs">
{TABS.map(t => (
<button key={t} className={tab === t ? 'active' : ''}
onClick={() => setTab(t)}>{t}</button>
))}
</div>
{tab === 'Profile' && (
<div style={{ display: 'grid', gridTemplateColumns: '1fr 260px', gap: '1rem', alignItems: 'start' }}>
<div className="vstack">
<div className="card" style={{ padding: '1.5rem' }}>
<PrimusSection title="Personal Information">
<PrimusInput label="First name" value={form.firstName} onChange={v => set('firstName', v)} />
<PrimusInput label="Last name" value={form.lastName} onChange={v => set('lastName', v)} />
<PrimusInput label="Email" type="email" value={form.email} onChange={v => set('email', v)} />
</PrimusSection>
<PrimusButton onClick={saveProfile}>Save changes</PrimusButton>
</div>
</div>
<UserProfileCard user={form} />
</div>
)}
{tab === 'Security' && <SecurityTab />}
{tab === 'Notifications' && <NotificationsTab />}
</PrimusLayout>
);
}
<primus-layout>
<primus-header title="Settings" subtitle="Manage your account preferences"></primus-header>
<!-- Tab nav -->
<div class="settings-tabs">
<button [class.active]="tab === 'profile'" (click)="tab = 'profile'">Profile</button>
<button [class.active]="tab === 'security'" (click)="tab = 'security'">Security</button>
<button [class.active]="tab === 'notifications'" (click)="tab = 'notifications'">Notifications</button>
</div>
<!-- Profile -->
<ng-container *ngIf="tab === 'profile'">
<div style="display:grid;grid-template-columns:1fr 260px;gap:1rem;align-items:start">
<div class="vstack">
<div class="card" style="padding:1.5rem">
<primus-section title="Personal Information">
<primus-input label="First name" [(value)]="form.firstName"></primus-input>
<primus-input label="Last name" [(value)]="form.lastName"></primus-input>
<primus-input label="Email" type="email" [(value)]="form.email"></primus-input>
</primus-section>
<primus-button (clicked)="saveProfile()">Save changes</primus-button>
</div>
</div>
<primus-user-profile [user]="currentUser" [showLogout]="true"></primus-user-profile>
</div>
</ng-container>
</primus-layout>