diff --git a/app/components/AddHistoryModal.jsx b/app/components/AddHistoryModal.jsx index 2e32445..18d05e8 100644 --- a/app/components/AddHistoryModal.jsx +++ b/app/components/AddHistoryModal.jsx @@ -1,10 +1,15 @@ 'use client'; import { useState, useEffect } from 'react'; -import { motion } from 'framer-motion'; import { CloseIcon } from './Icons'; import { fetchSmartFundNetValue } from '../api/fund'; import { DatePicker } from './Common'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; export default function AddHistoryModal({ fund, onClose, onConfirm }) { const [type, setType] = useState(''); @@ -77,30 +82,36 @@ export default function AddHistoryModal({ fund, onClose, onConfirm }) { onClose(); }; + const handleOpenChange = (open) => { + if (!open) { + onClose?.(); + } + }; + + const handleCloseClick = (event) => { + event.stopPropagation(); + onClose?.(); + }; + return ( - - + e.stopPropagation()} + overlayClassName="modal-overlay" + overlayStyle={{ zIndex: 9998 }} + style={{ maxWidth: '420px', zIndex: 9999, width: '90vw' }} > + 添加历史记录 +
添加历史记录 -
@@ -200,15 +211,18 @@ export default function AddHistoryModal({ fund, onClose, onConfirm }) {
*此处补录的买入/卖出仅作记录展示,不会改变当前持仓金额与份额;实际持仓请在持仓设置中维护。
- - -
-
+
+ +
+ + ); } diff --git a/app/components/DcaModal.jsx b/app/components/DcaModal.jsx index 567bd38..4c7b028 100644 --- a/app/components/DcaModal.jsx +++ b/app/components/DcaModal.jsx @@ -1,13 +1,17 @@ 'use client'; import { useEffect, useState, useRef } from 'react'; -import { motion } from 'framer-motion'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; import { DatePicker, NumericInput } from './Common'; import { isNumber } from 'lodash'; import { CloseIcon } from './Icons'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; dayjs.extend(utc); dayjs.extend(timezone); @@ -170,30 +174,28 @@ export default function DcaModal({ fund, plan, onClose, onConfirm }) { return true; }; + const handleOpenChange = (open) => { + if (!open) { + onClose?.(); + } + }; + return ( - - + e.stopPropagation()} + overlayClassName="modal-overlay" style={{ maxWidth: '420px', maxHeight: '90vh', display: 'flex', flexDirection: 'column', + zIndex: 999, + width: '90vw', }} > + 定投设置
-
-
+ + ); } diff --git a/app/components/FundCard.jsx b/app/components/FundCard.jsx index 6f32760..3612c28 100644 --- a/app/components/FundCard.jsx +++ b/app/components/FundCard.jsx @@ -227,25 +227,25 @@ export default function FundCard({ display: 'flex', alignItems: 'center', gap: 4, - cursor: layoutMode === 'drawer' ? 'default' : 'pointer', + cursor: 'pointer', }} - onClick={() => layoutMode !== 'drawer' && onHoldingClick?.(f)} + onClick={() => onHoldingClick?.(f)} > - 未设置 {layoutMode !== 'drawer' && } + 未设置 ) : ( <>
layoutMode !== 'drawer' && onActionClick?.(f)} + style={{ cursor: 'pointer', flexDirection: 'column', gap: 4 }} + onClick={() => onActionClick?.(f)} > - 持仓金额 {layoutMode !== 'drawer' && } + 持仓金额 {masked ? '******' : `¥${profit.amount.toFixed(2)}`} diff --git a/app/components/HoldingActionModal.jsx b/app/components/HoldingActionModal.jsx index 1401c3b..a5ebe22 100644 --- a/app/components/HoldingActionModal.jsx +++ b/app/components/HoldingActionModal.jsx @@ -1,53 +1,50 @@ 'use client'; -import { motion } from 'framer-motion'; import { CloseIcon, SettingsIcon } from './Icons'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; export default function HoldingActionModal({ fund, onClose, onAction, hasHistory }) { + const handleOpenChange = (open) => { + if (!open) { + onClose?.(); + } + }; + return ( - - + e.stopPropagation()} - style={{ maxWidth: '320px' }} + overlayClassName="modal-overlay" + style={{ maxWidth: '320px', zIndex: 99 }} > + 持仓操作
持仓操作 - +
-
-
+ + ); } diff --git a/app/components/HoldingEditModal.jsx b/app/components/HoldingEditModal.jsx index 494e66d..3af822d 100644 --- a/app/components/HoldingEditModal.jsx +++ b/app/components/HoldingEditModal.jsx @@ -1,8 +1,12 @@ 'use client'; import { useEffect, useState } from 'react'; -import { motion } from 'framer-motion'; import { CloseIcon, SettingsIcon } from './Icons'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; export default function HoldingEditModal({ fund, holding, onClose, onSave }) { const [mode, setMode] = useState('amount'); // 'amount' | 'share' @@ -89,25 +93,21 @@ export default function HoldingEditModal({ fund, holding, onClose, onSave }) { ? (share && cost && !isNaN(share) && !isNaN(cost)) : (amount && !isNaN(amount) && (!profit || !isNaN(profit)) && dwjz > 0); + const handleOpenChange = (open) => { + if (!open) { + onClose?.(); + } + }; + return ( - - + e.stopPropagation()} - style={{ maxWidth: '400px' }} + overlayClassName="modal-overlay" + style={{ maxWidth: '400px', zIndex: 999, width: '90vw' }} > + 编辑持仓
@@ -238,7 +238,7 @@ export default function HoldingEditModal({ fund, holding, onClose, onSave }) {
- - + + ); } diff --git a/app/components/PendingTradesModal.jsx b/app/components/PendingTradesModal.jsx new file mode 100644 index 0000000..d14bfc3 --- /dev/null +++ b/app/components/PendingTradesModal.jsx @@ -0,0 +1,94 @@ +'use client'; + +import { CloseIcon } from './Icons'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; + +export default function PendingTradesModal({ + open, + trades = [], + onClose, + onRevoke, +}) { + const handleOpenChange = (nextOpen) => { + if (!nextOpen) { + onClose?.(); + } + }; + + return ( + + + 待交易队列 + +
+
+ 📥 + 待交易队列 +
+ +
+ +
+
+ {trades.map((trade, idx) => ( +
+
+ + {trade.type === 'buy' ? '买入' : '卖出'} + + + {trade.date} {trade.isAfter3pm ? '(15:00后)' : ''} + +
+
+ 份额/金额 + {trade.share ? `${trade.share} 份` : `¥${trade.amount}`} +
+
+ 状态 +
+ 等待净值更新... + +
+
+
+ ))} +
+
+
+
+ ); +} + diff --git a/app/components/TradeModal.jsx b/app/components/TradeModal.jsx index 92e18b8..a5059df 100644 --- a/app/components/TradeModal.jsx +++ b/app/components/TradeModal.jsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect, useMemo, useState } from 'react'; -import { AnimatePresence, motion } from 'framer-motion'; +import { AnimatePresence } from 'framer-motion'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; @@ -10,6 +10,12 @@ import { fetchSmartFundNetValue } from '../api/fund'; import { DatePicker, NumericInput } from './Common'; import ConfirmModal from './ConfirmModal'; import { CloseIcon } from './Icons'; +import { + Dialog, + DialogContent, + DialogTitle, +} from '@/components/ui/dialog'; +import PendingTradesModal from './PendingTradesModal'; dayjs.extend(utc); dayjs.extend(timezone); @@ -153,36 +159,33 @@ export default function TradeModal({ type, fund, holding, onClose, onConfirm, pe const [revokeTrade, setRevokeTrade] = useState(null); + const handleOpenChange = (open) => { + if (!open) { + onClose?.(); + } + }; + return ( - - + e.stopPropagation()} - style={{ maxWidth: '420px' }} + overlayClassName="modal-overlay" + overlayStyle={{ zIndex: 99 }} + style={{ maxWidth: '420px', width: '90vw', zIndex: 99 }} > + {isBuy ? '加仓' : '减仓'}
{isBuy ? '📥' : '📤'} - {showPendingList ? '待交易队列' : (showConfirm ? (isBuy ? '买入确认' : '卖出确认') : (isBuy ? '加仓' : '减仓'))} + {showConfirm ? (isBuy ? '买入确认' : '卖出确认') : (isBuy ? '加仓' : '减仓')}
- {!showPendingList && !showConfirm && currentPendingTrades.length > 0 && ( + {!showConfirm && currentPendingTrades.length > 0 && (
setShowPendingList(true)} @@ -192,49 +195,6 @@ export default function TradeModal({ type, fund, holding, onClose, onConfirm, pe
)} - {showPendingList ? ( -
-
- -
-
- {currentPendingTrades.map((trade, idx) => ( -
-
- - {trade.type === 'buy' ? '买入' : '卖出'} - - {trade.date} {trade.isAfter3pm ? '(15:00后)' : ''} -
-
- 份额/金额 - {trade.share ? `${trade.share} 份` : `¥${trade.amount}`} -
-
- 状态 -
- 等待净值更新... - -
-
-
- ))} -
-
- ) : ( - <> {!showConfirm && (
{fund?.name}
@@ -316,10 +276,10 @@ export default function TradeModal({ type, fund, holding, onClose, onConfirm, pe @@ -398,7 +358,7 @@ export default function TradeModal({ type, fund, holding, onClose, onConfirm, pe
@@ -73,10 +94,10 @@ export default function TransactionHistoryModal({
{fund?.name}
#{fund?.code}
- @@ -108,13 +129,16 @@ export default function TransactionHistoryModal({
等待净值更新... - +
))} @@ -158,13 +182,16 @@ export default function TransactionHistoryModal({ )}
- +
)) @@ -172,22 +199,21 @@ export default function TransactionHistoryModal({ - - - - {deleteConfirm && ( - setDeleteConfirm(null)} - confirmText="确认删除" - /> - )} - - + + {deleteConfirm && ( + setDeleteConfirm(null)} + confirmText="确认删除" + /> + )} + + + ); } diff --git a/app/globals.css b/app/globals.css index 6dda2b2..95c7b65 100644 --- a/app/globals.css +++ b/app/globals.css @@ -2270,6 +2270,10 @@ input[type="number"] { color: var(--text) !important; } +[data-theme="light"] .trade-modal .queue-button { + color: #ffffff !important; +} + .trade-time-slot { background: rgba(0, 0, 0, 0.2); border-radius: 8px; diff --git a/components/ui/button.jsx b/components/ui/button.jsx index 143adf0..d12b91b 100644 --- a/components/ui/button.jsx +++ b/components/ui/button.jsx @@ -9,7 +9,7 @@ const buttonVariants = cva( { variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", + default: "bg-[linear-gradient(#0ea5e9,#0891b2)] text-white hover:bg-[linear-gradient(#0284c7,#0e7490)]", destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40", outline: diff --git a/components/ui/dialog.jsx b/components/ui/dialog.jsx index 811365d..e918bb3 100644 --- a/components/ui/dialog.jsx +++ b/components/ui/dialog.jsx @@ -50,11 +50,12 @@ function DialogContent({ children, showCloseButton = true, overlayClassName, + overlayStyle, ...props }) { return ( - +