refactor(icons): 迁移 components 目录图标到 lucide-react

- @chakra-ui/icons → lucide-react
- react-icons → lucide-react
- 涉及 49 个组件文件

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-25 12:23:19 +08:00
parent 5b05ae17c9
commit b2100d6f75
49 changed files with 250 additions and 282 deletions

View File

@@ -27,7 +27,8 @@ import {
Divider, Divider,
IconButton, IconButton,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { FaLock, FaWeixin } from "react-icons/fa"; import { Lock } from "lucide-react";
import { WechatOutlined } from '@ant-design/icons';
import { useAuth } from "../../contexts/AuthContext"; import { useAuth } from "../../contexts/AuthContext";
import { useAuthModal } from "../../hooks/useAuthModal"; import { useAuthModal } from "../../hooks/useAuthModal";
import { useNotification } from "../../contexts/NotificationContext"; import { useNotification } from "../../contexts/NotificationContext";
@@ -490,7 +491,7 @@ export default function AuthFormContent() {
<Text fontSize="xs" color="gray.500">其他登录方式</Text> <Text fontSize="xs" color="gray.500">其他登录方式</Text>
<IconButton <IconButton
aria-label="微信登录" aria-label="微信登录"
icon={<Icon as={FaWeixin} w={4} h={4} />} icon={<WechatOutlined style={{ fontSize: '16px' }} />}
size="sm" size="sm"
variant="ghost" variant="ghost"
color="#07C160" color="#07C160"
@@ -511,7 +512,7 @@ export default function AuthFormContent() {
)} )}
</Box> </Box>
<Button type="submit" width="100%" size="lg" colorScheme="green" color="white" borderRadius="lg" isLoading={isLoading} loadingText={config.loadingText} fontWeight="bold"><Icon as={FaLock} mr={2} />{config.buttonText}</Button> <Button type="submit" width="100%" size="lg" colorScheme="green" color="white" borderRadius="lg" isLoading={isLoading} loadingText={config.loadingText} fontWeight="bold"><Icon as={Lock} mr={2} />{config.buttonText}</Button>
{/* 隐私声明 */} {/* 隐私声明 */}
<Text fontSize="xs" color="gray.500" textAlign="center" mt={2}> <Text fontSize="xs" color="gray.500" textAlign="center" mt={2}>

View File

