From 30398d2aeb28a32d693899bdb8f3f22bddecfef6 Mon Sep 17 00:00:00 2001 From: "diana.dolgolyova" Date: Thu, 26 Mar 2026 00:55:39 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20FAQ=20collapsible=20+=20drag=20UX=20?= =?UTF-8?q?=E2=80=94=20gold=20styling,=20compact=20cards,=20drop=20highlig?= =?UTF-8?q?ht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/_components/ArrayEditor.tsx | 64 ++++++++++++++--------- src/app/admin/faq/page.tsx | 2 + 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/app/admin/_components/ArrayEditor.tsx b/src/app/admin/_components/ArrayEditor.tsx index df95621..a69f3cf 100644 --- a/src/app/admin/_components/ArrayEditor.tsx +++ b/src/app/admin/_components/ArrayEditor.tsx @@ -37,6 +37,7 @@ export function ArrayEditor({ const itemRefs = useRef<(HTMLDivElement | null)[]>([]); const [mounted, setMounted] = useState(false); const [newItemIndex, setNewItemIndex] = useState(null); + const [droppedIndex, setDroppedIndex] = useState(null); const [collapsed, setCollapsed] = useState>(() => collapsible ? new Set(items.map((_, i) => i)) : new Set()); function toggleCollapse(index: number) { @@ -132,6 +133,8 @@ export function ArrayEditor({ const [moved] = updated.splice(capturedDrag, 1); updated.splice(targetIndex, 0, moved); onChange(updated); + setDroppedIndex(targetIndex); + setTimeout(() => setDroppedIndex(null), 1500); } } }); @@ -157,7 +160,7 @@ export function ArrayEditor({ key={i} ref={(el) => { itemRefs.current[i] = el; }} className={`rounded-lg border bg-neutral-900/50 mb-3 hover:border-white/25 hover:bg-neutral-800/50 focus-within:border-gold/50 focus-within:bg-neutral-800 transition-all ${ - newItemIndex === i ? "border-gold/40 ring-1 ring-gold/20" : "border-white/10" + newItemIndex === i || droppedIndex === i ? "border-gold/40 ring-1 ring-gold/20" : "border-white/10" } ${isHidden ? "hidden" : ""}`} >
@@ -226,35 +229,48 @@ export function ArrayEditor({ elements.push(
); } const item = items[i]; + const dragTitle = getItemTitle?.(item, i) || `#${i + 1}`; elements.push(
{ itemRefs.current[i] = el; }} - className="rounded-lg border border-white/10 bg-neutral-900/50 p-4 mb-3 hover:border-white/25 hover:bg-neutral-800/50 focus-within:border-gold/50 focus-within:bg-neutral-800 transition-colors" + className="rounded-lg border border-white/10 bg-neutral-900/50 mb-3 transition-colors" > -
-
handleGripMouseDown(e, i)} - > - + {collapsible ? ( +
+ + {dragTitle} + {getItemBadge?.(item, i)}
- -
- {renderItem(item, i, (updated) => updateItem(i, updated))} + ) : ( + <> +
+
handleGripMouseDown(e, i)} + > + +
+ +
+
+ {renderItem(item, i, (updated) => updateItem(i, updated))} +
+ + )}
); visualIndex++; @@ -264,8 +280,8 @@ export function ArrayEditor({ elements.push(
); } @@ -304,9 +320,9 @@ export function ArrayEditor({ height: dragSize.h, }} > -
- - Перемещение элемента... +
+ + {collapsible && dragIndex !== null ? (getItemTitle?.(items[dragIndex], dragIndex) || "Перемещение...") : "Перемещение элемента..."}
, document.body diff --git a/src/app/admin/faq/page.tsx b/src/app/admin/faq/page.tsx index e5583cc..feee013 100644 --- a/src/app/admin/faq/page.tsx +++ b/src/app/admin/faq/page.tsx @@ -23,6 +23,8 @@ export default function FAQEditorPage() { label="Вопросы и ответы" items={data.items} onChange={(items) => update({ ...data, items })} + collapsible + getItemTitle={(item) => item.question || "Без вопроса"} renderItem={(item, _i, updateItem) => (