added pages tested via backend

This commit is contained in:
2025-08-06 16:33:03 +03:00
parent 9232da69d3
commit a986ddbb95
33 changed files with 498 additions and 167 deletions

View File

@@ -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",

View File

@@ -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"
}
}
}

View File

@@ -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>

View File

@@ -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>
</>
);
}

View File

@@ -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 />;
}

View File

@@ -0,0 +1,5 @@
import { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return children;
}

View File

@@ -0,0 +1,8 @@
'use server'
import { redirect } from '@/i18n/navigation';
const RedirectHome = async () => {
return redirect({ locale: "en", href: "/" })
}
export default RedirectHome

View File

@@ -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.');
}

View File

@@ -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;
}

View File

@@ -0,0 +1,11 @@
'use client';
const DashboardPtnZblJTri0DnlQaUOikQx: React.FC = () => {
return (
<div>
<h1>DashboardPtnZblJTri0DnlQaUOikQx</h1>
</div>
);
}
export default DashboardPtnZblJTri0DnlQaUOikQx;

View File

@@ -1,11 +0,0 @@
'use client';
const DashboardU0QncONSk22PFxZ5xefmgx: React.FC = () => {
return (
<div>
<h1>DashboardU0QncONSk22PFxZ5xefmgx</h1>
</div>
);
}
export default DashboardU0QncONSk22PFxZ5xefmgx;

View File

@@ -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: []
}
};

View File

@@ -0,0 +1,4 @@
import {dashboardPages} from "./dashboard/mapper";
export const employeeMapper = {
...dashboardPages
}

View File

@@ -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[];
}
}

View File

@@ -1,11 +0,0 @@
'use client';
const DashboardIdTch3qS9aJXkvqXodAxxx: React.FC = () => {
return (
<div>
<h1>DashboardIdTch3qS9aJXkvqXodAxxx</h1>
</div>
);
}
export default DashboardIdTch3qS9aJXkvqXodAxxx;

View File

@@ -0,0 +1,11 @@
'use client';
const DashboardhES1KfaPRZeadmmjdryShA: React.FC = () => {
return (
<div>
<h1>DashboardhES1KfaPRZeadmmjdryShA</h1>
</div>
);
}
export default DashboardhES1KfaPRZeadmmjdryShA;

View File

@@ -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: []
}
};

View File

@@ -0,0 +1,5 @@
import { dashboardPages } from "./dashboard/mapper";
export const occupantMapper = {
...dashboardPages,
}