feat: base mui

This commit is contained in:
redglow
2026-06-20 16:16:12 +02:00
parent 4708a6396c
commit 1eeab12f8e
14 changed files with 511 additions and 25 deletions
+135
View File
@@ -0,0 +1,135 @@
import MenuIcon from "@mui/icons-material/Menu";
import {
AppBar,
Box,
Button,
IconButton,
Menu,
MenuItem,
Toolbar,
Typography,
} from "@mui/material";
import { Link } from "@tanstack/react-router";
import { useState } from "react";
import { RouterButton } from "./RouterButton";
const pages = ["Products", "Pricing", "Blog"];
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null);
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget);
};
const handleCloseNavMenu = () => {
setAnchorElNav(null);
};
return (
<Box
sx={{
position: "relative",
display: "flex",
overflow: "hidden",
height: "100%",
width: "100%",
}}
>
<AppBar position="static">
<Toolbar>
{/* desktop */}
<Typography
variant="h6"
noWrap
sx={{ mr: 2, display: { xs: "none", md: "flex" } }}
>
<em>owof</em> Announcements
</Typography>
{/* mobile */}
<Box sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{ display: { xs: "block", md: "none" } }}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography sx={{ textAlign: "center" }}>{page}</Typography>
</MenuItem>
))}
</Menu>
</Box>
<Typography
variant="h6"
noWrap
sx={{ display: { xs: "flex", md: "none" } }}
>
<em>owof</em> Announcements
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}>
{pages.map((page) => (
<RouterButton
key={page}
onClick={handleCloseNavMenu}
sx={{ my: 2, color: "white", display: "block" }}
to="."
>
{page}
</RouterButton>
))}
</Box>
</Toolbar>
</AppBar>
<Box
sx={{
display: "flex",
flexDirection: "column",
flex: 1,
minWidth: 0,
}}
>
<Toolbar sx={{ displayPrint: "none" }} />
<Box
component="main"
sx={{
display: "flex",
flexDirection: "column",
flex: 1,
overflow: "auto",
}}
>
{children}
</Box>
</Box>
</Box>
);
}
+11
View File
@@ -0,0 +1,11 @@
// src/components/ui/mui-router-button.tsx
import { createLink } from "@tanstack/react-router";
import { Button, type ButtonProps } from "@mui/material";
import { forwardRef } from "react";
// Create a router-compatible MUI Button
export const RouterButton = createLink(
forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
return <Button ref={ref} component="button" {...props} />;
}),
);
+11
View File
@@ -0,0 +1,11 @@
// src/components/ui/mui-router-fab.tsx
import { createLink } from "@tanstack/react-router";
import { Fab, type FabProps } from "@mui/material";
import { forwardRef } from "react";
// Router-compatible Floating Action Button
export const RouterFab = createLink(
forwardRef<HTMLButtonElement, FabProps>((props, ref) => {
return <Fab ref={ref} {...props} />;
}),
);
+11
View File
@@ -0,0 +1,11 @@
// src/components/ui/mui-router-link.tsx
import { createLink } from "@tanstack/react-router";
import { Link as MuiLink, type LinkProps } from "@mui/material";
import { forwardRef } from "react";
// Create a router-compatible MUI Link with full type safety
export const RouterLink = createLink(
forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
return <MuiLink ref={ref} {...props} />;
}),
);
+18 -6
View File
@@ -1,15 +1,27 @@
import "@fontsource/roboto/300.css";
import "@fontsource/roboto/400.css";
import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css";
import "@fontsource/raleway/300.css";
import "@fontsource/raleway/400.css";
import "@fontsource/raleway/500.css";
import "@fontsource/raleway/700.css";
import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import App from "./App";
// Import the generated route tree
import { routeTree } from "./routeTree.gen";
// Create a new router instance
const router = createRouter({ routeTree });
// Register the router instance for type safety
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
<RouterProvider router={router} />
</React.StrictMode>,
);
+35
View File
@@ -0,0 +1,35 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
export interface FileRoutesByFullPath {}
export interface FileRoutesByTo {}
export interface FileRoutesById {
__root__: typeof rootRouteImport
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: never
fileRoutesByTo: FileRoutesByTo
to: never
id: '__root__'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {}
}
const rootRouteChildren: RootRouteChildren = {}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()
+19
View File
@@ -0,0 +1,19 @@
import { CssBaseline } from "@mui/material";
import { createRootRoute, Outlet } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { AppTheme } from "../theme";
import DashboardLayout from "../components/DashboardLayout";
export const Route = createRootRoute({
component: () => (
<>
<AppTheme>
<CssBaseline enableColorScheme />
<DashboardLayout>
<Outlet />
</DashboardLayout>
<TanStackRouterDevtools />
</AppTheme>
</>
),
});
+25
View File
@@ -0,0 +1,25 @@
import { createTheme, ThemeProvider } from "@mui/material";
const themeOptions = {
palette: {
secondary: {
main: "#27a6b0",
},
primary: {
main: "#d21981",
},
},
typography: {
fontFamily: "Raleway",
},
shape: {
borderRadius: 7,
},
spacing: 9,
};
export const myTheme = createTheme(themeOptions);
export function AppTheme({ children }: React.PropsWithChildren<unknown>) {
return <ThemeProvider theme={myTheme}>{children}</ThemeProvider>;
}