Skip to content

Commit

Permalink
Merge pull request #24 from acm-uiuc/dsingh14/ui-up2
Browse files Browse the repository at this point in the history
functional profile designer
  • Loading branch information
devksingh4 authored Jul 13, 2024
2 parents 703e7a7 + f96a9b3 commit a6fdd1b
Show file tree
Hide file tree
Showing 17 changed files with 899 additions and 161 deletions.
1 change: 1 addition & 0 deletions clientv2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@kinde-oss/kinde-auth-react": "^4.0.1",
"@mantine/core": "7.11.1",
"@mantine/hooks": "7.11.1",
"@mantine/notifications": "^7.11.1",
"@tabler/icons-react": "^3.10.0",
"axios": "^1.7.2",
"dotenv": "^16.4.5",
Expand Down
3 changes: 3 additions & 0 deletions clientv2/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import { MantineProvider } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import { Router } from './Router';
import { theme } from './theme';

export default function App() {
return (
<MantineProvider theme={theme}>
<Notifications position="top-right" />
<Router />
</MantineProvider>
);
Expand Down
12 changes: 10 additions & 2 deletions clientv2/src/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom';
import { AuthRoleEnum, useAuth } from './components/AuthContext';
import { LoginPage } from './pages/Login.page';
import { StudentHomePage } from './pages/student/StudentHome.page';
import { StudentHomePage } from './pages/student/StudentProfile.page';
import { RecruiterHomePage } from './pages/recruiter/RecruiterHome.page';

const unauthenticatedRouter = createBrowserRouter([
Expand All @@ -13,6 +13,10 @@ const unauthenticatedRouter = createBrowserRouter([
path: '/login',
element: <LoginPage />,
},
{
path: '/profile',
element: <Navigate to="/login" replace />,
},
]);

const recruiterRouter = createBrowserRouter([
Expand All @@ -29,12 +33,16 @@ const recruiterRouter = createBrowserRouter([
const studentRouter = createBrowserRouter([
{
path: '/',
element: <StudentHomePage />,
element: <Navigate to="/profile" replace />,
},
{
path: '/login',
element: <Navigate to="/" replace />,
},
{
path: '/profile',
element: <StudentHomePage />,
},
]);

export function Router() {
Expand Down
32 changes: 18 additions & 14 deletions clientv2/src/components/AuthContext/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { createContext, ReactNode, useContext, useState, useEffect } from 'react';
import { useMsal } from '@azure/msal-react';
import { useKindeAuth } from '@kinde-oss/kinde-auth-react';
import { AuthenticationResult, InteractionRequiredAuthError, InteractionStatus } from '@azure/msal-browser';
import {
AuthenticationResult,
InteractionRequiredAuthError,
InteractionStatus,
} from '@azure/msal-browser';
import { MantineProvider } from '@mantine/core';
import FullScreenLoader from './LoadingScreen';

Expand Down Expand Up @@ -57,19 +61,19 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
user,
logout: kindeLogout,
getToken: getKindeToken,
getPermission: getKindePermission
getPermission: getKindePermission,
} = useKindeAuth();

const [userData, setUserData] = useState<AuthContextData | null>(null);
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(
(isAuthenticated || accounts.length > 0) && !isLoading
);
if (isAuthenticated && !isLoading && !userData) {
const isRecruiter = getKindePermission("recruiter:resume-book").isGranted;
const isRecruiter = getKindePermission('recruiter:resume-book').isGranted;
if (!isRecruiter) {
setUserData(null);
setIsLoggedIn(false);
window.location.href = "/";
window.location.href = '/';
} else {
setUserData({
email: user?.email!,
Expand All @@ -79,7 +83,6 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
});
setIsLoggedIn(true);
}

}

useEffect(() => {
Expand All @@ -89,9 +92,10 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
handleMsalResponse(response);
} else if (accounts.length > 0) {
// User is already logged in, set the state
const [lastName, firstName] = accounts[0].name?.split(",")!
setUserData({
email: accounts[0].username,
name: accounts[0].name,
name: `${firstName} ${lastName}`,
authenticationMethod: AuthSourceEnum.MSAL,
role: AuthRoleEnum.STUDENT,
});
Expand Down Expand Up @@ -125,25 +129,25 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
}
if (userData?.authenticationMethod === AuthSourceEnum.MSAL) {
try {
const accounts = instance.getAllAccounts();
if (accounts.length > 0) {
const msalAccounts = instance.getAllAccounts();
if (msalAccounts.length > 0) {
const silentRequest = {
account: accounts[0],
scopes: [".default"], // Adjust scopes as needed
account: msalAccounts[0],
scopes: ['.default'], // Adjust scopes as needed
};
const tokenResponse = await instance.acquireTokenSilent(silentRequest);
return tokenResponse.accessToken;
} else {
throw new Error('No accounts found.');
throw new Error("More than one account found, cannot proceed.")
}
} catch (error) {
console.error('Silent token acquisition failed.', error);
if (error instanceof InteractionRequiredAuthError) {
// Fallback to interaction when silent token acquisition fails
try {
const interactiveRequest = {
scopes: [".default"], // Adjust scopes as needed
redirectUri: "/login", // Redirect URI after login
scopes: ['.default'], // Adjust scopes as needed
redirectUri: '/login', // Redirect URI after login
};
const tokenResponse: any = await instance.acquireTokenRedirect(interactiveRequest);
return tokenResponse.accessToken;
Expand All @@ -161,7 +165,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
}
throw new Error('Unknown authentication method.');
};

const loginMsal = () => {
instance.loginRedirect();
};
Expand Down
26 changes: 26 additions & 0 deletions clientv2/src/components/FullPageError/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { MouseEventHandler } from 'react';
import { Container, Paper, Title, Text, Button } from '@mantine/core';

interface FullPageErrorProps {
errorCode?: number;
errorMessage?: string;
onRetry?: MouseEventHandler<HTMLButtonElement>;
}

const FullPageError: React.FC<FullPageErrorProps> = ({ errorCode, errorMessage, onRetry }) => (
<Container>
<Paper shadow="md" radius="md">
<Title>{errorCode || 'An error occurred'}</Title>
<Text color="dimmed">
{errorMessage || 'Something went wrong. Please try again later.'}
</Text>
{onRetry && (
<Button variant="outline" onClick={onRetry}>
Retry
</Button>
)}
</Paper>
</Container>
);

export default FullPageError;
21 changes: 15 additions & 6 deletions clientv2/src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@ import { Group, Divider, Box, Burger, Drawer, ScrollArea, rem, Badge } from '@ma
import { useDisclosure } from '@mantine/hooks';
import classes from './index.module.css';
import LogoBadge from './Logo';
import { AuthContextData, AuthSourceEnum } from '../AuthContext';
import { AuthContextData, AuthRoleEnum, AuthSourceEnum } from '../AuthContext';
import { AuthenticatedProfileDropdown } from '../ProfileDropdown';

interface HeaderNavbarProps {
userData?: AuthContextData | null;
}

const isActiveLink = (path: string) => location.pathname === path;

const HeaderNavbar: React.FC<HeaderNavbarProps> = ({ userData }) => {
const [drawerOpened, { toggle: toggleDrawer, close: closeDrawer }] = useDisclosure(false);
let badge = null;
if (userData?.authenticationMethod === AuthSourceEnum.LOCAL) {
if (userData?.role === AuthRoleEnum.RECRUITER) {
badge = (
<Badge color="blue" style={{ marginLeft: 10 }}>
Recruiter
</Badge>
);
} else if (userData?.authenticationMethod === AuthSourceEnum.MSAL) {
} else if (userData?.role === AuthRoleEnum.STUDENT) {
badge = (
<Badge color="#FF5F05" style={{ marginLeft: 10 }}>
Student
Expand All @@ -34,9 +36,16 @@ const HeaderNavbar: React.FC<HeaderNavbarProps> = ({ userData }) => {
<Group justify="start" h="100%" gap={10}>
<LogoBadge />
{badge}
<a href="/" className={classes.link}>
Home
</a>
{userData?.role !== AuthRoleEnum.STUDENT ? (
<a href="/" className={classes.link}>
Home
</a>
) : null}
{userData?.role === AuthRoleEnum.STUDENT ? (
<a href="/profile" className={classes.link}>
My Profile
</a>
) : null}
</Group>
<Group h="100%" justify="end" gap={10} visibleFrom="sm">
{userData ? <AuthenticatedProfileDropdown userData={userData} /> : null}
Expand Down
4 changes: 2 additions & 2 deletions clientv2/src/components/ProfileDropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const AuthenticatedProfileDropdown: React.FC<ProfileDropdownProps> = ({ userData
>
<Center inline>
<Box component="span" mr={5}>
Profile
My Account
</Box>
<IconChevronDown
style={{ width: rem(16), height: rem(16) }}
Expand All @@ -57,7 +57,7 @@ const AuthenticatedProfileDropdown: React.FC<ProfileDropdownProps> = ({ userData
</a>
</Popover.Target>

<Popover.Dropdown style={{ overflow: 'hidden' }} aria-label="Authenticated Profile Dropdown">
<Popover.Dropdown style={{ overflow: 'hidden' }} aria-label="Authenticated My Account Dropdown">
<SimpleGrid cols={1} spacing={0}>
<UnstyledButton className={classes.subLink} key="name">
<Group wrap="nowrap" align="flex-start">
Expand Down
Loading

0 comments on commit a6fdd1b

Please sign in to comment.