You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

204 lines
7.2 KiB

import type { Metadata, Viewport } from "next";
import { Amiri } from "next/font/google";
import localFont from "next/font/local";
import Script from "next/script";
import Providers from "./providers";
import "./globals.css";
import DevClickToComponent from "@/components/Componentes/dev-click-to-component";
import TokenSwitcher from "@/components/Componentes/token-switcher";
const faminela = localFont({
src: "../../public/fonts/Faminela/Faminela.otf",
variable: "--font-faminela-local",
display: "swap",
preload: true,
fallback: ["Arial", "sans-serif"],
});
const amiri = Amiri({
weight: ["400", "700"],
subsets: ["arabic"],
variable: "--font-amiri",
display: "swap",
preload: true,
fallback: ["Arial", "sans-serif"],
});
const isDevelopment = process.env.NODE_ENV !== "production";
// Never ship a fallback token to production: without it a real user whose
// Flutter token has not been injected yet would silently browse a test account.
const developmentFallbackToken = isDevelopment
? (process.env.NEXT_PUBLIC_DEFAULT_TOKEN ?? "")
: "";
export const metadata: Metadata = {
title: "Habib Marriage",
description: "Islamic Marriage Platform",
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 1,
themeColor: "#ffffff",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<link rel="preconnect" href="https://habibapp.com" />
<link rel="dns-prefetch" href="https://habibapp.com" />
<Script
id="flutter-and-cookies-setup"
strategy="beforeInteractive"
dangerouslySetInnerHTML={{
__html: `
if (typeof window !== 'undefined') {
var flutterResponseListeners = window.__flutterResponseListeners || [];
window.__flutterResponseListeners = flutterResponseListeners;
window.addFlutterResponseListener = window.addFlutterResponseListener || function(listener) {
flutterResponseListeners.push(listener);
return function() {
var index = flutterResponseListeners.indexOf(listener);
if (index >= 0) {
flutterResponseListeners.splice(index, 1);
}
};
};
window.onFlutterResponse = function(event) {
flutterResponseListeners.slice().forEach(function(listener) {
try {
listener(event);
} catch (error) {
console.error('Flutter response listener failed', error);
}
});
};
var HABIB_TOKEN_COOKIE = 'HABIB_TOKEN';
var HABIB_COINS_COOKIE = 'HABIB_COINS';
var HABIB_COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
function writeCookie(name, value) {
if (value === undefined || value === null || value === '') return;
var secure = window.location.protocol === 'https:';
var cookie = name + '=' + encodeURIComponent(String(value)) + '; Path=/; Max-Age=' + HABIB_COOKIE_MAX_AGE + '; SameSite=Lax';
if (secure) {
cookie += '; Secure';
}
document.cookie = cookie;
}
function readCookie(name) {
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0; i < cookies.length; i += 1) {
var parts = cookies[i].split('=');
if (parts[0] === name) {
return decodeURIComponent(parts.slice(1).join('='));
}
}
return '';
}
if (!Object.getOwnPropertyDescriptor(window, 'HABIB_TOKEN')) {
Object.defineProperty(window, 'HABIB_TOKEN', {
configurable: true,
set: function(value) {
this._habib_token = value;
if (value) {
writeCookie(HABIB_TOKEN_COOKIE, value);
try {
sessionStorage.setItem(HABIB_TOKEN_COOKIE, value);
} catch (e) {}
}
},
get: function() {
var ssVal;
try {
ssVal = sessionStorage.getItem(HABIB_TOKEN_COOKIE);
} catch (e) {}
return this._habib_token || readCookie(HABIB_TOKEN_COOKIE) || ssVal || undefined;
}
});
}
if (!Object.getOwnPropertyDescriptor(window, 'HABIB_COINS')) {
Object.defineProperty(window, 'HABIB_COINS', {
configurable: true,
set: function(value) {
this._habib_coins = value;
if (value !== undefined && value !== null && value !== '') {
writeCookie(HABIB_COINS_COOKIE, value);
try {
sessionStorage.setItem(HABIB_COINS_COOKIE, String(value));
} catch (e) {}
}
},
get: function() {
var cookieValue = readCookie(HABIB_COINS_COOKIE);
var ssVal;
try {
ssVal = sessionStorage.getItem(HABIB_COINS_COOKIE);
} catch (e) {}
return this._habib_coins || parseInt(cookieValue || ssVal || '0');
}
});
}
// Performance monitoring
window.addEventListener('load', function() {
try {
var perfData = performance.getEntriesByType('navigation')[0];
if (perfData) {
console.log('⏱️ Load time:', Math.round(perfData.loadEventEnd - perfData.fetchStart), 'ms');
}
} catch (e) {}
});
}
`,
}}
/>
<Script
id="habib-app-ready"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
if (typeof window !== 'undefined' && window.HabibApp) {
window.HabibApp.postMessage(JSON.stringify({ action: 'web_ready' }));
window.HabibApp.postMessage(JSON.stringify({ action: 'get_view_paddings' }));
}
`,
}}
/>
</head>
<body
className={`${faminela.variable} ${amiri.variable}`}
suppressHydrationWarning
>
<Providers>
{isDevelopment ? (
<div className="fixed top-3 left-3 z-[9999] pointer-events-auto">
<TokenSwitcher />
</div>
) : null}
<div className="app-shell">{children}</div>
</Providers>
{isDevelopment ? <DevClickToComponent /> : null}
</body>
</html>
);
}