From f71c00d2abeb073c751a12d23b6155158682c2d2 Mon Sep 17 00:00:00 2001 From: gunshiz Date: Fri, 2 Oct 2026 22:12:43 +0700 Subject: [PATCH] fix : correct color --- components/admin/create-guide-flow.tsx | 4 +-- components/admin/glossary-manager.tsx | 5 ++-- components/admin/guide-section-editor.tsx | 5 ++-- components/admin/stygian-editor.tsx | 1 + components/admin/ui/catalog-select.tsx | 19 +++++++----- components/commission/request-summary.tsx | 12 ++++---- components/commission/ticket-chat.tsx | 35 +++++++++++------------ components/commission/ticket-detail.tsx | 2 +- components/public/stygian-guide.tsx | 4 +-- components/public/team-search.tsx | 7 +++-- lib/catalog/rarity.test.ts | 18 ++++++++++-- lib/catalog/rarity.ts | 15 +++++++--- lib/catalog/sync.ts | 1 + lib/catalog/version.ts | 2 +- 14 files changed, 79 insertions(+), 51 deletions(-) diff --git a/components/admin/create-guide-flow.tsx b/components/admin/create-guide-flow.tsx index 24fa86a..5650d8a 100644 --- a/components/admin/create-guide-flow.tsx +++ b/components/admin/create-guide-flow.tsx @@ -17,7 +17,7 @@ import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group"; import { Spinner } from "@/components/ui/spinner"; import { Textarea } from "@/components/ui/textarea"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass } from "@/lib/catalog/rarity"; import { cn } from "@/lib/utils"; type Character = { key: string; name: string; aliases: string[]; element: string | null; rarity: number | null; imageUrl: string }; @@ -85,7 +85,7 @@ export function CreateGuideFlow({ characters, existingKeys }: { characters: Char const disabled = existing.has(character.key); return ( -
{character.name}
+
{character.name}
{character.name} {character.element ?? "Unknown element"} diff --git a/components/admin/glossary-manager.tsx b/components/admin/glossary-manager.tsx index 80ca486..67c2599 100644 --- a/components/admin/glossary-manager.tsx +++ b/components/admin/glossary-manager.tsx @@ -19,7 +19,7 @@ import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, Pagi import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Spinner } from "@/components/ui/spinner"; import type { GlossaryKind } from "@/lib/glossary"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import { cn } from "@/lib/utils"; type CatalogItem = { key: string; name: string; imageUrl: string; rarity?: number | null }; @@ -113,6 +113,7 @@ export function GlossaryManager({ onValueChange={(key) => setItem(catalogs[kind].find((value) => value.key === key) ?? null)} placeholder="ค้นหารายการ…" rarityBackground + characterBackground={kind === "character"} /> @@ -154,7 +155,7 @@ export function GlossaryManager({ {catalogItem ? ( diff --git a/components/admin/guide-section-editor.tsx b/components/admin/guide-section-editor.tsx index ab51b0c..e409a0c 100644 --- a/components/admin/guide-section-editor.tsx +++ b/components/admin/guide-section-editor.tsx @@ -162,7 +162,7 @@ import { } from "@/lib/guides/stats"; import { elementBackgroundColor, elementIconFilter } from "@/lib/catalog/element"; import { supportsWeaponType } from "@/lib/catalog/lunaris"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import { isCustomTravelerKey } from "@/lib/catalog/travelers"; import { applyPresetFields, @@ -3911,7 +3911,7 @@ function TeamEditor({ return (
-
+
{character ? {character.name} : null}
@@ -4162,6 +4162,7 @@ function ExtraCatalogItemsEditor({ placeholder={`เลือก${labels[kind]}`} showSelectedImage rarityBackground + characterBackground={kind === "character"} />
diff --git a/components/admin/stygian-editor.tsx b/components/admin/stygian-editor.tsx index 5d3e7db..405d8dd 100644 --- a/components/admin/stygian-editor.tsx +++ b/components/admin/stygian-editor.tsx @@ -219,6 +219,7 @@ function ItemPicker({ placeholder={`Search ${kind}…`} emptyLabel="No matches" rarityBackground + characterBackground={kind === "character"} /> ) : null} diff --git a/components/admin/ui/catalog-select.tsx b/components/admin/ui/catalog-select.tsx index a559fa0..b349380 100644 --- a/components/admin/ui/catalog-select.tsx +++ b/components/admin/ui/catalog-select.tsx @@ -13,7 +13,7 @@ import { ComboboxTrigger, FuzzyCombobox, } from "@/components/ui/combobox"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import { cn } from "@/lib/utils"; export interface AdminCatalogItem { @@ -50,6 +50,7 @@ type CommonSelectProps = { emptyLabel?: string; invalid?: boolean; rarityBackground?: boolean; + characterBackground?: boolean; searchNames?: (item: Item) => string[]; }; @@ -69,6 +70,7 @@ export function CatalogDropdown({ emptyLabel = "ไม่พบรายการ", invalid = false, rarityBackground = false, + characterBackground = false, showSelectedImage = false, showClear = true, label, @@ -82,7 +84,7 @@ export function CatalogDropdown({
@@ -110,7 +112,7 @@ export function CatalogDropdown({ {(item) => ( - + {item.name} )} @@ -138,6 +140,7 @@ function CatalogSlotSelect({ emptyLabel = "ไม่พบรายการ", invalid = false, rarityBackground = true, + characterBackground = false, searchNames = (item) => [item.name, ...(item.aliases ?? [])], className, }: CatalogSlotSelectProps) { @@ -158,7 +161,7 @@ function CatalogSlotSelect({ aria-invalid={invalid} className={cn( "relative flex aspect-square w-full items-center justify-center overflow-hidden rounded-md border bg-muted p-0 outline-none focus-visible:ring-2 focus-visible:ring-ring aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 [&>svg]:hidden", - rarityBackground && selected && rarityGradientClass(selected.rarity), + rarityBackground && selected && (characterBackground ? characterRarityGradientClass(selected.key, selected.rarity) : rarityGradientClass(selected.rarity)), className, )} > @@ -174,7 +177,7 @@ function CatalogSlotSelect({ {(item) => ( - + {item.name} )} @@ -216,7 +219,7 @@ function DomainCatalogSelect({ } export function CharacterSelect(props: DomainSelectProps) { - return ; + return ; } export function WeaponSelect(props: DomainSelectProps) { @@ -318,15 +321,17 @@ export function ArtifactSelect( function CatalogOptionImage({ item, rarityBackground, + characterBackground = false, }: { item: AdminCatalogItem; rarityBackground: boolean; + characterBackground?: boolean; }) { return (
diff --git a/components/commission/request-summary.tsx b/components/commission/request-summary.tsx index 1ada932..1e582c0 100644 --- a/components/commission/request-summary.tsx +++ b/components/commission/request-summary.tsx @@ -2,15 +2,15 @@ import Image from "next/image"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { elementBackgroundColor } from "@/lib/catalog/element"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import type { CommissionRequest } from "@/lib/commission/request"; import { cn } from "@/lib/utils"; type Item = { key: string; name: string; imageUrl: string; rarity?: number | null; element?: string | null }; type Catalog = { characters: Item[]; weapons: Item[]; artifacts: Item[] }; -function ItemImage({ item, size = "small" }: { item: Item; size?: "small" | "large" }) { - return
+function ItemImage({ item, size = "small", character = false }: { item: Item; size?: "small" | "large"; character?: boolean }) { + return
{item.name}
; } @@ -30,7 +30,7 @@ function CommissionTeamCard({ team, index, catalog }: { team: CommissionRequest[ const artifact = artifacts.get(member.artifactKey); return
- {character ? :
} + {character ? :
}
{weapon ? :
} {artifact ? :
} @@ -77,7 +77,7 @@ export function CommissionRequestSummary({ request, catalog, amountBaht }: { :

{key}

; })}
- {character ?

{character.name}

: null} + {character ?

{character.name}

: null} ; })} @@ -89,7 +89,7 @@ export function CommissionRequestSummary({ request, catalog, amountBaht }: {
{set.levels.map((level) => C{level})}
- {character ?

{character.name}

: null} + {character ?

{character.name}

: null}
; })} diff --git a/components/commission/ticket-chat.tsx b/components/commission/ticket-chat.tsx index a44c23d..c2b712d 100644 --- a/components/commission/ticket-chat.tsx +++ b/components/commission/ticket-chat.tsx @@ -776,8 +776,24 @@ export function CommissionTicketChat({ mine ? "items-end" : "items-start", )} > +
+ +
- {mine ? "คุณ" : message.authorName} + {message.authorName}
)} - - - ); @@ -970,7 +970,6 @@ export function CommissionTicketChat({ {visibleOptimisticMessages.map((message) => ( - คุณ คำขอที่ชำระเงินแล้ว - ฿{data.checkout.amountBaht} + รายละเอียดคำขอ - ฿{data.checkout.amountBaht} {catalog && }

การชำระเงิน: {data.payment.transRef} - {data.payment.transferredAt.toLocaleString("th-TH")}

diff --git a/components/public/stygian-guide.tsx b/components/public/stygian-guide.tsx index 14c7e17..c56d687 100644 --- a/components/public/stygian-guide.tsx +++ b/components/public/stygian-guide.tsx @@ -7,7 +7,7 @@ import { StygianBossTab, } from "@/components/stygian/stygian-boss-display"; import { elementIconFilter } from "@/lib/catalog/element"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import type { getActiveCatalog } from "@/lib/guides/queries"; import type { getStygianSchedule } from "@/lib/stygian/repository"; import { cn } from "@/lib/utils"; @@ -47,7 +47,7 @@ function RecommendationIcon({ item, catalog, teamLayout = false }: { item: Item; return (
-
+
{value.imageUrl ? {value.name} : null}
{hasEquipment ?
diff --git a/components/public/team-search.tsx b/components/public/team-search.tsx index ab37299..fcdb937 100644 --- a/components/public/team-search.tsx +++ b/components/public/team-search.tsx @@ -25,7 +25,7 @@ import { import { Separator } from "@/components/ui/separator"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import { elementBackgroundColor } from "@/lib/catalog/element"; -import { rarityGradientClass } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity"; import { isCustomTravelerKey } from "@/lib/catalog/travelers"; import type { PublicGuide } from "@/lib/guides/queries"; import { teamConstellationLabel, teamRefinementLabel } from "@/lib/guides/team-tools"; @@ -226,7 +226,7 @@ export function TeamExportImage({ team }: { team: TeamExportData }) { const percent = total > 0 ? damage / total * 100 : 0; return (
-
+
@@ -316,7 +316,8 @@ function TeamCard({ exporting ? "col-span-2 row-span-2" : "sm:col-span-2 sm:row-span-2", - rarityGradientClass( + characterRarityGradientClass( + member.character.key, isCustomTravelerKey(member.character.key) ? 5 : member.character.rarity, diff --git a/lib/catalog/rarity.test.ts b/lib/catalog/rarity.test.ts index 7cb5d0d..c2c0d53 100644 --- a/lib/catalog/rarity.test.ts +++ b/lib/catalog/rarity.test.ts @@ -1,11 +1,13 @@ import { describe, expect, it } from "vitest"; -import { rarityGradient, rarityGradientClass, rarityTextClass, rarityTextColor } from "@/lib/catalog/rarity"; +import { characterRarityGradientClass, rarityGradient, rarityGradientClass, rarityTextClass, rarityTextColor } from "@/lib/catalog/rarity"; describe("catalog rarity backgrounds", () => { it("maps every weapon and artifact rarity to its Tailwind gradient", () => { - expect(rarityGradientClass(1)).toContain("rgba(23,25,28,1)"); - expect(rarityGradientClass(2)).toContain("rgba(11,43,24,1)"); + expect(rarityGradientClass(1)).toBe("bg-[#697177] bg-[linear-gradient(90deg,rgba(105,113,119,1)_0%,rgba(137,144,147,1)_100%)]"); + expect(rarityGradientClass(2)).toBe("bg-[#5D8972] bg-[linear-gradient(90deg,rgba(93,137,114,1)_0%,rgba(121,167,127,1)_100%)]"); + expect(rarityGradient(1)).toBe("linear-gradient(90deg, rgba(105, 113, 119, 1) 0%, rgba(137, 144, 147, 1) 100%)"); + expect(rarityGradient(2)).toBe("linear-gradient(90deg, rgba(93, 137, 114, 1) 0%, rgba(121, 167, 127, 1) 100%)"); expect(rarityGradientClass(3)).toBe("bg-[#4D7691] bg-[linear-gradient(90deg,rgba(77,118,145,1)_0%,rgba(71,135,165,1)_100%)]"); expect(rarityGradientClass(4)).toBe("bg-[#6D6A9C] bg-[linear-gradient(90deg,rgba(109,106,156,1)_0%,rgba(150,122,179,1)_100%)]"); expect(rarityGradientClass(5)).toBe("bg-[#A67B34] bg-[linear-gradient(90deg,rgba(166,123,52,1)_0%,rgba(178,123,44,1)_100%)]"); @@ -26,4 +28,14 @@ describe("catalog rarity backgrounds", () => { expect(rarityTextClass(undefined)).toBeUndefined(); expect(rarityTextColor(undefined)).toBe("#17171c"); }); + + it("uses red for special characters without changing other rarity backgrounds", () => { + for (const key of ["10000062", "10000117", "10000118"]) { + expect(characterRarityGradientClass(key, 5)).toBe("bg-[#9A424E] bg-[linear-gradient(90deg,#9A424E_0%,#B85D67_100%)]"); + expect(characterRarityGradientClass(key, null)).toBe(characterRarityGradientClass(key, 5)); + } + expect(characterRarityGradientClass("ordinary-character", 5)).toBe(rarityGradientClass(5)); + expect(characterRarityGradientClass("ordinary-character", 1)).toBe(rarityGradientClass(1)); + expect(characterRarityGradientClass("ordinary-character", 2)).toBe(rarityGradientClass(2)); + }); }); diff --git a/lib/catalog/rarity.ts b/lib/catalog/rarity.ts index 181871b..ccbfcb4 100644 --- a/lib/catalog/rarity.ts +++ b/lib/catalog/rarity.ts @@ -1,14 +1,17 @@ const rarityGradientClasses: Record = { - 1: "bg-[linear-gradient(90deg,rgba(23,25,28,1)_0%,rgba(19,20,23,1)_100%)]", - 2: "bg-[linear-gradient(90deg,rgba(11,43,24,1)_0%,rgba(7,18,13,1)_100%)]", + 1: "bg-[#697177] bg-[linear-gradient(90deg,rgba(105,113,119,1)_0%,rgba(137,144,147,1)_100%)]", + 2: "bg-[#5D8972] bg-[linear-gradient(90deg,rgba(93,137,114,1)_0%,rgba(121,167,127,1)_100%)]", 3: "bg-[#4D7691] bg-[linear-gradient(90deg,rgba(77,118,145,1)_0%,rgba(71,135,165,1)_100%)]", 4: "bg-[#6D6A9C] bg-[linear-gradient(90deg,rgba(109,106,156,1)_0%,rgba(150,122,179,1)_100%)]", 5: "bg-[#A67B34] bg-[linear-gradient(90deg,rgba(166,123,52,1)_0%,rgba(178,123,44,1)_100%)]", }; +const specialCharacterKeys = new Set(["10000062", "10000117", "10000118"]); +const specialCharacterGradientClass = "bg-[#9A424E] bg-[linear-gradient(90deg,#9A424E_0%,#B85D67_100%)]"; + const rarityGradients: Record = { - 1: "linear-gradient(90deg, rgba(23, 25, 28, 1) 0%, rgba(19, 20, 23, 1) 100%)", - 2: "linear-gradient(90deg, rgba(11, 43, 24, 1) 0%, rgba(7, 18, 13, 1) 100%)", + 1: "linear-gradient(90deg, rgba(105, 113, 119, 1) 0%, rgba(137, 144, 147, 1) 100%)", + 2: "linear-gradient(90deg, rgba(93, 137, 114, 1) 0%, rgba(121, 167, 127, 1) 100%)", 3: "linear-gradient(90deg, rgba(77, 118, 145, 1) 0%, rgba(71, 135, 165, 1) 100%)", 4: "linear-gradient(90deg, rgba(109, 106, 156, 1) 0%, rgba(150, 122, 179, 1) 100%)", 5: "linear-gradient(90deg, rgba(166, 123, 52, 1) 0%, rgba(178, 123, 44, 1) 100%)", @@ -30,6 +33,10 @@ export function rarityGradientClass(rarity: number | null | undefined): string | return rarity ? rarityGradientClasses[rarity] : undefined; } +export function characterRarityGradientClass(key: string | null | undefined, rarity: number | null | undefined): string | undefined { + return key && specialCharacterKeys.has(key) ? specialCharacterGradientClass : rarityGradientClass(rarity); +} + export function rarityGradient(rarity: number | null | undefined): string { return (rarity && rarityGradients[rarity]) || "#17383d"; } diff --git a/lib/catalog/sync.ts b/lib/catalog/sync.ts index 003d109..7cb78b4 100644 --- a/lib/catalog/sync.ts +++ b/lib/catalog/sync.ts @@ -182,6 +182,7 @@ function rarity(value: string | undefined): number | null { QUALITY_BLUE: 3, QUALITY_PURPLE: 4, QUALITY_ORANGE: 5, + QUALITY_ORANGE_SP: 5, }[value] ?? null ); } diff --git a/lib/catalog/version.ts b/lib/catalog/version.ts index 9d5af62..0fc9e27 100644 --- a/lib/catalog/version.ts +++ b/lib/catalog/version.ts @@ -1,7 +1,7 @@ import * as z from "zod"; export const lunarisVersionSchema = z.string().regex(/^\d+(?:\.\d+)+$/u); -export const catalogFormatVersion = 2; +export const catalogFormatVersion = 3; export interface LunarisVersionChange { previousVersion: string;