import Image from "next/image";
import Link from "next/link";
import { ArrowUpRightIcon, ChevronLeftIcon, DownloadIcon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { buttonVariants } from "@/components/ui/button";
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { SiteHeader } from "@/components/public/site-header";
import { ScrollableNav } from "@/components/public/scrollable-nav";
import { TeamSearch } from "@/components/public/team-search";
import { LiveRefresh } from "@/components/live-refresh";
import { rarityGradientClass, rarityTextClass } from "@/lib/catalog/rarity";
import type { PublicGuide } from "@/lib/guides/queries";
import { artifactTierCount } from "@/lib/guides/artifacts";
import { navigationIconPath } from "@/lib/navigation";
import { normalizeTargetStat, statPriorityColorClass, targetStatIconName } from "@/lib/guides/stats";
import { normalizeTalentPriorities, talentRelationSymbol, talentTypeLabel } from "@/lib/guides/talents";
import { cn } from "@/lib/utils";
function hasSection(guide: PublicGuide, slug: string): boolean {
if (slug === "weapon") return guide.weapons.length > 0;
if (slug === "artifact")
return (
guide.artifactGroups.some((group) => group.rows.length > 0) ||
Boolean(
guide.artifactProfile &&
(guide.artifactProfile.sands.length ||
guide.artifactProfile.goblet.length ||
guide.artifactProfile.circlet.length),
)
);
if (slug === "constellations") return guide.constellations.length > 0;
if (slug === "team") return guide.teams.length > 0;
return guide.extras.some(
(extra) => extra.slug === slug && extra.rows.length > 0,
);
}
export function publicSections(guide: PublicGuide) {
return guide.sections.filter((section) => hasSection(guide, section.slug));
}
function publicSectionTitle(slug: string, fallback: string): string {
if (slug === "weapon") return "อาวุธ";
if (slug === "artifact") return "อาร์ติแฟกต์และค่าสถานะ";
if (slug === "constellations") return "กลุ่มดาว";
if (slug === "team") return "คำนวณทีม";
return fallback;
}
export function StructuredGuideShell({
guide,
section,
}: {
guide: PublicGuide;
section?: string;
}) {
const sections = publicSections(guide);
const currentPageTitle = section ? sections.find((item) => item.slug === section)?.title ?? section : "Overview";
return (
{guide.name}
{currentPageTitle}
Overview
{sections.map((item) => (
{navigationIconPath(item.slug) ? : null}
{item.title}
))}
{section ? (
) : (
)}
);
}
function GuideOverview({
guide,
sections,
}: {
guide: PublicGuide;
sections: ReturnType;
}) {
return (
ภาพรวมแนวทาง
{guide.name}
{guide.overview}
{sections.length ? (
{sections.map((item) => (
{navigationIconPath(item.slug) ? : null}
{publicSectionTitle(item.slug, item.title)}
เปิดดูคำแนะนำฉบับเต็ม
))}
) : (
กำลังจัดทำเนื้อหา
กลับมาตรวจสอบอีกครั้งหลังผู้ดูแลเพิ่มข้อมูล
)}
);
}
function GuideSection({
guide,
section,
}: {
guide: PublicGuide;
section: string;
}) {
if (section === "weapon") return ;
if (section === "artifact") return ;
if (section === "constellations")
return ;
if (section === "team") return ;
const extra = guide.extras.find((item) => item.slug === section);
return extra ? : null;
}
function metric(value: string | null) {
return value === null
? null
: `${Number(value).toLocaleString(undefined, { maximumFractionDigits: 2 })}%`;
}
function WeaponSection({ guide }: { guide: PublicGuide }) {
const note = guide.sections.find((section) => section.slug === "weapon")?.note;
return (
อาวุธที่แนะนำ
อาวุธ
{note ? {note}
: null}
ส่งออกภาพ
{guide.weapons.map((row, index) => (
{index + 1}. {row.weapon.name} R{row.refinement}
{row.note ?
{row.note}
: null}
{row.overallPercent ? (
{Number(row.overallPercent) === 0 ? "-%" : metric(row.overallPercent)}
ดาเมททั้งทีม
) : null}
{row.personalPercent ? (
{Number(row.personalPercent) === 0 ? "-%" : metric(row.personalPercent)}
ดาเมจส่วนตัว
) : null}
))}
);
}
function ArtifactSection({ guide }: { guide: PublicGuide }) {
const profile = guide.artifactProfile;
return (
{" "}
{guide.artifactGroups.map((group) => (
{group.name === "Late Game" ? "เลทเกม" : group.name === "Early Game" ? "ช่วงต้นเกม" : group.name}
{group.rows.map((row, index) => (
{row.second ? (
) : null}
{artifactTierCount(row.second?.name ?? null)}{" "}
{row.first.name}
{row.second ? ` + ${row.second.name}` : ""}
{row.note ?
{row.note}
: null}
{Number(row.percent) === 0 ? "-%" : metric(row.percent)}
))}
))}
{profile ? (
ออฟหลักที่แนะนำ
{profile.substats.length ? (
ลำดับค่าสถานะ:
{profile.substats.map((stat, index) => (
{statLabel(stat)}
))}
) : null}
รายละเอียดเพิ่มเติม
{profile.targets.length ? (
ค่าสถานะเป้าหมาย
{profile.targets.map((target, index) => (
{targetStatIconName(target.stat) ? : null}
{statLabel(normalizeTargetStat(target.stat) ?? target.stat)}
{target.value}
))}
) : null}
{profile.talents.length ? (
ลำดับการอัพพรสวรรค์
{normalizeTalentPriorities(profile.talents)
.map((talent, index, talents) => {
const catalogTalent = guide.character.talents.find((item) => item.type === talent.type);
const talentName = catalogTalent?.name ?? talent.type;
return (
{catalogTalent?.iconUrl ? : {talent.type}}
{talent.level ? `เลเวล ${talent.level}+` : "—"}
{talentName}
{talentTypeLabel(talent.type)}
{index < talents.length - 1 ? (
{talentRelationSymbol(talent.relationToNext)}
) : null}
);
})}
) : null}
{profile.note ? (
) : null}
) : null}
);
}
function statLabel(value: string): string {
const labels: Record = {
HP: "พลังชีวิต",
ATK: "พลังโจมตี",
DEF: "พลังป้องกัน",
EM: "ความชำนาญธาตุ",
ER: "ฟื้นฟูพลังงาน",
"CRIT RATE": "อัตราคริ",
"CRIT DAMAGE": "ความแรงคริ",
"ATK%": "พลังโจมตี%",
"HP%": "พลังชีวิต%",
"DEF%": "พลังป้องกัน%",
"CRIT Rate%/CRIT DMG%": "อัตราคริ/ความแรงคริ",
"Pyro DMG%": "ความเสียหายธาตุไฟ%",
"Hydro DMG%": "ความเสียหายธาตุน้ำ%",
"Cryo DMG%": "ความเสียหายธาตุน้ำแข็ง%",
"Electro DMG%": "ความเสียหายธาตุไฟฟ้า%",
"Anemo DMG%": "ความเสียหายธาตุลม%",
"Geo DMG%": "ความเสียหายธาตุดิน%",
"Dendro DMG%": "ความเสียหายธาตุไม้%",
"Physical DMG%": "ความเสียหายกายภาพ%",
"Healing Bonus%": "โบนัสการรักษา%",
};
return labels[value] ?? value;
}
function ArtifactStat({ iconSrc, label, values }: { iconSrc: string; label: string; values: string[] }) {
return (
{label}
{values.length
? values.map((value, index) => (
{statLabel(value)}
))
: —}
);
}
function ConstellationSection({ guide }: { guide: PublicGuide }) {
const note = guide.sections.find((section) => section.slug === "constellations")?.note;
return (
กลุ่มดาว
กลุ่มดาว
{note ? {note}
: null}
{guide.constellations.map((row) => (
{row.iconUrl ? (
) : null}
{metric(row.cumulativePercent)}
C{row.level} · {row.name}
{row.detail}
))}
);
}
function TeamSection({ guide }: { guide: PublicGuide }) {
return (
คำนวณความเสียหาย
คำนวณทีม
);
}
function ExtraSection({ extra }: { extra: PublicGuide["extras"][number] }) {
return (
คู่มือเสริม
{extra.title}
{extra.rows.map((row) => (
{row.imageUrl ? (
) : null}
{row.heading}
{row.body}
{row.percent ? {metric(row.percent)} : null}
))}
);
}