From ecbb8dda5547627747b1cde65c93b915dfbe86b2 Mon Sep 17 00:00:00 2001 From: gunshiz Date: Fri, 11 Sep 2026 16:35:17 +0700 Subject: [PATCH] feat(admin) : add sortable condition defaults --- components/admin/guide-section-editor.tsx | 262 ++++++++++++++++------ 1 file changed, 188 insertions(+), 74 deletions(-) diff --git a/components/admin/guide-section-editor.tsx b/components/admin/guide-section-editor.tsx index 46d7e6e..baeeda9 100644 --- a/components/admin/guide-section-editor.tsx +++ b/components/admin/guide-section-editor.tsx @@ -1128,6 +1128,140 @@ function SortableExtraItem({ ); } +type ConditionNavItem = { + clientId: string; + name: string; +}; + +function SortableConditionTab({ + item, + index, + active, + onSelect, + onRename, +}: { + item: ConditionNavItem; + index: number; + active: boolean; + onSelect: () => void; + onRename: () => void; +}) { + const { + attributes, + listeners, + setNodeRef, + transform, + transition, + isDragging, + } = useSortable({ id: item.clientId }); + const label = item.name.trim() || `Condition ${index + 1}`; + + return ( +
+ + {label} + {index === 0 ? Default : null} + + + + +
+ ); +} + +function SortableConditionSwitcher({ + ariaLabel, + items, + activeIndex, + onActiveIndexChange, + onReorder, + onRename, +}: { + ariaLabel: string; + items: ConditionNavItem[]; + activeIndex: number; + onActiveIndexChange: (index: number) => void; + onReorder: (from: number, to: number) => void; + onRename: (index: number) => void; +}) { + const sensors = useSensors( + useSensor(PointerSensor, { activationConstraint: { distance: 8 } }), + useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }), + ); + const activeId = items[activeIndex]?.clientId; + + return ( + + { + if (!over || active.id === over.id) return; + const from = items.findIndex((item) => item.clientId === active.id); + const to = items.findIndex((item) => item.clientId === over.id); + if (from !== -1 && to !== -1) onReorder(from, to); + }} + > + item.clientId)} strategy={rectSortingStrategy}> + { + const index = items.findIndex((item) => item.clientId === values[0]); + if (index !== -1) onActiveIndexChange(index); + }} + > + {items.map((item, index) => ( + onActiveIndexChange(index)} + onRename={() => onRename(index)} + /> + ))} + + + + + ); +} + +function reorderConditions( + items: T[], + activeIndex: number, + from: number, + to: number, +) { + const activeId = items[activeIndex]?.clientId; + const reordered = arrayMove(items, from, to); + return { + items: reordered, + activeIndex: Math.max(0, reordered.findIndex((item) => item.clientId === activeId)), + }; +} + export function GuideSectionEditor(props: GuideSectionEditorProps) { return (
@@ -1249,27 +1383,18 @@ function WeaponEditor({ guide, weapons, characters, initial }: EditorBase) { />
- - { - if (values[0]) setActiveGroupIndex(Number(values[0])); - }} - > - {groups.map((group, index) => ( - setRenamingWeaponGroupIndex(index)} - > - {group.name.trim() || `Condition ${index + 1}`} - - ))} - - + { + const reordered = reorderConditions(groups, activeGroupIndex, from, to); + setGroups(reordered.items); + setActiveGroupIndex(reordered.activeIndex); + }} + />