Şablonlar
Hesap özeti
Kullanıcı hesabı sayfası; profil kartı, bilgiler, sınıra göre kullanım ve son etkinlikler.
Hesap özeti bloğu kullanıcının profilini, çalışma alanı kullanımını ve son etkinlikleri tek sayfada gösterir. Düzenleme işlemleri Ayarlar bloğundadır.
Önizleme
Bölüm başlığı “Önizleme”Sayfa başlığındaki marka ve mod seçimi önizlemeyi de değiştirir.
pnpm add @bigbang/ui| Veri | Tür | Not |
|---|---|---|
| Profil | { name, role, email, team, since, language } |
Ad Avatar baş harflerini de üretir. |
| Kullanım | { value, max, unit }[] |
Meter high eşiği sınırın %80’i; aşınca uyarı tonuna geçer. |
| Etkinlikler | { icon, title, meta }[] |
En yeni önce; zaman göreli yazılır. |
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> );}- AppShell şablonu, breadcrumbs ve
h1“Hesap”. - Tabs: Genel, Güvenlik, Bildirimler.
- Profil kartı: Avatar,
h2ad, rol Tag, “Profili düzenle” ve DescriptionList. - Kullanım kartı: üç Meter.
- Son etkinlikler: ListItem listesi.
Erişilebilirlik
Bölüm başlığı “Erişilebilirlik”- Her kart
h2başlığıyla adlandırılmış birsection’dır. - Kullanım ölçerleri “40 GB / 100 GB” gibi okunur (
aria-valuetext); eşik rengi metinle desteklenir. - Etkinlik ikonları süstür; anlamı başlık taşır.
- Profil bilgileri salt okunur alan yerine tanım listesinde durur (Devre dışı ve salt okunur).