diff --git a/src/app/admin/_components/ArrayEditor.tsx b/src/app/admin/_components/ArrayEditor.tsx index e9362bd..2d558d6 100644 --- a/src/app/admin/_components/ArrayEditor.tsx +++ b/src/app/admin/_components/ArrayEditor.tsx @@ -2,7 +2,7 @@ import { useState, useRef, useCallback, useEffect } from "react"; import { createPortal } from "react-dom"; -import { Plus, Trash2, GripVertical, ChevronDown } from "lucide-react"; +import { Plus, Trash2, GripVertical, ChevronDown, ChevronsUpDown } from "lucide-react"; interface ArrayEditorProps { items: T[]; @@ -293,8 +293,23 @@ export function ArrayEditor({ return (
- {label && ( -

{label}

+ {(label || (collapsible && items.length > 1)) && ( +
+ {label ?

{label}

:
} + {collapsible && items.length > 1 && (() => { + const allCollapsed = collapsed.size >= items.length; + return ( + + ); + })()} +
)} {addPosition === "top" && ( diff --git a/src/app/admin/pricing/page.tsx b/src/app/admin/pricing/page.tsx index 6be3a39..535647b 100644 --- a/src/app/admin/pricing/page.tsx +++ b/src/app/admin/pricing/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { ChevronDown } from "lucide-react"; +import { ChevronDown, ChevronsUpDown } from "lucide-react"; import { SectionEditor } from "../_components/SectionEditor"; import { InputField, SelectField } from "../_components/FormField"; import { ArrayEditor } from "../_components/ArrayEditor"; @@ -52,21 +52,21 @@ function PriceField({ label, value, onChange }: { label: string; value: string; function CollapsibleSection({ title, count, - defaultOpen = true, + isOpen, + onToggle, children, }: { title: string; count?: number; - defaultOpen?: boolean; + isOpen: boolean; + onToggle: () => void; children: React.ReactNode; }) { - const [open, setOpen] = useState(defaultOpen); - return (
@@ -94,26 +94,46 @@ function CollapsibleSection({ ); } -export default function PricingEditorPage() { - return ( - sectionKey="pricing" title="Цены"> - {(data, update) => ( -
-
- update({ ...data, title: v })} - /> - update({ ...data, subtitle: v })} - /> -
+function PricingContent({ data, update }: { data: PricingData; update: (d: PricingData) => void }) { + const [sections, setSections] = useState({ subscriptions: true, rental: true, rules: false }); + const allOpen = sections.subscriptions && sections.rental && sections.rules; - {/* Абонементы */} - + function toggleAll() { + const target = !allOpen; + setSections({ subscriptions: target, rental: target, rules: target }); + } + + function toggleSection(key: keyof typeof sections) { + setSections(prev => ({ ...prev, [key]: !prev[key] })); + } + + return ( +
+
+
+ update({ ...data, title: v })} + /> + update({ ...data, subtitle: v })} + /> +
+ +
+ + {/* Абонементы */} + toggleSection("subscriptions")}> {(() => { const itemOptions = data.items .map((it, idx) => ({ value: String(idx), label: it.name })) @@ -196,7 +216,7 @@ export default function PricingEditorPage() { {/* Аренда */} - + toggleSection("rental")}> {/* Правила */} - + toggleSection("rules")}> update({ ...data, rules })} @@ -248,7 +268,13 @@ export default function PricingEditorPage() { />
- )} + ); +} + +export default function PricingEditorPage() { + return ( + sectionKey="pricing" title="Цены"> + {(data, update) => } ); }