100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
import { connection } from "next/server";
|
|
import { getCachedPublicGuide } from "@/lib/cache/public";
|
|
import { publicSections } from "@/components/public/structured-guide";
|
|
import {
|
|
generateOgImage,
|
|
ogImageContentType,
|
|
ogImageSize,
|
|
} from "@/lib/og-image";
|
|
|
|
export const alt = "Buzz Guide section";
|
|
export const size = ogImageSize;
|
|
export const contentType = ogImageContentType;
|
|
|
|
function sectionTitle(slug: string, fallback: string): string {
|
|
if (slug === "weapon") return "อาวุธแนะนำ";
|
|
if (slug === "artifact") return "อาร์ติแฟกต์และค่าสถานะ";
|
|
if (slug === "constellations") return "กลุ่มดาว";
|
|
if (slug === "team") return "ทีมแนะนำ";
|
|
return fallback;
|
|
}
|
|
|
|
function sectionContent(
|
|
guide: Awaited<ReturnType<typeof getCachedPublicGuide>>,
|
|
slug: string,
|
|
) {
|
|
if (!guide) return { description: "คู่มือเกนชินอิมแพกต์", highlights: [] };
|
|
|
|
if (slug === "weapon") {
|
|
return {
|
|
description: "อาวุธที่เหมาะกับตัวละคร พร้อมอันดับและเปอร์เซ็นต์การใช้งาน",
|
|
highlights: guide.weapons.slice(0, 3).map((item, index) => {
|
|
const percent = item.overallPercent ? ` · ${item.overallPercent}%` : "";
|
|
return `${index + 1}. ${item.weapon.name}${percent}`;
|
|
}),
|
|
};
|
|
}
|
|
|
|
if (slug === "artifact") {
|
|
const artifactHighlights = guide.artifactGroups.flatMap((group) =>
|
|
group.rows.slice(0, 2).map((row) =>
|
|
`${group.name}: ${row.first.name}${row.second ? ` + ${row.second.name}` : ""}`,
|
|
),
|
|
);
|
|
const targetHighlights = guide.artifactProfile?.targets
|
|
.slice(0, 2)
|
|
.map((target) => `${target.stat}: ${target.value}`) ?? [];
|
|
return {
|
|
description: "เซ็ตอาร์ติแฟกต์ ค่าสถานะหลัก และเป้าหมายที่ควรจัด",
|
|
highlights: [...artifactHighlights, ...targetHighlights],
|
|
};
|
|
}
|
|
|
|
if (slug === "team") {
|
|
return {
|
|
description: "ทีมแนะนำพร้อมสมาชิกและเวลาหมุนคอมโบ",
|
|
highlights: guide.teams
|
|
.slice(0, 3)
|
|
.map((team) => `${team.title} · ${team.members.length} ตัวละคร`),
|
|
};
|
|
}
|
|
|
|
if (slug === "constellations") {
|
|
return {
|
|
description: "รายละเอียดกลุ่มดาวและพลังที่เพิ่มขึ้นในแต่ละระดับ",
|
|
highlights: guide.constellations
|
|
.slice(0, 3)
|
|
.map((constellation) => `C${constellation.level} ${constellation.name}`),
|
|
};
|
|
}
|
|
|
|
const extra = guide.extras.find((item) => item.slug === slug);
|
|
return {
|
|
description: extra?.title ?? "รายละเอียดเพิ่มเติมของคู่มือ",
|
|
highlights: extra?.rows.slice(0, 3).map((row) => row.heading || row.body) ?? [],
|
|
};
|
|
}
|
|
|
|
export default async function Image({
|
|
params,
|
|
}: {
|
|
params: Promise<{ character: string; page: string }>;
|
|
}) {
|
|
await connection();
|
|
const { character, page } = await params;
|
|
const guide = await getCachedPublicGuide(character);
|
|
const section = guide
|
|
? publicSections(guide).find((item) => item.slug === page)
|
|
: null;
|
|
if (!guide || !section) return new Response("Not found", { status: 404 });
|
|
|
|
const content = sectionContent(guide, page);
|
|
return generateOgImage({
|
|
title: guide.name,
|
|
sub: `${sectionTitle(page, section.title)} · ${content.highlights.join(" · ") || content.description}`,
|
|
characterCard: true,
|
|
backgroundUrl: guide.character.nameCardImageUrl,
|
|
characterUrl: guide.character.splashImageUrl ?? guide.character.imageUrl,
|
|
});
|
|
}
|