From 17e7370830300761b58255f80fd94976c88634ae Mon Sep 17 00:00:00 2001 From: Kapil Kumar Date: Sat, 4 May 2024 09:12:35 +0530 Subject: [PATCH] 1) Added axios instance 2) Fixed logout functionality 3) proper navigation for navItems instead of realoding page 4) Minor refactoring --- apps/backend/src/router/auth.ts | 5 +- apps/frontend/package.json | 1 + apps/frontend/src/App.tsx | 12 +---- .../src/components/constants/side-nav.tsx | 20 ++----- apps/frontend/src/components/side-nav.tsx | 49 ++++++++++++----- apps/frontend/src/constants/endpoints.ts | 3 ++ apps/frontend/src/constants/routes.ts | 4 ++ apps/frontend/src/hooks/useSocket.ts | 3 +- apps/frontend/src/lib/api.ts | 13 +++++ apps/frontend/src/screens/Game.tsx | 26 ++++----- apps/frontend/src/screens/Login.tsx | 4 +- apps/ws/src/SocketManager.ts | 11 ++-- packages/store/src/atoms/user.ts | 2 +- yarn.lock | 54 +++++++++++++++++-- 14 files changed, 136 insertions(+), 71 deletions(-) create mode 100644 apps/frontend/src/constants/endpoints.ts create mode 100644 apps/frontend/src/constants/routes.ts create mode 100644 apps/frontend/src/lib/api.ts diff --git a/apps/backend/src/router/auth.ts b/apps/backend/src/router/auth.ts index ad328713..7e945a2e 100644 --- a/apps/backend/src/router/auth.ts +++ b/apps/backend/src/router/auth.ts @@ -47,7 +47,10 @@ router.get('/logout', (req: Request, res: Response) => { res.status(500).json({ error: 'Failed to log out' }); } else { res.clearCookie('jwt'); - res.redirect('http://localhost:5173/'); + res.json({ + message: 'Logged Out!', + success: true, + }); } }); }); diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 51d2eef1..54b7c735 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-slot": "^1.0.2", "@repo/store": "*", "@repo/ui": "*", + "axios": "^1.6.8", "chess.js": "^1.0.0-beta.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", diff --git a/apps/frontend/src/App.tsx b/apps/frontend/src/App.tsx index e0a1abfa..8e421b77 100644 --- a/apps/frontend/src/App.tsx +++ b/apps/frontend/src/App.tsx @@ -5,7 +5,6 @@ import { Game } from './screens/Game'; import Login from './screens/Login'; import { Suspense } from 'react'; import { RecoilRoot } from 'recoil'; -import { useUser } from '@repo/store/useUser'; import { Loader } from './components/Loader'; import { Layout } from './layout'; @@ -22,19 +21,12 @@ function App() { } function AuthApp() { - const user = useUser(); return ( } />} /> - } - /> - } />} - /> + } /> + } />} /> ); diff --git a/apps/frontend/src/components/constants/side-nav.tsx b/apps/frontend/src/components/constants/side-nav.tsx index c7686baa..df9d7bae 100644 --- a/apps/frontend/src/components/constants/side-nav.tsx +++ b/apps/frontend/src/components/constants/side-nav.tsx @@ -1,6 +1,6 @@ +import { logout } from '@/services/auth'; import { PuzzleIcon, LogInIcon, LogOutIcon, SettingsIcon } from 'lucide-react'; -const BACKEND_URL = - import.meta.env.VITE_APP_BACKEND_URL ?? 'http://localhost:3000'; + export const UpperNavItems = [ { title: 'Play', @@ -8,19 +8,6 @@ export const UpperNavItems = [ href: '/game/random', color: 'text-green-500', }, - // - // { - // title: 'Puzzles', - // icon: PuzzleIcon, - // href: '/', - // color: 'text-sky-500', - // }, - // { - // title: 'Learn', - // icon: PuzzleIcon, - // href: '/', - // color: 'text-sky-500', - // }, ]; export const LowerNavItems = [ @@ -33,8 +20,9 @@ export const LowerNavItems = [ { title: 'Logout', icon: LogOutIcon, - href: `${BACKEND_URL}/logout`, + href: '/logout', color: 'text-green-500', + action: 'logout', }, { title: 'Settings', diff --git a/apps/frontend/src/components/side-nav.tsx b/apps/frontend/src/components/side-nav.tsx index 846b1c4d..8b8c6acd 100644 --- a/apps/frontend/src/components/side-nav.tsx +++ b/apps/frontend/src/components/side-nav.tsx @@ -1,25 +1,29 @@ import { cn } from '@/lib/utils'; import { useSidebar } from '@/hooks/useSidebar'; import { buttonVariants } from '@/components/ui/button'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from '@/components/subnav-accordian'; -import { useEffect, useState } from 'react'; +import { SyntheticEvent, useEffect, useState } from 'react'; import { ChevronDownIcon } from '@radix-ui/react-icons'; import { type LucideIcon } from 'lucide-react'; -import { useUser } from '@repo/store/useUser'; +import { api } from '@/lib/api'; +import { useRecoilState } from 'recoil'; +import { userAtom } from '../../../../packages/store/src/atoms/user'; +import { LANDING_PAGE } from '@/constants/routes'; export interface NavItem { title: string; - href: string; + href?: string; icon: LucideIcon; color?: string; isChidren?: boolean; children?: NavItem[]; + action?: string; } interface SideNavProps { @@ -29,7 +33,8 @@ interface SideNavProps { } export function SideNav({ items, setOpen, className }: SideNavProps) { - const user = useUser(); + const [user, setUser] = useRecoilState(userAtom); + const navigate = useNavigate(); const location = useLocation(); const { isOpen } = useSidebar(); const [openItem, setOpenItem] = useState(''); @@ -44,6 +49,30 @@ export function SideNav({ items, setOpen, className }: SideNavProps) { } }, [isOpen]); + const handleLogout = async () => { + await api.get('/auth/logout/'); + // Perform Cleanup + setUser(null); + navigate(LANDING_PAGE); + }; + + const executeAction = (action: string) => { + switch (action) { + case 'logout': + handleLogout(); + break; + default: + console.error('Invalid Action Identifier'); + } + }; + + const handleNavItemClick = (event: SyntheticEvent, navItem: NavItem) => { + event.preventDefault(); + if (setOpen) setOpen(false); + if (navItem.action) executeAction(navItem.action); + else if (navItem.href) navigate(navItem.href); + }; + return (