84 lines
4.6 KiB
TypeScript
84 lines
4.6 KiB
TypeScript
import { translate } from "@/lib/i18n/messages";
|
|
import type { Locale } from "@/lib/i18n/locales";
|
|
|
|
export type GuideValidationSection = "weapon" | "artifact" | "constellations" | "team" | "extra";
|
|
|
|
interface ValidationIssue {
|
|
path: readonly PropertyKey[];
|
|
message: string;
|
|
}
|
|
|
|
const fieldMessages: Record<string, string> = {
|
|
weaponKey: "กรุณาเลือกอาวุธ",
|
|
firstArtifactKey: "กรุณาเลือก Artifact ชุดแรก",
|
|
characterKey: "กรุณาเลือกตัวละคร",
|
|
overallPercent: "กรุณากรอก Overall % ระหว่าง -9,999 ถึง 9,999",
|
|
personalPercent: "กรุณากรอก Personal % ระหว่าง -9,999 ถึง 9,999",
|
|
percent: "กรุณากรอกเปอร์เซ็นต์ระหว่าง -9,999 ถึง 9,999",
|
|
cumulativePercent: "กรุณากรอก Cumulative % ระหว่าง -9,999 ถึง 9,999",
|
|
title: "กรุณากรอกชื่อไม่เกิน 160 ตัวอักษร",
|
|
heading: "กรุณากรอกหัวข้อไม่เกิน 200 ตัวอักษร",
|
|
combo: "กรุณากรอก Combo",
|
|
rotationSeconds: "กรุณากรอก Rotation เป็นตัวเลขมากกว่า 0",
|
|
damage: "กรุณากรอก Damage เป็นตัวเลข 0 ขึ้นไป",
|
|
};
|
|
|
|
const sectionLabels: Record<GuideValidationSection, string> = {
|
|
weapon: "Weapon tier list",
|
|
artifact: "Artifact",
|
|
constellations: "Constellations",
|
|
team: "Team Calc",
|
|
extra: "Extra sections",
|
|
};
|
|
|
|
function indexAfter(path: readonly PropertyKey[], key: string): number | null {
|
|
const position = path.indexOf(key);
|
|
const value = path[position + 1];
|
|
return position >= 0 && typeof value === "number" ? value : null;
|
|
}
|
|
|
|
function issueContext(section: GuideValidationSection, path: readonly PropertyKey[], teamNames?: readonly string[], locale: Locale = "th"): string {
|
|
const rowIndex = indexAfter(path, "rows");
|
|
const groupIndex = indexAfter(path, "groups");
|
|
const teamIndex = indexAfter(path, "teams");
|
|
const memberIndex = indexAfter(path, "members");
|
|
const sectionIndex = indexAfter(path, "sections");
|
|
|
|
if (section === "weapon" && groupIndex === null && rowIndex !== null) return translate("อาวุธอันดับ {rank}", { rank: rowIndex + 1 }, locale);
|
|
if (section === "weapon" && groupIndex !== null) {
|
|
return rowIndex === null ? `Condition ${groupIndex + 1}` : translate("Condition {index} · อาวุธอันดับ {rank}", { index: groupIndex + 1, rank: rowIndex + 1 }, locale);
|
|
}
|
|
if (section === "artifact" && groupIndex !== null) {
|
|
const group = groupIndex === 0 ? "Late Game" : "Early Game";
|
|
return rowIndex === null ? `Artifact ${group}` : translate("Artifact {name} อันดับ {rank}", { name: group, rank: rowIndex + 1 }, locale);
|
|
}
|
|
if (section === "constellations" && groupIndex !== null) {
|
|
return rowIndex === null ? `Condition ${groupIndex + 1}` : `Condition ${groupIndex + 1} · C${rowIndex + 1}`;
|
|
}
|
|
if (section === "team" && teamIndex !== null) {
|
|
const teamName = teamNames?.[teamIndex]?.trim() || `Team ${teamIndex + 1}`;
|
|
return memberIndex === null ? teamName : translate("{name} · ตัวละคร {index}", { name: teamName, index: memberIndex + 1 }, locale);
|
|
}
|
|
if (section === "extra" && sectionIndex !== null) {
|
|
return rowIndex === null ? `Extra section ${sectionIndex + 1}` : translate("Extra section {index} · แถว {row}", { index: sectionIndex + 1, row: rowIndex + 1 }, locale);
|
|
}
|
|
return sectionLabels[section];
|
|
}
|
|
|
|
function issueMessage(issue: ValidationIssue): string {
|
|
const field = issue.path.at(-1);
|
|
if (typeof field === "string" && fieldMessages[field]) return fieldMessages[field];
|
|
if (/[-]/u.test(issue.message)) return issue.message;
|
|
if (issue.message.startsWith("Too small")) return "กรุณากรอกข้อมูลให้ครบ";
|
|
if (issue.message.startsWith("Too big")) return "ข้อมูลเกินจำนวนหรือความยาวที่กำหนด";
|
|
return "กรุณาตรวจสอบข้อมูลให้ถูกต้อง";
|
|
}
|
|
|
|
export function formatGuideValidationIssues(
|
|
section: GuideValidationSection,
|
|
issues: readonly ValidationIssue[],
|
|
options: { teamNames?: readonly string[]; locale?: Locale } = {},
|
|
): string[] {
|
|
return issues.map((issue) => `${issueContext(section, issue.path, options.teamNames, options.locale)}: ${translate(issueMessage(issue), {}, options.locale)}`);
|
|
}
|