Attempt 2 to install MUI
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
apatil 2025-05-05 17:38:52 +01:00
parent da138ca738
commit 6a5438ed00
9 changed files with 129 additions and 71 deletions

36
package-lock.json generated
View File

@ -13,6 +13,7 @@
"@fontsource/roboto": "^5.2.5", "@fontsource/roboto": "^5.2.5",
"@mui/icons-material": "^7.0.2", "@mui/icons-material": "^7.0.2",
"@mui/material": "^7.0.2", "@mui/material": "^7.0.2",
"@mui/material-nextjs": "^7.0.2",
"next": "15.3.1", "next": "15.3.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0"
@ -1094,6 +1095,41 @@
} }
} }
}, },
"node_modules/@mui/material-nextjs": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@mui/material-nextjs/-/material-nextjs-7.0.2.tgz",
"integrity": "sha512-hjm0MFSjx7HWbORMRldbwfKrQPHTSMXD6dkCCSTQZ2XX8fkKlnOXNnoXUFzlzFtMKMzs9QOfe3dHooTvnDEfuQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.27.0"
},
"engines": {
"node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui-org"
},
"peerDependencies": {
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.4",
"@emotion/server": "^11.11.0",
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"next": "^13.0.0 || ^14.0.0 || ^15.0.0",
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/cache": {
"optional": true
},
"@emotion/server": {
"optional": true
},
"@types/react": {
"optional": true
}
}
},
"node_modules/@mui/private-theming": { "node_modules/@mui/private-theming": {
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.0.2.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.0.2.tgz",

View File

@ -14,6 +14,7 @@
"@fontsource/roboto": "^5.2.5", "@fontsource/roboto": "^5.2.5",
"@mui/icons-material": "^7.0.2", "@mui/icons-material": "^7.0.2",
"@mui/material": "^7.0.2", "@mui/material": "^7.0.2",
"@mui/material-nextjs": "^7.0.2",
"next": "15.3.1", "next": "15.3.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0"

View File

@ -1,12 +1,13 @@
'use client'
/* eslint-disable @next/next/no-page-custom-font */
import type { Metadata } from "next"; import type { Metadata } from "next";
import "./globals.css"; import "./globals.css";
import Header from "@/components/Header"; import theme from "@/theme/theme";
import { light, dark } from "@/theme/theme";
import { ThemeProvider } from "@mui/material/styles"; import { ThemeProvider } from "@mui/material/styles";
import { CssBaseline } from "@mui/material"; import { CssBaseline } from "@mui/material";
import { useState } from "react"; import InitColorSchemeScript from "@mui/material/InitColorSchemeScript";
import { AppRouterCacheProvider } from "@mui/material-nextjs/v13-appRouter";
import ModeSwitch from "@/components/ModeSwitch/ModeSwitch";
import Header from "@/components/Header/Header";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "The Coding Grizzly", title: "The Coding Grizzly",
@ -18,33 +19,21 @@ export default function RootLayout({
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
const [isDarkMode, setIsDarkMode] = useState(false);
const toggleTheme = () => {
setIsDarkMode((prevMode) => !prevMode);
};
return ( return (
<html lang="en"> <html lang="en" suppressHydrationWarning>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
</head>
<body> <body>
<ThemeProvider theme={isDarkMode ? dark : light}> <InitColorSchemeScript attribute="class" />
<AppRouterCacheProvider options={{ enableCssLayer: true }}>
<ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<Header toggleTheme={toggleTheme} /> <ModeSwitch />
<Header />
{children} {children}
</ThemeProvider> </ThemeProvider>
</AppRouterCacheProvider>
</body> </body>
</html> </html >
); );
} }

View File

@ -6,7 +6,6 @@ import MenuIcon from '@mui/icons-material/Menu'
import { import {
AppBar, AppBar,
Box, Box,
Button,
Drawer, Drawer,
IconButton, IconButton,
List, List,
@ -22,7 +21,7 @@ const navItems = [
{ label: 'Info', href: '/info' }, { label: 'Info', href: '/info' },
{ label: 'Music', href: '/music' } { label: 'Music', href: '/music' }
] ]
export default function Header({ toggleTheme }: { toggleTheme: () => void }) { export default function Header() {
const [mobileOpen, setMobileOpen] = React.useState(false) const [mobileOpen, setMobileOpen] = React.useState(false)
const handleDrawerToggle = () => { const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen) setMobileOpen(!mobileOpen)
@ -30,9 +29,6 @@ export default function Header({ toggleTheme }: { toggleTheme: () => void }) {
const drawer = ( const drawer = (
<Box onClick={handleDrawerToggle}> <Box onClick={handleDrawerToggle}>
<Typography variant="h6" >Menu</Typography> <Typography variant="h6" >Menu</Typography>
<Button variant="contained" onClick={toggleTheme}>
Toggle Theme
</Button>
<List> <List>
{navItems.map((item) => ( {navItems.map((item) => (
<ListItem key={item.label} disablePadding> <ListItem key={item.label} disablePadding>

View File

@ -0,0 +1 @@
export * from './Header';

View File

@ -0,0 +1,40 @@
'use client';
import * as React from 'react';
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import { useColorScheme } from '@mui/material/styles';
export default function ModeSwitch() {
const { mode, setMode } = useColorScheme();
if (!mode) {
return null;
}
return (
<Box
sx={{
display: 'flex',
justifyContent: 'flex-end',
mt: 1,
p: 1,
}}
>
<FormControl>
<InputLabel id="mode-select-label">Theme</InputLabel>
<Select
labelId="mode-select-label"
id="mode-select"
value={mode}
onChange={(event) => setMode(event.target.value as typeof mode)}
label="Theme"
>
<MenuItem value="system">System</MenuItem>
<MenuItem value="light">Light</MenuItem>
<MenuItem value="dark">Dark</MenuItem>
</Select>
</FormControl>
</Box>
);
}

View File

@ -0,0 +1 @@
export * from './ModeSwitch';

1
src/theme/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './theme';

View File

@ -1,44 +1,37 @@
// theme.js 'use client';
import { createTheme } from '@mui/material/styles'; import { createTheme } from '@mui/material/styles';
import { Roboto } from 'next/font/google';
const light = createTheme({ const roboto = Roboto({
palette: { weight: ['300', '400', '500', '700'],
mode: 'light', subsets: ['latin'],
primary: { display: 'swap',
main: '#1976d2', // Blue });
const theme = createTheme({
colorSchemes: { light: true, dark: true },
cssVariables: {
colorSchemeSelector: 'class',
}, },
secondary: { typography: {
main: '#dc004e', // Red fontFamily: roboto.style.fontFamily,
},
components: {
MuiAlert: {
styleOverrides: {
root: {
variants: [
{
props: { severity: 'info' },
style: {
backgroundColor: '#60a5fa',
},
},
],
}, },
background: {
default: '#ffffff', // White
paper: '#f5f5f5', // Light Grey
}, },
text: {
primary: '#000000', // Black
secondary: '#555555', // Dark Grey
}, },
}, },
}); });
const dark = createTheme({ export default theme;
palette: {
mode: 'dark',
primary: {
main: '#90caf9', // Light Blue
},
secondary: {
main: '#f48fb1', // Pink
},
background: {
default: '#121212', // Dark Grey
paper: '#1d1d1d', // Slightly Lighter Grey
},
text: {
primary: '#ffffff', // White
secondary: '#bbbbbb', // Light Grey
},
},
});
export { light, dark };