feat: redesigned dashboard UI with editorial aesthetic and RTL support
Deploy HiHala Dashboard / deploy (push) Successful in 9s

- Replace Dashboard/Comparison with DashboardDemo/PeriodSelectorDemo as primary pages at / and /comparison
- New editorial design: DM Serif Display + Outfit fonts, inline period picker, multi-select filters for museum/channel/district
- Full Arabic RTL support with IBM Plex Sans Arabic; EN/AR toggle synced to global LanguageContext
- Bar/pie chart toggle + absolute/percent toggle for museum, channel, district charts
- Refined top nav: transparent inactive links, accent active state, visual separator between nav links and utilities
- DateRangePicker, MultiSelect, FilterControls shared components added
- NavDemo: sidebar layout alternative (accessible at /nav-demo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
fahed
2026-04-19 17:58:33 +03:00
parent 0f6881309c
commit c8c3465233
13 changed files with 2819 additions and 178 deletions
+13 -8
View File
@@ -1,7 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react';
import { useSearchParams, Link } from 'react-router-dom';
import { Line, Bar, Pie } from 'react-chartjs-2';
import { Carousel, EmptyState, FilterControls, MultiSelect, PeriodPicker, StatCard } from './shared';
import { Carousel, EmptyState, FilterControls, MultiSelect, DateRangePicker, StatCard } from './shared';
import { ExportableChart } from './ChartExport';
import { chartColors, chartPalette, createBaseOptions } from '../config/chartConfig';
import { useLanguage } from '../contexts/LanguageContext';
@@ -515,15 +515,18 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
</div>
</div>
<div className="period-selector-row">
<DateRangePicker
startDate={filters.startDate}
endDate={filters.endDate}
onChange={(start, end) => setFilters({ ...filters, startDate: start, endDate: end })}
availableYears={years.map(Number)}
seasons={seasons}
/>
</div>
<FilterControls title={t('filters.title')} onReset={resetFilters}>
<FilterControls.Row>
<PeriodPicker
startDate={filters.startDate}
endDate={filters.endDate}
onChange={(start, end) => setFilters({ ...filters, startDate: start, endDate: end })}
availableYears={years.map(Number)}
seasons={seasons}
/>
<FilterControls.Group label={t('filters.district')}>
<select value={filters.district} onChange={e => setFilters({...filters, district: e.target.value, museum: []})}>
<option value="all">{t('filters.allDistricts')}</option>
@@ -532,6 +535,7 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
</FilterControls.Group>
<FilterControls.Group label={t('filters.channel')}>
<MultiSelect
label={t('filters.channel')}
options={channels}
selected={filters.channel}
onChange={channel => setFilters({...filters, channel})}
@@ -540,6 +544,7 @@ function Dashboard({ data, seasons, userRole, showDataLabels, setShowDataLabels,
</FilterControls.Group>
<FilterControls.Group label={t('filters.museum')}>
<MultiSelect
label={t('filters.museum')}
options={availableMuseums}
selected={filters.museum}
onChange={museum => setFilters({...filters, museum})}