style: update the overview style

This commit is contained in:
Nathnael
2026-06-22 08:05:04 +00:00
parent 9a224e9baf
commit ec708d85b3
5 changed files with 34 additions and 70 deletions

View File

@@ -1,65 +1,36 @@
import { Group, Paper, Text } from "@mantine/core";
import { KpiStrip, type KpiItem } from "@/components/page";
import {
OverviewKpiCard,
type KpiGraphVariant,
type OverviewKpiItem,
} from "./OverviewKpiCard";
import type { OverviewKpiItem } from "./OverviewKpiCard";
/** Rotate mini-graph types per card so each strip reads as a lively mix. */
const VARIANT_CYCLE: KpiGraphVariant[] = ["area", "line", "ring"];
/** Cohesive accent rotation — gold-forward with an orange and neutral break. */
const ACCENT_CYCLE: NonNullable<OverviewKpiItem["accent"]>[] = [
"gold",
"orange",
"default",
];
/**
* Map the overview accent vocabulary onto brand / Mantine palette colors so the
* shared KpiStrip renders a flat tinted icon chip per cell — no gradients,
* gauges or sparklines.
*/
const ACCENT_COLOR: Record<string, string> = {
default: "edr-green",
emerald: "edr-green",
amber: "yellow",
rose: "red",
sky: "blue",
violet: "violet",
gold: "yellow",
orange: "orange",
};
interface OverviewKpiStripProps {
title?: string;
items: OverviewKpiItem[];
}
/** Parse a numeric magnitude out of a KPI value (handles formatted currency strings). */
function toNumber(value: number | string): number {
if (typeof value === "number") return value;
const parsed = Number(String(value).replace(/[^0-9.-]/g, ""));
return Number.isFinite(parsed) ? parsed : 0;
}
/** Clean KPI strip for the overview tabs — delegates to the shared KpiStrip. */
export function OverviewKpiStrip({ items }: OverviewKpiStripProps) {
const kpiItems: KpiItem[] = items.map((item) => ({
label: item.label,
value: item.value,
icon: item.icon,
hint: item.hint,
color: ACCENT_COLOR[item.accent ?? "default"] ?? "edr-green",
}));
export function OverviewKpiStrip({ title, items }: OverviewKpiStripProps) {
const max = Math.max(...items.map((item) => toNumber(item.value)), 0);
return (
<Paper
p="lg"
radius="lg"
withBorder
style={{
background: "#ffffff",
border: "1px solid var(--mantine-color-gray-2)",
}}
>
{title && (
<Text size="sm" fw={600} mb="md" c="dimmed">
{title}
</Text>
)}
<Group gap="md" align="stretch" wrap="wrap">
{items.map((item, index) => (
<OverviewKpiCard
key={item.label}
item={{
...item,
accent: ACCENT_CYCLE[index % ACCENT_CYCLE.length],
variant: item.variant ?? VARIANT_CYCLE[index % VARIANT_CYCLE.length],
progress:
item.progress ?? (max > 0 ? toNumber(item.value) / max : 0),
}}
/>
))}
</Group>
</Paper>
);
return <KpiStrip items={kpiItems} />;
}

View File

@@ -47,11 +47,11 @@ export function OverviewPageHeader({
data={RANGE_OPTIONS}
size="sm"
radius="lg"
color="green"
color="edr-green"
/>
<ActionIcon
variant="light"
color="green"
color="edr-green"
size="lg"
radius="lg"
aria-label="Refresh dashboard"

View File

@@ -78,7 +78,7 @@ export function OverviewTabContent({ tab, range }: OverviewTabContentProps) {
<Stack gap="md" pos="relative">
{isFetching && (
<Center style={{ position: "absolute", top: 8, right: 8, zIndex: 2 }}>
<Loader size="sm" color="green" />
<Loader size="sm" color="edr-green" />
</Center>
)}

View File

@@ -16,7 +16,7 @@
font-weight: 600;
}
.ov-seg-label[data-active] {
color: #15805f;
color: var(--mantine-color-edr-green-7);
}
/* ---- Premium tab bar ---- */
@@ -47,10 +47,8 @@
box-shadow: 0 2px 10px -4px rgba(15, 23, 42, 0.18);
}
.ov-tab[data-active] {
background: linear-gradient(135deg, #2dbf95 0%, #1b9e7a 100%) !important;
background: var(--mantine-color-edr-green-5) !important;
color: #ffffff !important;
box-shadow: 0 10px 20px -8px rgba(27, 158, 122, 0.55);
transform: translateY(-1px);
}
.ov-tab[data-active]:hover {
color: #ffffff;

View File

@@ -132,7 +132,7 @@ const OverviewPage = () => {
value={activeTab}
onChange={(value) => setActiveTab((value as OverviewTabKey) ?? "bookings")}
variant="pills"
color="green"
color="edr-green"
keepMounted={false}
classNames={{ list: "ov-tablist", tab: "ov-tab" }}
>
@@ -151,12 +151,7 @@ const OverviewPage = () => {
size="sm"
radius="sm"
variant={isActive ? "white" : "light"}
color={isActive ? "green" : "gray"}
styles={
isActive
? { root: { background: "rgba(255,255,255,0.9)", color: "#15805f" } }
: undefined
}
color={isActive ? "edr-green" : "gray"}
>
{getTabBadge(tab)}
</Badge>