From 6d0feb11cad343b3f3e62769df3d1d5b9a435bb5 Mon Sep 17 00:00:00 2001 From: gunshiz Date: Wed, 7 Oct 2026 19:01:45 +0700 Subject: [PATCH] feat : update --- app/commission/page.tsx | 8 +-- app/donate/page.tsx | 2 +- .../admin/constellation-image-generator.tsx | 2 +- components/admin/create-guide-flow.tsx | 3 +- components/admin/extra-sheet-editor.tsx | 2 +- components/admin/glossary-manager.tsx | 2 +- components/admin/guide-extra-controls.tsx | 2 +- components/admin/guide-overview-form.tsx | 2 +- components/admin/guide-section-editor.tsx | 2 +- components/admin/overview-image-generator.tsx | 2 +- components/admin/structured-dashboard.tsx | 2 +- components/admin/team-image-generator.tsx | 2 +- components/admin/ui/clearable-input.tsx | 55 +++++++++++++++++++ components/admin/weapon-image-generator.tsx | 2 +- components/commission/mobile-slip-form.tsx | 2 +- components/commission/mobile-slip-handoff.tsx | 2 +- components/commission/payment-form.tsx | 4 +- components/commission/request-form.tsx | 2 +- components/public/artifact-image-export.tsx | 2 +- components/public/guide-image-export.tsx | 4 +- components/public/public-navigation.tsx | 2 +- components/public/structured-directory.tsx | 8 +-- components/public/structured-guide.tsx | 1 - components/public/team-search.tsx | 2 +- components/public/weapon-image-export.tsx | 2 +- 25 files changed, 87 insertions(+), 32 deletions(-) create mode 100644 components/admin/ui/clearable-input.tsx diff --git a/app/commission/page.tsx b/app/commission/page.tsx index 6af8c8b..c5ed252 100644 --- a/app/commission/page.tsx +++ b/app/commission/page.tsx @@ -19,7 +19,7 @@ async function CommissionContent() { if (!availability.isOpen) return

ปิดรับ Commission ชั่วคราว

{availability.closureMessage}

-
; @@ -28,14 +28,14 @@ async function CommissionContent() {

เริ่มคำขอ

เข้าสู่ระบบหรือสมัครสมาชิกเพื่อบันทึกคำขอ ติดตามผล และพูดคุยกับทีมงาน

- - + +
; const catalog = await getCatalogOptions(); if (!catalog) return

ยังไม่มีข้อมูลตัวละครสำหรับสร้างคำขอ

; return
-
+
; } diff --git a/app/donate/page.tsx b/app/donate/page.tsx index fc183a2..023e3a5 100644 --- a/app/donate/page.tsx +++ b/app/donate/page.tsx @@ -34,7 +34,7 @@ export default function DonatePage() { priority /> - +

สแกน QR ด้วยแอปธนาคาร หรือบันทึก QR แล้วเลือกรูปในแอปธนาคารบนมือถือเครื่องนี้
diff --git a/components/admin/constellation-image-generator.tsx b/components/admin/constellation-image-generator.tsx index a6bb491..1458689 100644 --- a/components/admin/constellation-image-generator.tsx +++ b/components/admin/constellation-image-generator.tsx @@ -33,7 +33,7 @@ import { EmptyTitle, } from "@/components/ui/empty"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import { isValidPercent } from "@/lib/guides/percent-input"; diff --git a/components/admin/create-guide-flow.tsx b/components/admin/create-guide-flow.tsx index 993c851..47f166d 100644 --- a/components/admin/create-guide-flow.tsx +++ b/components/admin/create-guide-flow.tsx @@ -14,7 +14,8 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group"; +import { InputGroup, InputGroupAddon } from "@/components/ui/input-group"; +import { ClearableInputGroupInput as InputGroupInput } from "@/components/admin/ui/clearable-input"; import { Spinner } from "@/components/ui/spinner"; import { Textarea } from "@/components/ui/textarea"; import { characterRarityGradientClass } from "@/lib/catalog/rarity"; diff --git a/components/admin/extra-sheet-editor.tsx b/components/admin/extra-sheet-editor.tsx index 5ecb6d3..83b2e66 100644 --- a/components/admin/extra-sheet-editor.tsx +++ b/components/admin/extra-sheet-editor.tsx @@ -82,7 +82,7 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { InputGroup, InputGroupAddon, diff --git a/components/admin/glossary-manager.tsx b/components/admin/glossary-manager.tsx index 1df0166..a611bc2 100644 --- a/components/admin/glossary-manager.tsx +++ b/components/admin/glossary-manager.tsx @@ -14,7 +14,7 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from "@/components/ui/pagination"; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Spinner } from "@/components/ui/spinner"; diff --git a/components/admin/guide-extra-controls.tsx b/components/admin/guide-extra-controls.tsx index d67bf48..8acacc0 100644 --- a/components/admin/guide-extra-controls.tsx +++ b/components/admin/guide-extra-controls.tsx @@ -35,7 +35,7 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Spinner } from "@/components/ui/spinner"; import { cn } from "@/lib/utils"; diff --git a/components/admin/guide-overview-form.tsx b/components/admin/guide-overview-form.tsx index 8e2e776..90571a4 100644 --- a/components/admin/guide-overview-form.tsx +++ b/components/admin/guide-overview-form.tsx @@ -27,7 +27,7 @@ import { FieldGroup, FieldLabel, } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Combobox, ComboboxContent, diff --git a/components/admin/guide-section-editor.tsx b/components/admin/guide-section-editor.tsx index 644061d..8f8190f 100644 --- a/components/admin/guide-section-editor.tsx +++ b/components/admin/guide-section-editor.tsx @@ -119,7 +119,7 @@ import { FieldLegend, FieldSet, } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, diff --git a/components/admin/overview-image-generator.tsx b/components/admin/overview-image-generator.tsx index 8f3b6d8..bf41fa8 100644 --- a/components/admin/overview-image-generator.tsx +++ b/components/admin/overview-image-generator.tsx @@ -81,7 +81,7 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Popover, PopoverContent, diff --git a/components/admin/structured-dashboard.tsx b/components/admin/structured-dashboard.tsx index 7cfea74..0077773 100644 --- a/components/admin/structured-dashboard.tsx +++ b/components/admin/structured-dashboard.tsx @@ -47,8 +47,8 @@ import { import { InputGroup, InputGroupAddon, - InputGroupInput, } from "@/components/ui/input-group"; +import { ClearableInputGroupInput as InputGroupInput } from "@/components/admin/ui/clearable-input"; import { Spinner } from "@/components/ui/spinner"; import { useAdminPresence } from "@/hooks/use-presence"; import type { CatalogSyncJob } from "@/lib/catalog/sync"; diff --git a/components/admin/team-image-generator.tsx b/components/admin/team-image-generator.tsx index 89ae194..d6fda24 100644 --- a/components/admin/team-image-generator.tsx +++ b/components/admin/team-image-generator.tsx @@ -13,7 +13,7 @@ import { Button } from "@/components/ui/button"; import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Textarea } from "@/components/ui/textarea"; import { supportsWeaponType } from "@/lib/catalog/lunaris"; diff --git a/components/admin/ui/clearable-input.tsx b/components/admin/ui/clearable-input.tsx new file mode 100644 index 0000000..c612aa6 --- /dev/null +++ b/components/admin/ui/clearable-input.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { useRef, useState, type ComponentProps } from "react"; +import { XIcon } from "lucide-react"; + +import { Input } from "@/components/ui/input"; +import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/ui/input-group"; + +export function ClearableInput({ className, ...props }: ComponentProps) { + const editableText = ["text", "search", "email", "url", "tel"].includes(props.type ?? "text"); + if (!editableText) return ; + return ; +} + +export function ClearableInputGroupInput({ ref, onChange, onValueChange, ...props }: ComponentProps) { + const inputRef = useRef(null); + const [uncontrolledValue, setUncontrolledValue] = useState(props.defaultValue ?? ""); + const value = props.value ?? uncontrolledValue; + + return ( + <> + { + inputRef.current = node; + if (typeof ref === "function") return ref(node); + if (ref) ref.current = node; + }} + onChange={(event) => { + setUncontrolledValue(event.target.value); + onValueChange?.(event.target.value); + onChange?.(event); + }} + /> + {String(value).length > 0 && !props.disabled && !props.readOnly ? ( + + { + const input = inputRef.current; + if (!input) return; + // Use the native setter so React receives the same change as typing. + Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set?.call(input, ""); + input.dispatchEvent(new Event("input", { bubbles: true })); + input.focus(); + }} + > + + + + ) : null} + + ); +} diff --git a/components/admin/weapon-image-generator.tsx b/components/admin/weapon-image-generator.tsx index 90a7b3c..f846d8f 100644 --- a/components/admin/weapon-image-generator.tsx +++ b/components/admin/weapon-image-generator.tsx @@ -36,7 +36,7 @@ import { EmptyTitle, } from "@/components/ui/empty"; import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; -import { Input } from "@/components/ui/input"; +import { ClearableInput as Input } from "@/components/admin/ui/clearable-input"; import { Select, SelectContent, diff --git a/components/commission/mobile-slip-form.tsx b/components/commission/mobile-slip-form.tsx index a12d05b..0cc90eb 100644 --- a/components/commission/mobile-slip-form.tsx +++ b/components/commission/mobile-slip-form.tsx @@ -49,7 +49,7 @@ export function MobileSlipForm() { {ready && <>

ยอดชำระ ฿{amount}

เลือกรูปสลิปจากแอปธนาคาร - +
} {error && {error}} ; diff --git a/components/commission/mobile-slip-handoff.tsx b/components/commission/mobile-slip-handoff.tsx index 6b89b0d..35777ce 100644 --- a/components/commission/mobile-slip-handoff.tsx +++ b/components/commission/mobile-slip-handoff.tsx @@ -70,7 +70,7 @@ export function MobileSlipHandoff({ checkoutId }: { checkoutId: string }) { }, [checkoutId, link, router]); return
- diff --git a/components/commission/payment-form.tsx b/components/commission/payment-form.tsx index 87eb36c..74368e6 100644 --- a/components/commission/payment-form.tsx +++ b/components/commission/payment-form.tsx @@ -53,7 +53,7 @@ export function CommissionPaymentForm({ checkoutId, amountBaht, qr, expiresAt, s {/* Generated locally from the fixed checkout amount and configured recipient. */} {/* eslint-disable-next-line @next/next/no-img-element */} {`PromptPay - + ฿{amountBaht}

ใช้มือถือเครื่องนี้ชำระเงิน: บันทึก QR แล้วเลือกรูปในแอปธนาคาร

โอนเงินแล้วอัปโหลดรูปสลิปเพื่อยืนยัน

@@ -63,6 +63,6 @@ export function CommissionPaymentForm({ checkoutId, amountBaht, qr, expiresAt, s อัปโหลดสลิปที่ชำระเงินแล้ว - + {error && {error}}; } diff --git a/components/commission/request-form.tsx b/components/commission/request-form.tsx index ccce414..874d3eb 100644 --- a/components/commission/request-form.tsx +++ b/components/commission/request-form.tsx @@ -278,7 +278,7 @@ export function CommissionRequestForm({ catalog, userId }: { catalog: Catalog; u

{request.teams.length} ทีม - {request.weapons.reduce((sum, set) => sum + set.weaponKeys.filter(Boolean).length, 0)} อาวุธ - {request.constellations.reduce((sum, set) => sum + set.levels.length, 0)} ระดับกลุ่มดาว

{request.teams.length === 0 && request.weapons.length + request.constellations.length > 0 &&

รวมค่าบริการพื้นฐาน ฿100

}
- + ; diff --git a/components/public/artifact-image-export.tsx b/components/public/artifact-image-export.tsx index 688f41d..2bece83 100644 --- a/components/public/artifact-image-export.tsx +++ b/components/public/artifact-image-export.tsx @@ -148,7 +148,7 @@ export function ArtifactImageExport({ return ( - }> + }> บันทึกภาพ diff --git a/components/public/guide-image-export.tsx b/components/public/guide-image-export.tsx index cf47437..2cab71b 100644 --- a/components/public/guide-image-export.tsx +++ b/components/public/guide-image-export.tsx @@ -229,7 +229,7 @@ export function GuideImageExport({ type="button" variant="outline" size="sm" - className={mobileIconOnly ? "max-sm:size-11 max-sm:px-0 max-sm:has-data-[icon=inline-start]:pl-0" : "max-sm:min-h-11"} + className={mobileIconOnly ? "max-sm:size-11 max-sm:px-0 max-sm:has-data-[icon=inline-start]:pl-0" : undefined} disabled={capturing || disabled} onClick={() => { if (modeSelection === "direct") setCaptureMode("with-notes"); @@ -299,7 +299,7 @@ export function GuideImageExport({ ); const exportAction = ( - diff --git a/components/public/public-navigation.tsx b/components/public/public-navigation.tsx index 97a855d..f91417b 100644 --- a/components/public/public-navigation.tsx +++ b/components/public/public-navigation.tsx @@ -36,7 +36,7 @@ export function PublicNavigation() {
- }> + }> diff --git a/components/public/structured-directory.tsx b/components/public/structured-directory.tsx index c243ffd..0daf169 100644 --- a/components/public/structured-directory.tsx +++ b/components/public/structured-directory.tsx @@ -170,7 +170,7 @@ export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
- + @@ -192,15 +192,15 @@ export function StructuredDirectory({ guides }: { guides: GuideCard[] }) {
- }> + }> ตัวกรอง{activeFilters.length ? ` (${activeFilters.length})` : ""} ตัวกรองไกด์เลือกธาตุ อาวุธ หรือจำนวนดาว
{filterControls(true)}
- - }>ดู {filtered.length} ไกด์ + + }>ดู {filtered.length} ไกด์
diff --git a/components/public/structured-guide.tsx b/components/public/structured-guide.tsx index cea6536..d2d23d1 100644 --- a/components/public/structured-guide.tsx +++ b/components/public/structured-guide.tsx @@ -779,7 +779,6 @@ function ArtifactSectionContent({ const TierGroup = exporting ? Card : Fragment; const tierCards = guide.artifactGroups.map((condition, conditionIndex) => (
- {!exporting && } {exporting && guide.artifactGroups.length > 1 ?

{condition.name || }

: null} {condition.tiers.map((group, groupIndex) => diff --git a/components/public/team-search.tsx b/components/public/team-search.tsx index 8b65b7b..167e529 100644 --- a/components/public/team-search.tsx +++ b/components/public/team-search.tsx @@ -549,7 +549,7 @@ export function TeamSearch({ groups }: { groups: PublicGuide["teamGroups"] }) {

{query.trim() ? "ไม่พบทีมที่ตรงกับคำค้นหาในเงื่อนไขนี้" : "ยังไม่มีทีมในเงื่อนไขนี้"}

- {query && } + {query && }
diff --git a/components/public/weapon-image-export.tsx b/components/public/weapon-image-export.tsx index a30a05c..814ee12 100644 --- a/components/public/weapon-image-export.tsx +++ b/components/public/weapon-image-export.tsx @@ -177,7 +177,7 @@ export function WeaponImageExport({ return ( - }> + }> บันทึกภาพ