Skip to content

Commit

Permalink
Add protected ui routes
Browse files Browse the repository at this point in the history
  • Loading branch information
ckng0221 committed Jan 30, 2024
1 parent 4716fa9 commit 725a4b6
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 26 deletions.
1 change: 1 addition & 0 deletions apps/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"axios": "^1.6.2",
"bootstrap": "^5.3.2",
"dayjs": "^1.11.10",
"query-string": "^8.1.0",
"react": "^18.2.0",
"react-bootstrap": "^2.9.1",
"react-cookie": "^7.0.2",
Expand Down
84 changes: 61 additions & 23 deletions apps/ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { AlertColor } from '@mui/material';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useEffect, useState } from 'react';
import { useCookies } from 'react-cookie';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import {
BrowserRouter,
Route,
Routes,
Navigate,
Outlet,
useLocation,
} from 'react-router-dom';
import { tokenVerification } from './api/auth-api';
import { getCustomerById } from './api/customer-api';
import { ICart } from './interfaces/cart';
Expand Down Expand Up @@ -58,7 +65,7 @@ function App() {

getCustomerById(customerId)
.then((res) => {
console.log(res.data);
// console.log(res.data);

return setCustomer(res.data);
})
Expand All @@ -67,6 +74,31 @@ function App() {
}
}, [cookies]);

const ProtectedRoute = ({
isAllowed,
redirectPath = `/login`,
children,
}: {
isAllowed: boolean;
redirectPath?: string;
children?: React.ReactNode;
}) => {
const prevLocation = useLocation();

// FIXME: Not a good approach, as usertoken is not verified.
// Need to click twice
if (!isAllowed && !cookies['usertoken']) {
return (
<Navigate
to={`${redirectPath}?redirectTo=${prevLocation.pathname}`}
replace
/>
);
}

return children ? children : <Outlet />;
};

return (
<>
<BrowserRouter>
Expand All @@ -83,38 +115,19 @@ function App() {
/>
}
>
{/* Public */}
<Route index element={<Home />} />
<Route path="books" element={<Books />} />
<Route
path="books/:bookId"
element={
<BookDetails
customer={customer}
cartItems={cartItems}
setCartItems={setCartItems}
/>
}
/>
<Route
path="checkout"
element={
<Checkout
cartItems={cartItems}
setCartItems={setCartItems}
customer={customer}
/>
}
/>
<Route path="account" element={<Account customer={customer} />} />
<Route
path="borrowings"
element={<Borrowings customer={customer} />}
/>
<Route
path="borrowings/:borrowingId"
element={<BorrowingDetails />}
/>
<Route path="about" element={<About />} />
<Route path="admin" element={<Admin />} />
<Route
path="login"
element={
Expand All @@ -131,6 +144,31 @@ function App() {
<SignUp alertCompProps={alertCompProps} setCookie={setCookie} />
}
/>
<Route path="about" element={<About />} />

{/* Private */}
<Route path="account" element={<Account customer={customer} />} />
<Route
path="checkout"
element={
<Checkout
cartItems={cartItems}
setCartItems={setCartItems}
customer={customer}
/>
}
/>
<Route element={<ProtectedRoute isAllowed={!!customer._id} />}>
<Route
path="borrowings"
element={<Borrowings customer={customer} />}
/>
<Route
path="borrowings/:borrowingId"
element={<BorrowingDetails />}
/>
</Route>
<Route path="admin" element={<Admin />} />
</Route>
</Routes>
</BrowserRouter>
Expand Down
11 changes: 10 additions & 1 deletion apps/ui/src/pages/BookDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,26 @@ import {
Typography,
} from '@mui/material';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import { getBookById } from '../api/book-api';
import { IBook } from '../interfaces/book';
import sampleBook from '/sample-book.webp';
import { ICart } from '../interfaces/cart';
import AlertComp from '../components/Alert';
import { Link as RouterLink } from 'react-router-dom';
import { ICustomer } from '../interfaces/customer';

interface IProps {
customer: ICustomer;
cartItems: ICart[];
setCartItems: (array: ICart[]) => void;
}

function BookDetails(props: IProps) {
const { bookId } = useParams();
const [snackOpen, setSnackOpen] = useState(false);
const navigate = useNavigate();
const prevLocation = useLocation();

if (!bookId) throw Error();

Expand All @@ -39,6 +43,11 @@ function BookDetails(props: IProps) {
});

function addToCart(bookId: string, bookTitle: string) {
if (!props.customer?._id) {
// navigate('/login');
// console.log(prevLocation);
navigate(`/login?redirectTo=${prevLocation.pathname}`);
}
const book = props.cartItems.find((item) => item.book_id === bookId);
if (book) {
book.quantity++;
Expand Down
13 changes: 11 additions & 2 deletions apps/ui/src/pages/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { createTheme, ThemeProvider } from '@mui/material/styles';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import { useNavigate, useLocation } from 'react-router-dom';
import { CookieSetOptions } from 'universal-cookie';
import { login } from '../api/auth-api';
import queryString from 'query-string';
import { Link as RouterLink } from 'react-router-dom';

// TODO remove, this demo shouldn't need to reset the theme.
Expand All @@ -35,6 +36,7 @@ export default function Login({
const [error, setError] = React.useState(false);
const [loading, setLoading] = React.useState(false);
const navigate = useNavigate();
const location = useLocation();

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
Expand All @@ -51,8 +53,15 @@ export default function Login({
const name = res.data?.name;

// console.log(token);

setCookie('usertoken', token);
navigate('/');
const { redirectTo } = queryString.parse(location.search);
console.log(location);

console.log(redirectTo);

navigate(redirectTo == null ? '/' : String(redirectTo));
console.log('done navigate');

setAlertMessage(`Welcome back ${name}!`);
setAlertOpen(true);
Expand Down
47 changes: 47 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 725a4b6

Please sign in to comment.