polish: fix page title, multi-select styling, chart colors
All checks were successful
Deploy HiHala Dashboard / deploy (push) Successful in 6s

- Page title: "HiHala Data - Museums" -> "HiHala Data"
- Meta description: updated to "Event analytics"
- Multi-select dropdown: fix inherited uppercase, wider to fit labels
- Multi-select arrow: smooth CSS rotation instead of swapping characters
- Chart colors: 10-color palette for events/channels (was 3)
- Remove unused ArcElement (Doughnut) from Chart.js registration (-5KB)
- District chart uses dynamic palette instead of hardcoded 2 colors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
fahed
2026-03-31 15:16:20 +03:00
parent 9332cae350
commit 3912b3dd41
5 changed files with 41 additions and 16 deletions

View File

@@ -5,11 +5,11 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#f8fafc" />
<meta name="description" content="HiHala Data Dashboard — Museum analytics, visitor tracking, and revenue insights" />
<meta name="description" content="HiHala Data Dashboard — Event analytics, visitor tracking, and revenue insights" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap" rel="stylesheet">
<title>HiHala Data Museums</title>
<title>HiHala Data</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@@ -796,16 +796,22 @@ table tbody tr:hover {
}
.multi-select-arrow {
font-size: 0.65rem;
opacity: 0.5;
font-size: 0.6rem;
opacity: 0.4;
margin-inline-start: 8px;
transition: transform 150ms ease;
}
.multi-select-trigger[aria-expanded="true"] .multi-select-arrow {
transform: rotate(180deg);
}
.multi-select-dropdown {
position: absolute;
top: calc(100% + 4px);
left: 0;
right: 0;
min-width: 100%;
width: max-content;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
@@ -816,6 +822,12 @@ table tbody tr:hover {
padding: 4px;
}
.multi-select-dropdown,
.multi-select-dropdown * {
text-transform: none;
letter-spacing: normal;
}
.multi-select-option {
display: flex;
align-items: center;
@@ -825,8 +837,6 @@ table tbody tr:hover {
cursor: pointer;
font-size: 0.875rem;
color: var(--text-primary);
text-transform: none;
letter-spacing: normal;
font-weight: normal;
}

View File

@@ -3,7 +3,7 @@ import { useSearchParams } from 'react-router-dom';
import { Line, Bar } from 'react-chartjs-2';
import { Carousel, EmptyState, FilterControls, MultiSelect, StatCard } from './shared';
import { ExportableChart } from './ChartExport';
import { chartColors, createBaseOptions } from '../config/chartConfig';
import { chartColors, chartPalette, createBaseOptions } from '../config/chartConfig';
import { useLanguage } from '../contexts/LanguageContext';
import {
filterData,
@@ -206,15 +206,16 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
labels: museums,
datasets: [{
data: museums.map(m => grouped[m].visitors),
backgroundColor: [chartColors.primary + 'cc', chartColors.secondary + 'cc', chartColors.tertiary + 'cc'],
borderWidth: 0
backgroundColor: museums.map((_, i) => chartPalette[i % chartPalette.length] + 'cc'),
borderWidth: 0,
borderRadius: 4
}]
},
revenue: {
labels: museums,
datasets: [{
data: museums.map(m => grouped[m].revenue),
backgroundColor: [chartColors.primary + 'cc', chartColors.secondary + 'cc', chartColors.tertiary + 'cc'],
backgroundColor: museums.map((_, i) => chartPalette[i % chartPalette.length] + 'cc'),
borderRadius: 4
}]
}
@@ -229,7 +230,7 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
labels: channels,
datasets: [{
data: channels.map(d => grouped[d].revenue),
backgroundColor: [chartColors.secondary + 'cc', chartColors.tertiary + 'cc'],
backgroundColor: channels.map((_, i) => chartPalette[i % chartPalette.length] + 'cc'),
borderRadius: 4
}]
};
@@ -243,7 +244,7 @@ function Dashboard({ data, showDataLabels, setShowDataLabels, includeVAT, setInc
labels: districtNames,
datasets: [{
data: districtNames.map(d => grouped[d].revenue),
backgroundColor: [chartColors.primary + 'cc', chartColors.secondary + 'cc', chartColors.tertiary + 'cc', chartColors.muted + 'cc'],
backgroundColor: districtNames.map((_, i) => chartPalette[i % chartPalette.length] + 'cc'),
borderRadius: 4
}]
};

View File

@@ -50,7 +50,7 @@ function MultiSelect({ options, selected, onChange, allLabel, placeholder }: Mul
aria-expanded={open}
>
<span className="multi-select-text">{displayText}</span>
<span className="multi-select-arrow">{open ? '▲' : '▼'}</span>
<span className="multi-select-arrow"></span>
</button>
{open && (

View File

@@ -5,7 +5,7 @@ import {
PointElement,
LineElement,
BarElement,
ArcElement,
Title,
Tooltip,
Legend,
@@ -20,7 +20,7 @@ ChartJS.register(
PointElement,
LineElement,
BarElement,
ArcElement,
Title,
Tooltip,
Legend,
@@ -38,6 +38,20 @@ export const chartColors = {
grid: '#f1f5f9'
};
// Extended palette for charts with many categories (events, channels)
export const chartPalette = [
'#2563eb', // blue
'#7c3aed', // purple
'#0891b2', // cyan
'#059669', // emerald
'#d97706', // amber
'#e11d48', // rose
'#4f46e5', // indigo
'#0d9488', // teal
'#c026d3', // fuchsia
'#ea580c', // orange
];
export const createDataLabelConfig = (showDataLabels: boolean): any => ({
display: showDataLabels,
color: '#1e293b',