This is an automated email from the ASF dual-hosted git repository. dimuthuupe pushed a commit to branch cybershuttle-staging in repository https://gitbox.apache.org/repos/asf/airavata.git
commit ab6eaae418b31884bf055cd45b25c12e89f99a67 Author: ganning127 <[email protected]> AuthorDate: Sat Apr 5 02:44:01 2025 -0400 Support logout --- modules/research-framework/portal/src/App.tsx | 4 +- .../portal/src/components/auth/Login.tsx | 17 ++++++- .../src/components/auth/ProtectedComponent.tsx | 2 +- .../portal/src/components/auth/UserMenu.tsx | 55 ++++++++++++++++++++++ .../portal/src/layouts/NavBar.tsx | 13 +---- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/modules/research-framework/portal/src/App.tsx b/modules/research-framework/portal/src/App.tsx index ebeb14af3b..23694017ce 100644 --- a/modules/research-framework/portal/src/App.tsx +++ b/modules/research-framework/portal/src/App.tsx @@ -63,7 +63,9 @@ function App() { <Routes> {/* Public Route */} - <Route path="/" element={<Login />} /> + <Route element={<NavBarFooterLayout />}> + <Route path="/login" element={<Login />} /> + </Route> {/* Protected Routes with Layout */} <Route diff --git a/modules/research-framework/portal/src/components/auth/Login.tsx b/modules/research-framework/portal/src/components/auth/Login.tsx index 545fb3eeff..b338bacb01 100644 --- a/modules/research-framework/portal/src/components/auth/Login.tsx +++ b/modules/research-framework/portal/src/components/auth/Login.tsx @@ -1,9 +1,18 @@ import { Center, Text, Button, Image, VStack, Stack } from "@chakra-ui/react"; import { useAuth } from "react-oidc-context"; import AirvataLogo from "../../assets/airavata-logo.png"; +import { useEffect } from "react"; export const Login = () => { const auth = useAuth(); + + // Automatically login the user if they are authenticated + useEffect(() => { + if (auth.isAuthenticated && !auth.isLoading) { + auth.signinRedirect(); + } + }, [auth]); + return ( <Center height="100vh"> <Stack @@ -28,7 +37,13 @@ export const Login = () => { w="300px" onClick={() => { console.log("Sign in clicked"); - auth.signinRedirect(); + auth.signinRedirect({ + extraQueryParams: { + // This is the prompt that will be shown to the user + prompt: "login", + kc_idp_hint: "oidc", + }, + }); }} > Institution Login diff --git a/modules/research-framework/portal/src/components/auth/ProtectedComponent.tsx b/modules/research-framework/portal/src/components/auth/ProtectedComponent.tsx index e4b9160992..ecbf1feb66 100644 --- a/modules/research-framework/portal/src/components/auth/ProtectedComponent.tsx +++ b/modules/research-framework/portal/src/components/auth/ProtectedComponent.tsx @@ -10,7 +10,7 @@ function ProtectedComponent({ Component }: { Component: React.FC }) { } if (!auth.isAuthenticated) { - navigate("/"); + navigate("/login"); return; } diff --git a/modules/research-framework/portal/src/components/auth/UserMenu.tsx b/modules/research-framework/portal/src/components/auth/UserMenu.tsx new file mode 100644 index 0000000000..b929659908 --- /dev/null +++ b/modules/research-framework/portal/src/components/auth/UserMenu.tsx @@ -0,0 +1,55 @@ +import { Avatar, Box, HStack, Text, Menu, Portal } from "@chakra-ui/react"; +import { useAuth } from "react-oidc-context"; + +export const UserMenu = () => { + const auth = useAuth(); + + if (auth.isLoading || !auth.user) return null; + + const handleLogout = async () => { + await auth.signoutRedirect(); + }; + + return ( + <Menu.Root> + <Menu.Trigger asChild> + <HStack + gap={3} + p={1} + rounded="md" + as="button" + cursor="pointer" + transition="all .2s" + _hover={{ bg: "gray.200" }} + > + <Avatar.Root variant="subtle"> + <Avatar.Fallback name={auth.user?.profile.name} /> + </Avatar.Root> + <Box textAlign="left"> + <Text fontSize="sm">{auth.user?.profile.name}</Text> + <Text fontSize="xs" color="gray.500"> + {auth.user?.profile.email} + </Text> + </Box> + </HStack> + </Menu.Trigger> + + <Portal> + <Menu.Positioner> + <Menu.Content> + <Menu.Item + value="logout" + onClick={handleLogout} + _hover={{ + cursor: "pointer", + }} + > + Logout + </Menu.Item> + </Menu.Content> + <Menu.Arrow /> + </Menu.Positioner> + </Portal> + </Menu.Root> + ); +}; diff --git a/modules/research-framework/portal/src/layouts/NavBar.tsx b/modules/research-framework/portal/src/layouts/NavBar.tsx index be483f7f41..43090c1841 100644 --- a/modules/research-framework/portal/src/layouts/NavBar.tsx +++ b/modules/research-framework/portal/src/layouts/NavBar.tsx @@ -18,6 +18,7 @@ import { Link, useNavigate } from "react-router"; import { useAuth } from "react-oidc-context"; import { RxHamburgerMenu } from "react-icons/rx"; import { IoClose } from "react-icons/io5"; +import { UserMenu } from "@/components/auth/UserMenu"; const NAV_CONTENT = [ { @@ -98,17 +99,7 @@ const NavBar = () => { <Spacer /> {/* User Profile */} - <HStack gap={3}> - <Avatar.Root variant="subtle"> - <Avatar.Fallback name={auth.user?.profile.name} /> - </Avatar.Root> - <Box textAlign="left"> - <Text fontSize="sm">{auth.user?.profile.name}</Text> - <Text fontSize="xs" color="gray.500"> - {auth.user?.profile.email} - </Text> - </Box> - </HStack> + <UserMenu /> </Flex> {/* Mobile Nav Links (Collapse) */}
