w-funnel/src/app/[funnelId]/layout.tsx
2025-10-23 02:02:49 +02:00

89 lines
2.4 KiB
TypeScript

import type { ReactNode } from "react";
import { notFound } from "next/navigation";
import { PixelsProvider } from "@/components/providers/PixelsProvider";
import { UnleashProvider } 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 {
PaymentPlacementProvider,
TrialVariantSelectionProvider,
} from "@/entities/session/payment";
// Функция для загрузки воронки из базы данных
async function loadFunnelFromDatabase(
funnelId: string
): Promise<FunnelDefinition | null> {
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();
}
return (
<UnleashProvider>
<PixelsProvider
googleAnalyticsId={funnel.meta.googleAnalyticsId}
yandexMetrikaId={funnel.meta.yandexMetrikaId}
>
<PaymentPlacementProvider>
<TrialVariantSelectionProvider>
{children}
</TrialVariantSelectionProvider>
</PaymentPlacementProvider>
</PixelsProvider>
</UnleashProvider>
);
}