import Image from "next/image";
import Link from "next/link";
import { 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 { Kbd } from "@/components/ui/kbd";
import { Separator } from "@/components/ui/separator";
import { SiteHeader } from "@/components/public/site-header";
import { ElementIcon } from "@/components/public/element-icon";
import { LiveRefresh } from "@/components/live-refresh";
import { rarityGradientClass, rarityTextClass } from "@/lib/catalog/rarity";
import type { PublicGuide } from "@/lib/guides/queries";
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));
}
export function StructuredGuideShell({
guide,
section,
}: {
guide: PublicGuide;
section?: string;
}) {
const sections = publicSections(guide);
return (
{guide.character.element ? (
{guide.character.elementIconUrl ? (
) : null}
{guide.character.element}
) : null}
{section ? (
) : (
)}
);
}
function GuideOverview({
guide,
sections,
}: {
guide: PublicGuide;
sections: ReturnType;
}) {
return (
Build Overview
{guide.name}
{guide.overview}
{sections.length ? (
{sections.map((item) => (
{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 }) {
return (
{guide.weapons.map((row, index) => (
{index + 1}. {row.weapon.name} R{row.refinement}
{row.overallPercent ? (
{metric(row.overallPercent)}
ดาเมททั้งทีม
) : null}
{row.personalPercent ? (
{metric(row.personalPercent)}
ดาเมจส่วนตัว
) : null}
))}
);
}
function ArtifactSection({ guide }: { guide: PublicGuide }) {
const profile = guide.artifactProfile;
return (
{" "}
{guide.artifactGroups.map((group) => (
{group.name}
{group.rows.map((row, index) => (
{row.second ? (
) : null}
{index + 1}. {row.first.name}
{row.second ? ` + ${row.second.name}` : ""}
{metric(row.percent)}
))}
))}
{profile ? (
Artifact Stats
{profile.substats.length ? (
Stat Priority: {profile.substats.map(statLabel).join(" > ")}
) : null}
รายละเอียดเพิ่มเติม
{profile.targets.length ? (
Target Stats
{profile.targets.map((target) => (
{target.stat}
{target.value}
))}
) : null}
{profile.talents.length ? (
ลำดับการอัพพรสวรรค์
{[...profile.talents]
.sort((a, b) => a.priority - b.priority)
.map((talent) => {
const catalogTalent = guide.character.talents.find((item) => item.type === talent.type);
return catalogTalent?.iconUrl ? (
{talent.priority}
) :
{talent.priority}. {talent.type};
})}
) : null}
{profile.note ? (
) : null}
) : null}
);
}
function statLabel(value: string): string {
return value === "EM" ? "Elemental Mastery" : value === "ER" ? "Energy Recharge" : value;
}
function ArtifactStat({ iconSrc, label, values }: { iconSrc: string; label: string; values: string[] }) {
return (
{label}
{values.length ? values.map(statLabel).join(" > ") : "—"}
);
}
function ConstellationSection({ guide }: { guide: PublicGuide }) {
return (
{guide.constellations.map((row) => (
{metric(row.cumulativePercent)}
C{row.level} · {row.name}
{row.iconUrl ? (
) : null}
{row.detail}
))}
);
}
function TeamSection({ guide }: { guide: PublicGuide }) {
return (
คำนวณความเสียหาย
Team Calc
{guide.teams.map((team) => {
const total = team.members.reduce(
(sum, member) => sum + Number(member.damage),
0,
);
const seconds = Number(team.rotationSeconds);
return (
{team.title}
{seconds}s rotation
Export image
{team.members.map((member) => (
{member.weapon ? (
R{member.refinement}
) : (
)}
{member.artifact ? (
) : (
)}
C{member.constellation} {member.character.name}
{Number(member.damage).toLocaleString(undefined, {
maximumFractionDigits: 2,
})}
{total
? ((Number(member.damage) / total) * 100).toFixed(2)
: "0.00"}
%
))}
Total damage
{total.toLocaleString()}
Total DPS
{seconds > 0
? (total / seconds).toLocaleString(undefined, {
maximumFractionDigits: 0,
})
: "0"}
{team.combo}
);
})}
);
}
function ExtraSection({ extra }: { extra: PublicGuide["extras"][number] }) {
return (
Extra Guide
{extra.title}
{extra.rows.map((row) => (
{row.imageUrl ? (
) : null}
{row.heading}
{row.body}
{row.percent ? {metric(row.percent)} : null}
))}
);
}