feat(dashboard): unify desktop header with the planner toolbar style

Brings the dashboard header in line with the Bookings/Lists/Budget/Files
toolbars: a single rounded bg-tertiary bar that groups the title, the
active/archived trip counters, and the view-toggle + widgets + new-trip
actions. Added a border and light shadow so the bar stands out against
the dashboard background in both light and dark mode. Mobile header is
untouched.
This commit is contained in:
Maurice
2026-04-18 01:08:02 +02:00
parent b9395e1e36
commit 21649d3cf0
+67 -52
View File
@@ -897,61 +897,76 @@ export default function DashboardPage(): React.ReactElement {
</button> </button>
</div> </div>
{/* Desktop header */} {/* Desktop header — unified toolbar */}
<div className="hidden md:flex" style={{ alignItems: 'center', justifyContent: 'space-between', marginBottom: 28 }}> <div className="hidden md:block" style={{ marginBottom: 20 }}>
<div> <div style={{
<h1 style={{ margin: 0, fontSize: 24, fontWeight: 800, color: 'var(--text-primary)' }}>{t('dashboard.title')}</h1> background: 'var(--bg-tertiary)', borderRadius: 18,
<p style={{ margin: '3px 0 0', fontSize: 13, color: '#9ca3af' }}> border: '1px solid var(--border-primary)',
boxShadow: '0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04)',
padding: '14px 16px 14px 22px',
display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap',
}}>
<h2 style={{ margin: 0, fontSize: 18, fontWeight: 600, color: 'var(--text-primary)', letterSpacing: '-0.01em', flexShrink: 0 }}>
{t('dashboard.title')}
</h2>
<div style={{ width: 1, height: 22, background: 'var(--border-faint)', flexShrink: 0 }} />
<span style={{ fontSize: 13, color: 'var(--text-muted)' }}>
{isLoading ? t('common.loading') {isLoading ? t('common.loading')
: trips.length > 0 ? `${t(trips.length !== 1 ? 'dashboard.subtitle.activeMany' : 'dashboard.subtitle.activeOne', { count: trips.length })}${archivedTrips.length > 0 ? t('dashboard.subtitle.archivedSuffix', { count: archivedTrips.length }) : ''}` : trips.length > 0 ? `${t(trips.length !== 1 ? 'dashboard.subtitle.activeMany' : 'dashboard.subtitle.activeOne', { count: trips.length })}${archivedTrips.length > 0 ? t('dashboard.subtitle.archivedSuffix', { count: archivedTrips.length }) : ''}`
: t('dashboard.subtitle.empty')} : t('dashboard.subtitle.empty')}
</p> </span>
</div>
<div style={{ display: 'flex', gap: 8, alignItems: 'stretch' }}> <div style={{ display: 'inline-flex', gap: 6, alignItems: 'center', marginLeft: 'auto', flexShrink: 0 }}>
{/* View mode toggle */} <button
<button onClick={toggleViewMode}
onClick={toggleViewMode} title={viewMode === 'grid' ? t('dashboard.listView') : t('dashboard.gridView')}
title={viewMode === 'grid' ? t('dashboard.listView') : t('dashboard.gridView')} style={{
style={{ appearance: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit',
display: 'flex', alignItems: 'center', justifyContent: 'center', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0 14px', height: 37, padding: '7px 11px', borderRadius: 99,
background: 'var(--bg-card)', border: '1px solid var(--border-primary)', borderRadius: 12, background: 'transparent', color: 'var(--text-muted)',
cursor: 'pointer', color: 'var(--text-faint)', fontFamily: 'inherit', transition: 'all 0.15s ease',
transition: 'background 0.15s, border-color 0.15s', }}
}} onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-card)'; e.currentTarget.style.color = 'var(--text-primary)' }}
onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-hover)'; e.currentTarget.style.borderColor = 'var(--text-faint)' }} onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--text-muted)' }}
onMouseLeave={e => { e.currentTarget.style.background = 'var(--bg-card)'; e.currentTarget.style.borderColor = 'var(--border-primary)' }} >
> {viewMode === 'grid' ? <List size={15} /> : <LayoutGrid size={15} />}
{viewMode === 'grid' ? <List size={15} /> : <LayoutGrid size={15} />} </button>
</button> <button
{/* Widget settings */} onClick={() => setShowWidgetSettings(s => s ? false : true)}
<button title={t('dashboard.widgets') || 'Widgets'}
onClick={() => setShowWidgetSettings(s => s ? false : true)} style={{
style={{ appearance: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit',
display: 'flex', alignItems: 'center', justifyContent: 'center', display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
padding: '0 14px', height: 37, padding: '7px 11px', borderRadius: 99,
background: 'var(--bg-card)', border: '1px solid var(--border-primary)', borderRadius: 12, background: showWidgetSettings ? 'var(--bg-card)' : 'transparent',
cursor: 'pointer', color: 'var(--text-faint)', fontFamily: 'inherit', color: showWidgetSettings ? 'var(--text-primary)' : 'var(--text-muted)',
transition: 'background 0.15s, border-color 0.15s', boxShadow: showWidgetSettings ? '0 1px 2px rgba(0,0,0,0.06)' : 'none',
}} transition: 'all 0.15s ease',
onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-hover)'; e.currentTarget.style.borderColor = 'var(--text-faint)' }} }}
onMouseLeave={e => { e.currentTarget.style.background = 'var(--bg-card)'; e.currentTarget.style.borderColor = 'var(--border-primary)' }} onMouseEnter={e => { if (!showWidgetSettings) { e.currentTarget.style.background = 'var(--bg-card)'; e.currentTarget.style.color = 'var(--text-primary)' } }}
> onMouseLeave={e => { if (!showWidgetSettings) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--text-muted)' } }}
<Settings size={15} /> >
</button> <Settings size={15} />
{can('trip_create') && <button </button>
onClick={() => { setEditingTrip(null); setShowForm(true) }} {can('trip_create') && (
style={{ <button
display: 'flex', alignItems: 'center', gap: 7, padding: '9px 18px', onClick={() => { setEditingTrip(null); setShowForm(true) }}
background: 'var(--accent)', color: 'var(--accent-text)', border: 'none', borderRadius: 12, style={{
fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', appearance: 'none', border: 'none', cursor: 'pointer', fontFamily: 'inherit',
boxShadow: '0 2px 8px rgba(0,0,0,0.15)', display: 'inline-flex', alignItems: 'center', gap: 6,
}} padding: '9px 14px', borderRadius: 10, fontSize: 13, fontWeight: 500,
onMouseEnter={e => e.currentTarget.style.opacity = '0.85'} background: 'var(--accent)', color: 'var(--accent-text)', flexShrink: 0,
onMouseLeave={e => e.currentTarget.style.opacity = '1'} marginLeft: 2,
> transition: 'opacity 0.15s ease',
<Plus size={15} /> {t('dashboard.newTrip')} }}
</button>} onMouseEnter={e => e.currentTarget.style.opacity = '0.88'}
onMouseLeave={e => e.currentTarget.style.opacity = '1'}
>
<Plus size={14} strokeWidth={2.5} /> {t('dashboard.newTrip')}
</button>
)}
</div>
</div> </div>
</div> </div>