99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { notFound } from "next/navigation";
|
|
|
|
import {
|
|
listBakedFunnelScreenParams,
|
|
peekBakedFunnelDefinition,
|
|
loadFunnelDefinition,
|
|
} from "@/lib/funnel/loadFunnelDefinition";
|
|
import { FunnelRuntime } from "@/components/funnel/FunnelRuntime";
|
|
import type { FunnelDefinition } from "@/lib/funnel/types";
|
|
|
|
// Функция для загрузки воронки из базы данных напрямую
|
|
async function loadFunnelFromDatabase(funnelId: string): Promise<FunnelDefinition | null> {
|
|
try {
|
|
// Импортируем модели напрямую вместо HTTP запроса
|
|
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 FunnelScreenPageProps {
|
|
params: Promise<{
|
|
funnelId: string;
|
|
screenId: string;
|
|
}>;
|
|
}
|
|
|
|
export const dynamic = "force-dynamic"; // Изменено для поддержки базы данных
|
|
|
|
export function generateStaticParams() {
|
|
return listBakedFunnelScreenParams();
|
|
}
|
|
|
|
export async function generateMetadata({
|
|
params,
|
|
}: FunnelScreenPageProps): Promise<Metadata> {
|
|
const { funnelId } = await params;
|
|
let funnel: ReturnType<typeof peekBakedFunnelDefinition>;
|
|
try {
|
|
funnel = peekBakedFunnelDefinition(funnelId);
|
|
} catch (error) {
|
|
console.error(`Failed to load funnel '${funnelId}' for metadata:`, error);
|
|
notFound();
|
|
}
|
|
|
|
return {
|
|
title: funnel.meta.title ?? "Funnel",
|
|
description: funnel.meta.description ?? undefined,
|
|
} satisfies Metadata;
|
|
}
|
|
|
|
export default async function FunnelScreenPage({
|
|
params,
|
|
}: FunnelScreenPageProps) {
|
|
const { funnelId, screenId } = await params;
|
|
|
|
let funnel: FunnelDefinition | null = null;
|
|
|
|
// Сначала пытаемся загрузить из базы данных
|
|
funnel = await loadFunnelFromDatabase(funnelId);
|
|
|
|
// Если не найдено в базе, пытаемся загрузить из JSON файлов
|
|
if (!funnel) {
|
|
try {
|
|
funnel = await loadFunnelDefinition(funnelId);
|
|
} catch (error) {
|
|
console.error(`Failed to load funnel '${funnelId}' from files:`, error);
|
|
}
|
|
}
|
|
|
|
// Если воронка не найдена ни в базе, ни в файлах
|
|
if (!funnel) {
|
|
notFound();
|
|
}
|
|
|
|
const screen = funnel.screens.find((item) => item.id === screenId);
|
|
if (!screen) {
|
|
notFound();
|
|
}
|
|
|
|
return <FunnelRuntime funnel={funnel} initialScreenId={screenId} />;
|
|
}
|