diff --git a/__tests__/components/navbar.test.jsx b/__tests__/components/navbar.test.jsx
index 33f684deb..81cb405a6 100644
--- a/__tests__/components/navbar.test.jsx
+++ b/__tests__/components/navbar.test.jsx
@@ -2,6 +2,7 @@ import Navbar from '../../components/navbar';
import React from 'react';
import { SessionProvider } from 'next-auth/react';
import renderer from 'react-test-renderer';
+import Link from 'next/link';
describe('Navbar rendering correctly', () => {
it('renders correctly', () => {
@@ -14,4 +15,82 @@ describe('Navbar rendering correctly', () => {
.toJSON();
expect(tree).toMatchSnapshot();
});
+
+ it('renders Classes link as "Classes" for non-admin session', () => {
+ const tree = renderer
+ .create(
+
+
+
+ Classes
+
+
+
+ )
+ .toJSON();
+
+ const jsonString = JSON.stringify(tree);
+ expect(jsonString).toContain('Classes');
+ expect(jsonString).not.toContain('Dashboard');
+ });
+
+ it('renders Classes link as "Dashboard" for ADMIN session', () => {
+ const tree = renderer
+ .create(
+
+
+
+ Classes
+
+
+
+ )
+ .toJSON();
+
+ const jsonString = JSON.stringify(tree);
+ expect(jsonString).toContain('Dashboard');
+ expect(jsonString).not.toContain('Classes');
+ });
+
+ it('hides Classes link for STUDENT session', () => {
+ const tree = renderer
+ .create(
+
+
+
+ Classes
+
+
+
+ )
+ .toJSON();
+
+ const jsonString = JSON.stringify(tree);
+ expect(jsonString).not.toContain('Classes');
+ expect(jsonString).not.toContain('Dashboard');
+ });
+
+ it('hides Classes link for unauthenticated session', () => {
+ const tree = renderer
+ .create(
+
+
+
+ Classes
+
+
+
+ )
+ .toJSON();
+
+ const jsonString = JSON.stringify(tree);
+ expect(jsonString).not.toContain('Classes');
+ expect(jsonString).not.toContain('Dashboard');
+ });
});
diff --git a/components/navbar.js b/components/navbar.js
index 9d4c44adb..079949256 100644
--- a/components/navbar.js
+++ b/components/navbar.js
@@ -1,9 +1,61 @@
import Image from 'next/legacy/image';
import Link from 'next/link';
import React from 'react';
+import { useSession } from 'next-auth/react';
import AuthButton from '../components/authButton';
+function updateClassesLinkLabel(child, isAdmin) {
+ if (!child) return child;
+
+ if (React.isValidElement(child)) {
+ const isClassesLink =
+ child.props.href === '/classes' && child.props.children === 'Classes';
+
+ if (isClassesLink) {
+ return React.cloneElement(child, {
+ children: isAdmin ? 'Dashboard' : 'Classes'
+ });
+ }
+
+ if (child.props.children) {
+ const newChildren = React.Children.map(child.props.children, c =>
+ updateClassesLinkLabel(c, isAdmin)
+ );
+ return React.cloneElement(child, { children: newChildren });
+ }
+ }
+
+ return child;
+}
+
+function hasClassesLink(child) {
+ if (!child) return false;
+ if (React.isValidElement(child)) {
+ if (child.props.href === '/classes') {
+ return true;
+ }
+ if (child.props.children) {
+ return React.Children.toArray(child.props.children).some(hasClassesLink);
+ }
+ }
+ return false;
+}
+
export default function Navbar({ children }) {
+ const { data: session } = useSession();
+ const role = session?.user?.role;
+ const hasAccess = role === 'ADMIN' || role === 'TEACHER';
+ const isAdmin = role === 'ADMIN';
+
+ const processedChildren = React.Children.toArray(children)
+ .filter(child => {
+ if (hasClassesLink(child)) {
+ return hasAccess;
+ }
+ return true;
+ })
+ .map(child => updateClassesLinkLabel(child, isAdmin));
+
return (
@@ -20,7 +72,7 @@ export default function Navbar({ children }) {
>
- {React.Children.toArray(children).map(child => (
+ {processedChildren.map(child => (
{child}
diff --git a/pages/api/auth/[...nextauth].js b/pages/api/auth/[...nextauth].js
index 4895ac83c..27376ddf1 100644
--- a/pages/api/auth/[...nextauth].js
+++ b/pages/api/auth/[...nextauth].js
@@ -28,6 +28,13 @@ export const authOptions = {
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url;
return baseUrl;
+ },
+ async session({ session, user }) {
+ if (session?.user && user) {
+ session.user.role = user.role;
+ session.user.id = user.id;
+ }
+ return session;
}
}
};