diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/collections/page.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/collections/page.tsx index a6c14011..aaed61cf 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/collections/page.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/collections/page.tsx @@ -10,6 +10,7 @@ import Link from 'next/link' import { getAccessTokenFromRefreshTokenCookie } from '@services/auth/auth' import CollectionThumbnail from '@components/Objects/Thumbnails/CollectionThumbnail' import NewCollectionButton from '@components/StyledElements/Buttons/NewCollectionButton' +import ContentPlaceHolderIfUserIsNotAdmin from '@components/ContentPlaceHolder' type MetadataProps = { params: { orgslug: string; courseid: string } @@ -127,7 +128,9 @@ const CollectionsPage = async (params: any) => { No collections yet

- Create a collection to group courses together +

No courses yet -

+ {isUserAdmin ? (

Create a course to add content -

+

) : (

+ No courses available yet +

)} { No collections yet

- Create a collection to group courses together +

@@ -206,7 +209,7 @@ const OrgHomePage = async (params: any) => { No courses yet

- Create a course to add content +

diff --git a/apps/web/app/orgs/[orgslug]/dash/page.tsx b/apps/web/app/orgs/[orgslug]/dash/page.tsx index 75e551c5..9f104e12 100644 --- a/apps/web/app/orgs/[orgslug]/dash/page.tsx +++ b/apps/web/app/orgs/[orgslug]/dash/page.tsx @@ -76,7 +76,7 @@ function DashboardHome() {
diff --git a/apps/web/components/ContentPlaceHolder.tsx b/apps/web/components/ContentPlaceHolder.tsx new file mode 100644 index 00000000..1937a408 --- /dev/null +++ b/apps/web/components/ContentPlaceHolder.tsx @@ -0,0 +1,14 @@ +'use client'; +import React from 'react' +import useAdminStatus from './Hooks/useAdminStatus' + + +// Terrible name and terible implementation, need to be refactored asap +function ContentPlaceHolderIfUserIsNotAdmin({ text }: { text: string }) { + const isUserAdmin = useAdminStatus() as any + return ( +
{isUserAdmin ? text : 'No content yet'}
+ ) +} + +export default ContentPlaceHolderIfUserIsNotAdmin \ No newline at end of file diff --git a/apps/web/components/Hooks/useAdminStatus.tsx b/apps/web/components/Hooks/useAdminStatus.tsx new file mode 100644 index 00000000..9fe343a9 --- /dev/null +++ b/apps/web/components/Hooks/useAdminStatus.tsx @@ -0,0 +1,40 @@ +import { useOrg } from '@components/Contexts/OrgContext' +import { useSession } from '@components/Contexts/SessionContext' +import { useEffect } from 'react' + +function useAdminStatus() { + const session = useSession() as any + const org = useOrg() as any + + // If session is not loaded, redirect to login + + useEffect(() => { + if (session.isLoading) { + return + } + + } + , [session]) + + const isUserAdmin = () => { + if (session.isAuthenticated) { + const isAdmin = session.roles.some((role: any) => { + return ( + role.org.id === org.id && + (role.role.id === 1 || + role.role.id === 2 || + role.role.role_uuid === 'role_global_admin' || + role.role.role_uuid === 'role_global_maintainer') + ) + }) + return isAdmin + } + return false + } + + // Return the user admin status + return isUserAdmin() + +} + +export default useAdminStatus \ No newline at end of file diff --git a/apps/web/components/Objects/Menu/ProfileArea.tsx b/apps/web/components/Objects/Menu/ProfileArea.tsx deleted file mode 100644 index 76fcadad..00000000 --- a/apps/web/components/Objects/Menu/ProfileArea.tsx +++ /dev/null @@ -1,147 +0,0 @@ -'use client' -import React from 'react' -import styled from 'styled-components' -import Link from 'next/link' -import { - getNewAccessTokenUsingRefreshToken, - getUserInfo, -} from '@services/auth/auth' -import { usePathname } from 'next/navigation' -import { useRouter } from 'next/router' -import { Settings } from 'lucide-react' -import UserAvatar from '@components/Objects/UserAvatar' - -export interface Auth { - access_token: string - isAuthenticated: boolean - userInfo: any - isLoading: boolean -} - -function ProfileArea() { - const PRIVATE_ROUTES = ['/course/*/edit', '/settings*', '/trail'] - const NON_AUTHENTICATED_ROUTES = ['/login', '/register'] - - const router = useRouter() - const pathname = usePathname() - const [auth, setAuth] = React.useState({ - access_token: '', - isAuthenticated: false, - userInfo: {}, - isLoading: true, - }) - - async function checkRefreshToken() { - let data = await getNewAccessTokenUsingRefreshToken() - if (data) { - return data.access_token - } - } - - React.useEffect(() => { - checkAuth() - }, [pathname]) - - async function checkAuth() { - try { - let access_token = await checkRefreshToken() - let userInfo = {} - let isLoading = false - - if (access_token) { - userInfo = await getUserInfo(access_token) - setAuth({ access_token, isAuthenticated: true, userInfo, isLoading }) - - // Redirect to home if user is trying to access a NON_AUTHENTICATED_ROUTES route - - if ( - NON_AUTHENTICATED_ROUTES.some((route) => - new RegExp(`^${route.replace('*', '.*')}$`).test(pathname) - ) - ) { - router.push('/') - } - } else { - setAuth({ access_token, isAuthenticated: false, userInfo, isLoading }) - - // Redirect to login if user is trying to access a private route - if ( - PRIVATE_ROUTES.some((route) => - new RegExp(`^${route.replace('*', '.*')}$`).test(pathname) - ) - ) { - router.push('/login') - } - } - } catch (error) {} - } - return ( - - {!auth.isAuthenticated && ( - -
    -
  • - Login -
  • -
  • - Sign up -
  • -
-
- )} - {auth.isAuthenticated && ( - -
{auth.userInfo.user_object.username}
-
- -
- - - -
- )} -
- ) -} - -const AccountArea = styled.div` - padding-right: 20px; - display: flex; - place-items: center; - - div { - margin-right: 10px; - } - img { - width: 29px; - border-radius: 19px; - } -` - -const ProfileAreaStyled = styled.div` - display: flex; - place-items: stretch; - place-items: center; -` - -const UnidentifiedArea = styled.div` - display: flex; - place-items: stretch; - flex-grow: 1; - - ul { - display: flex; - place-items: center; - list-style: none; - padding-left: 20px; - - li { - padding-right: 20px; - font-size: 16px; - font-weight: 500; - color: #171717; - } - } -` - -export default ProfileArea diff --git a/apps/web/components/Security/AdminAuthorization.tsx b/apps/web/components/Security/AdminAuthorization.tsx index 9aca13fd..ff8158ad 100644 --- a/apps/web/components/Security/AdminAuthorization.tsx +++ b/apps/web/components/Security/AdminAuthorization.tsx @@ -1,6 +1,7 @@ 'use client' import { useOrg } from '@components/Contexts/OrgContext' import { useSession } from '@components/Contexts/SessionContext' +import useAdminStatus from '@components/Hooks/useAdminStatus' import { usePathname, useRouter } from 'next/navigation' import React from 'react' @@ -40,18 +41,7 @@ function AdminAuthorization(props: AuthorizationProps) { } // Verify if the user is an Admin (1), Maintainer (2) or Member (3) of the organization - const isUserAdmin = () => { - const isAdmin = session.roles.some((role: any) => { - return ( - role.org.id === org.id && - (role.role.id === 1 || - role.role.id === 2 || - role.role.role_uuid === 'role_global_admin' || - role.role.role_uuid === 'role_global_maintainer') - ) - }) - return isAdmin - } + const isUserAdmin = useAdminStatus() function checkPathname(pattern: string, pathname: string) { // Escape special characters in the pattern and replace '*' with a regex pattern @@ -72,7 +62,7 @@ function AdminAuthorization(props: AuthorizationProps) { console.log('Admin path') if (isUserAuthenticated()) { // Check if the user is an Admin - if (isUserAdmin()) { + if (isUserAdmin) { setIsAuthorized(true) } else { setIsAuthorized(false) @@ -93,7 +83,7 @@ function AdminAuthorization(props: AuthorizationProps) { if (props.authorizationMode === 'component') { // Component mode - if (isUserAuthenticated() && isUserAdmin()) { + if (isUserAuthenticated() && isUserAdmin) { setIsAuthorized(true) } else { setIsAuthorized(false) diff --git a/apps/web/components/Security/HeaderProfileBox.tsx b/apps/web/components/Security/HeaderProfileBox.tsx index 8d387093..b9e490aa 100644 --- a/apps/web/components/Security/HeaderProfileBox.tsx +++ b/apps/web/components/Security/HeaderProfileBox.tsx @@ -1,13 +1,19 @@ 'use client' -import React from 'react' +import React, { useEffect } from 'react' import styled from 'styled-components' import Link from 'next/link' import { Settings } from 'lucide-react' import { useSession } from '@components/Contexts/SessionContext' import UserAvatar from '@components/Objects/UserAvatar' +import useAdminStatus from '@components/Hooks/useAdminStatus' export const HeaderProfileBox = () => { const session = useSession() as any + const isUserAdmin = useAdminStatus() as any + + useEffect(() => { + } + , [session]) return ( @@ -26,7 +32,10 @@ export const HeaderProfileBox = () => { {session.isAuthenticated && (
-
{session.user.username}
+
+

{session.user.username}

+ {isUserAdmin &&
ADMIN
} +