"use client"; import { useMemo, useState } from "react"; import { AnimatePresence, Reorder } from "framer-motion"; import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerClose, } from "@/components/ui/drawer"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogClose, } from "@/components/ui/dialog"; import { CloseIcon, MinusIcon, ResetIcon, SettingsIcon } from "./Icons"; import ConfirmModal from "./ConfirmModal"; import { cn } from "@/lib/utils"; /** * 指数个性化设置弹框 * * - 移动端:使用 Drawer(自底向上抽屉) * - PC 端:使用 Dialog(居中弹窗) * * @param {Object} props * @param {boolean} props.open - 是否打开 * @param {() => void} props.onClose - 关闭回调 * @param {boolean} props.isMobile - 是否为移动端(由上层传入) * @param {Array<{code:string,name:string,price:number,change:number,changePercent:number}>} props.indices - 当前可用的大盘指数列表 * @param {string[]} props.selectedCodes - 已选中的指数 code,决定展示顺序 * @param {(codes: string[]) => void} props.onChangeSelected - 更新选中指数集合 * @param {() => void} props.onResetDefault - 恢复默认选中集合 */ export default function MarketSettingModal({ open, onClose, isMobile, indices = [], selectedCodes = [], onChangeSelected, onResetDefault, }) { const selectedList = useMemo(() => { if (!indices?.length || !selectedCodes?.length) return []; const map = new Map(indices.map((it) => [it.code, it])); return selectedCodes .map((code) => map.get(code)) .filter(Boolean); }, [indices, selectedCodes]); const allIndices = indices || []; const selectedSet = useMemo( () => new Set(selectedCodes || []), [selectedCodes] ); const [resetConfirmOpen, setResetConfirmOpen] = useState(false); const handleToggleCode = (code) => { if (!code) return; if (selectedSet.has(code)) { // 至少保留一个指数,阻止把最后一个也移除 if (selectedCodes.length <= 1) return; const next = selectedCodes.filter((c) => c !== code); onChangeSelected?.(next); } else { const next = [...selectedCodes, code]; onChangeSelected?.(next); } }; const handleReorder = (newOrder) => { onChangeSelected?.(newOrder); }; const body = (