initial redux setup

This commit is contained in:
Taehee Choi 2022-03-13 11:56:47 -07:00
parent adc1dc248f
commit 3320d0d932
11 changed files with 259 additions and 43 deletions

186
package-lock.json generated
View File

@ -12,8 +12,10 @@
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.4.2",
"@mui/material": "^5.4.3",
"@reduxjs/toolkit": "^1.8.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.1"
},
"devDependencies": {
@ -2205,6 +2207,29 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@reduxjs/toolkit": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.0.tgz",
"integrity": "sha512-cdfHWfcvLyhBUDicoFwG1u32JqvwKDxLxDd7zSmSoFw/RhYLOygIRtmaMjPRUUHmVmmAGAvquLLsKKU/677kSQ==",
"dependencies": {
"immer": "^9.0.7",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1",
"reselect": "^4.1.5"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || 18.0.0-beta",
"react-redux": "^7.2.1 || ^8.0.0-beta"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@sindresorhus/is": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@ -2560,6 +2585,15 @@
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
"dev": true
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -2654,6 +2688,17 @@
"@types/react": "*"
}
},
"node_modules/@types/react-redux": {
"version": "7.1.23",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz",
"integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==",
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"node_modules/@types/react-router": {
"version": "5.1.18",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz",
@ -4552,6 +4597,7 @@
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@ -7707,6 +7753,12 @@
"dev": true,
"dependencies": {
"imagemin": "^7.0.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-mozjpeg": "^9.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-pngquant": "^9.0.2",
"imagemin-svgo": "^9.0.0",
"imagemin-webp": "^7.0.0",
"loader-utils": "^2.0.0",
"object-assign": "^4.1.1",
"schema-utils": "^2.7.1"
@ -8163,6 +8215,15 @@
"node": ">=8"
}
},
"node_modules/immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
"integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -10470,6 +10531,35 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-redux": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
"integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
"dependencies": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"peerDependencies": {
"react": "^16.8.3 || ^17"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-router": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
@ -10548,6 +10638,22 @@
"node": ">= 0.10"
}
},
"node_modules/redux": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -10698,6 +10804,11 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
"node_modules/reselect": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
"integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
},
"node_modules/resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
@ -14247,6 +14358,17 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz",
"integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA=="
},
"@reduxjs/toolkit": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.0.tgz",
"integrity": "sha512-cdfHWfcvLyhBUDicoFwG1u32JqvwKDxLxDd7zSmSoFw/RhYLOygIRtmaMjPRUUHmVmmAGAvquLLsKKU/677kSQ==",
"requires": {
"immer": "^9.0.7",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1",
"reselect": "^4.1.5"
}
},
"@sindresorhus/is": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@ -14498,6 +14620,15 @@
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
"dev": true
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -14592,6 +14723,17 @@
"@types/react": "*"
}
},
"@types/react-redux": {
"version": "7.1.23",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz",
"integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==",
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/react-router": {
"version": "5.1.18",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz",
@ -18827,6 +18969,11 @@
"is-cwebp-readable": "^3.0.0"
}
},
"immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
"integrity": "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA=="
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -20521,6 +20668,26 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-redux": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz",
"integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==",
"requires": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"dependencies": {
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}
}
},
"react-router": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
@ -20582,6 +20749,20 @@
"resolve": "^1.9.0"
}
},
"redux": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
"integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
"requires": {}
},
"regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -20701,6 +20882,11 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
"reselect": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz",
"integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ=="
},
"resolve": {
"version": "1.22.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",

View File

@ -12,8 +12,10 @@
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.4.2",
"@mui/material": "^5.4.3",
"@reduxjs/toolkit": "^1.8.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.1"
},
"scripts": {

View File

@ -15,8 +15,6 @@ import Theme from "./Theme";
import "./style/App.css";
const App: React.FC = () => {
const [meetingInfoOpen, setMeetingInfoOpen] = useState(false);
return (
<ThemeProvider theme={Theme}>
<Router>
@ -24,15 +22,12 @@ const App: React.FC = () => {
<Route path="/login" element={<Login />} />
<Route element={<ProtectedRoute />}>
<Route path="/" element={<Home />} />
<Route
path="/contacts"
element={<Contacts setMeetingInfoOpen={setMeetingInfoOpen} />}
/>
<Route path="/contacts" element={<Contacts />} />
<Route path="/calendar" element={<Calendar />} />
</Route>
</Routes>
</Router>
<MeetingDetails open={meetingInfoOpen} setOpen={setMeetingInfoOpen} />
<MeetingDetails />
</ThemeProvider>
);
};

View File

@ -5,11 +5,7 @@ import Body from "./contacts-components/Body";
import ContactInfo from "./ContactInfo";
import Sidebar from "./contacts-components/Sidebar";
interface Props {
setMeetingInfoOpen: (open: boolean) => void;
}
const Contacts: React.FC<Props> = (props) => {
const Contacts: React.FC = () => {
const [contactSelected, setContactSelected] =
React.useState<ContactInfo | null>(null);
@ -17,10 +13,7 @@ const Contacts: React.FC<Props> = (props) => {
<Box sx={{ display: "flex", height: "100%" }}>
<Sidebar setContactSelected={setContactSelected} />
{contactSelected !== null ? (
<Body
contactSelected={contactSelected}
setMeetingInfoOpen={props.setMeetingInfoOpen}
/>
<Body contactSelected={contactSelected} />
) : null}
</Box>
);

View File

@ -6,7 +6,6 @@ import ContactInfo from "../ContactInfo";
interface Props {
contactSelected: ContactInfo;
setMeetingInfoOpen: (open: boolean) => void;
}
const Body: React.FC<Props> = (props) => {
@ -21,10 +20,7 @@ const Body: React.FC<Props> = (props) => {
>
<Toolbar />
<UpperBody contactInfo={props.contactSelected} />
<LowerBody
contactInfo={props.contactSelected}
setMeetingInfoOpen={props.setMeetingInfoOpen}
/>
<LowerBody />
</Box>
);
};

View File

@ -1,6 +1,7 @@
import { Box, Button, List, Typography } from "@mui/material";
import React from "react";
import ContactInfo from "../../ContactInfo";
import { useDispatch } from "react-redux";
import { open } from "../../../../redux/slices/meetingDetailsOpenSlice";
const meetings: { name: string; duration: string }[] = [
{ name: "Kanban Meeting", duration: "10:45 am - 11:45 am" },
@ -10,12 +11,9 @@ const meetings: { name: string; duration: string }[] = [
{ name: "Some kind of Meeting", duration: "10:45 am - 11:45 am" },
];
interface Props {
contactInfo: ContactInfo;
setMeetingInfoOpen: (open: boolean) => void;
}
const LowerBody: React.FC = () => {
const dispatch = useDispatch();
const LowerBody: React.FC<Props> = (props) => {
return (
<Box
sx={{
@ -47,7 +45,7 @@ const LowerBody: React.FC<Props> = (props) => {
<Button
variant="text"
color="info"
onClick={() => props.setMeetingInfoOpen(true)}
onClick={() => dispatch(open())}
>
{meeting.name}
</Button>

View File

@ -2,16 +2,19 @@ import { Dialog } from "@mui/material";
import React from "react";
import Body from "./meeting-details-components/Body";
import Header from "./meeting-details-components/Header";
import { useSelector, useDispatch } from "react-redux";
import {
close,
selectMeetingDetailsOpen,
} from "../../redux/slices/meetingDetailsOpenSlice";
interface Props {
open: boolean;
setOpen: (open: boolean) => void;
}
const MeetingDetails: React.FC = () => {
const open = useSelector(selectMeetingDetailsOpen);
const dispatch = useDispatch();
const MeetingDetails: React.FC<Props> = (props) => {
return (
<Dialog fullScreen open={props.open} onClose={() => props.setOpen(false)}>
<Header setOpen={props.setOpen} />
<Dialog fullScreen open={open} onClose={() => dispatch(close())}>
<Header />
<Body />
</Dialog>
);

View File

@ -1,12 +1,12 @@
import { AppBar, Button, IconButton, Toolbar, Typography } from "@mui/material";
import React from "react";
import CloseIcon from "@mui/icons-material/Close";
import { useDispatch } from "react-redux";
import { close } from "../../../redux/slices/meetingDetailsOpenSlice";
interface Props {
setOpen: (open: boolean) => void;
}
const Header: React.FC = () => {
const dispatch = useDispatch();
const Header: React.FC<Props> = (props) => {
return (
<AppBar sx={{ position: "relative" }}>
<Toolbar>
@ -23,7 +23,7 @@ const Header: React.FC<Props> = (props) => {
edge="start"
color="inherit"
aria-label="close"
onClick={() => props.setOpen(false)}
onClick={() => dispatch(close())}
sx={{ ml: 1 }}
>
<CloseIcon />

View File

@ -1,12 +1,16 @@
import ReactDOM from "react-dom";
import App from "./App";
import "./style/App.css";
import { AuthProvider } from './context/AuthProvider';
import { AuthProvider } from "./context/AuthProvider";
import { Provider } from "react-redux";
import { store } from "./redux/store";
const Index:React.FC = () => {
const Index: React.FC = () => {
return (
<AuthProvider>
<Provider store={store}>
<App />
</Provider>
</AuthProvider>
);
};

View File

@ -0,0 +1,28 @@
import { createSlice } from "@reduxjs/toolkit";
import { RootState } from "../store";
interface MeetingDetailsOpenState {
open: boolean;
}
const initialState: MeetingDetailsOpenState = {
open: false,
};
export const meetingDetailsOpenSlice = createSlice({
name: "meetingDetailsOpen",
initialState,
reducers: {
open: (state) => {
state.open = true;
},
close: (state) => {
state.open = false;
},
},
});
export const { open, close } = meetingDetailsOpenSlice.actions;
export const selectMeetingDetailsOpen = (state: RootState) =>
state.meetingDetailsOpen.open;
export default meetingDetailsOpenSlice.reducer;

11
src/redux/store.tsx Normal file
View File

@ -0,0 +1,11 @@
import { configureStore } from "@reduxjs/toolkit";
import meetingDetailsOpenReducer from "./slices/meetingDetailsOpenSlice";
export const store = configureStore({
reducer: {
meetingDetailsOpen: meetingDetailsOpenReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;