Files
vps-tracker/apps/web/src/components/analytics-page.tsx
T
DenozordecandCursor 0ea92746e4
Docker / build (push) Has been cancelled
refactor(web): унифицировать UI по паттернам ReUI на всех 12 страницах
Ввести CrudListPage, AnalyticsPage, RowActions и domain edit sheets с FormSheetRhf; убрать устаревшие TableCard/DataTableCard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 13:16:00 +07:00

70 lines
1.8 KiB
TypeScript

import type { ReactNode } from 'react'
import { ServerIcon } from 'lucide-react'
import { PageShell } from './page-shell'
import { PageHeader } from './page-header'
import { QueryState } from './query-state'
import { EmptyState } from './empty-state'
import { SectionCardsSkeleton } from './skeletons'
interface AnalyticsPageProps<T> {
title: string
description?: string
actions?: ReactNode
data: T | undefined
isLoading: boolean
isError: boolean
error?: unknown
onRetry?: () => void
/** Показать empty, если нет данных для аналитики (например, 0 VPS). */
analyticsEmpty?: boolean
emptyTitle?: string
emptyDescription?: string
emptyAction?: ReactNode
skeleton?: ReactNode
children: (data: T) => ReactNode
}
export function AnalyticsPage<T>({
title,
description,
actions,
data,
isLoading,
isError,
error,
onRetry,
analyticsEmpty,
emptyTitle = 'Нет данных для аналитики',
emptyDescription = 'Добавьте VPS или дождитесь синхронизации с BILLmanager',
emptyAction,
skeleton,
children,
}: AnalyticsPageProps<T>) {
return (
<PageShell>
<PageHeader title={title} description={description} actions={actions} />
<QueryState
data={data}
isLoading={isLoading}
isError={isError}
error={error}
onRetry={onRetry}
skeleton={skeleton ?? <SectionCardsSkeleton count={3} />}
>
{(snap) =>
analyticsEmpty ? (
<EmptyState
icon={<ServerIcon className="size-8" />}
title={emptyTitle}
description={emptyDescription}
action={emptyAction}
/>
) : (
children(snap)
)
}
</QueryState>
</PageShell>
)
}