updated route sites available
This commit is contained in:
parent
9b02620d1d
commit
531e8b2e39
|
|
@ -431,3 +431,48 @@ def authentication_page_valid(
|
|||
status_code=status.HTTP_202_ACCEPTED,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
|
||||
@auth_route.get(
|
||||
path="/sites/list",
|
||||
summary="Verify if page is valid returns application avaliable",
|
||||
description="Verify if page is valid returns application avaliable",
|
||||
)
|
||||
def authentication_page_valid(
|
||||
request: Request,
|
||||
language: str = Header(None, alias="language"),
|
||||
domain: str = Header(None, alias="domain"),
|
||||
tz: str = Header(None, alias="timezone"),
|
||||
):
|
||||
"""
|
||||
Verify if page is valid returns application that can user reach
|
||||
page: { url = /building/create}
|
||||
result: { "sites": ['/dashboard', '/building/create'] }
|
||||
"""
|
||||
token = request.headers.get(api_config.ACCESS_TOKEN_TAG, None)
|
||||
headers = {
|
||||
"language": language or "",
|
||||
"domain": domain or "",
|
||||
"eys-ext": f"{str(uuid.uuid4())}",
|
||||
"tz": tz or "GMT+3",
|
||||
"token": token,
|
||||
}
|
||||
if not domain or not language:
|
||||
return JSONResponse(
|
||||
content={"error": "EYS_0003"},
|
||||
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||
headers=headers,
|
||||
)
|
||||
result = AuthHandlers.PageHandlers.retrieve_valid_sites_via_token(access_token=token)
|
||||
if not result:
|
||||
return JSONResponse(
|
||||
content={"error": "EYS_0004"},
|
||||
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
||||
headers=headers,
|
||||
)
|
||||
return JSONResponse(
|
||||
content={"sites": result},
|
||||
status_code=status.HTTP_202_ACCEPTED,
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -367,12 +367,10 @@ class LoginHandler:
|
|||
request: FastAPI request object
|
||||
data: Request body containing login credentials
|
||||
{
|
||||
"data": {
|
||||
"domain": "evyos.com.tr",
|
||||
"access_key": "karatay.berkay.sup@evyos.com.tr",
|
||||
"password": "string",
|
||||
"remember_me": false
|
||||
}
|
||||
"domain": "evyos.com.tr",
|
||||
"access_key": "karatay.berkay.sup@evyos.com.tr",
|
||||
"password": "string",
|
||||
"remember_me": false
|
||||
}
|
||||
Returns:
|
||||
SuccessResponse containing authentication token and user info
|
||||
|
|
@ -709,7 +707,15 @@ class PasswordHandler:
|
|||
class PageHandlers:
|
||||
|
||||
@classmethod
|
||||
def retrieve_valid_page_via_token(cls, access_token: str, page_url: str):
|
||||
def retrieve_valid_page_via_token(cls, access_token: str, page_url: str) -> str:
|
||||
"""
|
||||
Retrieve valid page via token.
|
||||
{
|
||||
access_token: "string",
|
||||
page_url: "string"
|
||||
}
|
||||
Results: str(application)
|
||||
"""
|
||||
if result := RedisHandlers.get_object_from_redis(access_token=access_token):
|
||||
if result.is_employee:
|
||||
if application := result.selected_company.reachable_app_codes.get(page_url, None):
|
||||
|
|
@ -720,6 +726,23 @@ class PageHandlers:
|
|||
raise ValueError("EYS_0013")
|
||||
|
||||
|
||||
@classmethod
|
||||
def retrieve_valid_sites_via_token(cls, access_token: str) -> list:
|
||||
"""
|
||||
Retrieve valid pages via token.
|
||||
{
|
||||
"access_token": "string"
|
||||
}
|
||||
Results: list(sites)
|
||||
"""
|
||||
if result := RedisHandlers.get_object_from_redis(access_token=access_token):
|
||||
if result.is_employee:
|
||||
return result.selected_company.reachable_app_codes.keys()
|
||||
elif result.is_occupant:
|
||||
return result.selected_company.reachable_app_codes.keys()
|
||||
raise ValueError("EYS_0013")
|
||||
|
||||
|
||||
class AuthHandlers:
|
||||
|
||||
LoginHandler: LoginHandler = LoginHandler()
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
import { fetchDataWithToken, fetchData } from "../api-fetcher";
|
||||
import { baseUrlAuth, tokenSecret } from "../basics";
|
||||
import { cookies } from "next/headers";
|
||||
import NextCrypto from "next-crypto";
|
||||
|
||||
import NextCrypto from "next-crypto";
|
||||
const checkToken = `${baseUrlAuth}/authentication/token/check`;
|
||||
const pageValid = `${baseUrlAuth}/authentication/page/valid`;
|
||||
const siteUrls = `${baseUrlAuth}/authentication/page/list`;
|
||||
const siteUrls = `${baseUrlAuth}/authentication/sites/list`;
|
||||
|
||||
const nextCrypto = new NextCrypto(tokenSecret);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
import React from "react";
|
||||
import retrievePage from "@/components/NavigatePages";
|
||||
|
||||
function MainPage({
|
||||
pageSelected,
|
||||
lang,
|
||||
}: {
|
||||
pageSelected: string | undefined;
|
||||
lang: string;
|
||||
}) {
|
||||
const ComponentPage = retrievePage({
|
||||
pageId: pageSelected ?? "",
|
||||
});
|
||||
|
||||
if (!ComponentPage) {
|
||||
return (
|
||||
<div className="flex flex-col w-full">
|
||||
<h2 className="text-2xl font-semibold p-4">No Page Selected</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{/* Main Content */}
|
||||
<main className="flex-grow p-6 bg-gray-50 overflow-y-auto">
|
||||
<ComponentPage lang={lang} />
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainPage;
|
||||
|
|
@ -6,29 +6,14 @@ export const metadata: Metadata = {
|
|||
description: "WAG Frontend Application",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
export default function AuthLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body>
|
||||
<div className="min-h-screen flex">
|
||||
<div className="w-1/3 bg-purple-600 p-8 text-white">
|
||||
<h1 className="text-4xl font-bold mb-4">Welcome to evyos</h1>
|
||||
<p className="text-lg">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
||||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
|
||||
enim ad minim veniam, quis nostrud exercitation ullamco laboris
|
||||
nisi ut aliquip ex ea commodo consequat.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-2/3">
|
||||
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<div className="min-h-screen flex">
|
||||
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,26 +11,27 @@ import LeftMenu from "@/components/menu/leftMenu";
|
|||
export default async function DashboardLayout({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: { [key: string]: string | undefined };
|
||||
searchParams: Promise<{ [key: string]: string | undefined }>;
|
||||
}) {
|
||||
const token_is_valid = await checkAccessTokenIsValid();
|
||||
const siteUrlsList = await retrievePageList();
|
||||
const siteUrlsList = (await retrievePageList()) || [];
|
||||
if (!token_is_valid) {
|
||||
redirect("/auth/login");
|
||||
}
|
||||
const lang = "tr";
|
||||
const searchParamsInstance = await searchParams;
|
||||
const pageToDirect = await retrievePagebyUrl("/dashboard");
|
||||
const PageComponent = retrievePage(pageToDirect);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex h-screen overflow-hidden">
|
||||
<div className="min-h-screen min-w-screen flex h-screen w-screen overflow-hidden">
|
||||
{/* Sidebar */}
|
||||
<aside className="w-1/4 border-r p-4 overflow-y-auto">
|
||||
<LeftMenu
|
||||
pageUuidList={siteUrlsList}
|
||||
lang={lang}
|
||||
searchParams={searchParams}
|
||||
searchParams={searchParamsInstance}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ export default async function DashboardLayout({
|
|||
<div className="w-10 h-10 bg-gray-300 rounded-full"></div>
|
||||
</div>
|
||||
</header>
|
||||
<PageComponent lang={lang} queryParams={searchParams} />
|
||||
<PageComponent lang={lang} queryParams={searchParamsInstance} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import type { Metadata } from "next";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default function DashLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="min-h-screen min-w-screen flex h-screen w-screen overflow-hidden">
|
||||
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ export default function RootLayout({
|
|||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
<body className="text-black">{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,12 @@ import { PageProps } from "./interFaces";
|
|||
function App000001({ lang, queryParams }: PageProps) {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col w-3/4">
|
||||
<div className="flex">
|
||||
{/* Sticky Header */}
|
||||
<header className="sticky top-0 bg-white shadow-md z-10 p-4 flex justify-between items-center">
|
||||
<h1 className="text-2xl font-semibold">Dashboard</h1>
|
||||
<div className="flex items-center space-x-4">
|
||||
{JSON.stringify({
|
||||
lang,
|
||||
queryParams,
|
||||
})}
|
||||
{JSON.stringify({ lang, queryParams })}
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const PageIndexs = {
|
|||
app000001: App000001,
|
||||
};
|
||||
|
||||
function UnAuthorizedPage({ lang }: PageProps) {
|
||||
function UnAuthorizedPage({ lang, queryParams }: PageProps) {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col h-screen">
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ async function LeftMenu({
|
|||
lang: keyof LanguageTranslation;
|
||||
searchParams: { [key: string]: string | string[] | undefined };
|
||||
}) {
|
||||
const transformedMenu = transformMenu(pageUuidList);
|
||||
const transformedMenu = transformMenu(pageUuidList) || [];
|
||||
|
||||
// Get the menuContext from searchParams without setting a default value
|
||||
const menuContext = searchParams?.menu;
|
||||
|
|
@ -34,68 +34,69 @@ async function LeftMenu({
|
|||
<div>
|
||||
<nav className="flex flex-col space-y-2">
|
||||
<div className="text-xl font-bold mb-6 text-center">Dashboard</div>
|
||||
{transformedMenu.map((item, firstIndex) => (
|
||||
<div key={item.name} className="mb-4">
|
||||
<Link
|
||||
href={`/dashboard?${
|
||||
pageSelected ? `page=${pageSelected}` : ""
|
||||
}&menu=${firstIndex}*0`}
|
||||
className={`text-xl font-semibold pl-5 my-2 py-2 block ${
|
||||
firstIndex === firstLayerIndex
|
||||
? "text-emerald-600"
|
||||
: "text-emerald-400"
|
||||
} hover:text-emerald-600`}
|
||||
>
|
||||
{item.lg[lang]}
|
||||
</Link>
|
||||
{transformedMenu &&
|
||||
transformedMenu.map((item, firstIndex) => (
|
||||
<div key={item.name} className="mb-4">
|
||||
<Link
|
||||
href={`/dashboard?${
|
||||
pageSelected ? `page=${pageSelected}` : ""
|
||||
}&menu=${firstIndex}*0`}
|
||||
className={`text-xl font-semibold pl-5 my-2 py-2 block ${
|
||||
firstIndex === firstLayerIndex
|
||||
? "text-emerald-600"
|
||||
: "text-emerald-400"
|
||||
} hover:text-emerald-600`}
|
||||
>
|
||||
{item.lg[lang]}
|
||||
</Link>
|
||||
|
||||
{/* Only render the second layer if menuContext exists and this first layer item is selected */}
|
||||
{menuContext && firstIndex === firstLayerIndex && (
|
||||
<ul className="space-y-2">
|
||||
{item.subList.map((subItem, secondIndex) => (
|
||||
<div key={subItem.name}>
|
||||
<Link
|
||||
href={`/dashboard?${
|
||||
pageSelected ? `page=${pageSelected}` : ""
|
||||
}&menu=${firstIndex}*${secondIndex}`}
|
||||
className={`ml-5 my-4 pl-4 text-xl font-semibold block ${
|
||||
secondIndex === secondLayerIndex
|
||||
? "text-emerald-700"
|
||||
: "text-emerald-500"
|
||||
} hover:text-emerald-700`}
|
||||
>
|
||||
{subItem.lg[lang]}
|
||||
</Link>
|
||||
{/* Only render the third layer if this second layer item is selected */}
|
||||
{firstIndex === firstLayerIndex &&
|
||||
secondIndex === secondLayerIndex && (
|
||||
<div className="ml-5">
|
||||
{subItem.subList.map((subSubItem) => (
|
||||
<Link
|
||||
key={subSubItem.name}
|
||||
href={`/dashboard?page=${subSubItem.name}&menu=${firstIndex}*${secondIndex}`}
|
||||
className={`flex flex-row text-xl py-4 my-4 w-full space-x-2 p-2 rounded ${
|
||||
pageSelected === subSubItem.name
|
||||
? " bg-gray-100 cursor-not-allowed"
|
||||
: "hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
<span className="text-gray-400">
|
||||
<Home />
|
||||
</span>
|
||||
<span className="ml-5 text-gray-700">
|
||||
{subSubItem.lg[lang]}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{/* Only render the second layer if menuContext exists and this first layer item is selected */}
|
||||
{menuContext && firstIndex === firstLayerIndex && (
|
||||
<ul className="space-y-2">
|
||||
{item.subList.map((subItem, secondIndex) => (
|
||||
<div key={subItem.name}>
|
||||
<Link
|
||||
href={`/dashboard?${
|
||||
pageSelected ? `page=${pageSelected}` : ""
|
||||
}&menu=${firstIndex}*${secondIndex}`}
|
||||
className={`ml-5 my-4 pl-4 text-xl font-semibold block ${
|
||||
secondIndex === secondLayerIndex
|
||||
? "text-emerald-700"
|
||||
: "text-emerald-500"
|
||||
} hover:text-emerald-700`}
|
||||
>
|
||||
{subItem.lg[lang]}
|
||||
</Link>
|
||||
{/* Only render the third layer if this second layer item is selected */}
|
||||
{firstIndex === firstLayerIndex &&
|
||||
secondIndex === secondLayerIndex && (
|
||||
<div className="ml-5">
|
||||
{subItem.subList.map((subSubItem) => (
|
||||
<Link
|
||||
key={subSubItem.name}
|
||||
href={`/dashboard?page=${subSubItem.name}&menu=${firstIndex}*${secondIndex}`}
|
||||
className={`flex flex-row text-xl py-4 my-4 w-full space-x-2 p-2 rounded ${
|
||||
pageSelected === subSubItem.name
|
||||
? " bg-gray-100 cursor-not-allowed"
|
||||
: "hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
<span className="text-gray-400">
|
||||
<Home />
|
||||
</span>
|
||||
<span className="ml-5 text-gray-700">
|
||||
{subSubItem.lg[lang]}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue