diff --git a/components/admin/stygian-editor.tsx b/components/admin/stygian-editor.tsx index 3bb1422..9deace3 100644 --- a/components/admin/stygian-editor.tsx +++ b/components/admin/stygian-editor.tsx @@ -4,6 +4,7 @@ import Image from "@/components/ui/resilient-image"; import Link from "next/link"; import { useEffect, useMemo, useRef, useState, type ReactNode } from "react"; import { + CopyIcon, GripVerticalIcon, PlusIcon, Trash2Icon, @@ -742,10 +743,12 @@ function VisualRecommendationGrid({ function SortableTeam({ id, position, + onCopy, children, }: { id: string; position: number; + onCopy: () => void; children: ReactNode; }) { const { @@ -765,17 +768,29 @@ function SortableTeam({
Team {position + 1} - +
+ + +
{children}
@@ -934,6 +949,17 @@ function BossRecommendationEditor({ key={team.id} id={team.id} position={teamIndex} + onCopy={() => + setTeams((current) => { + const sourceIndex = current.findIndex((entry) => entry.id === team.id); + if (sourceIndex === -1) return current; + const source = current[sourceIndex]; + return current.toSpliced(sourceIndex + 1, 0, { + id: crypto.randomUUID(), + items: source.items.map((item) => ({ ...item })), + }); + }) + } > setLevel(Number(next) as 105 | 110)} + className="grid grid-cols-1" > - + {stygianLevels.map((entry) => ( Level {entry} ))} {stygianLevels.map((entry) => ( - + setBossPosition(Number(next))} + className="row-span-3 grid grid-rows-subgrid" > {stygianBossPositions.map((position) => { @@ -1104,7 +1132,7 @@ export function StygianEditor({ -

เลือกระดับบอส

- - {stygianLevels.map((level) => ( - เลเวล {level} - ))} - + +
+

เลือกระดับบอส

+ + {stygianLevels.map((level) => ( + เลเวล {level} + ))} + +
{stygianLevels.map((level) => ( - - -

เลือกบอส

- - {stygianBossPositions.map((position) => { - const boss = schedule.bosses.find((candidate) => candidate.level === level && candidate.position === position); - const label = boss?.name ?? `Boss ${position + 1}`; - const positionLabel = stygianBossPositionLabels[position]; - return - - ; - })} - - {stygianBossPositions.map((position) => )} -
+ + +
+

เลือกบอส

+ + {stygianBossPositions.map((position) => { + const boss = schedule.bosses.find((candidate) => candidate.level === level && candidate.position === position); + const label = boss?.name ?? `Boss ${position + 1}`; + const positionLabel = stygianBossPositionLabels[position]; + return + + ; + })} + +
+ {stygianBossPositions.map((position) => )} +
))} -
+ ); } diff --git a/components/stygian/stygian-navigation.tsx b/components/stygian/stygian-navigation.tsx new file mode 100644 index 0000000..079b814 --- /dev/null +++ b/components/stygian/stygian-navigation.tsx @@ -0,0 +1,37 @@ +"use client"; + +import { createContext, useContext, useState, type ReactNode } from "react"; + +import { Tabs } from "@/components/ui/tabs"; + +const BossSelectionContext = createContext<{ + position: string; + onPositionChange: (position: string) => void; +} | null>(null); + +export function StygianNavigation({ children }: { children: ReactNode }) { + const [position, onPositionChange] = useState("0"); + + return ( + + + {children} + + + ); +} + +export function StygianBossTabs({ children }: { children: ReactNode }) { + const selection = useContext(BossSelectionContext); + if (!selection) throw new Error("StygianBossTabs requires StygianNavigation."); + + return ( + + {children} + + ); +}