Merge pull request #97 from bluewave-labs/feat/redux-toolkit

Set up Redux Toolkit, Added redux demo to /demo route
This commit is contained in:
Veysel
2024-06-04 17:22:36 -04:00
committed by GitHub
9 changed files with 1621 additions and 362 deletions
+5 -2
View File
@@ -39,20 +39,22 @@ const levelConfig = {
* @param {string} props.label - The label of the button
* @param {React.ReactNode} props.img - Image for button
* @param {boolean} [props.disabled] - Whether the button is disabled
* @param {Object} prps.sx - Styles for the button
* @param {function} props.onClick - Function to run when the button is clicked
* @param {Object} props.sx - Styles for the button
* @returns {JSX.Element}
* @example
* // Render an error button
* <Button level="error" label="Error" disabled sx={{marginTop: "1rem"}}/>
*/
const Button = ({ level, label, disabled, img, sx }) => {
const Button = ({ level, label, disabled, img, onClick, sx }) => {
const { variant, color } = levelConfig[level];
return (
<MuiButton
variant={variant}
color={color}
disabled={disabled}
onClick={onClick}
sx={{
textTransform: "none",
...sx,
@@ -68,6 +70,7 @@ Button.propTypes = {
level: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
img: PropTypes.node,
onClick: PropTypes.func,
sx: PropTypes.object,
disabled: PropTypes.bool,
};
+1 -2
View File
@@ -16,7 +16,7 @@ import AddIcon from "@mui/icons-material/Add";
/**
* @component
* @param {Object} props
* @param { Array} props.montitors - Array of monitors associated with the section
* @param { Array} props.monitors - Array of monitors associated with the section
* @returns {JSX.Element}
* @example
* // Renders a section component with a list of monitors
@@ -29,7 +29,6 @@ const Section = ({ monitors }) => {
);
useEffect(() => {
console.log("Monitor states updated", monitorStates);
// Update DB here
}, [monitorStates]);
@@ -0,0 +1,51 @@
import axios from "axios";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
const initialState = {
isLoading: false,
monitors: [],
success: null,
msg: null,
};
export const getMonitors = createAsyncThunk(
"monitors/getMonitors",
async (token, thunkApi) => {
try {
const res = await axios.get(
import.meta.env.VITE_APP_API_BASE_URL + "/monitors"
);
return res.data;
} catch (error) {
return thunkApi.rejectWithValue(error.response.data);
}
}
);
const monitorsSlice = createSlice({
name: "monitors",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(getMonitors.pending, (state, action) => {
state.isLoading = true;
})
.addCase(getMonitors.fulfilled, (state, action) => {
state.isLoading = false;
state.success = action.payload.success;
state.msg = action.payload.msg;
console.log(action.payload);
state.monitors = action.payload.data;
})
.addCase(getMonitors.rejected, (state, action) => {
state.isLoading = false;
state.success = action.payload.success;
state.msg = action.payload.msg;
});
},
});
export const { setMonitors } = monitorsSlice.actions;
export default monitorsSlice.reducer;
+50 -2
View File
@@ -1,4 +1,5 @@
import React from "react";
import axios from "axios";
import Button from "../../Components/Button/";
import Link from "../../Components/Link";
import {
@@ -12,6 +13,7 @@ import {
RadioGroup,
Tab,
Tabs,
Typography,
} from "@mui/material";
import { ColoredLabel, StatusLabel } from "../../Components/Label/";
import Avatar from "../../Components/Avatar/";
@@ -25,6 +27,11 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import AddIcon from "@mui/icons-material/Add";
import Divider from "@mui/material/Divider";
// Redux
import { useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { getMonitors } from "../../Features/Monitors/monitorsSlice";
const cols = [
{
field: "name",
@@ -84,13 +91,15 @@ const steps = [
{ label: "Invite your team", content: "Start collaborating with your team" },
];
const monitors = [
const demoMonitors = [
{ id: 0, name: "Google", isActive: true },
{ id: 1, name: "Yahoo", isActive: false },
{ id: 2, name: "Reddit", isActive: true },
];
const Demo = () => {
const dispatch = useDispatch();
const [radio, setRadio] = React.useState(1);
const [tab, setTab] = React.useState("departments");
const [date, setDate] = React.useState("Pick a date!");
@@ -167,8 +176,47 @@ const Demo = () => {
];
const theme = useTheme();
// *********************************
// Redux Demo
// *********************************
const monitorState = useSelector((state) => state.monitors);
const { monitors, msg } = monitorState;
return (
<div>
<div style={{ padding: "4rem", border: "1px solid black" }}>
<Typography variant="h4">Redux Demo</Typography>
<Typography variant="h6">Monitors</Typography>
<table
style={{ border: "1px solid black", borderCollapse: "collapse" }}
>
<tbody>
<tr>
<th style={{ border: "1px solid black" }}>Name</th>
<th style={{ border: "1px solid black" }}>URL</th>
</tr>
{monitors &&
monitors.map((monitor) => {
return (
<tr key={monitor._id}>
<td style={{ border: "1px solid black" }}>
{monitor.name}
</td>
<td style={{ border: "1px solid black" }}>{monitor.url}</td>
</tr>
);
})}
</tbody>
</table>
<p>Message: {msg}</p>
<Button
level="primary"
label="Get Monitors"
onClick={() => {
dispatch(getMonitors());
}}
/>
</div>
<ul style={{ listStyle: "none" }}>
{links.map((link) => (
<li key={link.url}>
@@ -304,7 +352,7 @@ const Demo = () => {
</div>
<Divider sx={{ margin: `${theme.spacing(2)}` }} />
<h4 id="section">Section</h4>
<Section monitors={monitors} />
<Section monitors={demoMonitors} />
</div>
);
};
+10 -5
View File
@@ -5,12 +5,17 @@ import "./index.css";
import { BrowserRouter as Router, HashRouter } from "react-router-dom";
import theme from "./Utils/Theme.js";
import { ThemeProvider } from "@mui/material";
import { Provider } from "react-redux";
import store from "./store";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<ThemeProvider theme={theme}>
<Router>
<App />
</Router>
</ThemeProvider>
<Provider store={store}>
<ThemeProvider theme={theme}>
<Router>
<App />
</Router>
</ThemeProvider>
</Provider>
</React.StrictMode>
);
+6
View File
@@ -0,0 +1,6 @@
import { configureStore } from "@reduxjs/toolkit";
import monitorsReducer from "./Features/Monitors/monitorsSlice";
export default configureStore({
reducer: { monitors: monitorsReducer },
});