From a73afc90d9180e2ad52127772173a680e4846582 Mon Sep 17 00:00:00 2001 From: minhtrannhat Date: Fri, 21 Jul 2023 22:22:19 -0400 Subject: [PATCH] Feat(Frontend): Authentication Context --- frontend/README.md | 12 +++++++++-- frontend/package-lock.json | 35 +++++++++++++++++++++++++++++++ frontend/package.json | 1 + frontend/src/App.tsx | 19 ++++++++++++++--- frontend/src/AuthContext.tsx | 25 ++++++++++++++++++++++ frontend/src/components/Title.tsx | 19 +++++++++++++++++ 6 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 frontend/src/AuthContext.tsx create mode 100644 frontend/src/components/Title.tsx diff --git a/frontend/README.md b/frontend/README.md index b9cbf0a..d31cc49 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -21,10 +21,18 @@ useMemo is a React Hook that lets you cache the result of a calculation between Change default component colors to suit one's needs. -#### CSSBaseline +##### CSSBaseline Reset the CSS injected into ``. A collection of HTML element and attribute style-normalizations, you can expect all of the elements to look the same across all browsers. -#### useMediaQuery +##### useMediaQuery This React hook listens for matches to a CSS media query. It allows the rendering of components based on whether the query matches or not. + +##### Container's maxWidth + +This will make sure Material UI's Container will not expand to fill the entire screen and instead just stop expanding at around 960px (which is `md`). + +### Configure the page's title (Browser Tab Text) + +Use `react-helmet-async`, wrap it around the `App` in `App.tsx`. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 692bc5d..accc93b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,7 @@ "@types/react": "^18.2.15", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-helmet-async": "^1.3.0", "react-scripts": "^5.0.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4", @@ -9934,6 +9935,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ipaddr.js": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", @@ -15299,6 +15308,27 @@ "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -16154,6 +16184,11 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 768fc81..640e87a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "@types/react": "^18.2.15", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-helmet-async": "^1.3.0", "react-scripts": "^5.0.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2039f6b..df77705 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -13,11 +13,24 @@ import ThemeProvider from "./ThemeProvider"; // Material UI stuffs import Container from "@mui/material/Container"; +// React helmet async: configure the page's title +import { Helmet, HelmetProvider } from "react-helmet-async"; + +// Authentication Context: Check if user is logged in or not +import { AuthContextProvider } from "./AuthContext"; + function App() { return ( - - - + + + + Todo + + + + + + ); } diff --git a/frontend/src/AuthContext.tsx b/frontend/src/AuthContext.tsx new file mode 100644 index 0000000..68f5743 --- /dev/null +++ b/frontend/src/AuthContext.tsx @@ -0,0 +1,25 @@ +import { createContext, useState } from "react"; + +interface IAuth { + authenticated: boolean; + setAuthenticated: (value: boolean) => void; +} + +export const AuthContext = createContext({ + authenticated: true, + setAuthenticated: (value: boolean) => {}, +}); + +interface IProps { + children?: React.ReactNode; +} + +export const AuthContextProvider = ({ children }: IProps) => { + const [authenticated, setAuthenticated] = useState(true); + + return ( + + {children} + + ); +}; diff --git a/frontend/src/components/Title.tsx b/frontend/src/components/Title.tsx new file mode 100644 index 0000000..9ac6d85 --- /dev/null +++ b/frontend/src/components/Title.tsx @@ -0,0 +1,19 @@ +import Typography from "@mui/material/Typography"; +import { Helmet } from "react-helmet-async"; + +interface IProps { + title: string; +} + +const Title = ({ title }: IProps) => ( + <> + + Todo | {title} + + + {title} + + +); + +export default Title;