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,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
headers=headers,
|
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
|
request: FastAPI request object
|
||||||
data: Request body containing login credentials
|
data: Request body containing login credentials
|
||||||
{
|
{
|
||||||
"data": {
|
"domain": "evyos.com.tr",
|
||||||
"domain": "evyos.com.tr",
|
"access_key": "karatay.berkay.sup@evyos.com.tr",
|
||||||
"access_key": "karatay.berkay.sup@evyos.com.tr",
|
"password": "string",
|
||||||
"password": "string",
|
"remember_me": false
|
||||||
"remember_me": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Returns:
|
Returns:
|
||||||
SuccessResponse containing authentication token and user info
|
SuccessResponse containing authentication token and user info
|
||||||
|
|
@ -709,7 +707,15 @@ class PasswordHandler:
|
||||||
class PageHandlers:
|
class PageHandlers:
|
||||||
|
|
||||||
@classmethod
|
@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 := RedisHandlers.get_object_from_redis(access_token=access_token):
|
||||||
if result.is_employee:
|
if result.is_employee:
|
||||||
if application := result.selected_company.reachable_app_codes.get(page_url, None):
|
if application := result.selected_company.reachable_app_codes.get(page_url, None):
|
||||||
|
|
@ -720,6 +726,23 @@ class PageHandlers:
|
||||||
raise ValueError("EYS_0013")
|
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:
|
class AuthHandlers:
|
||||||
|
|
||||||
LoginHandler: LoginHandler = LoginHandler()
|
LoginHandler: LoginHandler = LoginHandler()
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
import { fetchDataWithToken, fetchData } from "../api-fetcher";
|
import { fetchDataWithToken, fetchData } from "../api-fetcher";
|
||||||
import { baseUrlAuth, tokenSecret } from "../basics";
|
import { baseUrlAuth, tokenSecret } from "../basics";
|
||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import NextCrypto from "next-crypto";
|
|
||||||
|
|
||||||
|
import NextCrypto from "next-crypto";
|
||||||
const checkToken = `${baseUrlAuth}/authentication/token/check`;
|
const checkToken = `${baseUrlAuth}/authentication/token/check`;
|
||||||
const pageValid = `${baseUrlAuth}/authentication/page/valid`;
|
const pageValid = `${baseUrlAuth}/authentication/page/valid`;
|
||||||
const siteUrls = `${baseUrlAuth}/authentication/page/list`;
|
const siteUrls = `${baseUrlAuth}/authentication/sites/list`;
|
||||||
|
|
||||||
const nextCrypto = new NextCrypto(tokenSecret);
|
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",
|
description: "WAG Frontend Application",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function AuthLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<div className="min-h-screen flex">
|
||||||
<body>
|
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
||||||
<div className="min-h-screen flex">
|
</div>
|
||||||
<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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,26 +11,27 @@ import LeftMenu from "@/components/menu/leftMenu";
|
||||||
export default async function DashboardLayout({
|
export default async function DashboardLayout({
|
||||||
searchParams,
|
searchParams,
|
||||||
}: {
|
}: {
|
||||||
searchParams: { [key: string]: string | undefined };
|
searchParams: Promise<{ [key: string]: string | undefined }>;
|
||||||
}) {
|
}) {
|
||||||
const token_is_valid = await checkAccessTokenIsValid();
|
const token_is_valid = await checkAccessTokenIsValid();
|
||||||
const siteUrlsList = await retrievePageList();
|
const siteUrlsList = (await retrievePageList()) || [];
|
||||||
if (!token_is_valid) {
|
if (!token_is_valid) {
|
||||||
redirect("/auth/login");
|
redirect("/auth/login");
|
||||||
}
|
}
|
||||||
const lang = "tr";
|
const lang = "tr";
|
||||||
|
const searchParamsInstance = await searchParams;
|
||||||
const pageToDirect = await retrievePagebyUrl("/dashboard");
|
const pageToDirect = await retrievePagebyUrl("/dashboard");
|
||||||
const PageComponent = retrievePage(pageToDirect);
|
const PageComponent = retrievePage(pageToDirect);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="min-h-screen min-w-screen flex h-screen w-screen overflow-hidden">
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<aside className="w-1/4 border-r p-4 overflow-y-auto">
|
<aside className="w-1/4 border-r p-4 overflow-y-auto">
|
||||||
<LeftMenu
|
<LeftMenu
|
||||||
pageUuidList={siteUrlsList}
|
pageUuidList={siteUrlsList}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
searchParams={searchParams}
|
searchParams={searchParamsInstance}
|
||||||
/>
|
/>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ export default async function DashboardLayout({
|
||||||
<div className="w-10 h-10 bg-gray-300 rounded-full"></div>
|
<div className="w-10 h-10 bg-gray-300 rounded-full"></div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<PageComponent lang={lang} queryParams={searchParams} />
|
<PageComponent lang={lang} queryParams={searchParamsInstance} />
|
||||||
</div>
|
</div>
|
||||||
</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 (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body>{children}</body>
|
<body className="text-black">{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,12 @@ import { PageProps } from "./interFaces";
|
||||||
function App000001({ lang, queryParams }: PageProps) {
|
function App000001({ lang, queryParams }: PageProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col w-3/4">
|
<div className="flex">
|
||||||
{/* Sticky Header */}
|
{/* Sticky Header */}
|
||||||
<header className="sticky top-0 bg-white shadow-md z-10 p-4 flex justify-between items-center">
|
<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>
|
<h1 className="text-2xl font-semibold">Dashboard</h1>
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-4">
|
||||||
{JSON.stringify({
|
{JSON.stringify({ lang, queryParams })}
|
||||||
lang,
|
|
||||||
queryParams,
|
|
||||||
})}
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export const PageIndexs = {
|
||||||
app000001: App000001,
|
app000001: App000001,
|
||||||
};
|
};
|
||||||
|
|
||||||
function UnAuthorizedPage({ lang }: PageProps) {
|
function UnAuthorizedPage({ lang, queryParams }: PageProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col h-screen">
|
<div className="flex flex-col h-screen">
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ async function LeftMenu({
|
||||||
lang: keyof LanguageTranslation;
|
lang: keyof LanguageTranslation;
|
||||||
searchParams: { [key: string]: string | string[] | undefined };
|
searchParams: { [key: string]: string | string[] | undefined };
|
||||||
}) {
|
}) {
|
||||||
const transformedMenu = transformMenu(pageUuidList);
|
const transformedMenu = transformMenu(pageUuidList) || [];
|
||||||
|
|
||||||
// Get the menuContext from searchParams without setting a default value
|
// Get the menuContext from searchParams without setting a default value
|
||||||
const menuContext = searchParams?.menu;
|
const menuContext = searchParams?.menu;
|
||||||
|
|
@ -34,68 +34,69 @@ async function LeftMenu({
|
||||||
<div>
|
<div>
|
||||||
<nav className="flex flex-col space-y-2">
|
<nav className="flex flex-col space-y-2">
|
||||||
<div className="text-xl font-bold mb-6 text-center">Dashboard</div>
|
<div className="text-xl font-bold mb-6 text-center">Dashboard</div>
|
||||||
{transformedMenu.map((item, firstIndex) => (
|
{transformedMenu &&
|
||||||
<div key={item.name} className="mb-4">
|
transformedMenu.map((item, firstIndex) => (
|
||||||
<Link
|
<div key={item.name} className="mb-4">
|
||||||
href={`/dashboard?${
|
<Link
|
||||||
pageSelected ? `page=${pageSelected}` : ""
|
href={`/dashboard?${
|
||||||
}&menu=${firstIndex}*0`}
|
pageSelected ? `page=${pageSelected}` : ""
|
||||||
className={`text-xl font-semibold pl-5 my-2 py-2 block ${
|
}&menu=${firstIndex}*0`}
|
||||||
firstIndex === firstLayerIndex
|
className={`text-xl font-semibold pl-5 my-2 py-2 block ${
|
||||||
? "text-emerald-600"
|
firstIndex === firstLayerIndex
|
||||||
: "text-emerald-400"
|
? "text-emerald-600"
|
||||||
} hover:text-emerald-600`}
|
: "text-emerald-400"
|
||||||
>
|
} hover:text-emerald-600`}
|
||||||
{item.lg[lang]}
|
>
|
||||||
</Link>
|
{item.lg[lang]}
|
||||||
|
</Link>
|
||||||
|
|
||||||
{/* Only render the second layer if menuContext exists and this first layer item is selected */}
|
{/* Only render the second layer if menuContext exists and this first layer item is selected */}
|
||||||
{menuContext && firstIndex === firstLayerIndex && (
|
{menuContext && firstIndex === firstLayerIndex && (
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{item.subList.map((subItem, secondIndex) => (
|
{item.subList.map((subItem, secondIndex) => (
|
||||||
<div key={subItem.name}>
|
<div key={subItem.name}>
|
||||||
<Link
|
<Link
|
||||||
href={`/dashboard?${
|
href={`/dashboard?${
|
||||||
pageSelected ? `page=${pageSelected}` : ""
|
pageSelected ? `page=${pageSelected}` : ""
|
||||||
}&menu=${firstIndex}*${secondIndex}`}
|
}&menu=${firstIndex}*${secondIndex}`}
|
||||||
className={`ml-5 my-4 pl-4 text-xl font-semibold block ${
|
className={`ml-5 my-4 pl-4 text-xl font-semibold block ${
|
||||||
secondIndex === secondLayerIndex
|
secondIndex === secondLayerIndex
|
||||||
? "text-emerald-700"
|
? "text-emerald-700"
|
||||||
: "text-emerald-500"
|
: "text-emerald-500"
|
||||||
} hover:text-emerald-700`}
|
} hover:text-emerald-700`}
|
||||||
>
|
>
|
||||||
{subItem.lg[lang]}
|
{subItem.lg[lang]}
|
||||||
</Link>
|
</Link>
|
||||||
{/* Only render the third layer if this second layer item is selected */}
|
{/* Only render the third layer if this second layer item is selected */}
|
||||||
{firstIndex === firstLayerIndex &&
|
{firstIndex === firstLayerIndex &&
|
||||||
secondIndex === secondLayerIndex && (
|
secondIndex === secondLayerIndex && (
|
||||||
<div className="ml-5">
|
<div className="ml-5">
|
||||||
{subItem.subList.map((subSubItem) => (
|
{subItem.subList.map((subSubItem) => (
|
||||||
<Link
|
<Link
|
||||||
key={subSubItem.name}
|
key={subSubItem.name}
|
||||||
href={`/dashboard?page=${subSubItem.name}&menu=${firstIndex}*${secondIndex}`}
|
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 ${
|
className={`flex flex-row text-xl py-4 my-4 w-full space-x-2 p-2 rounded ${
|
||||||
pageSelected === subSubItem.name
|
pageSelected === subSubItem.name
|
||||||
? " bg-gray-100 cursor-not-allowed"
|
? " bg-gray-100 cursor-not-allowed"
|
||||||
: "hover:bg-gray-200"
|
: "hover:bg-gray-200"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="text-gray-400">
|
<span className="text-gray-400">
|
||||||
<Home />
|
<Home />
|
||||||
</span>
|
</span>
|
||||||
<span className="ml-5 text-gray-700">
|
<span className="ml-5 text-gray-700">
|
||||||
{subSubItem.lg[lang]}
|
{subSubItem.lg[lang]}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue