theme changes

This commit is contained in:
2026-04-25 13:47:42 +05:30
parent 8a3ebdb1be
commit cc7e6509d2
5 changed files with 106 additions and 46 deletions

View File

@@ -23,15 +23,21 @@ export interface DashboardSection {
}; };
} }
export interface ColorDefinition {
primary: string;
background?: string;
text?: string;
}
export interface ThemeAwarePalette {
light: ColorDefinition;
dark: ColorDefinition;
}
export interface DashboardConfig { export interface DashboardConfig {
sections: DashboardSection[]; sections: DashboardSection[];
style?: { style?: {
palette: Record<DashboardMode, { palette?: Record<DashboardMode, ThemeAwarePalette>;
primary: string;
light: string;
dark: string;
text: string;
}>;
}; };
} }

View File

@@ -7,6 +7,7 @@ import {
ToggleButton, ToggleButton,
ToggleButtonGroup ToggleButtonGroup
} from "@mui/material"; } from "@mui/material";
import { useTheme, alpha } from "@mui/material/styles";
import { DashboardProps, DashboardState } from "./Dashboard.models"; import { DashboardProps, DashboardState } from "./Dashboard.models";
interface ViewProps extends DashboardProps { interface ViewProps extends DashboardProps {
@@ -22,8 +23,31 @@ export default function DashboardView({
setState, setState,
onModeChange onModeChange
}: ViewProps) { }: ViewProps) {
const theme = useTheme();
const themeMode = theme.palette.mode;
const { mode, period, comparison } = state; const { mode, period, comparison } = state;
const colors = config.style?.palette[mode] || { primary: '#000', light: '#fff' };
// Resolve colors with fallbacks
const colors = React.useMemo(() => {
const palette = config.style?.palette?.[mode];
const modeColors = palette ? palette[themeMode] : null;
if (modeColors) {
return {
primary: modeColors.primary,
light: modeColors.background || alpha(modeColors.primary, 0.1),
text: modeColors.text || (themeMode === 'light' ? theme.palette.text.primary : '#fff')
};
}
// Fallback to standard theme colors
const themeColor = mode === 'expense' ? theme.palette.error : theme.palette.success;
return {
primary: themeColor.main,
light: alpha(themeColor.main, themeMode === 'light' ? 0.08 : 0.15),
text: themeColor.main
};
}, [config.style?.palette, mode, themeMode, theme.palette]);
const handleModeChange = (_: any, newMode: any) => { const handleModeChange = (_: any, newMode: any) => {
if (newMode && onModeChange) { if (newMode && onModeChange) {
@@ -39,7 +63,8 @@ export default function DashboardView({
mb: 4, mb: 4,
background: `linear-gradient(180deg, ${colors.light} 0%, transparent 100%)`, background: `linear-gradient(180deg, ${colors.light} 0%, transparent 100%)`,
borderRadius: 4, borderRadius: 4,
p: 2 p: 2,
transition: 'background 0.3s ease'
}} }}
> >
<Box sx={{ display: "flex", justifyContent: "center", mb: 3 }}> <Box sx={{ display: "flex", justifyContent: "center", mb: 3 }}>

View File

@@ -6,6 +6,7 @@ import {
ToggleButton, ToggleButton,
Paper Paper
} from "@mui/material"; } from "@mui/material";
import { useTheme, alpha } from "@mui/material/styles";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft"; import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import ChevronRightIcon from "@mui/icons-material/ChevronRight";
@@ -48,6 +49,9 @@ export default function HistoryChartView(props: ViewProps) {
activeDataKey, activeDataKey,
} = props; } = props;
const theme = useTheme();
const isDark = theme.palette.mode === "dark";
const handleTabChange = (_: React.MouseEvent<HTMLElement>, newTab: string | null) => { const handleTabChange = (_: React.MouseEvent<HTMLElement>, newTab: string | null) => {
if (newTab !== null) setActiveTab(newTab); if (newTab !== null) setActiveTab(newTab);
}; };
@@ -66,16 +70,17 @@ export default function HistoryChartView(props: ViewProps) {
return ( return (
<Paper <Paper
sx={{ sx={{
p: { xs: 2, sm: 4 }, p: { xs: 2.5, sm: 4 },
borderRadius: 4, borderRadius: 4,
width: "100%", width: "100%",
boxShadow: "none", boxShadow: "none",
border: "1px solid", border: "1px solid",
borderColor: "divider", borderColor: "divider",
bgcolor: colorScheme.light, bgcolor: isDark ? "background.paper" : colorScheme.light,
transition: 'background-color 0.3s ease, border-color 0.3s ease'
}} }}
> >
<Typography variant="h6" fontWeight={700} gutterBottom color={colorScheme.text}> <Typography variant="h6" fontWeight={700} gutterBottom sx={{ color: isDark ? 'text.primary' : colorScheme.text }}>
{header} {header}
</Typography> </Typography>
@@ -157,7 +162,7 @@ export default function HistoryChartView(props: ViewProps) {
return ( return (
<Box key={point.id} sx={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "flex-end", height: "100%" }}> <Box key={point.id} sx={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "flex-end", height: "100%" }}>
<Box sx={{ display: "flex", alignItems: "flex-end", gap: comparison ? 0.5 : 0, height: "100%", position: "relative" }}> <Box sx={{ display: "flex", alignItems: "flex-end", gap: comparison ? 1 : 0.5, height: "100%", position: "relative" }}>
<Typography <Typography
variant="caption" variant="caption"
sx={{ sx={{
@@ -167,30 +172,31 @@ export default function HistoryChartView(props: ViewProps) {
transform: "translate(-50%, -6px)", transform: "translate(-50%, -6px)",
fontSize: "0.65rem", fontSize: "0.65rem",
whiteSpace: "nowrap", whiteSpace: "nowrap",
pointerEvents: "none" pointerEvents: "none",
color: 'text.secondary',
fontWeight: 600
}} }}
> >
{formatDisplay(point, activeTab.toLowerCase(), comparison)} {formatDisplay(point, activeTab.toLowerCase(), comparison)}
</Typography> </Typography>
{comparison && ( {comparison && (
<Box sx={{ width: 6, height: `${compareHeight}%`, bgcolor: `${colorScheme.primary}55`, borderRadius: 2 }} /> <Box sx={{ width: 8, height: `${compareHeight}%`, bgcolor: isDark ? alpha(colorScheme.primary, 0.3) : alpha(colorScheme.primary, 0.4), borderRadius: '4px 4px 0 0' }} />
)} )}
<Box sx={{ width: 4 }} />
<Box <Box
sx={{ sx={{
width: 10, width: comparison ? 10 : 16,
height: `${currentHeight}%`, height: `${currentHeight}%`,
bgcolor: point.highlighted ? colorScheme.primary : `${colorScheme.primary}99`, bgcolor: point.highlighted ? colorScheme.primary : isDark ? alpha(colorScheme.primary, 0.8) : alpha(colorScheme.primary, 0.9),
borderRadius: 2 borderRadius: '4px 4px 0 0',
boxShadow: point.highlighted ? `0 0 10px ${alpha(colorScheme.primary, 0.5)}` : 'none'
}} }}
/> />
</Box> </Box>
<Box sx={{ mt: 1, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1.1 }}> <Box sx={{ mt: 1.5, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1.1 }}>
<Typography variant="caption" sx={{ fontSize: "0.7rem", opacity: 0.7 }}> <Typography variant="caption" sx={{ fontSize: "0.7rem", opacity: 0.8, color: 'text.primary', fontWeight: 500 }}>
{formatLabel(point.id, activeDataKey)} {formatLabel(point.id, activeDataKey)}
</Typography> </Typography>
@@ -198,7 +204,7 @@ export default function HistoryChartView(props: ViewProps) {
variant="caption" variant="caption"
sx={{ sx={{
fontSize: "0.65rem", fontSize: "0.65rem",
color: "grey.400", color: "text.disabled",
visibility: comparison && point.compare && activeDataKey !== "daily" ? "visible" : "hidden" visibility: comparison && point.compare && activeDataKey !== "daily" ? "visible" : "hidden"
}} }}
> >

View File

@@ -7,6 +7,7 @@ import {
Divider, Divider,
linearProgressClasses linearProgressClasses
} from "@mui/material"; } from "@mui/material";
import { useTheme, alpha } from "@mui/material/styles";
import { ProgressCardProps } from "./ProgressCard.models"; import { ProgressCardProps } from "./ProgressCard.models";
interface ViewProps extends ProgressCardProps { interface ViewProps extends ProgressCardProps {
@@ -23,6 +24,9 @@ export default function ProgressCardView({
formattedTotal, formattedTotal,
compact = false, compact = false,
}: ViewProps) { }: ViewProps) {
const theme = useTheme();
const isDark = theme.palette.mode === "dark";
return ( return (
<Paper <Paper
elevation={compact ? 2 : 4} elevation={compact ? 2 : 4}
@@ -30,10 +34,13 @@ export default function ProgressCardView({
width: "100%", width: "100%",
p: compact ? { xs: 2.5, md: 3 } : { xs: 3, md: 4 }, p: compact ? { xs: 2.5, md: 3 } : { xs: 3, md: 4 },
borderRadius: compact ? 3 : 4, borderRadius: compact ? 3 : 4,
background: (theme) => background: (theme) => {
colorTheme === "info" const baseColor = theme.palette[colorTheme]?.main || theme.palette.primary.main;
? "linear-gradient(135deg, #0284c7 0%, #06b6d4 100%)" const lightColor = theme.palette[colorTheme]?.light || theme.palette.primary.light;
: `linear-gradient(135deg, ${theme.palette[colorTheme].main} 0%, ${theme.palette[colorTheme].light} 100%)`, return isDark
? `linear-gradient(135deg, ${alpha(baseColor, 0.9)} 0%, ${alpha(baseColor, 0.3)} 100%)`
: `linear-gradient(135deg, ${baseColor} 0%, ${lightColor} 100%)`;
},
color: "#fff", color: "#fff",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
@@ -41,11 +48,12 @@ export default function ProgressCardView({
justifyContent: "center", justifyContent: "center",
position: "relative", position: "relative",
overflow: "hidden", overflow: "hidden",
border: isDark ? "1px solid rgba(255,255,255,0.1)" : "none",
boxShadow: (theme) => boxShadow: (theme) =>
`0 ${compact ? 6 : 12}px ${compact ? 12 : 24}px -10px ${ `0 ${compact ? 6 : 12}px ${compact ? 12 : 24}px -10px ${
theme.palette.mode === "dark" isDark
? "#000" ? "rgba(0,0,0,0.5)"
: theme.palette[colorTheme].main : theme.palette[colorTheme]?.main || theme.palette.primary.main
}`, }`,
}} }}
> >
@@ -53,13 +61,14 @@ export default function ProgressCardView({
variant={compact ? "body2" : "subtitle1"} variant={compact ? "body2" : "subtitle1"}
fontWeight={700} fontWeight={700}
sx={{ sx={{
opacity: 0.9, opacity: 0.95,
mb: compact ? 1.5 : 2, mb: compact ? 1.5 : 2,
width: '100%', width: '100%',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
letterSpacing: 0.5 letterSpacing: 0.5,
textShadow: isDark ? '0 1px 2px rgba(0,0,0,0.3)' : 'none'
}} }}
> >
{header} {header}
@@ -69,7 +78,7 @@ export default function ProgressCardView({
<Typography <Typography
variant={compact ? "h5" : "h3"} variant={compact ? "h5" : "h3"}
fontWeight={900} fontWeight={900}
sx={{ mb: 0.5, lineHeight: 1.2 }} sx={{ mb: 0.5, lineHeight: 1.2, textShadow: isDark ? '0 2px 4px rgba(0,0,0,0.3)' : 'none' }}
> >
{formattedProgress} {formattedProgress}
</Typography> </Typography>
@@ -77,7 +86,7 @@ export default function ProgressCardView({
<Divider <Divider
sx={{ sx={{
my: 1, my: 1,
borderColor: "rgba(255,255,255,0.4)", borderColor: "rgba(255,255,255,0.25)",
width: "100%", width: "100%",
}} }}
/> />
@@ -85,12 +94,13 @@ export default function ProgressCardView({
<Typography <Typography
variant={compact ? "caption" : "body2"} variant={compact ? "caption" : "body2"}
sx={{ sx={{
opacity: 0.8, opacity: 0.85,
fontWeight: 400, fontWeight: 500,
display: "block" display: "block",
color: "rgba(255,255,255,0.9)"
}} }}
> >
{formattedTotal} of {formattedTotal}
</Typography> </Typography>
</Box> </Box>
@@ -102,11 +112,12 @@ export default function ProgressCardView({
height: compact ? 6 : 10, height: compact ? 6 : 10,
borderRadius: 5, borderRadius: 5,
[`&.${linearProgressClasses.colorPrimary}`]: { [`&.${linearProgressClasses.colorPrimary}`]: {
backgroundColor: "rgba(0, 0, 0, 0.2)", backgroundColor: "rgba(0, 0, 0, 0.25)",
}, },
[`& .${linearProgressClasses.bar}`]: { [`& .${linearProgressClasses.bar}`]: {
borderRadius: 5, borderRadius: 5,
backgroundColor: "#fff", backgroundColor: "#fff",
boxShadow: '0 0 8px rgba(255,255,255,0.4)'
}, },
}} }}
/> />

View File

@@ -44,16 +44,28 @@ export const configuration: DashboardConfig = {
style: { style: {
palette: { palette: {
expense: { expense: {
primary: "#d32f2f", light: {
light: "#fdecea", primary: "#d32f2f",
dark: "#9a0007", background: "#fdecea",
text: "#b71c1c" text: "#b71c1c"
},
dark: {
primary: "#f44336",
background: "rgba(244, 67, 54, 0.15)",
text: "#ffcdd2"
}
}, },
income: { income: {
primary: "#2e7d32", light: {
light: "#e8f5e9", primary: "#2e7d32",
dark: "#1b5e20", background: "#e8f5e9",
text: "#1b5e20" text: "#1b5e20"
},
dark: {
primary: "#4caf50",
background: "rgba(76, 175, 80, 0.15)",
text: "#c8e6c9"
}
} }
} }
} }