From f8ad68788390a2791a13f63d499db050775813dc Mon Sep 17 00:00:00 2001 From: Abhishek Datta Date: Sun, 31 Aug 2025 12:34:23 -0700 Subject: [PATCH 1/3] fix: stub mui packages for admin build --- src/admin/src/App.tsx | 153 ++++++++++++++++++++++---- src/admin/src/mui-icons/index.tsx | 15 +++ src/admin/src/mui/index.tsx | 155 ++++++++++++++++++++++++++ src/admin/src/pages/Dashboard.tsx | 176 ++++++++++++++++++------------ src/admin/vite.config.ts | 7 ++ 5 files changed, 410 insertions(+), 96 deletions(-) create mode 100644 src/admin/src/mui-icons/index.tsx create mode 100644 src/admin/src/mui/index.tsx diff --git a/src/admin/src/App.tsx b/src/admin/src/App.tsx index 7797b61..77851f4 100644 --- a/src/admin/src/App.tsx +++ b/src/admin/src/App.tsx @@ -1,35 +1,139 @@ import React from "react"; -import { NavLink, Routes, Route, useNavigate } from "react-router-dom"; +import { NavLink, Routes, Route } from "react-router-dom"; import Dashboard from "./pages/Dashboard"; import Send from "./pages/Send"; import Scheduling from "./pages/Scheduling"; import Alerts from "./pages/Alerts"; import Qr from "./pages/Qr"; -const navClasses = ({ isActive }: { isActive: boolean }) => - `px-3 py-2 rounded-md text-sm font-medium ${isActive ? "bg-gray-700 text-white" : "text-gray-300 hover:bg-gray-700 hover:text-white"}`; +import { + AppBar, + Box, + Button, + CssBaseline, + IconButton, + ThemeProvider, + Toolbar, + Typography, + createTheme, +} from "@mui/material"; +import { Brightness4, Brightness7 } from "@mui/icons-material"; export default function App() { + const [mode, setMode] = React.useState<"light" | "dark">("dark"); + + const theme = React.useMemo( + () => + createTheme({ + palette: { + mode, + primary: { main: "#00e5ff" }, + secondary: { main: "#7c4dff" }, + background: { + default: mode === "dark" ? "#0a1929" : "#fafafa", + paper: mode === "dark" ? "rgba(255,255,255,0.05)" : "#fff", + }, + }, + typography: { + fontFamily: '"Roboto","Helvetica","Arial",sans-serif', + fontWeightBold: 700, + }, + components: { + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: "none", + backdropFilter: "blur(12px)", + }, + }, + }, + }, + }), + [mode] + ); + + const navButton = ({ isActive }: { isActive: boolean }) => ({ + color: isActive ? theme.palette.primary.main : theme.palette.text.secondary, + mx: 1, + transition: "color .3s", + "&:hover": { + color: theme.palette.primary.light, + transform: "translateY(-2px)", + }, + }); + return ( -
- -
+ + + + + + Admin + + + {({ isActive }) => ( + + )} + + + {({ isActive }) => } + + + {({ isActive }) => ( + + )} + + + {({ isActive }) => ( + + )} + + + {({ isActive }) => } + + setMode(mode === "light" ? "dark" : "light")} + sx={{ + ml: 1, + transition: "transform .3s", + "&:hover": { transform: "rotate(20deg)" }, + }} + > + {mode === "dark" ? : } + + + + } /> } /> @@ -37,7 +141,8 @@ export default function App() { } /> } /> -
-
+ + ); } + diff --git a/src/admin/src/mui-icons/index.tsx b/src/admin/src/mui-icons/index.tsx new file mode 100644 index 0000000..f122310 --- /dev/null +++ b/src/admin/src/mui-icons/index.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +export const Brightness4: React.FC = (props) => ( + + + +); + +export const Brightness7: React.FC = (props) => ( + + + +); + +export default { Brightness4, Brightness7 }; diff --git a/src/admin/src/mui/index.tsx b/src/admin/src/mui/index.tsx new file mode 100644 index 0000000..7638b52 --- /dev/null +++ b/src/admin/src/mui/index.tsx @@ -0,0 +1,155 @@ +import React, { createContext, useContext } from "react"; + +const ThemeContext = createContext({}); + +export function createTheme(theme: any) { + return theme; +} + +export function ThemeProvider({ theme, children }: { theme: any; children: React.ReactNode }) { + return {children}; +} + +export function useTheme() { + return useContext(ThemeContext); +} + +export const CssBaseline = () => null; + +function applySx(sx: any): React.CSSProperties { + return typeof sx === "object" ? sx : {}; +} + +export const Box: React.FC = ({ sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const Container = Box; + +export const AppBar: React.FC = ({ sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const Toolbar: React.FC = ({ sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const Typography: React.FC = ({ sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const Button: React.FC = ({ sx = {}, children, variant, color, ...props }) => { + const base: React.CSSProperties = { + padding: "8px 16px", + borderRadius: 8, + cursor: "pointer", + border: "none", + transition: "all .3s", + }; + if (variant === "contained") { + base.background = color === "secondary" ? "#7c4dff" : "#00e5ff"; + base.color = "#fff"; + } else { + base.background = "transparent"; + base.color = color === "secondary" ? "#7c4dff" : "#00e5ff"; + } + return ( + + ); +}; + +export const IconButton: React.FC = ({ sx = {}, children, ...props }) => ( + +); + +export const Card: React.FC = ({ sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const Grid: React.FC = ({ container, item, spacing = 0, xs, sm, md, sx = {}, children, ...props }) => { + const style: React.CSSProperties = applySx(sx); + if (container) { + style.display = "flex"; + style.flexWrap = "wrap"; + style.gap = `${spacing * 8}px`; + } + if (item) { + const width = md || sm || xs || 12; + style.flexBasis = `${(width / 12) * 100}%`; + } + return ( +
+ {children} +
+ ); +}; + +export const Stack: React.FC = ({ direction = "column", spacing = 0, sx = {}, children, ...props }) => ( +
+ {children} +
+); + +export const TextField: React.FC = ({ sx = {}, label, multiline, minRows, fullWidth, ...props }) => { + const style: React.CSSProperties = { + padding: "8px", + borderRadius: 4, + border: "1px solid #ccc", + width: fullWidth ? "100%" : undefined, + ...applySx(sx), + }; + return multiline ? ( +