Templates
Account overview
A user account page; profile card, details, usage against limits and recent activity.
The account overview block shows the user’s profile, workspace usage and recent activity on one page. Editing lives in the Settings block.
Preview
Section titled “Preview”The brand and mode switches in the page header restyle the preview too.
pnpm add @bigbang/ui| Data | Type | Note |
|---|---|---|
| Profile | { name, role, email, team, since, language } |
The name also gives the Avatar initials. |
| Usage | { value, max, unit }[] |
The Meter high threshold is 80% of the limit; above it the tone turns to warning. |
| Activity | { icon, title, meta }[] |
Newest first; times are relative. |
import { Avatar, Button, Card, DescriptionList, Grid, Heading, Icon, ListItem, Meter, Stack, Tab, TabList, TabPanel, Tabs, Tag, Text } from '@bigbang/ui';import type { IconName } from '@bigbang/ui';import type { Lang } from '../../patterns/lang';import { AppShellTemplate } from '../../templates/app-shell/AppShellTemplate';
const copy = { tr: { title: 'Hesap', home: 'Ana sayfa', sections: 'Hesap bölümleri', tabs: { general: 'Genel', security: 'Güvenlik', notifications: 'Bildirimler' }, name: 'Kullanıcı A', role: 'Yönetici', edit: 'Profili düzenle', profile: 'Profil', email: 'E-posta', team: 'Ekip', teamValue: 'Ekip 1', since: 'Üyelik başlangıcı', sinceValue: '1 Ekim 2026', language: 'Dil', languageValue: 'Türkçe', usage: 'Kullanım', storage: 'Depolama', members: 'Üye sayısı', projects: 'Proje', of: (value: number, max: number, unit = '') => `${value}${unit} / ${max}${unit}`, activity: 'Son etkinlikler', events: [ { icon: 'pencil', title: 'Proje A güncellendi', meta: '10 dk önce' }, { icon: 'user', title: 'Ekibe yeni üye katıldı', meta: '2 sa önce' }, { icon: 'file', title: 'Rapor 3 oluşturuldu', meta: 'Dün' }, { icon: 'lock', title: 'Parola değiştirildi', meta: '3 gün önce' }, ], securityText: 'Parola, iki adımlı doğrulama ve oturumlar Ayarlar sayfasındadır.', notificationsText: 'Bildirim tercihleri Ayarlar sayfasındadır.', }, en: { title: 'Account', home: 'Home', sections: 'Account sections', tabs: { general: 'General', security: 'Security', notifications: 'Notifications' }, name: 'User A', role: 'Administrator', edit: 'Edit profile', profile: 'Profile', email: 'Email', team: 'Team', teamValue: 'Team 1', since: 'Member since', sinceValue: '1 October 2026', language: 'Language', languageValue: 'English', usage: 'Usage', storage: 'Storage', members: 'Members', projects: 'Projects', of: (value: number, max: number, unit = '') => `${value}${unit} of ${max}${unit}`, activity: 'Recent activity', events: [ { icon: 'pencil', title: 'Project A was updated', meta: '10 min ago' }, { icon: 'user', title: 'A new member joined the team', meta: '2 h ago' }, { icon: 'file', title: 'Report 3 was created', meta: 'Yesterday' }, { icon: 'lock', title: 'Password was changed', meta: '3 days ago' }, ], securityText: 'Password, two-step verification and sessions are on the Settings page.', notificationsText: 'Notification preferences are on the Settings page.', },};
const usage = [ { key: 'storage', value: 40, max: 100, unit: ' GB' }, { key: 'members', value: 12, max: 20, unit: '' }, { key: 'projects', value: 24, max: 50, unit: '' },] as const;
export type AccountOverviewBlockProps = { lang?: Lang };
/** A user account page: profile card, details, usage against limits and recent activity. */export function AccountOverviewBlock({ lang = 'tr' }: AccountOverviewBlockProps) { const t = copy[lang]; return ( <AppShellTemplate lang={lang} current="account" title={t.title} breadcrumbs={[{ label: t.home, href: '#' }, { label: t.title }]}> <Tabs defaultValue="general"> <TabList label={t.sections}> {(Object.keys(t.tabs) as (keyof typeof t.tabs)[]).map((key) => ( <Tab key={key} value={key}> {t.tabs[key]} </Tab> ))} </TabList> <TabPanel value="general"> <Grid columns={{ base: 1, md: 3 }} gap="lg" className="pt-xl"> <Card variant="outlined" padding="lg" className="md:col-span-2"> <section aria-labelledby={`profile-${lang}`}> <Stack gap="lg"> <div className="flex flex-wrap items-center gap-lg"> <Avatar name={t.name} size="lg" /> <Stack gap="xs" className="min-w-0 flex-1"> <Heading level={2} size="md" id={`profile-${lang}`}> {t.name} </Heading> <div> <Tag tone="brand" size="sm"> {t.role} </Tag> </div> </Stack> <Button variant="secondary" size="sm" startIcon={<Icon name="pencil" />}> {t.edit} </Button> </div> <DescriptionList layout="grid" columns={2} items={[ { term: t.email, details: 'kullanici@ornek.com' }, { term: t.team, details: t.teamValue }, { term: t.since, details: t.sinceValue }, { term: t.language, details: t.languageValue }, ]} /> </Stack> </section> </Card> <Card variant="outlined" padding="lg"> <section aria-labelledby={`usage-${lang}`}> <Stack gap="lg"> <Heading level={2} size="sm" id={`usage-${lang}`}> {t.usage} </Heading> {usage.map((item) => ( <Meter key={item.key} label={t[item.key]} value={item.value} max={item.max} high={item.max * 0.8} valueText={t.of(item.value, item.max, item.unit)} description={t.of(item.value, item.max, item.unit)} showValue={false} size="sm" /> ))} </Stack> </section> </Card> <Card variant="outlined" padding="lg" className="md:col-span-3"> <section aria-labelledby={`activity-${lang}`}> <Stack gap="md"> <Heading level={2} size="sm" id={`activity-${lang}`}> {t.activity} </Heading> <ListItem.List> {t.events.map((event) => ( <ListItem key={event.title} leading={<Icon name={event.icon as IconName} tone="subtle" />} title={event.title} meta={event.meta} /> ))} </ListItem.List> </Stack> </section> </Card> </Grid> </TabPanel> <TabPanel value="security"> <Text tone="subtle" className="pt-xl"> {t.securityText} </Text> </TabPanel> <TabPanel value="notifications"> <Text tone="subtle" className="pt-xl"> {t.notificationsText} </Text> </TabPanel> </Tabs> </AppShellTemplate> );}Structure
Section titled “Structure”- AppShell template, breadcrumbs and the
h1“Account”. - Tabs: General, Security, Notifications.
- Profile card: Avatar, an
h2name, a role Tag, “Edit profile” and a DescriptionList. - Usage card: three Meters.
- Recent activity: a ListItem list.
Accessibility
Section titled “Accessibility”- Each card is a
sectionnamed by itsh2. - Usage meters read like “40 GB of 100 GB” (
aria-valuetext); the threshold colour is backed by text. - Activity icons are decorative; the title carries the meaning.
- Profile details sit in a description list rather than in read-only fields (Disabled and read-only).