feat : update
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/navigation";
|
||||
import {
|
||||
ChartNoAxesCombinedIcon,
|
||||
ClipboardCopyIcon,
|
||||
@@ -43,9 +44,10 @@ import {
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
|
||||
import {
|
||||
deleteGuideExtra,
|
||||
saveArtifactSection,
|
||||
saveConstellationSection,
|
||||
saveExtraSectionList,
|
||||
saveGuideExtra,
|
||||
saveTeamSection,
|
||||
saveWeaponSection,
|
||||
} from "@/app/admin/actions";
|
||||
@@ -317,6 +319,7 @@ function hasIssuePrefix(
|
||||
|
||||
export interface GuideSectionEditorProps {
|
||||
section: "weapon" | "artifact" | "constellations" | "team" | "extra";
|
||||
extraSectionId?: string;
|
||||
guide: Guide;
|
||||
weapons: CatalogItem[];
|
||||
artifacts: CatalogItem[];
|
||||
@@ -340,6 +343,7 @@ export interface GuideSectionEditorProps {
|
||||
body: string;
|
||||
percent: string | null;
|
||||
backgroundColor: string | null;
|
||||
textColor: string | null;
|
||||
sheet: ExtraSheet | null;
|
||||
catalogItems: ExtraCatalogItem[];
|
||||
highlights: Array<{ text: string; color: string }>;
|
||||
@@ -3523,7 +3527,9 @@ function ExtraCatalogItemsEditor({
|
||||
);
|
||||
}
|
||||
|
||||
function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorBase) {
|
||||
function ExtraEditor({ guide, extraSectionId, initial, characters, weapons, artifacts }: EditorBase) {
|
||||
const router = useRouter();
|
||||
const sectionId = extraSectionId ?? initial.extras[0]?.id ?? "";
|
||||
const extraSensors = useSensors(
|
||||
useSensor(PointerSensor),
|
||||
useSensor(KeyboardSensor, {
|
||||
@@ -3557,6 +3563,7 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
? null
|
||||
: Number(row.percent),
|
||||
backgroundColor: row.backgroundColor,
|
||||
textColor: row.textColor,
|
||||
sheet: row.sheet,
|
||||
catalogItems: row.catalogItems,
|
||||
highlights: [],
|
||||
@@ -3575,8 +3582,11 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
valid: validation.success,
|
||||
initialVersion: guide.version,
|
||||
persist: (next, expectedVersion) =>
|
||||
saveExtraSectionList(guide.id, { ...next, expectedVersion }),
|
||||
storageKey: adminDraftKey(guide.id, "extra"),
|
||||
saveGuideExtra(guide.id, sectionId, {
|
||||
section: next.sections[0],
|
||||
expectedVersion,
|
||||
}),
|
||||
storageKey: adminDraftKey(guide.id, `extra:${sectionId}`),
|
||||
localDraft,
|
||||
parseLocalDraft: (candidate) =>
|
||||
parseEditorDraft<typeof localDraft>(candidate, ["sections"]),
|
||||
@@ -3590,6 +3600,7 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
id: row.id || createClientId("extra-row-record"),
|
||||
body: normalizeExtraRichText(row.body, row.highlights ?? []),
|
||||
backgroundColor: row.backgroundColor ?? null,
|
||||
textColor: row.textColor ?? null,
|
||||
sheet: row.sheet ?? null,
|
||||
catalogItems: row.catalogItems ?? [],
|
||||
highlights: [],
|
||||
@@ -3600,14 +3611,6 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
setOpenSectionIds(restoredSections.map((section) => section.clientId));
|
||||
},
|
||||
});
|
||||
const handleSectionDragEnd = ({ active, over }: DragEndEvent) => {
|
||||
if (!over || active.id === over.id) return;
|
||||
setSections((current) => {
|
||||
const from = current.findIndex((section) => section.clientId === active.id);
|
||||
const to = current.findIndex((section) => section.clientId === over.id);
|
||||
return from === -1 || to === -1 ? current : arrayMove(current, from, to);
|
||||
});
|
||||
};
|
||||
const handleRowDragEnd = (sectionId: string, { active, over }: DragEndEvent) => {
|
||||
if (!over || active.id === over.id) return;
|
||||
setSections((current) => current.map((section) => {
|
||||
@@ -3622,36 +3625,21 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Extra sections</CardTitle>
|
||||
<CardTitle>{sections[0]?.title ?? "Extra section"}</CardTitle>
|
||||
<CardDescription>
|
||||
เพิ่มส่วนเสริมแบบภาพ หัวข้อ ข้อความที่จัดรูปแบบได้ และเปอร์เซ็นต์
|
||||
ระบบจะบันทึกอัตโนมัติ
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-5">
|
||||
<DndContext
|
||||
sensors={extraSensors}
|
||||
collisionDetection={closestCenter}
|
||||
onDragEnd={handleSectionDragEnd}
|
||||
<Accordion
|
||||
multiple
|
||||
value={openSectionIds}
|
||||
onValueChange={setOpenSectionIds}
|
||||
className="gap-5"
|
||||
>
|
||||
<Accordion
|
||||
multiple
|
||||
value={openSectionIds}
|
||||
onValueChange={setOpenSectionIds}
|
||||
className="gap-5"
|
||||
>
|
||||
<SortableContext
|
||||
items={sections.map((section) => section.clientId)}
|
||||
strategy={verticalListSortingStrategy}
|
||||
>
|
||||
{sections.map((section, sectionIndex) => (
|
||||
<SortableExtraItem
|
||||
key={section.clientId}
|
||||
id={section.clientId}
|
||||
label={`ลากเพื่อจัดลำดับ ${section.title || `Extra section ${sectionIndex + 1}`}`}
|
||||
>
|
||||
{(sectionDragHandle) => (
|
||||
<AccordionItem value={section.clientId} className="border-0">
|
||||
<AccordionItem key={section.clientId} value={section.clientId} className="border-0">
|
||||
<Card
|
||||
size="sm"
|
||||
className={cn(
|
||||
@@ -3676,18 +3664,24 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
/>
|
||||
</CardTitle>
|
||||
<CardAction className="flex items-center gap-1">
|
||||
{sectionDragHandle}
|
||||
<DeleteConfirmationDialog
|
||||
trigger={
|
||||
<Button type="button" variant="ghost" size="icon-sm" />
|
||||
}
|
||||
title={`ลบ ${section.title || `Extra section ${sectionIndex + 1}`}?`}
|
||||
description="แถว ข้อความ รูปภาพ และเปอร์เซ็นต์ทั้งหมดในส่วนนี้จะถูกลบออกจาก Guide"
|
||||
onConfirm={() =>
|
||||
setSections(
|
||||
sections.filter((_, index) => index !== sectionIndex),
|
||||
)
|
||||
}
|
||||
showSuccessToast={false}
|
||||
onConfirm={async () => {
|
||||
const result = await deleteGuideExtra(guide.id, section.id);
|
||||
if (result.status !== "saved") {
|
||||
toast.error(result.message);
|
||||
return;
|
||||
}
|
||||
window.localStorage.removeItem(adminDraftKey(guide.id, `extra:${section.id}`));
|
||||
toast.success("ลบ Extra แล้ว");
|
||||
router.push(`/admin/${guide.characterKey}`);
|
||||
router.refresh();
|
||||
}}
|
||||
>
|
||||
<Trash2Icon />
|
||||
<span className="sr-only">ลบส่วน</span>
|
||||
@@ -4168,6 +4162,7 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
body: "",
|
||||
percent: null,
|
||||
backgroundColor: null,
|
||||
textColor: null,
|
||||
sheet: null,
|
||||
catalogItems: [],
|
||||
highlights: [],
|
||||
@@ -4187,33 +4182,10 @@ function ExtraEditor({ guide, initial, characters, weapons, artifacts }: EditorB
|
||||
</AccordionContent>
|
||||
</Card>
|
||||
</AccordionItem>
|
||||
)}
|
||||
</SortableExtraItem>
|
||||
))}
|
||||
</SortableContext>
|
||||
</Accordion>
|
||||
</DndContext>
|
||||
</Accordion>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-wrap justify-between gap-3">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
const clientId = createClientId("extra-section");
|
||||
setSections([
|
||||
...sections,
|
||||
{
|
||||
id: createClientId("extra-section-record"),
|
||||
title: "Extra",
|
||||
rows: [],
|
||||
clientId,
|
||||
},
|
||||
]);
|
||||
setOpenSectionIds([...openSectionIds, clientId]);
|
||||
}}
|
||||
>
|
||||
<PlusIcon data-icon="inline-start" />
|
||||
เพิ่ม Extra section
|
||||
</Button>
|
||||
<CardFooter className="flex-wrap justify-end gap-3">
|
||||
<AutosaveStatus
|
||||
state={autosave.state}
|
||||
issues={
|
||||
|
||||
Reference in New Issue
Block a user