Files
users/components/user-portrait/mobile/section.tsx
v0 f0a6a364f2 feat: sync Sidebar and BottomNav, standardize user profile API
Align Sidebar & BottomNav menus, remove "Search", add user profile mock data, implement /api/users, add FilterDrawer, complete Section, ProfileHeader, MetricsRFM components

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2025-08-08 07:00:12 +00:00

43 lines
1.2 KiB
TypeScript

"use client"
import { useState } from "react"
import { ChevronDown } from 'lucide-react'
import { cn } from "@/lib/utils"
export default function Section({
title,
subtitle,
count,
defaultOpen = true,
children,
}: {
title: string
subtitle?: string
count?: number
defaultOpen?: boolean
children: React.ReactNode
}) {
const [open, setOpen] = useState(defaultOpen)
return (
<section className="rounded-2xl bg-white/60 backdrop-blur-md p-4 shadow-sm border">
<button
onClick={() => setOpen((v) => !v)}
className="w-full flex items-center justify-between"
aria-expanded={open}
>
<div>
<h3 className="text-base font-semibold">{title}</h3>
{subtitle && <p className="text-xs text-muted-foreground mt-0.5">{subtitle}</p>}
</div>
<div className="flex items-center gap-2">
{typeof count === "number" && (
<span className="text-xs px-2 py-0.5 rounded-full bg-slate-100">{count}</span>
)}
<ChevronDown className={cn("h-4 w-4 transition-transform", open ? "rotate-180" : "")} />
</div>
</button>
{open && <div className="mt-3">{children}</div>}
</section>
)
}