98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
import type { ReactNode } from "react";
|
||
import { notFound } from "next/navigation";
|
||
import { AnalyticsProvider } from "@/components/providers/AnalyticsProvider";
|
||
import { WitLibInitializer } from "@/components/providers/WitLibInitializer";
|
||
import { UnleashSessionProvider } from "@/lib/funnel/unleash";
|
||
import type { FunnelDefinition } from "@/lib/funnel/types";
|
||
import { BAKED_FUNNELS } from "@/lib/funnel/bakedFunnels";
|
||
import { IS_FULL_SYSTEM_BUILD } from "@/lib/runtime/buildVariant";
|
||
import { fetchPixelsOnServer } from "@/lib/analytics/fetchPixels";
|
||
import {
|
||
PaymentPlacementProvider,
|
||
TrialVariantSelectionProvider,
|
||
} from "@/entities/session/payment";
|
||
|
||
// Функция для загрузки воронки из базы данных
|
||
async function loadFunnelFromDatabase(
|
||
funnelId: string
|
||
): Promise<FunnelDefinition | null> {
|
||
// В frontend-only режиме база данных недоступна
|
||
if (!IS_FULL_SYSTEM_BUILD) {
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
const { default: connectMongoDB } = await import("@/lib/mongodb");
|
||
const { default: FunnelModel } = await import("@/lib/models/Funnel");
|
||
|
||
await connectMongoDB();
|
||
|
||
const funnel = await FunnelModel.findOne({
|
||
"funnelData.meta.id": funnelId,
|
||
status: { $in: ["published", "draft"] },
|
||
}).lean();
|
||
|
||
if (funnel) {
|
||
return funnel.funnelData as FunnelDefinition;
|
||
}
|
||
|
||
return null;
|
||
} catch (error) {
|
||
console.error(
|
||
`Failed to load funnel '${funnelId}' from database:`,
|
||
error
|
||
);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
interface FunnelLayoutProps {
|
||
children: ReactNode;
|
||
params: Promise<{
|
||
funnelId: string;
|
||
}>;
|
||
}
|
||
|
||
export default async function FunnelLayout({
|
||
children,
|
||
params,
|
||
}: FunnelLayoutProps) {
|
||
const { funnelId } = await params;
|
||
|
||
let funnel: FunnelDefinition | null = null;
|
||
|
||
// Сначала пытаемся загрузить из базы данных
|
||
funnel = await loadFunnelFromDatabase(funnelId);
|
||
|
||
// Если не найдено в базе, пытаемся загрузить из JSON файлов
|
||
if (!funnel) {
|
||
funnel = BAKED_FUNNELS[funnelId] || null;
|
||
}
|
||
|
||
// Если воронка не найдена ни в базе, ни в файлах
|
||
if (!funnel) {
|
||
notFound();
|
||
}
|
||
|
||
// Prefetch analytics pixels на сервере
|
||
// Используем funnelId как source для API
|
||
const analyticsData = await fetchPixelsOnServer({ source: funnelId });
|
||
|
||
return (
|
||
<WitLibInitializer debug={process.env.NODE_ENV === 'development'}>
|
||
<UnleashSessionProvider
|
||
funnelId={funnelId}
|
||
googleAnalyticsId={funnel.meta.googleAnalyticsId}
|
||
>
|
||
<AnalyticsProvider prefetchedData={analyticsData} debug={process.env.NODE_ENV === 'development'}>
|
||
<PaymentPlacementProvider>
|
||
<TrialVariantSelectionProvider>
|
||
{children}
|
||
</TrialVariantSelectionProvider>
|
||
</PaymentPlacementProvider>
|
||
</AnalyticsProvider>
|
||
</UnleashSessionProvider>
|
||
</WitLibInitializer>
|
||
);
|
||
}
|