@@ -11,8 +11,7 @@ import {
useToast, useToast,
Spinner Spinner
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { FaQrcode } from "react-icons/fa"; import { QrCode, AlertCircle } from "lucide-react";
import { FiAlertCircle } from "react-icons/fi";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { authService, WECHAT_STATUS, STATUS_MESSAGES } from "../../services/authService"; import { authService, WECHAT_STATUS, STATUS_MESSAGES } from "../../services/authService";
import { useAuthModal } from "../../hooks/useAuthModal"; import { useAuthModal } from "../../hooks/useAuthModal";
@@ -508,7 +507,7 @@ export default function WechatRegister() {
) : ( ) : (
/* 未获取:显示占位符 */ /* 未获取:显示占位符 */
<Center width="100%" height="100%" flexDirection="column"> <Center width="100%" height="100%" flexDirection="column">
<Icon as={FaQrcode} w={16} h={16} color="gray.300" mb={4} /> <Icon as={QrCode} w={16} h={16} color="gray.300" mb={4} />
<Button <Button
size="sm" size="sm"
colorScheme="green" colorScheme="green"
@@ -535,7 +534,7 @@ export default function WechatRegister() {
backdropFilter="blur(4px)" backdropFilter="blur(4px)"
> >
<VStack spacing={2}> <VStack spacing={2}>
<Icon as={FiAlertCircle} w={8} h={8} color="white" /> <Icon as={AlertCircle} w={8} h={8} color="white" />
<Text color="white" fontSize="sm">二维码已过期</Text> <Text color="white" fontSize="sm">二维码已过期</Text>
<Button <Button
size="xs" size="xs"

View File

@@ -21,8 +21,7 @@ import {
MenuItem, MenuItem,
Button, Button,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiSend, FiRefreshCw, FiSettings, FiDownload } from 'react-icons/fi'; import { Send, RefreshCw, Settings, Download } from 'lucide-react';
import { ChevronDownIcon } from '@chakra-ui/icons';
import MessageBubble from './MessageBubble'; import MessageBubble from './MessageBubble';
import { mcpService } from '../../services/mcpService'; import { mcpService } from '../../services/mcpService';
import { logger } from '../../utils/logger'; import { logger } from '../../utils/logger';
@@ -252,14 +251,14 @@ export const ChatInterface = () => {
</HStack> </HStack>
<HStack> <HStack>
<IconButton <IconButton
icon={<FiRefreshCw />} icon={<RefreshCw />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label="清空对话" aria-label="清空对话"
onClick={handleClearChat} onClick={handleClearChat}
/> />
<IconButton <IconButton
icon={<FiDownload />} icon={<Download />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label="导出对话" aria-label="导出对话"
@@ -268,7 +267,7 @@ export const ChatInterface = () => {
<Menu> <Menu>
<MenuButton <MenuButton
as={IconButton} as={IconButton}
icon={<FiSettings />} icon={<Settings />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label="设置" aria-label="设置"
@@ -360,7 +359,7 @@ export const ChatInterface = () => {
disabled={isLoading} disabled={isLoading}
/> />
<IconButton <IconButton
icon={<FiSend />} icon={<Send />}
colorScheme="blue" colorScheme="blue"
aria-label="发送" aria-label="发送"
onClick={handleSendMessage} onClick={handleSendMessage}

View File

@@ -21,7 +21,7 @@ import {
Progress, Progress,
Fade, Fade,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiSend, FiRefreshCw, FiDownload, FiCpu, FiUser, FiZap } from 'react-icons/fi'; import { Send, RefreshCw, Download, Cpu, User, Zap } from 'lucide-react';
import { PlanCard } from './PlanCard'; import { PlanCard } from './PlanCard';
import { StepResultCard } from './StepResultCard'; import { StepResultCard } from './StepResultCard';
import { mcpService } from '../../services/mcpService'; import { mcpService } from '../../services/mcpService';
@@ -387,14 +387,14 @@ export const ChatInterfaceV2 = () => {
<Avatar <Avatar
size="md" size="md"
bg="blue.500" bg="blue.500"
icon={<FiCpu fontSize="1.5rem" />} icon={<Cpu fontSize="1.5rem" />}
/> />
<VStack align="start" spacing={0}> <VStack align="start" spacing={0}>
<Heading size="md">AI投资研究助手</Heading> <Heading size="md">AI投资研究助手</Heading>
<HStack> <HStack>
<Badge colorScheme="green" fontSize="xs"> <Badge colorScheme="green" fontSize="xs">
<HStack spacing={1}> <HStack spacing={1}>
<FiZap size={10} /> <Zap size={10} />
<span>智能分析</span> <span>智能分析</span>
</HStack> </HStack>
</Badge> </Badge>
@@ -407,14 +407,14 @@ export const ChatInterfaceV2 = () => {
<HStack> <HStack>
<IconButton <IconButton
icon={<FiRefreshCw />} icon={<RefreshCw />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label="清空对话" aria-label="清空对话"
onClick={handleClearChat} onClick={handleClearChat}
/> />
<IconButton <IconButton
icon={<FiDownload />} icon={<Download />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label="导出对话" aria-label="导出对话"
@@ -507,7 +507,7 @@ export const ChatInterfaceV2 = () => {
size="lg" size="lg"
/> />
<IconButton <IconButton
icon={isProcessing ? <Spinner size="sm" /> : <FiSend />} icon={isProcessing ? <Spinner size="sm" /> : <Send />}
colorScheme="blue" colorScheme="blue"
aria-label="发送" aria-label="发送"
onClick={handleSendMessage} onClick={handleSendMessage}
@@ -546,7 +546,7 @@ const MessageRenderer = ({ message }) => {
{message.content} {message.content}
</Text> </Text>
</Box> </Box>
<Avatar size="sm" bg="blue.500" icon={<FiUser fontSize="1rem" />} /> <Avatar size="sm" bg="blue.500" icon={<User fontSize="1rem" />} />
</HStack> </HStack>
</Flex> </Flex>
); );
@@ -555,7 +555,7 @@ const MessageRenderer = ({ message }) => {
return ( return (
<Flex justify="flex-start"> <Flex justify="flex-start">
<HStack align="flex-start" maxW="75%"> <HStack align="flex-start" maxW="75%">
<Avatar size="sm" bg="purple.500" icon={<FiCpu fontSize="1rem" />} /> <Avatar size="sm" bg="purple.500" icon={<Cpu fontSize="1rem" />} />
<Box <Box
bg={agentBubbleBg} bg={agentBubbleBg}
px={4} px={4}
@@ -580,7 +580,7 @@ const MessageRenderer = ({ message }) => {
return ( return (
<Flex justify="flex-start"> <Flex justify="flex-start">
<HStack align="flex-start" maxW="85%"> <HStack align="flex-start" maxW="85%">
<Avatar size="sm" bg="blue.500" icon={<FiCpu fontSize="1rem" />} /> <Avatar size="sm" bg="blue.500" icon={<Cpu fontSize="1rem" />} />
<VStack align="stretch" flex={1}> <VStack align="stretch" flex={1}>
<PlanCard plan={message.plan} stepResults={[]} /> <PlanCard plan={message.plan} stepResults={[]} />
</VStack> </VStack>
@@ -592,7 +592,7 @@ const MessageRenderer = ({ message }) => {
return ( return (
<Flex justify="flex-start"> <Flex justify="flex-start">
<HStack align="flex-start" maxW="85%"> <HStack align="flex-start" maxW="85%">
<Avatar size="sm" bg="orange.500" icon={<FiCpu fontSize="1rem" />} /> <Avatar size="sm" bg="orange.500" icon={<Cpu fontSize="1rem" />} />
<VStack align="stretch" flex={1} spacing={3}> <VStack align="stretch" flex={1} spacing={3}>
<PlanCard plan={message.plan} stepResults={message.stepResults} /> <PlanCard plan={message.plan} stepResults={message.stepResults} />
{message.stepResults?.map((result, idx) => ( {message.stepResults?.map((result, idx) => (
@@ -607,7 +607,7 @@ const MessageRenderer = ({ message }) => {
return ( return (
<Flex justify="flex-start"> <Flex justify="flex-start">
<HStack align="flex-start" maxW="85%"> <HStack align="flex-start" maxW="85%">
<Avatar size="sm" bg="green.500" icon={<FiCpu fontSize="1rem" />} /> <Avatar size="sm" bg="green.500" icon={<Cpu fontSize="1rem" />} />
<VStack align="stretch" flex={1} spacing={3}> <VStack align="stretch" flex={1} spacing={3}>
{/* 最终总结 */} {/* 最终总结 */}
<Box <Box
@@ -657,7 +657,7 @@ const MessageRenderer = ({ message }) => {
return ( return (
<Flex justify="flex-start"> <Flex justify="flex-start">
<HStack align="flex-start" maxW="75%"> <HStack align="flex-start" maxW="75%">
<Avatar size="sm" bg="red.500" icon={<FiCpu fontSize="1rem" />} /> <Avatar size="sm" bg="red.500" icon={<Cpu fontSize="1rem" />} />
<Box <Box
bg="red.50" bg="red.50"
color="red.700" color="red.700"

View File

@@ -14,7 +14,7 @@ import {
Badge, Badge,
VStack, VStack,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiCopy, FiThumbsUp, FiThumbsDown } from 'react-icons/fi'; import { Copy, ThumbsUp, ThumbsDown } from 'lucide-react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
/** /**
@@ -105,21 +105,21 @@ export const MessageBubble = ({ message, isUser, onCopy, onFeedback }) => {
{!isUser && ( {!isUser && (
<HStack mt={2} spacing={2}> <HStack mt={2} spacing={2}>
<IconButton <IconButton
icon={<FiCopy />} icon={<Copy />}
size="xs" size="xs"
variant="ghost" variant="ghost"
aria-label="复制" aria-label="复制"
onClick={handleCopy} onClick={handleCopy}
/> />
<IconButton <IconButton
icon={<FiThumbsUp />} icon={<ThumbsUp />}
size="xs" size="xs"
variant="ghost" variant="ghost"
aria-label="赞" aria-label="赞"
onClick={() => onFeedback?.('positive')} onClick={() => onFeedback?.('positive')}
/> />
<IconButton <IconButton
icon={<FiThumbsDown />} icon={<ThumbsDown />}
size="xs" size="xs"
variant="ghost" variant="ghost"
aria-label="踩" aria-label="踩"

View File

@@ -17,7 +17,7 @@ import {
useColorModeValue, useColorModeValue,
Divider, Divider,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiTarget, FiCheckCircle, FiXCircle, FiClock, FiTool } from 'react-icons/fi'; import { Target, CheckCircle, XCircle, Clock, Wrench } from 'lucide-react';
/** /**
* 执行计划卡片组件 * 执行计划卡片组件
@@ -38,11 +38,11 @@ export const PlanCard = ({ plan, stepResults }) => {
const getStepIcon = (status) => { const getStepIcon = (status) => {
switch (status) { switch (status) {
case 'success': case 'success':
return FiCheckCircle; return CheckCircle;
case 'failed': case 'failed':
return FiXCircle; return XCircle;
default: default:
return FiClock; return Clock;
} }
}; };
@@ -70,7 +70,7 @@ export const PlanCard = ({ plan, stepResults }) => {
<VStack align="stretch" spacing={3}> <VStack align="stretch" spacing={3}>
{/* 目标 */} {/* 目标 */}
<HStack> <HStack>
<Icon as={FiTarget} color="blue.500" boxSize={5} /> <Icon as={Target} color="blue.500" boxSize={5} />
<Text fontWeight="bold" fontSize="md">执行目标</Text> <Text fontWeight="bold" fontSize="md">执行目标</Text>
</HStack> </HStack>
<Text fontSize="sm" color={useColorModeValue('gray.600', '#9BA1A6')} pl={7}> <Text fontSize="sm" color={useColorModeValue('gray.600', '#9BA1A6')} pl={7}>

View File

@@ -15,7 +15,7 @@ import {
useColorModeValue, useColorModeValue,
Divider, Divider,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiChevronDown, FiChevronUp, FiCheckCircle, FiXCircle, FiClock, FiDatabase } from 'react-icons/fi'; import { ChevronDown, ChevronUp, CheckCircle, XCircle, Clock, Database } from 'lucide-react';
/** /**
* 步骤结果卡片组件 * 步骤结果卡片组件
@@ -31,11 +31,11 @@ export const StepResultCard = ({ stepResult }) => {
const getStatusIcon = () => { const getStatusIcon = () => {
switch (stepResult.status) { switch (stepResult.status) {
case 'success': case 'success':
return FiCheckCircle; return CheckCircle;
case 'failed': case 'failed':
return FiXCircle; return XCircle;
default: default:
return FiClock; return Clock;
} }
}; };
@@ -101,7 +101,7 @@ export const StepResultCard = ({ stepResult }) => {
</HStack> </HStack>
<IconButton <IconButton
icon={<Icon as={isExpanded ? FiChevronUp : FiChevronDown} />} icon={<Icon as={isExpanded ? ChevronUp : ChevronDown} />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label={isExpanded ? "收起" : "展开"} aria-label={isExpanded ? "收起" : "展开"}
@@ -117,7 +117,7 @@ export const StepResultCard = ({ stepResult }) => {
{stepResult.arguments && Object.keys(stepResult.arguments).length > 0 && ( {stepResult.arguments && Object.keys(stepResult.arguments).length > 0 && (
<VStack align="stretch" spacing={2} mb={3}> <VStack align="stretch" spacing={2} mb={3}>
<HStack> <HStack>
<Icon as={FiDatabase} color="blue.500" boxSize={4} /> <Icon as={Database} color="blue.500" boxSize={4} />
<Text fontSize="xs" fontWeight="bold">请求参数:</Text> <Text fontSize="xs" fontWeight="bold">请求参数:</Text>
</HStack> </HStack>
<Code <Code

View File

@@ -22,7 +22,7 @@ import {
useColorModeValue, useColorModeValue,
useBreakpointValue, useBreakpointValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaTable } from 'react-icons/fa'; import { Table2 } from 'lucide-react';
import marketService from '@services/marketService'; import marketService from '@services/marketService';
import { logger } from '@utils/logger'; import { logger } from '@utils/logger';
@@ -161,7 +161,7 @@ const ConceptStocksModal: React.FC<ConceptStocksModalProps> = ({
<ModalContent bg={cardBg} maxH={isMobile ? '70vh' : undefined}> <ModalContent bg={cardBg} maxH={isMobile ? '70vh' : undefined}>
<ModalHeader bg="purple.500" color="white" borderTopRadius="md"> <ModalHeader bg="purple.500" color="white" borderTopRadius="md">
<HStack> <HStack>
<Icon as={FaTable} /> <Icon as={Table2} />
<Text>{concept?.concept_name} - </Text> <Text>{concept?.concept_name} - </Text>
</HStack> </HStack>
</ModalHeader> </ModalHeader>

View File

@@ -37,7 +37,7 @@ import GitHubButton from "react-github-btn";
import { HSeparator } from "components/Separator/Separator"; import { HSeparator } from "components/Separator/Separator";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import React, { useState } from "react"; import React, { useState } from "react";
import { FaTwitter, FaFacebook } from "react-icons/fa"; import { Twitter, Facebook } from "lucide-react";
export default function Configurator(props) { export default function Configurator(props) {
const { const {
@@ -172,7 +172,7 @@ export default function Configurator(props) {
href='https://twitter.com/intent/tweet?url=https://www.creative-tim.com/product/argon-dashboard-chakra-pro/&text=Check%20Argon%20Dashboard%20Chakra%20PRO%20made%20by%20@simmmple_web%20and%20@CreativeTim'> href='https://twitter.com/intent/tweet?url=https://www.creative-tim.com/product/argon-dashboard-chakra-pro/&text=Check%20Argon%20Dashboard%20Chakra%20PRO%20made%20by%20@simmmple_web%20and%20@CreativeTim'>
<Button <Button
colorScheme='twitter' colorScheme='twitter'
leftIcon={<FaTwitter />} leftIcon={<Twitter size={16} />}
me='10px'> me='10px'>
<Text>Tweet</Text> <Text>Tweet</Text>
</Button> </Button>
@@ -180,7 +180,7 @@ export default function Configurator(props) {
<Link <Link
isExternal='true' isExternal='true'
href='https://www.facebook.com/sharer/sharer.php?u=https://www.creative-tim.com/product/argon-dashboard-chakra-pro/'> href='https://www.facebook.com/sharer/sharer.php?u=https://www.creative-tim.com/product/argon-dashboard-chakra-pro/'>
<Button colorScheme='facebook' leftIcon={<FaFacebook />}> <Button colorScheme='facebook' leftIcon={<Facebook size={16} />}>
<Text>Share</Text> <Text>Share</Text>
</Button> </Button>
</Link> </Link>

View File

@@ -17,7 +17,7 @@ import {
useColorModeValue, useColorModeValue,
Slide, Slide,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { MdRefresh } from 'react-icons/md'; import { RefreshCw } from 'lucide-react';
/** /**
* 连接状态枚举 * 连接状态枚举
@@ -119,7 +119,7 @@ const ConnectionStatusBar = ({
<Button <Button
size="sm" size="sm"
colorScheme="red" colorScheme="red"
leftIcon={<MdRefresh />} leftIcon={<RefreshCw size={16} />}
onClick={onRetry} onClick={onRetry}
mr={2} mr={2}
flexShrink={0} flexShrink={0}

View File

@@ -14,7 +14,7 @@ import {
Collapse, Collapse,
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons'; import { ChevronDown, ChevronUp } from 'lucide-react';
import { ExclamationCircleOutlined } from '@ant-design/icons'; import { ExclamationCircleOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { trackEventAsync } from '@/lib/posthog'; import { trackEventAsync } from '@/lib/posthog';
@@ -362,7 +362,7 @@ const ErrorPage: React.FC<ErrorPageProps> = ({
variant="ghost" variant="ghost"
size="sm" size="sm"
color="gray.500" color="gray.500"
rightIcon={isTechOpen ? <ChevronUpIcon /> : <ChevronDownIcon />} rightIcon={isTechOpen ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
onClick={onTechToggle} onClick={onTechToggle}
_hover={{ bg: 'transparent', color: 'gray.400' }} _hover={{ bg: 'transparent', color: 'gray.400' }}
> >

View File

@@ -23,7 +23,7 @@ import {
Button, Button,
useDisclosure, useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons'; import { Trash2 } from 'lucide-react';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
@@ -117,7 +117,7 @@ const CommentItem = ({ comment, currentUserId, onDelete }) => {
{canDelete && ( {canDelete && (
<Tooltip label="删除评论" placement="top"> <Tooltip label="删除评论" placement="top">
<IconButton <IconButton
icon={<DeleteIcon />} icon={<Trash2 size={14} />}
size="xs" size="xs"
variant="ghost" variant="ghost"
colorScheme="red" colorScheme="red"

View File

@@ -13,7 +13,7 @@ import {
Box, Box,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChatIcon } from '@chakra-ui/icons'; import { MessageCircle } from 'lucide-react';
import CommentItem from './CommentItem'; import CommentItem from './CommentItem';
const CommentList = ({ comments, loading, currentUserId, onDelete }) => { const CommentList = ({ comments, loading, currentUserId, onDelete }) => {
@@ -44,7 +44,7 @@ const CommentList = ({ comments, loading, currentUserId, onDelete }) => {
bg={emptyBgColor} bg={emptyBgColor}
borderRadius="full" borderRadius="full"
> >
<ChatIcon boxSize={6} color={emptyTextColor} /> <MessageCircle size={24} color="var(--chakra-colors-gray-500)" style={{ display: 'block' }} />
</Box> </Box>
<Text fontSize="sm" color={emptyTextColor}> <Text fontSize="sm" color={emptyTextColor}>
还没有评论快来发表第一条吧~ 还没有评论快来发表第一条吧~

View File

@@ -11,8 +11,8 @@ import {
IconButton, IconButton,
Button, Button,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons';
import { PROFESSIONAL_COLORS } from '@constants/professionalTheme'; import { PROFESSIONAL_COLORS } from '@constants/professionalTheme';
import { ChevronDown, ChevronUp } from 'lucide-react';
/** /**
* 可折叠模块标题组件 * 可折叠模块标题组件
@@ -57,7 +57,7 @@ const CollapsibleHeader = ({
return null; // 简单模式不显示图标 return null; // 简单模式不显示图标
} }
// 详细模式:展开显示向上箭头,收起显示向下箭头 // 详细模式:展开显示向上箭头,收起显示向下箭头
return isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />; return isOpen ? <ChevronUp size={16} /> : <ChevronDown size={16} />;
}; };
return ( return (
@@ -95,7 +95,7 @@ const CollapsibleHeader = ({
{/* 展开/收起图标showModeToggle 时显示在标题旁边) */} {/* 展开/收起图标showModeToggle 时显示在标题旁边) */}
{showModeToggle && ( {showModeToggle && (
<IconButton <IconButton
icon={isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />} icon={isOpen ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
size="xs" size="xs"
variant="ghost" variant="ghost"
aria-label={isOpen ? '收起' : '展开'} aria-label={isOpen ? '收起' : '展开'}
@@ -125,7 +125,7 @@ const CollapsibleHeader = ({
{/* showModeToggle=false 时显示原有的 IconButton */} {/* showModeToggle=false 时显示原有的 IconButton */}
{!showModeToggle && ( {!showModeToggle && (
<IconButton <IconButton
icon={isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />} icon={isOpen ? <ChevronUp size={20} /> : <ChevronDown size={20} />}
size="sm" size="sm"
variant="ghost" variant="ghost"
aria-label={isOpen ? '收起' : '展开'} aria-label={isOpen ? '收起' : '展开'}

View File

@@ -9,8 +9,8 @@ import {
Icon, Icon,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ViewIcon } from '@chakra-ui/icons';
import { EventFollowButton } from '@views/Community/components/EventCard/atoms'; import { EventFollowButton } from '@views/Community/components/EventCard/atoms';
import { Eye } from 'lucide-react';
/** /**
* 精简信息栏组件 * 精简信息栏组件
@@ -79,7 +79,7 @@ const CompactMetaBar = ({ event, importance, isFollowing, followerCount, onToggl
borderRadius="md" borderRadius="md"
boxShadow="sm" boxShadow="sm"
> >
<ViewIcon color="gray.400" boxSize={4} /> <Eye color="gray.400" size={16} />
<Text fontSize="sm" color={viewCountTextColor} whiteSpace="nowrap"> <Text fontSize="sm" color={viewCountTextColor} whiteSpace="nowrap">
{(event.view_count || 0).toLocaleString()} {(event.view_count || 0).toLocaleString()}
</Text> </Text>

View File

@@ -12,8 +12,8 @@ import {
Icon, Icon,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ViewIcon } from '@chakra-ui/icons';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { Eye } from 'lucide-react';
import StockChangeIndicators from '../StockChangeIndicators'; import StockChangeIndicators from '../StockChangeIndicators';
import { EventFollowButton } from '@views/Community/components/EventCard/atoms'; import { EventFollowButton } from '@views/Community/components/EventCard/atoms';
@@ -90,7 +90,7 @@ const EventHeaderInfo = ({ event, importance, isFollowing, followerCount, onTogg
<Flex align="left" mb={3} gap={4}> <Flex align="left" mb={3} gap={4}>
{/* 浏览数 */} {/* 浏览数 */}
<HStack spacing={1}> <HStack spacing={1}>
<ViewIcon color="gray.400" boxSize={4} /> <Eye color="gray.400" size={16} />
<Text fontSize="sm" color="gray.400" whiteSpace="nowrap"> <Text fontSize="sm" color="gray.400" whiteSpace="nowrap">
{(event.view_count || 0).toLocaleString()}次浏览 {(event.view_count || 0).toLocaleString()}次浏览
</Text> </Text>

View File

@@ -7,7 +7,7 @@ import {
Text, Text,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaCalendarAlt } from 'react-icons/fa'; import { Calendar } from 'lucide-react';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
/** /**
@@ -25,7 +25,7 @@ const TradingDateInfo = ({ effectiveTradingDate, eventTime }) => {
return ( return (
<HStack spacing={2}> <HStack spacing={2}>
<FaCalendarAlt color="gray" size={12} /> <Calendar color="gray" size={12} />
<Text fontSize="xs" color={stockCountColor}> <Text fontSize="xs" color={stockCountColor}>
涨跌幅数据{effectiveTradingDate} 涨跌幅数据{effectiveTradingDate}
{eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && ( {eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && (

View File

@@ -16,8 +16,8 @@ import {
Badge, Badge,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { StarIcon } from '@chakra-ui/icons';
import { Tag } from 'antd'; import { Tag } from 'antd';
import { Star } from 'lucide-react';
import { RobotOutlined } from '@ant-design/icons'; import { RobotOutlined } from '@ant-design/icons';
import { selectIsMobile } from '@store/slices/deviceSlice'; import { selectIsMobile } from '@store/slices/deviceSlice';
import { MiniTimelineChart } from '@components/Charts/Stock'; import { MiniTimelineChart } from '@components/Charts/Stock';
@@ -197,7 +197,7 @@ const StockListItem = ({
size="xs" size="xs"
variant={isInWatchlist ? 'solid' : 'outline'} variant={isInWatchlist ? 'solid' : 'outline'}
colorScheme={isInWatchlist ? 'yellow' : 'gray'} colorScheme={isInWatchlist ? 'yellow' : 'gray'}
icon={<StarIcon color={isInWatchlist ? undefined : 'gray.400'} />} icon={<Star size={14} color={isInWatchlist ? undefined : 'gray.400'} fill={isInWatchlist ? 'currentColor' : 'none'} />}
onClick={handleWatchlistClick} onClick={handleWatchlistClick}
aria-label={isInWatchlist ? '已关注' : '加自选'} aria-label={isInWatchlist ? '已关注' : '加自选'}
borderRadius="full" borderRadius="full"

View File

@@ -18,7 +18,7 @@ import {
useDisclosure, useDisclosure,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiSmartphone } from 'react-icons/fi'; import { Smartphone } from 'lucide-react';
// 默认小程序码图片(可替换为实际的小程序码) // 默认小程序码图片(可替换为实际的小程序码)
// 注意:需要在微信公众平台生成小程序码图片 // 注意:需要在微信公众平台生成小程序码图片
@@ -52,7 +52,7 @@ const QRCodeDisplay = ({
<Button <Button
onClick={onOpen} onClick={onOpen}
colorScheme="green" colorScheme="green"
leftIcon={<Icon as={FiSmartphone} />} leftIcon={<Icon as={Smartphone} />}
{...buttonProps} {...buttonProps}
> >
{children || '打开小程序'} {children || '打开小程序'}

View File

@@ -19,7 +19,7 @@ import {
useToast, useToast,
Icon, Icon,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiExternalLink, FiCopy, FiCheck } from 'react-icons/fi'; import { ExternalLink, Copy, Check } from 'lucide-react';
import { isIOSDevice } from './hooks/useWechatEnvironment'; import { isIOSDevice } from './hooks/useWechatEnvironment';
// 小程序 AppID // 小程序 AppID
@@ -145,7 +145,7 @@ const UrlSchemeLauncher = ({
isLoading={loading} isLoading={loading}
loadingText="正在跳转..." loadingText="正在跳转..."
colorScheme="green" colorScheme="green"
leftIcon={<Icon as={FiExternalLink} />} leftIcon={<Icon as={ExternalLink} />}
style={buttonStyle} style={buttonStyle}
{...buttonProps} {...buttonProps}
> >
@@ -186,7 +186,7 @@ const UrlSchemeLauncher = ({
colorScheme="green" colorScheme="green"
width="100%" width="100%"
onClick={handleRetry} onClick={handleRetry}
leftIcon={<Icon as={FiExternalLink} />} leftIcon={<Icon as={ExternalLink} />}
> >
打开微信 打开微信
</Button> </Button>
@@ -194,7 +194,7 @@ const UrlSchemeLauncher = ({
variant="outline" variant="outline"
width="100%" width="100%"
onClick={handleCopy} onClick={handleCopy}
leftIcon={<Icon as={copied ? FiCheck : FiCopy} />} leftIcon={<Icon as={copied ? Check : Copy} />}
> >
{copied ? '已复制' : '复制链接'} {copied ? '已复制' : '复制链接'}
</Button> </Button>

View File

@@ -48,8 +48,7 @@ import {
import { SidebarResponsive } from 'components/Sidebar/Sidebar'; import { SidebarResponsive } from 'components/Sidebar/Sidebar';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Fragment } from 'react'; import { Fragment } from 'react';
import { AiFillStar } from 'react-icons/ai'; import { Star, ChevronDown, ChevronRight } from 'lucide-react';
import { GoChevronDown, GoChevronRight } from 'react-icons/go';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import { SidebarContext } from 'contexts/SidebarContext'; import { SidebarContext } from 'contexts/SidebarContext';
import routes from 'routes.js'; import routes from 'routes.js';
@@ -313,7 +312,7 @@ export default function AuthNavbar(props) {
{link.name} {link.name}
</Text> </Text>
<Icon <Icon
as={GoChevronRight} as={ChevronRight}
color={mainText} color={mainText}
w='14px' w='14px'
h='14px' h='14px'
@@ -419,7 +418,7 @@ export default function AuthNavbar(props) {
Pages Pages
</Text> </Text>
<Icon <Icon
as={GoChevronDown} as={ChevronDown}
color={mainText} color={mainText}
w='14px' w='14px'
h='14px' h='14px'
@@ -457,7 +456,7 @@ export default function AuthNavbar(props) {
Authentications Authentications
</Text> </Text>
<Icon <Icon
as={GoChevronDown} as={ChevronDown}
color={mainText} color={mainText}
w='14px' w='14px'
h='14px' h='14px'
@@ -493,7 +492,7 @@ export default function AuthNavbar(props) {
w='50px' w='50px'
mb='12px' mb='12px'
> >
<Icon as={AiFillStar} w='25px' h='25px' color='blue.500' /> <Icon as={Star} w='25px' h='25px' color='blue.500' fill='currentColor' />
</IconBox> </IconBox>
<Text <Text
fontSize='xl' fontSize='xl'
@@ -527,7 +526,7 @@ export default function AuthNavbar(props) {
Application Application
</Text> </Text>
<Icon <Icon
as={GoChevronDown} as={ChevronDown}
color={mainText} color={mainText}
w='14px' w='14px'
h='14px' h='14px'
@@ -564,7 +563,7 @@ export default function AuthNavbar(props) {
Ecommerce Ecommerce
</Text> </Text>
<Icon <Icon
as={GoChevronDown} as={ChevronDown}
color={mainText} color={mainText}
w='14px' w='14px'
h='14px' h='14px'

View File

@@ -21,9 +21,7 @@ import {
useColorModeValue, useColorModeValue,
useToast, useToast,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/icons'; import { ChevronDown, Menu as MenuIcon, Sun, Moon, Star, Calendar, User, Settings, Home, LogOut, Crown } from 'lucide-react';
import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi';
import { FaCrown } from 'react-icons/fa';
import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigate, useLocation } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext'; import { useAuth } from '../../contexts/AuthContext';
import { useAuthModal } from '../../hooks/useAuthModal'; import { useAuthModal } from '../../hooks/useAuthModal';

View File

@@ -20,8 +20,8 @@ import {
ListItem, ListItem,
Flex, Flex,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { SearchIcon, CloseIcon } from "@chakra-ui/icons";
import { useStockSearch } from "@hooks/useStockSearch"; import { useStockSearch } from "@hooks/useStockSearch";
import { Search, X } from "lucide-react";
export function SearchBar(props) { export function SearchBar(props) {
const { variant, children, ...rest } = props; const { variant, children, ...rest } = props;
@@ -80,7 +80,7 @@ export function SearchBar(props) {
<Box ref={containerRef} position="relative" {...rest}> <Box ref={containerRef} position="relative" {...rest}>
<InputGroup borderRadius="8px" w="220px"> <InputGroup borderRadius="8px" w="220px">
<InputLeftElement pointerEvents="none"> <InputLeftElement pointerEvents="none">
<SearchIcon color={searchIconColor} w="15px" h="15px" /> <Search color={searchIconColor} size={15} />
</InputLeftElement> </InputLeftElement>
<Input <Input
variant="search" variant="search"
@@ -103,7 +103,7 @@ export function SearchBar(props) {
<IconButton <IconButton
size="xs" size="xs"
variant="ghost" variant="ghost"
icon={<CloseIcon w="10px" h="10px" />} icon={<X size={10} />}
onClick={clearSearch} onClick={clearSearch}
aria-label="清除搜索" aria-label="清除搜索"
_hover={{ bg: "transparent" }} _hover={{ bg: "transparent" }}

View File

@@ -9,7 +9,7 @@ import {
ModalBody, ModalBody,
ModalCloseButton ModalCloseButton
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiCalendar } from 'react-icons/fi'; import { Calendar } from 'lucide-react';
import InvestmentCalendar from '@components/InvestmentCalendar'; import InvestmentCalendar from '@components/InvestmentCalendar';
/** /**
@@ -35,7 +35,7 @@ const CalendarButton = memo(() => {
colorScheme="blue" colorScheme="blue"
variant="solid" variant="solid"
borderRadius="full" borderRadius="full"
leftIcon={<FiCalendar />} leftIcon={<Calendar size={16} />}
onClick={() => setIsModalOpen(true)} onClick={() => setIsModalOpen(true)}
> >
投资日历 投资日历

View File

@@ -17,8 +17,7 @@ import {
Spinner, Spinner,
useColorModeValue useColorModeValue
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons'; import { Calendar, ChevronDown } from 'lucide-react';
import { FiCalendar } from 'react-icons/fi';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useFollowingEvents } from '../../../../hooks/useFollowingEvents'; import { useFollowingEvents } from '../../../../hooks/useFollowingEvents';
import { getEventDetailUrl } from '@/utils/idEncoder'; import { getEventDetailUrl } from '@/utils/idEncoder';
@@ -67,8 +66,8 @@ const FollowingEventsMenu = memo(() => {
colorScheme="purple" colorScheme="purple"
variant="solid" variant="solid"
borderRadius="full" borderRadius="full"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={16} />}
leftIcon={<FiCalendar />} leftIcon={<Calendar size={16} />}
> >
自选事件 自选事件
{followingEvents && followingEvents.length > 0 && ( {followingEvents && followingEvents.length > 0 && (

View File

@@ -17,8 +17,7 @@ import {
Spinner, Spinner,
useColorModeValue useColorModeValue
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons'; import { Star, ChevronDown } from 'lucide-react';
import { FiStar } from 'react-icons/fi';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useWatchlist } from '../../../../hooks/useWatchlist'; import { useWatchlist } from '../../../../hooks/useWatchlist';
import FavoriteButton from '@/components/FavoriteButton'; import FavoriteButton from '@/components/FavoriteButton';
@@ -66,8 +65,8 @@ const WatchlistMenu = memo(() => {
colorScheme="teal" colorScheme="teal"
variant="solid" variant="solid"
borderRadius="full" borderRadius="full"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={16} />}
leftIcon={<FiStar />} leftIcon={<Star size={16} />}
> >
自选股 自选股
{watchlistQuotes && watchlistQuotes.length > 0 && ( {watchlistQuotes && watchlistQuotes.length > 0 && (

View File

@@ -3,7 +3,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { HStack, IconButton, Box } from '@chakra-ui/react'; import { HStack, IconButton, Box } from '@chakra-ui/react';
import { HamburgerIcon } from '@chakra-ui/icons'; import { Menu } from 'lucide-react';
// import ThemeToggleButton from '../ThemeToggleButton'; // ❌ 已删除 - 不再支持深色模式切换 // import ThemeToggleButton from '../ThemeToggleButton'; // ❌ 已删除 - 不再支持深色模式切换
import LoginButton from '../LoginButton'; import LoginButton from '../LoginButton';
import CalendarButton from '../CalendarButton'; import CalendarButton from '../CalendarButton';
@@ -84,7 +84,7 @@ const NavbarActions = memo(({
) : ( ) : (
// 移动端:汉堡菜单(打开抽屉) // 移动端:汉堡菜单(打开抽屉)
<IconButton <IconButton
icon={<HamburgerIcon />} icon={<Menu size={20} />}
variant="ghost" variant="ghost"
onClick={onMenuOpen} onClick={onMenuOpen}
aria-label="打开菜单" aria-label="打开菜单"

View File

@@ -17,7 +17,7 @@ import {
Box, Box,
useColorModeValue useColorModeValue
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons'; import { ChevronDown } from 'lucide-react';
import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigate, useLocation } from 'react-router-dom';
import { useNavigationEvents } from '../../../../hooks/useNavigationEvents'; import { useNavigationEvents } from '../../../../hooks/useNavigationEvents';
import { useDelayedMenu } from '../../../../hooks/useDelayedMenu'; import { useDelayedMenu } from '../../../../hooks/useDelayedMenu';
@@ -60,7 +60,7 @@ const DesktopNav = memo(({ isAuthenticated, user }) => {
<MenuButton <MenuButton
as={Button} as={Button}
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon color={isActive(['/community', '/concepts']) ? 'white' : 'inherit'} />} rightIcon={<ChevronDown size={16} color={isActive(['/community', '/concepts']) ? 'white' : 'currentColor'} />}
bg={isActive(['/community', '/concepts']) ? 'blue.600' : 'transparent'} bg={isActive(['/community', '/concepts']) ? 'blue.600' : 'transparent'}
color={isActive(['/community', '/concepts']) ? 'white' : 'inherit'} color={isActive(['/community', '/concepts']) ? 'white' : 'inherit'}
fontWeight={isActive(['/community', '/concepts']) ? 'bold' : 'normal'} fontWeight={isActive(['/community', '/concepts']) ? 'bold' : 'normal'}
@@ -127,7 +127,7 @@ const DesktopNav = memo(({ isAuthenticated, user }) => {
<MenuButton <MenuButton
as={Button} as={Button}
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon color={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'white' : 'inherit'} />} rightIcon={<ChevronDown size={16} color={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'white' : 'currentColor'} />}
bg={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'blue.600' : 'transparent'} bg={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'blue.600' : 'transparent'}
color={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'white' : 'inherit'} color={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'white' : 'inherit'}
fontWeight={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'bold' : 'normal'} fontWeight={isActive(['/limit-analyse', '/stocks', '/trading-simulation']) ? 'bold' : 'normal'}
@@ -199,7 +199,7 @@ const DesktopNav = memo(({ isAuthenticated, user }) => {
<MenuButton <MenuButton
as={Button} as={Button}
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon color={isActive(['/agent-chat', '/value-forum']) ? 'white' : 'inherit'} />} rightIcon={<ChevronDown size={16} color={isActive(['/agent-chat', '/value-forum']) ? 'white' : 'currentColor'} />}
bg={isActive(['/agent-chat', '/value-forum']) ? 'blue.600' : 'transparent'} bg={isActive(['/agent-chat', '/value-forum']) ? 'blue.600' : 'transparent'}
color={isActive(['/agent-chat', '/value-forum']) ? 'white' : 'inherit'} color={isActive(['/agent-chat', '/value-forum']) ? 'white' : 'inherit'}
fontWeight={isActive(['/agent-chat', '/value-forum']) ? 'bold' : 'normal'} fontWeight={isActive(['/agent-chat', '/value-forum']) ? 'bold' : 'normal'}
@@ -274,7 +274,7 @@ const DesktopNav = memo(({ isAuthenticated, user }) => {
<MenuButton <MenuButton
as={Button} as={Button}
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={16} />}
onMouseEnter={contactUsMenu.handleMouseEnter} onMouseEnter={contactUsMenu.handleMouseEnter}
onMouseLeave={contactUsMenu.handleMouseLeave} onMouseLeave={contactUsMenu.handleMouseLeave}
onClick={contactUsMenu.handleClick} onClick={contactUsMenu.handleClick}

View File

@@ -14,7 +14,7 @@ import {
HStack, HStack,
Badge Badge
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons'; import { ChevronDown } from 'lucide-react';
import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigate, useLocation } from 'react-router-dom';
import { useDelayedMenu } from '../../../../hooks/useDelayedMenu'; import { useDelayedMenu } from '../../../../hooks/useDelayedMenu';
@@ -45,7 +45,7 @@ const MoreMenu = memo(({ isAuthenticated, user }) => {
<MenuButton <MenuButton
as={Button} as={Button}
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={16} />}
fontWeight="medium" fontWeight="medium"
onMouseEnter={moreMenu.handleMouseEnter} onMouseEnter={moreMenu.handleMouseEnter}
onMouseLeave={moreMenu.handleMouseLeave} onMouseLeave={moreMenu.handleMouseLeave}

View File

@@ -15,9 +15,7 @@ import {
useColorModeValue, useColorModeValue,
useDisclosure useDisclosure
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons'; import { ChevronDown, Home, User, Settings, LogOut, Crown } from 'lucide-react';
import { FiHome, FiUser, FiSettings, FiLogOut } from 'react-icons/fi';
import { FaCrown } from 'react-icons/fa';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
/** /**
@@ -50,7 +48,7 @@ const PersonalCenterMenu = memo(({ user, handleLogout }) => {
as={Button} as={Button}
size="sm" size="sm"
variant="ghost" variant="ghost"
rightIcon={<ChevronDownIcon />} rightIcon={<ChevronDown size={16} />}
_hover={{ bg: hoverBg }} _hover={{ bg: hoverBg }}
onMouseEnter={onOpen} onMouseEnter={onOpen}
onMouseLeave={onClose} onMouseLeave={onClose}
@@ -70,7 +68,7 @@ const PersonalCenterMenu = memo(({ user, handleLogout }) => {
</Box> </Box>
{/* 前往个人中心 */} {/* 前往个人中心 */}
<MenuItem icon={<FiHome />} onClick={() => { <MenuItem icon={<Home size={16} />} onClick={() => {
onClose(); // 先关闭菜单 onClose(); // 先关闭菜单
navigate('/home/center'); navigate('/home/center');
}}> }}>
@@ -80,13 +78,13 @@ const PersonalCenterMenu = memo(({ user, handleLogout }) => {
<MenuDivider /> <MenuDivider />
{/* 账户管理组 */} {/* 账户管理组 */}
<MenuItem icon={<FiUser />} onClick={() => { <MenuItem icon={<User size={16} />} onClick={() => {
onClose(); // 先关闭菜单 onClose(); // 先关闭菜单
navigate('/home/profile'); navigate('/home/profile');
}}> }}>
个人资料 个人资料
</MenuItem> </MenuItem>
<MenuItem icon={<FiSettings />} onClick={() => { <MenuItem icon={<Settings size={16} />} onClick={() => {
onClose(); // 先关闭菜单 onClose(); // 先关闭菜单
navigate('/home/settings'); navigate('/home/settings');
}}> }}>
@@ -96,7 +94,7 @@ const PersonalCenterMenu = memo(({ user, handleLogout }) => {
<MenuDivider /> <MenuDivider />
{/* 功能入口组 */} {/* 功能入口组 */}
<MenuItem icon={<FaCrown />} onClick={() => { <MenuItem icon={<Crown size={16} />} onClick={() => {
onClose(); // 先关闭菜单 onClose(); // 先关闭菜单
navigate('/home/pages/account/subscription'); navigate('/home/pages/account/subscription');
}}> }}>
@@ -106,7 +104,7 @@ const PersonalCenterMenu = memo(({ user, handleLogout }) => {
<MenuDivider /> <MenuDivider />
{/* 退出 */} {/* 退出 */}
<MenuItem icon={<FiLogOut />} onClick={handleLogout} color="red.500"> <MenuItem icon={<LogOut size={16} />} onClick={handleLogout} color="red.500">
退出登录 退出登录
</MenuItem> </MenuItem>
</MenuList> </MenuList>

View File

@@ -12,7 +12,7 @@ import {
IconButton, IconButton,
Icon Icon
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiStar } from 'react-icons/fi'; import { Star } from 'lucide-react';
/** /**
* 资料完整性提醒横幅组件 * 资料完整性提醒横幅组件
@@ -45,7 +45,7 @@ const ProfileCompletenessAlert = memo(({
<Container maxW="container.xl"> <Container maxW="container.xl">
<HStack justify="space-between" align="center" spacing={{ base: 2, md: 4 }}> <HStack justify="space-between" align="center" spacing={{ base: 2, md: 4 }}>
<HStack spacing={{ base: 2, md: 3 }} flex={1} minW={0}> <HStack spacing={{ base: 2, md: 3 }} flex={1} minW={0}>
<Icon as={FiStar} display={{ base: 'none', sm: 'block' }} /> <Icon as={Star} boxSize={5} display={{ base: 'none', sm: 'block' }} />
<VStack spacing={0} align="start" flex={1} minW={0}> <VStack spacing={0} align="start" flex={1} minW={0}>
<Text fontSize={{ base: 'xs', md: 'sm' }} fontWeight="bold" noOfLines={1}> <Text fontSize={{ base: 'xs', md: 'sm' }} fontWeight="bold" noOfLines={1}>
完善资料享受更好服务 完善资料享受更好服务

View File

@@ -14,8 +14,7 @@ import {
Flex, Flex,
useColorModeValue useColorModeValue
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiStar, FiCalendar, FiUser, FiSettings, FiHome, FiLogOut } from 'react-icons/fi'; import { Star, Calendar, User, Settings, Home, LogOut, Crown } from 'lucide-react';
import { FaCrown } from 'react-icons/fa';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import UserAvatar from './UserAvatar'; import UserAvatar from './UserAvatar';
import { useSubscription } from '../../../../hooks/useSubscription'; import { useSubscription } from '../../../../hooks/useSubscription';
@@ -84,7 +83,7 @@ const TabletUserMenu = memo(({
</Box> </Box>
{/* 订阅管理 - 移动端导航到订阅页面 */} {/* 订阅管理 - 移动端导航到订阅页面 */}
<MenuItem icon={<FaCrown />} onClick={() => navigate('/home/pages/account/subscription')}> <MenuItem icon={<Crown size={16} />} onClick={() => navigate('/home/pages/account/subscription')}>
<Flex justify="space-between" align="center" w="100%"> <Flex justify="space-between" align="center" w="100%">
<Text>订阅管理</Text> <Text>订阅管理</Text>
<Badge colorScheme={getSubscriptionBadgeColor()}> <Badge colorScheme={getSubscriptionBadgeColor()}>
@@ -96,12 +95,12 @@ const TabletUserMenu = memo(({
<MenuDivider /> <MenuDivider />
{/* 投资日历 */} {/* 投资日历 */}
<MenuItem icon={<FiCalendar />} onClick={() => navigate('/community')}> <MenuItem icon={<Calendar size={16} />} onClick={() => navigate('/community')}>
<Text>投资日历</Text> <Text>投资日历</Text>
</MenuItem> </MenuItem>
{/* 自选股 */} {/* 自选股 */}
<MenuItem icon={<FiStar />} onClick={() => navigate('/home/center')}> <MenuItem icon={<Star size={16} />} onClick={() => navigate('/home/center')}>
<Flex justify="space-between" align="center" w="100%"> <Flex justify="space-between" align="center" w="100%">
<Text>我的自选股</Text> <Text>我的自选股</Text>
{watchlistQuotes && watchlistQuotes.length > 0 && ( {watchlistQuotes && watchlistQuotes.length > 0 && (
@@ -111,7 +110,7 @@ const TabletUserMenu = memo(({
</MenuItem> </MenuItem>
{/* 自选事件 */} {/* 自选事件 */}
<MenuItem icon={<FiCalendar />} onClick={() => navigate('/home/center')}> <MenuItem icon={<Calendar size={16} />} onClick={() => navigate('/home/center')}>
<Flex justify="space-between" align="center" w="100%"> <Flex justify="space-between" align="center" w="100%">
<Text>我的自选事件</Text> <Text>我的自选事件</Text>
{followingEvents && followingEvents.length > 0 && ( {followingEvents && followingEvents.length > 0 && (
@@ -123,20 +122,20 @@ const TabletUserMenu = memo(({
<MenuDivider /> <MenuDivider />
{/* 个人中心 */} {/* 个人中心 */}
<MenuItem icon={<FiHome />} onClick={() => navigate('/home/center')}> <MenuItem icon={<Home size={16} />} onClick={() => navigate('/home/center')}>
个人中心 个人中心
</MenuItem> </MenuItem>
<MenuItem icon={<FiUser />} onClick={() => navigate('/home/profile')}> <MenuItem icon={<User size={16} />} onClick={() => navigate('/home/profile')}>
个人资料 个人资料
</MenuItem> </MenuItem>
<MenuItem icon={<FiSettings />} onClick={() => navigate('/home/settings')}> <MenuItem icon={<Settings size={16} />} onClick={() => navigate('/home/settings')}>
账户设置 账户设置
</MenuItem> </MenuItem>
<MenuDivider /> <MenuDivider />
{/* 退出登录 */} {/* 退出登录 */}
<MenuItem icon={<FiLogOut />} onClick={handleLogout} color="red.500"> <MenuItem icon={<LogOut size={16} />} onClick={handleLogout} color="red.500">
退出登录 退出登录
</MenuItem> </MenuItem>
</MenuList> </MenuList>

View File

@@ -19,7 +19,7 @@ import {
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { keyframes } from '@emotion/react'; import { keyframes } from '@emotion/react';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { MdClose, MdOpenInNew, MdSchedule, MdExpandMore, MdExpandLess, MdPerson, MdAccessTime } from 'react-icons/md'; import { X, ExternalLink, Clock as ClockIcon, ChevronDown, ChevronUp, User, Clock } from 'lucide-react';
import { useNotification } from '../../contexts/NotificationContext'; import { useNotification } from '../../contexts/NotificationContext';
import { import {
NOTIFICATION_TYPE_CONFIGS, NOTIFICATION_TYPE_CONFIGS,
@@ -479,7 +479,7 @@ const NotificationItem = React.memo(({ notification, onClose, isNewest = false }
{/* 关闭按钮 */} {/* 关闭按钮 */}
<IconButton <IconButton
icon={<MdClose />} icon={<X size={16} />}
size="xs" size="xs"
variant="ghost" variant="ghost"
colorScheme={typeConfig.colorScheme} colorScheme={typeConfig.colorScheme}
@@ -524,7 +524,7 @@ const NotificationItem = React.memo(({ notification, onClose, isNewest = false }
> >
{/* 时间信息 */} {/* 时间信息 */}
<HStack spacing={1}> <HStack spacing={1}>
<Icon as={MdAccessTime} w={3} h={3} /> <Icon as={Clock} w={3} h={3} />
<Text> <Text>
{publishTime && formatNotificationTime(publishTime)} {publishTime && formatNotificationTime(publishTime)}
{!publishTime && pushTime && formatNotificationTime(pushTime)} {!publishTime && pushTime && formatNotificationTime(pushTime)}
@@ -553,7 +553,7 @@ const NotificationItem = React.memo(({ notification, onClose, isNewest = false }
<Badge colorScheme="gray" size="xs">预测</Badge> <Badge colorScheme="gray" size="xs">预测</Badge>
{extra?.statusHint && ( {extra?.statusHint && (
<> <>
<Icon as={MdSchedule} w={3} h={3} color="gray.400" /> <Icon as={ClockIcon} w={3} h={3} color="gray.400" />
<Text color="gray.400">{extra.statusHint}</Text> <Text color="gray.400">{extra.statusHint}</Text>
</> </>
)} )}
@@ -566,7 +566,7 @@ const NotificationItem = React.memo(({ notification, onClose, isNewest = false }
<> <>
<Text display={{ base: "none", md: "inline" }}>|</Text> <Text display={{ base: "none", md: "inline" }}>|</Text>
<HStack spacing={1} display={{ base: "none", md: "flex" }}> <HStack spacing={1} display={{ base: "none", md: "flex" }}>
<Icon as={MdPerson} w={3} h={3} /> <Icon as={User} w={3} h={3} />
<Text>{author.name} - {author.organization}</Text> <Text>{author.name} - {author.organization}</Text>
</HStack> </HStack>
</> </>
@@ -581,7 +581,7 @@ const NotificationItem = React.memo(({ notification, onClose, isNewest = false }
{isNavigating ? ( {isNavigating ? (
<Spinner size="xs" /> <Spinner size="xs" />
) : ( ) : (
<Icon as={MdOpenInNew} w={3} h={3} /> <Icon as={ExternalLink} w={3} h={3} />
)} )}
{/* Loading 时显示"跳转中...",否则显示"查看详情" */} {/* Loading 时显示"跳转中...",否则显示"查看详情" */}
<Text color={isNavigating ? 'blue.500' : undefined}> <Text color={isNavigating ? 'blue.500' : undefined}>
@@ -734,7 +734,7 @@ const NotificationContainer = () => {
outlineColor: 'blue.500', outlineColor: 'blue.500',
outlineOffset: '2px', outlineOffset: '2px',
}} }}
leftIcon={<Icon as={isExpanded ? MdExpandLess : MdExpandMore} />} leftIcon={<Icon as={isExpanded ? ChevronUp : ChevronDown} />}
onClick={() => setIsExpanded(!isExpanded)} onClick={() => setIsExpanded(!isExpanded)}
aria-expanded={isExpanded} aria-expanded={isExpanded}
aria-label={isExpanded ? '收起通知' : `展开查看还有 ${hiddenCount} 条通知`} aria-label={isExpanded ? '收起通知' : `展开查看还有 ${hiddenCount} 条通知`}

View File

@@ -27,7 +27,7 @@ import {
DrawerContent, DrawerContent,
DrawerCloseButton, DrawerCloseButton,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { MdSpeed, MdClose, MdRefresh, MdFileDownload } from 'react-icons/md'; import { Gauge, X, RefreshCw, Download } from 'lucide-react';
import { performanceMonitor } from '@/utils/performanceMonitor'; import { performanceMonitor } from '@/utils/performanceMonitor';
/** /**
@@ -98,7 +98,7 @@ export const PerformancePanel: React.FC = () => {
{/* 浮动按钮 */} {/* 浮动按钮 */}
<IconButton <IconButton
aria-label="Open performance panel" aria-label="Open performance panel"
icon={<MdSpeed />} icon={<Gauge size={24} />}
position="fixed" position="fixed"
bottom="100px" bottom="100px"
right="20px" right="20px"
@@ -117,7 +117,7 @@ export const PerformancePanel: React.FC = () => {
<DrawerCloseButton /> <DrawerCloseButton />
<DrawerHeader borderBottomWidth="1px"> <DrawerHeader borderBottomWidth="1px">
<HStack> <HStack>
<MdSpeed size={24} /> <Gauge size={24} />
<Text></Text> <Text></Text>
</HStack> </HStack>
</DrawerHeader> </DrawerHeader>
@@ -128,7 +128,7 @@ export const PerformancePanel: React.FC = () => {
{/* 操作按钮 */} {/* 操作按钮 */}
<HStack spacing={2}> <HStack spacing={2}>
<Button <Button
leftIcon={<MdRefresh />} leftIcon={<RefreshCw size={16} />}
size="sm" size="sm"
colorScheme="blue" colorScheme="blue"
onClick={refreshData} onClick={refreshData}
@@ -136,7 +136,7 @@ export const PerformancePanel: React.FC = () => {
</Button> </Button>
<Button <Button
leftIcon={<MdFileDownload />} leftIcon={<Download size={16} />}
size="sm" size="sm"
colorScheme="green" colorScheme="green"
onClick={exportJSON} onClick={exportJSON}

View File

@@ -3,7 +3,7 @@
import React from 'react'; import React from 'react';
import { Flex, Box, Text, useColorModeValue } from '@chakra-ui/react'; import { Flex, Box, Text, useColorModeValue } from '@chakra-ui/react';
import { TriangleUpIcon, TriangleDownIcon } from '@chakra-ui/icons'; import { ChevronUp, ChevronDown } from 'lucide-react';
import { getChangeColor } from '../utils/colorUtils'; import { getChangeColor } from '../utils/colorUtils';
/** /**
@@ -108,16 +108,12 @@ const StockChangeIndicators = ({
{/* 三角形图标 */} {/* 三角形图标 */}
{value !== 0 && ( {value !== 0 && (
value > 0 ? ( value > 0 ? (
<TriangleUpIcon <ChevronUp
w={2} style={{ width: '8px', height: '8px', color: numberColor }}
h={2}
color={numberColor}
/> />
) : ( ) : (
<TriangleDownIcon <ChevronDown
w={2} style={{ width: '8px', height: '8px', color: numberColor }}
h={2}
color={numberColor}
/> />
) )
)} )}

View File

@@ -35,7 +35,7 @@ import {
Spinner, Spinner,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import type { ComponentType } from 'react'; import type { ComponentType } from 'react';
import type { IconType } from 'react-icons'; import type { LucideIcon } from 'lucide-react';
/** /**
* Tab 配置项 * Tab 配置项
@@ -43,7 +43,7 @@ import type { IconType } from 'react-icons';
export interface SubTabConfig { export interface SubTabConfig {
key: string; key: string;
name: string; name: string;
icon?: IconType | ComponentType; icon?: LucideIcon | ComponentType;
component?: ComponentType<any>; component?: ComponentType<any>;
/** 自定义 Suspense fallback如骨架屏 */ /** 自定义 Suspense fallback如骨架屏 */
fallback?: React.ReactNode; fallback?: React.ReactNode;

View File

@@ -42,19 +42,19 @@ import { useSubscriptionEvents } from '../../hooks/useSubscriptionEvents';
// Icons // Icons
import { import {
FaWeixin, Crown,
FaGem, Star,
FaCheck, Check,
FaQrcode, QrCode,
FaClock, Clock,
FaRedo, RefreshCw,
FaCrown, X,
FaStar, Infinity,
FaTimes, ChevronDown,
FaInfinity, ChevronUp,
FaChevronDown, Gem,
FaChevronUp, } from 'lucide-react';
} from 'react-icons/fa'; import { WechatOutlined } from '@ant-design/icons';
import { getApiBase } from '../../utils/apiConfig'; import { getApiBase } from '../../utils/apiConfig';
// 会员协议 URL 配置 // 会员协议 URL 配置
@@ -761,7 +761,7 @@ export default function SubscriptionContent() {
)} )}
{user.subscription_status === 'active' && user.subscription_type !== 'free' && ( {user.subscription_status === 'active' && user.subscription_type !== 'free' && (
<Icon <Icon
as={user.subscription_type === 'max' ? FaCrown : FaGem} as={user.subscription_type === 'max' ? Crown : Gem}
color={user.subscription_type === 'max' ? 'purple.400' : 'blue.400'} color={user.subscription_type === 'max' ? 'purple.400' : 'blue.400'}
boxSize={6} boxSize={6}
/> />
@@ -909,7 +909,7 @@ export default function SubscriptionContent() {
<Flex justify="space-between" align="center"> <Flex justify="space-between" align="center">
<HStack spacing={3}> <HStack spacing={3}>
<Icon <Icon
as={FaStar} as={Star}
boxSize={8} boxSize={8}
color="gray.400" color="gray.400"
/> />
@@ -945,7 +945,7 @@ export default function SubscriptionContent() {
return ( return (
<HStack key={index} spacing={3} align="start"> <HStack key={index} spacing={3} align="start">
<Icon <Icon
as={hasFreeAccess ? FaCheck : FaTimes} as={hasFreeAccess ? Check : X}
color={hasFreeAccess ? 'blue.500' : 'gray.300'} color={hasFreeAccess ? 'blue.500' : 'gray.300'}
boxSize={4} boxSize={4}
mt={0.5} mt={0.5}
@@ -1031,7 +1031,7 @@ export default function SubscriptionContent() {
<Flex justify="space-between" align="center"> <Flex justify="space-between" align="center">
<HStack spacing={3}> <HStack spacing={3}>
<Icon <Icon
as={plan.name === 'pro' ? FaGem : FaCrown} as={plan.name === 'pro' ? Gem : Crown}
boxSize={8} boxSize={8}
color={plan.name === 'pro' ? 'blue.400' : 'purple.400'} color={plan.name === 'pro' ? 'blue.400' : 'purple.400'}
/> />
@@ -1139,7 +1139,7 @@ export default function SubscriptionContent() {
return ( return (
<HStack key={index} spacing={3} align="start"> <HStack key={index} spacing={3} align="start">
<Icon <Icon
as={isSupported ? FaCheck : FaTimes} as={isSupported ? Check : X}
color={isSupported ? 'blue.500' : 'gray.300'} color={isSupported ? 'blue.500' : 'gray.300'}
boxSize={4} boxSize={4}
mt={0.5} mt={0.5}
@@ -1226,7 +1226,7 @@ export default function SubscriptionContent() {
如何取消订阅 如何取消订阅
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 0 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 0 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1260,7 +1260,7 @@ export default function SubscriptionContent() {
支持哪些支付方式 支持哪些支付方式
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 1 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 1 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1294,7 +1294,7 @@ export default function SubscriptionContent() {
升级或切换套餐时原套餐的费用怎么办 升级或切换套餐时原套餐的费用怎么办
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 2 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 2 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1342,7 +1342,7 @@ export default function SubscriptionContent() {
可以在月付和年付之间切换吗 可以在月付和年付之间切换吗
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 3 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 3 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1376,7 +1376,7 @@ export default function SubscriptionContent() {
是否支持退款 是否支持退款
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 4 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 4 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1430,7 +1430,7 @@ export default function SubscriptionContent() {
Pro版和Max版有什么区别 Pro版和Max版有什么区别
</Text> </Text>
<Icon <Icon
as={openFaqIndex === 5 ? FaChevronUp : FaChevronDown} as={openFaqIndex === 5 ? ChevronUp : ChevronDown}
color={textColor} color={textColor}
/> />
</Flex> </Flex>
@@ -1467,7 +1467,7 @@ export default function SubscriptionContent() {
<ModalContent> <ModalContent>
<ModalHeader> <ModalHeader>
<HStack> <HStack>
<Icon as={FaWeixin} color="green.500" /> <WechatOutlined style={{ fontSize: '24px', color: '#52c41a' }} />
<Text>微信支付</Text> <Text>微信支付</Text>
</HStack> </HStack>
</ModalHeader> </ModalHeader>
@@ -1509,7 +1509,7 @@ export default function SubscriptionContent() {
{priceInfo && priceInfo.is_upgrade && ( {priceInfo && priceInfo.is_upgrade && (
<Box bg="blue.50" p={3} borderRadius="md" mb={2}> <Box bg="blue.50" p={3} borderRadius="md" mb={2}>
<HStack spacing={2} mb={2}> <HStack spacing={2} mb={2}>
<Icon as={FaCheck} color="blue.500" boxSize={4} /> <Icon as={Check} color="blue.500" boxSize={4} />
<Text fontSize="sm" fontWeight="bold" color="blue.700"> <Text fontSize="sm" fontWeight="bold" color="blue.700">
{priceInfo.upgrade_type === 'plan_upgrade' ? '套餐升级' : {priceInfo.upgrade_type === 'plan_upgrade' ? '套餐升级' :
priceInfo.upgrade_type === 'cycle_change' ? '周期变更' : '套餐和周期调整'} priceInfo.upgrade_type === 'cycle_change' ? '周期变更' : '套餐和周期调整'}
@@ -1601,12 +1601,12 @@ export default function SubscriptionContent() {
)} )}
{promoCodeApplied && priceInfo && ( {promoCodeApplied && priceInfo && (
<HStack mt={2} p={2} bg="green.50" borderRadius="md"> <HStack mt={2} p={2} bg="green.50" borderRadius="md">
<Icon as={FaCheck} color="green.500" /> <Icon as={Check} color="green.500" />
<Text color="green.700" fontSize="sm" fontWeight="medium" flex={1}> <Text color="green.700" fontSize="sm" fontWeight="medium" flex={1}>
优惠码已应用节省 ¥{priceInfo.discount_amount.toFixed(2)} 优惠码已应用节省 ¥{priceInfo.discount_amount.toFixed(2)}
</Text> </Text>
<Icon <Icon
as={FaTimes} as={X}
color="gray.500" color="gray.500"
cursor="pointer" cursor="pointer"
onClick={handleRemovePromoCode} onClick={handleRemovePromoCode}
@@ -1642,7 +1642,7 @@ export default function SubscriptionContent() {
<Button <Button
colorScheme="green" colorScheme="green"
size="lg" size="lg"
leftIcon={<Icon as={FaWeixin} />} leftIcon={<WechatOutlined style={{ fontSize: '20px' }} />}
onClick={() => { onClick={() => {
if (!agreementChecked) { if (!agreementChecked) {
toast({ toast({
@@ -1673,7 +1673,7 @@ export default function SubscriptionContent() {
{/* 倒计时 */} {/* 倒计时 */}
<Box p={3} bg="orange.50" borderRadius="lg"> <Box p={3} bg="orange.50" borderRadius="lg">
<HStack justify="center" spacing={2} mb={2}> <HStack justify="center" spacing={2} mb={2}>
<Icon as={FaClock} color="orange.500" /> <Icon as={Clock} color="orange.500" />
<Text color="orange.700" fontSize="sm"> <Text color="orange.700" fontSize="sm">
二维码有效时间: {formatTime(paymentCountdown)} 二维码有效时间: {formatTime(paymentCountdown)}
</Text> </Text>
@@ -1710,7 +1710,7 @@ export default function SubscriptionContent() {
borderColor={borderColor} borderColor={borderColor}
borderRadius="lg" borderRadius="lg"
> >
<Icon as={FaQrcode} color="gray.400" boxSize={12} /> <Icon as={QrCode} color="gray.400" boxSize={12} />
</Flex> </Flex>
)} )}
</Box> </Box>
@@ -1734,7 +1734,7 @@ export default function SubscriptionContent() {
<Button <Button
flex={1} flex={1}
variant="outline" variant="outline"
leftIcon={<Icon as={FaRedo} />} leftIcon={<Icon as={RefreshCw} />}
onClick={handleCheckPaymentStatus} onClick={handleCheckPaymentStatus}
isLoading={checkingPayment} isLoading={checkingPayment}
loadingText="检查中..." loadingText="检查中..."

View File

@@ -27,20 +27,19 @@ import {
Link as ChakraLink, Link as ChakraLink,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { import {
FaWeixin, Crown,
FaGem, Star,
FaCheck, Check,
FaQrcode, QrCode,
FaClock, Clock,
FaRedo, RefreshCw,
FaCrown, X,
FaStar, ChevronDown,
FaTimes, ChevronUp,
FaChevronDown, ExternalLink,
FaChevronUp, Gem,
FaExternalLinkAlt, } from 'lucide-react';
} from 'react-icons/fa'; import { AlipayCircleOutlined, WechatOutlined } from '@ant-design/icons';
import { AlipayCircleOutlined } from '@ant-design/icons';
import { logger } from '../../utils/logger'; import { logger } from '../../utils/logger';
import { useAuth } from '../../contexts/AuthContext'; import { useAuth } from '../../contexts/AuthContext';
@@ -825,11 +824,11 @@ export default function SubscriptionContentNew() {
const getIconComponent = (iconName: string) => { const getIconComponent = (iconName: string) => {
const icons: any = { const icons: any = {
star: FaStar, star: Star,
gem: FaGem, gem: Gem,
crown: FaCrown, crown: Crown,
}; };
return icons[iconName] || FaStar; return icons[iconName] || Star;
}; };
// 获取按钮文字 // 获取按钮文字
@@ -967,7 +966,7 @@ export default function SubscriptionContentNew() {
<HStack justify="space-between" align="center"> <HStack justify="space-between" align="center">
<HStack spacing={3}> <HStack spacing={3}>
<Icon <Icon
as={user.subscription_type === 'max' ? FaCrown : FaGem} as={user.subscription_type === 'max' ? Crown : Gem}
color="#D4AF37" color="#D4AF37"
boxSize={6} boxSize={6}
/> />
@@ -1003,7 +1002,7 @@ export default function SubscriptionContentNew() {
<Flex justify="space-between" align="center"> <Flex justify="space-between" align="center">
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaClock} color="rgba(212, 175, 55, 0.8)" boxSize={4} /> <Icon as={Clock} color="rgba(212, 175, 55, 0.8)" boxSize={4} />
<Text color="rgba(255, 255, 255, 0.7)" fontSize="sm"> <Text color="rgba(255, 255, 255, 0.7)" fontSize="sm">
</Text> </Text>
@@ -1065,7 +1064,7 @@ export default function SubscriptionContentNew() {
if (currentOption && currentOption.discountPercent > 0) { if (currentOption && currentOption.discountPercent > 0) {
return ( return (
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaStar} color="#D4AF37" boxSize={4} /> <Icon as={Star} color="#D4AF37" boxSize={4} />
<Text fontSize="sm" color="#D4AF37" fontWeight="medium"> <Text fontSize="sm" color="#D4AF37" fontWeight="medium">
{currentOption.discountPercent}% {currentOption.discountPercent}%
</Text> </Text>
@@ -1285,7 +1284,7 @@ export default function SubscriptionContentNew() {
} }
> >
<Icon <Icon
as={feature.enabled ? FaCheck : FaTimes} as={feature.enabled ? Check : X}
color={feature.enabled ? '#000' : 'rgba(255, 255, 255, 0.3)'} color={feature.enabled ? '#000' : 'rgba(255, 255, 255, 0.3)'}
boxSize={3} boxSize={3}
/> />
@@ -1360,7 +1359,7 @@ export default function SubscriptionContentNew() {
{faq.question} {faq.question}
</Text> </Text>
<Icon <Icon
as={openFaqIndex === index ? FaChevronUp : FaChevronDown} as={openFaqIndex === index ? ChevronUp : ChevronDown}
color="#D4AF37" color="#D4AF37"
boxSize={5} boxSize={5}
/> />
@@ -1423,7 +1422,7 @@ export default function SubscriptionContentNew() {
transition="all 0.2s" transition="all 0.2s"
> >
<HStack spacing={3}> <HStack spacing={3}>
<Icon as={FaWeixin} color="#07C160" boxSize={6} /> <WechatOutlined style={{ fontSize: '24px', color: '#07C160' }} />
<Text color="white" fontWeight="medium"></Text> <Text color="white" fontWeight="medium"></Text>
</HStack> </HStack>
</Button> </Button>
@@ -1460,7 +1459,7 @@ export default function SubscriptionContentNew() {
border="1px solid rgba(76, 175, 80, 0.3)" border="1px solid rgba(76, 175, 80, 0.3)"
> >
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaCheck} color="green.400" /> <Icon as={Check} color="green.400" />
<Text color="green.400" fontSize="sm" fontWeight="medium"> <Text color="green.400" fontSize="sm" fontWeight="medium">
{priceInfo.final_amount === 0 {priceInfo.final_amount === 0
? `恭喜!您的当前订阅剩余价值足够直接升级到${selectedPlan.displayName},无需支付额外费用!` ? `恭喜!您的当前订阅剩余价值足够直接升级到${selectedPlan.displayName},无需支付额外费用!`
@@ -1477,7 +1476,7 @@ export default function SubscriptionContentNew() {
border="1px solid rgba(255, 165, 0, 0.3)" border="1px solid rgba(255, 165, 0, 0.3)"
> >
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaClock} color="orange.400" /> <Icon as={Clock} color="orange.400" />
<Text color="orange.400" fontSize="sm" fontWeight="medium"> <Text color="orange.400" fontSize="sm" fontWeight="medium">
{priceInfo.current_plan?.toUpperCase()}{selectedPlan.displayName} {priceInfo.current_plan?.toUpperCase()}{selectedPlan.displayName}
</Text> </Text>
@@ -1492,7 +1491,7 @@ export default function SubscriptionContentNew() {
border="1px solid rgba(33, 150, 243, 0.3)" border="1px solid rgba(33, 150, 243, 0.3)"
> >
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaRedo} color="blue.400" /> <Icon as={RefreshCw} color="blue.400" />
<Text color="blue.400" fontSize="sm" fontWeight="medium"> <Text color="blue.400" fontSize="sm" fontWeight="medium">
{selectedPlan.displayName} {selectedPlan.displayName}
</Text> </Text>
@@ -1536,7 +1535,7 @@ export default function SubscriptionContentNew() {
{promoCodeApplied && priceInfo.discount_amount > 0 && ( {promoCodeApplied && priceInfo.discount_amount > 0 && (
<Flex justify="space-between" align="center"> <Flex justify="space-between" align="center">
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaCheck} color="green.400" boxSize={3} /> <Icon as={Check} color="green.400" boxSize={3} />
<Text color="rgba(255, 255, 255, 0.7)" fontSize="sm"> <Text color="rgba(255, 255, 255, 0.7)" fontSize="sm">
</Text> </Text>
@@ -1606,12 +1605,12 @@ export default function SubscriptionContentNew() {
borderRadius="md" borderRadius="md"
border="1px solid rgba(72, 187, 120, 0.3)" border="1px solid rgba(72, 187, 120, 0.3)"
> >
<Icon as={FaCheck} color="green.400" /> <Icon as={Check} color="green.400" />
<Text color="green.400" fontSize="sm" fontWeight="medium" flex={1}> <Text color="green.400" fontSize="sm" fontWeight="medium" flex={1}>
¥{priceInfo.discount_amount.toFixed(2)} ¥{priceInfo.discount_amount.toFixed(2)}
</Text> </Text>
<Icon <Icon
as={FaTimes} as={X}
color="rgba(255, 255, 255, 0.5)" color="rgba(255, 255, 255, 0.5)"
cursor="pointer" cursor="pointer"
onClick={handleRemovePromoCode} onClick={handleRemovePromoCode}
@@ -1672,7 +1671,7 @@ export default function SubscriptionContentNew() {
isDisabled={!selectedPlan} isDisabled={!selectedPlan}
leftIcon={paymentMethod === 'alipay' leftIcon={paymentMethod === 'alipay'
? <Box as={AlipayCircleOutlined} fontSize="20px" /> ? <Box as={AlipayCircleOutlined} fontSize="20px" />
: <Icon as={FaWeixin} boxSize={5} />} : <WechatOutlined style={{ fontSize: '20px' }} />}
_hover={{ _hover={{
bgGradient: paymentMethod === 'alipay' bgGradient: paymentMethod === 'alipay'
? 'linear-gradient(135deg, #4096ff, #1677FF)' ? 'linear-gradient(135deg, #4096ff, #1677FF)'
@@ -1770,7 +1769,7 @@ export default function SubscriptionContentNew() {
w="full" w="full"
> >
<HStack justify="center" spacing={2} mb={2}> <HStack justify="center" spacing={2} mb={2}>
<Icon as={FaClock} color="orange.400" /> <Icon as={Clock} color="orange.400" />
<Text color="orange.300" fontSize="sm"> <Text color="orange.300" fontSize="sm">
: {formatTime(paymentCountdown)} : {formatTime(paymentCountdown)}
</Text> </Text>
@@ -1810,7 +1809,7 @@ export default function SubscriptionContentNew() {
borderColor="rgba(255, 255, 255, 0.2)" borderColor="rgba(255, 255, 255, 0.2)"
borderRadius="lg" borderRadius="lg"
> >
<Icon as={FaQrcode} color="rgba(255, 255, 255, 0.3)" boxSize={12} /> <Icon as={QrCode} color="rgba(255, 255, 255, 0.3)" boxSize={12} />
</Flex> </Flex>
)} )}
</Box> </Box>
@@ -1845,7 +1844,7 @@ export default function SubscriptionContentNew() {
bgGradient="linear-gradient(135deg, #1677FF, #0958d9)" bgGradient="linear-gradient(135deg, #1677FF, #0958d9)"
color="white" color="white"
fontWeight="bold" fontWeight="bold"
leftIcon={<Icon as={FaExternalLinkAlt} />} leftIcon={<Icon as={ExternalLink} />}
onClick={handleReopenAlipay} onClick={handleReopenAlipay}
_hover={{ _hover={{
bgGradient: 'linear-gradient(135deg, #4096ff, #1677FF)', bgGradient: 'linear-gradient(135deg, #4096ff, #1677FF)',
@@ -1864,7 +1863,7 @@ export default function SubscriptionContentNew() {
bgGradient="linear-gradient(135deg, #D4AF37, #B8941F)" bgGradient="linear-gradient(135deg, #D4AF37, #B8941F)"
color="#000" color="#000"
fontWeight="bold" fontWeight="bold"
leftIcon={<Icon as={FaRedo} />} leftIcon={<Icon as={RefreshCw} />}
onClick={handleForceUpdate} onClick={handleForceUpdate}
isLoading={forceUpdating} isLoading={forceUpdating}
_hover={{ _hover={{

View File

@@ -12,7 +12,7 @@ import {
Text, Text,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FiStar } from 'react-icons/fi'; import { Star } from 'lucide-react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import SubscriptionContent from './SubscriptionContent'; import SubscriptionContent from './SubscriptionContent';
@@ -23,7 +23,7 @@ export default function SubscriptionModal({ isOpen, onClose }) {
<ModalContent maxH="90vh"> <ModalContent maxH="90vh">
<ModalHeader borderBottomWidth="1px" borderColor={useColorModeValue('gray.200', 'gray.600')}> <ModalHeader borderBottomWidth="1px" borderColor={useColorModeValue('gray.200', 'gray.600')}>
<HStack> <HStack>
<Icon as={FiStar} color="blue.500" boxSize={5} /> <Icon as={Star} color="blue.500" boxSize={5} />
<Text>订阅管理</Text> <Text>订阅管理</Text>
</HStack> </HStack>
</ModalHeader> </ModalHeader>

View File

@@ -9,7 +9,7 @@ import {
Text, Text,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaStar, FaCrown } from 'react-icons/fa'; import { Star, Crown } from 'lucide-react';
import { logger } from '../utils/logger'; import { logger } from '../utils/logger';
/** /**
@@ -23,13 +23,13 @@ const SubscriptionBadge = ({ tier = 'pro', size = 'sm' }) => {
const config = { const config = {
pro: { pro: {
label: 'PRO专享', label: 'PRO专享',
icon: FaStar, icon: Star,
bgGradient: 'linear(to-r, blue.400, purple.500)', bgGradient: 'linear(to-r, blue.400, purple.500)',
color: 'white', color: 'white',
}, },
max: { max: {
label: 'MAX专享', label: 'MAX专享',
icon: FaCrown, icon: Crown,
bgGradient: 'linear(to-r, pink.400, red.500)', bgGradient: 'linear(to-r, pink.400, red.500)',
color: 'white', color: 'white',
}, },

View File

@@ -17,7 +17,7 @@ import {
Icon, Icon,
Divider Divider
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaCrown, FaLock, FaStar, FaRocket } from 'react-icons/fa'; import { Crown, Lock, Star, Rocket } from 'lucide-react';
const SubscriptionUpgradeModal = ({ const SubscriptionUpgradeModal = ({
isOpen, isOpen,
@@ -34,19 +34,19 @@ const SubscriptionUpgradeModal = ({
const subscriptionLevels = { const subscriptionLevels = {
free: { free: {
name: '免费版', name: '免费版',
icon: FaLock, icon: Lock,
color: 'gray', color: 'gray',
features: ['基础事件浏览', '有限历史事件查看'] features: ['基础事件浏览', '有限历史事件查看']
}, },
pro: { pro: {
name: 'Pro版', name: 'Pro版',
icon: FaStar, icon: Star,
color: 'blue', color: 'blue',
features: ['相关标的分析', '相关概念分析', '完整历史事件'] features: ['相关标的分析', '相关概念分析', '完整历史事件']
}, },
max: { max: {
name: 'Max版', name: 'Max版',
icon: FaCrown, icon: Crown,
color: 'purple', color: 'purple',
features: ['传导链分析', '高级分析工具', '实时数据推送', '所有Pro版功能'] features: ['传导链分析', '高级分析工具', '实时数据推送', '所有Pro版功能']
} }
@@ -66,7 +66,7 @@ const SubscriptionUpgradeModal = ({
<ModalContent bg={bgColor}> <ModalContent bg={bgColor}>
<ModalHeader borderBottomWidth="1px" borderColor={borderColor}> <ModalHeader borderBottomWidth="1px" borderColor={borderColor}>
<HStack spacing={3}> <HStack spacing={3}>
<Icon as={FaLock} color="red.500" boxSize={6} /> <Icon as={Lock} color="red.500" boxSize={6} />
<VStack align="start" spacing={0}> <VStack align="start" spacing={0}>
<Text fontSize="lg" fontWeight="bold"> <Text fontSize="lg" fontWeight="bold">
需要{requiredLevelInfo.name}订阅 需要{requiredLevelInfo.name}订阅
@@ -138,13 +138,13 @@ const SubscriptionUpgradeModal = ({
</Box> </Box>
{/* 升级提示 */} {/* 升级提示 */}
<Box <Box
p={3} p={3}
bg={useColorModeValue('yellow.50', 'yellow.900')} bg={useColorModeValue('yellow.50', 'yellow.900')}
borderRadius="md" borderRadius="md"
> >
<HStack spacing={2}> <HStack spacing={2}>
<Icon as={FaRocket} color="yellow.600" /> <Icon as={Rocket} color="yellow.600" />
<Text fontSize="sm" color={useColorModeValue('yellow.800', 'yellow.200')}> <Text fontSize="sm" color={useColorModeValue('yellow.800', 'yellow.200')}>
升级到{requiredLevelInfo.name}即可解锁此功能 升级到{requiredLevelInfo.name}即可解锁此功能
</Text> </Text>
@@ -158,9 +158,9 @@ const SubscriptionUpgradeModal = ({
<Button variant="outline" onClick={onClose}> <Button variant="outline" onClick={onClose}>
稍后再说 稍后再说
</Button> </Button>
<Button <Button
colorScheme={requiredLevelInfo.color} colorScheme={requiredLevelInfo.color}
leftIcon={<Icon as={FaCrown} />} leftIcon={<Icon as={Crown} />}
onClick={handleUpgrade} onClick={handleUpgrade}
> >
立即升级 立即升级

View File

@@ -3,7 +3,7 @@
*/ */
import type { ComponentType, ReactNode } from 'react'; import type { ComponentType, ReactNode } from 'react';
import type { IconType } from 'react-icons'; import type { LucideIcon } from 'lucide-react';
/** /**
* Tab 配置项 * Tab 配置项
@@ -14,7 +14,7 @@ export interface TabConfig {
/** Tab 显示名称 */ /** Tab 显示名称 */
name: string; name: string;
/** Tab 图标(可选) */ /** Tab 图标(可选) */
icon?: IconType | ComponentType; icon?: LucideIcon | ComponentType;
/** Tab 内容组件(可选,如果不传则使用 children 渲染) */ /** Tab 内容组件(可选,如果不传则使用 children 渲染) */
component?: ComponentType<any>; component?: ComponentType<any>;
} }

View File

@@ -35,12 +35,7 @@ import {
Tr, Tr,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { GrFormNext, GrFormPrevious } from "react-icons/gr"; import { ChevronRight, ChevronLeft, ChevronDown, ChevronUp, ChevronsUpDown } from "lucide-react";
import {
TiArrowSortedDown,
TiArrowSortedUp,
TiArrowUnsorted,
} from "react-icons/ti";
import { usePagination, useSortBy, useTable } from "react-table"; import { usePagination, useSortBy, useTable } from "react-table";
function BasicTable(props) { function BasicTable(props) {
@@ -142,9 +137,9 @@ function BasicTable(props) {
as={ as={
column.isSorted column.isSorted
? column.isSortedDesc ? column.isSortedDesc
? TiArrowSortedDown ? ChevronDown
: TiArrowSortedUp : ChevronUp
: TiArrowUnsorted : ChevronsUpDown
} }
/> />
</Flex> </Flex>
@@ -211,7 +206,7 @@ function BasicTable(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormPrevious} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronLeft} w="16px" h="16px" color="gray.400" />
</Button> </Button>
{pageSize === 5 ? ( {pageSize === 5 ? (
<NumberInput <NumberInput
@@ -276,7 +271,7 @@ function BasicTable(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormNext} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronRight} w="16px" h="16px" color="gray.400" />
</Button> </Button>
</Stack> </Stack>
</Flex> </Flex>

View File

@@ -24,7 +24,7 @@ import {
useColorModeValue, useColorModeValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React from "react"; import React from "react";
import { FaPencilAlt, FaTrashAlt } from "react-icons/fa"; import { Pencil, Trash2 } from "lucide-react";
function BillingRow(props) { function BillingRow(props) {
const textColor = useColorModeValue("gray.700", "white"); const textColor = useColorModeValue("gray.700", "white");
@@ -70,7 +70,7 @@ function BillingRow(props) {
me={{ md: "12px" }} me={{ md: "12px" }}
> >
<Flex color="red.500" cursor="pointer" align="center" p="12px"> <Flex color="red.500" cursor="pointer" align="center" p="12px">
<Icon as={FaTrashAlt} me="4px" /> <Icon as={Trash2} me="4px" />
<Text fontSize="sm" fontWeight="semibold"> <Text fontSize="sm" fontWeight="semibold">
DELETE DELETE
</Text> </Text>
@@ -78,7 +78,7 @@ function BillingRow(props) {
</Button> </Button>
<Button p="0px" variant="no-effects"> <Button p="0px" variant="no-effects">
<Flex color={textColor} cursor="pointer" align="center" p="12px"> <Flex color={textColor} cursor="pointer" align="center" p="12px">
<Icon as={FaPencilAlt} me="4px" /> <Icon as={Pencil} me="4px" />
<Text fontSize="sm" fontWeight="semibold"> <Text fontSize="sm" fontWeight="semibold">
EDIT EDIT
</Text> </Text>

View File

@@ -36,12 +36,7 @@ import {
Tr, Tr,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { GrFormNext, GrFormPrevious } from "react-icons/gr"; import { ChevronRight, ChevronLeft, ChevronDown, ChevronUp, ChevronsUpDown } from "lucide-react";
import {
TiArrowSortedDown,
TiArrowSortedUp,
TiArrowUnsorted,
} from "react-icons/ti";
import { import {
useGlobalFilter, useGlobalFilter,
usePagination, usePagination,
@@ -165,9 +160,9 @@ function SearchTable1(props) {
as={ as={
column.isSorted column.isSorted
? column.isSortedDesc ? column.isSortedDesc
? TiArrowSortedDown ? ChevronDown
: TiArrowSortedUp : ChevronUp
: TiArrowUnsorted : ChevronsUpDown
} }
/> />
</Flex> </Flex>
@@ -235,7 +230,7 @@ function SearchTable1(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormPrevious} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronLeft} w="16px" h="16px" color="gray.400" />
</Button> </Button>
{pageSize === 5 ? ( {pageSize === 5 ? (
<NumberInput <NumberInput
@@ -300,7 +295,7 @@ function SearchTable1(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormNext} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronRight} w="16px" h="16px" color="gray.400" />
</Button> </Button>
</Stack> </Stack>
</Flex> </Flex>

View File

@@ -40,15 +40,7 @@ import {
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { SearchBar } from "components/Navbars/SearchBar/SearchBar"; import { SearchBar } from "components/Navbars/SearchBar/SearchBar";
import { MdReplay, MdCheck } from "react-icons/md"; import { RotateCcw, Check, X, CheckCircle, XCircle, Undo2, ChevronRight, ChevronLeft, ChevronDown, ChevronUp, ChevronsUpDown } from "lucide-react";
import { IoMdClose } from "react-icons/io";
import { FaCheckCircle, FaTimesCircle, FaUndoAlt } from "react-icons/fa";
import { GrFormNext, GrFormPrevious } from "react-icons/gr";
import {
TiArrowSortedDown,
TiArrowSortedUp,
TiArrowUnsorted,
} from "react-icons/ti";
import { import {
useGlobalFilter, useGlobalFilter,
usePagination, usePagination,
@@ -145,9 +137,9 @@ function SearchTable2(props) {
as={ as={
column.isSorted column.isSorted
? column.isSortedDesc ? column.isSortedDesc
? TiArrowSortedDown ? ChevronDown
: TiArrowSortedUp : ChevronUp
: TiArrowUnsorted : ChevronsUpDown
} }
/> />
</Flex> </Flex>
@@ -185,10 +177,10 @@ function SearchTable2(props) {
<Icon <Icon
as={ as={
cell.value === "Paid" cell.value === "Paid"
? MdCheck ? Check
: cell.value === "Refunded" : cell.value === "Refunded"
? MdReplay ? RotateCcw
: IoMdClose : X
} }
color={ color={
cell.value === "Paid" cell.value === "Paid"
@@ -283,7 +275,7 @@ function SearchTable2(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormPrevious} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronLeft} w="16px" h="16px" color="gray.400" />
</Button> </Button>
{pageSize === 5 ? ( {pageSize === 5 ? (
<NumberInput <NumberInput
@@ -348,7 +340,7 @@ function SearchTable2(props) {
borderColor: "gray.500", borderColor: "gray.500",
}} }}
> >
<Icon as={GrFormNext} w="16px" h="16px" color="gray.400" /> <Icon as={ChevronRight} w="16px" h="16px" color="gray.400" />
</Button> </Button>
</Stack> </Stack>
</Flex> </Flex>

View File

@@ -26,7 +26,7 @@ import {
useColorModeValue, useColorModeValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React from "react"; import React from "react";
import { FaEllipsisV } from "react-icons/fa"; import { MoreVertical } from "lucide-react";
function DashboardTableRow(props) { function DashboardTableRow(props) {
const { logo, name, status, budget, progression } = props; const { logo, name, status, budget, progression } = props;
@@ -74,7 +74,7 @@ function DashboardTableRow(props) {
</Td> </Td>
<Td> <Td>
<Button p="0px" bg="transparent"> <Button p="0px" bg="transparent">
<Icon as={FaEllipsisV} color="gray.400" cursor="pointer" /> <Icon as={MoreVertical} color="gray.400" cursor="pointer" />
</Button> </Button>
</Td> </Td>
</Tr> </Tr>

View File

@@ -25,7 +25,7 @@ import {
useColorModeValue, useColorModeValue,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import React from "react"; import React from "react";
import { BsCircleFill } from "react-icons/bs"; import { Circle } from "lucide-react";
function TablesReportsRow(props) { function TablesReportsRow(props) {
const { const {
@@ -99,9 +99,10 @@ function TablesReportsRow(props) {
> >
<Flex align="center"> <Flex align="center">
<Icon <Icon
as={BsCircleFill} as={Circle}
w="8px" w="8px"
h="8px" h="8px"
fill="currentColor"
color={ color={
review === "Positive" review === "Positive"
? "teal.300" ? "teal.300"

View File

@@ -7,8 +7,7 @@ import {
Tooltip, Tooltip,
useColorModeValue, useColorModeValue,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons'; import { Info, Calendar } from 'lucide-react';
import { FaCalendarAlt } from 'react-icons/fa';
export interface TradeDatePickerProps { export interface TradeDatePickerProps {
/** 当前选中的日期 */ /** 当前选中的日期 */
@@ -117,7 +116,7 @@ const TradeDatePicker: React.FC<TradeDatePickerProps> = ({
<> <>
{/* 标签 */} {/* 标签 */}
<HStack spacing={3}> <HStack spacing={3}>
{showIcon && <Icon as={FaCalendarAlt} color={iconColor} boxSize={5} />} {showIcon && <Icon as={Calendar} color={iconColor} boxSize={5} />}
<Text fontWeight="bold" color={labelColor}> <Text fontWeight="bold" color={labelColor}>
{label} {label}
</Text> </Text>
@@ -157,7 +156,7 @@ const TradeDatePicker: React.FC<TradeDatePickerProps> = ({
_hover={{ opacity: 1 }} _hover={{ opacity: 1 }}
transition="opacity 0.2s" transition="opacity 0.2s"
> >
<Icon as={InfoIcon} color={tipIconColor} boxSize={3} /> <Info size={12} color="var(--chakra-colors-blue-300)" style={{ display: 'inline-block' }} />
<Text fontSize="xs" color={tipTextColor}> <Text fontSize="xs" color={tipTextColor}>
{latestTradeDate.toLocaleDateString('zh-CN')} {latestTradeDate.toLocaleDateString('zh-CN')}
</Text> </Text>