fix(frontend): align dashboard card heading hierarchy
BrokerDashboardCard previously rendered <Heading level={3} size="section">,
which produced an <h3> under the <h1> account name in BrokerAccountLayout,
skipping the <h2> level. Use level={2} so the semantic HTML is a proper
<h2> while keeping the compact "section" visual size.
Also extract the byte-identical toolbar wrapper (grid + chips + date filter
slot) shared by BrokerDashboardEventsCard and BrokerDashboardIncomeCard
into BrokerDashboardTableToolbar to remove duplicated sx config.
This commit is contained in:
parent
0a1ae0552c
commit
21df354df6
@ -40,7 +40,7 @@ export function BrokerDashboardCard({
|
|||||||
mb: 1.5,
|
mb: 1.5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Heading level={3} size="section">
|
<Heading level={2} size="section">
|
||||||
{title}
|
{title}
|
||||||
</Heading>
|
</Heading>
|
||||||
{action}
|
{action}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { eventStatusLabel, eventTypeLabel } from '../lib/dashboardFormatters'
|
|||||||
import { BrokerDashboardCard } from './BrokerDashboardCard'
|
import { BrokerDashboardCard } from './BrokerDashboardCard'
|
||||||
import { BrokerDashboardDateFilter } from './BrokerDashboardDateFilter'
|
import { BrokerDashboardDateFilter } from './BrokerDashboardDateFilter'
|
||||||
import { BrokerDashboardTableSkeleton } from './BrokerDashboardTableSkeleton'
|
import { BrokerDashboardTableSkeleton } from './BrokerDashboardTableSkeleton'
|
||||||
|
import { BrokerDashboardTableToolbar } from './BrokerDashboardTableToolbar'
|
||||||
|
|
||||||
const EVENT_FILTERS: Array<{
|
const EVENT_FILTERS: Array<{
|
||||||
type: DashboardEventType
|
type: DashboardEventType
|
||||||
@ -81,30 +82,17 @@ export function BrokerDashboardEventsCard({
|
|||||||
title="События"
|
title="События"
|
||||||
action={<Link to={`/broker/${encodeURIComponent(accountId)}/events`}>Все события</Link>}
|
action={<Link to={`/broker/${encodeURIComponent(accountId)}/events`}>Все события</Link>}
|
||||||
filters={
|
filters={
|
||||||
<Box
|
<BrokerDashboardTableToolbar
|
||||||
sx={{
|
chips={EVENT_FILTERS.map((filter) => (
|
||||||
display: 'grid',
|
<Chip
|
||||||
gridTemplateColumns: { xs: '1fr', md: 'minmax(0, 1fr) auto' },
|
key={filter.type}
|
||||||
gap: 1.25,
|
label={filter.label}
|
||||||
alignItems: 'center',
|
tone={filter.tone}
|
||||||
border: '1px solid',
|
selected={selectedTypes.includes(filter.type)}
|
||||||
borderColor: 'divider',
|
onClick={() => onToggleType(filter.type)}
|
||||||
bgcolor: 'grey.50',
|
/>
|
||||||
borderRadius: 2,
|
))}
|
||||||
p: 1,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75, minWidth: 0 }}>
|
|
||||||
{EVENT_FILTERS.map((filter) => (
|
|
||||||
<Chip
|
|
||||||
key={filter.type}
|
|
||||||
label={filter.label}
|
|
||||||
tone={filter.tone}
|
|
||||||
selected={selectedTypes.includes(filter.type)}
|
|
||||||
onClick={() => onToggleType(filter.type)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
<BrokerDashboardDateFilter
|
<BrokerDashboardDateFilter
|
||||||
appliedLabel={appliedDateLabel}
|
appliedLabel={appliedDateLabel}
|
||||||
preset={draftPreset}
|
preset={draftPreset}
|
||||||
@ -117,7 +105,7 @@ export function BrokerDashboardEventsCard({
|
|||||||
onReset={onResetFilters}
|
onReset={onResetFilters}
|
||||||
onApply={onApplyFilters}
|
onApply={onApplyFilters}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</BrokerDashboardTableToolbar>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{selectedTypes.length === 0 ? (
|
{selectedTypes.length === 0 ? (
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { getDashboardIncomeRows, sumDashboardIncome } from '../lib/dashboardInco
|
|||||||
import { BrokerDashboardCard } from './BrokerDashboardCard'
|
import { BrokerDashboardCard } from './BrokerDashboardCard'
|
||||||
import { BrokerDashboardDateFilter } from './BrokerDashboardDateFilter'
|
import { BrokerDashboardDateFilter } from './BrokerDashboardDateFilter'
|
||||||
import { BrokerDashboardTableSkeleton } from './BrokerDashboardTableSkeleton'
|
import { BrokerDashboardTableSkeleton } from './BrokerDashboardTableSkeleton'
|
||||||
|
import { BrokerDashboardTableToolbar } from './BrokerDashboardTableToolbar'
|
||||||
|
|
||||||
const INCOME_FILTERS: Array<{
|
const INCOME_FILTERS: Array<{
|
||||||
type: DashboardIncomeType
|
type: DashboardIncomeType
|
||||||
@ -73,30 +74,17 @@ export function BrokerDashboardIncomeCard({
|
|||||||
title="Доходы"
|
title="Доходы"
|
||||||
action={<Link to={`/broker/${encodeURIComponent(accountId)}/operations`}>Все операции</Link>}
|
action={<Link to={`/broker/${encodeURIComponent(accountId)}/operations`}>Все операции</Link>}
|
||||||
filters={
|
filters={
|
||||||
<Box
|
<BrokerDashboardTableToolbar
|
||||||
sx={{
|
chips={INCOME_FILTERS.map((filter) => (
|
||||||
display: 'grid',
|
<Chip
|
||||||
gridTemplateColumns: { xs: '1fr', md: 'minmax(0, 1fr) auto' },
|
key={filter.type}
|
||||||
gap: 1.25,
|
label={filter.label}
|
||||||
alignItems: 'center',
|
tone={filter.tone}
|
||||||
border: '1px solid',
|
selected={selectedTypes.includes(filter.type)}
|
||||||
borderColor: 'divider',
|
onClick={() => onToggleType(filter.type)}
|
||||||
bgcolor: 'grey.50',
|
/>
|
||||||
borderRadius: 2,
|
))}
|
||||||
p: 1,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75, minWidth: 0 }}>
|
|
||||||
{INCOME_FILTERS.map((filter) => (
|
|
||||||
<Chip
|
|
||||||
key={filter.type}
|
|
||||||
label={filter.label}
|
|
||||||
tone={filter.tone}
|
|
||||||
selected={selectedTypes.includes(filter.type)}
|
|
||||||
onClick={() => onToggleType(filter.type)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
<BrokerDashboardDateFilter
|
<BrokerDashboardDateFilter
|
||||||
appliedLabel={appliedDateLabel}
|
appliedLabel={appliedDateLabel}
|
||||||
preset={draftPreset}
|
preset={draftPreset}
|
||||||
@ -109,7 +97,7 @@ export function BrokerDashboardIncomeCard({
|
|||||||
onReset={onResetFilters}
|
onReset={onResetFilters}
|
||||||
onApply={onApplyFilters}
|
onApply={onApplyFilters}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</BrokerDashboardTableToolbar>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{selectedTypes.length === 0 ? (
|
{selectedTypes.length === 0 ? (
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { Box } from '@mui/material'
|
||||||
|
import type { ReactNode } from 'react'
|
||||||
|
|
||||||
|
type BrokerDashboardTableToolbarProps = {
|
||||||
|
chips: ReactNode
|
||||||
|
children: ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export function BrokerDashboardTableToolbar({ chips, children }: BrokerDashboardTableToolbarProps) {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: { xs: '1fr', md: 'minmax(0, 1fr) auto' },
|
||||||
|
gap: 1.25,
|
||||||
|
alignItems: 'center',
|
||||||
|
border: '1px solid',
|
||||||
|
borderColor: 'divider',
|
||||||
|
bgcolor: 'grey.50',
|
||||||
|
borderRadius: 2,
|
||||||
|
p: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.75, minWidth: 0 }}>{chips}</Box>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user