feat: add themeing

This commit is contained in:
Jayden Pyles
2024-07-06 23:32:40 -05:00
parent 2bfc751d01
commit ce00acc4cb
4 changed files with 229 additions and 76 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React from "react";
import { import {
TextField, TextField,
Table, Table,
@@ -7,6 +7,8 @@ import {
TableHead, TableHead,
TableRow, TableRow,
Button, Button,
Box,
Typography,
} from "@mui/material"; } from "@mui/material";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@@ -59,64 +61,80 @@ const JobTable: React.FC<JobTableProps> = ({ jobs }) => {
return ( return (
<> <>
<Table> <Box
<TableHead> width="fullWidth"
<TableRow> bgcolor="background.paper"
<TableCell>id</TableCell> className="flex justify-center"
<TableCell>url</TableCell> >
<TableCell>elements</TableCell> <Box
<TableCell>result</TableCell> maxWidth="lg"
<TableCell>time_created</TableCell> minHeight="100vh"
</TableRow> bgcolor="background.paper"
</TableHead> className="p-4"
<TableBody> >
{jobs.map((row, index) => ( <Typography variant="h4">Scrape Jobs</Typography>
<TableRow key={index}> <Table>
<TableCell> <TableHead>
<TextField variant="outlined" fullWidth value={row.id} /> <TableRow>
</TableCell> <TableCell>id</TableCell>
<TableCell> <TableCell>url</TableCell>
<TextField variant="outlined" fullWidth value={row.url} /> <TableCell>elements</TableCell>
</TableCell> <TableCell>result</TableCell>
<TableCell> <TableCell>time_created</TableCell>
<TextField </TableRow>
variant="outlined" </TableHead>
fullWidth <TableBody>
value={JSON.stringify(row.elements)} {jobs.map((row, index) => (
/> <TableRow key={index}>
</TableCell> <TableCell>
<TableCell> <TextField variant="outlined" fullWidth value={row.id} />
<TextField </TableCell>
variant="outlined" <TableCell>
fullWidth <TextField variant="outlined" fullWidth value={row.url} />
value={JSON.stringify(row.result)} </TableCell>
/> <TableCell>
</TableCell> <TextField
<TableCell> variant="outlined"
<TextField fullWidth
variant="outlined" value={JSON.stringify(row.elements)}
fullWidth />
value={row.time_created} </TableCell>
/> <TableCell>
</TableCell> <TextField
<TableCell> variant="outlined"
<Button fullWidth
onClick={() => { value={JSON.stringify(row.result)}
handleDownload(row.id); />
}} </TableCell>
> <TableCell>
Download <TextField
</Button> variant="outlined"
</TableCell> fullWidth
<TableCell> value={row.time_created}
<Button onClick={() => handleNavigate(row.elements, row.url)}> />
Rerun </TableCell>
</Button> <TableCell>
</TableCell> <Button
</TableRow> onClick={() => {
))} handleDownload(row.id);
</TableBody> }}
</Table> >
Download
</Button>
</TableCell>
<TableCell>
<Button
onClick={() => handleNavigate(row.elements, row.url)}
>
Rerun
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Box>
</> </>
); );
}; };

View File

@@ -13,13 +13,19 @@ import {
IconButton, IconButton,
Typography, Typography,
Button, Button,
Switch,
} from "@mui/material"; } from "@mui/material";
import HomeIcon from "@mui/icons-material/Home"; import HomeIcon from "@mui/icons-material/Home";
import HttpIcon from "@mui/icons-material/Http"; import HttpIcon from "@mui/icons-material/Http";
import MenuIcon from "@mui/icons-material/Menu"; import MenuIcon from "@mui/icons-material/Menu";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
const NavDrawer: React.FC = () => { interface NavDrawerProps {
toggleTheme: () => void;
isDarkMode: boolean;
}
const NavDrawer: React.FC<NavDrawerProps> = ({ toggleTheme, isDarkMode }) => {
const router = useRouter(); const router = useRouter();
const { login, logout, user, isAuthenticated } = useAuth(); const { login, logout, user, isAuthenticated } = useAuth();
const [open, setOpen] = useState<boolean>(false); const [open, setOpen] = useState<boolean>(false);
@@ -70,20 +76,23 @@ const NavDrawer: React.FC = () => {
<> <>
<AppBar position="static"> <AppBar position="static">
<Toolbar className="flex flex-row justify-between items-center"> <Toolbar className="flex flex-row justify-between items-center">
<IconButton <div className="flex flex-row">
edge="start" <IconButton
color="inherit" edge="start"
aria-label="menu" color="inherit"
onClick={toggleDrawer(true)} aria-label="menu"
> onClick={toggleDrawer(true)}
<MenuIcon /> >
</IconButton> <MenuIcon />
</IconButton>
<Switch checked={isDarkMode} onChange={toggleTheme} />
</div>
{isAuthenticated ? ( {isAuthenticated ? (
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<Typography variant="body1" sx={{ marginRight: 2 }}> <Typography variant="body1" sx={{ marginRight: 2 }}>
Welcome, {user?.full_name} Welcome, {user?.full_name}
</Typography> </Typography>
<Button color="inherit" onClick={logout}> <Button color="inherit" onClick={logout} className="!color-white">
Logout Logout
</Button> </Button>
</div> </div>

View File

@@ -1,21 +1,143 @@
import "bootstrap/dist/css/bootstrap.min.css"; import "bootstrap/dist/css/bootstrap.min.css";
import "../styles/globals.css"; import "../styles/globals.css";
import React from "react"; import React, { useState, useEffect } from "react";
import type { AppProps } from "next/app"; import type { AppProps } from "next/app";
import Head from "next/head"; import Head from "next/head";
import { SessionProvider } from "next-auth/react"; import { SessionProvider } from "next-auth/react";
import { ThemeProvider, createTheme, CssBaseline } from "@mui/material";
import NavDrawer from "../components/NavDrawer"; import NavDrawer from "../components/NavDrawer";
const lightTheme = createTheme({
palette: {
mode: "light",
primary: {
main: "#1976d2",
},
secondary: {
main: "#dc004e",
},
background: {
default: "#f4f6f8",
paper: "#ffffff",
},
text: {
primary: "#000000",
secondary: "#333333",
},
},
typography: {
fontFamily: "Roboto, sans-serif",
h1: {
fontWeight: 500,
},
h2: {
fontWeight: 500,
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
color: "black",
},
},
},
MuiPaper: {
styleOverrides: {
root: {
padding: 16,
},
},
},
},
});
const darkTheme = createTheme({
palette: {
mode: "dark",
primary: {
main: "#90caf9",
},
secondary: {
main: "#f48fb1",
},
background: {
default: "#121212",
paper: "#1e1e1e",
},
text: {
primary: "#ffffff",
secondary: "#bbbbbb",
},
},
typography: {
fontFamily: "Roboto, sans-serif",
h1: {
fontWeight: 500,
color: "white",
},
h2: {
fontWeight: 500,
color: "white",
},
h4: {
fontWeight: 500,
color: "white",
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
color: "white",
},
},
},
MuiPaper: {
styleOverrides: {
root: {
padding: 16,
},
},
},
},
});
const App: React.FC<AppProps> = ({ Component, pageProps }) => { const App: React.FC<AppProps> = ({ Component, pageProps }) => {
const [isDarkMode, setIsDarkMode] = useState(false);
useEffect(() => {
const savedTheme = localStorage.getItem("theme");
if (savedTheme) {
setIsDarkMode(savedTheme === "dark");
} else {
const prefersDarkMode = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
setIsDarkMode(prefersDarkMode);
}
}, []);
const toggleTheme = () => {
const newTheme = !isDarkMode;
setIsDarkMode(newTheme);
localStorage.setItem("theme", newTheme ? "dark" : "light");
};
return ( return (
<> <>
<Head> <Head>
<title>Webapp Template</title> <title>Webapp Template</title>
</Head> </Head>
<SessionProvider session={pageProps.session}> <SessionProvider session={pageProps.session}>
<NavDrawer /> <ThemeProvider theme={isDarkMode ? darkTheme : lightTheme}>
<Component {...pageProps} /> <CssBaseline />
<NavDrawer isDarkMode={isDarkMode} toggleTheme={toggleTheme} />
<Component {...pageProps} />
</ThemeProvider>
</SessionProvider> </SessionProvider>
</> </>
); );

View File

@@ -16,6 +16,7 @@ import {
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import { useAuth } from "../hooks/useAuth"; import { useAuth } from "../hooks/useAuth";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import CircularProgress from "@mui/material/CircularProgress";
interface Element { interface Element {
name: string; name: string;
@@ -58,6 +59,7 @@ const Home = () => {
xpath: "", xpath: "",
url: "", url: "",
}); });
const [loading, setLoading] = useState(false);
const resultsRef = useRef<HTMLTableElement | null>(null); const resultsRef = useRef<HTMLTableElement | null>(null);
@@ -99,6 +101,7 @@ const Home = () => {
setIsValidUrl(true); setIsValidUrl(true);
setUrlError(null); setUrlError(null);
setLoading(true);
fetch("/api/submit-scrape-job", { fetch("/api/submit-scrape-job", {
method: "POST", method: "POST",
@@ -111,11 +114,13 @@ const Home = () => {
}), }),
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((data) => setResults(data)); .then((data) => setResults(data))
.finally(() => setLoading(false));
}; };
return ( return (
<Box <Box
bgcolor="background.paper"
display="flex" display="flex"
flexDirection="column" flexDirection="column"
justifyContent="center" justifyContent="center"
@@ -141,14 +146,13 @@ const Home = () => {
helperText={!isValidURL ? urlError : ""} helperText={!isValidURL ? urlError : ""}
/> />
<Button <Button
className="!text-black"
variant="contained" variant="contained"
color="primary" color="primary"
size="small" size="small"
onClick={handleSubmit} onClick={handleSubmit}
disabled={!(rows.length > 0)} disabled={!(rows.length > 0) || loading}
> >
Submit {loading ? <CircularProgress size={24} /> : "Submit"}
</Button> </Button>
</div> </div>
<Box display="flex" gap={2} marginBottom={2} className="items-center"> <Box display="flex" gap={2} marginBottom={2} className="items-center">