diff --git a/package.json b/package.json index 288e4c7..f9c1217 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,10 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.52.0", "react-hot-toast": "^2.4.1", + "react-jwt": "^1.2.1", "react-redux": "^9.1.2", "react-router-dom": "^6.23.1", + "react-spinners": "^0.13.8", "redux": "^5.0.1", "vitest": "^1.6.0" }, @@ -31,7 +33,7 @@ "@testing-library/jest-dom": "^6.4.5", "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", - "@types/node": "^20.14.2", + "@types/node": "^20.14.7", "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", "@typescript-eslint/eslint-plugin": "^7.2.0", diff --git a/src/Routes/Router.tsx b/src/Routes/Router.tsx index ce93939..b08b434 100644 --- a/src/Routes/Router.tsx +++ b/src/Routes/Router.tsx @@ -1,12 +1,24 @@ import React from 'react'; -import { Route, Routes } from 'react-router-dom'; +import { Navigate, Route, Routes } from 'react-router-dom'; import PageTitle from '../components/PageTitle'; import WelcomePage from '../pages/welcomePage'; import Register from '../pages/Authentication/Register'; import RegisterVendor from '../pages/Authentication/RegisterVendor'; import VerifyEmail from '../pages/Authentication/VerifyEmail'; +import Login, { DecodedToken } from '../pages/Authentication/Login'; +import { useSelector } from 'react-redux'; +import { RootState } from '../redux/store'; +import GoogleLoginSuccess from '../pages/Authentication/GoogleLoginSuccess'; +import { useJwt } from 'react-jwt'; const Router = () => { + const { userToken } = useSelector((state: RootState) => state.auth); + const { decodedToken } = useJwt(userToken); + + const isAdmin = decodedToken?.role.toLowerCase() === 'admin'; + const isVendor = decodedToken?.role.toLowerCase() === 'vendor'; + const isBuyer = decodedToken?.role.toLowerCase() === 'buyer'; + return ( } /> @@ -40,6 +52,30 @@ const Router = () => { } /> + + + {userToken && isAdmin && } + {userToken && isVendor && } + {userToken && isBuyer && } + {!userToken && } + + } + /> + + + {userToken && isAdmin && } + {userToken && isVendor && } + {userToken && isBuyer && } + {!userToken && } + + } + /> ); }; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 6243c82..c360aa3 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -9,7 +9,7 @@ function Footer() {
-

+

KNIGHTS STORE

@@ -42,24 +42,17 @@ function Footer() {

Address / Office

- -

- Kigali-Rwanda -

-

- Gasabo, Kimironko -

-

- Tel No: +250780288777 -

-

- Email: knights@andela.com -

+
+

Kigali-Rwanda

+

Gasabo, Kimironko

+

Tel No: +250780288777

+

Email: knights@andela.com

+

-

+

© {new Date().getFullYear()} Knights Store. All Rights Reserved.

diff --git a/src/components/Menu/DesktopMenu.tsx b/src/components/Menu/DesktopMenu.tsx new file mode 100644 index 0000000..1819e2b --- /dev/null +++ b/src/components/Menu/DesktopMenu.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { AppDispatch } from '../../redux/store'; +import { clearCredentials } from '../../redux/reducers/authReducer'; +import { useDispatch } from 'react-redux'; + +function DesktopMenu() { + const dispatch = useDispatch(); + + const logoutHandler = () => { + dispatch(clearCredentials('')); + }; + + return ( +
+
    +
  • WishList
  • +
  • Profile
  • +
  • + Logout +
  • +
+
+ ); +} + +export default DesktopMenu; diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 0ec8eea..b629fb1 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -1,39 +1,76 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Search } from 'lucide-react'; import knightsLogo from '../../images/logo.png'; import cart from '../../images/cart.png'; +import user from '../../images/user.png'; +import notificationBell from '../../images/bell.png'; +import { useSelector } from 'react-redux'; +import { RootState } from '../../redux/store'; +import { Link } from 'react-router-dom'; +import DesktopMenu from '../Menu/DesktopMenu'; function Navbar() { + const { userToken } = useSelector((state: RootState) => state.auth); + const [showDesktopMenu, setShowDesktopMenu] = useState(false); + + useEffect(() => { + setShowDesktopMenu(false); + }, [userToken]); + + const desktopMenuHandler = () => { + setShowDesktopMenu((prevData) => !prevData); + }; + return ( -