Merge branch 'feature_bugfix/251217_stock' of https://git.valuefrontier.cn/vf/vf_react into feature_bugfix/251217_stock

This commit is contained in:
2025-12-25 13:16:01 +08:00
403 changed files with 1701 additions and 147570 deletions

View File

@@ -32,7 +32,6 @@ import {
// Assets
import BasicImage from "assets/img/BasicImage.png";
import React from "react";
import { FaApple, FaFacebook, FaGoogle } from "react-icons/fa";
import AuthBasic from "layouts/AuthBasic";
function LockBasic() {

View File

@@ -30,7 +30,7 @@ import BasicImage from "assets/img/BasicImage.png";
import React from "react";
import AuthBasic from "layouts/AuthBasic";
import { PinInputLight } from "components/PinInput/PinInput";
import { IoIosRocket } from "react-icons/io";
import { Rocket } from "lucide-react";
function LockBasic() {
// Chakra color mode
@@ -75,7 +75,7 @@ function LockBasic() {
align="center"
mb="30px"
>
<Icon as={IoIosRocket} color="white" w="36px" h="36px" />
<Icon as={Rocket} color="white" w="36px" h="36px" />
</Flex>
<Text
fontWeight="bold"

View File

@@ -27,7 +27,7 @@ import {
} from "@chakra-ui/react";
// Assets
import { PinInputLight } from "components/PinInput/PinInput";
import { IoIosRocket } from "react-icons/io";
import { Rocket } from "lucide-react";
import CoverImage from "assets/img/CoverImage.png";
import React from "react";
import AuthCover from "layouts/AuthCover";
@@ -64,7 +64,7 @@ function LockCover() {
align="center"
mb="30px"
>
<Icon as={IoIosRocket} color="white" w="36px" h="36px" />
<Icon as={Rocket} color="white" w="36px" h="36px" />
</Flex>
<Text
fontWeight="bold"

View File

@@ -13,7 +13,7 @@ import {
import illustration from "assets/img/illustration-auth.png";
import AuthIllustration from "layouts/AuthIllustration";
import { PinInputDark } from "components/PinInput/PinInput";
import { IoIosRocket } from "react-icons/io";
import { Rocket } from "lucide-react";
function LockIllustration() {
// Chakra color mode
@@ -51,7 +51,7 @@ function LockIllustration() {
justify='center'
align='center'
mb='30px'>
<Icon as={IoIosRocket} color='white' w='36px' h='36px' />
<Icon as={Rocket} color='white' w='36px' h='36px' />
</Flex>
<Text
fontWeight='bold'

View File

@@ -30,14 +30,14 @@ import {
useColorModeValue,
} from '@chakra-ui/react';
import {
FiEdit2,
FiTrash2,
FiFileText,
FiCalendar,
FiTrendingUp,
FiChevronDown,
FiChevronUp,
} from 'react-icons/fi';
Pencil,
Trash2,
FileText,
Calendar,
TrendingUp,
ChevronDown,
ChevronUp,
} from 'lucide-react';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
@@ -191,7 +191,7 @@ export const EventCard = memo<EventCardProps>(({
<VStack align="start" spacing={1} flex={1}>
{/* 标题行 */}
<HStack spacing={{ base: 1, md: 2 }} flexWrap="wrap">
<Icon as={FiFileText} color={`${colorScheme}.500`} boxSize={{ base: 4, md: 5 }} />
<Icon as={FileText} color={`${colorScheme}.500`} boxSize={{ base: 4, md: 5 }} />
<Text fontWeight="bold" fontSize={{ base: 'md', md: 'lg' }}>
{event.title}
</Text>
@@ -206,7 +206,7 @@ export const EventCard = memo<EventCardProps>(({
{/* list 模式显示日期 */}
{isListMode && (
<HStack spacing={{ base: 1, md: 2 }} flexWrap="wrap">
<Icon as={FiCalendar} boxSize={{ base: 2.5, md: 3 }} color={finalSecondaryText} />
<Icon as={Calendar} boxSize={{ base: 2.5, md: 3 }} color={finalSecondaryText} />
<Text fontSize={{ base: 'xs', md: 'sm' }} color={finalSecondaryText}>
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
</Text>
@@ -219,7 +219,7 @@ export const EventCard = memo<EventCardProps>(({
<HStack spacing={{ base: 0, md: 1 }}>
{onEdit && (
<IconButton
icon={<FiEdit2 />}
icon={<Pencil />}
size="sm"
variant="ghost"
onClick={() => onEdit(event)}
@@ -228,7 +228,7 @@ export const EventCard = memo<EventCardProps>(({
)}
{onDelete && (
<IconButton
icon={<FiTrash2 />}
icon={<Trash2 />}
size="sm"
variant="ghost"
colorScheme="red"
@@ -258,7 +258,7 @@ export const EventCard = memo<EventCardProps>(({
variant="ghost"
colorScheme={colorScheme}
mt={1}
rightIcon={isExpanded ? <FiChevronUp /> : <FiChevronDown />}
rightIcon={isExpanded ? <ChevronUp /> : <ChevronDown />}
onClick={() => setIsExpanded(!isExpanded)}
>
{isExpanded ? '收起' : '展开'}
@@ -280,7 +280,7 @@ export const EventCard = memo<EventCardProps>(({
const displayText = typeof stock === 'string' ? stock : `${stock.name}(${stock.code})`;
return (
<Tag key={stockCode || idx} size="sm" colorScheme="blue" variant="subtle">
<TagLeftIcon as={FiTrendingUp} />
<TagLeftIcon as={TrendingUp} />
<TagLabel>{displayText}</TagLabel>
</Tag>
);

View File

@@ -19,7 +19,7 @@ import {
Icon,
useToast,
} from '@chakra-ui/react';
import { FiFileText } from 'react-icons/fi';
import { FileText } from 'lucide-react';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import {
@@ -165,7 +165,7 @@ export const EventPanel: React.FC<EventPanelProps> = ({
) : events.length === 0 ? (
<Center py={{ base: 6, md: 8 }}>
<VStack spacing={{ base: 2, md: 3 }}>
<Icon as={FiFileText} boxSize={{ base: 8, md: 12 }} color="gray.300" />
<Icon as={FileText} boxSize={{ base: 8, md: 12 }} color="gray.300" />
<Text color={secondaryText} fontSize={{ base: 'sm', md: 'md' }}>{label}</Text>
</VStack>
</Center>

View File

@@ -21,14 +21,16 @@ import {
Button,
} from '@chakra-ui/react';
import {
FiEdit2,
FiTrash2,
FiCalendar,
FiTrendingUp,
FiChevronDown,
FiChevronUp,
} from 'react-icons/fi';
import { FileText, Heart, Target } from 'lucide-react';
Pencil,
Trash2,
Calendar,
TrendingUp,
ChevronDown,
ChevronUp,
FileText,
Heart,
Target,
} from 'lucide-react';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
@@ -170,7 +172,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
<HStack spacing={0}>
{onEdit && (
<IconButton
icon={<FiEdit2 size={14} />}
icon={<Pencil size={14} />}
size="xs"
variant="ghost"
color={FUI_THEME.text.secondary}
@@ -181,7 +183,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
)}
{onDelete && (
<IconButton
icon={<FiTrash2 size={14} />}
icon={<Trash2 size={14} />}
size="xs"
variant="ghost"
color={FUI_THEME.text.secondary}
@@ -197,7 +199,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
{/* 日期行 */}
<HStack spacing={2}>
<FiCalendar size={12} color={FUI_THEME.text.muted} />
<Calendar size={12} color={FUI_THEME.text.muted} />
<Text fontSize="xs" color={FUI_THEME.text.secondary}>
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
</Text>
@@ -243,7 +245,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
mt={1}
ml={4}
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
rightIcon={isExpanded ? <FiChevronUp /> : <FiChevronDown />}
rightIcon={isExpanded ? <ChevronUp /> : <ChevronDown />}
onClick={() => setIsExpanded(!isExpanded)}
>
{isExpanded ? '收起' : '展开'}
@@ -270,7 +272,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
border="1px solid"
borderColor="rgba(212, 175, 55, 0.2)"
>
<TagLeftIcon as={FiTrendingUp} boxSize={3} />
<TagLeftIcon as={TrendingUp} boxSize={3} />
<TagLabel fontSize="xs">{displayText}</TagLabel>
</Tag>
);

View File

@@ -3,8 +3,8 @@
* 黑金色主题,展示平台核心功能快捷入口
*/
import React, { useCallback } from 'react';
import { Box, SimpleGrid, HStack, Text, Icon } from '@chakra-ui/react';
import { CheckCircleIcon } from '@chakra-ui/icons';
import { Box, SimpleGrid, HStack, Text } from '@chakra-ui/react';
import { CheckCircle } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import GlassCard from '@components/GlassCard';
import { CORE_FEATURES } from '@/constants/homeFeatures';
@@ -35,10 +35,10 @@ const FeatureEntryPanel: React.FC = () => {
>
{/* 标题栏 - 参考投资仪表盘样式 */}
<HStack mb={4} spacing={2}>
<Icon
as={CheckCircleIcon}
boxSize={5}
<CheckCircle
size={20}
color="rgba(72, 187, 120, 0.9)"
style={{ display: 'inline-block' }}
/>
<Text
fontSize="lg"

View File

@@ -28,12 +28,12 @@ import {
ButtonGroup,
} from '@chakra-ui/react';
import {
FiCalendar,
FiFileText,
FiList,
FiPlus,
} from 'react-icons/fi';
import { Target } from 'lucide-react';
Calendar,
FileText,
List,
Plus,
Target,
} from 'lucide-react';
import GlassCard from '@components/GlassCard';
import { PlanningDataProvider } from './PlanningContext';
@@ -148,7 +148,7 @@ const InvestmentPlanningCenter: React.FC = () => {
{/* 视图切换按钮组 - H5隐藏 */}
<ButtonGroup size="sm" isAttached display={{ base: 'none', md: 'flex' }}>
<Button
leftIcon={<Icon as={FiList} boxSize={4} />}
leftIcon={<Icon as={List} boxSize={4} />}
bg={viewMode === 'list' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
color={viewMode === 'list' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
border="1px solid"
@@ -159,7 +159,7 @@ const InvestmentPlanningCenter: React.FC = () => {
</Button>
<Button
leftIcon={<Icon as={FiCalendar} boxSize={4} />}
leftIcon={<Icon as={Calendar} boxSize={4} />}
bg={viewMode === 'calendar' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
color={viewMode === 'calendar' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
border="1px solid"
@@ -223,7 +223,7 @@ const InvestmentPlanningCenter: React.FC = () => {
borderColor: goldAccent,
}}
>
<Icon as={FiFileText} mr={1} boxSize={{ base: 3, md: 4 }} />
<Icon as={FileText} mr={1} boxSize={{ base: 3, md: 4 }} />
({reviews.length})
</Tab>
</TabList>
@@ -233,7 +233,7 @@ const InvestmentPlanningCenter: React.FC = () => {
color={goldAccent}
border="1px solid"
borderColor="rgba(212, 175, 55, 0.3)"
leftIcon={<Icon as={FiPlus} boxSize={3} />}
leftIcon={<Icon as={Plus} boxSize={3} />}
fontSize={{ base: '11px', md: 'sm' }}
flexShrink={0}
_hover={{ bg: 'rgba(212, 175, 55, 0.3)' }}

View File

@@ -21,12 +21,12 @@ import {
} from '@chakra-ui/react';
import { Link } from 'react-router-dom';
import {
FiCalendar,
FiClock,
FiStar,
FiTrendingUp,
FiAlertCircle,
} from 'react-icons/fi';
Calendar,
Clock,
Star,
TrendingUp,
AlertCircle,
} from 'lucide-react';
import { eventService } from '../../../services/eventService';
import { logger } from '../../../utils/logger';
import dayjs from 'dayjs';
@@ -153,7 +153,7 @@ export default function MyFutureEvents({ limit = 5 }) {
return (
<Center py={8}>
<VStack spacing={3}>
<Icon as={FiCalendar} boxSize={12} color="gray.300" />
<Icon as={Calendar} boxSize={12} color="gray.300" />
<Text color={secondaryText} fontSize="sm">
暂无关注的未来事件
</Text>
@@ -214,7 +214,7 @@ export default function MyFutureEvents({ limit = 5 }) {
<HStack spacing={3}>
<Badge colorScheme={timeInfo.color} variant="subtle">
<HStack spacing={1}>
<Icon as={FiClock} boxSize={3} />
<Icon as={Clock} boxSize={3} />
<Text>{timeInfo.date}</Text>
</HStack>
</Badge>
@@ -228,7 +228,7 @@ export default function MyFutureEvents({ limit = 5 }) {
{[...Array(5)].map((_, i) => (
<Icon
key={i}
as={FiStar}
as={Star}
boxSize={3}
color={i < event.star ? importanceColor : 'gray.300'}
fill={i < event.star ? 'currentColor' : 'none'}
@@ -247,7 +247,7 @@ export default function MyFutureEvents({ limit = 5 }) {
)}
{event.related_stocks && event.related_stocks.length > 0 && (
<Tag size="sm" variant="subtle" colorScheme="purple">
<Icon as={FiTrendingUp} boxSize={3} mr={1} />
<Icon as={TrendingUp} boxSize={3} mr={1} />
<TagLabel>{event.related_stocks.length}只相关股票</TagLabel>
</Tag>
)}
@@ -271,7 +271,7 @@ export default function MyFutureEvents({ limit = 5 }) {
{event.forecast && (
<Box>
<HStack spacing={1} mb={1}>
<Icon as={FiAlertCircle} boxSize={3} color={secondaryText} />
<Icon as={AlertCircle} boxSize={3} color={secondaryText} />
<Text fontSize="xs" color={secondaryText}>
预测
</Text>

View File

@@ -23,7 +23,7 @@ import {
Tooltip,
Icon,
} from '@chakra-ui/react';
import { TimeIcon, BellIcon } from '@chakra-ui/icons';
import { Clock, Bell } from 'lucide-react';
import { useNotification } from '@contexts/NotificationContext';
import EventScrollList from './EventScrollList';
import ModeToggleButtons from './ModeToggleButtons';
@@ -565,7 +565,7 @@ const [currentMode, setCurrentMode] = useState('vertical');
<HStack spacing={4}>
<Heading size={isMobile ? "sm" : "md"} color={PROFESSIONAL_COLORS.text.primary}>
<HStack spacing={2}>
<TimeIcon color={PROFESSIONAL_COLORS.gold[500]} />
<Clock size={20} color={PROFESSIONAL_COLORS.gold[500]} />
<Text bgGradient={PROFESSIONAL_COLORS.gradients.gold} bgClip="text">实时要闻·动态追踪</Text>
</HStack>
</Heading>
@@ -584,9 +584,8 @@ const [currentMode, setCurrentMode] = useState('vertical');
_hover={{ opacity: 0.8 }}
transition="opacity 0.2s"
>
<Icon
as={BellIcon}
boxSize={3.5}
<Bell
size={14}
color={PROFESSIONAL_COLORS.gold[500]}
/>
<Text

View File

@@ -12,10 +12,7 @@ import {
useColorModeValue,
useToast,
} from '@chakra-ui/react';
import {
ChevronLeftIcon,
ChevronRightIcon,
} from '@chakra-ui/icons';
import { ChevronLeft, ChevronRight } from 'lucide-react';
/**
* 分页控制器组件(使用 React.memo 优化,避免不必要的重新渲染)
@@ -116,7 +113,7 @@ const PaginationControl = React.memo(({ currentPage, totalPages, onPageChange })
<HStack spacing={1.5} justify="center" flexWrap="wrap">
{/* 上一页按钮 */}
<IconButton
icon={<ChevronLeftIcon />}
icon={<ChevronLeft size={14} />}
size="xs"
onClick={() => onPageChange(currentPage - 1)}
isDisabled={currentPage === 1}
@@ -164,7 +161,7 @@ const PaginationControl = React.memo(({ currentPage, totalPages, onPageChange })
{/* 下一页按钮 */}
<IconButton
icon={<ChevronRightIcon />}
icon={<ChevronRight size={14} />}
size="xs"
onClick={() => onPageChange(currentPage + 1)}
isDisabled={currentPage === totalPages}

View File

@@ -23,8 +23,7 @@ import {
Tooltip,
Button,
} from "@chakra-ui/react";
import { ChevronDownIcon, ChevronUpIcon, RepeatIcon } from "@chakra-ui/icons";
import { FiTrendingUp, FiZap } from "react-icons/fi";
import { ChevronDown, ChevronUp, RefreshCw, TrendingUp, Zap } from "lucide-react";
import { FireOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import { Select } from "antd";
@@ -363,7 +362,7 @@ const MainlineCard = React.memo(
)}
</VStack>
<Icon
as={isExpanded ? ChevronUpIcon : ChevronDownIcon}
as={isExpanded ? ChevronUp : ChevronDown}
boxSize={4}
color={COLORS.secondaryTextColor}
ml={2}
@@ -744,7 +743,7 @@ const MainlineTimelineViewComponent = forwardRef(
<VStack spacing={4}>
<Text color="red.500">加载失败: {error}</Text>
<IconButton
icon={<RepeatIcon />}
icon={<RefreshCw size={16} />}
colorScheme="blue"
onClick={fetchMainlineData}
aria-label="重试"
@@ -761,7 +760,7 @@ const MainlineTimelineViewComponent = forwardRef(
<Box display={display} p={8} bg={COLORS.containerBg} minH="400px">
<Center h="400px">
<VStack spacing={4}>
<Icon as={FiZap} boxSize={12} color="gray.400" />
<Icon as={Zap} boxSize={12} color="gray.400" />
<Text color={COLORS.secondaryTextColor}>暂无主线数据</Text>
<Text fontSize="sm" color={COLORS.secondaryTextColor}>
尝试调整筛选条件
@@ -801,7 +800,7 @@ const MainlineTimelineViewComponent = forwardRef(
>
<HStack spacing={4}>
<HStack spacing={2}>
<Icon as={FiTrendingUp} color="blue.400" />
<Icon as={TrendingUp} color="blue.400" />
<Text fontWeight="bold" color={COLORS.textColor} fontSize="sm">
{mainline_count} 条主线
</Text>
@@ -900,7 +899,7 @@ const MainlineTimelineViewComponent = forwardRef(
/>
<Tooltip label="全部展开">
<IconButton
icon={<ChevronDownIcon />}
icon={<ChevronDown size={16} />}
size="sm"
variant="ghost"
color={COLORS.secondaryTextColor}
@@ -911,7 +910,7 @@ const MainlineTimelineViewComponent = forwardRef(
</Tooltip>
<Tooltip label="全部折叠">
<IconButton
icon={<ChevronUpIcon />}
icon={<ChevronUp size={16} />}
size="sm"
variant="ghost"
color={COLORS.secondaryTextColor}
@@ -922,7 +921,7 @@ const MainlineTimelineViewComponent = forwardRef(
</Tooltip>
<Tooltip label="刷新">
<IconButton
icon={<RepeatIcon />}
icon={<RefreshCw size={16} />}
size="sm"
variant="ghost"
color={COLORS.secondaryTextColor}

View File

@@ -11,7 +11,7 @@ import {
useBreakpointValue,
useDisclosure
} from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
import { Info } from 'lucide-react';
import HorizontalDynamicNewsEventCard from '../../EventCard/HorizontalDynamicNewsEventCard';
import EventDetailScrollPanel from '../EventDetailScrollPanel';
import EventDetailModal from '../../EventDetailModal';
@@ -134,7 +134,7 @@ const VerticalModeLayout = React.memo(({
/* 空状态 */
<Center h="100%" minH="400px">
<VStack spacing={4}>
<InfoIcon w={12} h={12} color="gray.400" />
<Info size={48} color="gray.400" />
<Text fontSize="lg" color="gray.500" textAlign="center">
当前筛选条件下暂无数据
</Text>

View File

@@ -1,7 +1,7 @@
// src/views/Community/components/EventCard/atoms/EventFollowButton.js
import React from 'react';
import { IconButton, Box } from '@chakra-ui/react';
import { AiFillStar, AiOutlineStar } from 'react-icons/ai';
import { Star } from 'lucide-react';
/**
* 事件关注按钮组件
@@ -39,17 +39,11 @@ const EventFollowButton = ({
boxShadow: 'md'
}}
icon={
isFollowing ? (
<AiFillStar
size={iconSize}
color="gold"
/>
) : (
<AiOutlineStar
size={iconSize}
color="gold"
/>
)
<Star
size={iconSize}
color="gold"
fill={isFollowing ? "currentColor" : "none"}
/>
}
onClick={handleClick}
aria-label={isFollowing ? '取消关注' : '关注'}

View File

@@ -1,7 +1,7 @@
// src/views/Community/components/EventCard/atoms/EventImportanceBadge.js
import React from 'react';
import { Badge, Tooltip, VStack, HStack, Text, Divider, Circle } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
import { Info } from 'lucide-react';
import { getImportanceConfig, getAllImportanceLevels } from '@constants/importanceLevels';
/**
@@ -86,7 +86,7 @@ const EventImportanceBadge = ({
gap={1}
flexShrink={0}
>
{showIcon && <InfoIcon boxSize={2.5} />}
{showIcon && <Info size={10} />}
{importance || 'C'}
</Badge>
</Tooltip>

View File

@@ -1,7 +1,7 @@
// src/views/Community/components/EventCard/EventStats.js
import React from 'react';
import { HStack, Text, Tooltip } from '@chakra-ui/react';
import { ViewIcon, ChatIcon, StarIcon } from '@chakra-ui/icons';
import { Eye, MessageCircle, Star } from 'lucide-react';
/**
* 事件统计信息组件(浏览量、帖子数、关注数)
@@ -31,7 +31,7 @@ const EventStats = ({
{/* 浏览量 */}
<Tooltip label="浏览量" placement="top">
<HStack spacing={1}>
<ViewIcon boxSize={iconSize} />
<Eye size={iconSize === '12px' ? 12 : 16} />
<Text fontSize={fontSize}>{viewCount}</Text>
</HStack>
</Tooltip>
@@ -39,7 +39,7 @@ const EventStats = ({
{/* 帖子数 */}
<Tooltip label="帖子数" placement="top">
<HStack spacing={1}>
<ChatIcon boxSize={iconSize} />
<MessageCircle size={iconSize === '12px' ? 12 : 16} />
<Text fontSize={fontSize}>{postCount}</Text>
</HStack>
</Tooltip>
@@ -47,7 +47,7 @@ const EventStats = ({
{/* 关注数 */}
<Tooltip label="关注数" placement="top">
<HStack spacing={1}>
<StarIcon boxSize={iconSize} />
<Star size={iconSize === '12px' ? 12 : 16} />
<Text fontSize={fontSize}>{followerCount}</Text>
</HStack>
</Tooltip>

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { Box, Text, VStack, Icon } from '@chakra-ui/react';
import { FaChartLine } from 'react-icons/fa';
import { LineChart } from 'lucide-react';
/**
* 预测报告组件 - 占位符
@@ -16,7 +16,7 @@ const ForecastReport = ({ stockCode }) => {
textAlign="center"
>
<VStack spacing={4}>
<Icon as={FaChartLine} boxSize={12} color="gray.400" />
<Icon as={LineChart} boxSize={12} color="gray.400" />
<Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}>
预测报告功能开发中
</Text>

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { Box, Text, VStack, Icon } from '@chakra-ui/react';
import { FaChartBar } from 'react-icons/fa';
import { BarChart2 } from 'lucide-react';
/**
* 市场数据视图组件 - 占位符
@@ -16,7 +16,7 @@ const MarketDataView = ({ stockCode }) => {
textAlign="center"
>
<VStack spacing={4}>
<Icon as={FaChartBar} boxSize={12} color="gray.400" />
<Icon as={BarChart2} boxSize={12} color="gray.400" />
<Text fontSize="lg" fontWeight="medium" color="gray.600" _dark={{ color: 'gray.400' }}>
市场数据功能开发中
</Text>

View File

@@ -22,7 +22,7 @@ import {
ModalFooter,
useDisclosure,
} from "@chakra-ui/react";
import { ExternalLinkIcon } from "@chakra-ui/icons";
import { ExternalLink } from "lucide-react";
import { useAnnouncementsData } from "../../hooks/useAnnouncementsData";
import { THEME } from "../config";
@@ -92,7 +92,7 @@ const AnnouncementsPanel: React.FC<AnnouncementsPanelProps> = ({ stockCode, isAc
)}
<IconButton
size="sm"
icon={<ExternalLinkIcon />}
icon={<ExternalLink size={16} />}
variant="ghost"
color={THEME.goldLight}
aria-label="查看原文"

View File

@@ -11,7 +11,7 @@ import {
SimpleGrid,
Center,
} from "@chakra-ui/react";
import { FaSitemap, FaBuilding, FaCheckCircle, FaTimesCircle } from "react-icons/fa";
import { GitBranch, Building2, CheckCircle, XCircle } from "lucide-react";
import { useBranchesData } from "../../hooks/useBranchesData";
import { THEME } from "../config";
@@ -85,7 +85,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
border="1px solid"
borderColor="rgba(212, 175, 55, 0.2)"
>
<Icon as={FaSitemap} boxSize={10} color={THEME.gold} opacity={0.6} />
<Icon as={GitBranch} boxSize={10} color={THEME.gold} opacity={0.6} />
</Box>
<Text color={THEME.textSecondary} fontSize="sm">
@@ -118,7 +118,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
borderRadius="md"
bg="rgba(212, 175, 55, 0.1)"
>
<Icon as={FaBuilding} boxSize={3.5} color={THEME.gold} />
<Icon as={Building2} boxSize={3.5} color={THEME.gold} />
</Box>
<Text
fontWeight="bold"
@@ -134,7 +134,7 @@ const BranchesPanel: React.FC<BranchesPanelProps> = ({ stockCode, isActive = tru
{/* 状态徽章 */}
<Box sx={getStatusBadgeStyles(isActive)}>
<Icon
as={isActive ? FaCheckCircle : FaTimesCircle}
as={isActive ? CheckCircle : XCircle}
boxSize={3}
/>
<Text>{branch.business_status}</Text>

View File

@@ -12,15 +12,15 @@ import {
Icon,
} from "@chakra-ui/react";
import {
FaBuilding,
FaMapMarkerAlt,
FaIdCard,
FaUsers,
FaBalanceScale,
FaCalculator,
FaBriefcase,
FaFileAlt,
} from "react-icons/fa";
Building2,
MapPin,
CreditCard,
Users,
Scale,
Calculator,
Briefcase,
FileText,
} from "lucide-react";
// 使用统一主题
import { COLORS, GLASS, glassCardStyle } from "@views/Company/theme";
@@ -173,27 +173,27 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
{/* 工商信息卡片 */}
<Box {...glassCardStyle} p={4}>
<SectionTitle icon={FaBuilding} title="工商信息" />
<SectionTitle icon={Building2} title="工商信息" />
<VStack spacing={2} align="stretch">
<InfoRow
icon={FaIdCard}
icon={CreditCard}
label="信用代码"
value={basicInfo.credit_code}
isCode
/>
<InfoRow
icon={FaUsers}
icon={Users}
label="公司规模"
value={basicInfo.company_size}
/>
<InfoRow
icon={FaMapMarkerAlt}
icon={MapPin}
label="注册地址"
value={basicInfo.reg_address}
isMultiline
/>
<InfoRow
icon={FaMapMarkerAlt}
icon={MapPin}
label="办公地址"
value={basicInfo.office_address}
isMultiline
@@ -203,15 +203,15 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
{/* 服务机构卡片 */}
<Box {...glassCardStyle} p={4}>
<SectionTitle icon={FaBalanceScale} title="服务机构" />
<SectionTitle icon={Scale} title="服务机构" />
<VStack spacing={3} align="stretch">
<ServiceCard
icon={FaCalculator}
icon={Calculator}
label="会计师事务所"
value={basicInfo.accounting_firm}
/>
<ServiceCard
icon={FaBalanceScale}
icon={Scale}
label="律师事务所"
value={basicInfo.law_firm}
/>
@@ -222,12 +222,12 @@ const BusinessInfoPanel: React.FC<BusinessInfoPanelProps> = ({ stockCode, isActi
{/* 下半部分:主营业务 + 经营范围 */}
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={4}>
<TextSection
icon={FaBriefcase}
icon={Briefcase}
title="主营业务"
content={basicInfo.main_business}
/>
<TextSection
icon={FaFileAlt}
icon={FileText}
title="经营范围"
content={basicInfo.business_scope}
/>

View File

@@ -24,11 +24,11 @@ import {
Td,
} from '@chakra-ui/react';
import {
FaShareAlt,
FaUserTie,
FaSitemap,
FaInfoCircle,
} from 'react-icons/fa';
Share2,
UserRound,
GitBranch,
Info,
} from 'lucide-react';
// 深空 FUI 主题配置(与 SubTabContainer 保持一致)
const DEEP_SPACE = {
@@ -46,10 +46,10 @@ const DEEP_SPACE = {
// 导航配置(与主组件 config.ts 保持同步)
const OVERVIEW_TABS = [
{ key: 'shareholder', name: '股权结构', icon: FaShareAlt },
{ key: 'management', name: '管理团队', icon: FaUserTie },
{ key: 'branches', name: '分支机构', icon: FaSitemap },
{ key: 'business', name: '工商信息', icon: FaInfoCircle },
{ key: 'shareholder', name: '股权结构', icon: Share2 },
{ key: 'management', name: '管理团队', icon: UserRound },
{ key: 'branches', name: '分支机构', icon: GitBranch },
{ key: 'business', name: '工商信息', icon: Info },
];
/**

View File

@@ -10,7 +10,7 @@ import {
Icon,
SimpleGrid,
} from "@chakra-ui/react";
import type { IconType } from "react-icons";
import type { LucideIcon } from "lucide-react";
import { THEME } from "../../config";
import ManagementCard from "./ManagementCard";
@@ -19,7 +19,7 @@ import type { ManagementPerson, ManagementCategory } from "./types";
interface CategorySectionProps {
category: ManagementCategory;
people: ManagementPerson[];
icon: IconType;
icon: LucideIcon;
color: string;
}

View File

@@ -13,10 +13,10 @@ import {
Tag,
} from "@chakra-ui/react";
import {
FaVenusMars,
FaGraduationCap,
FaPassport,
} from "react-icons/fa";
Users as GenderIcon,
GraduationCap,
CreditCard,
} from "lucide-react";
import { THEME } from "../../config";
import { formatDate } from "../../utils";
@@ -53,7 +53,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
</Text>
{person.gender && (
<Icon
as={FaVenusMars}
as={GenderIcon}
color={person.gender === "男" ? "blue.400" : "pink.400"}
boxSize={3}
/>
@@ -69,7 +69,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
<HStack spacing={2} flexWrap="wrap">
{person.education && (
<Tag size="sm" bg={THEME.tableHoverBg} color={THEME.textSecondary}>
<Icon as={FaGraduationCap} mr={1} boxSize={3} />
<Icon as={GraduationCap} mr={1} boxSize={3} />
{person.education}
</Tag>
)}
@@ -80,7 +80,7 @@ const ManagementCard: React.FC<ManagementCardProps> = ({ person, categoryColor }
)}
{person.nationality && person.nationality !== "中国" && (
<Tag size="sm" bg="orange.600" color="white">
<Icon as={FaPassport} mr={1} boxSize={3} />
<Icon as={CreditCard} mr={1} boxSize={3} />
{person.nationality}
</Tag>
)}

View File

@@ -3,11 +3,11 @@
import React, { useMemo } from "react";
import {
FaUserTie,
FaCrown,
FaEye,
FaUsers,
} from "react-icons/fa";
UserRound,
Crown,
Eye,
Users,
} from "lucide-react";
import { useManagementData } from "../../../hooks/useManagementData";
import { THEME } from "../../config";
@@ -31,10 +31,10 @@ interface ManagementPanelProps {
* 分类配置映射
*/
const CATEGORY_CONFIG: Record<ManagementCategory, CategoryConfig> = {
: { icon: FaUserTie, color: THEME.gold },
: { icon: FaCrown, color: THEME.goldLight },
: { icon: FaEye, color: "green.400" },
: { icon: FaUsers, color: THEME.textSecondary },
: { icon: UserRound, color: THEME.gold },
: { icon: Crown, color: THEME.goldLight },
: { icon: Eye, color: "green.400" },
: { icon: Users, color: THEME.textSecondary },
};
/**

View File

@@ -1,7 +1,7 @@
// src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/types.ts
// 管理团队相关类型定义
import type { IconType } from "react-icons";
import type { LucideIcon } from "lucide-react";
/**
* 管理人员信息
@@ -31,6 +31,6 @@ export type CategorizedManagement = Record<ManagementCategory, ManagementPerson[
* 分类配置项
*/
export interface CategoryConfig {
icon: IconType;
icon: LucideIcon;
color: string;
}

View File

@@ -1,13 +1,7 @@
// src/views/Company/components/CompanyOverview/BasicInfoTab/config.ts
// Tab 配置 + 黑金主题配置
import { IconType } from "react-icons";
import {
FaShareAlt,
FaUserTie,
FaSitemap,
FaInfoCircle,
} from "react-icons/fa";
import { LucideIcon, Share2, UserRound, GitBranch, Info } from "lucide-react";
// 主题类型定义
export interface Theme {
@@ -54,7 +48,7 @@ export const THEME: Theme = {
export interface TabConfig {
key: string;
name: string;
icon: IconType;
icon: LucideIcon;
enabled: boolean;
}
@@ -63,25 +57,25 @@ export const TAB_CONFIG: TabConfig[] = [
{
key: "shareholder",
name: "股权结构",
icon: FaShareAlt,
icon: Share2,
enabled: true,
},
{
key: "management",
name: "管理团队",
icon: FaUserTie,
icon: UserRound,
enabled: true,
},
{
key: "branches",
name: "分支机构",
icon: FaSitemap,
icon: GitBranch,
enabled: true,
},
{
key: "business",
name: "工商信息",
icon: FaInfoCircle,
icon: Info,
enabled: true,
},
];

View File

@@ -17,7 +17,7 @@ import {
Tag,
Icon,
} from '@chakra-ui/react';
import { FaArrowUp, FaArrowDown } from 'react-icons/fa';
import { ArrowUp, ArrowDown } from 'lucide-react';
import type { KeyFactorCardProps, ImpactDirection } from '../types';
// 黑金主题样式常量
@@ -94,7 +94,7 @@ const KeyFactorCard: React.FC<KeyFactorCardProps> = ({ factor }) => {
color={factor.year_on_year > 0 ? 'red.400' : 'green.400'}
>
<Icon
as={factor.year_on_year > 0 ? FaArrowUp : FaArrowDown}
as={factor.year_on_year > 0 ? ArrowUp : ArrowDown}
mr={1}
boxSize={3}
/>

View File

@@ -7,7 +7,7 @@
import React, { memo } from 'react';
import { HStack, VStack, Box, Text, Icon, Badge } from '@chakra-ui/react';
import { FaArrowRight } from 'react-icons/fa';
import { ArrowRight } from 'lucide-react';
// 黑金主题配置(使用更亮的金色提高对比度)
const THEME = {
@@ -133,7 +133,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
/>
<Icon
as={FaArrowRight}
as={ArrowRight}
color={THEME.textSecondary}
boxSize={4}
/>
@@ -148,7 +148,7 @@ const ProcessNavigation: React.FC<ProcessNavigationProps> = memo(({
/>
<Icon
as={FaArrowRight}
as={ArrowRight}
color={THEME.textSecondary}
boxSize={4}
/>

View File

@@ -20,7 +20,7 @@ import {
SimpleGrid,
Button,
} from '@chakra-ui/react';
import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
import { Factory, Maximize2, Minimize2 } from 'lucide-react';
import type { BusinessSegment } from '../types';
// 黑金主题配置
@@ -52,7 +52,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
<Card bg={THEME.cardBg} shadow="md">
<CardHeader>
<HStack>
<Icon as={FaIndustry} color={THEME.gold} />
<Icon as={Factory} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessSegments.length} </Badge>
</HStack>
@@ -74,7 +74,7 @@ const BusinessSegmentsCard: React.FC<BusinessSegmentsCardProps> = ({
size="sm"
variant="ghost"
leftIcon={
<Icon as={isExpanded ? FaCompressAlt : FaExpandAlt} />
<Icon as={isExpanded ? Minimize2 : Maximize2} />
}
onClick={() => onToggleSegment(idx)}
color={THEME.gold}

View File

@@ -16,7 +16,7 @@ import {
Badge,
Icon,
} from '@chakra-ui/react';
import { FaChartPie } from 'react-icons/fa';
import { PieChart } from 'lucide-react';
import { BusinessTreeItem } from '../atoms';
import type { BusinessStructure } from '../types';
@@ -42,7 +42,7 @@ const BusinessStructureCard: React.FC<BusinessStructureCardProps> = ({
<Card bg={THEME.cardBg} shadow="md">
<CardHeader>
<HStack>
<Icon as={FaChartPie} color={THEME.gold} />
<Icon as={PieChart} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}></Heading>
<Badge bg={THEME.gold} color="gray.900">{businessStructure[0]?.report_period}</Badge>
</HStack>

View File

@@ -33,17 +33,17 @@ import {
useDisclosure,
} from '@chakra-ui/react';
import {
FaTrophy,
FaCog,
FaStar,
FaChartLine,
FaDollarSign,
FaFlask,
FaShieldAlt,
FaRocket,
FaUsers,
FaExternalLinkAlt,
} from 'react-icons/fa';
Trophy,
Settings,
Star,
TrendingUp,
DollarSign,
FlaskConical,
Shield,
Rocket,
Users,
ExternalLink,
} from 'lucide-react';
import ReactECharts from 'echarts-for-react';
import { ScoreBar } from '../atoms';
import { getRadarChartOption } from '../utils/chartOptions';
@@ -110,7 +110,7 @@ const CompetitorTags = memo<CompetitorTagsProps>(({ competitors }) => (
color="yellow.500"
borderRadius="full"
>
<Icon as={FaUsers} mr={1} />
<Icon as={Users} mr={1} />
<TagLabel>{competitor}</TagLabel>
</Tag>
))}
@@ -127,14 +127,14 @@ interface ScoreSectionProps {
const ScoreSection = memo<ScoreSectionProps>(({ scores }) => (
<VStack spacing={4} align="stretch">
<ScoreBar label="市场地位" score={scores?.market_position} icon={FaTrophy} />
<ScoreBar label="技术实力" score={scores?.technology} icon={FaCog} />
<ScoreBar label="品牌价值" score={scores?.brand} icon={FaStar} />
<ScoreBar label="运营效率" score={scores?.operation} icon={FaChartLine} />
<ScoreBar label="财务健康" score={scores?.finance} icon={FaDollarSign} />
<ScoreBar label="创新能力" score={scores?.innovation} icon={FaFlask} />
<ScoreBar label="风险控制" score={scores?.risk} icon={FaShieldAlt} />
<ScoreBar label="成长潜力" score={scores?.growth} icon={FaRocket} />
<ScoreBar label="市场地位" score={scores?.market_position} icon={Trophy} />
<ScoreBar label="技术实力" score={scores?.technology} icon={Settings} />
<ScoreBar label="品牌价值" score={scores?.brand} icon={Star} />
<ScoreBar label="运营效率" score={scores?.operation} icon={TrendingUp} />
<ScoreBar label="财务健康" score={scores?.finance} icon={DollarSign} />
<ScoreBar label="创新能力" score={scores?.innovation} icon={FlaskConical} />
<ScoreBar label="风险控制" score={scores?.risk} icon={Shield} />
<ScoreBar label="成长潜力" score={scores?.growth} icon={Rocket} />
</VStack>
));
@@ -201,7 +201,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
<Card {...CARD_STYLES}>
<CardHeader>
<HStack>
<Icon as={FaTrophy} color="yellow.500" />
<Icon as={Trophy} color="yellow.500" />
<Heading size="sm" color="yellow.500"></Heading>
{competitivePosition.ranking && (
<Badge
@@ -223,7 +223,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
size="xs"
variant="ghost"
color="yellow.500"
rightIcon={<Icon as={FaExternalLinkAlt} boxSize={3} />}
rightIcon={<Icon as={ExternalLink} boxSize={3} />}
onClick={onOpen}
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
>
@@ -269,7 +269,7 @@ const CompetitiveAnalysisCard: React.FC<CompetitiveAnalysisCardProps> = memo(
<ModalContent {...MODAL_STYLES.content}>
<ModalHeader {...MODAL_STYLES.header}>
<HStack>
<Icon as={FaTrophy} color="yellow.500" />
<Icon as={Trophy} color="yellow.500" />
<Text></Text>
</HStack>
</ModalHeader>

View File

@@ -4,7 +4,7 @@
import React, { memo } from 'react';
import { Box, HStack, VStack, Icon, Text } from '@chakra-ui/react';
import { FaUsers } from 'react-icons/fa';
import { Users } from 'lucide-react';
import { THEME, ICON_MAP, HIGHLIGHT_HOVER_STYLES } from '../theme';
import type { InvestmentHighlightItem } from '../../../types';
@@ -13,7 +13,7 @@ interface HighlightCardProps {
}
export const HighlightCard = memo<HighlightCardProps>(({ highlight }) => {
const IconComponent = ICON_MAP[highlight.icon] || FaUsers;
const IconComponent = ICON_MAP[highlight.icon] || Users;
return (
<Box

View File

@@ -4,11 +4,11 @@
import React, { memo } from 'react';
import { HStack, Icon, Text } from '@chakra-ui/react';
import type { IconType } from 'react-icons';
import type { LucideIcon } from 'lucide-react';
import { THEME } from '../theme';
interface SectionHeaderProps {
icon: IconType;
icon: LucideIcon;
title: string;
color?: string;
}

View File

@@ -15,7 +15,7 @@ import {
Grid,
GridItem,
} from '@chakra-ui/react';
import { FaCrown, FaStar, FaBriefcase } from 'react-icons/fa';
import { Crown, Star, Briefcase } from 'lucide-react';
import type {
QualitativeAnalysis,
InvestmentHighlightItem,
@@ -57,7 +57,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<Card {...CARD_STYLES}>
<CardBody>
<VStack spacing={4} align="stretch">
<SectionHeader icon={FaCrown} title="核心定位" />
<SectionHeader icon={Crown} title="核心定位" />
{corePositioning?.one_line_intro && (
<Box
p={4}
@@ -74,7 +74,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<Grid templateColumns={GRID_COLUMNS.twoColumnMd} gap={4}>
<GridItem>
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
<SectionHeader icon={FaStar} title="投资亮点" />
<SectionHeader icon={Star} title="投资亮点" />
<Text
fontSize="sm"
color={THEME.light.subtextColor}
@@ -89,7 +89,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
</GridItem>
<GridItem>
<Box p={4} bg={THEME.light.cardBg} borderRadius="lg">
<SectionHeader icon={FaBriefcase} title="商业模式" />
<SectionHeader icon={Briefcase} title="商业模式" />
<Text
fontSize="sm"
color={THEME.light.subtextColor}
@@ -126,7 +126,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
<VStack spacing={0} align="stretch">
{/* 核心定位区域(深色背景) */}
<Box p={6} bg={THEME.dark.bg}>
<SectionHeader icon={FaCrown} title="核心定位" />
<SectionHeader icon={Crown} title="核心定位" />
{/* 一句话介绍 */}
{corePositioning?.one_line_intro && (
@@ -152,7 +152,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
borderRight={BORDER_RIGHT_RESPONSIVE}
borderColor="whiteAlpha.100"
>
<SectionHeader icon={FaStar} title="投资亮点" />
<SectionHeader icon={Star} title="投资亮点" />
<VStack spacing={3} align="stretch">
{highlights.length > 0 ? (
highlights.map((highlight, idx) => (
@@ -168,7 +168,7 @@ const CorePositioningCard: React.FC<CorePositioningCardProps> = memo(
{/* 商业模式区域 */}
<GridItem p={6}>
<SectionHeader icon={FaBriefcase} title="商业模式" />
<SectionHeader icon={Briefcase} title="商业模式" />
<Box
p={4}
bg={THEME.light.cardBg}

View File

@@ -3,14 +3,14 @@
*/
import {
FaUniversity,
FaFire,
FaUsers,
FaChartLine,
FaMicrochip,
FaShieldAlt,
} from 'react-icons/fa';
import type { IconType } from 'react-icons';
University,
Flame,
Users,
TrendingUp,
Cpu,
Shield,
type LucideIcon,
} from 'lucide-react';
// ==================== 主题常量 ====================
@@ -39,13 +39,13 @@ export const THEME = {
// ==================== 图标映射 ====================
export const ICON_MAP: Record<string, IconType> = {
bank: FaUniversity,
fire: FaFire,
users: FaUsers,
'trending-up': FaChartLine,
cpu: FaMicrochip,
'shield-check': FaShieldAlt,
export const ICON_MAP: Record<string, LucideIcon> = {
bank: University,
fire: Flame,
users: Users,
'trending-up': TrendingUp,
cpu: Cpu,
'shield-check': Shield,
};
// ==================== 样式常量 ====================

View File

@@ -23,7 +23,7 @@ import {
AccordionPanel,
AccordionIcon,
} from '@chakra-ui/react';
import { FaBalanceScale } from 'react-icons/fa';
import { Scale } from 'lucide-react';
import { KeyFactorCard } from '../atoms';
import type { KeyFactors } from '../types';
@@ -66,7 +66,7 @@ const KeyFactorsCard: React.FC<KeyFactorsCardProps> = ({ keyFactors }) => {
<Card {...CARD_STYLES} h="full">
<CardHeader>
<HStack>
<Icon as={FaBalanceScale} color="yellow.500" />
<Icon as={Scale} color="yellow.500" />
<Heading size="sm" color={THEME.titleColor}>
</Heading>

View File

@@ -19,7 +19,7 @@ import {
GridItem,
Center,
} from '@chakra-ui/react';
import { FaRocket, FaChartBar } from 'react-icons/fa';
import { Rocket, BarChart2 } from 'lucide-react';
import type { Strategy } from '../types';
// 样式常量 - 避免每次渲染创建新对象
@@ -54,7 +54,7 @@ const EmptyState = memo(() => (
<Box {...EMPTY_BOX_STYLES}>
<Center>
<VStack spacing={3}>
<Icon as={FaChartBar} boxSize={10} color="yellow.600" />
<Icon as={BarChart2} boxSize={10} color="yellow.600" />
<Text fontWeight="medium"></Text>
<Text fontSize="sm" color="gray.500">
@@ -97,7 +97,7 @@ const StrategyAnalysisCard: React.FC<StrategyAnalysisCardProps> = memo(
<Card {...CARD_STYLES}>
<CardHeader>
<HStack>
<Icon as={FaRocket} color="yellow.500" />
<Icon as={Rocket} color="yellow.500" />
<Heading size="sm" color="yellow.500"></Heading>
</HStack>
</CardHeader>

View File

@@ -16,7 +16,7 @@ import {
Box,
Icon,
} from '@chakra-ui/react';
import { FaHistory } from 'react-icons/fa';
import { History } from 'lucide-react';
import TimelineComponent from '../organisms/TimelineComponent';
import type { DevelopmentTimeline } from '../types';
@@ -59,7 +59,7 @@ const TimelineCard: React.FC<TimelineCardProps> = ({ developmentTimeline }) => {
<Card {...CARD_STYLES} h="full">
<CardHeader>
<HStack>
<Icon as={FaHistory} color="yellow.500" />
<Icon as={History} color="yellow.500" />
<Heading size="sm" color={THEME.titleColor}>
线
</Heading>

View File

@@ -20,7 +20,7 @@ import {
Box,
Flex,
} from '@chakra-ui/react';
import { FaNetworkWired } from 'react-icons/fa';
import { Network } from 'lucide-react';
import ReactECharts from 'echarts-for-react';
import {
ProcessNavigation,
@@ -133,7 +133,7 @@ const ValueChainCard: React.FC<ValueChainCardProps> = memo(({
{/* 头部区域 */}
<CardHeader py={0}>
<HStack flexWrap="wrap" gap={0}>
<Icon as={FaNetworkWired} color={THEME.gold} />
<Icon as={Network} color={THEME.gold} />
<Heading size="sm" color={THEME.textPrimary}>
</Heading>

View File

@@ -12,7 +12,7 @@
import React, { useMemo } from 'react';
import { Card, CardBody } from '@chakra-ui/react';
import { FaBrain, FaBuilding, FaLink, FaHistory } from 'react-icons/fa';
import { Brain, Building2, Link2, History } from 'lucide-react';
import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer';
import LoadingState from '../../LoadingState';
import { StrategyTab, BusinessTab, ValueChainTab, DevelopmentTab } from './tabs';
@@ -28,10 +28,10 @@ const THEME = {
* Tab 配置
*/
const DEEP_ANALYSIS_TABS: SubTabConfig[] = [
{ key: 'strategy', name: '战略分析', icon: FaBrain, component: StrategyTab },
{ key: 'business', name: '业务结构', icon: FaBuilding, component: BusinessTab },
{ key: 'valueChain', name: '产业链', icon: FaLink, component: ValueChainTab },
{ key: 'development', name: '发展历程', icon: FaHistory, component: DevelopmentTab },
{ key: 'strategy', name: '战略分析', icon: Brain, component: StrategyTab },
{ key: 'business', name: '业务结构', icon: Building2, component: BusinessTab },
{ key: 'valueChain', name: '产业链', icon: Link2, component: ValueChainTab },
{ key: 'development', name: '发展历程', icon: History, component: DevelopmentTab },
];
/**

View File

@@ -22,7 +22,7 @@ import {
Icon,
Button,
} from '@chakra-ui/react';
import { FaCheckCircle, FaExclamationCircle } from 'react-icons/fa';
import { CheckCircle, AlertCircle } from 'lucide-react';
import type { TimelineEvent } from '../../types';
interface EventDetailModalProps {
@@ -48,7 +48,7 @@ const EventDetailModal: React.FC<EventDetailModalProps> = ({
<ModalHeader>
<HStack>
<Icon
as={isPositive ? FaCheckCircle : FaExclamationCircle}
as={isPositive ? CheckCircle : AlertCircle}
color={isPositive ? 'red.500' : 'green.500'}
boxSize={6}
/>

View File

@@ -20,10 +20,10 @@ import {
useDisclosure,
} from '@chakra-ui/react';
import {
FaCalendarAlt,
FaArrowUp,
FaArrowDown,
} from 'react-icons/fa';
Calendar,
ArrowUp,
ArrowDown,
} from 'lucide-react';
import EventDetailModal from './EventDetailModal';
import type { TimelineComponentProps, TimelineEvent } from '../../types';
@@ -74,7 +74,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
shadow="md"
>
<Icon
as={isPositive ? FaArrowUp : FaArrowDown}
as={isPositive ? ArrowUp : ArrowDown}
color="white"
boxSize={3}
/>
@@ -108,7 +108,7 @@ const TimelineComponent: React.FC<TimelineComponentProps> = ({ events }) => {
</Text>
<HStack spacing={2}>
<Icon
as={FaCalendarAlt}
as={Calendar}
boxSize={3}
color="gray.500"
/>

View File

@@ -34,19 +34,19 @@ import {
Tooltip,
Button,
} from '@chakra-ui/react';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import {
FaBuilding,
FaHandshake,
FaUserTie,
FaIndustry,
FaCog,
FaNetworkWired,
FaFlask,
FaStar,
FaArrowRight,
FaArrowLeft,
} from 'react-icons/fa';
ExternalLink,
Building,
Handshake,
UserCircle,
Factory,
Settings,
Network,
FlaskConical,
Star,
ArrowRight,
ArrowLeft,
} from 'lucide-react';
import type { ValueChainNode, RelatedCompany } from '../../types';
interface RelatedCompaniesModalProps {
@@ -64,15 +64,15 @@ interface RelatedCompaniesModalProps {
*/
const getNodeTypeIcon = (type: string) => {
const icons: Record<string, React.ComponentType> = {
company: FaBuilding,
supplier: FaHandshake,
customer: FaUserTie,
product: FaIndustry,
service: FaCog,
channel: FaNetworkWired,
raw_material: FaFlask,
company: Building,
supplier: Handshake,
customer: UserCircle,
product: Factory,
service: Settings,
channel: Network,
raw_material: FlaskConical,
};
return icons[type] || FaBuilding;
return icons[type] || Building;
};
/**
@@ -242,7 +242,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
</VStack>
<IconButton
size="sm"
icon={<ExternalLinkIcon />}
icon={<ExternalLink size={16} />}
variant="ghost"
colorScheme="blue"
onClick={() => {
@@ -287,8 +287,8 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
<Icon
as={
rel.role === 'source'
? FaArrowRight
: FaArrowLeft
? ArrowRight
: ArrowLeft
}
color={
rel.role === 'source'
@@ -323,7 +323,7 @@ const RelatedCompaniesModal: React.FC<RelatedCompaniesModalProps> = ({
) : (
<Center py={4}>
<VStack spacing={2}>
<Icon as={FaBuilding} boxSize={8} color="gray.300" />
<Icon as={Building} boxSize={8} color="gray.300" />
<Text fontSize="sm" color="gray.500">
</Text>

View File

@@ -22,15 +22,15 @@ import {
ScaleFade,
} from '@chakra-ui/react';
import {
FaBuilding,
FaHandshake,
FaUserTie,
FaIndustry,
FaCog,
FaNetworkWired,
FaFlask,
FaStar,
} from 'react-icons/fa';
Building,
Handshake,
UserCircle,
Factory,
Settings,
Network,
FlaskConical,
Star,
} from 'lucide-react';
import { logger } from '@utils/logger';
import axios from '@utils/axiosConfig';
import RelatedCompaniesModal from './RelatedCompaniesModal';
@@ -71,17 +71,17 @@ const THEME = {
*/
const getNodeTypeIcon = (type: string) => {
const icons: Record<string, React.ComponentType> = {
company: FaBuilding,
supplier: FaHandshake,
customer: FaUserTie,
product: FaIndustry,
service: FaCog,
channel: FaNetworkWired,
raw_material: FaFlask,
regulator: FaBuilding,
end_user: FaUserTie,
company: Building,
supplier: Handshake,
customer: UserCircle,
product: Factory,
service: Settings,
channel: Network,
raw_material: FlaskConical,
regulator: Building,
end_user: UserCircle,
};
return icons[type] || FaBuilding;
return icons[type] || Building;
};
/**
@@ -195,7 +195,7 @@ const ValueChainNodeCard: React.FC<ValueChainNodeCardProps> = memo(({
node.importance_score >= 70 && (
<Tooltip label="重要节点">
<span>
<Icon as={FaStar} color={THEME.gold} boxSize={4} />
<Icon as={Star} color={THEME.gold} boxSize={4} />
</span>
</Tooltip>
)}

View File

@@ -17,7 +17,7 @@ import {
StatNumber,
StatHelpText,
} from "@chakra-ui/react";
import { FaCrown } from "react-icons/fa";
import { Crown } from "lucide-react";
import type { ActualControl } from "../../types";
import { THEME } from "../../BasicInfoTab/config";
@@ -58,7 +58,7 @@ const ActualControlCard: React.FC<ActualControlCardProps> = ({ actualControl = [
return (
<Box>
<HStack mb={4}>
<Icon as={FaCrown} color={THEME.gold} boxSize={5} />
<Icon as={Crown} color={THEME.gold} boxSize={5} />
<Heading size="sm" color={THEME.gold}></Heading>
</HStack>
<Card bg={THEME.cardBg} borderColor={THEME.border} borderWidth="1px">

View File

@@ -15,7 +15,7 @@ import {
CardHeader,
SimpleGrid,
} from "@chakra-ui/react";
import { FaChartPie, FaArrowUp, FaArrowDown } from "react-icons/fa";
import { PieChart, ArrowUp, ArrowDown } from "lucide-react";
import { echarts, type ECharts, type EChartsOption } from '@lib/echarts';
import type { Concentration } from "../../types";
import { THEME } from "../../BasicInfoTab/config";
@@ -182,7 +182,7 @@ const ConcentrationCard: React.FC<ConcentrationCardProps> = ({ concentration = [
return (
<Box>
<HStack mb={4}>
<Icon as={FaChartPie} color={THEME.gold} boxSize={5} />
<Icon as={PieChart} color={THEME.gold} boxSize={5} />
<Heading size="sm" color={THEME.gold}></Heading>
</HStack>
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
@@ -208,7 +208,7 @@ const ConcentrationCard: React.FC<ConcentrationCardProps> = ({ concentration = [
colorScheme={item.ratio_change > 0 ? "red" : "green"}
>
<Icon
as={item.ratio_change > 0 ? FaArrowUp : FaArrowDown}
as={item.ratio_change > 0 ? ArrowUp : ArrowDown}
mr={1}
boxSize={3}
/>

View File

@@ -5,7 +5,7 @@ import React, { useMemo, memo } from "react";
import { Box, HStack, Heading, Badge, Icon, useBreakpointValue } from "@chakra-ui/react";
import { Table, Tag, Tooltip, ConfigProvider } from "antd";
import type { ColumnsType } from "antd/es/table";
import { FaUsers, FaChartLine } from "react-icons/fa";
import { Users, LineChart } from "lucide-react";
import type { Shareholder } from "../../types";
import { THEME } from "../../BasicInfoTab/config";
@@ -96,7 +96,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
if (type === "circulation") {
return {
title: title || "十大流通股东",
icon: FaChartLine,
icon: LineChart,
iconColor: "purple.500",
ratioField: "circulation_share_ratio" as keyof Shareholder,
ratioLabel: "流通股比例",
@@ -106,7 +106,7 @@ const ShareholdersTable: React.FC<ShareholdersTableProps> = ({
}
return {
title: title || "十大股东",
icon: FaUsers,
icon: Users,
iconColor: "green.500",
ratioField: "total_share_ratio" as keyof Shareholder,
ratioLabel: "持股比例",

View File

@@ -3,7 +3,7 @@
import React, { memo } from 'react';
import { Center, VStack, Icon, Text } from '@chakra-ui/react';
import { FaNewspaper } from 'react-icons/fa';
import { Newspaper } from 'lucide-react';
import type { NewsEmptyStateProps } from '../types';
const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
@@ -15,7 +15,7 @@ const NewsEmptyState: React.FC<NewsEmptyStateProps> = ({
<Center h="400px">
<VStack spacing={3}>
<Icon
as={FaNewspaper}
as={Newspaper}
boxSize={16}
color={isBlackGold ? theme.gold : 'gray.300'}
opacity={0.5}

View File

@@ -13,7 +13,7 @@ import {
CardBody,
Tag,
} from '@chakra-ui/react';
import { FaEye, FaFire, FaChartLine } from 'react-icons/fa';
import { Eye, Flame, TrendingUp } from 'lucide-react';
import type { NewsEventCardProps } from '../types';
import {
getEventTypeIcon,
@@ -117,7 +117,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
<HStack spacing={3}>
{event.view_count !== undefined && (
<HStack spacing={1}>
<Icon as={FaEye} boxSize={3} color={theme.textMuted} />
<Icon as={Eye} boxSize={3} color={theme.textMuted} />
<Text fontSize="xs" color={theme.textMuted}>
{event.view_count}
</Text>
@@ -125,7 +125,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
)}
{event.hot_score !== undefined && (
<HStack spacing={1}>
<Icon as={FaFire} boxSize={3} color={theme.goldLight} />
<Icon as={Flame} boxSize={3} color={theme.goldLight} />
<Text fontSize="xs" color={theme.textMuted}>
{event.hot_score.toFixed(1)}
</Text>
@@ -152,7 +152,7 @@ const NewsEventCard: React.FC<NewsEventCardProps> = ({
<Box pt={2} borderTop="1px" borderColor={theme.cardBorder}>
<HStack spacing={6} flexWrap="wrap">
<HStack spacing={1}>
<Icon as={FaChartLine} boxSize={3} color={theme.textMuted} />
<Icon as={TrendingUp} boxSize={3} color={theme.textMuted} />
<Text fontSize="xs" color={theme.textMuted} fontWeight="medium">
:
</Text>

View File

@@ -3,7 +3,7 @@
import React, { memo, useMemo } from 'react';
import { Box, HStack, Text, Button, Icon } from '@chakra-ui/react';
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import type { NewsPaginationProps } from '../types';
const NewsPagination: React.FC<NewsPaginationProps> = ({
@@ -87,7 +87,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
onClick={() => onPageChange(1)}
isDisabled={!has_prev || isLoading}
leftIcon={<Icon as={FaChevronLeft} />}
leftIcon={<Icon as={ChevronLeft} />}
>
</Button>
@@ -128,7 +128,7 @@ const NewsPagination: React.FC<NewsPaginationProps> = ({
_hover={{ bg: theme.cardHoverBg, borderColor: theme.gold }}
onClick={() => onPageChange(totalPages)}
isDisabled={!has_next || isLoading}
rightIcon={<Icon as={FaChevronRight} />}
rightIcon={<Icon as={ChevronRight} />}
>
</Button>

View File

@@ -3,8 +3,7 @@
import React, { memo } from 'react';
import { HStack, Input, InputGroup, InputLeftElement, Button, Text, Icon } from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons';
import { FaNewspaper } from 'react-icons/fa';
import { Search, Newspaper } from 'lucide-react';
import type { NewsSearchBarProps } from '../types';
const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
@@ -31,7 +30,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
<HStack flex={1} minW="300px">
<InputGroup>
<InputLeftElement pointerEvents="none">
<SearchIcon color={theme.textMuted} />
<Search size={16} color={theme.textMuted} />
</InputLeftElement>
<Input
placeholder="搜索相关新闻..."
@@ -60,7 +59,7 @@ const NewsSearchBar: React.FC<NewsSearchBarProps> = ({
{total > 0 && (
<HStack spacing={2}>
<Icon as={FaNewspaper} color={theme.gold} />
<Icon as={Newspaper} color={theme.gold} />
<Text fontSize="sm" color={theme.textSecondary}>
{' '}
<Text as="span" fontWeight="bold" color={theme.gold}>

View File

@@ -1,7 +1,7 @@
// src/views/Company/components/DynamicTracking/NewsEventsTab/types.ts
// 新闻动态 - 类型定义
import type { IconType } from 'react-icons';
import type { LucideIcon } from 'lucide-react';
/**
* 徽章样式配置

View File

@@ -1,38 +1,38 @@
// src/views/Company/components/DynamicTracking/NewsEventsTab/utils.ts
// 新闻动态 - 工具函数
import type { IconType } from 'react-icons';
import type { LucideIcon } from 'lucide-react';
import {
FaNewspaper,
FaBullhorn,
FaGavel,
FaFlask,
FaDollarSign,
FaShieldAlt,
FaFileAlt,
FaIndustry,
} from 'react-icons/fa';
Newspaper,
Megaphone,
Gavel,
FlaskConical,
DollarSign,
Shield,
FileText,
Factory,
} from 'lucide-react';
import type { ThemeConfig, BadgeStyle } from './types';
/**
* 事件类型图标映射
*/
const EVENT_TYPE_ICONS: Record<string, IconType> = {
企业公告: FaBullhorn,
政策: FaGavel,
技术突破: FaFlask,
企业融资: FaDollarSign,
政策监管: FaShieldAlt,
政策动态: FaFileAlt,
行业事件: FaIndustry,
const EVENT_TYPE_ICONS: Record<string, LucideIcon> = {
企业公告: Megaphone,
政策: Gavel,
技术突破: FlaskConical,
企业融资: DollarSign,
政策监管: Shield,
政策动态: FileText,
行业事件: Factory,
};
/**
* 获取事件类型对应的图标
*/
export const getEventTypeIcon = (eventType?: string): IconType => {
if (!eventType) return FaNewspaper;
return EVENT_TYPE_ICONS[eventType] || FaNewspaper;
export const getEventTypeIcon = (eventType?: string): LucideIcon => {
if (!eventType) return Newspaper;
return EVENT_TYPE_ICONS[eventType] || Newspaper;
};
/**

View File

@@ -17,7 +17,7 @@ import {
Card,
CardBody,
} from '@chakra-ui/react';
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa';
import { Newspaper, Megaphone, Calendar, BarChart2 } from 'lucide-react';
// 深空 FUI 主题配置(与 SubTabContainer 保持一致)
const DEEP_SPACE = {
@@ -35,10 +35,10 @@ const DEEP_SPACE = {
// 导航配置(与主组件保持同步)
const TRACKING_TABS = [
{ key: 'news', name: '新闻动态', icon: FaNewspaper },
{ key: 'announcements', name: '公司公告', icon: FaBullhorn },
{ key: 'disclosure', name: '财报披露日程', icon: FaCalendarAlt },
{ key: 'forecast', name: '业绩预告', icon: FaChartBar },
{ key: 'news', name: '新闻动态', icon: Newspaper },
{ key: 'announcements', name: '公司公告', icon: Megaphone },
{ key: 'disclosure', name: '财报披露日程', icon: Calendar },
{ key: 'forecast', name: '业绩预告', icon: BarChart2 },
];
/**

View File

@@ -4,7 +4,7 @@
import React, { useState, useEffect, useMemo, useCallback, memo, lazy } from 'react';
import { Card, CardBody } from '@chakra-ui/react';
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa';
import { Newspaper, Megaphone, Calendar, BarChart2 } from 'lucide-react';
import SubTabContainer from '@components/SubTabContainer';
import {
@@ -29,28 +29,28 @@ const TRACKING_TABS = [
{
key: 'news',
name: '新闻动态',
icon: FaNewspaper,
icon: Newspaper,
component: NewsPanel,
fallback: <NewsPanelSkeleton />,
},
{
key: 'announcements',
name: '公司公告',
icon: FaBullhorn,
icon: Megaphone,
component: AnnouncementsPanel,
fallback: <AnnouncementsSkeleton />,
},
{
key: 'disclosure',
name: '财报披露日程',
icon: FaCalendarAlt,
icon: Calendar,
component: DisclosureSchedulePanel,
fallback: <DisclosureScheduleSkeleton />,
},
{
key: 'forecast',
name: '业绩预告',
icon: FaChartBar,
icon: BarChart2,
component: ForecastPanel,
fallback: <ForecastPanelSkeleton />,
},

View File

@@ -23,7 +23,7 @@ import {
Grid,
GridItem,
} from '@chakra-ui/react';
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons';
import { ArrowUp, ArrowDown } from 'lucide-react';
import { useToast } from '@chakra-ui/react';
import ReactECharts from 'echarts-for-react';
import { logger } from '@utils/logger';
@@ -166,8 +166,8 @@ export const StockComparison: React.FC<StockComparisonProps> = ({
<Td isNumeric color={diffColor}>
{diff !== null ? (
<HStack spacing={1} justify="flex-end">
{diff > 0 && <ArrowUpIcon boxSize={3} />}
{diff < 0 && <ArrowDownIcon boxSize={3} />}
{diff > 0 && <ArrowUp size={12} />}
{diff < 0 && <ArrowDown size={12} />}
<Text>
{metric.format === 'percent'
? `${Math.abs(diff).toFixed(2)}pp`

View File

@@ -3,6 +3,7 @@
*/
import { formatUtils } from '@services/financialService';
import { alpha, fui, chartTheme } from '@views/Company/theme';
interface ChartDataItem {
period: string;
@@ -106,22 +107,22 @@ export const getComparisonChartOption = (
text: '营收与利润趋势',
left: 'center',
textStyle: {
color: '#D4AF37',
color: fui.gold,
fontSize: 16,
fontWeight: 'bold',
},
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(26, 32, 44, 0.95)',
borderColor: 'rgba(212, 175, 55, 0.3)',
backgroundColor: chartTheme.tooltip.bg,
borderColor: chartTheme.tooltip.border,
textStyle: {
color: '#E2E8F0',
},
axisPointer: {
type: 'cross',
crossStyle: {
color: 'rgba(212, 175, 55, 0.5)',
color: alpha('gold', 0.5),
},
},
},
@@ -144,7 +145,7 @@ export const getComparisonChartOption = (
data: revenueData.map((d) => d.period),
axisLine: {
lineStyle: {
color: 'rgba(212, 175, 55, 0.3)',
color: chartTheme.axisLine,
},
},
axisLabel: {
@@ -161,7 +162,7 @@ export const getComparisonChartOption = (
},
axisLine: {
lineStyle: {
color: 'rgba(212, 175, 55, 0.3)',
color: chartTheme.axisLine,
},
},
axisLabel: {
@@ -169,7 +170,7 @@ export const getComparisonChartOption = (
},
splitLine: {
lineStyle: {
color: 'rgba(212, 175, 55, 0.1)',
color: chartTheme.splitLine,
},
},
},
@@ -182,7 +183,7 @@ export const getComparisonChartOption = (
},
axisLine: {
lineStyle: {
color: 'rgba(212, 175, 55, 0.3)',
color: chartTheme.axisLine,
},
},
axisLabel: {
@@ -201,7 +202,7 @@ export const getComparisonChartOption = (
itemStyle: {
color: (params: { dataIndex: number; value: number }) => {
const idx = params.dataIndex;
if (idx === 0) return '#D4AF37'; // 金色作为基准
if (idx === 0) return fui.gold; // 金色作为基准
const prevValue = revenueData[idx - 1].value;
const currValue = params.value;
// 红涨绿跌
@@ -215,37 +216,18 @@ export const getComparisonChartOption = (
yAxisIndex: 1,
data: profitData.map((d) => d.value?.toFixed(2)),
smooth: true,
itemStyle: { color: '#D4AF37' },
lineStyle: { width: 2, color: '#D4AF37' },
itemStyle: { color: fui.gold },
lineStyle: { width: 2, color: fui.gold },
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(212, 175, 55, 0.3)' },
{ offset: 1, color: 'rgba(212, 175, 55, 0.05)' },
],
},
color: chartTheme.goldGradient(0.3, 0.05),
},
},
],
};
};
// 黑金主题饼图配色
const BLACK_GOLD_PIE_COLORS = [
'#D4AF37', // 金色
'#B8860B', // 深金色
'#FFD700', // 亮金色
'#DAA520', // 金菊色
'#CD853F', // 秘鲁色
'#F4A460', // 沙褐色
'#DEB887', // 实木色
'#D2691E', // 巧克力色
];
// 黑金主题饼图配色(使用 chartTheme 统一定义)
const BLACK_GOLD_PIE_COLORS = chartTheme.goldSeries;
/**
* 生成主营业务饼图配置 - 黑金主题
@@ -265,7 +247,7 @@ export const getMainBusinessPieOption = (
subtext: subtitle,
left: 'center',
textStyle: {
color: '#D4AF37',
color: fui.gold,
fontSize: 14,
},
subtextStyle: {
@@ -275,8 +257,8 @@ export const getMainBusinessPieOption = (
},
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(26, 32, 44, 0.95)',
borderColor: 'rgba(212, 175, 55, 0.3)',
backgroundColor: chartTheme.tooltip.bg,
borderColor: chartTheme.tooltip.border,
textStyle: {
color: '#E2E8F0',
},
@@ -310,14 +292,14 @@ export const getMainBusinessPieOption = (
},
labelLine: {
lineStyle: {
color: 'rgba(212, 175, 55, 0.5)',
color: alpha('gold', 0.5),
},
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(212, 175, 55, 0.5)',
shadowColor: alpha('gold', 0.5),
},
},
},

View File

@@ -16,7 +16,6 @@ import {
Text,
Icon,
} from '@chakra-ui/react';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { FileText, TrendingUp, Building2, Newspaper, BookOpen } from 'lucide-react';
import MarkdownRenderer from './MarkdownRenderer';
import { formatNumber } from '../utils/formatUtils';

View File

@@ -28,8 +28,7 @@ import {
Flex,
useDisclosure,
} from '@chakra-ui/react';
import { SearchIcon, CloseIcon, AddIcon } from '@chakra-ui/icons';
import { Database, TrendingUp } from 'lucide-react';
import { Database, TrendingUp, Search, X, Plus } from 'lucide-react';
import debounce from 'lodash/debounce';
import { searchMetrics, fetchMetricData, type MetricSearchResult } from '@services/categoryService';
@@ -233,7 +232,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
{/* Search input */}
<InputGroup size="sm" mb={3}>
<InputLeftElement pointerEvents="none">
<SearchIcon color={darkGoldTheme.textMuted} />
<Search size={16} color={darkGoldTheme.textMuted} />
</InputLeftElement>
<Input
ref={inputRef}
@@ -255,7 +254,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
<IconButton
size="xs"
variant="ghost"
icon={<CloseIcon w="8px" h="8px" />}
icon={<X size={12} />}
onClick={() => {
setSearchQuery('');
setSearchResults([]);
@@ -318,7 +317,7 @@ const MetricOverlaySearch: React.FC<MetricOverlaySearchProps> = ({
{isAdded ? (
<Badge colorScheme="green" fontSize="10px">Added</Badge>
) : (
<AddIcon boxSize={3} color={darkGoldTheme.textMuted} />
<Plus size={12} color={darkGoldTheme.textMuted} />
)}
</Flex>
</ListItem>

View File

@@ -3,7 +3,7 @@
import React, { memo, useMemo } from 'react';
import { Box, Text, VStack, Center, Icon } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
import { Info } from 'lucide-react';
import ReactECharts from 'echarts-for-react';
import { darkGoldTheme } from '../../../../constants';
@@ -32,7 +32,7 @@ export interface DailyKLineChartProps {
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
<Center h="300px">
<VStack spacing={4}>
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} />
<Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
<VStack spacing={2}>
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>

View File

@@ -18,8 +18,7 @@ import {
MenuItem,
Tooltip,
} from '@chakra-ui/react';
import { RepeatIcon, ChevronDownIcon, ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil } from 'lucide-react';
import { BarChart2, TrendingUp, Calendar, LineChart, Activity, Pencil, RefreshCw, ChevronDown, Eye, EyeOff } from 'lucide-react';
import { darkGoldTheme, PERIOD_OPTIONS } from '../../../../constants';
import type { IndicatorType, MainIndicatorType, DrawingType } from '../../../../utils/chartOptions';
@@ -155,7 +154,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
<Button
size="sm"
variant="outline"
leftIcon={showAnalysis ? <ViewOffIcon /> : <ViewIcon />}
leftIcon={showAnalysis ? <EyeOff size={14} /> : <Eye size={14} />}
onClick={onToggleAnalysis}
{...(showAnalysis ? INACTIVE_BUTTON_STYLE : ACTIVE_BUTTON_STYLE)}
minW="90px"
@@ -171,7 +170,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button}
size="sm"
variant="outline"
rightIcon={<ChevronDownIcon />}
rightIcon={<ChevronDown size={14} />}
{...INACTIVE_BUTTON_STYLE}
minW="90px"
>
@@ -205,7 +204,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button}
size="sm"
variant="outline"
rightIcon={<ChevronDownIcon />}
rightIcon={<ChevronDown size={14} />}
leftIcon={<Activity size={14} />}
{...INACTIVE_BUTTON_STYLE}
minW="100px"
@@ -240,7 +239,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
as={Button}
size="sm"
variant="outline"
rightIcon={<ChevronDownIcon />}
rightIcon={<ChevronDown size={14} />}
leftIcon={<Pencil size={14} />}
{...(drawingType !== 'NONE' ? ACTIVE_BUTTON_STYLE : INACTIVE_BUTTON_STYLE)}
minW="90px"
@@ -296,7 +295,7 @@ const KLineToolbar: React.FC<KLineToolbarProps> = ({
{/* 刷新按钮 */}
<Button
leftIcon={<RepeatIcon />}
leftIcon={<RefreshCw size={14} />}
size="sm"
variant="outline"
onClick={onRefreshMinuteData}

View File

@@ -14,7 +14,7 @@ import {
GridItem,
Icon,
} from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
import { Info } from 'lucide-react';
import ReactECharts from 'echarts-for-react';
// 导入实时行情 Hook 和五档盘口组件
@@ -38,7 +38,7 @@ export interface MinuteChartWithOrderBookProps {
const EmptyState: React.FC<{ title: string; description: string }> = ({ title, description }) => (
<Center h="300px">
<VStack spacing={4}>
<Icon as={InfoIcon} color={darkGoldTheme.textMuted} boxSize={12} />
<Icon as={Info} color={darkGoldTheme.textMuted} boxSize={12} />
<VStack spacing={2}>
<Text color={darkGoldTheme.textMuted} fontSize="lg">{title}</Text>
<Text color={darkGoldTheme.textMuted} fontSize="sm" textAlign="center">{description}</Text>

View File

@@ -2,6 +2,7 @@
// 共享样式常量
import { darkGoldTheme } from '../../constants';
import { alpha, fui } from '@views/Company/theme';
import type { SystemStyleObject } from '@chakra-ui/react';
/**
@@ -21,7 +22,7 @@ export const darkGoldCardStyle: SystemStyleObject = {
*/
export const darkGoldCardHoverStyle: SystemStyleObject = {
borderColor: darkGoldTheme.borderHover,
boxShadow: '0 8px 30px rgba(212, 175, 55, 0.15)',
boxShadow: `0 8px 30px ${alpha('gold', 0.15)}`,
transform: 'translateY(-2px)',
};
@@ -47,7 +48,7 @@ export const dataRowStyle: SystemStyleObject = {
* 表格行悬停样式
*/
export const tableRowHoverStyle: SystemStyleObject = {
bg: 'rgba(212, 175, 55, 0.08)',
bg: alpha('gold', 0.08),
};
/**
@@ -55,7 +56,7 @@ export const tableRowHoverStyle: SystemStyleObject = {
*/
export const tableBorderStyle: SystemStyleObject = {
borderBottom: '1px solid',
borderColor: 'rgba(212, 175, 55, 0.1)',
borderColor: fui.border('subtle'),
};
/**
@@ -63,14 +64,14 @@ export const tableBorderStyle: SystemStyleObject = {
*/
export const financingRowStyle: SystemStyleObject = {
p: 3,
bg: 'rgba(212, 175, 55, 0.08)',
bg: alpha('gold', 0.08),
borderRadius: 'md',
border: '1px solid',
borderColor: 'rgba(212, 175, 55, 0.15)',
borderColor: alpha('gold', 0.15),
transition: 'all 0.2s',
_hover: {
bg: 'rgba(212, 175, 55, 0.12)',
borderColor: 'rgba(212, 175, 55, 0.3)',
bg: alpha('gold', 0.12),
borderColor: alpha('gold', 0.3),
},
};
@@ -127,8 +128,8 @@ export const sellRowStyle: SystemStyleObject = {
*/
export const dayCardStyle: SystemStyleObject = {
p: 4,
bg: 'rgba(212, 175, 55, 0.05)',
bg: alpha('gold', 0.05),
borderRadius: 'lg',
border: '1px solid',
borderColor: 'rgba(212, 175, 55, 0.15)',
borderColor: alpha('gold', 0.15),
};

View File

@@ -16,8 +16,7 @@ import {
VStack,
Spinner,
} from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons';
import { BarChart2 } from 'lucide-react';
import { BarChart2, Search } from 'lucide-react';
import { useStockSearch, type Stock } from '../../../hooks/useStockSearch';
interface CompareStockInputProps {
@@ -106,7 +105,7 @@ const CompareStockInput: React.FC<CompareStockInputProps> = ({
<HStack spacing={2}>
<InputGroup size="sm" w="160px">
<InputLeftElement pointerEvents="none">
<SearchIcon color={textColor} boxSize={3} />
<Search size={12} color={textColor} />
</InputLeftElement>
<Input
placeholder="对比股票"

View File

@@ -30,7 +30,7 @@ import {
Spinner,
Center,
} from '@chakra-ui/react';
import { ArrowUpIcon, ArrowDownIcon } from '@chakra-ui/icons';
import { ArrowUp, ArrowDown } from 'lucide-react';
import ReactECharts from 'echarts-for-react';
import { COMPARE_METRICS } from '../../FinancialPanorama/constants';
@@ -149,8 +149,8 @@ const StockCompareModal: React.FC<StockCompareModalProps> = ({
<Td isNumeric color={diffColor} fontSize="sm">
{diff !== null ? (
<HStack spacing={1} justify="flex-end">
{diff > 0 && <ArrowUpIcon boxSize={3} />}
{diff < 0 && <ArrowDownIcon boxSize={3} />}
{diff > 0 && <ArrowUp size={12} />}
{diff < 0 && <ArrowDown size={12} />}
<Text>
{metric.format === 'percent'
? `${Math.abs(diff).toFixed(2)}pp`

View File

@@ -1,19 +1,19 @@
// src/views/Company/constants/index.js
// 公司详情页面常量配置
import { FaChartLine, FaMoneyBillWave, FaChartBar, FaInfoCircle, FaBrain, FaNewspaper } from 'react-icons/fa';
import { LineChart, Banknote, BarChart2, Info, Brain, Newspaper } from 'lucide-react';
/**
* Tab 配置
* @type {Array<{key: string, name: string, icon: React.ComponentType}>}
*/
export const COMPANY_TABS = [
{ key: 'overview', name: '公司档案', icon: FaInfoCircle },
{ key: 'analysis', name: '深度分析', icon: FaBrain },
{ key: 'market', name: '股票行情', icon: FaChartLine },
{ key: 'financial', name: '财务全景', icon: FaMoneyBillWave },
{ key: 'forecast', name: '盈利预测', icon: FaChartBar },
{ key: 'tracking', name: '动态跟踪', icon: FaNewspaper },
{ key: 'overview', name: '公司档案', icon: Info },
{ key: 'analysis', name: '深度分析', icon: Brain },
{ key: 'market', name: '股票行情', icon: LineChart },
{ key: 'financial', name: '财务全景', icon: Banknote },
{ key: 'forecast', name: '盈利预测', icon: BarChart2 },
{ key: 'tracking', name: '动态跟踪', icon: Newspaper },
];
/**

View File

@@ -50,6 +50,20 @@ export const FUI_COLORS = {
default: 'rgba(212, 175, 55, 0.2)',
emphasis: 'rgba(212, 175, 55, 0.4)',
glow: 'rgba(212, 175, 55, 0.6)',
// 完整透明度等级(用于替换硬编码)
opacity03: 'rgba(212, 175, 55, 0.03)',
opacity05: 'rgba(212, 175, 55, 0.05)',
opacity08: 'rgba(212, 175, 55, 0.08)',
opacity10: 'rgba(212, 175, 55, 0.1)',
opacity12: 'rgba(212, 175, 55, 0.12)',
opacity15: 'rgba(212, 175, 55, 0.15)',
opacity20: 'rgba(212, 175, 55, 0.2)',
opacity30: 'rgba(212, 175, 55, 0.3)',
opacity40: 'rgba(212, 175, 55, 0.4)',
opacity50: 'rgba(212, 175, 55, 0.5)',
opacity60: 'rgba(212, 175, 55, 0.6)',
opacity70: 'rgba(212, 175, 55, 0.7)',
opacity80: 'rgba(212, 175, 55, 0.8)',
},
// 文字

View File

@@ -4,6 +4,7 @@
* 使用方式:
* import { COLORS, GLOW, GLASS } from '@views/Company/theme';
* import { FUI_COLORS, FUI_THEME } from '@views/Company/theme';
* import { alpha, fui, chartTheme } from '@views/Company/theme';
*/
// 完整主题对象
@@ -20,6 +21,22 @@ export {
// 主题组件
export * from './components';
// ============================================
// 工具函数导出(推荐使用)
// ============================================
export {
// 核心工具
alpha,
hex,
fui,
BASE_COLORS,
OPACITY,
chartTheme,
// 类型
type ColorName,
} from './utils';
// ============================================
// 便捷常量导出(推荐使用)
// ============================================

View File

@@ -0,0 +1,251 @@
/**
* FUI 颜色工具函数
*
* 提供便捷的颜色+透明度生成能力,用于替换硬编码的 rgba 值
*
* @example
* // 替换 'rgba(212, 175, 55, 0.2)' 为:
* alpha('gold', 0.2)
*
* // 或使用语义化 API
* fui.border() // => 'rgba(212, 175, 55, 0.2)'
* fui.border('hover') // => 'rgba(212, 175, 55, 0.4)'
*/
// ============================================
// 基础色值(单一数据源)
// ============================================
export const BASE_COLORS = {
gold: { r: 212, g: 175, b: 55 }, // #D4AF37
white: { r: 255, g: 255, b: 255 },
black: { r: 0, g: 0, b: 0 },
bgPrimary: { r: 15, g: 15, b: 26 }, // #0F0F1A
bgElevated: { r: 26, g: 26, b: 46 }, // #1A1A2E
positive: { r: 239, g: 68, b: 68 }, // #EF4444 涨
negative: { r: 34, g: 197, b: 94 }, // #22C55E 跌
warning: { r: 245, g: 158, b: 11 }, // #F59E0B
info: { r: 59, g: 130, b: 246 }, // #3B82F6
} as const;
export type ColorName = keyof typeof BASE_COLORS;
// ============================================
// 核心工具函数
// ============================================
/**
* 生成带透明度的颜色值
* @param color - 颜色名称
* @param opacity - 透明度 (0-1)
* @returns rgba 字符串
*
* @example
* alpha('gold', 0.2) => 'rgba(212, 175, 55, 0.2)'
* alpha('white', 0.5) => 'rgba(255, 255, 255, 0.5)'
*/
export function alpha(color: ColorName, opacity: number): string {
const { r, g, b } = BASE_COLORS[color];
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
}
/**
* 获取十六进制颜色值
* @param color - 颜色名称
* @returns hex 字符串
*
* @example
* hex('gold') => '#D4AF37'
*/
export function hex(color: ColorName): string {
const { r, g, b } = BASE_COLORS[color];
const toHex = (n: number) => n.toString(16).padStart(2, '0').toUpperCase();
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
// ============================================
// 预设透明度级别
// ============================================
export const OPACITY = {
/** 0.05 - 极淡背景 */
ghost: 0.05,
/** 0.08 - 微弱背景 */
faint: 0.08,
/** 0.1 - 淡背景/边框 */
subtle: 0.1,
/** 0.15 - 轻背景 */
light: 0.15,
/** 0.2 - 默认边框 */
muted: 0.2,
/** 0.3 - 标签边框 */
soft: 0.3,
/** 0.4 - 悬停边框 */
medium: 0.4,
/** 0.5 - 半透明 */
half: 0.5,
/** 0.6 - 发光边框 */
emphasis: 0.6,
/** 0.7 - 次要文字 */
secondary: 0.7,
/** 0.8 - 高可见 */
high: 0.8,
/** 0.95 - 主文字 */
primary: 0.95,
} as const;
// ============================================
// 语义化颜色生成器
// ============================================
type BorderVariant = 'subtle' | 'default' | 'hover' | 'emphasis';
type BgVariant = 'ghost' | 'subtle' | 'light' | 'medium';
type TextVariant = 'primary' | 'secondary' | 'muted' | 'dim';
type GlowSize = 'sm' | 'md' | 'lg' | 'pulse';
/**
* FUI 语义化颜色 API
* 提供直观的颜色获取方式
*/
export const fui = {
/**
* 边框颜色
* @example
* fui.border() => 'rgba(212, 175, 55, 0.2)'
* fui.border('hover') => 'rgba(212, 175, 55, 0.4)'
*/
border: (variant: BorderVariant = 'default'): string => {
const opacityMap: Record<BorderVariant, number> = {
subtle: 0.1,
default: 0.2,
hover: 0.4,
emphasis: 0.6,
};
return alpha('gold', opacityMap[variant]);
},
/**
* 背景颜色(金色系)
* @example
* fui.bg() => 'rgba(212, 175, 55, 0.1)'
* fui.bg('ghost') => 'rgba(212, 175, 55, 0.05)'
*/
bg: (variant: BgVariant = 'subtle'): string => {
const opacityMap: Record<BgVariant, number> = {
ghost: 0.05,
subtle: 0.1,
light: 0.15,
medium: 0.2,
};
return alpha('gold', opacityMap[variant]);
},
/**
* 文字颜色(白色系)
* @example
* fui.text() => 'rgba(255, 255, 255, 0.95)'
* fui.text('secondary') => 'rgba(255, 255, 255, 0.7)'
*/
text: (variant: TextVariant = 'primary'): string => {
const opacityMap: Record<TextVariant, number> = {
primary: 0.95,
secondary: 0.7,
muted: 0.5,
dim: 0.3,
};
return alpha('white', opacityMap[variant]);
},
/**
* 发光效果box-shadow 值)
* @example
* fui.glow() => '0 0 16px rgba(212, 175, 55, 0.4)'
* fui.glow('lg') => '0 0 32px rgba(212, 175, 55, 0.5)'
*/
glow: (size: GlowSize = 'md'): string => {
const sizeMap: Record<GlowSize, string> = {
sm: `0 0 8px ${alpha('gold', 0.3)}`,
md: `0 0 16px ${alpha('gold', 0.4)}`,
lg: `0 0 32px ${alpha('gold', 0.5)}`,
pulse: `0 0 20px ${alpha('gold', 0.6)}, 0 0 40px ${alpha('gold', 0.3)}`,
};
return sizeMap[size];
},
/**
* 玻璃态边框(完整 border 属性)
* @example
* fui.glassBorder() => '1px solid rgba(212, 175, 55, 0.2)'
*/
glassBorder: (variant: BorderVariant = 'default'): string => {
return `1px solid ${fui.border(variant)}`;
},
/**
* 状态颜色
*/
status: {
positive: hex('positive'), // #EF4444
negative: hex('negative'), // #22C55E
warning: hex('warning'), // #F59E0B
info: hex('info'), // #3B82F6
positiveBg: alpha('positive', 0.15),
negativeBg: alpha('negative', 0.15),
},
/**
* 金色(主色调)
*/
gold: hex('gold'), // #D4AF37
} as const;
// ============================================
// 图表主题配置
// ============================================
/**
* ECharts 图表主题配置
*/
export const chartTheme = {
// 轴线和网格线
axisLine: alpha('gold', 0.3),
splitLine: alpha('gold', 0.1),
// Tooltip
tooltip: {
bg: alpha('bgElevated', 0.95),
border: alpha('gold', 0.3),
text: alpha('white', 0.9),
},
// 标题
title: {
color: hex('gold'),
subtextColor: alpha('white', 0.6),
},
// 金色系列配色
goldSeries: [
'#D4AF37',
'#B8860B',
'#FFD700',
'#DAA520',
'#CD853F',
'#F4A460',
'#DEB887',
'#D2691E',
],
// 渐变生成器
goldGradient: (startOpacity = 0.3, endOpacity = 0.05) => ({
type: 'linear' as const,
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: alpha('gold', startOpacity) },
{ offset: 1, color: alpha('gold', endOpacity) },
],
}),
} as const;

View File

@@ -0,0 +1,15 @@
/**
* FUI 主题工具函数导出
*/
export {
// 核心工具
alpha,
hex,
fui,
BASE_COLORS,
OPACITY,
chartTheme,
// 类型
type ColorName,
} from './colorUtils';

View File

@@ -3,7 +3,6 @@
*/
import type { ComponentType, ReactNode } from 'react';
import type { IconType } from 'react-icons';
import type { LucideIcon } from 'lucide-react';
// ============================================
@@ -34,7 +33,7 @@ export interface CompanyTheme {
export interface TabConfig {
key: string;
name: string;
icon: LucideIcon | IconType | ComponentType;
icon: LucideIcon | ComponentType;
component: ComponentType<TabComponentProps>;
/** 自定义 Suspense fallback如骨架屏 */
fallback?: ReactNode;

View File

@@ -33,21 +33,21 @@ import {
useBreakpointValue,
} from '@chakra-ui/react';
import {
ChevronDownIcon,
ChevronRightIcon,
ExternalLinkIcon,
ViewIcon,
CalendarIcon,
} from '@chakra-ui/icons';
ChevronDown,
ChevronRight,
ExternalLink,
Eye,
Calendar,
} from 'lucide-react';
import {
FaChartLine,
FaArrowUp,
FaArrowDown,
FaHistory,
FaNewspaper,
FaFileAlt,
FaClock,
} from 'react-icons/fa';
LineChart,
ArrowUp,
ArrowDown,
History,
Newspaper as NewspaperIcon,
FileText,
Clock,
} from 'lucide-react';
import { keyframes } from '@emotion/react';
dayjs.locale('zh-cn');
@@ -179,13 +179,13 @@ const ConceptTimelineModal = ({
if (value > 0) {
return {
color: 'red',
icon: FaArrowUp,
icon: ArrowUp,
text: `+${value.toFixed(2)}%`
};
} else if (value < 0) {
return {
color: 'green',
icon: FaArrowDown,
icon: ArrowDown,
text: `${value.toFixed(2)}%`
};
} else {
@@ -691,7 +691,7 @@ const ConceptTimelineModal = ({
>
<HStack spacing={{ base: 2, md: 4 }} flexWrap="wrap">
<Icon
as={FaChartLine}
as={LineChart}
boxSize={{ base: 4, md: 6 }}
color="cyan.400"
/>
@@ -815,7 +815,7 @@ const ConceptTimelineModal = ({
borderColor="red.400"
flexShrink={0}
>
<Icon as={FaArrowUp} color="red.400" boxSize={{ base: 2, md: 3 }} />
<Icon as={ArrowUp} color="red.400" boxSize={{ base: 2, md: 3 }} />
<Text fontSize={{ base: 'xs', md: 'sm' }} fontWeight="medium" color="whiteAlpha.900" whiteSpace="nowrap">上涨</Text>
</HStack>
<HStack
@@ -828,7 +828,7 @@ const ConceptTimelineModal = ({
borderColor="green.400"
flexShrink={0}
>
<Icon as={FaArrowDown} color="green.400" boxSize={{ base: 2, md: 3 }} />
<Icon as={ArrowDown} color="green.400" boxSize={{ base: 2, md: 3 }} />
<Text fontSize={{ base: 'xs', md: 'sm' }} fontWeight="medium" color="whiteAlpha.900" whiteSpace="nowrap">下跌</Text>
</HStack>
<HStack
@@ -874,7 +874,7 @@ const ConceptTimelineModal = ({
borderColor="whiteAlpha.200"
>
<Icon
as={FaHistory}
as={History}
boxSize={24}
color="purple.400"
opacity={0.6}
@@ -928,7 +928,7 @@ const ConceptTimelineModal = ({
<VStack align="start" spacing={3} position="relative" zIndex={1}>
<HStack spacing={3}>
<Icon
as={CalendarIcon}
as={Calendar}
boxSize={6}
color="cyan.400"
/>
@@ -991,7 +991,7 @@ const ConceptTimelineModal = ({
borderColor="blue.500"
>
<HStack spacing={2}>
<Icon as={FaNewspaper} color="blue.400" boxSize={5} />
<Icon as={Newspaper} color="blue.400" boxSize={5} />
<Text fontWeight="bold" fontSize="lg" color="blue.300">
{selectedDateData.events.filter(e => e.type === 'news').length}
</Text>
@@ -1007,7 +1007,7 @@ const ConceptTimelineModal = ({
borderColor="green.500"
>
<HStack spacing={2}>
<Icon as={FaFileAlt} color="green.400" boxSize={5} />
<Icon as={FileText} color="green.400" boxSize={5} />
<Text fontWeight="bold" fontSize="lg" color="green.300">
{selectedDateData.events.filter(e => e.type === 'report').length}
</Text>
@@ -1109,7 +1109,7 @@ const ConceptTimelineModal = ({
<HStack spacing={4} w="100%" justify="space-between" align="center" mt={1}>
{event.time && (
<HStack spacing={1}>
<Icon as={FaClock} color="whiteAlpha.500" boxSize={3} />
<Icon as={Clock} color="whiteAlpha.500" boxSize={3} />
<Text fontSize="xs" color="whiteAlpha.500" fontWeight="medium">
{formatDateTime(event.time)}
</Text>
@@ -1120,7 +1120,7 @@ const ConceptTimelineModal = ({
size="sm"
colorScheme={event.type === 'news' ? 'blue' : 'green'}
variant="solid"
leftIcon={<ViewIcon />}
leftIcon={<Eye size={16} />}
boxShadow="sm"
_hover={{
transform: 'scale(1.05)',
@@ -1175,7 +1175,7 @@ const ConceptTimelineModal = ({
borderColor="whiteAlpha.200"
>
<Icon
as={FaHistory}
as={History}
boxSize={20}
color="purple.400"
opacity={0.6}
@@ -1286,7 +1286,7 @@ const ConceptTimelineModal = ({
size="sm"
bg="whiteAlpha.100"
color="white"
leftIcon={<ExternalLinkIcon />}
leftIcon={<ExternalLink size={16} />}
onClick={() => {
const url = formatUrl(selectedReport.content_url);
if (url) {
@@ -1379,7 +1379,7 @@ const ConceptTimelineModal = ({
size="sm"
bg="whiteAlpha.100"
color="white"
leftIcon={<ExternalLinkIcon />}
leftIcon={<ExternalLink size={16} />}
onClick={() => window.open(selectedNews.url, '_blank')}
_hover={{ bg: 'whiteAlpha.200' }}
>

View File

@@ -16,8 +16,7 @@ import {
Flex,
Tooltip,
} from '@chakra-ui/react';
import { ChevronRightIcon } from '@chakra-ui/icons';
import { FaFilter, FaTimes, FaHome } from 'react-icons/fa';
import { ChevronRight, Filter, X, Home } from 'lucide-react';
const BreadcrumbNav = ({
filter,
@@ -139,7 +138,7 @@ const BreadcrumbNav = ({
py={1}
borderRadius="full"
>
<Icon as={FaFilter} boxSize={3} />
<Icon as={Filter} boxSize={3} />
<Text fontSize="sm" fontWeight="bold">
层级筛选
</Text>
@@ -161,7 +160,7 @@ const BreadcrumbNav = ({
alignItems="center"
gap={1}
>
<Icon as={FaHome} boxSize={3} />
<Icon as={Home} boxSize={3} />
全部
</Badge>
</Tooltip>
@@ -169,7 +168,7 @@ const BreadcrumbNav = ({
{/* 面包屑路径 */}
{breadcrumbs.map((crumb, index) => (
<React.Fragment key={crumb.level}>
<Icon as={ChevronRightIcon} color={styles.chevron.color} boxSize={4} />
<Icon as={ChevronRight} color={styles.chevron.color} boxSize={4} />
<Badge
{...(isDarkMode ? {} : { colorScheme: styles.crumbBadge(crumb.level, index === breadcrumbs.length - 1).colorScheme })}
bg={isDarkMode ? styles.crumbBadge(crumb.level, index === breadcrumbs.length - 1).bg : undefined}
@@ -196,7 +195,7 @@ const BreadcrumbNav = ({
<Tooltip label="清除筛选" placement="top">
<IconButton
size="sm"
icon={<FaTimes />}
icon={<X />}
{...(isDarkMode ? {} : { colorScheme: 'red' })}
color={isDarkMode ? styles.clearBtn.color : undefined}
variant="ghost"

View File

@@ -37,14 +37,16 @@ import {
useToast,
} from '@chakra-ui/react';
import {
FaArrowUp,
FaArrowDown,
FaChartLine,
FaNewspaper,
FaRocket,
FaCrown,
} from 'react-icons/fa';
import { BsLightningFill, BsGraphUp, BsGraphDown } from 'react-icons/bs';
ArrowUp,
ArrowDown,
LineChart,
Newspaper,
Rocket,
Crown,
Zap,
TrendingUp,
TrendingDown,
} from 'lucide-react';
const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
// 获取正确的API基础URL
@@ -274,7 +276,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
const tabsData = [
{
label: '涨幅榜',
icon: FaArrowUp,
icon: ArrowUp,
color: 'red',
data: statsData.hot_concepts,
renderItem: (item, index) => (
@@ -314,7 +316,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</Badge>
{index === 0 && (
<Icon
as={FaCrown}
as={Crown}
position="absolute"
top="-8px"
right="-8px"
@@ -329,12 +331,12 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</Text>
<HStack spacing={2} fontSize="xs" color="whiteAlpha.600">
<HStack spacing={1}>
<Icon as={FaChartLine} boxSize={2.5} />
<Icon as={LineChart} boxSize={2.5} />
<Text>{item.stock_count}</Text>
</HStack>
<Text>·</Text>
<HStack spacing={1}>
<Icon as={FaNewspaper} boxSize={2.5} />
<Icon as={Newspaper} boxSize={2.5} />
<Text>{item.news_count}</Text>
</HStack>
</HStack>
@@ -349,7 +351,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
px={2}
py={1}
>
<Icon as={FaArrowUp} boxSize={2} mr={1} />
<Icon as={ArrowUp} boxSize={2} mr={1} />
{formatChange(item.change_pct)}
</Badge>
</Flex>
@@ -357,7 +359,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
},
{
label: '跌幅榜',
icon: FaArrowDown,
icon: ArrowDown,
color: 'green',
data: statsData.cold_concepts,
renderItem: (item, index) => (
@@ -400,12 +402,12 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</Text>
<HStack spacing={2} fontSize="xs" color="whiteAlpha.600">
<HStack spacing={1}>
<Icon as={FaChartLine} boxSize={2.5} />
<Icon as={LineChart} boxSize={2.5} />
<Text>{item.stock_count}</Text>
</HStack>
<Text>·</Text>
<HStack spacing={1}>
<Icon as={FaNewspaper} boxSize={2.5} />
<Icon as={Newspaper} boxSize={2.5} />
<Text>{item.news_count}</Text>
</HStack>
</HStack>
@@ -420,7 +422,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
px={2}
py={1}
>
<Icon as={FaArrowDown} boxSize={2} mr={1} />
<Icon as={ArrowDown} boxSize={2} mr={1} />
{formatChange(item.change_pct)}
</Badge>
</Flex>
@@ -428,7 +430,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
},
{
label: '波动榜',
icon: BsLightningFill,
icon: Zap,
color: 'purple',
data: statsData.volatile_concepts,
renderItem: (item, index) => (
@@ -468,7 +470,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</Badge>
{index === 0 && (
<Icon
as={BsLightningFill}
as={Zap}
position="absolute"
top="-8px"
right="-8px"
@@ -495,7 +497,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
px={2}
py={1}
>
<Icon as={BsLightningFill} boxSize={2} mr={1} />
<Icon as={Zap} boxSize={2} mr={1} />
{item.volatility?.toFixed(1)}%
</Badge>
</Flex>
@@ -503,7 +505,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
},
{
label: '连涨榜',
icon: FaRocket,
icon: Rocket,
color: 'cyan',
data: statsData.momentum_concepts,
renderItem: (item, index) => (
@@ -543,7 +545,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
</Badge>
{index === 0 && (
<Icon
as={FaRocket}
as={Rocket}
position="absolute"
top="-8px"
right="-8px"
@@ -570,7 +572,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
px={2}
py={1}
>
<Icon as={FaRocket} boxSize={2} mr={1} />
<Icon as={Rocket} boxSize={2} mr={1} />
{item.consecutive_days}
</Badge>
</Flex>
@@ -620,7 +622,7 @@ const ConceptStatsPanel = ({ apiBaseUrl, onConceptClick }) => {
<Flex justify="space-between" align="center" w="full">
<HStack spacing={2}>
<Box p={2} bg="whiteAlpha.100" borderRadius="lg" border="1px solid" borderColor="cyan.500">
<Icon as={FaChartLine} color="cyan.400" boxSize={4} />
<Icon as={LineChart} color="cyan.400" boxSize={4} />
</Box>
<VStack align="start" spacing={0}>
<Heading size="sm" color="white" fontWeight="bold">

View File

@@ -31,18 +31,18 @@ import {
} from '@chakra-ui/react';
import { keyframes } from '@emotion/react';
import {
FaLayerGroup,
FaSync,
FaExpand,
FaCompress,
FaHome,
FaArrowUp,
FaArrowDown,
FaCircle,
FaTh,
FaChevronRight,
FaArrowLeft,
} from 'react-icons/fa';
Layers,
RefreshCw,
Maximize2,
Minimize2,
Home,
ArrowUp,
ArrowDown,
Circle,
Grid3x3,
ChevronRight,
ArrowLeft,
} from 'lucide-react';
import { logger } from '../../../utils/logger';
// 极光动画 - 黑金色主题
@@ -1052,7 +1052,7 @@ const ForceGraphView = ({
borderColor="whiteAlpha.100"
>
<VStack spacing={4}>
<Icon as={FaLayerGroup} boxSize={16} color="gray.600" />
<Icon as={Layers} boxSize={16} color="gray.600" />
<Text color="gray.400">加载失败{error}</Text>
<Button
colorScheme="purple"
@@ -1078,7 +1078,7 @@ const ForceGraphView = ({
<Tooltip label="返回上一层" placement="bottom">
<IconButton
size="sm"
icon={<FaArrowLeft />}
icon={<ArrowLeft />}
onClick={handleGoBack}
bg="whiteAlpha.100"
color="white"
@@ -1104,7 +1104,7 @@ const ForceGraphView = ({
border="1px solid"
borderColor="whiteAlpha.200"
>
<Icon as={FaTh} color="purple.300" />
<Icon as={Grid3x3} color="purple.300" />
<Text color="white" fontWeight="bold" fontSize="sm">
概念矩形树图
</Text>
@@ -1123,7 +1123,7 @@ const ForceGraphView = ({
{breadcrumbItems.map((item, index) => (
<HStack key={index} spacing={2}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} />
<Icon as={ChevronRight} color="whiteAlpha.400" boxSize={3} />
)}
<Text
color={index === breadcrumbItems.length - 1 ? 'purple.300' : 'whiteAlpha.700'}
@@ -1153,7 +1153,7 @@ const ForceGraphView = ({
<Tooltip label="返回全部" placement="left">
<IconButton
size="sm"
icon={<FaHome />}
icon={<Home />}
onClick={handleGoHome}
bg="whiteAlpha.100"
color="white"
@@ -1174,7 +1174,7 @@ const ForceGraphView = ({
<Tooltip label="刷新数据" placement="left">
<IconButton
size="sm"
icon={<FaSync />}
icon={<RefreshCw />}
onClick={handleRefresh}
isLoading={priceLoading}
bg="whiteAlpha.100"
@@ -1195,7 +1195,7 @@ const ForceGraphView = ({
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'} placement="left">
<IconButton
size="sm"
icon={isFullscreen ? <FaCompress /> : <FaExpand />}
icon={isFullscreen ? <Minimize2 /> : <Maximize2 />}
onClick={toggleFullscreen}
bg="whiteAlpha.100"
color="white"

View File

@@ -27,87 +27,87 @@ import {
} from '@chakra-ui/react';
import { keyframes } from '@emotion/react';
import {
FaLayerGroup,
FaExpand,
FaCompress,
FaSync,
FaHome,
FaChevronRight,
FaBrain,
FaMicrochip,
FaRobot,
FaMobileAlt,
FaCar,
FaBolt,
FaRocket,
FaShieldAlt,
FaGlobe,
FaIndustry,
FaShoppingCart,
FaCoins,
FaHeartbeat,
FaAtom,
FaArrowUp,
FaArrowDown,
FaCubes,
FaServer,
FaCode,
FaMagic,
FaEye,
FaPlane,
FaSatellite,
FaBatteryFull,
FaSolarPanel,
FaTags,
FaExternalLinkAlt,
} from 'react-icons/fa';
Layers,
Maximize2,
Minimize2,
RefreshCw,
Home,
ChevronRight,
Brain,
Cpu,
Bot,
Smartphone,
Car,
Zap,
Rocket,
Shield,
Globe,
Factory,
ShoppingCart,
Coins,
Heart,
Atom,
ArrowUp,
ArrowDown,
Box as BoxIcon,
Server,
Code,
Sparkles,
Eye,
Plane,
Satellite,
BatteryFull,
Sun,
Tags,
ExternalLink,
} from 'lucide-react';
import { logger } from '../../../utils/logger';
// 一级分类图标映射
const LV1_ICONS = {
'人工智能': FaBrain,
'半导体': FaMicrochip,
'机器人': FaRobot,
'消费电子': FaMobileAlt,
'智能驾驶与汽车': FaCar,
'新能源与电力': FaBolt,
'空天经济': FaRocket,
'国防军工': FaShieldAlt,
'政策与主题': FaGlobe,
'周期与材料': FaIndustry,
'大消费': FaShoppingCart,
'数字经济与金融科技': FaCoins,
'全球宏观与贸易': FaGlobe,
'医药健康': FaHeartbeat,
'前沿科技': FaAtom,
'人工智能': Brain,
'半导体': Cpu,
'机器人': Bot,
'消费电子': Smartphone,
'智能驾驶与汽车': Car,
'新能源与电力': Zap,
'空天经济': Rocket,
'国防军工': Shield,
'政策与主题': Globe,
'周期与材料': Factory,
'大消费': ShoppingCart,
'数字经济与金融科技': Coins,
'全球宏观与贸易': Globe,
'医药健康': Heart,
'前沿科技': Atom,
};
// 二级分类图标映射
const LV2_ICONS = {
'AI基础设施': FaServer,
'AI模型与软件': FaCode,
'AI应用': FaMagic,
'半导体设备': FaCubes,
'半导体材料': FaAtom,
'芯片设计与制造': FaMicrochip,
'先进封装': FaCubes,
'人形机器人整机': FaRobot,
'机器人核心零部件': FaCubes,
'其他类型机器人': FaRobot,
'智能终端': FaMobileAlt,
'XR与空间计算': FaEye,
'华为产业链': FaMobileAlt,
'自动驾驶解决方案': FaCar,
'智能汽车产业链': FaCar,
'车路协同': FaCar,
'新型电池技术': FaBatteryFull,
'电力设备与电网': FaBolt,
'清洁能源': FaSolarPanel,
'低空经济': FaPlane,
'商业航天': FaSatellite,
'无人作战与信息化': FaShieldAlt,
'海军装备': FaShieldAlt,
'军贸出海': FaGlobe,
'AI基础设施': Server,
'AI模型与软件': Code,
'AI应用': Sparkles,
'半导体设备': BoxIcon,
'半导体材料': Atom,
'芯片设计与制造': Cpu,
'先进封装': BoxIcon,
'人形机器人整机': Bot,
'机器人核心零部件': BoxIcon,
'其他类型机器人': Bot,
'智能终端': Smartphone,
'XR与空间计算': Eye,
'华为产业链': Smartphone,
'自动驾驶解决方案': Car,
'智能汽车产业链': Car,
'车路协同': Car,
'新型电池技术': BatteryFull,
'电力设备与电网': Zap,
'清洁能源': Sun,
'低空经济': Plane,
'商业航天': Satellite,
'无人作战与信息化': Shield,
'海军装备': Shield,
'军贸出海': Globe,
};
// 根据涨跌幅获取背景渐变色(涨红跌绿)
@@ -151,10 +151,10 @@ const formatChangePercent = (value) => {
// 获取图标
const getIcon = (name, level) => {
if (level === 'lv1') return LV1_ICONS[name] || FaLayerGroup;
if (level === 'lv2') return LV2_ICONS[name] || FaCubes;
if (level === 'lv3') return FaCubes;
return FaTags;
if (level === 'lv1') return LV1_ICONS[name] || Layers;
if (level === 'lv2') return LV2_ICONS[name] || Box;
if (level === 'lv3') return Box;
return Tags;
};
// 从 API 返回的名称中提取纯名称
@@ -352,7 +352,7 @@ const GlassCard = ({ item, onClick, size = 'normal' }) => {
{/* 外链图标 */}
{isLeafConcept && (
<Icon
as={FaExternalLinkAlt}
as={ExternalLink}
boxSize={3}
color="whiteAlpha.500"
/>
@@ -372,7 +372,7 @@ const GlassCard = ({ item, onClick, size = 'normal' }) => {
<HStack spacing={1} align="center">
{hasChange && (isPositive || isNegative) && (
<Icon
as={isPositive ? FaArrowUp : FaArrowDown}
as={isPositive ? ArrowUp : ArrowDown}
boxSize={3}
color={getChangeTextColor(item.avg_change_pct)}
/>
@@ -766,7 +766,7 @@ const HierarchyView = ({
<Center h="400px" position="relative">
<AuroraBackground />
<VStack spacing={4} position="relative" zIndex={1}>
<Icon as={FaLayerGroup} boxSize={16} color="gray.600" />
<Icon as={Layers} boxSize={16} color="gray.600" />
<Text color="gray.400">加载失败{error}</Text>
<Button
colorScheme="purple"
@@ -787,7 +787,7 @@ const HierarchyView = ({
<Center h="400px" position="relative">
<AuroraBackground />
<VStack spacing={4} position="relative" zIndex={1}>
<Icon as={FaLayerGroup} boxSize={16} color="gray.600" />
<Icon as={Layers} boxSize={16} color="gray.600" />
<Text color="gray.400">暂无层级数据</Text>
</VStack>
</Center>
@@ -832,14 +832,14 @@ const HierarchyView = ({
{breadcrumbs.map((crumb, index) => (
<React.Fragment key={index}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} mx={1} />
<Icon as={ChevronRight} color="whiteAlpha.400" boxSize={3} mx={1} />
)}
<Button
size="sm"
variant="ghost"
bg={index === breadcrumbs.length - 1 ? 'purple.500' : 'transparent'}
color={index === breadcrumbs.length - 1 ? 'white' : 'whiteAlpha.700'}
leftIcon={index === 0 ? <FaHome /> : undefined}
leftIcon={index === 0 ? <Home /> : undefined}
onClick={() => handleBreadcrumbClick(crumb, index)}
isDisabled={index === breadcrumbs.length - 1}
fontWeight={index === breadcrumbs.length - 1 ? 'bold' : 'medium'}
@@ -861,7 +861,7 @@ const HierarchyView = ({
<Tooltip label="刷新涨跌幅" placement="top">
<IconButton
size="sm"
icon={<FaSync />}
icon={<RefreshCw />}
onClick={handleRefreshPrice}
isLoading={priceLoading}
bg="whiteAlpha.100"
@@ -876,7 +876,7 @@ const HierarchyView = ({
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'} placement="top">
<IconButton
size="sm"
icon={isFullscreen ? <FaCompress /> : <FaExpand />}
icon={isFullscreen ? <Minimize2 /> : <Maximize2 />}
onClick={toggleFullscreen}
bg="whiteAlpha.100"
color="white"

View File

@@ -79,9 +79,43 @@ import {
Collapse,
useBreakpointValue,
} from '@chakra-ui/react';
import { SearchIcon, ViewIcon, CalendarIcon, ExternalLinkIcon, StarIcon, ChevronDownIcon, InfoIcon, CloseIcon, ChevronRightIcon } from '@chakra-ui/icons';
import { FaThLarge, FaList, FaTags, FaChartLine, FaRobot, FaTable, FaHistory, FaBrain, FaLightbulb, FaRocket, FaShieldAlt, FaCalendarAlt, FaArrowUp, FaArrowDown, FaNewspaper, FaFileAlt, FaExpand, FaCompress, FaClock, FaLock, FaSitemap, FaLayerGroup, FaCube, FaProjectDiagram } from 'react-icons/fa';
import { BsGraphUp, BsLightningFill } from 'react-icons/bs';
import {
Search,
Eye,
Calendar,
ExternalLink,
Star,
ChevronDown,
Info,
X,
ChevronRight,
LayoutGrid,
List,
Tags,
LineChart,
Bot,
Table2,
History,
Brain,
Lightbulb,
Rocket,
Shield,
CalendarDays,
ArrowUp,
ArrowDown,
Newspaper,
FileText,
Maximize2,
Minimize2,
Clock,
Lock,
GitBranch,
Layers,
Box as BoxIcon,
Network,
TrendingUp,
Zap,
} from 'lucide-react';
import { keyframes } from '@emotion/react';
import ConceptTimelineModal from './ConceptTimelineModal';
import ConceptStatsPanel from './components/ConceptStatsPanel';
@@ -769,7 +803,7 @@ const ConceptCenter = () => {
return (
<HStack spacing={2}>
<Icon as={CalendarIcon} boxSize={3} color="blue.500" />
<Icon as={Calendar} boxSize={3} color="blue.500" />
<Text fontSize="xs" color="gray.600" fontWeight="medium">
添加于 {new Date(addedDate).toLocaleDateString('zh-CN')}
</Text>
@@ -1021,7 +1055,7 @@ const ConceptCenter = () => {
<Flex align="center" justify="space-between">
<Box flex={1}>
<HStack spacing={2} mb={{ base: 1, md: 2 }}>
<Icon as={FaChartLine} boxSize={3} color="purple.300" />
<Icon as={LineChart} boxSize={3} color="purple.300" />
<Text fontSize="xs" color="purple.200" fontWeight="bold">
热门个股
</Text>
@@ -1068,7 +1102,7 @@ const ConceptCenter = () => {
</>
) : (
<HStack spacing={1}>
<Icon as={FaLock} boxSize="10px" color="yellow.400" />
<Icon as={Lock} boxSize="10px" color="yellow.400" />
<Text fontSize="xs" color="yellow.400" fontWeight="medium">
升级查看{concept.stocks.length}只个股
</Text>
@@ -1077,7 +1111,7 @@ const ConceptCenter = () => {
</HStack>
</Box>
<Icon
as={hasFeatureAccess('hot_stocks') ? ChevronRightIcon : FaLock}
as={hasFeatureAccess('hot_stocks') ? ChevronRight : FaLock}
color={hasFeatureAccess('hot_stocks') ? 'purple.300' : 'yellow.400'}
boxSize={4}
/>
@@ -1097,7 +1131,7 @@ const ConceptCenter = () => {
if (latestOutbreak) {
return (
<HStack spacing={2}>
<Icon as={BsLightningFill} boxSize={3} color="orange.400" />
<Icon as={Zap} boxSize={3} color="orange.400" />
<Text fontSize="xs" color="orange.300" fontWeight="medium">
爆发于 {new Date(latestOutbreak).toLocaleDateString('zh-CN')}
</Text>
@@ -1106,7 +1140,7 @@ const ConceptCenter = () => {
} else if (addedDate) {
return (
<HStack spacing={2}>
<Icon as={CalendarIcon} boxSize={3} color="cyan.400" />
<Icon as={Calendar} boxSize={3} color="cyan.400" />
<Text fontSize="xs" color="whiteAlpha.600" fontWeight="medium">
添加于 {new Date(addedDate).toLocaleDateString('zh-CN')}
</Text>
@@ -1202,7 +1236,7 @@ const ConceptCenter = () => {
border="1px solid"
borderColor="whiteAlpha.100"
>
<Icon as={FaTags} boxSize={{ base: 6, md: 8 }} color="white" opacity={0.8} />
<Icon as={Tags} boxSize={{ base: 6, md: 8 }} color="white" opacity={0.8} />
{hasChange && (
<Badge
position="absolute"
@@ -1247,7 +1281,7 @@ const ConceptCenter = () => {
_hover={{ color: 'purple.300' }}
transition="color 0.2s"
>
<Icon as={FaChartLine} boxSize={4} color="purple.300" />
<Icon as={LineChart} boxSize={4} color="purple.300" />
<Text fontSize="sm" fontWeight="medium" color="whiteAlpha.800" _groupHover={{ color: 'purple.300' }}>
{concept.stock_count || 0} 只股票
</Text>
@@ -1255,7 +1289,7 @@ const ConceptCenter = () => {
{hasChange && concept.price_info?.trade_date && (
<HStack spacing={1}>
<Icon as={FaCalendarAlt} boxSize={4} color="cyan.400" />
<Icon as={CalendarDays} boxSize={4} color="cyan.400" />
<Text fontSize="sm" color="whiteAlpha.600">
{new Date(concept.price_info.trade_date).toLocaleDateString('zh-CN')}
</Text>
@@ -1270,7 +1304,7 @@ const ConceptCenter = () => {
if (latestOutbreak) {
return (
<HStack spacing={1}>
<Icon as={BsLightningFill} boxSize={4} color="orange.400" />
<Icon as={Zap} boxSize={4} color="orange.400" />
<Text fontSize="sm" color="orange.300" fontWeight="medium">
爆发于 {new Date(latestOutbreak).toLocaleDateString('zh-CN')}
</Text>
@@ -1279,7 +1313,7 @@ const ConceptCenter = () => {
} else if (addedDate) {
return (
<HStack spacing={1}>
<Icon as={CalendarIcon} boxSize={4} color="cyan.400" />
<Icon as={Calendar} boxSize={4} color="cyan.400" />
<Text fontSize="sm" color="whiteAlpha.600">
添加于 {new Date(addedDate).toLocaleDateString('zh-CN')}
</Text>
@@ -1297,7 +1331,7 @@ const ConceptCenter = () => {
<HStack spacing={3}>
<Button
size="sm"
leftIcon={<ViewIcon />}
leftIcon={<Eye size={16} />}
bg="whiteAlpha.100"
color="white"
border="1px solid"
@@ -1373,7 +1407,7 @@ const ConceptCenter = () => {
) : (
<WrapItem>
<HStack spacing={1}>
<Icon as={FaLock} boxSize="8px" color="yellow.400" />
<Icon as={Lock} boxSize="8px" color="yellow.400" />
<Text fontSize="xs" color="yellow.400" fontWeight="medium">
升级查看{concept.stocks.length}
</Text>
@@ -1518,7 +1552,7 @@ const ConceptCenter = () => {
_hover={{ opacity: 1 }}
transition="opacity 0.2s"
>
<Icon as={InfoIcon} color="blue.300" boxSize={3} />
<Icon as={Info} color="blue.300" boxSize={3} />
<Text fontSize="xs" color="blue.200">
数据更新至 {latestTradeDate.toLocaleDateString('zh-CN')}
</Text>
@@ -1585,7 +1619,7 @@ const ConceptCenter = () => {
{/* 标题区域 */}
<VStack spacing={3} textAlign="center">
<HStack spacing={3} justify="center">
<Icon as={FaBrain} boxSize={10} color="cyan.300" filter="drop-shadow(0 0 10px rgba(6, 182, 212, 0.5))" />
<Icon as={Brain} boxSize={10} color="cyan.300" filter="drop-shadow(0 0 10px rgba(6, 182, 212, 0.5))" />
</HStack>
<VStack spacing={1}>
@@ -1601,7 +1635,7 @@ const ConceptCenter = () => {
概念中心
</Heading>
<HStack spacing={2} justify="center">
<Icon as={FaClock} boxSize={3} color="cyan.200" />
<Icon as={Clock} boxSize={3} color="cyan.200" />
<Text fontSize="xs" fontWeight="medium" opacity={0.8}>
数据约下午4点更新
</Text>
@@ -1627,21 +1661,21 @@ const ConceptCenter = () => {
boxShadow="0 8px 32px rgba(0, 0, 0, 0.3)"
>
<HStack spacing={2}>
<Icon as={FaTags} boxSize={4} color="cyan.300" />
<Icon as={Tags} boxSize={4} color="cyan.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="cyan.300">500+</Text>
<Text fontSize="xs" opacity={0.7}>概念板块</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={FaChartLine} boxSize={4} color="purple.300" />
<Icon as={LineChart} boxSize={4} color="purple.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="purple.300">5000+</Text>
<Text fontSize="xs" opacity={0.7}>相关个股</Text>
</VStack>
</HStack>
<HStack spacing={2}>
<Icon as={BsLightningFill} boxSize={4} color="yellow.300" />
<Icon as={Zap} boxSize={4} color="yellow.300" />
<VStack spacing={0} align="start">
<Text fontSize="xl" fontWeight="bold" color="yellow.300">24/7</Text>
<Text fontSize="xs" opacity={0.7}>实时监控</Text>
@@ -1668,7 +1702,7 @@ const ConceptCenter = () => {
>
<InputGroup size="lg" flex={1}>
<InputLeftElement pointerEvents="none" h="full">
<Icon as={SearchIcon} color="purple.400" boxSize={5} />
<Icon as={Search} color="purple.400" boxSize={5} />
</InputLeftElement>
<Input
placeholder="搜索概念板块、个股、关键词..."
@@ -1696,7 +1730,7 @@ const ConceptCenter = () => {
transform="translateY(-50%)"
size="sm"
aria-label="清除搜索"
icon={<CloseIcon />}
icon={<X size={16} />}
variant="ghost"
color="gray.500"
borderRadius="full"
@@ -1711,7 +1745,7 @@ const ConceptCenter = () => {
borderRadius="0 50px 50px 0"
bgGradient="linear(135deg, #667eea 0%, #764ba2 100%)"
color="white"
leftIcon={<SearchIcon />}
leftIcon={<Search size={16} />}
_hover={{
bgGradient: 'linear(135deg, #5568d3 0%, #663a8e 100%)',
transform: 'scale(1.02)',
@@ -1777,7 +1811,7 @@ const ConceptCenter = () => {
{/* 排序方式 - 仅在列表视图显示 */}
{viewMode === 'list' && (
<HStack spacing={4} align="center">
<Icon as={FaTags} boxSize={4} color="purple.300" />
<Icon as={Tags} boxSize={4} color="purple.300" />
<Text fontWeight="bold" color="white">排序方式</Text>
<Select
value={sortBy}
@@ -1812,7 +1846,7 @@ const ConceptCenter = () => {
borderRadius="full"
boxShadow="0 0 10px rgba(59, 130, 246, 0.4)"
>
<Icon as={InfoIcon} color="white" boxSize={3} />
<Icon as={Info} color="white" boxSize={3} />
<Text fontSize="xs" color="white" fontWeight="medium">
智能排序
</Text>
@@ -1896,7 +1930,7 @@ const ConceptCenter = () => {
{selectedDate && viewMode !== 'hierarchy' && viewMode !== 'force3d' && (
<Box mb={4} p={3} bg="rgba(59, 130, 246, 0.2)" borderRadius="xl" borderLeft="4px solid" borderColor="blue.400">
<HStack>
<Icon as={InfoIcon} color="blue.300" />
<Icon as={Info} color="blue.300" />
<Text fontSize="sm" color="whiteAlpha.800">
当前显示 <Text as="strong" color="cyan.300">{selectedDate.toLocaleDateString('zh-CN')}</Text>
{searchQuery && <span>搜索词<Text as="strong" color="cyan.300">"{searchQuery}"</Text></span>}
@@ -2030,7 +2064,7 @@ const ConceptCenter = () => {
) : viewMode !== 'hierarchy' && viewMode !== 'force3d' ? (
<Center h="400px">
<VStack spacing={6}>
<Icon as={FaTags} boxSize={20} color="whiteAlpha.300" />
<Icon as={Tags} boxSize={20} color="whiteAlpha.300" />
<VStack spacing={2}>
<Text fontSize="xl" color="white" fontWeight="medium">暂无概念数据</Text>
<Text color="whiteAlpha.600">
@@ -2075,7 +2109,7 @@ const ConceptCenter = () => {
>
<CardBody p={6}>
<VStack spacing={4} textAlign="center">
<Icon as={FaChartLine} boxSize={12} color="whiteAlpha.300" />
<Icon as={LineChart} boxSize={12} color="whiteAlpha.300" />
<VStack spacing={2}>
<Heading size="md" color="white">
概念统计中心
@@ -2087,7 +2121,7 @@ const ConceptCenter = () => {
<Button
bg="blue.500"
color="white"
leftIcon={<Icon as={FaRocket} />}
leftIcon={<Icon as={Rocket} />}
onClick={() => {
setUpgradeFeature('pro');
setUpgradeModalOpen(true);

View File

@@ -12,11 +12,11 @@ import {
} from '@chakra-ui/react';
import { init, dispose } from 'klinecharts';
import {
FaExpand,
FaCompress,
FaCamera,
FaRedo,
} from 'react-icons/fa';
Maximize,
Minimize,
Camera,
RotateCcw,
} from 'lucide-react';
import { MetricDataPoint } from '@services/categoryService';
// 黑金主题配色
@@ -265,7 +265,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={handleReset}
>
<Icon as={FaRedo} />
<Icon as={RotateCcw} />
</Button>
</Tooltip>
<Tooltip label="截图">
@@ -276,7 +276,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={handleScreenshot}
>
<Icon as={FaCamera} />
<Icon as={Camera} />
</Button>
</Tooltip>
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
@@ -287,7 +287,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={toggleFullscreen}
>
<Icon as={isFullscreen ? FaCompress : FaExpand} />
<Icon as={isFullscreen ? Minimize : Maximize} />
</Button>
</Tooltip>
</HStack>

View File

@@ -29,7 +29,7 @@ import {
Input,
useToast,
} from '@chakra-ui/react';
import { FaTable, FaChartLine, FaCalendar, FaDownload } from 'react-icons/fa';
import { Table2, LineChart, Calendar, Download } from 'lucide-react';
import { fetchMetricData, MetricDataResponse, TreeMetric } from '@services/categoryService';
import SimpleLineChart from './SimpleLineChart';
@@ -182,7 +182,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
>
<HStack spacing={4} wrap="wrap">
<HStack flex="1" minW="200px">
<Icon as={FaCalendar} color={themeColors.text.muted} />
<Icon as={Calendar} color={themeColors.text.muted} />
<Input
type="date"
size="sm"
@@ -235,7 +235,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
variant="outline"
borderColor={themeColors.border.gold}
color={themeColors.text.gold}
leftIcon={<FaDownload />}
leftIcon={<Download />}
onClick={handleExportCSV}
isDisabled={!metricData || !metricData.data || metricData.data.length === 0}
>
@@ -260,7 +260,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
bg: themeColors.bg.card,
}}
>
<Icon as={FaChartLine} mr={2} />
<Icon as={LineChart} mr={2} />
线
</Tab>
<Tab
@@ -271,7 +271,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
bg: themeColors.bg.card,
}}
>
<Icon as={FaTable} mr={2} />
<Icon as={Table2} mr={2} />
</Tab>
</TabList>

View File

@@ -11,11 +11,11 @@ import {
Tooltip,
} from '@chakra-ui/react';
import {
FaExpand,
FaCompress,
FaCamera,
FaRedo,
} from 'react-icons/fa';
Maximize,
Minimize,
Camera,
RotateCcw,
} from 'lucide-react';
import { MetricDataPoint } from '@services/categoryService';
// 黑金主题配色
@@ -386,7 +386,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={handleReset}
>
<Icon as={FaRedo} />
<Icon as={RotateCcw} />
</Button>
</Tooltip>
<Tooltip label="截图">
@@ -397,7 +397,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={handleScreenshot}
>
<Icon as={FaCamera} />
<Icon as={Camera} />
</Button>
</Tooltip>
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
@@ -408,7 +408,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
_hover={{ color: themeColors.primary.gold }}
onClick={toggleFullscreen}
>
<Icon as={isFullscreen ? FaCompress : FaExpand} />
<Icon as={isFullscreen ? Minimize : Maximize} />
</Button>
</Tooltip>
</HStack>

View File

@@ -21,17 +21,17 @@ import {
useDisclosure,
} from '@chakra-ui/react';
import {
FaDatabase,
FaFolder,
FaFolderOpen,
FaFile,
FaSearch,
FaHome,
FaChevronRight,
FaChevronDown,
FaTimes,
FaEye,
} from 'react-icons/fa';
Database,
Folder,
FolderOpen,
File,
Search,
Home,
ChevronRight,
ChevronDown,
X,
Eye,
} from 'lucide-react';
import { motion } from 'framer-motion';
import {
fetchCategoryTree,
@@ -126,7 +126,7 @@ const TreeNodeComponent: React.FC<{
<Spinner size="xs" color={themeColors.primary.gold} mr={2} />
) : hasChildren || !hasMetrics ? (
<Icon
as={isExpanded ? FaChevronDown : FaChevronRight}
as={isExpanded ? ChevronDown : ChevronRight}
color={themeColors.text.muted}
mr={2}
fontSize="xs"
@@ -136,7 +136,7 @@ const TreeNodeComponent: React.FC<{
)}
<Icon
as={hasChildren || !hasMetrics ? (isExpanded ? FaFolderOpen : FaFolder) : FaFile}
as={hasChildren || !hasMetrics ? (isExpanded ? FolderOpen : Folder) : File}
color={hasChildren || !hasMetrics ? themeColors.primary.gold : themeColors.text.secondary}
mr={2}
/>
@@ -244,7 +244,7 @@ const MetricCard: React.FC<{ metric: TreeMetric; onClick: () => void }> = ({ met
size="xs"
variant="ghost"
color={themeColors.primary.gold}
leftIcon={<FaEye />}
leftIcon={<Eye />}
_hover={{ bg: themeColors.bg.cardHover }}
>
@@ -489,7 +489,7 @@ const DataBrowser: React.FC = () => {
>
<VStack spacing={4} align="stretch" mb={8}>
<HStack spacing={4}>
<Icon as={FaDatabase} color={themeColors.primary.gold} boxSize={8} />
<Icon as={Database} color={themeColors.primary.gold} boxSize={8} />
<VStack align="start" spacing={0}>
<Text
fontSize="3xl"
@@ -568,7 +568,7 @@ const DataBrowser: React.FC = () => {
}}
/>
<Button
leftIcon={<FaSearch />}
leftIcon={<Search />}
bg={themeColors.primary.gold}
color={themeColors.bg.primary}
_hover={{ bg: themeColors.primary.goldLight }}
@@ -579,7 +579,7 @@ const DataBrowser: React.FC = () => {
</Button>
{searchQuery && (
<Button
leftIcon={<FaTimes />}
leftIcon={<X />}
variant="ghost"
color={themeColors.text.secondary}
_hover={{ color: themeColors.text.primary }}
@@ -625,7 +625,7 @@ const DataBrowser: React.FC = () => {
<CardBody py={2}>
<Breadcrumb
spacing={2}
separator={<Icon as={FaChevronRight} color={themeColors.text.muted} />}
separator={<Icon as={ChevronRight} color={themeColors.text.muted} />}
>
<BreadcrumbItem>
<BreadcrumbLink
@@ -633,7 +633,7 @@ const DataBrowser: React.FC = () => {
_hover={{ color: themeColors.primary.gold }}
onClick={() => handleBreadcrumbClick(-1)}
>
<Icon as={FaHome} />
<Icon as={Home} />
</BreadcrumbLink>
</BreadcrumbItem>
{breadcrumbs.map((crumb, index) => (
@@ -754,7 +754,7 @@ const DataBrowser: React.FC = () => {
) : searchResults ? (
<Flex justify="center" align="center" py={10}>
<VStack spacing={3}>
<Icon as={FaSearch} color={themeColors.text.muted} boxSize={12} />
<Icon as={Search} color={themeColors.text.muted} boxSize={12} />
<Text color={themeColors.text.muted}></Text>
<Text color={themeColors.text.muted} fontSize="sm">
使
@@ -837,7 +837,7 @@ const DataBrowser: React.FC = () => {
) : (
<Flex justify="center" align="center" py={10}>
<VStack spacing={3}>
<Icon as={FaFolder} color={themeColors.text.muted} boxSize={12} />
<Icon as={Folder} color={themeColors.text.muted} boxSize={12} />
<Text color={themeColors.text.muted}>
{currentNode.children && currentNode.children.length > 0
? '该节点包含子分类,请展开查看'
@@ -850,7 +850,7 @@ const DataBrowser: React.FC = () => {
) : (
<Flex justify="center" align="center" py={20}>
<VStack spacing={4}>
<Icon as={FaDatabase} color={themeColors.primary.gold} boxSize={16} />
<Icon as={Database} color={themeColors.primary.gold} boxSize={16} />
<Text color={themeColors.text.secondary} fontSize="lg" textAlign="center">
</Text>

View File

@@ -25,15 +25,14 @@ import {
StatArrow
} from '@chakra-ui/react';
import {
FaHeart,
FaRegHeart,
FaEye,
FaComment,
FaUsers,
FaClock,
FaCalendarAlt,
FaChartLine
} from 'react-icons/fa';
Heart,
Eye,
MessageCircle,
Users,
Clock,
Calendar,
LineChart
} from 'lucide-react';
const EventHeader = ({ event, onFollowToggle }) => {
// 颜色主题
@@ -174,7 +173,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
</HStack>
<HStack spacing={3}>
<Icon as={FaCalendarAlt} color={textSecondary} />
<Icon as={Calendar} color={textSecondary} />
<VStack align="flex-start" spacing={0}>
<Text fontSize="sm" color={textPrimary}>
{formatDate(event.created_at)}
@@ -190,7 +189,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
{/* 右侧关注按钮 */}
<Flex align="flex-start" justify="center">
<Button
leftIcon={<Icon as={event.is_following ? FaHeart : FaRegHeart} />}
leftIcon={<Icon as={Heart} fill={event.is_following ? "currentColor" : "none"} />}
colorScheme={event.is_following ? "red" : "blue"}
variant={event.is_following ? "solid" : "outline"}
size="lg"
@@ -226,7 +225,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
>
<StatLabel fontSize="xs" color={textSecondary}>
<HStack justify="center" spacing={1}>
<Icon as={FaEye} />
<Icon as={Eye} />
<Text>浏览量</Text>
</HStack>
</StatLabel>
@@ -246,7 +245,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
>
<StatLabel fontSize="xs" color={textSecondary}>
<HStack justify="center" spacing={1}>
<Icon as={FaComment} />
<Icon as={MessageCircle} />
<Text>回复数</Text>
</HStack>
</StatLabel>
@@ -266,7 +265,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
>
<StatLabel fontSize="xs" color={textSecondary}>
<HStack justify="center" spacing={1}>
<Icon as={FaUsers} />
<Icon as={Users} />
<Text>关注数</Text>
</HStack>
</StatLabel>
@@ -286,7 +285,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
>
<StatLabel fontSize="xs" color={textSecondary}>
<HStack justify="center" spacing={1}>
<Icon as={FaChartLine} />
<Icon as={LineChart} />
<Text>热度分</Text>
</HStack>
</StatLabel>

View File

@@ -27,9 +27,9 @@ import {
Tooltip
} from '@chakra-ui/react';
import {
FaChartLine,
FaInfoCircle
} from 'react-icons/fa';
LineChart,
Info
} from 'lucide-react';
import { Tag } from 'antd';
import { RobotOutlined } from '@ant-design/icons';
import { stockService } from '@services/eventService';
@@ -230,7 +230,7 @@ const HistoricalEvents = ({
borderRadius="md"
>
<HStack spacing={3}>
<Icon as={FaChartLine} color="yellow.600" boxSize="20px" />
<Icon as={LineChart} color="yellow.600" boxSize="20px" />
<VStack align="flex-start" spacing={1}>
<Text fontSize="sm" fontWeight="bold" color="yellow.800">
超预期得分: {expectationScore}
@@ -306,7 +306,7 @@ const HistoricalEvents = ({
{/* 右侧:相关股票按钮 */}
<Button
size="sm"
leftIcon={<Icon as={FaChartLine} />}
leftIcon={<Icon as={LineChart} boxSize={4} />}
onClick={(e) => {
e.stopPropagation();
handleViewStocks(event);
@@ -467,7 +467,7 @@ const StocksList = ({ stocks, eventTradingDate }) => {
if (!stocks || stocks.length === 0) {
return (
<Box textAlign="center" py={12} color={textSecondary}>
<Icon as={FaInfoCircle} boxSize="48px" mb={4} />
<Icon as={Info} boxSize="48px" mb={4} />
<Text fontSize="lg" mb={2}>暂无相关股票数据</Text>
<Text fontSize="sm">该历史事件暂未关联股票信息</Text>
</Box>
@@ -533,7 +533,7 @@ const StocksList = ({ stocks, eventTradingDate }) => {
variant="ghost"
colorScheme={stock.event_day_change_pct > 0 ? 'red' : stock.event_day_change_pct < 0 ? 'green' : 'gray'}
onClick={() => handleOpenKLine(stock)}
rightIcon={<Icon as={FaChartLine} boxSize={3} />}
rightIcon={<Icon as={LineChart} boxSize={3} />}
px={2}
>
<Text

View File

@@ -42,15 +42,15 @@ import {
Container,
} from '@chakra-ui/react';
import {
FiTrendingUp,
FiBarChart2,
FiPieChart,
FiActivity,
FiDownload,
FiCalendar,
FiTarget,
FiZap,
} from 'react-icons/fi';
TrendingUp,
BarChart2,
PieChart,
Activity,
Download,
Calendar,
Target,
Zap,
} from 'lucide-react';
import 'echarts-wordcloud';
// 导入现有的卡片组件
@@ -484,7 +484,7 @@ const LimitAnalyse = () => {
<HStack justify="space-between" align="center">
<VStack align="start" spacing={2}>
<HStack spacing={3}>
<Icon as={FiTrendingUp} color="blue.500" boxSize={6} />
<Icon as={TrendingUp} color="blue.500" boxSize={6} />
<Text fontSize="xl" fontWeight="bold">
涨停分析
</Text>
@@ -508,7 +508,7 @@ const LimitAnalyse = () => {
))}
</Select>
<Button
leftIcon={<FiDownload />}
leftIcon={<Icon as={Download} boxSize={4} />}
colorScheme="blue"
variant="outline"
onClick={() => handleExport('excel')}
@@ -536,7 +536,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiPieChart} color="blue.500" boxSize={5} />
<Icon as={PieChart} color="blue.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
板块分布
</Text>
@@ -564,7 +564,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiBarChart2} color="green.500" boxSize={5} />
<Icon as={BarChart2} color="green.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
板块股票数量
</Text>
@@ -592,7 +592,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiPieChart} color="purple.500" boxSize={5} />
<Icon as={PieChart} color="purple.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
板块关联TOP10
</Text>
@@ -637,7 +637,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiPieChart} color="purple.500" boxSize={5} />
<Icon as={PieChart} color="purple.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
板块关联关系图
</Text>
@@ -670,7 +670,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiActivity} color="orange.500" boxSize={5} />
<Icon as={Activity} color="orange.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
热点词云
</Text>
@@ -691,7 +691,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiActivity} color="purple.500" boxSize={5} />
<Icon as={Activity} color="purple.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
数据统计
</Text>
@@ -700,25 +700,25 @@ const LimitAnalyse = () => {
<CardBody>
<Grid templateColumns="repeat(auto-fit, minmax(200px, 1fr))" gap={4}>
<StatCard
icon={FiTarget}
icon={Target}
label="涨停股票总数"
value={totalStocks}
color="blue"
/>
<StatCard
icon={FiBarChart2}
icon={BarChart2}
label="涉及板块数"
value={sectorCount}
color="green"
/>
<StatCard
icon={FiTrendingUp}
icon={TrendingUp}
label="平均涨幅"
value={`${avgChange}%`}
color="orange"
/>
<StatCard
icon={FiZap}
icon={Zap}
label="最大涨幅"
value={`${maxChange}%`}
color="red"
@@ -735,7 +735,7 @@ const LimitAnalyse = () => {
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
<CardHeader>
<HStack spacing={3}>
<Icon as={FiBarChart2} color="teal.500" boxSize={5} />
<Icon as={BarChart2} color="teal.500" boxSize={5} />
<Text fontSize="lg" fontWeight="bold">
板块详细数据
</Text>

View File

@@ -29,7 +29,7 @@ import {
Center,
Divider
} from '@chakra-ui/react';
import { FaEye, FaExternalLinkAlt, FaChartLine, FaCalendarAlt } from 'react-icons/fa';
import { Eye, ExternalLink, LineChart, Calendar } from 'lucide-react';
import dayjs from 'dayjs';
import tradingDayUtils from '../../../utils/tradingDayUtils'; // 引入交易日工具
import { logger } from '../../../utils/logger';
@@ -230,7 +230,7 @@ const ConceptCard = ({ concept, tradingDate, onViewDetails }) => {
<Button
size="sm"
colorScheme="blue"
leftIcon={<FaChartLine />}
leftIcon={<Icon as={LineChart} boxSize={4} />}
flex={1}
onClick={(e) => {
e.stopPropagation();
@@ -243,7 +243,7 @@ const ConceptCard = ({ concept, tradingDate, onViewDetails }) => {
size="sm"
variant="outline"
colorScheme="blue"
leftIcon={<FaEye />}
leftIcon={<Icon as={Eye} boxSize={4} />}
flex={1}
onClick={(e) => {
e.stopPropagation();
@@ -532,7 +532,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
<Button
colorScheme="blue"
size="lg"
leftIcon={<FaChartLine />}
leftIcon={<Icon as={LineChart} boxSize={5} />}
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
>
进入概念中心
@@ -547,7 +547,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
{effectiveTradingDate && (
<Box mb={4} p={3} bg={bgColor} borderRadius="md">
<HStack spacing={2}>
<FaCalendarAlt color={textColor} />
<Icon as={Calendar} color={textColor} boxSize={4} />
<Text fontSize="sm" color={textColor}>
涨跌幅数据日期{effectiveTradingDate}
{eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && (
@@ -578,7 +578,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
<Button
colorScheme="blue"
size="lg"
leftIcon={<FaChartLine />}
leftIcon={<Icon as={LineChart} boxSize={5} />}
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
px={8}
py={6}
@@ -641,7 +641,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
{selectedConcept?.description && (
<Box>
<HStack mb={3}>
<Icon as={FaChartLine} color="blue.500" />
<Icon as={LineChart} color="blue.500" />
<Text fontSize="md" fontWeight="bold">
概念解析
</Text>
@@ -666,7 +666,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
{selectedConcept?.happened_times && selectedConcept.happened_times.length > 0 && (
<Box>
<HStack mb={3}>
<Icon as={FaCalendarAlt} color="purple.500" />
<Icon as={Calendar} color="purple.500" />
<Text fontSize="md" fontWeight="bold">
历史触发时间
</Text>
@@ -691,7 +691,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
{selectedConcept?.stocks && selectedConcept.stocks.length > 0 && (
<Box>
<HStack mb={3}>
<Icon as={FaEye} color="green.500" />
<Icon as={Eye} color="green.500" />
<Text fontSize="md" fontWeight="bold">
核心相关股票 ({selectedConcept.stock_count})
</Text>
@@ -760,7 +760,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
onClick={() => {
window.open(`https://valuefrontier.cn/htmls/${encodeURIComponent(selectedConcept.concept)}.html`, '_blank');
}}
leftIcon={<FaExternalLinkAlt />}
leftIcon={<Icon as={ExternalLink} boxSize={4} />}
>
查看概念详情页
</Button>

View File

@@ -41,12 +41,12 @@ import {
useToast
} from '@chakra-ui/react';
import {
FaPlus,
FaTrash,
FaChartLine,
FaRedo,
FaSearch
} from 'react-icons/fa';
Plus,
Trash2,
LineChart,
RefreshCw,
Search
} from 'lucide-react';
import { echarts } from '@lib/echarts';
import StockChartModal from '../../../components/StockChart/StockChartModal';
@@ -297,7 +297,7 @@ const RelatedStocks = ({
<Flex mb={4} align="center" wrap="wrap" gap={4}>
{/* 搜索框 */}
<HStack>
<FaSearch />
<Icon as={Search} boxSize={4} />
<Input
placeholder="搜索股票代码或名称..."
value={searchTerm}
@@ -313,7 +313,7 @@ const RelatedStocks = ({
<HStack>
<Tooltip label="刷新报价">
<IconButton
icon={<FaRedo />}
icon={<Icon as={RefreshCw} boxSize={4} />}
size="sm"
onClick={handleRefreshQuotes}
isLoading={quotesLoading}
@@ -487,7 +487,7 @@ const RelatedStocks = ({
<Tooltip label="查看K线图">
<IconButton
icon={<FaChartLine />}
icon={<Icon as={LineChart} boxSize={3} />}
size="xs"
onClick={() => handleShowChart(stock)}
aria-label="查看K线图"
@@ -496,7 +496,7 @@ const RelatedStocks = ({
<Tooltip label="删除">
<IconButton
icon={<FaTrash />}
icon={<Icon as={Trash2} boxSize={3} />}
size="xs"
colorScheme="red"
variant="ghost"

View File

@@ -32,8 +32,7 @@ import {
Tooltip,
Center
} from '@chakra-ui/react';
import { InfoIcon, ViewIcon } from '@chakra-ui/icons';
import { Share2, GitBranch, Inbox } from 'lucide-react';
import { Info, Eye, Share2, GitBranch, Inbox } from 'lucide-react';
import ReactECharts from 'echarts-for-react';
import { eventService } from '../../../services/eventService';
import CitedContent from '../../../components/Citation/CitedContent';
@@ -875,7 +874,7 @@ const TransmissionChainAnalysis = ({ eventId }) => {
py={1}
borderRadius="md"
>
<Icon as={ViewIcon} mr={1} boxSize={3} />
<Eye size={12} style={{ display: 'inline', marginRight: '4px' }} />
点击节点查看详情
</Text>
{chartReady && (

View File

@@ -37,7 +37,7 @@ import {
useColorModeValue,
} from '@chakra-ui/react';
import { getFormattedTextProps } from '../../../utils/textUtils';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { ExternalLink } from 'lucide-react';
import RiskDisclaimer from '../../../components/RiskDisclaimer';
import ReactECharts from 'echarts-for-react';
import 'echarts-wordcloud';
@@ -760,7 +760,7 @@ export const StockDetailModal = ({ isOpen, onClose, selectedStock }) => {
<Button variant="ghost" mr={3} onClick={onClose}>
关闭
</Button>
<Button colorScheme="blue" leftIcon={<ExternalLinkIcon />}>
<Button colorScheme="blue" leftIcon={<ExternalLink size={16} />}>
查看K线图
</Button>
</ModalFooter>

View File

@@ -16,7 +16,7 @@ import {
Alert,
AlertIcon,
} from '@chakra-ui/react';
import { ChevronLeftIcon, ChevronRightIcon, CalendarIcon } from '@chakra-ui/icons';
import { ChevronLeft, ChevronRight, Calendar } from 'lucide-react';
const EnhancedCalendar = ({
selectedDate,
@@ -110,20 +110,20 @@ const EnhancedCalendar = ({
<VStack spacing={3}>
<HStack justify="space-between" w="full">
<IconButton
icon={<ChevronLeftIcon />}
icon={<ChevronLeft size={compact ? 16 : 20} />}
size={compact ? 'sm' : 'md'}
variant="ghost"
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1))}
aria-label="上个月"
/>
<HStack spacing={2}>
<CalendarIcon boxSize={5} />
<Calendar size={20} />
<Heading size={headerSize}>
{currentMonth.getFullYear()} {monthNames[currentMonth.getMonth()]}
</Heading>
</HStack>
<IconButton
icon={<ChevronRightIcon />}
icon={<ChevronRight size={compact ? 16 : 20} />}
size={compact ? 'sm' : 'md'}
variant="ghost"
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1))}

View File

@@ -26,7 +26,7 @@ import {
Flex,
Icon,
} from '@chakra-ui/react';
import { StarIcon, TriangleUpIcon } from '@chakra-ui/icons';
import { Star, TrendingUp } from 'lucide-react';
import { logger } from '../../../utils/logger';
import ztStaticService from '../../../services/ztStaticService';
@@ -124,7 +124,7 @@ const HighPositionStocks = ({ dateStr }) => {
<CardHeader bg="red.500" color="white" borderTopRadius="xl">
<Flex justify="space-between" align="center">
<HStack spacing={3}>
<TriangleUpIcon boxSize={6} />
<TrendingUp size={24} />
<Heading size="md">高位股统计</Heading>
</HStack>
<HStack spacing={2}>
@@ -203,7 +203,7 @@ const HighPositionStocks = ({ dateStr }) => {
<HStack>
<Text>{stock.stock_name}</Text>
{stock.continuous_limit_up >= 5 && (
<StarIcon color="red.500" boxSize={3} />
<Star size={12} color="#E53E3E" fill="#E53E3E" />
)}
</HStack>
</Td>
@@ -241,7 +241,7 @@ const HighPositionStocks = ({ dateStr }) => {
{/* 风险提示 */}
<Box mt={4} p={3} bg="yellow.50" borderRadius="md" border="1px solid" borderColor="yellow.200">
<HStack spacing={2}>
<Icon as={TriangleUpIcon} color="yellow.500" />
<Box as={TrendingUp} size={20} color="#D69E2E" />
<Text fontSize="sm" color="yellow.700">
<strong>风险提示</strong>
连续涨停天数越多风险相对越高

View File

@@ -34,7 +34,7 @@ import {
AlertIcon,
} from '@chakra-ui/react';
import { formatTooltipText, getFormattedTextProps } from '../../../utils/textUtils';
import { SearchIcon, DownloadIcon } from '@chakra-ui/icons';
import { Search, Download } from 'lucide-react';
// 简化版搜索组件 - 仅支持股票代码/名称精确匹配
export const AdvancedSearch = ({ onSearch, loading }) => {
@@ -73,7 +73,7 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
<HStack w="full" spacing={3}>
<InputGroup size="lg" flex={1}>
<InputLeftElement>
<SearchIcon color="gray.400" />
<Search size={20} color="#A0AEC0" />
</InputLeftElement>
<Input
placeholder="输入股票代码或名称搜索(如 600000 或 浦发银行)"
@@ -89,7 +89,7 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
onClick={handleSearch}
isLoading={loading}
px={8}
leftIcon={<SearchIcon />}
leftIcon={<Search size={20} />}
>
搜索
</Button>
@@ -152,7 +152,7 @@ export const SearchResultsModal = ({ isOpen, onClose, searchResults, onStockClic
</Badge>
<Button
size="sm"
leftIcon={<DownloadIcon />}
leftIcon={<Download size={16} />}
onClick={exportResults}
variant="outline"
colorScheme="whiteAlpha"

View File

@@ -23,7 +23,7 @@ import {
useColorModeValue,
Link,
} from '@chakra-ui/react';
import { StarIcon, TimeIcon, ExternalLinkIcon } from '@chakra-ui/icons';
import { Star, Clock, ExternalLink } from 'lucide-react';
const SectorDetails = ({ sortedSectors, totalStocks }) => {
// 使用 useRef 来维持展开状态,避免重新渲染时重置
@@ -141,7 +141,7 @@ const SectorDetails = ({ sortedSectors, totalStocks }) => {
>
<Text fontWeight="bold" fontSize="md">{index + 1}</Text>
</Circle>
{sector === '公告' && <StarIcon />}
{sector === '公告' && <Star size={16} />}
<VStack align="start" spacing={0}>
<Text fontWeight="bold" fontSize="lg">{sector}</Text>
<Text fontSize="sm" opacity={0.9}>
@@ -190,7 +190,7 @@ const SectorDetails = ({ sortedSectors, totalStocks }) => {
onClick={(e) => e.stopPropagation()}
>
{stock.sname}
<ExternalLinkIcon mx="2px" boxSize={3} />
<Box as={ExternalLink} display="inline" size={12} style={{ marginLeft: '2px', marginRight: '2px', verticalAlign: 'middle' }} />
</Link>
<Badge colorScheme="purple" fontSize="xs">{stock.scode}</Badge>
{stock.continuous_days && (
@@ -207,7 +207,7 @@ const SectorDetails = ({ sortedSectors, totalStocks }) => {
{/* 中间:时间和涨幅信息 */}
<HStack spacing={4} fontSize="xs" color="gray.500" flex={1} justify="center">
<HStack spacing={1}>
<TimeIcon boxSize={3} />
<Clock size={12} />
<Text>涨停: {formatStockTime(stock)}</Text>
</HStack>
{stock.first_time && (

View File

@@ -18,10 +18,7 @@ import {
Alert,
AlertIcon,
} from '@chakra-ui/react';
import {
RepeatIcon,
ChevronUpIcon,
} from '@chakra-ui/icons';
import { RefreshCw, ChevronUp } from 'lucide-react';
// 导入拆分的组件
// 注意:在实际使用中,这些组件应该被拆分到独立的文件中
@@ -414,7 +411,7 @@ export default function LimitAnalyse() {
<VStack spacing={3}>
<Tooltip label="刷新数据" placement="left">
<IconButton
icon={<RepeatIcon />}
icon={<RefreshCw size={20} />}
colorScheme="blue"
size="lg"
borderRadius="full"
@@ -425,7 +422,7 @@ export default function LimitAnalyse() {
</Tooltip>
<Tooltip label="回到顶部" placement="left">
<IconButton
icon={<ChevronUpIcon />}
icon={<ChevronUp size={20} />}
colorScheme="gray"
size="lg"
borderRadius="full"

View File

@@ -41,13 +41,12 @@ import TransactionRow from 'components/Tables/TransactionRow';
import React from 'react';
import { useNavigate } from 'react-router-dom';
import {
FaPaypal,
FaPencilAlt,
FaRegCalendarAlt,
FaWallet,
FaGem,
} from 'react-icons/fa';
import { RiMastercardFill } from 'react-icons/ri';
Wallet,
Edit2,
Calendar,
Gem,
CreditCard,
} from 'lucide-react';
import {
billingData,
invoicesData,
@@ -101,7 +100,7 @@ function Billing() {
Argon x Chakra
</Text>
<Icon
as={RiMastercardFill}
as={CreditCard}
w='48px'
h='auto'
color='gray.400'
@@ -134,7 +133,7 @@ function Billing() {
<Card p='16px' display='flex' align='center' justify='center'>
<Flex direction='column' align='center' w='100%' py='14px'>
<IconBox h={'60px'} w={'60px'} bg={iconBlue}>
<Icon h={'24px'} w={'24px'} color='white' as={FaWallet} />
<Icon h={'24px'} w={'24px'} color='white' as={Wallet} />
</IconBox>
<Flex
direction='column'
@@ -171,7 +170,7 @@ function Billing() {
py='14px'
>
<IconBox h={'60px'} w={'60px'} bg='purple.500'>
<Icon h={'24px'} w={'24px'} color='white' as={FaGem} />
<Icon h={'24px'} w={'24px'} color='white' as={Gem} />
</IconBox>
<Flex
direction='column'
@@ -248,7 +247,7 @@ function Billing() {
<Spacer />
<Button p='0px' w='16px' h='16px' variant='no-effects'>
<Icon
as={FaPencilAlt}
as={Edit2}
color={colorMode === 'dark' && 'white'}
/>
</Button>
@@ -277,7 +276,7 @@ function Billing() {
variant='no-effects'
>
<Icon
as={FaPencilAlt}
as={Edit2}
color={colorMode === 'dark' && 'white'}
/>
</Button>
@@ -369,7 +368,7 @@ function Billing() {
</Text>
<Flex align='center'>
<Icon
as={FaRegCalendarAlt}
as={Calendar}
color='gray.400'
fontSize='md'
me='6px'

View File

@@ -56,14 +56,7 @@ import {
} from 'components/Icons/Icons';
import { HSeparator } from 'components/Separator/Separator';
import React, { useState } from 'react';
import { AiFillDelete } from 'react-icons/ai';
import { BsArrowRight, BsCircleFill, BsToggleOn } from 'react-icons/bs';
import { FaCube, FaUser } from 'react-icons/fa';
import { GiSmartphone } from 'react-icons/gi';
import { IoIosArrowUp, IoIosRocket, IoMdNotifications } from 'react-icons/io';
import { IoDocumentText } from 'react-icons/io5';
import { MdPowerSettingsNew } from 'react-icons/md';
import { RiComputerLine } from 'react-icons/ri';
import { Trash2, ArrowRight, Circle, ToggleLeft, Box as BoxIcon, User, Smartphone, ChevronUp, Rocket, Bell, FileText, Power, Monitor } from 'lucide-react';
import { Element, Link } from 'react-scroll';
function Settings() {
@@ -293,7 +286,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={IoIosRocket}
as={Rocket}
me='12px'
w='18px'
h='18px'
@@ -313,7 +306,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={IoDocumentText}
as={FileText}
me='12px'
w='18px'
h='18px'
@@ -333,7 +326,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={FaCube}
as={Box}
me='12px'
w='18px'
h='18px'
@@ -353,7 +346,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={BsToggleOn}
as={ToggleLeft}
me='12px'
w='18px'
h='18px'
@@ -373,7 +366,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={FaUser}
as={User}
me='12px'
w='18px'
h='18px'
@@ -393,7 +386,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={IoMdNotifications}
as={Bell}
me='12px'
w='18px'
h='18px'
@@ -413,7 +406,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={MdPowerSettingsNew}
as={Power}
me='12px'
w='18px'
h='18px'
@@ -433,7 +426,7 @@ function Settings() {
>
<Flex align='center' justifySelf='flex-start' w='100%'>
<Icon
as={AiFillDelete}
as={Trash2}
me='12px'
w='18px'
h='18px'
@@ -827,7 +820,8 @@ function Settings() {
>
<Flex align='center'>
<Icon
as={BsCircleFill}
as={Circle}
fill='gray.500'
w='6px'
h='6px'
color='gray.500'
@@ -839,7 +833,8 @@ function Settings() {
</Flex>
<Flex align='center'>
<Icon
as={BsCircleFill}
as={Circle}
fill='gray.500'
w='6px'
h='6px'
color='gray.500'
@@ -851,7 +846,8 @@ function Settings() {
</Flex>
<Flex align='center'>
<Icon
as={BsCircleFill}
as={Circle}
fill='gray.500'
w='6px'
h='6px'
color='gray.500'
@@ -863,7 +859,8 @@ function Settings() {
</Flex>
<Flex align='center'>
<Icon
as={BsCircleFill}
as={Circle}
fill='gray.500'
w='6px'
h='6px'
color='gray.500'
@@ -1059,7 +1056,7 @@ function Settings() {
>
Show Less
</Text>
<Icon as={IoIosArrowUp} color='gray.400' />
<Icon as={ChevronUp} color='gray.400' />
</Flex>
</Flex>
</Flex>
@@ -1460,7 +1457,7 @@ function Settings() {
>
<Flex align='center'>
<Icon
as={RiComputerLine}
as={Monitor}
me='30px'
w='28px'
h='28px'
@@ -1509,7 +1506,7 @@ function Settings() {
See more
</Text>
<Icon
as={BsArrowRight}
as={ArrowRight}
w='20px'
h='20px'
transition='all .3s ease'
@@ -1527,7 +1524,7 @@ function Settings() {
>
<Flex align='center'>
<Icon
as={RiComputerLine}
as={Monitor}
me='30px'
w='28px'
h='28px'
@@ -1565,7 +1562,7 @@ function Settings() {
See more
</Text>
<Icon
as={BsArrowRight}
as={ArrowRight}
w='20px'
h='20px'
transition='all .3s ease'
@@ -1583,7 +1580,7 @@ function Settings() {
>
<Flex align='center'>
<Icon
as={GiSmartphone}
as={Smartphone}
me='30px'
w='28px'
h='28px'
@@ -1622,7 +1619,7 @@ function Settings() {
See more
</Text>
<Icon
as={BsArrowRight}
as={ArrowRight}
w='20px'
h='20px'
transition='all .3s ease'

View File

@@ -43,7 +43,7 @@ import microsoftLogo from "assets/svg/microsoft-logo.svg";
import msnLogo from "assets/svg/msn-logo.svg";
import zohoLogo from "assets/svg/zoho-logo.svg";
import Card from "components/Card/Card";
import { FaCheckCircle, FaTimesCircle } from "react-icons/fa";
import { CheckCircle, XCircle } from "lucide-react";
function Pricing() {
const [activeButton, setActiveButton] = useState({
@@ -155,7 +155,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -167,7 +167,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -179,7 +179,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -191,7 +191,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -203,7 +203,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -215,7 +215,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -244,7 +244,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -256,7 +256,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -268,7 +268,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -280,7 +280,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -292,7 +292,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -304,7 +304,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaTimesCircle}
as={XCircle}
mr="8px"
color={bgTimesIcon}
/>
@@ -333,7 +333,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -345,7 +345,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -357,7 +357,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -369,7 +369,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -381,7 +381,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>
@@ -393,7 +393,7 @@ function Pricing() {
<Icon
w="20px"
h="20px"
as={FaCheckCircle}
as={CheckCircle}
mr="8px"
color="blue.500"
/>

View File

@@ -42,14 +42,14 @@ import ImageArchitect1 from "assets/img/ImageArchitect1.png";
import ImageArchitect2 from "assets/img/ImageArchitect2.png";
import ImageArchitect3 from "assets/img/ImageArchitect3.png";
import {
FaCube,
FaFacebook,
FaInstagram,
FaPenFancy,
FaPlus,
FaTwitter,
} from "react-icons/fa";
import { IoDocumentsSharp } from "react-icons/io5";
Box,
Facebook,
Instagram,
PenTool,
Plus,
Twitter,
Files,
} from "lucide-react";
// Custom components
import Card from "components/Card/Card";
import CardBody from "components/Card/CardBody";
@@ -170,7 +170,7 @@ function Overview() {
dispatch({ type: "SWITCH_ACTIVE", payload: "overview" })
}
>
<Icon color={textColor} as={FaCube} me="6px" />
<Icon color={textColor} as={Box} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
OVERVIEW
</Text>
@@ -200,7 +200,7 @@ function Overview() {
dispatch({ type: "SWITCH_ACTIVE", payload: "teams" })
}
>
<Icon color={textColor} as={IoDocumentsSharp} me="6px" />
<Icon color={textColor} as={Files} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
TEAMS
</Text>
@@ -229,7 +229,7 @@ function Overview() {
dispatch({ type: "SWITCH_ACTIVE", payload: "projects" })
}
>
<Icon color={textColor} as={FaPenFancy} me="6px" />
<Icon color={textColor} as={PenTool} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
PROJECTS
</Text>
@@ -411,7 +411,7 @@ function Overview() {
me="10px"
_hover={{ color: "blue.500" }}
>
<Icon as={FaFacebook} />
<Icon as={Facebook} />
</Link>
<Link
href="#"
@@ -420,7 +420,7 @@ function Overview() {
me="10px"
_hover={{ color: "blue.500" }}
>
<Icon as={FaInstagram} />
<Icon as={Instagram} />
</Link>
<Link
href="#"
@@ -429,7 +429,7 @@ function Overview() {
me="10px"
_hover={{ color: "blue.500" }}
>
<Icon as={FaTwitter} />
<Icon as={Twitter} />
</Link>
</Flex>
</Flex>
@@ -741,7 +741,7 @@ function Overview() {
minHeight={{ sm: "200px", md: "100%" }}
>
<Flex direction="column" justifyContent="center" align="center">
<Icon as={FaPlus} color={textColor} fontSize="lg" mb="12px" />
<Icon as={Plus} color={textColor} fontSize="lg" mb="12px" />
<Text fontSize="lg" color={textColor} fontWeight="bold">
Create a New Project
</Text>

View File

@@ -53,9 +53,7 @@ import {
} from "components/Icons/Icons";
import { HSeparator } from "components/Separator/Separator";
import React, { useReducer } from "react";
import { BsPlus } from "react-icons/bs";
import { FaCube, FaPenFancy } from "react-icons/fa";
import { IoDocumentsSharp, IoEllipsisVerticalSharp } from "react-icons/io5";
import { Plus, Box, PenTool, Files, MoreVertical } from "lucide-react";
const reducer = (state, action) => {
if (action.type === "SWITCH_ACTIVE") {
@@ -205,7 +203,7 @@ function Projects() {
dispatch({ type: "SWITCH_ACTIVE", payload: "overview" })
}
>
<Icon color={textColor} as={FaCube} me="6px" />
<Icon color={textColor} as={Box} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
OVERVIEW
</Text>
@@ -235,7 +233,7 @@ function Projects() {
dispatch({ type: "SWITCH_ACTIVE", payload: "teams" })
}
>
<Icon color={textColor} as={IoDocumentsSharp} me="6px" />
<Icon color={textColor} as={Files} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
TEAMS
</Text>
@@ -264,7 +262,7 @@ function Projects() {
dispatch({ type: "SWITCH_ACTIVE", payload: "projects" })
}
>
<Icon color={textColor} as={FaPenFancy} me="6px" />
<Icon color={textColor} as={PenTool} me="6px" />
<Text fontSize="xs" color={textColor} fontWeight="bold">
PROJECTS
</Text>
@@ -324,7 +322,7 @@ function Projects() {
<Menu isOpen={isOpen1} onClose={onClose1}>
<MenuButton onClick={onOpen1} alignSelf="flex-start">
<Icon
as={IoEllipsisVerticalSharp}
as={MoreVertical}
color="gray.400"
w="20px"
h="20px"
@@ -408,7 +406,7 @@ function Projects() {
<Menu isOpen={isOpen2} onClose={onClose2}>
<MenuButton onClick={onOpen2} alignSelf="flex-start">
<Icon
as={IoEllipsisVerticalSharp}
as={MoreVertical}
color="gray.400"
w="20px"
h="20px"
@@ -494,7 +492,7 @@ function Projects() {
<Menu isOpen={isOpen3} onClose={onClose3}>
<MenuButton onClick={onOpen3} alignSelf="flex-start">
<Icon
as={IoEllipsisVerticalSharp}
as={MoreVertical}
color="gray.400"
w="20px"
h="20px"
@@ -576,7 +574,7 @@ function Projects() {
<Menu isOpen={isOpen4} onClose={onClose4}>
<MenuButton onClick={onOpen4} alignSelf="flex-start">
<Icon
as={IoEllipsisVerticalSharp}
as={MoreVertical}
color="gray.400"
w="20px"
h="20px"
@@ -659,7 +657,7 @@ function Projects() {
<Menu isOpen={isOpen5} onClose={onClose5}>
<MenuButton onClick={onOpen5} alignSelf="flex-start">
<Icon
as={IoEllipsisVerticalSharp}
as={MoreVertical}
color="gray.400"
w="20px"
h="20px"
@@ -722,7 +720,7 @@ function Projects() {
color={secondaryColor}
>
<Icon
as={BsPlus}
as={Plus}
w="30px"
h="30px"
mb="12px"

Some files were not shown because too many files have changed in this diff Show More