added pages tested via backend
This commit is contained in:
parent
9232da69d3
commit
a986ddbb95
|
|
@ -37,7 +37,5 @@ export class AccountsController {
|
|||
@Post('filter')
|
||||
@HttpCode(200)
|
||||
@UseGuards(AuthControlGuard, EndpointControlGuard)
|
||||
async filterAccounts(@Body() query: any, @Req() req: any) {
|
||||
return await this.navigator.getFunction(req, this.accountsService.mapper, query)
|
||||
}
|
||||
async filterAccounts(@Body() query: any, @Req() req: any) { return await this.navigator.getFunction(req, this.accountsService.mapper, query) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ import {
|
|||
import { SuperUsersService } from './superusers/superusers.service';
|
||||
import { UrlHandler } from '../utils/navigator/urlHandler';
|
||||
import { Navigator } from '@/src/utils/navigator/navigator';
|
||||
import { NavigatorModule } from '../navigator/navigator.module';
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, UtilsModule, RedisModule],
|
||||
imports: [PrismaModule, UtilsModule, RedisModule, NavigatorModule],
|
||||
providers: [
|
||||
AccountsService,
|
||||
AuthControlGuard,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { SuperUsersService } from './superusers/superusers.service';
|
||||
import { EventsService } from '../navigator/events/events.service';
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
|
|
@ -7,9 +8,32 @@ export class AccountsService {
|
|||
|
||||
constructor(
|
||||
private superUsersService: SuperUsersService,
|
||||
private eventService: EventsService,
|
||||
) {
|
||||
this.mapper = {
|
||||
"j0adQOsJBR0xq24dxLKdDU9EQRmt4gzE05CmhA": this.superUsersService,
|
||||
}
|
||||
}
|
||||
|
||||
async onModuleInit() {
|
||||
Object.entries(this.mapper).map(async ([key, value]) => {
|
||||
const service = value as any
|
||||
await this.eventService.setEvents(service.events, "AccountsService")
|
||||
})
|
||||
// const accountPages = await fetch(
|
||||
// "http://localhost:3000/pages",
|
||||
// {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// },
|
||||
// body: JSON.stringify({
|
||||
// token: 'j0adQOsJBR0xq24dxLKdDU9EQRmt4gzE05CmhA',
|
||||
// pages: {
|
||||
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,8 +235,7 @@ export class SelectService {
|
|||
value: part.api_enum_dropdown_build_parts_part_type_idToapi_enum_dropdown.value
|
||||
},
|
||||
build: {
|
||||
uu_id: build.uu_id,
|
||||
build_name: build.build_name
|
||||
uu_id: build.uu_id, build_name: build.build_name
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -245,19 +244,9 @@ export class SelectService {
|
|||
kind: UserType.occupant
|
||||
});
|
||||
|
||||
// Render page and menu
|
||||
const eventsObject = await this.eventService.getEventsOccupants(livingSpace.uu_id)
|
||||
eventsObject && (occupantToken.events = eventsObject)
|
||||
|
||||
const tokenSelect = await this.redis.setSelectToRedis(
|
||||
accessToken,
|
||||
occupantToken,
|
||||
accessObject.value.users.uu_id,
|
||||
dto.uuid
|
||||
);
|
||||
occupantToken.events = await this.eventService.getEventsOccupants(livingSpace.uu_id) || null
|
||||
const tokenSelect = await this.redis.setSelectToRedis(accessToken, occupantToken, accessObject.value.users.uu_id, dto.uuid);
|
||||
return { message: 'Select successful', token: tokenSelect };
|
||||
} else {
|
||||
throw new NotAcceptableException('Invalid user type');
|
||||
}
|
||||
} else { throw new NotAcceptableException('Invalid user type') }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { Db, Document, Collection, Filter, ObjectId, UpdateResult } from 'mongodb';
|
||||
import { Db, Document, Collection, Filter, ObjectId, UpdateResult, Sort, SortDirection } from 'mongodb';
|
||||
|
||||
@Injectable()
|
||||
export class MongoService {
|
||||
|
|
@ -12,6 +12,35 @@ export class MongoService {
|
|||
|
||||
async getDb() { return this.collection }
|
||||
|
||||
async create(data: Record<string, any>): Promise<Document> {
|
||||
const insertResult = await this.collection.insertOne(data);
|
||||
if (!insertResult.acknowledged) { throw new Error('Failed to insert document') }
|
||||
return await this.getOne(insertResult.insertedId);
|
||||
}
|
||||
async createMany(data: Record<string, any>[]): Promise<number> {
|
||||
const insertResult = await this.collection.insertMany(data);
|
||||
if (!insertResult.acknowledged) { throw new Error('Failed to insert documents') }
|
||||
return insertResult.insertedCount;
|
||||
}
|
||||
|
||||
async findManyKeyWhere(value: string, limit?: number, skip?: number): Promise<Document[]> {
|
||||
const docs = await this.collection.find({
|
||||
$where: function () {
|
||||
return Object.keys(this).some(key => key.includes(value));
|
||||
}
|
||||
}).toArray();
|
||||
return docs;
|
||||
}
|
||||
|
||||
async findManyKeyWhereValue(value: string, limit?: number, skip?: number): Promise<Document[]> {
|
||||
const docs = await this.collection.find({
|
||||
$where: function () {
|
||||
return Object.keys(this).some(key => this[key] === value);
|
||||
}
|
||||
}).toArray();
|
||||
return docs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a document by UUID or create it if it doesn't exist
|
||||
* @param data Document data with UUID field
|
||||
|
|
@ -53,10 +82,9 @@ export class MongoService {
|
|||
* const user = await mongoService.findOne('12345');
|
||||
* This will search for documents with uuid matching pattern ^TOKEN:12345:
|
||||
*/
|
||||
async findOne(filter: Filter<Document>): Promise<Document> {
|
||||
async findOne(filter: Filter<Document>): Promise<Document | null> {
|
||||
const result = await this.collection.findOne(filter);
|
||||
if (!result) { throw new Error(`Document with ID key ${filter} not found`) }
|
||||
return result;
|
||||
return result ? result : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,11 +102,19 @@ export class MongoService {
|
|||
* @example
|
||||
* Find users by role
|
||||
* const admins = await mongoService.findMany({ role: 'admin' } as Filter<Document>);
|
||||
* const documents = await mongoService.findMany(filter, limit, skip, ['name', 'createdAt'], ['asc', 'desc']);
|
||||
*/
|
||||
async findMany(filter: Filter<Document>, limit?: number, skip?: number): Promise<Document[]> {
|
||||
async findMany(filter: Filter<Document>, limit?: number, skip?: number, sortBys?: string[], sortDirections?: SortDirection[]): Promise<Document[]> {
|
||||
let query = this.collection.find(filter);
|
||||
if (typeof skip === 'number') { query = query.skip(skip) }
|
||||
if (typeof limit === 'number') { query = query.limit(limit) }
|
||||
if (sortBys && sortDirections && sortBys.length === sortDirections.length) {
|
||||
const sortOptions = sortBys.reduce<Record<string, SortDirection>>((acc, sortBy, index) => ({
|
||||
...acc,
|
||||
[sortBy]: sortDirections[index]
|
||||
}), {});
|
||||
query = query.sort(sortOptions);
|
||||
}
|
||||
return await query.toArray();
|
||||
}
|
||||
|
||||
|
|
@ -254,4 +290,5 @@ export class MongoService {
|
|||
|
||||
return await this.collection.find(query as unknown as Filter<Document>).toArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ export class AuthControlGuard implements CanActivate {
|
|||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const req = context.switchToHttp().getRequest();
|
||||
const accessToken = this.cacheService.mergeLoginKey(req);
|
||||
if (!accessToken) { throw new ForbiddenException('Send to Login') }
|
||||
this.cacheService.renewTtlLoginFromRedis(req);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +34,9 @@ export class EndpointControlGuard implements CanActivate {
|
|||
const keyUrl = `${path}:${method.toUpperCase()}`;
|
||||
const driveToken = await this.urlHandler.getSecureUrlToken(keyUrl);
|
||||
const accessObject = await this.cacheService.getSelectFromRedis(req);
|
||||
if (!accessObject) { throw new ForbiddenException('Access denied') }
|
||||
req.driveToken = `${driveToken}:${accessObject?.value.functionsRetriever}`;
|
||||
this.cacheService.renewTtlSelectFromRedis(req);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,21 @@ export class mongoGetValidator {
|
|||
@IsNumber()
|
||||
@IsOptional()
|
||||
skip: number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class eventSetValidator {
|
||||
@IsString()
|
||||
usersUUID: string;
|
||||
|
||||
@IsObject()
|
||||
event: Record<string, Record<string, Record<string, string>>>;
|
||||
}
|
||||
|
||||
export class eventGetValidator {
|
||||
@IsString()
|
||||
usersUUID: string;
|
||||
|
||||
@IsString()
|
||||
typeToken: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import { IsString, IsObject, IsOptional, IsNumber, ValidateNested } from 'class-
|
|||
export class EventsSetterValidator {
|
||||
|
||||
@IsObject()
|
||||
data: Record<string, Record<string, Record<string, string>>>;
|
||||
event: Record<string, Record<string, Record<string, string>>>;
|
||||
|
||||
@IsString()
|
||||
dutyUUID: string; // UUID of employee or occupant
|
||||
userUUID: string; // UUID of employee or occupant
|
||||
}
|
||||
|
||||
export class EventsGetterValidator {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export class EventsService {
|
|||
seperator = "/"
|
||||
|
||||
private async getBuildUUID(uuid: string) {
|
||||
console.log('uuid', uuid)
|
||||
const livingSpace = await this.prisma.build_living_space.findFirstOrThrow({
|
||||
where: { uu_id: uuid },
|
||||
select: {
|
||||
|
|
@ -97,20 +98,18 @@ export class EventsService {
|
|||
await this.mongoService.set(`EVENTS${this.seperator}${buildUUID}`);
|
||||
}
|
||||
|
||||
private async findByRegexKey(regexKey: string, searchType: SearchType = 'value'): Promise<Document[]> {
|
||||
const tokens = await this.mongoService.findByRegexAcrossFields(regexKey, 'i', searchType);
|
||||
if (tokens.length === 0) {
|
||||
throw new NotFoundException('Token not found')
|
||||
}
|
||||
return tokens;
|
||||
private escapeRegex(text: string): string {
|
||||
return text.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
|
||||
}
|
||||
|
||||
private async findByFilter(filter: object): Promise<Document[]> {
|
||||
const tokens = await this.mongoService.findMany(filter);
|
||||
if (tokens.length === 0) {
|
||||
throw new NotFoundException('Token not found')
|
||||
}
|
||||
return tokens;
|
||||
async getAllEventsOccupants(userTypeToken: string): Promise<Document[] | null> {
|
||||
await this.mongoService.set(`Events`)
|
||||
return await this.mongoService.findManyKeyWhere(userTypeToken) || null;
|
||||
}
|
||||
|
||||
async getAllEventsEmployees(userTypeToken: string): Promise<Document[] | null> {
|
||||
await this.mongoService.set(`Events`)
|
||||
return await this.mongoService.findManyKeyWhere(userTypeToken) || null;
|
||||
}
|
||||
|
||||
async getEventsOccupants(livingSpaceUUID: string) {
|
||||
|
|
@ -136,51 +135,67 @@ export class EventsService {
|
|||
return eventsObject
|
||||
}
|
||||
|
||||
async getEventsEmployees(@Body() body: EventsGetterValidator) {
|
||||
const companyUUID = await this.getCompanyUUID(body.dutyUUID);
|
||||
async getEventsEmployees(employeeUUID: string) {
|
||||
const eventsObject = {}
|
||||
const companyUUID = await this.getCompanyUUID(employeeUUID);
|
||||
if (!companyUUID) { throw new NotFoundException('Company not found') }
|
||||
await this.mongoService.set(`EVENTS${this.seperator}${companyUUID}`);
|
||||
if (body.regexKey) {
|
||||
// Use the new flattened search for regex with search type
|
||||
const searchType: SearchType = body.searchType as SearchType || 'value';
|
||||
const tokens = await this.mongoService.findByRegexAcrossFields(body.regexKey, 'i', searchType);
|
||||
if (tokens.length === 0) { throw new NotFoundException('Token not found') }
|
||||
return { data: tokens, message: 'Tokens found' };
|
||||
} else if (body.filter) {
|
||||
const tokens = await this.mongoService.findMany(body.filter);
|
||||
if (tokens.length === 0) { throw new NotFoundException('Token not found') }
|
||||
return { data: tokens, message: 'Tokens found' };
|
||||
} else { throw new NotFoundException('Regex key or filter is required') }
|
||||
const eventsResponse = await this.mongoService.findOne({ [employeeUUID]: { $exists: true } });
|
||||
if (eventsResponse && typeof eventsResponse === 'object') {
|
||||
const mapOfEvents = eventsResponse[employeeUUID];
|
||||
if (mapOfEvents && typeof mapOfEvents === 'object') {
|
||||
const userTypeTokenKey = Object.keys(mapOfEvents)[0];
|
||||
const userTypeTokenValue = mapOfEvents[userTypeTokenKey];
|
||||
if (userTypeTokenValue && typeof userTypeTokenValue === 'object') {
|
||||
for (const siteUrlTokenKey of Object.keys(userTypeTokenValue)) {
|
||||
const siteUrlTokenValue = userTypeTokenValue[siteUrlTokenKey];
|
||||
eventsObject[`${siteUrlTokenKey}:${userTypeTokenKey}`] = siteUrlTokenValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return eventsObject
|
||||
}
|
||||
|
||||
private async setSavedEventToMapper(data: any, useruuid: string) {
|
||||
await this.mongoService.set(`MAP${this.seperator}EVENTS`);
|
||||
const events = await this.mongoService.findOrCreate({ uuid: `EVENTS:${useruuid}:${data.uuid}`, data });
|
||||
const events = await this.mongoService.findOrCreate({ uuid: `EVENTS${this.seperator}${useruuid}:${data.uuid}`, data });
|
||||
}
|
||||
|
||||
private async deleteSavedEventFromMapper(data: any, useruuid: string) {
|
||||
await this.mongoService.set(`MAP${this.seperator}EVENTS`);
|
||||
const events = await this.mongoService.deleteMany({ uuid: `EVENTS:${useruuid}:${data.uuid}` });
|
||||
const events = await this.mongoService.deleteMany({ uuid: `EVENTS${this.seperator}${useruuid}:${data.uuid}` });
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
async setEventsEmployees(@Body() body: EventsSetterValidator) {
|
||||
const companyUUID = await this.getCompanyUUID(body.dutyUUID);
|
||||
const companyUUID = await this.getCompanyUUID(body.userUUID);
|
||||
if (!companyUUID) { throw new NotFoundException('Company not found') }
|
||||
await this.mongoService.set(`EVENTS${this.seperator}${companyUUID}`);
|
||||
const events = await this.mongoService.findOrCreate(body.data);
|
||||
const events = await this.mongoService.findOrCreate(body.event);
|
||||
// await this.setSavedEventToMapper(events, body.dutyUUID);
|
||||
return events;
|
||||
}
|
||||
|
||||
async setEventsOccupants(@Body() body: EventsSetterValidator) {
|
||||
const buildUUID = await this.getBuildUUID(body.dutyUUID);
|
||||
const buildUUID = await this.getBuildUUID(body.userUUID);
|
||||
if (!buildUUID) { throw new NotFoundException('Build not found') }
|
||||
await this.mongoService.set(`EVENTS${this.seperator}${buildUUID}`);
|
||||
const events = await this.mongoService.findOrCreate(body.data);
|
||||
const events = await this.mongoService.findOrCreate(body.event);
|
||||
return events;
|
||||
}
|
||||
|
||||
async setEvents(events: any, serviceName: string) {
|
||||
await this.mongoService.set(`Events`);
|
||||
for (const [key, value] of Object.entries(events)) {
|
||||
const description = (value as Array<any>)[0].endpoint || "";
|
||||
console.log(`Setting events for ${serviceName} ${description} is carried to nosql database store.`)
|
||||
await this.mongoService.deleteMany({ [key]: { $exists: true } });
|
||||
await this.mongoService.create({ [key]: value });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteEventsEmployees(@Body() body: EventsGetterValidator) {
|
||||
const companyUUID = await this.getCompanyUUID(body.dutyUUID);
|
||||
if (!companyUUID) { throw new NotFoundException('Company not found') }
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ const menuForOccupantDefinition = [
|
|||
icon: "",
|
||||
text: { "tr": "Pano", "en": "Dashboard" },
|
||||
page: "/dashboard",
|
||||
token: null,
|
||||
token: "IbGpchaw3muiY7y9rnV0EJYoPy5XoOOrITT9JlfIbqwE",
|
||||
color: "",
|
||||
subs: [],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,25 +1,174 @@
|
|||
import { Controller, Post, NotFoundException, Body } from '@nestjs/common';
|
||||
import { PrismaService } from '@/src/prisma.service';
|
||||
import { EventsService } from '@/src/navigator/events/events.service';
|
||||
import { MongoService } from '@/src/database/mongo/mongo.service';
|
||||
import { mongoSetValidator, mongoGetValidator } from '@/src/navigator/dtoValidator';
|
||||
import { UrlHandler } from '@/src/utils/navigator/urlHandler';
|
||||
import { eventSetValidator, eventGetValidator } from './dtoValidator';
|
||||
|
||||
const tokens = { employeeTypeToken: "L9wBdwV9OlxsLAgh", occupantTypeToken: "j0adQOsJBR0xq24d" }
|
||||
|
||||
@Controller('navigator')
|
||||
export class NavigatorController {
|
||||
constructor(private mongoService: MongoService) { }
|
||||
constructor(private prismaService: PrismaService, private eventService: EventsService, private mongoService: MongoService, private urlHandler: UrlHandler) { }
|
||||
|
||||
@Post('event/set')
|
||||
async setEvent(@Body() body: any) { }
|
||||
async setEvent(@Body() body: eventSetValidator) {
|
||||
const user = await this.prismaService.users.findFirst({ where: { uu_id: body.usersUUID }, include: { people: true } });
|
||||
if (!user) { throw new NotFoundException('User not found') }
|
||||
const userType = await this.prismaService.user_types.findFirstOrThrow({ where: { token: body.event.token } })
|
||||
const person = user.people[0]
|
||||
const people2userType = await this.prismaService.employees.findFirstOrThrow({ where: { uu_id: person.uu_id, staff: { user_type_uu_id: userType.uu_id } } })
|
||||
if (!people2userType) { throw new NotFoundException('User type not found') }
|
||||
if (userType.type_token == tokens.employeeTypeToken) { await this.eventService.setEventsEmployees({ event: body.event, userUUID: body.usersUUID }) }
|
||||
else if (userType.type_token == tokens.occupantTypeToken) { await this.eventService.setEventsOccupants({ event: body.event, userUUID: body.usersUUID }) }
|
||||
else { throw new NotFoundException('User type not found') }
|
||||
return body.event;
|
||||
}
|
||||
|
||||
@Post('event/get')
|
||||
async getEvent(@Body() body: any) {
|
||||
// Get all events from backend statics & Get users registered event from mongo service
|
||||
async getEvent(@Body() body: eventGetValidator) {
|
||||
const { typeToken, usersUUID } = body
|
||||
const userType = await this.prismaService.user_types.findFirstOrThrow({ where: { token: typeToken } })
|
||||
if (userType.type_token == tokens.employeeTypeToken) {
|
||||
const allEvents = await this.eventService.getAllEventsEmployees(typeToken);
|
||||
if (!allEvents) { throw new NotFoundException('Events not found') }
|
||||
const selectedEvents = await this.eventService.getEventsEmployees(usersUUID);
|
||||
const selectedEventsKeys = Object.values(selectedEvents).map((value: any) => value.key) || [];
|
||||
for (const event of allEvents) { if (selectedEventsKeys.includes(event.key)) { event.isSelected = true } else { event.isSelected = false } }
|
||||
return { events: allEvents }
|
||||
}
|
||||
else if (userType.type_token == tokens.occupantTypeToken) {
|
||||
const allEvents = await this.eventService.getAllEventsOccupants(typeToken);
|
||||
if (!allEvents) { throw new NotFoundException('Events not found') }
|
||||
const selectedEvents = await this.eventService.getEventsOccupants(usersUUID);
|
||||
const selectedEventsKeys = Object.values(selectedEvents).map((value: any) => value.key) || [];
|
||||
for (const event of allEvents) { if (selectedEventsKeys.includes(event.key)) { event.isSelected = true } else { event.isSelected = false } }
|
||||
return { events: allEvents }
|
||||
} else { throw new NotFoundException('User type not found') }
|
||||
}
|
||||
|
||||
@Post('page/set')
|
||||
async setPage(@Body() body: any) { }
|
||||
async setPage(@Body() body: { usersUUID: string, usersToken: string, url: string, page: Record<string, any> }) {
|
||||
const user = await this.prismaService.users.findFirstOrThrow({ where: { uu_id: body.usersUUID }, include: { people: true } });
|
||||
const userType = await this.prismaService.user_types.findFirstOrThrow({ where: { token: body.usersToken } })
|
||||
const urlToken = await this.urlHandler.getSecureUrlToken(body.url)
|
||||
if (userType.type_token == tokens.employeeTypeToken) {
|
||||
const person = user.people[0]
|
||||
const employee = await this.prismaService.employees.findFirstOrThrow({ where: { people_id: person.id, staff: { user_type_id: userType.id } } })
|
||||
const companyUUID = await this.prismaService.companies.findFirstOrThrow({
|
||||
where: { departments: { some: { duties: { some: { staff: { some: { uu_id: employee.staff_uu_id } } } } } } }, select: { uu_id: true }
|
||||
})
|
||||
this.mongoService.set(`Pages/${companyUUID.uu_id}`);
|
||||
const userPage = await this.mongoService.findOne({ [employee.uu_id]: { $exists: true } });
|
||||
if (!userPage) {
|
||||
console.log('urlToken', urlToken)
|
||||
} else { console.log('urlToken', urlToken) }
|
||||
} else if (userType.type_token == tokens.occupantTypeToken) {
|
||||
const person = user.people
|
||||
const livingSpace = await this.prismaService.build_living_space.findFirstOrThrow({
|
||||
where: { person_id: person.id, occupant_types: { user_types: { id: userType.id } } },
|
||||
select: { uu_id: true, build_parts_id: true }
|
||||
})
|
||||
const buildUUID = await this.prismaService.build.findFirstOrThrow({
|
||||
where: { build_parts: { some: { id: livingSpace.build_parts_id } } }, select: { uu_id: true }
|
||||
})
|
||||
this.mongoService.set(`Pages/${buildUUID.uu_id}`);
|
||||
const userPage = await this.mongoService.findOne({ [user.uu_id]: { $exists: true } });
|
||||
if (!userPage) {
|
||||
const newUserPageSlot = await this.mongoService.create({ [user.uu_id]: { [`${body.usersToken}`]: { [`${urlToken}`]: `${body.page.key}` } } })
|
||||
return newUserPageSlot
|
||||
} else {
|
||||
console.log('body')
|
||||
console.dir(body, { depth: null })
|
||||
console.log('userPage')
|
||||
console.dir(userPage, { depth: null })
|
||||
const updatedUserPageSlot = await this.mongoService.updateOne(
|
||||
userPage._id, { [`${user.uu_id}.${body.usersToken}.${urlToken}`]: `${body.page.key}` }
|
||||
)
|
||||
return updatedUserPageSlot ? {
|
||||
status: "success",
|
||||
data: updatedUserPageSlot
|
||||
} : {
|
||||
status: "error",
|
||||
data: null
|
||||
}
|
||||
}
|
||||
// console.log('urlToken', { [user.uu_id]: { [`${body.usersToken}`]: { [`${urlToken}`]: `${body.page.key}` } } })
|
||||
}
|
||||
else { throw new NotFoundException('User type not found') }
|
||||
}
|
||||
|
||||
@Post('page/get')
|
||||
async getPage(@Body() body: any) {
|
||||
// Get all pages from Frontend & Get users registered page from mongo service
|
||||
async getPage(@Body() body: { usersUUID: string, token: string, url?: string, skip?: number, limit?: number }) {
|
||||
this.mongoService.set("Pages");
|
||||
const addUrlQuery = body.url ? { url: body.url } : {};
|
||||
const user = await this.prismaService.users.findFirstOrThrow({ where: { uu_id: body.usersUUID }, include: { people: true } });
|
||||
const userType = await this.prismaService.user_types.findFirstOrThrow({ where: { token: body.token } })
|
||||
if (userType.type_token == tokens.employeeTypeToken) {
|
||||
const person = user.people[0]
|
||||
const pages = await this.mongoService.findMany({
|
||||
$and: [
|
||||
{ $or: [{ includeTokens: { $in: ['*'] } }, { includeTokens: { $in: [body.token] } }] },
|
||||
{ $nor: [{ excludeTokens: { $in: ['*'] } }, { excludeTokens: { $in: [body.token] } }] },
|
||||
addUrlQuery,
|
||||
{ typeToken: tokens.employeeTypeToken },
|
||||
],
|
||||
}, body.limit || 50, body.skip || 0, ['url'], ['asc'])
|
||||
if (!pages) { throw new NotFoundException(`Pages not found. User type: ${userType.type_token}`) }
|
||||
const employee = await this.prismaService.employees.findFirstOrThrow({
|
||||
where: { people_id: person.id, staff: { user_type_id: userType.id } },
|
||||
select: { uu_id: true, staff_uu_id: true }
|
||||
})
|
||||
const companyUUID = await this.prismaService.companies.findFirstOrThrow({
|
||||
where: { departments: { some: { duties: { some: { staff: { some: { uu_id: employee.staff_uu_id } } } } } } }, select: { uu_id: true }
|
||||
})
|
||||
this.mongoService.set(`Pages/${companyUUID.uu_id}`);
|
||||
const usersPages = await this.mongoService.findMany({ [employee.uu_id]: { $exists: true } });
|
||||
return pages;
|
||||
}
|
||||
else if (userType.type_token == tokens.occupantTypeToken) {
|
||||
const person = user.people
|
||||
const pages = await this.mongoService.findMany({
|
||||
$and: [
|
||||
{ $or: [{ includeTokens: { $in: ['*'] } }, { includeTokens: { $in: [body.token] } }] },
|
||||
{ $nor: [{ excludeTokens: { $in: ['*'] } }, { excludeTokens: { $in: [body.token] } }] },
|
||||
addUrlQuery,
|
||||
{ typeToken: tokens.occupantTypeToken },
|
||||
],
|
||||
}, body.limit || 50, body.skip || 0, ['url'], ['asc'])
|
||||
console.log('pages', pages)
|
||||
if (!pages) { throw new NotFoundException(`Pages not found. User type: ${userType.type_token}`) }
|
||||
const livingSpace = await this.prismaService.build_living_space.findFirstOrThrow({
|
||||
where: { person_id: person.id, occupant_types: { user_types: { id: userType.id } } },
|
||||
select: { uu_id: true, build_parts_id: true }
|
||||
})
|
||||
console.log('livingSpace', livingSpace)
|
||||
const buildUUID = await this.prismaService.build.findFirstOrThrow({
|
||||
where: { build_parts: { some: { id: livingSpace.build_parts_id } } }, select: { uu_id: true }
|
||||
})
|
||||
this.mongoService.set(`Pages/${buildUUID.uu_id}`);
|
||||
const usersPages = await this.mongoService.findMany({ [livingSpace.uu_id]: { $exists: true } });
|
||||
console.log('usersPages', usersPages)
|
||||
return Object.entries(pages).map(([key, value]: [string, any]) => {
|
||||
if (usersPages.some((page: any) => page[key])) { value.isSelected = true } else { value.isSelected = false }
|
||||
return value;
|
||||
})
|
||||
}
|
||||
else { throw new NotFoundException('User type not found') }
|
||||
}
|
||||
|
||||
private async saveChunkToDB(data: Record<string, any>, chunkIndex: number) {
|
||||
await this.mongoService.set("Pages");
|
||||
if (chunkIndex == 1) { await this.mongoService.deleteMany({}) }
|
||||
await this.mongoService.createMany(Object.values(data));
|
||||
}
|
||||
|
||||
@Post('page/configure')
|
||||
async setPages(@Body() body: { chunkIndex: number; chunkCount: number; data: Record<string, any> }) {
|
||||
const count = Object.keys(body.data).length;
|
||||
console.log(`🧩 Chunk [${body.chunkIndex}/${body.chunkCount}] alındı. Kayıt sayısı: ${count}`);
|
||||
await this.saveChunkToDB(body.data, body.chunkIndex);
|
||||
return { message: 'Chunk işlendi', count };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ import { MenusService } from '@/src/navigator/menus/services.service';
|
|||
import { NavigatorController } from '@/src/navigator/navigator.controller';
|
||||
import { EventsService } from './events/events.service';
|
||||
import { PrismaService } from '@/src/prisma.service';
|
||||
import { UrlHandler } from '@/src/utils/navigator/urlHandler';
|
||||
|
||||
@Module({
|
||||
controllers: [NavigatorController],
|
||||
imports: [MongoModule],
|
||||
providers: [MenusService, EventsService, PrismaService],
|
||||
providers: [MenusService, EventsService, PrismaService, UrlHandler],
|
||||
exports: [MenusService, EventsService, PrismaService]
|
||||
})
|
||||
export class NavigatorModule {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,18 @@ export class Navigator {
|
|||
|
||||
constructor(private redisHandler: RedisHandlers) { }
|
||||
|
||||
async getAllInfos(mainService: any) {
|
||||
const mainServiceMapper = mainService?.mapper
|
||||
if (!mainServiceMapper) { throw new ForbiddenException(`Mapper in ${mainService.constructor.name} is missing or null`) }
|
||||
const allInfos = Object.entries(mainServiceMapper).map(([key, value]) => {
|
||||
return {
|
||||
key,
|
||||
value
|
||||
}
|
||||
})
|
||||
return allInfos
|
||||
}
|
||||
|
||||
async getInfos(mainService: any, userToken: string) {
|
||||
// Get asked service by userToken
|
||||
const mainServiceMapper = mainService?.mapper
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { createHash } from 'crypto';
|
|||
@Injectable()
|
||||
export class UrlHandler {
|
||||
private createSecureKeyWithoutLib(url: string): string {
|
||||
const subString = createHash('sha256').update(url).digest().toString('base64').substring(0, 16)
|
||||
const subString = createHash('sha256').update(url).digest().toString('base64').substring(0, 48)
|
||||
return subString.replace(/=/g, 'E').replace(/-/g, 'M').replace(/_/g, 'N').replace(/\+/g, 'P').replace(/\//g, 'Q')
|
||||
}
|
||||
|
||||
|
|
@ -13,7 +13,6 @@ export class UrlHandler {
|
|||
return this.createSecureKeyWithoutLib(url);
|
||||
}
|
||||
|
||||
|
||||
async getEvents(events: Events, mapper: Mapper) {
|
||||
for (const keyUrl of Object.keys(mapper)) {
|
||||
const splittedMapper = keyUrl.split(':')
|
||||
|
|
|
|||
|
|
@ -224,15 +224,15 @@ export class RedisHandlers {
|
|||
}
|
||||
|
||||
async renewTtlLoginFromRedis(req: Request): Promise<any> {
|
||||
const mergedKey = this.mergeLoginKey(req);
|
||||
const value = await this.cacheService.get(mergedKey);
|
||||
return this.cacheService.set_with_ttl(mergedKey, value, 86400);
|
||||
const loginToken = await this.getLoginFromRedis(req);
|
||||
if (!loginToken) { throw new ForbiddenException('Login token not found') }
|
||||
return this.cacheService.set_with_ttl(loginToken.key, loginToken.value, 60 * 30);
|
||||
}
|
||||
|
||||
async renewTtlSelectFromRedis(req: Request): Promise<any> {
|
||||
const mergedKey = this.mergeSelectKey(req);
|
||||
const value = await this.cacheService.get(mergedKey);
|
||||
return this.cacheService.set_with_ttl(mergedKey, value, 60 * 30);
|
||||
const selectToken = await this.getSelectFromRedis(req);
|
||||
if (!selectToken) { throw new ForbiddenException('Select token not found') }
|
||||
return this.cacheService.set_with_ttl(selectToken.key, selectToken.value, 60 * 30);
|
||||
}
|
||||
|
||||
async setLoginToRedis(token: AuthToken, userUUID: string): Promise<any> {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
"next-intl": "^4.3.4",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"undici": "^7.13.0",
|
||||
"zod": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -2318,6 +2319,15 @@
|
|||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.13.0.tgz",
|
||||
"integrity": "sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "next lint",
|
||||
"reset-sync": "rm ./.next/server/app/[locale]/sync.lock"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
"next-intl": "^4.3.4",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"undici": "^7.13.0",
|
||||
"zod": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -30,4 +32,4 @@
|
|||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,16 +8,17 @@ import { getSelectToken } from '@/fetchers/token/select';
|
|||
export default async function DashboardPage() {
|
||||
const pageUrl = "/office/dashboard";
|
||||
const selectToken = await getSelectToken();
|
||||
const RenderPage = renderPage(selectToken, pageUrl, dashboardPages);
|
||||
if (RenderPage) {
|
||||
|
||||
return <>
|
||||
<div>Dashboard Page</div>
|
||||
<div className='flex align-center justify-center h-screen w-screen mt-10 text-2xl'>
|
||||
<RenderPage />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
try {
|
||||
const RenderPage = renderPage(selectToken, pageUrl, dashboardPages);
|
||||
if (RenderPage) {
|
||||
return <>
|
||||
<div>Dashboard Page</div>
|
||||
<div className='flex align-center justify-center h-screen w-screen mt-10 text-2xl'>
|
||||
<RenderPage />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
} catch (error) { console.log(error) }
|
||||
return <>
|
||||
<div>Dashboard Page</div>
|
||||
<div>You are not allowed to reach any page under {pageUrl}. Please contact your administrator.</div>
|
||||
|
|
|
|||
|
|
@ -1,59 +1,43 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { Inter } from 'next/font/google';
|
||||
import { notFound } from "next/navigation";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { Locale, locales } from "@/i18n/locales";
|
||||
import { routing } from "@/i18n/routing";
|
||||
import { NextIntlClientProvider } from 'next-intl';
|
||||
import '../globals.css';
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
params: Promise<{ locale: Locale }>;
|
||||
children: ReactNode;
|
||||
params: Promise<{ locale: Locale }>;
|
||||
};
|
||||
|
||||
export function generateStaticParams() {
|
||||
return locales.map((locale) => ({ locale }));
|
||||
return locales.map((locale) => ({ locale }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Omit<Props, 'children'>) {
|
||||
// Properly await params before accessing properties
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: 'LocaleLayout' });
|
||||
|
||||
return {
|
||||
title: t('title')
|
||||
};
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: 'LocaleLayout' });
|
||||
return { title: t('title') };
|
||||
}
|
||||
|
||||
export default async function LocaleLayout({ children, params }: Props) {
|
||||
// Properly await params before accessing properties
|
||||
const { locale } = await params;
|
||||
|
||||
// Validate that the incoming locale is valid
|
||||
if (!locales.includes(locale as Locale)) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// Load messages for all child components
|
||||
const messages = (await import(`@/i18n/${locale}.json`)).default;
|
||||
|
||||
// Enable static rendering
|
||||
// Note: unstable_setRequestLocale is removed as it's causing TypeScript errors
|
||||
|
||||
return (
|
||||
<html lang={locale}>
|
||||
<body className={inter.className}>
|
||||
<NextIntlClientProvider
|
||||
locale={locale}
|
||||
messages={messages}
|
||||
timeZone="Europe/Istanbul" // Configure a default timezone for Turkey
|
||||
>
|
||||
{children}
|
||||
</NextIntlClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
const { locale } = await params;
|
||||
if (!locales.includes(locale as Locale)) {
|
||||
redirect('/' + locales[0]);
|
||||
}
|
||||
const messages = (await import(`@/i18n/${locale}.json`)).default;
|
||||
return (
|
||||
<>
|
||||
<html lang={locale}>
|
||||
<body className={inter.className}>
|
||||
<NextIntlClientProvider locale={locale} messages={messages} timeZone="Europe/Istanbul">
|
||||
{children}
|
||||
</NextIntlClientProvider>
|
||||
</body>
|
||||
</html>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
'use server';
|
||||
import HomePage from '@/app/home-page';
|
||||
import { sendChunksToNest } from '@/lib/init-sync';
|
||||
|
||||
export default async function Home() {
|
||||
sendChunksToNest();
|
||||
return <HomePage />;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { ReactNode } from 'react';
|
||||
|
||||
export default function RootLayout({ children }: { children: ReactNode }) {
|
||||
return children;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
'use server'
|
||||
import { redirect } from '@/i18n/navigation';
|
||||
|
||||
const RedirectHome = async () => {
|
||||
return redirect({ locale: "en", href: "/" })
|
||||
}
|
||||
|
||||
export default RedirectHome
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { employeeMapper } from '@/pages/office/mapper';
|
||||
import { occupantMapper } from '@/pages/venue/mapper';
|
||||
import { Page } from '@/pages/types/page';
|
||||
|
||||
function chunkifyObject<T>(obj: Record<string, T>, chunkSize: number): Record<string, T>[] {
|
||||
const keys = Object.keys(obj);
|
||||
const chunks: Record<string, T>[] = [];
|
||||
for (let i = 0; i < keys.length; i += chunkSize) {
|
||||
const chunk: Record<string, T> = {};
|
||||
keys.slice(i, i + chunkSize).forEach((key) => {
|
||||
chunk[key] = obj[key];
|
||||
});
|
||||
chunks.push(chunk);
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
export async function sendChunksToNest() {
|
||||
const sendObject: Page = { ...employeeMapper, ...occupantMapper };
|
||||
const lockPath = path.join(__dirname, 'sync.lock');
|
||||
|
||||
if (fs.existsSync(lockPath)) {
|
||||
console.log('🔁 Zaten sync edilmiş, işlem atlandı.');
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks = chunkifyObject(sendObject, 50);
|
||||
const totalChunks = chunks.length;
|
||||
|
||||
for (let i = 0; i < totalChunks; i++) {
|
||||
const chunk = chunks[i];
|
||||
|
||||
// 👇 Bu şekilde index bilgisiyle beraber nested body oluşturuyoruz
|
||||
const payload = {
|
||||
chunkIndex: i + 1,
|
||||
chunkCount: totalChunks,
|
||||
data: chunk,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('http://localhost:8001/navigator/page/configure', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
console.log(`✅ [${payload.chunkIndex}/${payload.chunkCount}] Chunk gönderildi. Kayıt sayısı: ${result.count}`);
|
||||
} catch (err) {
|
||||
console.error(`❌ [${i + 1}/${totalChunks}] Chunk gönderimi sırasında hata:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(lockPath, 'done');
|
||||
console.log('🎉 Tüm chunklar gönderildi ve lock dosyası oluşturuldu.');
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
function renderPage(selectToken: any, pageUrl: string, dashboardPages: any) {
|
||||
function renderPage(selectToken: any, pageUrl: string, fromTokenPages: any) {
|
||||
const subPageKey = selectToken.pages[pageUrl];
|
||||
if (Object.keys(dashboardPages).includes(subPageKey)) {
|
||||
const subPage = dashboardPages[subPageKey as keyof typeof dashboardPages];
|
||||
if (Object.keys(fromTokenPages).includes(subPageKey)) {
|
||||
const subPage = fromTokenPages[subPageKey as keyof typeof fromTokenPages];
|
||||
if (subPage) { if (subPage.page) { return subPage.page } }
|
||||
} return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
'use client';
|
||||
|
||||
const DashboardPtnZblJTri0DnlQaUOikQx: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>DashboardPtnZblJTri0DnlQaUOikQx</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardPtnZblJTri0DnlQaUOikQx;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
'use client';
|
||||
|
||||
const DashboardU0QncONSk22PFxZ5xefmgx: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>DashboardU0QncONSk22PFxZ5xefmgx</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardU0QncONSk22PFxZ5xefmgx;
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
import { Page } from "@/pages/types/page";
|
||||
import DashboardU0QncONSk22PFxZ5xefmgx from "./U0QncONSk22PFxZ5xefmgx";
|
||||
import DashboardPtnZblJTri0DnlQaUOikQx from "./PtnZblJTri0DnlQaUOikQx";
|
||||
|
||||
const dashboardPages: Page = {
|
||||
"qY56XMEr08wJkNvOR6EYQZKMVdTQEfHdLXGzzxcKU24E:U0QncONSk22PFxZ5xefmgx": {
|
||||
name: "DashboardU0QncONSk22PFxZ5xefmgx",
|
||||
key: "U0QncONSk22PFxZ5xefmgx",
|
||||
url: "/venue/dashboard",
|
||||
page: DashboardU0QncONSk22PFxZ5xefmgx,
|
||||
"qY56XMEr08wJkNvOR6EYQZKMVdTQEfHdLXGzzxcKU24E:PtnZblJTri0DnlQaUOikQx": {
|
||||
name: "DashboardPtnZblJTri0DnlQaUOikQx",
|
||||
key: "PtnZblJTri0DnlQaUOikQx",
|
||||
url: "/office/dashboard",
|
||||
page: DashboardPtnZblJTri0DnlQaUOikQx,
|
||||
description: "Dashboard",
|
||||
isDefault: true,
|
||||
typeToken: "L9wBdwV9OlxsLAgh",
|
||||
params: {},
|
||||
events: ["Aevent", "Aevent", "Aevent"],
|
||||
tokens: ["TOKEN", "TOKEN", "TOKEN", "TOKEN"]
|
||||
includeTokens: ['*'],
|
||||
excludeTokens: []
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
import {dashboardPages} from "./dashboard/mapper";
|
||||
export const employeeMapper = {
|
||||
...dashboardPages
|
||||
}
|
||||
|
|
@ -6,9 +6,11 @@ export interface Page {
|
|||
page: React.FC;
|
||||
description: string;
|
||||
isDefault: boolean;
|
||||
typeToken: string;
|
||||
params: Record<string, boolean>;
|
||||
events?: string[];
|
||||
tokens?: string[];
|
||||
includeTokens?: string[];
|
||||
excludeTokens?: string[];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
'use client';
|
||||
|
||||
const DashboardIdTch3qS9aJXkvqXodAxxx: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>DashboardIdTch3qS9aJXkvqXodAxxx</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardIdTch3qS9aJXkvqXodAxxx;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
'use client';
|
||||
|
||||
const DashboardhES1KfaPRZeadmmjdryShA: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>DashboardhES1KfaPRZeadmmjdryShA</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardhES1KfaPRZeadmmjdryShA;
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
import { Page } from "@/pages/types/page";
|
||||
import DashboardIdTch3qS9aJXkvqXodAxxx from "./IdTch3qS9aJXkvqXodAxxx";
|
||||
import DashboardhES1KfaPRZeadmmjdryShA from "./hES1KfaPRZeadmmjdryShA";
|
||||
|
||||
const dashboardPages: Page = {
|
||||
"IbGpchaw3muiY7y9rnV0EJYoPy5XoOOrITT9JlfIbqwE:IdTch3qS9aJXkvqXodAxxx": {
|
||||
name: "DashboardIdTch3qS9aJXkvqXodAxxx",
|
||||
key: "IdTch3qS9aJXkvqXodAxxx",
|
||||
"IbGpchaw3muiY7y9rnV0EJYoPy5XoOOrITT9JlfIbqwE:hES1KfaPRZeadmmjdryShA": {
|
||||
name: "DashboardhES1KfaPRZeadmmjdryShA",
|
||||
key: "hES1KfaPRZeadmmjdryShA",
|
||||
url: "/venue/dashboard",
|
||||
page: DashboardIdTch3qS9aJXkvqXodAxxx,
|
||||
page: DashboardhES1KfaPRZeadmmjdryShA,
|
||||
description: "Dashboard",
|
||||
isDefault: true,
|
||||
typeToken: "j0adQOsJBR0xq24d",
|
||||
params: {},
|
||||
events: ["Aevent", "Aevent", "Aevent"],
|
||||
tokens: ["TOKEN", "TOKEN", "TOKEN", "TOKEN"]
|
||||
events: [],
|
||||
includeTokens: ["*"],
|
||||
excludeTokens: []
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
import { dashboardPages } from "./dashboard/mapper";
|
||||
|
||||
export const occupantMapper = {
|
||||
...dashboardPages,
|
||||
}
|
||||
Loading…
Reference in New Issue