65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
/**
|
||
* Секция со списком «ключ — значение». Переиспользуется для всех ролей.
|
||
*/
|
||
|
||
'use client';
|
||
|
||
import React from 'react';
|
||
import { Panel } from './Panel';
|
||
import { SectionHeader } from './SectionHeader';
|
||
import { ListRow } from './ListRow';
|
||
|
||
export interface StatsListRow {
|
||
label: string;
|
||
value: React.ReactNode;
|
||
highlight?: boolean | 'primary' | 'tertiary' | 'error';
|
||
icon?: React.ReactNode;
|
||
}
|
||
|
||
export interface StatsListSectionProps {
|
||
title: string;
|
||
rows: StatsListRow[];
|
||
loading?: boolean;
|
||
}
|
||
|
||
export const StatsListSection: React.FC<StatsListSectionProps> = ({
|
||
title,
|
||
rows,
|
||
loading = false,
|
||
}) => {
|
||
return (
|
||
<Panel padding="md">
|
||
<SectionHeader title={title} />
|
||
{loading ? (
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||
{[1, 2, 3, 4].map((i) => (
|
||
<div
|
||
key={i}
|
||
style={{
|
||
height: 20,
|
||
background: 'var(--md-sys-color-surface-variant)',
|
||
borderRadius: 8,
|
||
width: i === 4 ? '70%' : '100%',
|
||
opacity: 0.5,
|
||
}}
|
||
/>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||
{rows.map((row, i) => (
|
||
<ListRow
|
||
key={i}
|
||
label={row.label}
|
||
value={row.value}
|
||
highlight={row.highlight}
|
||
icon={row.icon}
|
||
last={i === rows.length - 1}
|
||
/>
|
||
))}
|
||
</div>
|
||
)}
|
||
</Panel>
|
||
);
|
||
};
|