Commit 8e77dc13 authored by Pavel Mishakov's avatar Pavel Mishakov

94 done FRONT

parent f6961248
...@@ -8,6 +8,8 @@ import PrivateRoute from "./utils/PrivateRoute"; ...@@ -8,6 +8,8 @@ import PrivateRoute from "./utils/PrivateRoute";
import UserForm from "./components/UserForm/UserForm"; import UserForm from "./components/UserForm/UserForm";
import ForgotPasswordForm from "./components/ForgotPasswordForm/ForgotPasswordForm"; import ForgotPasswordForm from "./components/ForgotPasswordForm/ForgotPasswordForm";
import ResetPasswordForm from "./components/ResetPasswordForm/ResetPasswordForm"; import ResetPasswordForm from "./components/ResetPasswordForm/ResetPasswordForm";
import PermissionRoute from "./utils/PermissionRoute";
import { ERoles } from "./enums/ERoles";
const App = () => { const App = () => {
return ( return (
...@@ -16,8 +18,12 @@ const App = () => { ...@@ -16,8 +18,12 @@ const App = () => {
<Route element={<Layout />} > <Route element={<Layout />} >
<Route path={"/"} element={<h1>HOME</h1>} /> <Route path={"/"} element={<h1>HOME</h1>} />
<Route path={"/products"} element={<ProductsPage />} /> <Route path={"/products"} element={<ProductsPage />} />
<Route path={"/add-product"} element={<ProductFormPage />} /> <Route element={<PermissionRoute roles={[ERoles.SUPER_ADMIN]} />}>
<Route path={"/edit-user"} element={<UserForm />} /> <Route path={"/add-product"} element={<ProductFormPage />} />
</Route>
<Route element={<PermissionRoute roles={[ERoles.ADMIN]} />}>
<Route path={"/edit-user"} element={<UserForm />} />
</Route>
</Route> </Route>
</Route> </Route>
<Route path={"/login"} element={<Login />} /> <Route path={"/login"} element={<Login />} />
......
...@@ -19,12 +19,15 @@ const Header: FunctionComponent = (): ReactElement => { ...@@ -19,12 +19,15 @@ const Header: FunctionComponent = (): ReactElement => {
<NavLink className={styles.Header__link} to={"/add-product"}> <NavLink className={styles.Header__link} to={"/add-product"}>
Add product Add product
</NavLink> </NavLink>
<NavLink className={styles.Header__link} to={"/products"}> <NavLink className={styles.Header__link} to={"/products"}>
Products Products
</NavLink> </NavLink>
<NavLink className={styles.Header__link} to={"/edit-user"}> <NavLink className={styles.Header__link} to={"/edit-user"}>
Edit user Edit user
</NavLink> </NavLink>
<div> <div>
{user?.username} {user?.username}
</div> </div>
......
...@@ -5,6 +5,8 @@ import defaultImage from '../../assets/images/default.jpg' ...@@ -5,6 +5,8 @@ import defaultImage from '../../assets/images/default.jpg'
import { AppDispatch } from "../../store/store"; import { AppDispatch } from "../../store/store";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { deleteProductById } from "../../store/products/products.slice"; import { deleteProductById } from "../../store/products/products.slice";
import Button from "../UI/Button/Button";
import { ERoles } from "../../enums/ERoles";
const ProductItem: FunctionComponent<IProductItemProps> = (props): ReactElement => { const ProductItem: FunctionComponent<IProductItemProps> = (props): ReactElement => {
const dispatch: AppDispatch = useDispatch() const dispatch: AppDispatch = useDispatch()
...@@ -58,9 +60,17 @@ const ProductItem: FunctionComponent<IProductItemProps> = (props): ReactElement ...@@ -58,9 +60,17 @@ const ProductItem: FunctionComponent<IProductItemProps> = (props): ReactElement
<p>{props.product.price}</p> <p>{props.product.price}</p>
<div className={styles.ProductItem__btnBlock}> <div className={styles.ProductItem__btnBlock}>
<button>Details</button> <Button
<button>Edit</button> title={'Details'}
<button onClick={deleteHandler}>Delete</button> />
<Button
title={'Edit'}
/>
<Button
title={'Delete'}
click={deleteHandler}
roles={[ERoles.SUPER_ADMIN]}
/>
</div> </div>
</div> </div>
) )
......
import React, { useContext } from 'react'
import IButtonProps from './IButtonProps'
import { UserContext } from '../../../utils/PrivateRoute'
import { ERoles } from '../../../enums/ERoles'
const Button: React.FunctionComponent<IButtonProps> = (props): React.ReactElement => {
const role = useContext(UserContext)
return (
!props.roles || role && props.roles.includes(role) ?
<button onClick={props.click}>{props.title}</button>
: <></>
)
}
export default Button
\ No newline at end of file
import { MouseEventHandler } from "react"
import { ERoles } from "../../../enums/ERoles"
export default interface IButtonProps {
title: string
click?: MouseEventHandler<HTMLButtonElement>
roles?: ERoles[]
}
\ No newline at end of file
export enum ERoles {
ADMIN = 'ADMIN',
USER = 'USER',
SUPER_ADMIN = 'SUPER_ADMIN'
}
\ No newline at end of file
import { ERoles } from "../enums/ERoles"
export default interface IUser { export default interface IUser {
_id: string _id: string
username: string username: string
password: string password: string
active: boolean active: boolean
token: string token: string
role: string role: ERoles
} }
\ No newline at end of file
import React, { useEffect } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
import { Navigate, Outlet } from 'react-router-dom'
import { AppDispatch, AppState } from '../store/store'
import { checkToken } from '../store/users/users.slice'
const PermissionRoute: React.FunctionComponent<{roles: string[]}> = ({roles}): React.ReactElement => {
const {isAuth, user} = useSelector((state: AppState) => state.users, shallowEqual)
const dispatch: AppDispatch = useDispatch()
useEffect(() => {
dispatch(checkToken())
}, [])
return (
isAuth && user?.role && roles.includes(user?.role)
?
<Outlet />
:
<Navigate to='/' replace />
)
}
export default PermissionRoute
\ No newline at end of file
import React, { useEffect } from 'react' import React, { createContext, useEffect } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux' import { shallowEqual, useDispatch, useSelector } from 'react-redux'
import { Navigate, Outlet, useLocation } from 'react-router-dom' import { Navigate, Outlet, useLocation } from 'react-router-dom'
import { AppDispatch, AppState } from '../store/store' import { AppDispatch, AppState } from '../store/store'
import { checkToken } from '../store/users/users.slice' import { checkToken } from '../store/users/users.slice'
import { ERoles } from '../enums/ERoles'
export const UserContext = createContext<ERoles | undefined>(undefined)
const PrivateRoute: React.FunctionComponent = (): React.ReactElement => { const PrivateRoute: React.FunctionComponent = (): React.ReactElement => {
const {isAuth} = useSelector((state: AppState) => state.users, shallowEqual) const {isAuth, user} = useSelector((state: AppState) => state.users, shallowEqual)
const location = useLocation() const location = useLocation()
const dispatch: AppDispatch = useDispatch() const dispatch: AppDispatch = useDispatch()
useEffect(() => { useEffect(() => {
dispatch(checkToken()) dispatch(checkToken())
}, []) }, [])
return ( return (
isAuth isAuth
? ?
<Outlet /> <UserContext.Provider value={user?.role}><Outlet /></UserContext.Provider>
: :
<Navigate to='/login' replace state={{from: location}} /> <Navigate to='/login' replace state={{from: location}} />
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment