133 lines
3.6 KiB
TypeScript
133 lines
3.6 KiB
TypeScript
import { type NextRequest, NextResponse } from "next/server";
|
|
import {
|
|
getPublicChangelogEvents,
|
|
getEnabledAiModelsWithProvider,
|
|
getNavLinks,
|
|
getPublicFeaturedImages,
|
|
getPublicFeaturedRanking,
|
|
getSiteSettings,
|
|
getTutorialVideos,
|
|
} from "@/lib/db/queries";
|
|
|
|
function formatProviderStats(models: Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>) {
|
|
const providerMap = new Map<string, number>();
|
|
|
|
for (const item of models) {
|
|
const providerName = item.provider.name;
|
|
providerMap.set(providerName, (providerMap.get(providerName) ?? 0) + 1);
|
|
}
|
|
|
|
return Array.from(providerMap.entries()).map(([name, count]) => ({ name, count }));
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const view = request.nextUrl.searchParams.get("view") || "home";
|
|
|
|
const [settings, navLinks, models, videos] = await Promise.all([
|
|
getSiteSettings(),
|
|
getNavLinks(),
|
|
getEnabledAiModelsWithProvider(),
|
|
getTutorialVideos(),
|
|
]);
|
|
|
|
if (view === "pricing") {
|
|
const featuredImages = await getPublicFeaturedImages(8);
|
|
|
|
const response = NextResponse.json({
|
|
view,
|
|
settings,
|
|
pricing: {
|
|
models: models.length,
|
|
tutorials: videos.length,
|
|
featuredSamples: featuredImages,
|
|
},
|
|
});
|
|
|
|
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
|
|
return response;
|
|
}
|
|
|
|
if (view === "news") {
|
|
const [featuredImages, ranking] = await Promise.all([
|
|
getPublicFeaturedImages(12),
|
|
settings.rankingEnabled ? getPublicFeaturedRanking(6) : Promise.resolve([]),
|
|
]);
|
|
|
|
const response = NextResponse.json({
|
|
view,
|
|
settings,
|
|
news: {
|
|
videos,
|
|
featuredImages,
|
|
ranking,
|
|
},
|
|
});
|
|
|
|
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
|
|
return response;
|
|
}
|
|
|
|
if (view === "blog") {
|
|
const featuredImages = await getPublicFeaturedImages(8);
|
|
|
|
const response = NextResponse.json({
|
|
view,
|
|
settings,
|
|
blog: {
|
|
videos,
|
|
featuredImages,
|
|
},
|
|
});
|
|
|
|
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
|
|
return response;
|
|
}
|
|
|
|
if (view === "changelog") {
|
|
const [events, ranking] = await Promise.all([
|
|
getPublicChangelogEvents(18),
|
|
settings.rankingEnabled ? getPublicFeaturedRanking(6) : Promise.resolve([]),
|
|
]);
|
|
|
|
const response = NextResponse.json({
|
|
view,
|
|
settings,
|
|
changelog: {
|
|
events,
|
|
ranking,
|
|
},
|
|
});
|
|
|
|
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
|
|
return response;
|
|
}
|
|
|
|
const [featuredImages, ranking] = await Promise.all([
|
|
getPublicFeaturedImages(12),
|
|
settings.rankingEnabled ? getPublicFeaturedRanking(5) : Promise.resolve([]),
|
|
]);
|
|
|
|
const response = NextResponse.json({
|
|
view: "home",
|
|
settings,
|
|
navLinks,
|
|
providers: formatProviderStats(models),
|
|
stats: {
|
|
modelCount: models.length,
|
|
tutorialCount: videos.length,
|
|
featuredCount: featuredImages.length,
|
|
},
|
|
featuredImages,
|
|
ranking,
|
|
videos: settings.tutorialEnabled ? videos : [],
|
|
});
|
|
|
|
response.headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=300");
|
|
return response;
|
|
} catch (error) {
|
|
console.error("[Public Lovart API] Error:", error);
|
|
return NextResponse.json({ error: "Failed to fetch Lovart public payload" }, { status: 500 });
|
|
}
|
|
}
|