From d0ccc20a1c1ad669281c3eb46ac3b4735eb0983b Mon Sep 17 00:00:00 2001 From: David Arranz Date: Thu, 6 Jun 2024 23:07:40 +0200 Subject: [PATCH] . --- client/src/Routes.tsx | 32 ++- .../ProtectedRoute/ProtectedRoute.tsx | 32 +-- client/src/components/UeckoLogo/UeckoLogo.tsx | 10 +- client/src/lib/hooks/useAuth/useLogout.tsx | 35 +++ .../src/pages/DashboardPage/DashboardPage.tsx | 232 ++++++++++++++++++ client/src/pages/DashboardPage/index.ts | 1 + client/src/pages/ErrorPage.tsx | 9 +- client/src/pages/LoginPage.tsx | 6 +- client/src/pages/LogoutPage.tsx | 13 + client/src/pages/index.ts | 4 + 10 files changed, 335 insertions(+), 39 deletions(-) create mode 100644 client/src/lib/hooks/useAuth/useLogout.tsx create mode 100644 client/src/pages/DashboardPage/DashboardPage.tsx create mode 100644 client/src/pages/DashboardPage/index.ts create mode 100644 client/src/pages/LogoutPage.tsx create mode 100644 client/src/pages/index.ts diff --git a/client/src/Routes.tsx b/client/src/Routes.tsx index 5591968..15dd2c0 100644 --- a/client/src/Routes.tsx +++ b/client/src/Routes.tsx @@ -1,11 +1,9 @@ import { RouterProvider, createBrowserRouter } from "react-router-dom"; import { ProtectedRoute } from "./components"; -import { AuthContextState, useAuth } from "./lib/hooks"; +import { DashboardPage, LogoutPage } from "./pages"; import { LoginPage } from "./pages/LoginPage"; export const Routes = () => { - const { isLoggedIn } = useAuth() as AuthContextState; - // Define public routes accessible to all users const routesForPublic = [ { @@ -20,6 +18,22 @@ export const Routes = () => { // Define routes accessible only to authenticated users const routesForAuthenticatedOnly = [ + { + path: "/profile", + element: ( + +

Profile

+
+ ), + }, + { + path: "/logout", + element: ( + + + + ), + }, { path: "/admin", element: , // Wrap the component in ProtectedRoute @@ -28,14 +42,6 @@ export const Routes = () => { path: "", element:
Dashboard
, }, - { - path: "profile", - element:
User Profile
, - }, - { - path: "logout", - element:
Logout
, - }, ], }, ]; @@ -44,7 +50,7 @@ export const Routes = () => { const routesForNotAuthenticatedOnly = [ { path: "/", - element:
Home Page
, + Component: DashboardPage, }, { path: "/login", @@ -55,7 +61,7 @@ export const Routes = () => { // Combine and conditionally include routes based on authentication status const router = createBrowserRouter([ ...routesForPublic, - ...(!isLoggedIn ? routesForNotAuthenticatedOnly : []), + ...routesForNotAuthenticatedOnly, ...routesForAuthenticatedOnly, ]); diff --git a/client/src/components/ProtectedRoute/ProtectedRoute.tsx b/client/src/components/ProtectedRoute/ProtectedRoute.tsx index baf00a5..bc4a897 100644 --- a/client/src/components/ProtectedRoute/ProtectedRoute.tsx +++ b/client/src/components/ProtectedRoute/ProtectedRoute.tsx @@ -1,28 +1,30 @@ import { useIsLoggedIn } from "@/lib/hooks"; import React from "react"; import { Navigate } from "react-router-dom"; +import { LoadingOverlay } from "../LoadingOverlay"; type ProctectRouteProps = { children?: React.ReactNode; }; export const ProtectedRoute = ({ children }: ProctectRouteProps) => { - const { isSuccess, data } = useIsLoggedIn(); + const { isPending, isSuccess, data: { authenticated, redirectTo } = {} } = useIsLoggedIn(); - if (isSuccess && data) { - const { authenticated, redirectTo } = data; - if (authenticated) { - return ( - - ); - } + if (isPending) { + return ; } - return children; + if (isSuccess && !authenticated) { + return ( + + ); + } + + return <>{children ?? null}; }; diff --git a/client/src/components/UeckoLogo/UeckoLogo.tsx b/client/src/components/UeckoLogo/UeckoLogo.tsx index bfb77d4..806c70c 100644 --- a/client/src/components/UeckoLogo/UeckoLogo.tsx +++ b/client/src/components/UeckoLogo/UeckoLogo.tsx @@ -1,5 +1,11 @@ -export const UeckoLogo = ({ className }: { className: string }) => ( - +export const UeckoLogo = ({ className, ...props }: { className: string }) => ( + ) => { + const { onSuccess, onError, ...restParams } = params || {}; + const keys = useQueryKey(); + const { logout } = useAuth(); + const navigate = useNavigate(); + + return useMutation({ + mutationKey: keys().auth().action("logout").get(), + mutationFn: logout, + onSuccess: async (data, variables, context) => { + const { success, redirectTo } = data; + if (success && redirectTo) { + navigate(redirectTo); + } + if (onSuccess) { + onSuccess(data, variables, context); + } + }, + onError: (error, variables, context) => { + const { message } = error; + toast.error(message); + + if (onError) { + onError(error, variables, context); + } + }, + ...restParams, + }); +}; diff --git a/client/src/pages/DashboardPage/DashboardPage.tsx b/client/src/pages/DashboardPage/DashboardPage.tsx new file mode 100644 index 0000000..a5c32e8 --- /dev/null +++ b/client/src/pages/DashboardPage/DashboardPage.tsx @@ -0,0 +1,232 @@ +import { CircleUser, LogOutIcon, Menu, Package2Icon, Search, UserIcon } from "lucide-react"; + +import { + Button, + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, + Checkbox, + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, + Input, + Sheet, + SheetContent, + SheetTrigger, +} from "@/ui"; + +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/ui"; + +import { UeckoLogo } from "@/components/UeckoLogo/UeckoLogo"; +import { SyntheticEvent, useState } from "react"; +import { Link } from "react-router-dom"; + +export const DashboardPage = () => { + const [logoutAlertVisible, setLogoutAlertVisible] = useState(false); + + const openLogoutAlert = (event: Event) => { + event.preventDefault(); + setLogoutAlertVisible(true); + return; + }; + + const closeLogoutAlert = (event: SyntheticEvent) => { + event.preventDefault(); + setLogoutAlertVisible(false); + return; + }; + + return ( +
+
+ + + + + + + + + +
+
+
+ + +
+
+ + + + + + My Account + + + + + Profile + ⇧⌘P + + Settings + Support + + + + + Log out + ⇧⌘Q + + + +
+
+
+
+

Settings

+
+
+ +
+ + + Store Name + Used to identify your store in the marketplace. + + +
+ +
+
+ + + +
+ + + Plugins Directory + + The directory within your project, in which your plugins are located. + + + +
+ +
+ + +
+
+
+ + + +
+ + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your account and + remove your data from our servers. + + + + + + Cancel + + + + Continue + + + + +
+
+
+
+ ); +}; diff --git a/client/src/pages/DashboardPage/index.ts b/client/src/pages/DashboardPage/index.ts new file mode 100644 index 0000000..353b584 --- /dev/null +++ b/client/src/pages/DashboardPage/index.ts @@ -0,0 +1 @@ +export * from "./DashboardPage"; diff --git a/client/src/pages/ErrorPage.tsx b/client/src/pages/ErrorPage.tsx index e3d910e..c910633 100644 --- a/client/src/pages/ErrorPage.tsx +++ b/client/src/pages/ErrorPage.tsx @@ -1,12 +1,11 @@ -// - - - - - ErrorPage.tsx - - - - - import { Button } from "@/ui"; import { useLocation, useNavigate } from "react-router-dom"; // import Button -const isDev = process.env.REACT_APP_NODE_ENV === "development"; +/*const isDev = process.env.REACT_APP_NODE_ENV === "development"; const hostname = `${ isDev ? process.env.REACT_APP_DEV_API_URL : process.env.REACT_APP_PROD_API_URL -}`; +}`;*/ type ErrorPageProps = { error?: string; @@ -39,8 +38,8 @@ export const ErrorPage = (props: ErrorPageProps) => {