diff --git a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx index 9a850760..05df761a 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx @@ -2,7 +2,7 @@ import "@styles/globals.css"; import { Menu } from "@components/UI/Elements/Menu/Menu"; import AuthProvider from "@components/Security/AuthProvider"; -export default function RootLayout({ children, params }: { children: React.ReactNode , params:any}) { +export default async function RootLayout({ children, params }: { children: React.ReactNode , params:any}) { return ( <> diff --git a/front/components/UI/Elements/Menu/Menu.tsx b/front/components/UI/Elements/Menu/Menu.tsx index 9d80d1a5..12933cb1 100644 --- a/front/components/UI/Elements/Menu/Menu.tsx +++ b/front/components/UI/Elements/Menu/Menu.tsx @@ -4,19 +4,19 @@ import learnhouseLogo from "public/learnhouse_logo.png"; import Link from "next/link"; import Image from "next/image"; import { getUriWithOrg } from "@services/config/config"; -import { getOrganizationContextInfo } from "@services/organizations/orgs"; +import { getOrganizationContextInfo, getOrganizationContextInfoNoAsync } from "@services/organizations/orgs"; import ClientComponentSkeleton from "@components/UI/Utils/ClientComp"; import { HeaderProfileBox } from "@components/Security/HeaderProfileBox"; -export const Menu = async (props: any) => { +export const Menu = (props: any) => { const orgslug = props.orgslug; - const org = await getOrganizationContextInfo(orgslug, { revalidate: 1800, tags: ['organizations'] }); + const org = getOrganizationContextInfoNoAsync(orgslug, { revalidate: 1800, tags: ['organizations'] }); console.log(org); return ( <>
-
+
@@ -46,7 +46,7 @@ const LinkItem = (props: any, orgslug: any) => { const link = props.link; return ( -
  • +
  • {props.type == 'courses' && <> diff --git a/front/components/UI/Elements/Menu/ProfileArea.tsx b/front/components/UI/Elements/Menu/ProfileArea.tsx new file mode 100644 index 00000000..e912f092 --- /dev/null +++ b/front/components/UI/Elements/Menu/ProfileArea.tsx @@ -0,0 +1,156 @@ +"use client"; +import React from "react"; +import styled from "styled-components"; +import Link from "next/link"; +import Avvvatars from "avvvatars-react"; +import { GearIcon } from "@radix-ui/react-icons"; +import { getRefreshToken, getUserInfo } from "@services/auth/auth"; +import { usePathname } from "next/navigation"; +import { useRouter } from "next/router"; + +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 getRefreshToken(); + if (data) { + return data.access_token; + } + } + + + 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; + + a{ + // center the gear icon + display: flex; + place-items: center; + place-content: center; + width: 29px; + height: 29px; + border-radius: 19px; + background: #F5F5F5; + + // hover effect + &:hover{ + background: #E5E5E5; + + } + } + + 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 \ No newline at end of file diff --git a/front/services/organizations/orgs.ts b/front/services/organizations/orgs.ts index 56a11a94..1a2c6d32 100644 --- a/front/services/organizations/orgs.ts +++ b/front/services/organizations/orgs.ts @@ -19,7 +19,12 @@ export async function deleteOrganizationFromBackend(org_id: any) { } export async function getOrganizationContextInfo(org_slug: any, next: any) { - const result = await fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null,next)); + const result = await fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null, next)); const res = await errorHandling(result); return res; } + +export function getOrganizationContextInfoNoAsync(org_slug: any, next: any) { + const result = fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null, next)); + return result; +} \ No newline at end of file