feat: refactor the entire learnhouse project

This commit is contained in:
swve 2023-10-13 20:03:27 +02:00
parent f556e41dda
commit 4c215e91d5
247 changed files with 7716 additions and 1013 deletions

View file

@ -0,0 +1,79 @@
"use client";
import React, { useEffect } from "react";
import { getNewAccessTokenUsingRefreshToken, getUserInfo } from "../../services/auth/auth";
import { useRouter, usePathname } from "next/navigation";
export const AuthContext: any = React.createContext({});
const PRIVATE_ROUTES = ["/course/*/edit", "/settings*", "/trail"];
const NON_AUTHENTICATED_ROUTES = ["/login", "/register"];
export interface Auth {
access_token: string;
isAuthenticated: boolean;
userInfo: {};
isLoading: boolean;
}
const AuthProvider = ({ children }: any) => {
const router = useRouter();
const pathname = usePathname();
const [auth, setAuth] = React.useState<Auth>({ access_token: "", isAuthenticated: false, userInfo: {}, isLoading: true });
function deleteCookie(cookieName: string) {
document.cookie = cookieName + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
async function checkRefreshToken() {
//deleteCookie("access_token_cookie");
let data = await getNewAccessTokenUsingRefreshToken();
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) {
console.log(error);
}
}
useEffect(() => {
checkAuth();
return () => {
auth.isLoading = false;
};
}, [pathname]);
return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;
};
export default AuthProvider;

View file

@ -0,0 +1,50 @@
'use client';
import React from "react";
import { AuthContext } from "./AuthProvider";
interface AuthenticatedClientElementProps {
children: React.ReactNode;
checkMethod: 'authentication' | 'roles';
orgId?: string;
}
export const AuthenticatedClientElement = (props: AuthenticatedClientElementProps) => {
const auth: any = React.useContext(AuthContext);
// Available roles
const org_roles_values = ["admin", "owner"];
const user_roles_values = ["role_admin"];
function checkRoles() {
const org_id = props.orgId;
const org_roles = auth.userInfo.user_object.orgs;
const user_roles = auth.userInfo.user_object.roles;
const org_role = org_roles.find((org: any) => org.org_id == org_id);
const user_role = user_roles.find((role: any) => role.org_id == org_id);
if (org_role && user_role) {
if (org_roles_values.includes(org_role.org_role) || user_roles_values.includes(user_role.role_id)) {
return true;
}
else {
return false;
}
} else {
return false;
}
}
if ((props.checkMethod == 'authentication' && auth.isAuthenticated) || (auth.isAuthenticated && props.checkMethod == 'roles' && checkRoles())) {
return <>{props.children}</>;
}
return <></>;
}
export default AuthenticatedClientElement

View file

@ -0,0 +1,67 @@
'use client';
import React from "react";
import styled from "styled-components";
import Link from "next/link";
import { AuthContext } from "./AuthProvider";
import Avvvatars from "avvvatars-react";
import { GearIcon } from "@radix-ui/react-icons";
export const HeaderProfileBox = () => {
const auth: any = React.useContext(AuthContext);
return (
<ProfileArea>
{!auth.isAuthenticated && (
<UnidentifiedArea className="flex text-sm text-gray-700 font-bold p-1.5 px-2 rounded-lg">
<ul className="flex space-x-3 items-center">
<li>
<Link href="/login">
Login
</Link>
</li>
<li className="bg-black rounded-lg shadow-md p-2 px-3 text-white">
<Link href="/signup">
Sign up
</Link>
</li>
</ul>
</UnidentifiedArea>
)}
{auth.isAuthenticated && (
<AccountArea className="-space-x-2">
<div className="text-xs px-4 text-gray-600 p-1.5 rounded-full bg-gray-50">{auth.userInfo.user_object.full_name}</div>
<div className="flex -space-x-2 items-center">
<div className="py-4">
<Avvvatars size={26} value={auth.userInfo.user_object.user_id} style="shape" />
</div>
<Link className="bg-gray-50 p-1.5 rounded-full" href={"/settings"}><GearIcon fontSize={26} /></Link>
</div>
</AccountArea>
)}
</ProfileArea>
);
};
const AccountArea = styled.div`
display: flex;
place-items: center;
img {
width: 29px;
border-radius: 19px;
}
`;
const ProfileArea = styled.div`
display: flex;
place-items: stretch;
place-items: center;
`;
const UnidentifiedArea = styled.div`
display: flex;
place-items: stretch;
flex-grow: 1;
`;