user selection compoleted tested

This commit is contained in:
2025-06-15 19:05:48 +03:00
parent a48e560ece
commit 9fb517fa15
24 changed files with 574 additions and 313 deletions

View File

@@ -1,6 +1,6 @@
import {
getSelectionFromRedis,
setSelectionToRedis,
setActiveSelectionToRedis,
} from "@/fetchers/custom/context/dash/selection/fetch";
import { AuthError } from "@/fetchers/types/context";
import { NextResponse } from "next/server";
@@ -43,7 +43,8 @@ export async function GET() {
export async function POST(request: Request) {
try {
const selection = await request.json();
await setSelectionToRedis(selection);
await setActiveSelectionToRedis(selection);
return NextResponse.json({
status: 200,
data: selection || null,

View File

@@ -1,5 +1,5 @@
import { NextResponse } from "next/server";
import { loginViaAccessKeys } from "@/fetchers/custom/login/login";
import { loginViaAccessKeys, initFirstSelection } from "@/fetchers/custom/login/login";
import { loginSchemaEmail } from "@/pages/single/auth/login/schemas";
export async function POST(req: Request): Promise<NextResponse> {
@@ -20,6 +20,7 @@ export async function POST(req: Request): Promise<NextResponse> {
}
const userLogin = await loginViaAccessKeys(dataValidated);
await initFirstSelection(userLogin.data?.firstSelection, userLogin.data?.userType);
if (userLogin.status === 200 || userLogin.status === 202) {
return NextResponse.json({
status: 200,

View File

@@ -0,0 +1,26 @@
import { NextResponse } from "next/server";
import { logoutActiveSession } from "@/fetchers/custom/login/login";
export async function GET(req: Request): Promise<NextResponse> {
try {
const headers = req.headers;
const userLogin = await logoutActiveSession();
if (userLogin.status === 200 || userLogin.status === 202) {
return NextResponse.json({
status: 200,
message: "Logout successfully completed",
data: userLogin.data,
});
} else {
return NextResponse.json({
status: userLogin.status,
message: "Logout NOT successfully completed",
});
}
} catch (error) {
return NextResponse.json({
status: 401,
message: "Logout NOT successfully completed",
});
}
}

View File

@@ -1,9 +1,11 @@
'use client';
import { useRouter } from "next/navigation";
import { FC, useState, useEffect } from "react";
import { HeaderProps } from "@/validations/mutual/dashboard/props";
import { langGetKey } from "@/lib/langGet";
import { LanguageTypes } from "@/validations/mutual/language/validations";
import LanguageSelectionComponent from "@/components/mutual/languageSelection/component";
import { apiGetFetcher } from "@/lib/fetcher";
const translations = {
en: {
@@ -34,30 +36,25 @@ const HeaderComponent: FC<HeaderProps> = ({
userData, userLoading, userError, refreshUser, updateUser
}) => {
const lang = onlineData?.lang as LanguageTypes || 'en';
const router = useRouter();
const [activeTab, setActiveTab] = useState('notifications');
const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => {
const handleFullscreenChange = () => {
setIsFullscreen(!!document.fullscreenElement);
};
const handleFullscreenChange = () => { setIsFullscreen(!!document.fullscreenElement) };
document.addEventListener('fullscreenchange', handleFullscreenChange);
return () => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
};
return () => { document.removeEventListener('fullscreenchange', handleFullscreenChange) };
}, []);
const toggleFullscreen = () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
document.documentElement.requestFullscreen().catch(err => {
console.error(`Error attempting to enable fullscreen: ${err.message}`);
});
if (document.fullscreenElement) { document.exitFullscreen() } else {
document.documentElement.requestFullscreen().catch(err => { console.error(`Error attempting to enable fullscreen: ${err.message}`) });
}
};
const logoutSession = () => { apiGetFetcher({ url: '/api/login/logout', isNoCache: true }).then((logoutSession) => { router.push('/auth/login') }) }
return (
<div className="py-2 px-6 bg-[#f8f4f3] flex items-center shadow-md shadow-black/5 sticky top-0 left-0 z-30">
<button type="button" className="text-lg text-gray-900 font-semibold sidebar-toggle">
@@ -187,10 +184,7 @@ const HeaderComponent: FC<HeaderProps> = ({
<a
role="menuitem"
className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50 cursor-pointer"
onClick={(e) => {
e.preventDefault();
// Handle logout logic here
}}
onClick={logoutSession}
>
{langGetKey(translations[lang], 'logout')}
</a>

View File

@@ -1,39 +1,78 @@
'use client';
import { FC, useState } from "react";
import renderOneClientSelection from "./renderOneClientSelection";
interface ClientSelectionSectionProps {
selectionData: any;
initialSelectedClient?: any;
onClientSelect?: (client: any) => void;
refreshSelection: () => Promise<void>;
updateSelection: (newSelection: any) => Promise<boolean>;
}
const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({
selectionData,
initialSelectedClient = null,
onClientSelect
}) => {
const [selectedClient, setSelectedClient] = useState<any>(initialSelectedClient);
if (!selectionData || !selectionData.selectionList || selectionData.selectionList.length === 0) { return null }
const handleClientSelection = (client: any) => { setSelectedClient(client); if (onClientSelect) { onClientSelect(client) } };
const ClientSelectionSection: FC<ClientSelectionSectionProps> = ({ selectionData, refreshSelection, updateSelection }) => {
const [expandedBuilds, setExpandedBuilds] = useState<{ [key: string]: boolean }>({});
if (!selectionData || !selectionData.selectionList) { return null }
const toggleBuildExpansion = (buildUuid: string) => { setExpandedBuilds(prev => ({ ...prev, [buildUuid]: !prev[buildUuid] })); };
const isArray = Array.isArray(selectionData.selectionList);
return (
<div className="mb-3">
{selectionData.selectionList.map((client: any, index: number) => {
return (
<div
key={client.uu_id || client.id || `client-${index}`}
onClick={() => handleClientSelection(client)}
>
{client && renderOneClientSelection({
item: client,
isSelected: selectedClient?.uu_id === client.uu_id,
onClickHandler: handleClientSelection
})}
</div>
);
})}
{isArray ? (
selectionData.selectionList.map((client: any, index: number) => {
return (
<div key={client.uu_id || client.id || `client-${index}`}>
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
</div>
);
})
) : (
Object.entries(selectionData.selectionList).map(([buildUuid, buildData]: [string, any]) => {
const isExpanded = expandedBuilds[buildUuid] || false;
const selectedBuild = selectionData.selectionList[buildUuid].occupants.filter((client: any) => client.uu_id === selectionData.activeSelection?.uu_id)
const isSelected = selectedBuild.length > 0;
return (
<div key={buildUuid} className="mb-2 border rounded">
{/* Build header - clickable */}
<div
className={`w-full text-xs shadow rounded-lg overflow-hidden mb-2 transition-all cursor-pointer ${isExpanded ? 'border-2 border-blue-500' : ''} hover:shadow-md`}
onClick={() => toggleBuildExpansion(buildUuid)}
>
<div className={`${isExpanded ? 'bg-amber-300' : `${isSelected ? 'bg-blue-400' : 'bg-blue-100'}`} p-2 hover:bg-blue-50 transition-all`}>
<div className="flex items-center">
<div className="w-10 h-10 rounded bg-gray-200 flex items-center justify-center border border-gray-300 mr-2">
<div className="text-gray-500 text-sm font-bold">{buildData.build_name ? buildData.build_name.slice(0, 2).toUpperCase() : 'B'}</div>
</div>
<div className="overflow-hidden">
<h2 className="text-sm font-bold text-gray-800 truncate">{buildData.build_name || buildData.build_no || 'Build'}</h2>
<p className="text-xs text-gray-500 truncate">{buildData.description || `Build #${buildData.build_no || ''}`}</p>
</div>
<div className="ml-auto">
<div className={`${isExpanded ? 'bg-blue-500' : 'bg-gray-300'} rounded-full w-6 h-6 flex items-center justify-center`}>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={isExpanded ? "M19 9l-7 7-7-7" : "M9 5l7 7-7 7"} />
</svg>
</div>
</div>
</div>
</div>
</div>
{/* Occupants list - collapsible */}
{isExpanded && (
<div className="pl-3 p-2 border-t">
{buildData.occupants && Array.isArray(buildData.occupants) ? (
buildData.occupants.map((client: any, index: number) => (
<div key={client.occupant_uu_id || client.part_uu_id || `occupant-${index}`}>
{client && renderOneClientSelection({ item: client, selectedItem: selectionData.activeSelection, updateSelection, refreshSelection })}
</div>
))
) : (<div>No occupants found</div>)}
</div>
)}
</div>
);
})
)}
</div>
);
};

View File

@@ -13,26 +13,26 @@ import LoadingContent from "@/components/mutual/loader/component";
const MenuComponent: FC<MenuProps> = ({
activePageUrl, availableApplications, prefix,
onlineData, onlineLoading, onlineError,
userData, userLoading, userError,
selectionData, selectionLoading, selectionError,
menuData, menuLoading, menuError
onlineData, onlineLoading, onlineError, refreshOnline, updateOnline,
userData, userLoading, userError, refreshUser, updateUser,
selectionData, selectionLoading, selectionError, refreshSelection, updateSelection,
menuData, menuLoading, menuError, refreshMenu, updateMenu
}) => {
if (menuLoading) { return <MenuLoadingState /> }
if (menuError) { return <MenuErrorState error={menuError} />; }
if (availableApplications.length === 0) { return <MenuEmptyState />; }
function handleClientSelection(client: any) { console.log('Client selected:', client) }
const lang = onlineData?.lang as LanguageTypes || 'en';
return (
<div className="fixed top-24 p-5 left-0 right-0 w-80 border-emerald-150 border-r-2 overflow-y-auto h-[calc(100vh-6rem)]">
<div className="flex flex-col">
{/* User Profile Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
<UserProfileSection userData={userData} onlineData={onlineData} />
<UserProfileSection userData={userData} onlineData={onlineData} selectionData={selectionData} />
</Suspense>
{/* Client Selection Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>
<ClientSelectionSection selectionData={selectionData} initialSelectedClient={selectionData} onClientSelect={handleClientSelection} />
<ClientSelectionSection selectionData={selectionData} refreshSelection={refreshSelection} updateSelection={updateSelection} />
</Suspense>
{/* Menu Items Section */}
<Suspense fallback={<div><LoadingContent height="h-16" size="w-36 h-48" key={"loading-content"} plane="h-full w-full" /></div>}>

View File

@@ -2,32 +2,44 @@
import { FC } from "react";
import { Briefcase } from "lucide-react";
interface Props {
item: any;
isSelected: boolean;
onClickHandler: (item: any) => void;
selectedItem: any;
refreshSelection: () => Promise<void>;
updateSelection: (newSelection: any) => Promise<boolean>;
}
const RenderOneClientSelection: FC<Props> = ({ item, isSelected, onClickHandler }) => {
if (isSelected) {
const selectFromSelectionList = (item: any, selectedItem: any, updateSelection: (newSelection: any) => Promise<boolean>, refreshSelection: () => Promise<void>) => {
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
if (selectedUUID !== itemUUID) { updateSelection(item); refreshSelection() }
}
const RenderOneClientSelection: FC<Props> = ({ item, selectedItem, updateSelection, refreshSelection }) => {
const selectedUUID = selectedItem?.uu_id || selectedItem?.build_living_space_uu_id;
const itemUUID = item?.uu_id || item?.build_living_space_uu_id;
const getDisplayName = () => { if (item.public_name) return item.public_name; if (item.part_name) return item.part_name; return "No Name" };
const getDescription = () => { if (item.duty) return item.duty; if (item.description) return item.description; if (item.code) return item.code; return "" };
const getInitials = () => { const name = getDisplayName(); return name.slice(0, 2) };
if (selectedUUID !== itemUUID) {
return (
<div key={item.uu_id} onClick={() => { onClickHandler(item) }}
<div key={itemUUID} onClick={() => { selectFromSelectionList(item, selectedItem, updateSelection, refreshSelection) }}
className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all hover:shadow-md mb-2 cursor-pointer">
<div className="bg-amber-300 p-2 hover:bg-amber-400 transition-all">
<div className="bg-amber-800 p-2 hover:bg-amber-900 transition-all">
<div className="flex items-center">
<div className="mr-2 relative">
<div className="w-8 h-8 rounded-full bg-amber-400 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Company" className="w-full h-full object-cover" />) :
(<div className="text-white text-xs font-bold">{(item.public_name || "No Name").slice(0, 2)}</div>)}
<div className="w-8 h-8 rounded-full bg-amber-700 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Occupant" className="w-full h-full object-cover" />) :
(<div className="text-white text-xs font-bold">{getInitials()}</div>)}
</div>
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-amber-400">
<Briefcase size={8} className="text-amber-600" />
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-amber-600">
<Briefcase size={8} className="text-amber-800" />
</div>
</div>
<div className="overflow-hidden">
<h2 className="text-xs font-bold text-black truncate">{item.public_name} {item.company_type}</h2>
<p className="text-xs text-amber-800 truncate">{item.duty}</p>
<h2 className="text-xs font-bold text-white truncate">{getDisplayName()} {item.company_type || ''}</h2>
<p className="text-xs text-amber-200 truncate">{getDescription()}</p>
</div>
</div>
</div>
@@ -35,21 +47,21 @@ const RenderOneClientSelection: FC<Props> = ({ item, isSelected, onClickHandler
)
}
return (
<div key={item.uu_id} className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all mb-2 cursor-pointer">
<div className="bg-gray-100 p-2">
<div key={itemUUID} className="w-full text-xs bg-white shadow rounded-lg overflow-hidden transition-all mb-2 pointer-events-none opacity-70">
<div className="bg-amber-300 p-2">
<div className="flex items-center">
<div className="mr-2 relative">
<div className="w-8 h-8 rounded-full bg-gray-300 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Company" className="w-full h-full object-cover" />) :
(<div className="text-white text-xs font-bold">{(item.duty || "No Duty").slice(0, 2)}</div>)}
<div className="w-8 h-8 rounded-full bg-gray-400 flex items-center justify-center overflow-hidden border border-white">
{item.avatar ? (<img src={item.avatar} alt="Occupant" className="w-full h-full object-cover opacity-70" />) :
(<div className="text-white text-xs font-bold">{getInitials()}</div>)}
</div>
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-gray-300">
<Briefcase size={8} className="text-gray-600" />
<div className="absolute -bottom-0.5 -right-0.5 bg-white p-0.5 rounded-full border border-gray-400">
<Briefcase size={8} className="text-gray-500" />
</div>
</div>
<div className="overflow-hidden">
<h2 className="text-xs font-bold text-gray-700 truncate">{item.public_name} {item.company_type}</h2>
<p className="text-xs text-gray-600 truncate">{item.duty}</p>
<h2 className="text-xs font-bold text-gray-600 truncate">{getDisplayName()} {item.company_type || ''}</h2>
<p className="text-xs text-gray-500 truncate">{getDescription()}</p>
</div>
</div>
</div>

View File

@@ -1,15 +1,29 @@
'use client';
import { FC } from "react";
import { ClientUser } from "@/types/mutual/context/validations";
import { ClientOnline } from "@/types/mutual/context/validations";
import { ClientUser } from "@/types/mutual/context";
import { ClientOnline } from "@/types/mutual/context";
import { ClientSelection } from "@/types/mutual/context";
interface UserProfileSectionProps {
userData: ClientUser | null;
onlineData: ClientOnline | null;
selectionData: ClientSelection;
}
const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData }) => {
const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData, selectionData }) => {
console.log("selectionData", selectionData)
if (!selectionData?.activeSelection) return null;
let selectionDefinitionFirst = "";
let selectionDefinitionSecond = "";
if (selectionData.activeSelection?.description && selectionData.activeSelection?.part_name) {
selectionDefinitionFirst = selectionData?.activeSelection?.description || "No selection";
selectionDefinitionSecond = selectionData?.activeSelection?.part_name || "No selection";
} else {
selectionDefinitionFirst = selectionData?.activeSelection?.public_name || "No selection";
selectionDefinitionSecond = selectionData?.activeSelection?.duty || "No selection";
}
if (!userData) return null;
return (
<div className="mb-2">
@@ -26,7 +40,8 @@ const UserProfileSection: FC<UserProfileSectionProps> = ({ userData, onlineData
<div className="overflow-hidden">
<h2 className="text-sm font-bold text-black truncate">{userData?.person ? `${userData.person.firstname} ${userData.person.surname}` : 'User'}</h2>
<p className="text-xs text-amber-800 truncate">{userData?.email || 'No email'}</p>
<p className="text-xs font-medium capitalize">{onlineData?.userType || 'guest'}</p>
<p className="text-xs font-medium capitalize">{selectionDefinitionFirst}</p>
<p className="text-xs font-medium capitalize">{selectionDefinitionSecond || ''}</p>
</div>
</div>
</div>

View File

@@ -3,6 +3,7 @@ import { redis } from "@/lib/redis";
import { functionRetrieveUserSelection } from "@/fetchers/fecther";
import { ClientSelection, AuthError } from "@/fetchers/types/context";
import { getCompleteFromRedis, setCompleteToRedis } from "@/fetchers/custom/context/complete/fetch";
import { loginSelectEmployee, loginSelectOccupant } from "@/fetchers/custom/login/login";
const getSelectionFromRedis = async (): Promise<ClientSelection> => {
try {
@@ -17,7 +18,7 @@ const getSelectionFromRedis = async (): Promise<ClientSelection> => {
} catch (error) { return { selectionList: [], activeSelection: {} } }
}
const setSelectionToRedis = async (selectionObject: ClientSelection) => {
const setActiveSelectionToRedis = async (selectionObject: any) => {
try {
const decrpytUserSelection = await functionRetrieveUserSelection()
if (!decrpytUserSelection) throw new AuthError("No user selection found");
@@ -30,10 +31,19 @@ const setSelectionToRedis = async (selectionObject: ClientSelection) => {
const oldData = await getCompleteFromRedis();
if (!oldData) throw new AuthError("No old data found in redis");
await setCompleteToRedis({ ...oldData, selection: selectionObject })
await setCompleteToRedis({
...oldData, selection: {
selectionList: oldData.selection.selectionList,
activeSelection: selectionObject
}
})
if (oldData.online.userType.toUpperCase() === "EMPLOYEE") {
await loginSelectEmployee({ uuid: selectionObject.uuid });
} else if (oldData.online.userType.toUpperCase() === "OCCUPANT") {
await loginSelectOccupant({ uuid: selectionObject.build_living_space_uu_id });
}
return true;
} catch (error) {
// Re-throw AuthError instances, wrap other errors as AuthError
if (error instanceof AuthError) {
throw error;
} else {
@@ -42,4 +52,4 @@ const setSelectionToRedis = async (selectionObject: ClientSelection) => {
}
}
export { getSelectionFromRedis, setSelectionToRedis };
export { getSelectionFromRedis, setActiveSelectionToRedis };

View File

@@ -15,7 +15,7 @@ import {
import { retrievePageList } from "@/fetchers/mutual/cookies/token";
import { deleteAllCookies } from "@/fetchers/mutual/cookies/cookie-actions";
import { setMenuToRedis } from "@/fetchers/custom/context/page/menu/fetch";
import { LoginViaAccessKeys, LoginSelect, LoginSelectOccupant } from "@/fetchers/types/login/validations";
import { LoginViaAccessKeys, LoginSelect } from "@/fetchers/types/login/validations";
async function logoutActiveSession() {
const response = await fetchDataWithToken(urlLogoutEndpoint, {}, "GET", false);
@@ -25,29 +25,50 @@ async function logoutActiveSession() {
async function initRedis(loginRespone: any, firstSelection: any, accessToken: string, redisKey: string) {
let alreadyAtRedis = null
try {
const redisData = await getCompleteFromRedis();
alreadyAtRedis = redisData;
} catch (error) { }
console.log("loginRespone", loginRespone)
console.log("firstSelection", firstSelection)
console.log("accessToken", accessToken)
console.log("redisKey", redisKey)
if (!alreadyAtRedis) {
const loginObjectToRedis = {
online: {
...defaultValuesOnline,
lastLogin: new Date(),
userType: `${loginRespone.user_type}`.toUpperCase(),
lang: loginRespone.user.person.country_code.toLowerCase(),
},
pageConfig: defaultValuesPageConfig,
menu: defaultValuesMenu,
header: defaultValuesHeader,
selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
user: loginRespone.user,
settings: { lastOnline: new Date(), token: accessToken },
chatRoom: [],
notifications: [],
messages: [],
if (loginRespone.user_type.toUpperCase() === "EMPLOYEE") {
const loginObjectToRedis = {
online: { ...defaultValuesOnline, lastLogin: new Date(), userType: `${loginRespone.user_type}`.toUpperCase(), lang: loginRespone.user.person.country_code.toLowerCase() },
pageConfig: defaultValuesPageConfig,
menu: defaultValuesMenu,
header: defaultValuesHeader,
selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
user: loginRespone.user,
settings: { lastOnline: new Date(), token: accessToken },
chatRoom: [],
notifications: [],
messages: [],
}
await setNewCompleteToRedis(loginObjectToRedis, redisKey);
} else if (loginRespone.user_type.toUpperCase() === "OCCUPANT") {
const loginObjectToRedis = {
online: { ...defaultValuesOnline, lastLogin: new Date(), userType: `${loginRespone.user_type}`.toUpperCase(), lang: "tr" },
pageConfig: defaultValuesPageConfig,
menu: defaultValuesMenu,
header: defaultValuesHeader,
selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
user: loginRespone.user,
settings: { lastOnline: new Date(), token: accessToken },
chatRoom: [],
notifications: [],
messages: [],
}
await setNewCompleteToRedis(loginObjectToRedis, redisKey);
}
await setNewCompleteToRedis(loginObjectToRedis, redisKey);
}
}
async function initFirstSelection(firstSelection: any, userType: string) {
if (userType === "EMPLOYEE") {
const uuid = firstSelection.uuid;
await loginSelectEmployee({ uuid });
} else if (userType === "OCCUPANT") {
const uuid = firstSelection.build_living_space_uu_id;
await loginSelectOccupant({ uuid });
}
}
@@ -68,22 +89,24 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
if (response.status === 200 || response.status === 202) {
const loginRespone: any = response?.data;
const firstSelection = loginRespone.selection_list.find((item: any) => item.uu_id === loginRespone.selection_list[0].uu_id);
let firstSelection = null
if (loginRespone.user_type.toUpperCase() === "EMPLOYEE") {
firstSelection = loginRespone.selection_list.find((item: any) => item.uu_id === loginRespone.selection_list[0].uu_id);
} else if (loginRespone.user_type.toUpperCase() === "OCCUPANT") {
const firstKeyOfSelectionList = Object.keys(loginRespone.selection_list)[0];
firstSelection = loginRespone.selection_list[firstKeyOfSelectionList].occupants[0];
}
const nextCrypto = new NextCrypto(tokenSecret);
const accessToken = await nextCrypto.encrypt(loginRespone.access_token);
const redisKey = `CLIENT:${loginRespone.user_type.toUpperCase()}:${firstSelection.uu_id}`;
const userType = loginRespone.user_type.toUpperCase()
const redisKey = `CLIENT:${userType}:${loginRespone.user.uuid}`;
const redisKeyAccess = await nextCrypto.encrypt(redisKey);
const usersSelection = await nextCrypto.encrypt(
JSON.stringify({
selected: firstSelection.uu_id,
userType: loginRespone.user_type.toUpperCase(),
redisKey,
})
);
const usersSelection = await nextCrypto.encrypt(JSON.stringify({ selected: firstSelection, userType, redisKey }));
await initRedis(loginRespone, firstSelection, accessToken, redisKey);
cookieStore.set({
name: "eys-zzz",
value: accessToken,
@@ -99,12 +122,16 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
value: usersSelection,
...cookieObject,
});
try {
return {
completed: true,
message: "Login successful",
status: 200,
data: loginRespone,
data: {
userType,
firstSelection,
},
};
} catch (error) {
console.error("JSON parse error:", error);
@@ -112,7 +139,10 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
completed: false,
message: "Login NOT successful",
status: 401,
data: "{}",
data: {
userType,
firstSelection,
},
};
}
}
@@ -135,65 +165,32 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
}
async function loginSelectEmployee(payload: LoginSelect) {
const cookieStore = await cookies();
const nextCrypto = new NextCrypto(tokenSecret);
const employeeUUID = payload.uuid;
const redisKey = `CLIENT:EMPLOYEE:${employeeUUID}`;
const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: employeeUUID }, "POST", false);
cookieStore.delete({ name: "eys-sel", ...cookieObject });
console.log("selectResponse", selectResponse)
if (selectResponse.status === 200 || selectResponse.status === 202) {
const usersSelection = await nextCrypto.encrypt(
JSON.stringify({
selected: employeeUUID,
userType: "employee",
redisKey,
})
);
cookieStore.set({
name: "eys-sel",
value: usersSelection,
...cookieObject,
});
try {
const pageList = await retrievePageList()
await setMenuToRedis({
selectionList: pageList,
activeSelection: "/dashboard"
})
console.log("selectResponse", selectResponse)
} catch (error) { }
}
return selectResponse;
}
async function loginSelectOccupant(payload: LoginSelectOccupant) {
async function loginSelectOccupant(payload: LoginSelect) {
const livingSpaceUUID = payload.uuid;
const cookieStore = await cookies();
const nextCrypto = new NextCrypto(tokenSecret);
const selectResponse: any = await fetchDataWithToken(urlLoginSelectEndpoint, { uuid: livingSpaceUUID }, "POST", false);
const redisKey = `CLIENT:OCCUPANT:${livingSpaceUUID}`;
cookieStore.delete("eys-sel");
console.log("selectResponse", selectResponse)
if (selectResponse.status === 200 || selectResponse.status === 202) {
const usersSelection = await nextCrypto.encrypt(
JSON.stringify({
selected: livingSpaceUUID,
userType: "OCCUPANT",
redisKey,
})
);
cookieStore.set({
name: "eys-sel",
value: usersSelection,
...cookieObject,
});
try {
console.log("selectResponse", selectResponse)
} catch (error) { }
}
return selectResponse;
}
export {
loginViaAccessKeys,
initFirstSelection,
loginSelectEmployee,
loginSelectOccupant,
logoutActiveSession,

View File

@@ -8,8 +8,4 @@ interface LoginSelect {
uuid: string;
}
interface LoginSelectOccupant {
uuid: any;
}
export type { LoginViaAccessKeys, LoginSelect, LoginSelectOccupant };
export type { LoginViaAccessKeys, LoginSelect };

View File

@@ -1,10 +1,7 @@
import { DashboardPage } from "@/components/custom/content/DashboardPage";
const pageIndexMulti: Record<string, Record<string, React.FC<any>>> = {
"/dashboard": {
DashboardPage: DashboardPage,
},
// Add more pages as needed
"/dashboard": { DashboardPage: DashboardPage },
};
export { pageIndexMulti };