diff --git a/react-openapi/Admin.tsx b/react-openapi/Admin.tsx index 91ee8fe..5fd9bc6 100644 --- a/react-openapi/Admin.tsx +++ b/react-openapi/Admin.tsx @@ -8,7 +8,6 @@ import { getAppConfig } from "./config"; import { initializeApiClients } from "./api/client"; import { AppConfig } from "./types/config"; import { Box, Typography, Paper, CircularProgress } from "@mui/material"; -import AppTheme from "./shared-theme/AppTheme"; import { Routes, Route, @@ -126,30 +125,26 @@ export default function Admin({ basePath = "/admin" }: { basePath?: string }) { if (!config) { return ( - - - - - + + + ); } return ( - - - - - - - - - + + + + + + + ); } diff --git a/src/AppTheme.tsx b/src/AppTheme.tsx index cdb2f7a..288cd45 100644 --- a/src/AppTheme.tsx +++ b/src/AppTheme.tsx @@ -1,13 +1,48 @@ import * as React from "react"; import { ThemeProvider, createTheme } from "@mui/material/styles"; +import { getDesignTokens } from "./shared-theme/themePrimitives"; +import { inputsCustomizations } from "./shared-theme/customizations/inputs"; +import { dataDisplayCustomizations } from "./shared-theme/customizations/dataDisplay"; +import { feedbackCustomizations } from "./shared-theme/customizations/feedback"; +import { navigationCustomizations } from "./shared-theme/customizations/navigation"; +import { surfacesCustomizations } from "./shared-theme/customizations/surfaces"; -const theme = createTheme({ - palette: { - // mode: "light", // or "dark" - mode: "dark", // or "dark" - }, +export const ColorModeContext = React.createContext({ + toggleColorMode: () => {}, + mode: "light" as "light" | "dark", }); export default function AppTheme({ children }: { children: React.ReactNode }) { - return {children}; + const [mode, setMode] = React.useState<"light" | "dark">("light"); + + const colorMode = React.useMemo( + () => ({ + toggleColorMode: () => { + setMode((prevMode) => (prevMode === "light" ? "dark" : "light")); + }, + mode, + }), + [mode] + ); + + const theme = React.useMemo( + () => + createTheme({ + ...getDesignTokens(mode), + components: { + ...inputsCustomizations, + ...dataDisplayCustomizations, + ...feedbackCustomizations, + ...navigationCustomizations, + ...surfacesCustomizations, + }, + }), + [mode] + ); + + return ( + + {children} + + ); } diff --git a/src/Footer.tsx b/src/Footer.tsx index 85298ef..e8ad23f 100644 --- a/src/Footer.tsx +++ b/src/Footer.tsx @@ -40,7 +40,6 @@ export default function Footer() { flexDirection: 'column', alignItems: 'center', gap: { xs: 2, sm: 4 }, - py: { xs: 2, sm: 4 }, textAlign: { sm: 'center', md: 'left' }, }} > diff --git a/src/Header.tsx b/src/Header.tsx index 51d6824..c7c8875 100644 --- a/src/Header.tsx +++ b/src/Header.tsx @@ -16,8 +16,11 @@ import { } from "@mui/material"; import MenuIcon from "@mui/icons-material/Menu"; import LogoutIcon from "@mui/icons-material/Logout"; +import DarkModeIcon from "@mui/icons-material/DarkMode"; +import LightModeIcon from "@mui/icons-material/LightMode"; import { useNavigate } from "react-router-dom"; import { useAuth } from "../react-auth"; +import { ColorModeContext } from "./AppTheme"; interface HeaderProps { routerMapping: { @@ -39,6 +42,7 @@ export default function Header({ const navigate = useNavigate(); const { currentUser, logout } = useAuth(); + const { mode, toggleColorMode } = React.useContext(ColorModeContext); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); @@ -70,6 +74,11 @@ export default function Header({ )} + {/* THEME TOGGLE */} + + {mode === 'dark' ? : } + + {/* TITLE */} - - Welcome to Khata - + + + + theme.palette.mode === "dark" ? "rgba(255, 255, 255, 0.03)" : "rgba(255, 255, 255, 0.6)", + border: "1px solid", + borderColor: "divider", + borderRadius: 4, + boxShadow: (theme) => + theme.palette.mode === "dark" + ? "0 8px 32px 0 rgba(0, 0, 0, 0.37)" + : "0 8px 32px 0 rgba(31, 38, 135, 0.07)", + }} + > + + Welcome to Khata + + + + Your intelligent, extensible financial ledger. Control accounts, manage transactions, and track your data dynamically with our OpenAPI-driven architecture. + + + + + + + ); }