İçeriğe geç
BigBang

Sık açılanlar

    ↑↓Gezin↵AçEscKapat
    EN

    Şablonlar

    Durum sayfaları

    Uygulama düzeni dışındaki tam sayfa durumlar; bulunamadı (404), sunucu hatası (500) ve planlı bakım.

    Durum sayfaları, uygulama düzeni yüklenemediğinde ya da kullanıcı var olmayan bir adrese geldiğinde görünür. Üçü de tek bir ResultState ile kurulur: ne olduğunu, neden olduğunu ve sıradaki adımı söyler. Gezinme yoktur; yalnız ürün adı ve içerik vardır.

    500 sayfasında “Yeniden dene”ye basın: düğme meşgul olur, örnek yine başarısız olur ve sonuç okunur. Sayfa başlığındaki marka ve mod seçimi önizlemeyi de değiştirir.

    Canlı örnek, StorybookStorybook'ta aç
    Canlı örnek, StorybookStorybook'ta aç
    Canlı örnek, StorybookStorybook'ta aç
    Canlı örnek, StorybookStorybook'ta aç
    Terminal window
    pnpm add @bigbang/ui
    Veri Tür Not
    kind 'not-found' | 'server-error' | 'maintenance' Sayfa türü ve ResultState tonu: info, danger, warning.
    onRetry () => Promise<boolean> 500 sayfasında “Yeniden dene”; true dönerse uygulama sayfayı yeniden yükler.
    Başvuru kodu string Sunucunun verdiği iz kodu; destek ekibi bununla arar.

    Sunucu, bu sayfaları doğru HTTP durum koduyla (404, 500, 503) döndürür; içerik yalnız kullanıcıya ne olduğunu anlatır.

    import { Button, Icon, Link, ProgressBar, ResultState, Stack, Text } from '@bigbang/ui';
    import { useState } from 'react';
    import { type Lang, LangProvider } from '../../patterns/lang';
    const copy = {
    tr: {
    product: 'Ürün adı',
    home: 'Ana sayfaya dön',
    back: 'Önceki sayfa',
    code: 'Hata kodu',
    reference: 'Başvuru kodu',
    'not-found': {
    title: 'Sayfa bulunamadı',
    description: 'Adres yanlış yazılmış ya da sayfa taşınmış olabilir. Adresi kontrol edin veya ana sayfadan devam edin.',
    },
    'server-error': {
    title: 'Bir sorun oluştu',
    description: 'İsteğiniz şu an tamamlanamadı. Birkaç saniye sonra yeniden deneyin; sorun sürerse başvuru koduyla destek ekibine yazın.',
    },
    maintenance: {
    title: 'Bakım çalışması sürüyor',
    description: 'Hizmeti iyileştirmek için kısa bir bakım yapıyoruz. Çalışmanız kaydedildi; bakım bitince kaldığınız yerden devam edebilirsiniz.',
    },
    retry: 'Yeniden dene',
    retrying: 'Yeniden deneniyor',
    stillFailing: 'Hâlâ yanıt alınamıyor. Biraz sonra yeniden deneyin.',
    support: 'Destek ekibine yaz',
    progress: 'Bakım ilerlemesi',
    progressNote: 'Tahmini bitiş 14:00',
    statusPage: 'Durum sayfası',
    },
    en: {
    product: 'Product name',
    home: 'Go to the home page',
    back: 'Previous page',
    code: 'Error code',
    reference: 'Reference',
    'not-found': {
    title: 'Page not found',
    description: 'The address may be mistyped or the page may have moved. Check the address or go on from the home page.',
    },
    'server-error': {
    title: 'Something went wrong',
    description: 'Your request could not be completed right now. Try again in a few seconds; if it keeps failing, write to support with the reference.',
    },
    maintenance: {
    title: 'Maintenance in progress',
    description: 'We are doing a short maintenance to improve the service. Your work is saved; you can carry on where you left off once it ends.',
    },
    retry: 'Try again',
    retrying: 'Trying again',
    stillFailing: 'Still no response. Try again a little later.',
    support: 'Write to support',
    progress: 'Maintenance progress',
    progressNote: 'Expected to end at 14:00',
    statusPage: 'Status page',
    },
    };
    export type StatusPageKind = 'not-found' | 'server-error' | 'maintenance';
    export type StatusPagesBlockProps = {
    lang?: Lang;
    /** Which page: 404, 500 or planned maintenance. */
    kind?: StatusPageKind;
    /** Runs on "Try again" of the 500 page; resolve `true` when the request worked. The demo always fails. */
    onRetry?: () => Promise<boolean>;
    };
    const tones = { 'not-found': 'info', 'server-error': 'danger', maintenance: 'warning' } as const;
    const demoRetry = () => new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 1000));
    /**
    * Whole-page states outside the app layout: page not found (404), server error (500) with a retry
    * and a reference, and planned maintenance with progress. Each page has one `h1` from ResultState.
    */
    export function StatusPagesBlock({ lang = 'tr', kind = 'not-found', onRetry = demoRetry }: StatusPagesBlockProps) {
    const t = copy[lang];
    const [retrying, setRetrying] = useState(false);
    const [failedAgain, setFailedAgain] = useState(false);
    const retry = async () => {
    setRetrying(true);
    setFailedAgain(false);
    const ok = await onRetry();
    setRetrying(false);
    setFailedAgain(!ok);
    };
    const actions = {
    'not-found': (
    <>
    <Button render={<a href="#" />} nativeButton={false} startIcon={<Icon name="home" />}>
    {t.home}
    </Button>
    <Button variant="secondary" startIcon={<Icon name="arrow-left" />} onClick={() => window.history.back()}>
    {t.back}
    </Button>
    </>
    ),
    'server-error': (
    <>
    <Button startIcon={<Icon name="refresh" />} loading={retrying} loadingLabel={t.retrying} onClick={() => void retry()}>
    {t.retry}
    </Button>
    <Button render={<a href="#" />} nativeButton={false} variant="secondary">
    {t.home}
    </Button>
    </>
    ),
    maintenance: (
    <Link href="#" external>
    {t.statusPage}
    </Link>
    ),
    }[kind];
    return (
    <LangProvider lang={lang}>
    <div className="flex min-h-[36rem] w-full flex-col bg-surface-default" data-template="status-page">
    <header className="border-b border-line-subtle px-lg py-md">
    <strong className="type-label-md text-fg-default">{t.product}</strong>
    </header>
    <main className="flex flex-1 items-center justify-center px-lg py-4xl">
    <ResultState tone={tones[kind]} title={t[kind].title} description={t[kind].description} actions={actions} className="max-w-[32rem]">
    {kind === 'not-found' ? (
    <Text size="sm" tone="subtle" numeric>{`${t.code}: 404`}</Text>
    ) : kind === 'server-error' ? (
    <Stack gap="sm" align="center">
    <Text size="sm" tone="subtle" numeric>{`${t.code}: 500 · ${t.reference}: REF-0001`}</Text>
    <Text size="sm" tone="danger" role="status">
    {failedAgain ? t.stillFailing : ''}
    </Text>
    <Link href="#" size="sm">
    {t.support}
    </Link>
    </Stack>
    ) : (
    <div className="w-full min-w-[16rem]">
    <ProgressBar label={t.progress} value={60} description={t.progressNote} />
    </div>
    )}
    </ResultState>
    </main>
    </div>
    </LangProvider>
    );
    }
    1. Üstte yalnız ürün adı; gezinme ve arama yoktur.
    2. main içinde ortalanmış ResultState, başlık h1.
    3. 404 (info): “Ana sayfaya dön” birincil, “Önceki sayfa” ikincil; altında “Hata kodu: 404”.
    4. 500 (danger): “Yeniden dene” (loading ile meşgul), “Ana sayfaya dön”; hata ve başvuru kodu, kibar durum satırı ve “Destek ekibine yaz” bağlantısı.
    5. Bakım (warning): ProgressBar ve tahmini bitiş; “Durum sayfası” dış bağlantısı.

    ResultState ikonu motion.success ile büyüyerek gelir; ilerleme çubuğu motion.progress ile dolar. “Yeniden dene” basılınca motion.press ile küçülür ve döner göstergeye geçer. Azaltılmış harekette ölçek kalkar.

    • Her sayfada tek main ve tek h1 vardır. ResultState başlığa tonu görünmez ön ekle ekler: “Hata: Bir sorun oluştu”; anlam yalnız renk ve ikonla verilmez.
    • “Yeniden dene” beklerken adını korur, “Yeniden deneniyor” bir kez okunur; ikinci başarısızlık kibar durum satırında okunur.
    • Hata ve başvuru kodları numeric yazılır; destek için kopyalanabilir.
    • Bakım ilerlemesi progressbar rolündedir, değeri yüzde olarak ve tahmini bitiş açıklama olarak okunur.
    • “Durum sayfası” dış bağlantıdır; ekran okuyucuya yeni sekmede açıldığı söylenir.

    ResultState, Button, Link, ProgressBar, Text. Kalıplar: Hatadan kurtarma, Yükleme durumları.