refactor(icons): 迁移其他 views 目录图标到 lucide-react
- views/Center, views/Community, views/DataBrowser 等 - views/EventDetail, views/LimitAnalyse, views/StockOverview - views/TradingSimulation, views/Pages, views/Authentication - views/Profile, views/Settings - 处理 Tag/TagIcon 命名冲突 - 涉及 52 个组件文件 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,7 +32,6 @@ import {
|
|||||||
// Assets
|
// Assets
|
||||||
import BasicImage from "assets/img/BasicImage.png";
|
import BasicImage from "assets/img/BasicImage.png";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FaApple, FaFacebook, FaGoogle } from "react-icons/fa";
|
|
||||||
import AuthBasic from "layouts/AuthBasic";
|
import AuthBasic from "layouts/AuthBasic";
|
||||||
|
|
||||||
function LockBasic() {
|
function LockBasic() {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import BasicImage from "assets/img/BasicImage.png";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import AuthBasic from "layouts/AuthBasic";
|
import AuthBasic from "layouts/AuthBasic";
|
||||||
import { PinInputLight } from "components/PinInput/PinInput";
|
import { PinInputLight } from "components/PinInput/PinInput";
|
||||||
import { IoIosRocket } from "react-icons/io";
|
import { Rocket } from "lucide-react";
|
||||||
|
|
||||||
function LockBasic() {
|
function LockBasic() {
|
||||||
// Chakra color mode
|
// Chakra color mode
|
||||||
@@ -75,7 +75,7 @@ function LockBasic() {
|
|||||||
align="center"
|
align="center"
|
||||||
mb="30px"
|
mb="30px"
|
||||||
>
|
>
|
||||||
<Icon as={IoIosRocket} color="white" w="36px" h="36px" />
|
<Icon as={Rocket} color="white" w="36px" h="36px" />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text
|
<Text
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
// Assets
|
// Assets
|
||||||
import { PinInputLight } from "components/PinInput/PinInput";
|
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 CoverImage from "assets/img/CoverImage.png";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import AuthCover from "layouts/AuthCover";
|
import AuthCover from "layouts/AuthCover";
|
||||||
@@ -64,7 +64,7 @@ function LockCover() {
|
|||||||
align="center"
|
align="center"
|
||||||
mb="30px"
|
mb="30px"
|
||||||
>
|
>
|
||||||
<Icon as={IoIosRocket} color="white" w="36px" h="36px" />
|
<Icon as={Rocket} color="white" w="36px" h="36px" />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text
|
<Text
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import illustration from "assets/img/illustration-auth.png";
|
import illustration from "assets/img/illustration-auth.png";
|
||||||
import AuthIllustration from "layouts/AuthIllustration";
|
import AuthIllustration from "layouts/AuthIllustration";
|
||||||
import { PinInputDark } from "components/PinInput/PinInput";
|
import { PinInputDark } from "components/PinInput/PinInput";
|
||||||
import { IoIosRocket } from "react-icons/io";
|
import { Rocket } from "lucide-react";
|
||||||
|
|
||||||
function LockIllustration() {
|
function LockIllustration() {
|
||||||
// Chakra color mode
|
// Chakra color mode
|
||||||
@@ -51,7 +51,7 @@ function LockIllustration() {
|
|||||||
justify='center'
|
justify='center'
|
||||||
align='center'
|
align='center'
|
||||||
mb='30px'>
|
mb='30px'>
|
||||||
<Icon as={IoIosRocket} color='white' w='36px' h='36px' />
|
<Icon as={Rocket} color='white' w='36px' h='36px' />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text
|
<Text
|
||||||
fontWeight='bold'
|
fontWeight='bold'
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiEdit2,
|
Pencil,
|
||||||
FiTrash2,
|
Trash2,
|
||||||
FiFileText,
|
FileText,
|
||||||
FiCalendar,
|
Calendar,
|
||||||
FiTrendingUp,
|
TrendingUp,
|
||||||
FiChevronDown,
|
ChevronDown,
|
||||||
FiChevronUp,
|
ChevronUp,
|
||||||
} from 'react-icons/fi';
|
} from 'lucide-react';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
<VStack align="start" spacing={1} flex={1}>
|
<VStack align="start" spacing={1} flex={1}>
|
||||||
{/* 标题行 */}
|
{/* 标题行 */}
|
||||||
<HStack spacing={{ base: 1, md: 2 }} flexWrap="wrap">
|
<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' }}>
|
<Text fontWeight="bold" fontSize={{ base: 'md', md: 'lg' }}>
|
||||||
{event.title}
|
{event.title}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -206,7 +206,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
{/* list 模式显示日期 */}
|
{/* list 模式显示日期 */}
|
||||||
{isListMode && (
|
{isListMode && (
|
||||||
<HStack spacing={{ base: 1, md: 2 }} flexWrap="wrap">
|
<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}>
|
<Text fontSize={{ base: 'xs', md: 'sm' }} color={finalSecondaryText}>
|
||||||
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
|
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -219,7 +219,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
<HStack spacing={{ base: 0, md: 1 }}>
|
<HStack spacing={{ base: 0, md: 1 }}>
|
||||||
{onEdit && (
|
{onEdit && (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FiEdit2 />}
|
icon={<Pencil />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => onEdit(event)}
|
onClick={() => onEdit(event)}
|
||||||
@@ -228,7 +228,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
)}
|
)}
|
||||||
{onDelete && (
|
{onDelete && (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FiTrash2 />}
|
icon={<Trash2 />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
@@ -258,7 +258,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
colorScheme={colorScheme}
|
colorScheme={colorScheme}
|
||||||
mt={1}
|
mt={1}
|
||||||
rightIcon={isExpanded ? <FiChevronUp /> : <FiChevronDown />}
|
rightIcon={isExpanded ? <ChevronUp /> : <ChevronDown />}
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
onClick={() => setIsExpanded(!isExpanded)}
|
||||||
>
|
>
|
||||||
{isExpanded ? '收起' : '展开'}
|
{isExpanded ? '收起' : '展开'}
|
||||||
@@ -280,7 +280,7 @@ export const EventCard = memo<EventCardProps>(({
|
|||||||
const displayText = typeof stock === 'string' ? stock : `${stock.name}(${stock.code})`;
|
const displayText = typeof stock === 'string' ? stock : `${stock.name}(${stock.code})`;
|
||||||
return (
|
return (
|
||||||
<Tag key={stockCode || idx} size="sm" colorScheme="blue" variant="subtle">
|
<Tag key={stockCode || idx} size="sm" colorScheme="blue" variant="subtle">
|
||||||
<TagLeftIcon as={FiTrendingUp} />
|
<TagLeftIcon as={TrendingUp} />
|
||||||
<TagLabel>{displayText}</TagLabel>
|
<TagLabel>{displayText}</TagLabel>
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
Icon,
|
Icon,
|
||||||
useToast,
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FiFileText } from 'react-icons/fi';
|
import { FileText } from 'lucide-react';
|
||||||
|
|
||||||
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
import { useAppDispatch, useAppSelector } from '@/store/hooks';
|
||||||
import {
|
import {
|
||||||
@@ -165,7 +165,7 @@ export const EventPanel: React.FC<EventPanelProps> = ({
|
|||||||
) : events.length === 0 ? (
|
) : events.length === 0 ? (
|
||||||
<Center py={{ base: 6, md: 8 }}>
|
<Center py={{ base: 6, md: 8 }}>
|
||||||
<VStack spacing={{ base: 2, md: 3 }}>
|
<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>
|
<Text color={secondaryText} fontSize={{ base: 'sm', md: 'md' }}>暂无投资{label}</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -21,14 +21,16 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiEdit2,
|
Pencil,
|
||||||
FiTrash2,
|
Trash2,
|
||||||
FiCalendar,
|
Calendar,
|
||||||
FiTrendingUp,
|
TrendingUp,
|
||||||
FiChevronDown,
|
ChevronDown,
|
||||||
FiChevronUp,
|
ChevronUp,
|
||||||
} from 'react-icons/fi';
|
FileText,
|
||||||
import { FileText, Heart, Target } from 'lucide-react';
|
Heart,
|
||||||
|
Target,
|
||||||
|
} from 'lucide-react';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import 'dayjs/locale/zh-cn';
|
import 'dayjs/locale/zh-cn';
|
||||||
|
|
||||||
@@ -170,7 +172,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
|
|||||||
<HStack spacing={0}>
|
<HStack spacing={0}>
|
||||||
{onEdit && (
|
{onEdit && (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FiEdit2 size={14} />}
|
icon={<Pencil size={14} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={FUI_THEME.text.secondary}
|
color={FUI_THEME.text.secondary}
|
||||||
@@ -181,7 +183,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
|
|||||||
)}
|
)}
|
||||||
{onDelete && (
|
{onDelete && (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FiTrash2 size={14} />}
|
icon={<Trash2 size={14} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={FUI_THEME.text.secondary}
|
color={FUI_THEME.text.secondary}
|
||||||
@@ -197,7 +199,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
|
|||||||
|
|
||||||
{/* 日期行 */}
|
{/* 日期行 */}
|
||||||
<HStack spacing={2}>
|
<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}>
|
<Text fontSize="xs" color={FUI_THEME.text.secondary}>
|
||||||
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
|
{dayjs(event.event_date || event.date).format('YYYY年MM月DD日')}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -243,7 +245,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
|
|||||||
mt={1}
|
mt={1}
|
||||||
ml={4}
|
ml={4}
|
||||||
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
|
_hover={{ bg: 'rgba(212, 175, 55, 0.1)' }}
|
||||||
rightIcon={isExpanded ? <FiChevronUp /> : <FiChevronDown />}
|
rightIcon={isExpanded ? <ChevronUp /> : <ChevronDown />}
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
onClick={() => setIsExpanded(!isExpanded)}
|
||||||
>
|
>
|
||||||
{isExpanded ? '收起' : '展开'}
|
{isExpanded ? '收起' : '展开'}
|
||||||
@@ -270,7 +272,7 @@ export const FUIEventCard = memo<FUIEventCardProps>(({
|
|||||||
border="1px solid"
|
border="1px solid"
|
||||||
borderColor="rgba(212, 175, 55, 0.2)"
|
borderColor="rgba(212, 175, 55, 0.2)"
|
||||||
>
|
>
|
||||||
<TagLeftIcon as={FiTrendingUp} boxSize={3} />
|
<TagLeftIcon as={TrendingUp} boxSize={3} />
|
||||||
<TagLabel fontSize="xs">{displayText}</TagLabel>
|
<TagLabel fontSize="xs">{displayText}</TagLabel>
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
* 黑金色主题,展示平台核心功能快捷入口
|
* 黑金色主题,展示平台核心功能快捷入口
|
||||||
*/
|
*/
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { Box, SimpleGrid, HStack, Text, Icon } from '@chakra-ui/react';
|
import { Box, SimpleGrid, HStack, Text } from '@chakra-ui/react';
|
||||||
import { CheckCircleIcon } from '@chakra-ui/icons';
|
import { CheckCircle } from 'lucide-react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import GlassCard from '@components/GlassCard';
|
import GlassCard from '@components/GlassCard';
|
||||||
import { CORE_FEATURES } from '@/constants/homeFeatures';
|
import { CORE_FEATURES } from '@/constants/homeFeatures';
|
||||||
@@ -35,10 +35,10 @@ const FeatureEntryPanel: React.FC = () => {
|
|||||||
>
|
>
|
||||||
{/* 标题栏 - 参考投资仪表盘样式 */}
|
{/* 标题栏 - 参考投资仪表盘样式 */}
|
||||||
<HStack mb={4} spacing={2}>
|
<HStack mb={4} spacing={2}>
|
||||||
<Icon
|
<CheckCircle
|
||||||
as={CheckCircleIcon}
|
size={20}
|
||||||
boxSize={5}
|
|
||||||
color="rgba(72, 187, 120, 0.9)"
|
color="rgba(72, 187, 120, 0.9)"
|
||||||
|
style={{ display: 'inline-block' }}
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text
|
||||||
fontSize="lg"
|
fontSize="lg"
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ import {
|
|||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiCalendar,
|
Calendar,
|
||||||
FiFileText,
|
FileText,
|
||||||
FiList,
|
List,
|
||||||
FiPlus,
|
Plus,
|
||||||
} from 'react-icons/fi';
|
Target,
|
||||||
import { Target } from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import GlassCard from '@components/GlassCard';
|
import GlassCard from '@components/GlassCard';
|
||||||
|
|
||||||
import { PlanningDataProvider } from './PlanningContext';
|
import { PlanningDataProvider } from './PlanningContext';
|
||||||
@@ -148,7 +148,7 @@ const InvestmentPlanningCenter: React.FC = () => {
|
|||||||
{/* 视图切换按钮组 - H5隐藏 */}
|
{/* 视图切换按钮组 - H5隐藏 */}
|
||||||
<ButtonGroup size="sm" isAttached display={{ base: 'none', md: 'flex' }}>
|
<ButtonGroup size="sm" isAttached display={{ base: 'none', md: 'flex' }}>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<Icon as={FiList} boxSize={4} />}
|
leftIcon={<Icon as={List} boxSize={4} />}
|
||||||
bg={viewMode === 'list' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
|
bg={viewMode === 'list' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
|
||||||
color={viewMode === 'list' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
|
color={viewMode === 'list' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
|
||||||
border="1px solid"
|
border="1px solid"
|
||||||
@@ -159,7 +159,7 @@ const InvestmentPlanningCenter: React.FC = () => {
|
|||||||
列表视图
|
列表视图
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<Icon as={FiCalendar} boxSize={4} />}
|
leftIcon={<Icon as={Calendar} boxSize={4} />}
|
||||||
bg={viewMode === 'calendar' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
|
bg={viewMode === 'calendar' ? 'rgba(212, 175, 55, 0.2)' : 'transparent'}
|
||||||
color={viewMode === 'calendar' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
|
color={viewMode === 'calendar' ? goldAccent : 'rgba(255, 255, 255, 0.6)'}
|
||||||
border="1px solid"
|
border="1px solid"
|
||||||
@@ -223,7 +223,7 @@ const InvestmentPlanningCenter: React.FC = () => {
|
|||||||
borderColor: goldAccent,
|
borderColor: goldAccent,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon as={FiFileText} mr={1} boxSize={{ base: 3, md: 4 }} />
|
<Icon as={FileText} mr={1} boxSize={{ base: 3, md: 4 }} />
|
||||||
我的复盘 ({reviews.length})
|
我的复盘 ({reviews.length})
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
@@ -233,7 +233,7 @@ const InvestmentPlanningCenter: React.FC = () => {
|
|||||||
color={goldAccent}
|
color={goldAccent}
|
||||||
border="1px solid"
|
border="1px solid"
|
||||||
borderColor="rgba(212, 175, 55, 0.3)"
|
borderColor="rgba(212, 175, 55, 0.3)"
|
||||||
leftIcon={<Icon as={FiPlus} boxSize={3} />}
|
leftIcon={<Icon as={Plus} boxSize={3} />}
|
||||||
fontSize={{ base: '11px', md: 'sm' }}
|
fontSize={{ base: '11px', md: 'sm' }}
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
_hover={{ bg: 'rgba(212, 175, 55, 0.3)' }}
|
_hover={{ bg: 'rgba(212, 175, 55, 0.3)' }}
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
FiCalendar,
|
Calendar,
|
||||||
FiClock,
|
Clock,
|
||||||
FiStar,
|
Star,
|
||||||
FiTrendingUp,
|
TrendingUp,
|
||||||
FiAlertCircle,
|
AlertCircle,
|
||||||
} from 'react-icons/fi';
|
} from 'lucide-react';
|
||||||
import { eventService } from '../../../services/eventService';
|
import { eventService } from '../../../services/eventService';
|
||||||
import { logger } from '../../../utils/logger';
|
import { logger } from '../../../utils/logger';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@@ -153,7 +153,7 @@ export default function MyFutureEvents({ limit = 5 }) {
|
|||||||
return (
|
return (
|
||||||
<Center py={8}>
|
<Center py={8}>
|
||||||
<VStack spacing={3}>
|
<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 color={secondaryText} fontSize="sm">
|
||||||
暂无关注的未来事件
|
暂无关注的未来事件
|
||||||
</Text>
|
</Text>
|
||||||
@@ -214,7 +214,7 @@ export default function MyFutureEvents({ limit = 5 }) {
|
|||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Badge colorScheme={timeInfo.color} variant="subtle">
|
<Badge colorScheme={timeInfo.color} variant="subtle">
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<Icon as={FiClock} boxSize={3} />
|
<Icon as={Clock} boxSize={3} />
|
||||||
<Text>{timeInfo.date}</Text>
|
<Text>{timeInfo.date}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Badge>
|
</Badge>
|
||||||
@@ -228,7 +228,7 @@ export default function MyFutureEvents({ limit = 5 }) {
|
|||||||
{[...Array(5)].map((_, i) => (
|
{[...Array(5)].map((_, i) => (
|
||||||
<Icon
|
<Icon
|
||||||
key={i}
|
key={i}
|
||||||
as={FiStar}
|
as={Star}
|
||||||
boxSize={3}
|
boxSize={3}
|
||||||
color={i < event.star ? importanceColor : 'gray.300'}
|
color={i < event.star ? importanceColor : 'gray.300'}
|
||||||
fill={i < event.star ? 'currentColor' : 'none'}
|
fill={i < event.star ? 'currentColor' : 'none'}
|
||||||
@@ -247,7 +247,7 @@ export default function MyFutureEvents({ limit = 5 }) {
|
|||||||
)}
|
)}
|
||||||
{event.related_stocks && event.related_stocks.length > 0 && (
|
{event.related_stocks && event.related_stocks.length > 0 && (
|
||||||
<Tag size="sm" variant="subtle" colorScheme="purple">
|
<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>
|
<TagLabel>{event.related_stocks.length}只相关股票</TagLabel>
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
@@ -271,7 +271,7 @@ export default function MyFutureEvents({ limit = 5 }) {
|
|||||||
{event.forecast && (
|
{event.forecast && (
|
||||||
<Box>
|
<Box>
|
||||||
<HStack spacing={1} mb={1}>
|
<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 fontSize="xs" color={secondaryText}>
|
||||||
预测
|
预测
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Icon,
|
Icon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { TimeIcon, BellIcon } from '@chakra-ui/icons';
|
import { Clock, Bell } from 'lucide-react';
|
||||||
import { useNotification } from '@contexts/NotificationContext';
|
import { useNotification } from '@contexts/NotificationContext';
|
||||||
import EventScrollList from './EventScrollList';
|
import EventScrollList from './EventScrollList';
|
||||||
import ModeToggleButtons from './ModeToggleButtons';
|
import ModeToggleButtons from './ModeToggleButtons';
|
||||||
@@ -565,7 +565,7 @@ const [currentMode, setCurrentMode] = useState('vertical');
|
|||||||
<HStack spacing={4}>
|
<HStack spacing={4}>
|
||||||
<Heading size={isMobile ? "sm" : "md"} color={PROFESSIONAL_COLORS.text.primary}>
|
<Heading size={isMobile ? "sm" : "md"} color={PROFESSIONAL_COLORS.text.primary}>
|
||||||
<HStack spacing={2}>
|
<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>
|
<Text bgGradient={PROFESSIONAL_COLORS.gradients.gold} bgClip="text">实时要闻·动态追踪</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Heading>
|
</Heading>
|
||||||
@@ -584,9 +584,8 @@ const [currentMode, setCurrentMode] = useState('vertical');
|
|||||||
_hover={{ opacity: 0.8 }}
|
_hover={{ opacity: 0.8 }}
|
||||||
transition="opacity 0.2s"
|
transition="opacity 0.2s"
|
||||||
>
|
>
|
||||||
<Icon
|
<Bell
|
||||||
as={BellIcon}
|
size={14}
|
||||||
boxSize={3.5}
|
|
||||||
color={PROFESSIONAL_COLORS.gold[500]}
|
color={PROFESSIONAL_COLORS.gold[500]}
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
useToast,
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||||
ChevronLeftIcon,
|
|
||||||
ChevronRightIcon,
|
|
||||||
} from '@chakra-ui/icons';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页控制器组件(使用 React.memo 优化,避免不必要的重新渲染)
|
* 分页控制器组件(使用 React.memo 优化,避免不必要的重新渲染)
|
||||||
@@ -116,7 +113,7 @@ const PaginationControl = React.memo(({ currentPage, totalPages, onPageChange })
|
|||||||
<HStack spacing={1.5} justify="center" flexWrap="wrap">
|
<HStack spacing={1.5} justify="center" flexWrap="wrap">
|
||||||
{/* 上一页按钮 */}
|
{/* 上一页按钮 */}
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronLeftIcon />}
|
icon={<ChevronLeft size={14} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
onClick={() => onPageChange(currentPage - 1)}
|
onClick={() => onPageChange(currentPage - 1)}
|
||||||
isDisabled={currentPage === 1}
|
isDisabled={currentPage === 1}
|
||||||
@@ -164,7 +161,7 @@ const PaginationControl = React.memo(({ currentPage, totalPages, onPageChange })
|
|||||||
|
|
||||||
{/* 下一页按钮 */}
|
{/* 下一页按钮 */}
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronRightIcon />}
|
icon={<ChevronRight size={14} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
onClick={() => onPageChange(currentPage + 1)}
|
onClick={() => onPageChange(currentPage + 1)}
|
||||||
isDisabled={currentPage === totalPages}
|
isDisabled={currentPage === totalPages}
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Button,
|
Button,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { ChevronDownIcon, ChevronUpIcon, RepeatIcon } from "@chakra-ui/icons";
|
import { ChevronDown, ChevronUp, RefreshCw, TrendingUp, Zap } from "lucide-react";
|
||||||
import { FiTrendingUp, FiZap } from "react-icons/fi";
|
|
||||||
import { FireOutlined } from "@ant-design/icons";
|
import { FireOutlined } from "@ant-design/icons";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { Select } from "antd";
|
import { Select } from "antd";
|
||||||
@@ -363,7 +362,7 @@ const MainlineCard = React.memo(
|
|||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
<Icon
|
<Icon
|
||||||
as={isExpanded ? ChevronUpIcon : ChevronDownIcon}
|
as={isExpanded ? ChevronUp : ChevronDown}
|
||||||
boxSize={4}
|
boxSize={4}
|
||||||
color={COLORS.secondaryTextColor}
|
color={COLORS.secondaryTextColor}
|
||||||
ml={2}
|
ml={2}
|
||||||
@@ -744,7 +743,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
<VStack spacing={4}>
|
<VStack spacing={4}>
|
||||||
<Text color="red.500">加载失败: {error}</Text>
|
<Text color="red.500">加载失败: {error}</Text>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<RepeatIcon />}
|
icon={<RefreshCw size={16} />}
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
onClick={fetchMainlineData}
|
onClick={fetchMainlineData}
|
||||||
aria-label="重试"
|
aria-label="重试"
|
||||||
@@ -761,7 +760,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
<Box display={display} p={8} bg={COLORS.containerBg} minH="400px">
|
<Box display={display} p={8} bg={COLORS.containerBg} minH="400px">
|
||||||
<Center h="400px">
|
<Center h="400px">
|
||||||
<VStack spacing={4}>
|
<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 color={COLORS.secondaryTextColor}>暂无主线数据</Text>
|
||||||
<Text fontSize="sm" color={COLORS.secondaryTextColor}>
|
<Text fontSize="sm" color={COLORS.secondaryTextColor}>
|
||||||
尝试调整筛选条件
|
尝试调整筛选条件
|
||||||
@@ -801,7 +800,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
>
|
>
|
||||||
<HStack spacing={4}>
|
<HStack spacing={4}>
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<Icon as={FiTrendingUp} color="blue.400" />
|
<Icon as={TrendingUp} color="blue.400" />
|
||||||
<Text fontWeight="bold" color={COLORS.textColor} fontSize="sm">
|
<Text fontWeight="bold" color={COLORS.textColor} fontSize="sm">
|
||||||
{mainline_count} 条主线
|
{mainline_count} 条主线
|
||||||
</Text>
|
</Text>
|
||||||
@@ -900,7 +899,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
/>
|
/>
|
||||||
<Tooltip label="全部展开">
|
<Tooltip label="全部展开">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronDownIcon />}
|
icon={<ChevronDown size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={COLORS.secondaryTextColor}
|
color={COLORS.secondaryTextColor}
|
||||||
@@ -911,7 +910,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="全部折叠">
|
<Tooltip label="全部折叠">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronUpIcon />}
|
icon={<ChevronUp size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={COLORS.secondaryTextColor}
|
color={COLORS.secondaryTextColor}
|
||||||
@@ -922,7 +921,7 @@ const MainlineTimelineViewComponent = forwardRef(
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="刷新">
|
<Tooltip label="刷新">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<RepeatIcon />}
|
icon={<RefreshCw size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={COLORS.secondaryTextColor}
|
color={COLORS.secondaryTextColor}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
useBreakpointValue,
|
useBreakpointValue,
|
||||||
useDisclosure
|
useDisclosure
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { InfoIcon } from '@chakra-ui/icons';
|
import { Info } from 'lucide-react';
|
||||||
import HorizontalDynamicNewsEventCard from '../../EventCard/HorizontalDynamicNewsEventCard';
|
import HorizontalDynamicNewsEventCard from '../../EventCard/HorizontalDynamicNewsEventCard';
|
||||||
import EventDetailScrollPanel from '../EventDetailScrollPanel';
|
import EventDetailScrollPanel from '../EventDetailScrollPanel';
|
||||||
import EventDetailModal from '../../EventDetailModal';
|
import EventDetailModal from '../../EventDetailModal';
|
||||||
@@ -134,7 +134,7 @@ const VerticalModeLayout = React.memo(({
|
|||||||
/* 空状态 */
|
/* 空状态 */
|
||||||
<Center h="100%" minH="400px">
|
<Center h="100%" minH="400px">
|
||||||
<VStack spacing={4}>
|
<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 fontSize="lg" color="gray.500" textAlign="center">
|
||||||
当前筛选条件下暂无数据
|
当前筛选条件下暂无数据
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// src/views/Community/components/EventCard/atoms/EventFollowButton.js
|
// src/views/Community/components/EventCard/atoms/EventFollowButton.js
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IconButton, Box } from '@chakra-ui/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'
|
boxShadow: 'md'
|
||||||
}}
|
}}
|
||||||
icon={
|
icon={
|
||||||
isFollowing ? (
|
<Star
|
||||||
<AiFillStar
|
|
||||||
size={iconSize}
|
size={iconSize}
|
||||||
color="gold"
|
color="gold"
|
||||||
|
fill={isFollowing ? "currentColor" : "none"}
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<AiOutlineStar
|
|
||||||
size={iconSize}
|
|
||||||
color="gold"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-label={isFollowing ? '取消关注' : '关注'}
|
aria-label={isFollowing ? '取消关注' : '关注'}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// src/views/Community/components/EventCard/atoms/EventImportanceBadge.js
|
// src/views/Community/components/EventCard/atoms/EventImportanceBadge.js
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Badge, Tooltip, VStack, HStack, Text, Divider, Circle } from '@chakra-ui/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';
|
import { getImportanceConfig, getAllImportanceLevels } from '@constants/importanceLevels';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +86,7 @@ const EventImportanceBadge = ({
|
|||||||
gap={1}
|
gap={1}
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
>
|
>
|
||||||
{showIcon && <InfoIcon boxSize={2.5} />}
|
{showIcon && <Info size={10} />}
|
||||||
{importance || 'C'}级
|
{importance || 'C'}级
|
||||||
</Badge>
|
</Badge>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// src/views/Community/components/EventCard/EventStats.js
|
// src/views/Community/components/EventCard/EventStats.js
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { HStack, Text, Tooltip } from '@chakra-ui/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">
|
<Tooltip label="浏览量" placement="top">
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<ViewIcon boxSize={iconSize} />
|
<Eye size={iconSize === '12px' ? 12 : 16} />
|
||||||
<Text fontSize={fontSize}>{viewCount}</Text>
|
<Text fontSize={fontSize}>{viewCount}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -39,7 +39,7 @@ const EventStats = ({
|
|||||||
{/* 帖子数 */}
|
{/* 帖子数 */}
|
||||||
<Tooltip label="帖子数" placement="top">
|
<Tooltip label="帖子数" placement="top">
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<ChatIcon boxSize={iconSize} />
|
<MessageCircle size={iconSize === '12px' ? 12 : 16} />
|
||||||
<Text fontSize={fontSize}>{postCount}</Text>
|
<Text fontSize={fontSize}>{postCount}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -47,7 +47,7 @@ const EventStats = ({
|
|||||||
{/* 关注数 */}
|
{/* 关注数 */}
|
||||||
<Tooltip label="关注数" placement="top">
|
<Tooltip label="关注数" placement="top">
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<StarIcon boxSize={iconSize} />
|
<Star size={iconSize === '12px' ? 12 : 16} />
|
||||||
<Text fontSize={fontSize}>{followerCount}</Text>
|
<Text fontSize={fontSize}>{followerCount}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { init, dispose } from 'klinecharts';
|
import { init, dispose } from 'klinecharts';
|
||||||
import {
|
import {
|
||||||
FaExpand,
|
Maximize,
|
||||||
FaCompress,
|
Minimize,
|
||||||
FaCamera,
|
Camera,
|
||||||
FaRedo,
|
RotateCcw,
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { MetricDataPoint } from '@services/categoryService';
|
import { MetricDataPoint } from '@services/categoryService';
|
||||||
|
|
||||||
// 黑金主题配色
|
// 黑金主题配色
|
||||||
@@ -265,7 +265,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
>
|
>
|
||||||
<Icon as={FaRedo} />
|
<Icon as={RotateCcw} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="截图">
|
<Tooltip label="截图">
|
||||||
@@ -276,7 +276,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={handleScreenshot}
|
onClick={handleScreenshot}
|
||||||
>
|
>
|
||||||
<Icon as={FaCamera} />
|
<Icon as={Camera} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
|
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
|
||||||
@@ -287,7 +287,7 @@ const KLineChartView: React.FC<KLineChartViewProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
>
|
>
|
||||||
<Icon as={isFullscreen ? FaCompress : FaExpand} />
|
<Icon as={isFullscreen ? Minimize : Maximize} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
useToast,
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} 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 { fetchMetricData, MetricDataResponse, TreeMetric } from '@services/categoryService';
|
||||||
import SimpleLineChart from './SimpleLineChart';
|
import SimpleLineChart from './SimpleLineChart';
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
|
|||||||
>
|
>
|
||||||
<HStack spacing={4} wrap="wrap">
|
<HStack spacing={4} wrap="wrap">
|
||||||
<HStack flex="1" minW="200px">
|
<HStack flex="1" minW="200px">
|
||||||
<Icon as={FaCalendar} color={themeColors.text.muted} />
|
<Icon as={Calendar} color={themeColors.text.muted} />
|
||||||
<Input
|
<Input
|
||||||
type="date"
|
type="date"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -235,7 +235,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
borderColor={themeColors.border.gold}
|
borderColor={themeColors.border.gold}
|
||||||
color={themeColors.text.gold}
|
color={themeColors.text.gold}
|
||||||
leftIcon={<FaDownload />}
|
leftIcon={<Download />}
|
||||||
onClick={handleExportCSV}
|
onClick={handleExportCSV}
|
||||||
isDisabled={!metricData || !metricData.data || metricData.data.length === 0}
|
isDisabled={!metricData || !metricData.data || metricData.data.length === 0}
|
||||||
>
|
>
|
||||||
@@ -260,7 +260,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
|
|||||||
bg: themeColors.bg.card,
|
bg: themeColors.bg.card,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon as={FaChartLine} mr={2} />
|
<Icon as={LineChart} mr={2} />
|
||||||
折线图
|
折线图
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
@@ -271,7 +271,7 @@ const MetricDataModal: React.FC<MetricDataModalProps> = ({ isOpen, onClose, metr
|
|||||||
bg: themeColors.bg.card,
|
bg: themeColors.bg.card,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon as={FaTable} mr={2} />
|
<Icon as={Table2} mr={2} />
|
||||||
数据表格
|
数据表格
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaExpand,
|
Maximize,
|
||||||
FaCompress,
|
Minimize,
|
||||||
FaCamera,
|
Camera,
|
||||||
FaRedo,
|
RotateCcw,
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { MetricDataPoint } from '@services/categoryService';
|
import { MetricDataPoint } from '@services/categoryService';
|
||||||
|
|
||||||
// 黑金主题配色
|
// 黑金主题配色
|
||||||
@@ -386,7 +386,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={handleReset}
|
onClick={handleReset}
|
||||||
>
|
>
|
||||||
<Icon as={FaRedo} />
|
<Icon as={RotateCcw} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="截图">
|
<Tooltip label="截图">
|
||||||
@@ -397,7 +397,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={handleScreenshot}
|
onClick={handleScreenshot}
|
||||||
>
|
>
|
||||||
<Icon as={FaCamera} />
|
<Icon as={Camera} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
|
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'}>
|
||||||
@@ -408,7 +408,7 @@ const SimpleLineChart: React.FC<SimpleLineChartProps> = ({
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
>
|
>
|
||||||
<Icon as={isFullscreen ? FaCompress : FaExpand} />
|
<Icon as={isFullscreen ? Minimize : Maximize} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -21,17 +21,17 @@ import {
|
|||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaDatabase,
|
Database,
|
||||||
FaFolder,
|
Folder,
|
||||||
FaFolderOpen,
|
FolderOpen,
|
||||||
FaFile,
|
File,
|
||||||
FaSearch,
|
Search,
|
||||||
FaHome,
|
Home,
|
||||||
FaChevronRight,
|
ChevronRight,
|
||||||
FaChevronDown,
|
ChevronDown,
|
||||||
FaTimes,
|
X,
|
||||||
FaEye,
|
Eye,
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import {
|
import {
|
||||||
fetchCategoryTree,
|
fetchCategoryTree,
|
||||||
@@ -126,7 +126,7 @@ const TreeNodeComponent: React.FC<{
|
|||||||
<Spinner size="xs" color={themeColors.primary.gold} mr={2} />
|
<Spinner size="xs" color={themeColors.primary.gold} mr={2} />
|
||||||
) : hasChildren || !hasMetrics ? (
|
) : hasChildren || !hasMetrics ? (
|
||||||
<Icon
|
<Icon
|
||||||
as={isExpanded ? FaChevronDown : FaChevronRight}
|
as={isExpanded ? ChevronDown : ChevronRight}
|
||||||
color={themeColors.text.muted}
|
color={themeColors.text.muted}
|
||||||
mr={2}
|
mr={2}
|
||||||
fontSize="xs"
|
fontSize="xs"
|
||||||
@@ -136,7 +136,7 @@ const TreeNodeComponent: React.FC<{
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
as={hasChildren || !hasMetrics ? (isExpanded ? FaFolderOpen : FaFolder) : FaFile}
|
as={hasChildren || !hasMetrics ? (isExpanded ? FolderOpen : Folder) : File}
|
||||||
color={hasChildren || !hasMetrics ? themeColors.primary.gold : themeColors.text.secondary}
|
color={hasChildren || !hasMetrics ? themeColors.primary.gold : themeColors.text.secondary}
|
||||||
mr={2}
|
mr={2}
|
||||||
/>
|
/>
|
||||||
@@ -244,7 +244,7 @@ const MetricCard: React.FC<{ metric: TreeMetric; onClick: () => void }> = ({ met
|
|||||||
size="xs"
|
size="xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={themeColors.primary.gold}
|
color={themeColors.primary.gold}
|
||||||
leftIcon={<FaEye />}
|
leftIcon={<Eye />}
|
||||||
_hover={{ bg: themeColors.bg.cardHover }}
|
_hover={{ bg: themeColors.bg.cardHover }}
|
||||||
>
|
>
|
||||||
查看数据
|
查看数据
|
||||||
@@ -489,7 +489,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<VStack spacing={4} align="stretch" mb={8}>
|
<VStack spacing={4} align="stretch" mb={8}>
|
||||||
<HStack spacing={4}>
|
<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}>
|
<VStack align="start" spacing={0}>
|
||||||
<Text
|
<Text
|
||||||
fontSize="3xl"
|
fontSize="3xl"
|
||||||
@@ -568,7 +568,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<FaSearch />}
|
leftIcon={<Search />}
|
||||||
bg={themeColors.primary.gold}
|
bg={themeColors.primary.gold}
|
||||||
color={themeColors.bg.primary}
|
color={themeColors.bg.primary}
|
||||||
_hover={{ bg: themeColors.primary.goldLight }}
|
_hover={{ bg: themeColors.primary.goldLight }}
|
||||||
@@ -579,7 +579,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
{searchQuery && (
|
{searchQuery && (
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<FaTimes />}
|
leftIcon={<X />}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={themeColors.text.secondary}
|
color={themeColors.text.secondary}
|
||||||
_hover={{ color: themeColors.text.primary }}
|
_hover={{ color: themeColors.text.primary }}
|
||||||
@@ -625,7 +625,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
<CardBody py={2}>
|
<CardBody py={2}>
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
spacing={2}
|
spacing={2}
|
||||||
separator={<Icon as={FaChevronRight} color={themeColors.text.muted} />}
|
separator={<Icon as={ChevronRight} color={themeColors.text.muted} />}
|
||||||
>
|
>
|
||||||
<BreadcrumbItem>
|
<BreadcrumbItem>
|
||||||
<BreadcrumbLink
|
<BreadcrumbLink
|
||||||
@@ -633,7 +633,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
_hover={{ color: themeColors.primary.gold }}
|
_hover={{ color: themeColors.primary.gold }}
|
||||||
onClick={() => handleBreadcrumbClick(-1)}
|
onClick={() => handleBreadcrumbClick(-1)}
|
||||||
>
|
>
|
||||||
<Icon as={FaHome} />
|
<Icon as={Home} />
|
||||||
</BreadcrumbLink>
|
</BreadcrumbLink>
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
{breadcrumbs.map((crumb, index) => (
|
{breadcrumbs.map((crumb, index) => (
|
||||||
@@ -754,7 +754,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
) : searchResults ? (
|
) : searchResults ? (
|
||||||
<Flex justify="center" align="center" py={10}>
|
<Flex justify="center" align="center" py={10}>
|
||||||
<VStack spacing={3}>
|
<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}>未找到匹配的指标</Text>
|
||||||
<Text color={themeColors.text.muted} fontSize="sm">
|
<Text color={themeColors.text.muted} fontSize="sm">
|
||||||
尝试使用不同的关键词
|
尝试使用不同的关键词
|
||||||
@@ -837,7 +837,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Flex justify="center" align="center" py={10}>
|
<Flex justify="center" align="center" py={10}>
|
||||||
<VStack spacing={3}>
|
<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}>
|
<Text color={themeColors.text.muted}>
|
||||||
{currentNode.children && currentNode.children.length > 0
|
{currentNode.children && currentNode.children.length > 0
|
||||||
? '该节点包含子分类,请展开查看'
|
? '该节点包含子分类,请展开查看'
|
||||||
@@ -850,7 +850,7 @@ const DataBrowser: React.FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Flex justify="center" align="center" py={20}>
|
<Flex justify="center" align="center" py={20}>
|
||||||
<VStack spacing={4}>
|
<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 color={themeColors.text.secondary} fontSize="lg" textAlign="center">
|
||||||
选择左侧分类树节点查看详情
|
选择左侧分类树节点查看详情
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -25,15 +25,14 @@ import {
|
|||||||
StatArrow
|
StatArrow
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaHeart,
|
Heart,
|
||||||
FaRegHeart,
|
Eye,
|
||||||
FaEye,
|
MessageCircle,
|
||||||
FaComment,
|
Users,
|
||||||
FaUsers,
|
Clock,
|
||||||
FaClock,
|
Calendar,
|
||||||
FaCalendarAlt,
|
LineChart
|
||||||
FaChartLine
|
} from 'lucide-react';
|
||||||
} from 'react-icons/fa';
|
|
||||||
|
|
||||||
const EventHeader = ({ event, onFollowToggle }) => {
|
const EventHeader = ({ event, onFollowToggle }) => {
|
||||||
// 颜色主题
|
// 颜色主题
|
||||||
@@ -174,7 +173,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Icon as={FaCalendarAlt} color={textSecondary} />
|
<Icon as={Calendar} color={textSecondary} />
|
||||||
<VStack align="flex-start" spacing={0}>
|
<VStack align="flex-start" spacing={0}>
|
||||||
<Text fontSize="sm" color={textPrimary}>
|
<Text fontSize="sm" color={textPrimary}>
|
||||||
{formatDate(event.created_at)}
|
{formatDate(event.created_at)}
|
||||||
@@ -190,7 +189,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
{/* 右侧关注按钮 */}
|
{/* 右侧关注按钮 */}
|
||||||
<Flex align="flex-start" justify="center">
|
<Flex align="flex-start" justify="center">
|
||||||
<Button
|
<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"}
|
colorScheme={event.is_following ? "red" : "blue"}
|
||||||
variant={event.is_following ? "solid" : "outline"}
|
variant={event.is_following ? "solid" : "outline"}
|
||||||
size="lg"
|
size="lg"
|
||||||
@@ -226,7 +225,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
>
|
>
|
||||||
<StatLabel fontSize="xs" color={textSecondary}>
|
<StatLabel fontSize="xs" color={textSecondary}>
|
||||||
<HStack justify="center" spacing={1}>
|
<HStack justify="center" spacing={1}>
|
||||||
<Icon as={FaEye} />
|
<Icon as={Eye} />
|
||||||
<Text>浏览量</Text>
|
<Text>浏览量</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</StatLabel>
|
</StatLabel>
|
||||||
@@ -246,7 +245,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
>
|
>
|
||||||
<StatLabel fontSize="xs" color={textSecondary}>
|
<StatLabel fontSize="xs" color={textSecondary}>
|
||||||
<HStack justify="center" spacing={1}>
|
<HStack justify="center" spacing={1}>
|
||||||
<Icon as={FaComment} />
|
<Icon as={MessageCircle} />
|
||||||
<Text>回复数</Text>
|
<Text>回复数</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</StatLabel>
|
</StatLabel>
|
||||||
@@ -266,7 +265,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
>
|
>
|
||||||
<StatLabel fontSize="xs" color={textSecondary}>
|
<StatLabel fontSize="xs" color={textSecondary}>
|
||||||
<HStack justify="center" spacing={1}>
|
<HStack justify="center" spacing={1}>
|
||||||
<Icon as={FaUsers} />
|
<Icon as={Users} />
|
||||||
<Text>关注数</Text>
|
<Text>关注数</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</StatLabel>
|
</StatLabel>
|
||||||
@@ -286,7 +285,7 @@ const EventHeader = ({ event, onFollowToggle }) => {
|
|||||||
>
|
>
|
||||||
<StatLabel fontSize="xs" color={textSecondary}>
|
<StatLabel fontSize="xs" color={textSecondary}>
|
||||||
<HStack justify="center" spacing={1}>
|
<HStack justify="center" spacing={1}>
|
||||||
<Icon as={FaChartLine} />
|
<Icon as={LineChart} />
|
||||||
<Text>热度分</Text>
|
<Text>热度分</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</StatLabel>
|
</StatLabel>
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ import {
|
|||||||
Tooltip
|
Tooltip
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaChartLine,
|
LineChart,
|
||||||
FaInfoCircle
|
Info
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { Tag } from 'antd';
|
import { Tag } from 'antd';
|
||||||
import { RobotOutlined } from '@ant-design/icons';
|
import { RobotOutlined } from '@ant-design/icons';
|
||||||
import { stockService } from '@services/eventService';
|
import { stockService } from '@services/eventService';
|
||||||
@@ -230,7 +230,7 @@ const HistoricalEvents = ({
|
|||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
>
|
>
|
||||||
<HStack spacing={3}>
|
<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}>
|
<VStack align="flex-start" spacing={1}>
|
||||||
<Text fontSize="sm" fontWeight="bold" color="yellow.800">
|
<Text fontSize="sm" fontWeight="bold" color="yellow.800">
|
||||||
超预期得分: {expectationScore}
|
超预期得分: {expectationScore}
|
||||||
@@ -306,7 +306,7 @@ const HistoricalEvents = ({
|
|||||||
{/* 右侧:相关股票按钮 */}
|
{/* 右侧:相关股票按钮 */}
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
leftIcon={<Icon as={FaChartLine} />}
|
leftIcon={<Icon as={LineChart} boxSize={4} />}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleViewStocks(event);
|
handleViewStocks(event);
|
||||||
@@ -467,7 +467,7 @@ const StocksList = ({ stocks, eventTradingDate }) => {
|
|||||||
if (!stocks || stocks.length === 0) {
|
if (!stocks || stocks.length === 0) {
|
||||||
return (
|
return (
|
||||||
<Box textAlign="center" py={12} color={textSecondary}>
|
<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="lg" mb={2}>暂无相关股票数据</Text>
|
||||||
<Text fontSize="sm">该历史事件暂未关联股票信息</Text>
|
<Text fontSize="sm">该历史事件暂未关联股票信息</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -533,7 +533,7 @@ const StocksList = ({ stocks, eventTradingDate }) => {
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
colorScheme={stock.event_day_change_pct > 0 ? 'red' : stock.event_day_change_pct < 0 ? 'green' : 'gray'}
|
colorScheme={stock.event_day_change_pct > 0 ? 'red' : stock.event_day_change_pct < 0 ? 'green' : 'gray'}
|
||||||
onClick={() => handleOpenKLine(stock)}
|
onClick={() => handleOpenKLine(stock)}
|
||||||
rightIcon={<Icon as={FaChartLine} boxSize={3} />}
|
rightIcon={<Icon as={LineChart} boxSize={3} />}
|
||||||
px={2}
|
px={2}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -42,15 +42,15 @@ import {
|
|||||||
Container,
|
Container,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiTrendingUp,
|
TrendingUp,
|
||||||
FiBarChart2,
|
BarChart2,
|
||||||
FiPieChart,
|
PieChart,
|
||||||
FiActivity,
|
Activity,
|
||||||
FiDownload,
|
Download,
|
||||||
FiCalendar,
|
Calendar,
|
||||||
FiTarget,
|
Target,
|
||||||
FiZap,
|
Zap,
|
||||||
} from 'react-icons/fi';
|
} from 'lucide-react';
|
||||||
import 'echarts-wordcloud';
|
import 'echarts-wordcloud';
|
||||||
|
|
||||||
// 导入现有的卡片组件
|
// 导入现有的卡片组件
|
||||||
@@ -484,7 +484,7 @@ const LimitAnalyse = () => {
|
|||||||
<HStack justify="space-between" align="center">
|
<HStack justify="space-between" align="center">
|
||||||
<VStack align="start" spacing={2}>
|
<VStack align="start" spacing={2}>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="xl" fontWeight="bold">
|
||||||
涨停分析
|
涨停分析
|
||||||
</Text>
|
</Text>
|
||||||
@@ -508,7 +508,7 @@ const LimitAnalyse = () => {
|
|||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<FiDownload />}
|
leftIcon={<Icon as={Download} boxSize={4} />}
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => handleExport('excel')}
|
onClick={() => handleExport('excel')}
|
||||||
@@ -536,7 +536,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
板块分布
|
板块分布
|
||||||
</Text>
|
</Text>
|
||||||
@@ -564,7 +564,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
板块股票数量
|
板块股票数量
|
||||||
</Text>
|
</Text>
|
||||||
@@ -592,7 +592,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
板块关联TOP10
|
板块关联TOP10
|
||||||
</Text>
|
</Text>
|
||||||
@@ -637,7 +637,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
板块关联关系图
|
板块关联关系图
|
||||||
</Text>
|
</Text>
|
||||||
@@ -670,7 +670,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl" overflow="hidden">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
热点词云
|
热点词云
|
||||||
</Text>
|
</Text>
|
||||||
@@ -691,7 +691,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
数据统计
|
数据统计
|
||||||
</Text>
|
</Text>
|
||||||
@@ -700,25 +700,25 @@ const LimitAnalyse = () => {
|
|||||||
<CardBody>
|
<CardBody>
|
||||||
<Grid templateColumns="repeat(auto-fit, minmax(200px, 1fr))" gap={4}>
|
<Grid templateColumns="repeat(auto-fit, minmax(200px, 1fr))" gap={4}>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={FiTarget}
|
icon={Target}
|
||||||
label="涨停股票总数"
|
label="涨停股票总数"
|
||||||
value={totalStocks}
|
value={totalStocks}
|
||||||
color="blue"
|
color="blue"
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={FiBarChart2}
|
icon={BarChart2}
|
||||||
label="涉及板块数"
|
label="涉及板块数"
|
||||||
value={sectorCount}
|
value={sectorCount}
|
||||||
color="green"
|
color="green"
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={FiTrendingUp}
|
icon={TrendingUp}
|
||||||
label="平均涨幅"
|
label="平均涨幅"
|
||||||
value={`${avgChange}%`}
|
value={`${avgChange}%`}
|
||||||
color="orange"
|
color="orange"
|
||||||
/>
|
/>
|
||||||
<StatCard
|
<StatCard
|
||||||
icon={FiZap}
|
icon={Zap}
|
||||||
label="最大涨幅"
|
label="最大涨幅"
|
||||||
value={`${maxChange}%`}
|
value={`${maxChange}%`}
|
||||||
color="red"
|
color="red"
|
||||||
@@ -735,7 +735,7 @@ const LimitAnalyse = () => {
|
|||||||
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
|
<Card bg={cardBg} shadow="xl" borderRadius="2xl">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={3}>
|
<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 fontSize="lg" fontWeight="bold">
|
||||||
板块详细数据
|
板块详细数据
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
Center,
|
Center,
|
||||||
Divider
|
Divider
|
||||||
} from '@chakra-ui/react';
|
} 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 dayjs from 'dayjs';
|
||||||
import tradingDayUtils from '../../../utils/tradingDayUtils'; // 引入交易日工具
|
import tradingDayUtils from '../../../utils/tradingDayUtils'; // 引入交易日工具
|
||||||
import { logger } from '../../../utils/logger';
|
import { logger } from '../../../utils/logger';
|
||||||
@@ -230,7 +230,7 @@ const ConceptCard = ({ concept, tradingDate, onViewDetails }) => {
|
|||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
leftIcon={<FaChartLine />}
|
leftIcon={<Icon as={LineChart} boxSize={4} />}
|
||||||
flex={1}
|
flex={1}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -243,7 +243,7 @@ const ConceptCard = ({ concept, tradingDate, onViewDetails }) => {
|
|||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
leftIcon={<FaEye />}
|
leftIcon={<Icon as={Eye} boxSize={4} />}
|
||||||
flex={1}
|
flex={1}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -532,7 +532,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
<Button
|
<Button
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
size="lg"
|
size="lg"
|
||||||
leftIcon={<FaChartLine />}
|
leftIcon={<Icon as={LineChart} boxSize={5} />}
|
||||||
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
|
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
|
||||||
>
|
>
|
||||||
进入概念中心
|
进入概念中心
|
||||||
@@ -547,7 +547,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
{effectiveTradingDate && (
|
{effectiveTradingDate && (
|
||||||
<Box mb={4} p={3} bg={bgColor} borderRadius="md">
|
<Box mb={4} p={3} bg={bgColor} borderRadius="md">
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<FaCalendarAlt color={textColor} />
|
<Icon as={Calendar} color={textColor} boxSize={4} />
|
||||||
<Text fontSize="sm" color={textColor}>
|
<Text fontSize="sm" color={textColor}>
|
||||||
涨跌幅数据日期:{effectiveTradingDate}
|
涨跌幅数据日期:{effectiveTradingDate}
|
||||||
{eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && (
|
{eventTime && effectiveTradingDate !== dayjs(eventTime).format('YYYY-MM-DD') && (
|
||||||
@@ -578,7 +578,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
<Button
|
<Button
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
size="lg"
|
size="lg"
|
||||||
leftIcon={<FaChartLine />}
|
leftIcon={<Icon as={LineChart} boxSize={5} />}
|
||||||
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
|
onClick={() => window.open('https://valuefrontier.cn/concepts', '_blank')}
|
||||||
px={8}
|
px={8}
|
||||||
py={6}
|
py={6}
|
||||||
@@ -641,7 +641,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
{selectedConcept?.description && (
|
{selectedConcept?.description && (
|
||||||
<Box>
|
<Box>
|
||||||
<HStack mb={3}>
|
<HStack mb={3}>
|
||||||
<Icon as={FaChartLine} color="blue.500" />
|
<Icon as={LineChart} color="blue.500" />
|
||||||
<Text fontSize="md" fontWeight="bold">
|
<Text fontSize="md" fontWeight="bold">
|
||||||
概念解析
|
概念解析
|
||||||
</Text>
|
</Text>
|
||||||
@@ -666,7 +666,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
{selectedConcept?.happened_times && selectedConcept.happened_times.length > 0 && (
|
{selectedConcept?.happened_times && selectedConcept.happened_times.length > 0 && (
|
||||||
<Box>
|
<Box>
|
||||||
<HStack mb={3}>
|
<HStack mb={3}>
|
||||||
<Icon as={FaCalendarAlt} color="purple.500" />
|
<Icon as={Calendar} color="purple.500" />
|
||||||
<Text fontSize="md" fontWeight="bold">
|
<Text fontSize="md" fontWeight="bold">
|
||||||
历史触发时间
|
历史触发时间
|
||||||
</Text>
|
</Text>
|
||||||
@@ -691,7 +691,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
{selectedConcept?.stocks && selectedConcept.stocks.length > 0 && (
|
{selectedConcept?.stocks && selectedConcept.stocks.length > 0 && (
|
||||||
<Box>
|
<Box>
|
||||||
<HStack mb={3}>
|
<HStack mb={3}>
|
||||||
<Icon as={FaEye} color="green.500" />
|
<Icon as={Eye} color="green.500" />
|
||||||
<Text fontSize="md" fontWeight="bold">
|
<Text fontSize="md" fontWeight="bold">
|
||||||
核心相关股票 ({selectedConcept.stock_count}只)
|
核心相关股票 ({selectedConcept.stock_count}只)
|
||||||
</Text>
|
</Text>
|
||||||
@@ -760,7 +760,7 @@ const RelatedConcepts = ({ eventTitle, eventTime, eventId, loading: externalLoad
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open(`https://valuefrontier.cn/htmls/${encodeURIComponent(selectedConcept.concept)}.html`, '_blank');
|
window.open(`https://valuefrontier.cn/htmls/${encodeURIComponent(selectedConcept.concept)}.html`, '_blank');
|
||||||
}}
|
}}
|
||||||
leftIcon={<FaExternalLinkAlt />}
|
leftIcon={<Icon as={ExternalLink} boxSize={4} />}
|
||||||
>
|
>
|
||||||
查看概念详情页
|
查看概念详情页
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ import {
|
|||||||
useToast
|
useToast
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FaPlus,
|
Plus,
|
||||||
FaTrash,
|
Trash2,
|
||||||
FaChartLine,
|
LineChart,
|
||||||
FaRedo,
|
RefreshCw,
|
||||||
FaSearch
|
Search
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { echarts } from '@lib/echarts';
|
import { echarts } from '@lib/echarts';
|
||||||
import StockChartModal from '../../../components/StockChart/StockChartModal';
|
import StockChartModal from '../../../components/StockChart/StockChartModal';
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ const RelatedStocks = ({
|
|||||||
<Flex mb={4} align="center" wrap="wrap" gap={4}>
|
<Flex mb={4} align="center" wrap="wrap" gap={4}>
|
||||||
{/* 搜索框 */}
|
{/* 搜索框 */}
|
||||||
<HStack>
|
<HStack>
|
||||||
<FaSearch />
|
<Icon as={Search} boxSize={4} />
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索股票代码或名称..."
|
placeholder="搜索股票代码或名称..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
@@ -313,7 +313,7 @@ const RelatedStocks = ({
|
|||||||
<HStack>
|
<HStack>
|
||||||
<Tooltip label="刷新报价">
|
<Tooltip label="刷新报价">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FaRedo />}
|
icon={<Icon as={RefreshCw} boxSize={4} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleRefreshQuotes}
|
onClick={handleRefreshQuotes}
|
||||||
isLoading={quotesLoading}
|
isLoading={quotesLoading}
|
||||||
@@ -487,7 +487,7 @@ const RelatedStocks = ({
|
|||||||
|
|
||||||
<Tooltip label="查看K线图">
|
<Tooltip label="查看K线图">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FaChartLine />}
|
icon={<Icon as={LineChart} boxSize={3} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
onClick={() => handleShowChart(stock)}
|
onClick={() => handleShowChart(stock)}
|
||||||
aria-label="查看K线图"
|
aria-label="查看K线图"
|
||||||
@@ -496,7 +496,7 @@ const RelatedStocks = ({
|
|||||||
|
|
||||||
<Tooltip label="删除">
|
<Tooltip label="删除">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<FaTrash />}
|
icon={<Icon as={Trash2} boxSize={3} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Center
|
Center
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { InfoIcon, ViewIcon } from '@chakra-ui/icons';
|
import { Info, Eye, Share2, GitBranch, Inbox } from 'lucide-react';
|
||||||
import { Share2, GitBranch, Inbox } from 'lucide-react';
|
|
||||||
import ReactECharts from 'echarts-for-react';
|
import ReactECharts from 'echarts-for-react';
|
||||||
import { eventService } from '../../../services/eventService';
|
import { eventService } from '../../../services/eventService';
|
||||||
import CitedContent from '../../../components/Citation/CitedContent';
|
import CitedContent from '../../../components/Citation/CitedContent';
|
||||||
@@ -875,7 +874,7 @@ const TransmissionChainAnalysis = ({ eventId }) => {
|
|||||||
py={1}
|
py={1}
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
>
|
>
|
||||||
<Icon as={ViewIcon} mr={1} boxSize={3} />
|
<Eye size={12} style={{ display: 'inline', marginRight: '4px' }} />
|
||||||
点击节点查看详情
|
点击节点查看详情
|
||||||
</Text>
|
</Text>
|
||||||
{chartReady && (
|
{chartReady && (
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { getFormattedTextProps } from '../../../utils/textUtils';
|
import { getFormattedTextProps } from '../../../utils/textUtils';
|
||||||
import { ExternalLinkIcon } from '@chakra-ui/icons';
|
import { ExternalLink } from 'lucide-react';
|
||||||
import RiskDisclaimer from '../../../components/RiskDisclaimer';
|
import RiskDisclaimer from '../../../components/RiskDisclaimer';
|
||||||
import ReactECharts from 'echarts-for-react';
|
import ReactECharts from 'echarts-for-react';
|
||||||
import 'echarts-wordcloud';
|
import 'echarts-wordcloud';
|
||||||
@@ -760,7 +760,7 @@ export const StockDetailModal = ({ isOpen, onClose, selectedStock }) => {
|
|||||||
<Button variant="ghost" mr={3} onClick={onClose}>
|
<Button variant="ghost" mr={3} onClick={onClose}>
|
||||||
关闭
|
关闭
|
||||||
</Button>
|
</Button>
|
||||||
<Button colorScheme="blue" leftIcon={<ExternalLinkIcon />}>
|
<Button colorScheme="blue" leftIcon={<ExternalLink size={16} />}>
|
||||||
查看K线图
|
查看K线图
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
Alert,
|
Alert,
|
||||||
AlertIcon,
|
AlertIcon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ChevronLeftIcon, ChevronRightIcon, CalendarIcon } from '@chakra-ui/icons';
|
import { ChevronLeft, ChevronRight, Calendar } from 'lucide-react';
|
||||||
|
|
||||||
const EnhancedCalendar = ({
|
const EnhancedCalendar = ({
|
||||||
selectedDate,
|
selectedDate,
|
||||||
@@ -110,20 +110,20 @@ const EnhancedCalendar = ({
|
|||||||
<VStack spacing={3}>
|
<VStack spacing={3}>
|
||||||
<HStack justify="space-between" w="full">
|
<HStack justify="space-between" w="full">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronLeftIcon />}
|
icon={<ChevronLeft size={compact ? 16 : 20} />}
|
||||||
size={compact ? 'sm' : 'md'}
|
size={compact ? 'sm' : 'md'}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1))}
|
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1))}
|
||||||
aria-label="上个月"
|
aria-label="上个月"
|
||||||
/>
|
/>
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<CalendarIcon boxSize={5} />
|
<Calendar size={20} />
|
||||||
<Heading size={headerSize}>
|
<Heading size={headerSize}>
|
||||||
{currentMonth.getFullYear()}年 {monthNames[currentMonth.getMonth()]}
|
{currentMonth.getFullYear()}年 {monthNames[currentMonth.getMonth()]}
|
||||||
</Heading>
|
</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronRightIcon />}
|
icon={<ChevronRight size={compact ? 16 : 20} />}
|
||||||
size={compact ? 'sm' : 'md'}
|
size={compact ? 'sm' : 'md'}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1))}
|
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1))}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
Flex,
|
Flex,
|
||||||
Icon,
|
Icon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { StarIcon, TriangleUpIcon } from '@chakra-ui/icons';
|
import { Star, TrendingUp } from 'lucide-react';
|
||||||
import { logger } from '../../../utils/logger';
|
import { logger } from '../../../utils/logger';
|
||||||
import ztStaticService from '../../../services/ztStaticService';
|
import ztStaticService from '../../../services/ztStaticService';
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ const HighPositionStocks = ({ dateStr }) => {
|
|||||||
<CardHeader bg="red.500" color="white" borderTopRadius="xl">
|
<CardHeader bg="red.500" color="white" borderTopRadius="xl">
|
||||||
<Flex justify="space-between" align="center">
|
<Flex justify="space-between" align="center">
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<TriangleUpIcon boxSize={6} />
|
<TrendingUp size={24} />
|
||||||
<Heading size="md">高位股统计</Heading>
|
<Heading size="md">高位股统计</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
@@ -203,7 +203,7 @@ const HighPositionStocks = ({ dateStr }) => {
|
|||||||
<HStack>
|
<HStack>
|
||||||
<Text>{stock.stock_name}</Text>
|
<Text>{stock.stock_name}</Text>
|
||||||
{stock.continuous_limit_up >= 5 && (
|
{stock.continuous_limit_up >= 5 && (
|
||||||
<StarIcon color="red.500" boxSize={3} />
|
<Star size={12} color="#E53E3E" fill="#E53E3E" />
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
</Td>
|
</Td>
|
||||||
@@ -241,7 +241,7 @@ const HighPositionStocks = ({ dateStr }) => {
|
|||||||
{/* 风险提示 */}
|
{/* 风险提示 */}
|
||||||
<Box mt={4} p={3} bg="yellow.50" borderRadius="md" border="1px solid" borderColor="yellow.200">
|
<Box mt={4} p={3} bg="yellow.50" borderRadius="md" border="1px solid" borderColor="yellow.200">
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<Icon as={TriangleUpIcon} color="yellow.500" />
|
<Box as={TrendingUp} size={20} color="#D69E2E" />
|
||||||
<Text fontSize="sm" color="yellow.700">
|
<Text fontSize="sm" color="yellow.700">
|
||||||
<strong>风险提示:</strong>高位股通常具有较高的波动性和风险,请谨慎投资。
|
<strong>风险提示:</strong>高位股通常具有较高的波动性和风险,请谨慎投资。
|
||||||
连续涨停天数越多,风险相对越高。
|
连续涨停天数越多,风险相对越高。
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
AlertIcon,
|
AlertIcon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { formatTooltipText, getFormattedTextProps } from '../../../utils/textUtils';
|
import { formatTooltipText, getFormattedTextProps } from '../../../utils/textUtils';
|
||||||
import { SearchIcon, DownloadIcon } from '@chakra-ui/icons';
|
import { Search, Download } from 'lucide-react';
|
||||||
|
|
||||||
// 简化版搜索组件 - 仅支持股票代码/名称精确匹配
|
// 简化版搜索组件 - 仅支持股票代码/名称精确匹配
|
||||||
export const AdvancedSearch = ({ onSearch, loading }) => {
|
export const AdvancedSearch = ({ onSearch, loading }) => {
|
||||||
@@ -73,7 +73,7 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
|
|||||||
<HStack w="full" spacing={3}>
|
<HStack w="full" spacing={3}>
|
||||||
<InputGroup size="lg" flex={1}>
|
<InputGroup size="lg" flex={1}>
|
||||||
<InputLeftElement>
|
<InputLeftElement>
|
||||||
<SearchIcon color="gray.400" />
|
<Search size={20} color="#A0AEC0" />
|
||||||
</InputLeftElement>
|
</InputLeftElement>
|
||||||
<Input
|
<Input
|
||||||
placeholder="输入股票代码或名称搜索(如 600000 或 浦发银行)"
|
placeholder="输入股票代码或名称搜索(如 600000 或 浦发银行)"
|
||||||
@@ -89,7 +89,7 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
|
|||||||
onClick={handleSearch}
|
onClick={handleSearch}
|
||||||
isLoading={loading}
|
isLoading={loading}
|
||||||
px={8}
|
px={8}
|
||||||
leftIcon={<SearchIcon />}
|
leftIcon={<Search size={20} />}
|
||||||
>
|
>
|
||||||
搜索
|
搜索
|
||||||
</Button>
|
</Button>
|
||||||
@@ -152,7 +152,7 @@ export const SearchResultsModal = ({ isOpen, onClose, searchResults, onStockClic
|
|||||||
</Badge>
|
</Badge>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
leftIcon={<DownloadIcon />}
|
leftIcon={<Download size={16} />}
|
||||||
onClick={exportResults}
|
onClick={exportResults}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
colorScheme="whiteAlpha"
|
colorScheme="whiteAlpha"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
Link,
|
Link,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { StarIcon, TimeIcon, ExternalLinkIcon } from '@chakra-ui/icons';
|
import { Star, Clock, ExternalLink } from 'lucide-react';
|
||||||
|
|
||||||
const SectorDetails = ({ sortedSectors, totalStocks }) => {
|
const SectorDetails = ({ sortedSectors, totalStocks }) => {
|
||||||
// 使用 useRef 来维持展开状态,避免重新渲染时重置
|
// 使用 useRef 来维持展开状态,避免重新渲染时重置
|
||||||
@@ -141,7 +141,7 @@ const SectorDetails = ({ sortedSectors, totalStocks }) => {
|
|||||||
>
|
>
|
||||||
<Text fontWeight="bold" fontSize="md">{index + 1}</Text>
|
<Text fontWeight="bold" fontSize="md">{index + 1}</Text>
|
||||||
</Circle>
|
</Circle>
|
||||||
{sector === '公告' && <StarIcon />}
|
{sector === '公告' && <Star size={16} />}
|
||||||
<VStack align="start" spacing={0}>
|
<VStack align="start" spacing={0}>
|
||||||
<Text fontWeight="bold" fontSize="lg">{sector}</Text>
|
<Text fontWeight="bold" fontSize="lg">{sector}</Text>
|
||||||
<Text fontSize="sm" opacity={0.9}>
|
<Text fontSize="sm" opacity={0.9}>
|
||||||
@@ -190,7 +190,7 @@ const SectorDetails = ({ sortedSectors, totalStocks }) => {
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{stock.sname}
|
{stock.sname}
|
||||||
<ExternalLinkIcon mx="2px" boxSize={3} />
|
<Box as={ExternalLink} display="inline" size={12} style={{ marginLeft: '2px', marginRight: '2px', verticalAlign: 'middle' }} />
|
||||||
</Link>
|
</Link>
|
||||||
<Badge colorScheme="purple" fontSize="xs">{stock.scode}</Badge>
|
<Badge colorScheme="purple" fontSize="xs">{stock.scode}</Badge>
|
||||||
{stock.continuous_days && (
|
{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={4} fontSize="xs" color="gray.500" flex={1} justify="center">
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<TimeIcon boxSize={3} />
|
<Clock size={12} />
|
||||||
<Text>涨停: {formatStockTime(stock)}</Text>
|
<Text>涨停: {formatStockTime(stock)}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
{stock.first_time && (
|
{stock.first_time && (
|
||||||
|
|||||||
@@ -18,10 +18,7 @@ import {
|
|||||||
Alert,
|
Alert,
|
||||||
AlertIcon,
|
AlertIcon,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import { RefreshCw, ChevronUp } from 'lucide-react';
|
||||||
RepeatIcon,
|
|
||||||
ChevronUpIcon,
|
|
||||||
} from '@chakra-ui/icons';
|
|
||||||
|
|
||||||
// 导入拆分的组件
|
// 导入拆分的组件
|
||||||
// 注意:在实际使用中,这些组件应该被拆分到独立的文件中
|
// 注意:在实际使用中,这些组件应该被拆分到独立的文件中
|
||||||
@@ -414,7 +411,7 @@ export default function LimitAnalyse() {
|
|||||||
<VStack spacing={3}>
|
<VStack spacing={3}>
|
||||||
<Tooltip label="刷新数据" placement="left">
|
<Tooltip label="刷新数据" placement="left">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<RepeatIcon />}
|
icon={<RefreshCw size={20} />}
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
size="lg"
|
size="lg"
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
@@ -425,7 +422,7 @@ export default function LimitAnalyse() {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label="回到顶部" placement="left">
|
<Tooltip label="回到顶部" placement="left">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<ChevronUpIcon />}
|
icon={<ChevronUp size={20} />}
|
||||||
colorScheme="gray"
|
colorScheme="gray"
|
||||||
size="lg"
|
size="lg"
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
|
|||||||
@@ -41,13 +41,12 @@ import TransactionRow from 'components/Tables/TransactionRow';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
FaPaypal,
|
Wallet,
|
||||||
FaPencilAlt,
|
Edit2,
|
||||||
FaRegCalendarAlt,
|
Calendar,
|
||||||
FaWallet,
|
Gem,
|
||||||
FaGem,
|
CreditCard,
|
||||||
} from 'react-icons/fa';
|
} from 'lucide-react';
|
||||||
import { RiMastercardFill } from 'react-icons/ri';
|
|
||||||
import {
|
import {
|
||||||
billingData,
|
billingData,
|
||||||
invoicesData,
|
invoicesData,
|
||||||
@@ -101,7 +100,7 @@ function Billing() {
|
|||||||
Argon x Chakra
|
Argon x Chakra
|
||||||
</Text>
|
</Text>
|
||||||
<Icon
|
<Icon
|
||||||
as={RiMastercardFill}
|
as={CreditCard}
|
||||||
w='48px'
|
w='48px'
|
||||||
h='auto'
|
h='auto'
|
||||||
color='gray.400'
|
color='gray.400'
|
||||||
@@ -134,7 +133,7 @@ function Billing() {
|
|||||||
<Card p='16px' display='flex' align='center' justify='center'>
|
<Card p='16px' display='flex' align='center' justify='center'>
|
||||||
<Flex direction='column' align='center' w='100%' py='14px'>
|
<Flex direction='column' align='center' w='100%' py='14px'>
|
||||||
<IconBox h={'60px'} w={'60px'} bg={iconBlue}>
|
<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>
|
</IconBox>
|
||||||
<Flex
|
<Flex
|
||||||
direction='column'
|
direction='column'
|
||||||
@@ -171,7 +170,7 @@ function Billing() {
|
|||||||
py='14px'
|
py='14px'
|
||||||
>
|
>
|
||||||
<IconBox h={'60px'} w={'60px'} bg='purple.500'>
|
<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>
|
</IconBox>
|
||||||
<Flex
|
<Flex
|
||||||
direction='column'
|
direction='column'
|
||||||
@@ -248,7 +247,7 @@ function Billing() {
|
|||||||
<Spacer />
|
<Spacer />
|
||||||
<Button p='0px' w='16px' h='16px' variant='no-effects'>
|
<Button p='0px' w='16px' h='16px' variant='no-effects'>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaPencilAlt}
|
as={Edit2}
|
||||||
color={colorMode === 'dark' && 'white'}
|
color={colorMode === 'dark' && 'white'}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -277,7 +276,7 @@ function Billing() {
|
|||||||
variant='no-effects'
|
variant='no-effects'
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaPencilAlt}
|
as={Edit2}
|
||||||
color={colorMode === 'dark' && 'white'}
|
color={colorMode === 'dark' && 'white'}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
@@ -369,7 +368,7 @@ function Billing() {
|
|||||||
</Text>
|
</Text>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaRegCalendarAlt}
|
as={Calendar}
|
||||||
color='gray.400'
|
color='gray.400'
|
||||||
fontSize='md'
|
fontSize='md'
|
||||||
me='6px'
|
me='6px'
|
||||||
|
|||||||
@@ -56,14 +56,7 @@ import {
|
|||||||
} from 'components/Icons/Icons';
|
} from 'components/Icons/Icons';
|
||||||
import { HSeparator } from 'components/Separator/Separator';
|
import { HSeparator } from 'components/Separator/Separator';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { AiFillDelete } from 'react-icons/ai';
|
import { Trash2, ArrowRight, Circle, ToggleLeft, Box as BoxIcon, User, Smartphone, ChevronUp, Rocket, Bell, FileText, Power, Monitor } from 'lucide-react';
|
||||||
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 { Element, Link } from 'react-scroll';
|
import { Element, Link } from 'react-scroll';
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
@@ -293,7 +286,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={IoIosRocket}
|
as={Rocket}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -313,7 +306,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={IoDocumentText}
|
as={FileText}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -333,7 +326,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaCube}
|
as={Box}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -353,7 +346,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsToggleOn}
|
as={ToggleLeft}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -373,7 +366,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaUser}
|
as={User}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -393,7 +386,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={IoMdNotifications}
|
as={Bell}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -413,7 +406,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={MdPowerSettingsNew}
|
as={Power}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -433,7 +426,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center' justifySelf='flex-start' w='100%'>
|
<Flex align='center' justifySelf='flex-start' w='100%'>
|
||||||
<Icon
|
<Icon
|
||||||
as={AiFillDelete}
|
as={Trash2}
|
||||||
me='12px'
|
me='12px'
|
||||||
w='18px'
|
w='18px'
|
||||||
h='18px'
|
h='18px'
|
||||||
@@ -827,7 +820,8 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill='gray.500'
|
||||||
w='6px'
|
w='6px'
|
||||||
h='6px'
|
h='6px'
|
||||||
color='gray.500'
|
color='gray.500'
|
||||||
@@ -839,7 +833,8 @@ function Settings() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill='gray.500'
|
||||||
w='6px'
|
w='6px'
|
||||||
h='6px'
|
h='6px'
|
||||||
color='gray.500'
|
color='gray.500'
|
||||||
@@ -851,7 +846,8 @@ function Settings() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill='gray.500'
|
||||||
w='6px'
|
w='6px'
|
||||||
h='6px'
|
h='6px'
|
||||||
color='gray.500'
|
color='gray.500'
|
||||||
@@ -863,7 +859,8 @@ function Settings() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill='gray.500'
|
||||||
w='6px'
|
w='6px'
|
||||||
h='6px'
|
h='6px'
|
||||||
color='gray.500'
|
color='gray.500'
|
||||||
@@ -1059,7 +1056,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
Show Less
|
Show Less
|
||||||
</Text>
|
</Text>
|
||||||
<Icon as={IoIosArrowUp} color='gray.400' />
|
<Icon as={ChevronUp} color='gray.400' />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -1460,7 +1457,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={RiComputerLine}
|
as={Monitor}
|
||||||
me='30px'
|
me='30px'
|
||||||
w='28px'
|
w='28px'
|
||||||
h='28px'
|
h='28px'
|
||||||
@@ -1509,7 +1506,7 @@ function Settings() {
|
|||||||
See more
|
See more
|
||||||
</Text>
|
</Text>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsArrowRight}
|
as={ArrowRight}
|
||||||
w='20px'
|
w='20px'
|
||||||
h='20px'
|
h='20px'
|
||||||
transition='all .3s ease'
|
transition='all .3s ease'
|
||||||
@@ -1527,7 +1524,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={RiComputerLine}
|
as={Monitor}
|
||||||
me='30px'
|
me='30px'
|
||||||
w='28px'
|
w='28px'
|
||||||
h='28px'
|
h='28px'
|
||||||
@@ -1565,7 +1562,7 @@ function Settings() {
|
|||||||
See more
|
See more
|
||||||
</Text>
|
</Text>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsArrowRight}
|
as={ArrowRight}
|
||||||
w='20px'
|
w='20px'
|
||||||
h='20px'
|
h='20px'
|
||||||
transition='all .3s ease'
|
transition='all .3s ease'
|
||||||
@@ -1583,7 +1580,7 @@ function Settings() {
|
|||||||
>
|
>
|
||||||
<Flex align='center'>
|
<Flex align='center'>
|
||||||
<Icon
|
<Icon
|
||||||
as={GiSmartphone}
|
as={Smartphone}
|
||||||
me='30px'
|
me='30px'
|
||||||
w='28px'
|
w='28px'
|
||||||
h='28px'
|
h='28px'
|
||||||
@@ -1622,7 +1619,7 @@ function Settings() {
|
|||||||
See more
|
See more
|
||||||
</Text>
|
</Text>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsArrowRight}
|
as={ArrowRight}
|
||||||
w='20px'
|
w='20px'
|
||||||
h='20px'
|
h='20px'
|
||||||
transition='all .3s ease'
|
transition='all .3s ease'
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import microsoftLogo from "assets/svg/microsoft-logo.svg";
|
|||||||
import msnLogo from "assets/svg/msn-logo.svg";
|
import msnLogo from "assets/svg/msn-logo.svg";
|
||||||
import zohoLogo from "assets/svg/zoho-logo.svg";
|
import zohoLogo from "assets/svg/zoho-logo.svg";
|
||||||
import Card from "components/Card/Card";
|
import Card from "components/Card/Card";
|
||||||
import { FaCheckCircle, FaTimesCircle } from "react-icons/fa";
|
import { CheckCircle, XCircle } from "lucide-react";
|
||||||
|
|
||||||
function Pricing() {
|
function Pricing() {
|
||||||
const [activeButton, setActiveButton] = useState({
|
const [activeButton, setActiveButton] = useState({
|
||||||
@@ -155,7 +155,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -167,7 +167,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -179,7 +179,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -191,7 +191,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -203,7 +203,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -215,7 +215,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -244,7 +244,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -256,7 +256,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -268,7 +268,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -280,7 +280,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -292,7 +292,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -304,7 +304,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color={bgTimesIcon}
|
color={bgTimesIcon}
|
||||||
/>
|
/>
|
||||||
@@ -333,7 +333,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -345,7 +345,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -357,7 +357,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -369,7 +369,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -381,7 +381,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
@@ -393,7 +393,7 @@ function Pricing() {
|
|||||||
<Icon
|
<Icon
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
mr="8px"
|
mr="8px"
|
||||||
color="blue.500"
|
color="blue.500"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ import ImageArchitect1 from "assets/img/ImageArchitect1.png";
|
|||||||
import ImageArchitect2 from "assets/img/ImageArchitect2.png";
|
import ImageArchitect2 from "assets/img/ImageArchitect2.png";
|
||||||
import ImageArchitect3 from "assets/img/ImageArchitect3.png";
|
import ImageArchitect3 from "assets/img/ImageArchitect3.png";
|
||||||
import {
|
import {
|
||||||
FaCube,
|
Box,
|
||||||
FaFacebook,
|
Facebook,
|
||||||
FaInstagram,
|
Instagram,
|
||||||
FaPenFancy,
|
PenTool,
|
||||||
FaPlus,
|
Plus,
|
||||||
FaTwitter,
|
Twitter,
|
||||||
} from "react-icons/fa";
|
Files,
|
||||||
import { IoDocumentsSharp } from "react-icons/io5";
|
} from "lucide-react";
|
||||||
// Custom components
|
// Custom components
|
||||||
import Card from "components/Card/Card";
|
import Card from "components/Card/Card";
|
||||||
import CardBody from "components/Card/CardBody";
|
import CardBody from "components/Card/CardBody";
|
||||||
@@ -170,7 +170,7 @@ function Overview() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
OVERVIEW
|
OVERVIEW
|
||||||
</Text>
|
</Text>
|
||||||
@@ -200,7 +200,7 @@ function Overview() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "teams" })
|
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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
TEAMS
|
TEAMS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -229,7 +229,7 @@ function Overview() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
PROJECTS
|
PROJECTS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -411,7 +411,7 @@ function Overview() {
|
|||||||
me="10px"
|
me="10px"
|
||||||
_hover={{ color: "blue.500" }}
|
_hover={{ color: "blue.500" }}
|
||||||
>
|
>
|
||||||
<Icon as={FaFacebook} />
|
<Icon as={Facebook} />
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="#"
|
href="#"
|
||||||
@@ -420,7 +420,7 @@ function Overview() {
|
|||||||
me="10px"
|
me="10px"
|
||||||
_hover={{ color: "blue.500" }}
|
_hover={{ color: "blue.500" }}
|
||||||
>
|
>
|
||||||
<Icon as={FaInstagram} />
|
<Icon as={Instagram} />
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="#"
|
href="#"
|
||||||
@@ -429,7 +429,7 @@ function Overview() {
|
|||||||
me="10px"
|
me="10px"
|
||||||
_hover={{ color: "blue.500" }}
|
_hover={{ color: "blue.500" }}
|
||||||
>
|
>
|
||||||
<Icon as={FaTwitter} />
|
<Icon as={Twitter} />
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -741,7 +741,7 @@ function Overview() {
|
|||||||
minHeight={{ sm: "200px", md: "100%" }}
|
minHeight={{ sm: "200px", md: "100%" }}
|
||||||
>
|
>
|
||||||
<Flex direction="column" justifyContent="center" align="center">
|
<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">
|
<Text fontSize="lg" color={textColor} fontWeight="bold">
|
||||||
Create a New Project
|
Create a New Project
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ import {
|
|||||||
} from "components/Icons/Icons";
|
} from "components/Icons/Icons";
|
||||||
import { HSeparator } from "components/Separator/Separator";
|
import { HSeparator } from "components/Separator/Separator";
|
||||||
import React, { useReducer } from "react";
|
import React, { useReducer } from "react";
|
||||||
import { BsPlus } from "react-icons/bs";
|
import { Plus, Box, PenTool, Files, MoreVertical } from "lucide-react";
|
||||||
import { FaCube, FaPenFancy } from "react-icons/fa";
|
|
||||||
import { IoDocumentsSharp, IoEllipsisVerticalSharp } from "react-icons/io5";
|
|
||||||
|
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
if (action.type === "SWITCH_ACTIVE") {
|
if (action.type === "SWITCH_ACTIVE") {
|
||||||
@@ -205,7 +203,7 @@ function Projects() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
OVERVIEW
|
OVERVIEW
|
||||||
</Text>
|
</Text>
|
||||||
@@ -235,7 +233,7 @@ function Projects() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "teams" })
|
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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
TEAMS
|
TEAMS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -264,7 +262,7 @@ function Projects() {
|
|||||||
dispatch({ type: "SWITCH_ACTIVE", payload: "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">
|
<Text fontSize="xs" color={textColor} fontWeight="bold">
|
||||||
PROJECTS
|
PROJECTS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -324,7 +322,7 @@ function Projects() {
|
|||||||
<Menu isOpen={isOpen1} onClose={onClose1}>
|
<Menu isOpen={isOpen1} onClose={onClose1}>
|
||||||
<MenuButton onClick={onOpen1} alignSelf="flex-start">
|
<MenuButton onClick={onOpen1} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisVerticalSharp}
|
as={MoreVertical}
|
||||||
color="gray.400"
|
color="gray.400"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -408,7 +406,7 @@ function Projects() {
|
|||||||
<Menu isOpen={isOpen2} onClose={onClose2}>
|
<Menu isOpen={isOpen2} onClose={onClose2}>
|
||||||
<MenuButton onClick={onOpen2} alignSelf="flex-start">
|
<MenuButton onClick={onOpen2} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisVerticalSharp}
|
as={MoreVertical}
|
||||||
color="gray.400"
|
color="gray.400"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -494,7 +492,7 @@ function Projects() {
|
|||||||
<Menu isOpen={isOpen3} onClose={onClose3}>
|
<Menu isOpen={isOpen3} onClose={onClose3}>
|
||||||
<MenuButton onClick={onOpen3} alignSelf="flex-start">
|
<MenuButton onClick={onOpen3} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisVerticalSharp}
|
as={MoreVertical}
|
||||||
color="gray.400"
|
color="gray.400"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -576,7 +574,7 @@ function Projects() {
|
|||||||
<Menu isOpen={isOpen4} onClose={onClose4}>
|
<Menu isOpen={isOpen4} onClose={onClose4}>
|
||||||
<MenuButton onClick={onOpen4} alignSelf="flex-start">
|
<MenuButton onClick={onOpen4} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisVerticalSharp}
|
as={MoreVertical}
|
||||||
color="gray.400"
|
color="gray.400"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -659,7 +657,7 @@ function Projects() {
|
|||||||
<Menu isOpen={isOpen5} onClose={onClose5}>
|
<Menu isOpen={isOpen5} onClose={onClose5}>
|
||||||
<MenuButton onClick={onOpen5} alignSelf="flex-start">
|
<MenuButton onClick={onOpen5} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisVerticalSharp}
|
as={MoreVertical}
|
||||||
color="gray.400"
|
color="gray.400"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -722,7 +720,7 @@ function Projects() {
|
|||||||
color={secondaryColor}
|
color={secondaryColor}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
as={BsPlus}
|
as={Plus}
|
||||||
w="30px"
|
w="30px"
|
||||||
h="30px"
|
h="30px"
|
||||||
mb="12px"
|
mb="12px"
|
||||||
|
|||||||
@@ -49,10 +49,7 @@ import avatar7 from 'assets/img/avatars/avatar7.png';
|
|||||||
import avatar8 from 'assets/img/avatars/avatar8.png';
|
import avatar8 from 'assets/img/avatars/avatar8.png';
|
||||||
import avatar9 from 'assets/img/avatars/avatar9.png';
|
import avatar9 from 'assets/img/avatars/avatar9.png';
|
||||||
import teamsImage from 'assets/img/teams-image.png';
|
import teamsImage from 'assets/img/teams-image.png';
|
||||||
import { AiFillLike, AiOutlinePlus } from 'react-icons/ai';
|
import { ThumbsUp, Plus, MessageCircle, Box as BoxIcon, PenTool, Star, Share2, StarHalf, Files, MoreVertical } from 'lucide-react';
|
||||||
import { FaCommentDots, FaCube, FaPenFancy, FaPlus } from 'react-icons/fa';
|
|
||||||
import { IoIosStar, IoMdShareAlt, IoMdStarHalf } from 'react-icons/io';
|
|
||||||
import { IoDocumentsSharp, IoEllipsisVerticalSharp } from 'react-icons/io5';
|
|
||||||
// Custom components
|
// Custom components
|
||||||
import Card from 'components/Card/Card.js';
|
import Card from 'components/Card/Card.js';
|
||||||
import CardBody from 'components/Card/CardBody.js';
|
import CardBody from 'components/Card/CardBody.js';
|
||||||
@@ -163,7 +160,7 @@ function Teams() {
|
|||||||
cursor='pointer'
|
cursor='pointer'
|
||||||
transition='all .5s ease'
|
transition='all .5s ease'
|
||||||
onClick={() => dispatch({ type: 'SWITCH_ACTIVE', payload: 'overview' })}>
|
onClick={() => 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'>
|
<Text fontSize='xs' color={textColor} fontWeight='bold'>
|
||||||
OVERVIEW
|
OVERVIEW
|
||||||
</Text>
|
</Text>
|
||||||
@@ -182,7 +179,7 @@ function Teams() {
|
|||||||
bg={state.teams ? colorMode === 'dark' ? 'navy.900' : '#fff' : null}
|
bg={state.teams ? colorMode === 'dark' ? 'navy.900' : '#fff' : null}
|
||||||
transition='all .5s ease'
|
transition='all .5s ease'
|
||||||
onClick={() => dispatch({ type: 'SWITCH_ACTIVE', payload: 'teams' })}>
|
onClick={() => 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'>
|
<Text fontSize='xs' color={textColor} fontWeight='bold'>
|
||||||
TEAMS
|
TEAMS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -200,7 +197,7 @@ function Teams() {
|
|||||||
bg={state.projects ? colorMode === 'dark' ? 'navy.900' : '#fff' : null}
|
bg={state.projects ? colorMode === 'dark' ? 'navy.900' : '#fff' : null}
|
||||||
transition='all .5s ease'
|
transition='all .5s ease'
|
||||||
onClick={() => dispatch({ type: 'SWITCH_ACTIVE', payload: 'projects' })}>
|
onClick={() => 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'>
|
<Text fontSize='xs' color={textColor} fontWeight='bold'>
|
||||||
PROJECTS
|
PROJECTS
|
||||||
</Text>
|
</Text>
|
||||||
@@ -224,7 +221,7 @@ function Teams() {
|
|||||||
w='62px'
|
w='62px'
|
||||||
h='58px'
|
h='58px'
|
||||||
mb='7px'>
|
mb='7px'>
|
||||||
<Icon as={FaPlus} w='16px' h='16px' color='#fff' />
|
<Icon as={Plus} w='16px' h='16px' color='#fff' />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Link>
|
</Link>
|
||||||
<Text fontSize='sm' color='gray.400' fontWeight='normal'>
|
<Text fontSize='sm' color='gray.400' fontWeight='normal'>
|
||||||
@@ -407,7 +404,7 @@ function Teams() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Button variant='primary' p='8px 32px'>
|
<Button variant='primary' p='8px 32px'>
|
||||||
<Flex align='center' color='#fff' justifyContent='center'>
|
<Flex align='center' color='#fff' justifyContent='center'>
|
||||||
<Icon as={AiOutlinePlus} w='18px' h='18px' fontWeight='bold' me='4px' />
|
<Icon as={Plus} w='18px' h='18px' fontWeight='bold' me='4px' />
|
||||||
<Text fontSize='10px' fontWeight='bold' mt='4px'>
|
<Text fontSize='10px' fontWeight='bold' mt='4px'>
|
||||||
FOLLOW
|
FOLLOW
|
||||||
</Text>
|
</Text>
|
||||||
@@ -427,15 +424,15 @@ function Teams() {
|
|||||||
<Flex justify='space-between' align='center' my='6px'>
|
<Flex justify='space-between' align='center' my='6px'>
|
||||||
<Stack spacing='20px' direction='row' my='18px'>
|
<Stack spacing='20px' direction='row' my='18px'>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={AiFillLike} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={ThumbsUp} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>1502</Text>
|
<Text fontSize='md'>1502</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={FaCommentDots} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={MessageCircle} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>36</Text>
|
<Text fontSize='md'>36</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={IoMdShareAlt} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={Share2} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>12</Text>
|
<Text fontSize='md'>12</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -466,11 +463,11 @@ function Teams() {
|
|||||||
</Text>
|
</Text>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex align='center' color='gray.500' me='21px'>
|
<Flex align='center' color='gray.500' me='21px'>
|
||||||
<Icon as={AiFillLike} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={ThumbsUp} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>3 likes</Text>
|
<Text fontSize='md'>3 likes</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={IoMdShareAlt} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={Share2} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>2 shares</Text>
|
<Text fontSize='md'>2 shares</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -491,11 +488,11 @@ function Teams() {
|
|||||||
</Text>
|
</Text>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex align='center' color='gray.500' me='21px'>
|
<Flex align='center' color='gray.500' me='21px'>
|
||||||
<Icon as={AiFillLike} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={ThumbsUp} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>10 likes</Text>
|
<Text fontSize='md'>10 likes</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={IoMdShareAlt} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={Share2} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>1 share</Text>
|
<Text fontSize='md'>1 share</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -515,11 +512,11 @@ function Teams() {
|
|||||||
</Text>
|
</Text>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex align='center' color='gray.500' me='21px'>
|
<Flex align='center' color='gray.500' me='21px'>
|
||||||
<Icon as={AiFillLike} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={ThumbsUp} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>42 likes</Text>
|
<Text fontSize='md'>42 likes</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex align='center' color='gray.500'>
|
<Flex align='center' color='gray.500'>
|
||||||
<Icon as={IoMdShareAlt} w='18px' h='18px' me='4px' cursor='pointer' />
|
<Icon as={Share2} w='18px' h='18px' me='4px' cursor='pointer' />
|
||||||
<Text fontSize='md'>6 shares</Text>
|
<Text fontSize='md'>6 shares</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -548,7 +545,7 @@ function Teams() {
|
|||||||
<Flex as='div' variant='no-effects' p='0px'>
|
<Flex as='div' variant='no-effects' p='0px'>
|
||||||
<Menu isOpen={isOpen1} onClose={onClose1}>
|
<Menu isOpen={isOpen1} onClose={onClose1}>
|
||||||
<MenuButton onClick={onOpen1} alignSelf='flex-start'>
|
<MenuButton onClick={onOpen1} alignSelf='flex-start'>
|
||||||
<Icon as={IoEllipsisVerticalSharp} color='gray.400' w='20px' h='20px' />
|
<Icon as={MoreVertical} color='gray.400' w='20px' h='20px' />
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList>
|
<MenuList>
|
||||||
<MenuItem>Action</MenuItem>
|
<MenuItem>Action</MenuItem>
|
||||||
@@ -575,11 +572,11 @@ function Teams() {
|
|||||||
<Flex justify='space-between' align='center'>
|
<Flex justify='space-between' align='center'>
|
||||||
<Text color='gray.400'>Rating:</Text>
|
<Text color='gray.400'>Rating:</Text>
|
||||||
<Stack direction='row' spacing='2px'>
|
<Stack direction='row' spacing='2px'>
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoMdStarHalf} />
|
<Icon as={StarHalf} fill="currentColor" />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Flex>
|
</Flex>
|
||||||
<HSeparator my='14px' />
|
<HSeparator my='14px' />
|
||||||
@@ -604,7 +601,7 @@ function Teams() {
|
|||||||
<Flex variant='no-effects' p='0px'>
|
<Flex variant='no-effects' p='0px'>
|
||||||
<Menu isOpen={isOpen2} onClose={onClose2}>
|
<Menu isOpen={isOpen2} onClose={onClose2}>
|
||||||
<MenuButton onClick={onOpen2} alignSelf='flex-start'>
|
<MenuButton onClick={onOpen2} alignSelf='flex-start'>
|
||||||
<Icon as={IoEllipsisVerticalSharp} color='gray.400' w='20px' h='20px' />
|
<Icon as={MoreVertical} color='gray.400' w='20px' h='20px' />
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList>
|
<MenuList>
|
||||||
<MenuItem>Action</MenuItem>
|
<MenuItem>Action</MenuItem>
|
||||||
@@ -631,11 +628,11 @@ function Teams() {
|
|||||||
<Flex justify='space-between' align='center'>
|
<Flex justify='space-between' align='center'>
|
||||||
<Text color='gray.400'>Rating:</Text>
|
<Text color='gray.400'>Rating:</Text>
|
||||||
<Stack direction='row' spacing='2px'>
|
<Stack direction='row' spacing='2px'>
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoIosStar} />
|
<Icon as={Star} fill="currentColor" />
|
||||||
<Icon as={IoMdStarHalf} />
|
<Icon as={StarHalf} fill="currentColor" />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Flex>
|
</Flex>
|
||||||
<HSeparator my='14px' />
|
<HSeparator my='14px' />
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import Card from "components/Card/Card";
|
|||||||
import CardBody from "components/Card/CardBody";
|
import CardBody from "components/Card/CardBody";
|
||||||
import CardHeader from "components/Card/CardHeader";
|
import CardHeader from "components/Card/CardHeader";
|
||||||
// Assets
|
// Assets
|
||||||
import { BsCircleFill } from "react-icons/bs";
|
import { Circle } from "lucide-react";
|
||||||
|
|
||||||
function NewUser() {
|
function NewUser() {
|
||||||
const textColor = useColorModeValue("gray.700", "white");
|
const textColor = useColorModeValue("gray.700", "white");
|
||||||
@@ -102,7 +102,8 @@ function NewUser() {
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
zIndex="1"
|
zIndex="1"
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill={activeBullets.userInfo ? "white" : "blue.300"}
|
||||||
color={activeBullets.userInfo ? "white" : "blue.300"}
|
color={activeBullets.userInfo ? "white" : "blue.300"}
|
||||||
w={activeBullets.userInfo ? "16px" : "12px"}
|
w={activeBullets.userInfo ? "16px" : "12px"}
|
||||||
h={activeBullets.userInfo ? "16px" : "12px"}
|
h={activeBullets.userInfo ? "16px" : "12px"}
|
||||||
@@ -150,7 +151,8 @@ function NewUser() {
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
zIndex="1"
|
zIndex="1"
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill={activeBullets.address ? "white" : "blue.300"}
|
||||||
color={activeBullets.address ? "white" : "blue.300"}
|
color={activeBullets.address ? "white" : "blue.300"}
|
||||||
w={activeBullets.address ? "16px" : "12px"}
|
w={activeBullets.address ? "16px" : "12px"}
|
||||||
h={activeBullets.address ? "16px" : "12px"}
|
h={activeBullets.address ? "16px" : "12px"}
|
||||||
@@ -200,7 +202,8 @@ function NewUser() {
|
|||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
zIndex="1"
|
zIndex="1"
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill={activeBullets.socials ? "white" : "blue.300"}
|
||||||
color={activeBullets.socials ? "white" : "blue.300"}
|
color={activeBullets.socials ? "white" : "blue.300"}
|
||||||
w={activeBullets.socials ? "16px" : "12px"}
|
w={activeBullets.socials ? "16px" : "12px"}
|
||||||
h={activeBullets.socials ? "16px" : "12px"}
|
h={activeBullets.socials ? "16px" : "12px"}
|
||||||
@@ -233,7 +236,8 @@ function NewUser() {
|
|||||||
<Flex direction="column" justify="center" align="center">
|
<Flex direction="column" justify="center" align="center">
|
||||||
<Icon
|
<Icon
|
||||||
zIndex="1"
|
zIndex="1"
|
||||||
as={BsCircleFill}
|
as={Circle}
|
||||||
|
fill={activeBullets.profile ? "white" : "blue.300"}
|
||||||
color={activeBullets.profile ? "white" : "blue.300"}
|
color={activeBullets.profile ? "white" : "blue.300"}
|
||||||
w={activeBullets.profile ? "16px" : "12px"}
|
w={activeBullets.profile ? "16px" : "12px"}
|
||||||
h={activeBullets.profile ? "16px" : "12px"}
|
h={activeBullets.profile ? "16px" : "12px"}
|
||||||
|
|||||||
@@ -46,9 +46,7 @@ import IconBox from "components/Icons/IconBox";
|
|||||||
import { CartIcon, RocketIcon } from "components/Icons/Icons";
|
import { CartIcon, RocketIcon } from "components/Icons/Icons";
|
||||||
import TablesReportsRow from "components/Tables/TablesReportsRow";
|
import TablesReportsRow from "components/Tables/TablesReportsRow";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { AiFillLike } from "react-icons/ai";
|
import { ThumbsUp, User, MoreHorizontal } from "lucide-react";
|
||||||
import { FaUser } from "react-icons/fa";
|
|
||||||
import { IoEllipsisHorizontalSharp } from "react-icons/io5";
|
|
||||||
import { tablesReportsData } from "variables/general";
|
import { tablesReportsData } from "variables/general";
|
||||||
|
|
||||||
function Reports() {
|
function Reports() {
|
||||||
@@ -108,12 +106,12 @@ function Reports() {
|
|||||||
>
|
>
|
||||||
<Flex justify="space-between" w="100%">
|
<Flex justify="space-between" w="100%">
|
||||||
<IconBox bg="#fff" w="50px" h="50px">
|
<IconBox bg="#fff" w="50px" h="50px">
|
||||||
<Icon as={FaUser} w="25px" h="25px" color="blue.900" />
|
<Icon as={User} w="25px" h="25px" color="blue.900" />
|
||||||
</IconBox>
|
</IconBox>
|
||||||
<Menu isOpen={isOpen1} onClose={onClose1}>
|
<Menu isOpen={isOpen1} onClose={onClose1}>
|
||||||
<MenuButton onClick={onOpen1} alignSelf="flex-start">
|
<MenuButton onClick={onOpen1} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisHorizontalSharp}
|
as={MoreHorizontal}
|
||||||
color={iconColor}
|
color={iconColor}
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -173,7 +171,7 @@ function Reports() {
|
|||||||
<Menu isOpen={isOpen2} onClose={onClose2}>
|
<Menu isOpen={isOpen2} onClose={onClose2}>
|
||||||
<MenuButton onClick={onOpen2} alignSelf="flex-start">
|
<MenuButton onClick={onOpen2} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisHorizontalSharp}
|
as={MoreHorizontal}
|
||||||
color={iconColor}
|
color={iconColor}
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -233,7 +231,7 @@ function Reports() {
|
|||||||
<Menu isOpen={isOpen3} onClose={onClose3}>
|
<Menu isOpen={isOpen3} onClose={onClose3}>
|
||||||
<MenuButton onClick={onOpen3} alignSelf="flex-start">
|
<MenuButton onClick={onOpen3} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisHorizontalSharp}
|
as={MoreHorizontal}
|
||||||
color={iconColor}
|
color={iconColor}
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -289,12 +287,12 @@ function Reports() {
|
|||||||
>
|
>
|
||||||
<Flex justify="space-between" w="100%">
|
<Flex justify="space-between" w="100%">
|
||||||
<IconBox bg="#fff" w="50px" h="50px">
|
<IconBox bg="#fff" w="50px" h="50px">
|
||||||
<Icon as={AiFillLike} w="25px" h="25px" color="blue.900" />
|
<Icon as={ThumbsUp} w="25px" h="25px" color="blue.900" />
|
||||||
</IconBox>
|
</IconBox>
|
||||||
<Menu isOpen={isOpen4} onClose={onClose4}>
|
<Menu isOpen={isOpen4} onClose={onClose4}>
|
||||||
<MenuButton onClick={onOpen4} alignSelf="flex-start">
|
<MenuButton onClick={onOpen4} alignSelf="flex-start">
|
||||||
<Icon
|
<Icon
|
||||||
as={IoEllipsisHorizontalSharp}
|
as={MoreHorizontal}
|
||||||
color={iconColor}
|
color={iconColor}
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
Heading,
|
Heading,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { FaCheckCircle, FaTimesCircle } from "react-icons/fa";
|
import { CheckCircle, XCircle } from "lucide-react";
|
||||||
import { authService } from "../../services/authService";
|
import { authService } from "../../services/authService";
|
||||||
import { useAuth } from "../../contexts/AuthContext";
|
import { useAuth } from "../../contexts/AuthContext";
|
||||||
import { logger } from "../../utils/logger";
|
import { logger } from "../../utils/logger";
|
||||||
@@ -144,7 +144,7 @@ export default function WechatCallback() {
|
|||||||
{status === "success" && (
|
{status === "success" && (
|
||||||
<>
|
<>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaCheckCircle}
|
as={CheckCircle}
|
||||||
w={16}
|
w={16}
|
||||||
h={16}
|
h={16}
|
||||||
color="green.500"
|
color="green.500"
|
||||||
@@ -158,7 +158,7 @@ export default function WechatCallback() {
|
|||||||
{status === "error" && (
|
{status === "error" && (
|
||||||
<>
|
<>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaTimesCircle}
|
as={XCircle}
|
||||||
w={16}
|
w={16}
|
||||||
h={16}
|
h={16}
|
||||||
color="red.500"
|
color="red.500"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import {
|
|||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
useDisclosure
|
useDisclosure
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { EditIcon, CheckIcon, CloseIcon, AddIcon } from '@chakra-ui/icons';
|
import { Pencil, Check, X, Plus } from 'lucide-react';
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
import { useProfileEvents } from '../../hooks/useProfileEvents';
|
import { useProfileEvents } from '../../hooks/useProfileEvents';
|
||||||
@@ -189,7 +189,7 @@ export default function ProfilePage() {
|
|||||||
<Heading size="lg" color="gray.800">个人资料</Heading>
|
<Heading size="lg" color="gray.800">个人资料</Heading>
|
||||||
{!isEditing ? (
|
{!isEditing ? (
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<EditIcon />}
|
leftIcon={<Pencil size={16} />}
|
||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
onClick={() => setIsEditing(true)}
|
onClick={() => setIsEditing(true)}
|
||||||
>
|
>
|
||||||
@@ -198,7 +198,7 @@ export default function ProfilePage() {
|
|||||||
) : (
|
) : (
|
||||||
<HStack>
|
<HStack>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<CheckIcon />}
|
leftIcon={<Check size={16} />}
|
||||||
colorScheme="green"
|
colorScheme="green"
|
||||||
onClick={handleSaveProfile}
|
onClick={handleSaveProfile}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -206,7 +206,7 @@ export default function ProfilePage() {
|
|||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<CloseIcon />}
|
leftIcon={<X size={16} />}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
colorScheme="gray"
|
colorScheme="gray"
|
||||||
color="gray.300"
|
color="gray.300"
|
||||||
@@ -496,7 +496,7 @@ export default function ProfilePage() {
|
|||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<AddIcon />}
|
icon={<Plus size={16} />}
|
||||||
onClick={addMarketTag}
|
onClick={addMarketTag}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|||||||
@@ -31,12 +31,8 @@ import {
|
|||||||
PinInput,
|
PinInput,
|
||||||
PinInputField
|
PinInputField
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import { Link2, Trash2, Pencil, Smartphone, Mail } from 'lucide-react';
|
||||||
LinkIcon,
|
import { WechatOutlined } from '@ant-design/icons';
|
||||||
DeleteIcon,
|
|
||||||
EditIcon
|
|
||||||
} from '@chakra-ui/icons';
|
|
||||||
import { FaWeixin, FaMobile, FaEnvelope } from 'react-icons/fa';
|
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
import { getApiBase } from '../../utils/apiConfig';
|
import { getApiBase } from '../../utils/apiConfig';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
@@ -241,7 +237,7 @@ export default function SettingsPage() {
|
|||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<VStack align="start" spacing={1}>
|
<VStack align="start" spacing={1}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<FaMobile />
|
<Smartphone />
|
||||||
<Text fontWeight="medium" color={textColor}>
|
<Text fontWeight="medium" color={textColor}>
|
||||||
{user?.phone || '未绑定手机号'}
|
{user?.phone || '未绑定手机号'}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -255,7 +251,7 @@ export default function SettingsPage() {
|
|||||||
</VStack>
|
</VStack>
|
||||||
{user?.phone ? (
|
{user?.phone ? (
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<DeleteIcon />}
|
leftIcon={<Trash2 size={16} />}
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@@ -280,7 +276,7 @@ export default function SettingsPage() {
|
|||||||
解绑
|
解绑
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button leftIcon={<LinkIcon />} onClick={onPhoneOpen}>
|
<Button leftIcon={<Link2 size={16} />} onClick={onPhoneOpen}>
|
||||||
绑定手机号
|
绑定手机号
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -297,7 +293,7 @@ export default function SettingsPage() {
|
|||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<VStack align="start" spacing={1}>
|
<VStack align="start" spacing={1}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<FaEnvelope />
|
<Mail />
|
||||||
<Text fontWeight="medium" color={textColor}>{user?.email}</Text>
|
<Text fontWeight="medium" color={textColor}>{user?.email}</Text>
|
||||||
{user?.email_confirmed && (
|
{user?.email_confirmed && (
|
||||||
<Badge colorScheme="green" size="sm">已验证</Badge>
|
<Badge colorScheme="green" size="sm">已验证</Badge>
|
||||||
@@ -307,7 +303,7 @@ export default function SettingsPage() {
|
|||||||
邮箱用于登录和接收重要通知
|
邮箱用于登录和接收重要通知
|
||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
<Button leftIcon={<EditIcon />} onClick={onEmailOpen}>
|
<Button leftIcon={<Pencil size={16} />} onClick={onEmailOpen}>
|
||||||
更换邮箱
|
更换邮箱
|
||||||
</Button>
|
</Button>
|
||||||
</HStack>
|
</HStack>
|
||||||
@@ -323,7 +319,7 @@ export default function SettingsPage() {
|
|||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<VStack align="start" spacing={1}>
|
<VStack align="start" spacing={1}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<FaWeixin color="#1aad19" />
|
<WechatOutlined style={{ color: '#1aad19' }} />
|
||||||
<Text fontWeight="medium" color={textColor}>
|
<Text fontWeight="medium" color={textColor}>
|
||||||
{user?.has_wechat ? '已绑定微信' : '未绑定微信'}
|
{user?.has_wechat ? '已绑定微信' : '未绑定微信'}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -337,7 +333,7 @@ export default function SettingsPage() {
|
|||||||
</VStack>
|
</VStack>
|
||||||
{user?.has_wechat ? (
|
{user?.has_wechat ? (
|
||||||
<Button
|
<Button
|
||||||
leftIcon={<DeleteIcon />}
|
leftIcon={<Trash2 size={16} />}
|
||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@@ -361,7 +357,7 @@ export default function SettingsPage() {
|
|||||||
解绑微信
|
解绑微信
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button leftIcon={<LinkIcon />} colorScheme="green" onClick={async () => {
|
<Button leftIcon={<Link2 size={16} />} colorScheme="green" onClick={async () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const base = getApiBase();
|
const base = getApiBase();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
Collapse,
|
Collapse,
|
||||||
Badge,
|
Badge,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { CloseIcon, ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons';
|
import { X, ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import MiniTimelineChart from './MiniTimelineChart';
|
import MiniTimelineChart from './MiniTimelineChart';
|
||||||
@@ -210,7 +210,7 @@ const QuoteTile: React.FC<QuoteTileProps> = ({
|
|||||||
{/* 操作按钮 */}
|
{/* 操作按钮 */}
|
||||||
<HStack spacing={1} ml={2}>
|
<HStack spacing={1} ml={2}>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={expanded ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
icon={expanded ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={subTextColor}
|
color={subTextColor}
|
||||||
@@ -223,7 +223,7 @@ const QuoteTile: React.FC<QuoteTileProps> = ({
|
|||||||
/>
|
/>
|
||||||
<Tooltip label="移除">
|
<Tooltip label="移除">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<CloseIcon />}
|
icon={<X size={16} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color="red.400"
|
color="red.400"
|
||||||
|
|||||||
@@ -42,21 +42,7 @@ import {
|
|||||||
Tag,
|
Tag,
|
||||||
TagLabel,
|
TagLabel,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import { Search, X, Plus, ChevronDown, ChevronUp, Settings, Monitor, Trash2, RefreshCw, Wifi, AlertCircle } from 'lucide-react';
|
||||||
SearchIcon,
|
|
||||||
CloseIcon,
|
|
||||||
AddIcon,
|
|
||||||
ChevronDownIcon,
|
|
||||||
ChevronUpIcon,
|
|
||||||
SettingsIcon,
|
|
||||||
} from '@chakra-ui/icons';
|
|
||||||
import {
|
|
||||||
FaDesktop,
|
|
||||||
FaTrash,
|
|
||||||
FaSync,
|
|
||||||
FaWifi,
|
|
||||||
FaExclamationCircle,
|
|
||||||
} from 'react-icons/fa';
|
|
||||||
|
|
||||||
import { useRealtimeQuote } from './hooks';
|
import { useRealtimeQuote } from './hooks';
|
||||||
import { getFullCode } from './hooks/utils';
|
import { getFullCode } from './hooks/utils';
|
||||||
@@ -299,7 +285,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
{/* 头部 */}
|
{/* 头部 */}
|
||||||
<Flex align="center" mb={4}>
|
<Flex align="center" mb={4}>
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Icon as={FaDesktop} boxSize={6} color={accentColor} />
|
<Icon as={Monitor} boxSize={6} color={accentColor} />
|
||||||
<Heading size="md" color={textColor}>
|
<Heading size="md" color={textColor}>
|
||||||
灵活屏
|
灵活屏
|
||||||
</Heading>
|
</Heading>
|
||||||
@@ -311,7 +297,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
gap={1}
|
gap={1}
|
||||||
>
|
>
|
||||||
<Icon as={FaWifi} boxSize={3} />
|
<Icon as={Wifi} boxSize={3} />
|
||||||
{isAnyConnected ? '实时' : '离线'}
|
{isAnyConnected ? '实时' : '离线'}
|
||||||
</Badge>
|
</Badge>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -322,7 +308,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
icon={<SettingsIcon />}
|
icon={<Settings size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={subTextColor}
|
color={subTextColor}
|
||||||
@@ -331,7 +317,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<MenuList bg="#1a1a2e" borderColor={borderColor}>
|
<MenuList bg="#1a1a2e" borderColor={borderColor}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<FaSync />}
|
icon={<RefreshCw />}
|
||||||
onClick={resetWatchlist}
|
onClick={resetWatchlist}
|
||||||
bg="transparent"
|
bg="transparent"
|
||||||
color={textColor}
|
color={textColor}
|
||||||
@@ -340,7 +326,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
重置为默认
|
重置为默认
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<FaTrash />}
|
icon={<Trash2 />}
|
||||||
onClick={clearWatchlist}
|
onClick={clearWatchlist}
|
||||||
bg="transparent"
|
bg="transparent"
|
||||||
color="red.400"
|
color="red.400"
|
||||||
@@ -352,7 +338,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
{/* 折叠按钮 */}
|
{/* 折叠按钮 */}
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={isCollapsed ? <ChevronDownIcon /> : <ChevronUpIcon />}
|
icon={isCollapsed ? <ChevronDown size={16} /> : <ChevronUp size={16} />}
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={subTextColor}
|
color={subTextColor}
|
||||||
@@ -369,7 +355,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
<Box position="relative" mb={4}>
|
<Box position="relative" mb={4}>
|
||||||
<InputGroup size="md">
|
<InputGroup size="md">
|
||||||
<InputLeftElement pointerEvents="none">
|
<InputLeftElement pointerEvents="none">
|
||||||
<SearchIcon color={subTextColor} />
|
<Search size={16} color={subTextColor} />
|
||||||
</InputLeftElement>
|
</InputLeftElement>
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索股票/指数代码或名称..."
|
placeholder="搜索股票/指数代码或名称..."
|
||||||
@@ -390,7 +376,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
<IconButton
|
<IconButton
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<CloseIcon />}
|
icon={<X size={16} />}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color={subTextColor}
|
color={subTextColor}
|
||||||
_hover={{ bg: hoverBg, color: textColor }}
|
_hover={{ bg: hoverBg, color: textColor }}
|
||||||
@@ -457,7 +443,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<AddIcon />}
|
icon={<Plus size={16} />}
|
||||||
size="xs"
|
size="xs"
|
||||||
colorScheme="purple"
|
colorScheme="purple"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -523,7 +509,7 @@ const FlexScreen: React.FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Center py={8}>
|
<Center py={8}>
|
||||||
<VStack spacing={3}>
|
<VStack spacing={3}>
|
||||||
<Icon as={FaExclamationCircle} boxSize={10} color={subTextColor} />
|
<Icon as={AlertCircle} boxSize={10} color={subTextColor} />
|
||||||
<Text color={subTextColor}>自选列表为空,请搜索添加证券</Text>
|
<Text color={subTextColor}>自选列表为空,请搜索添加证券</Text>
|
||||||
</VStack>
|
</VStack>
|
||||||
</Center>
|
</Center>
|
||||||
|
|||||||
@@ -48,13 +48,11 @@ import {
|
|||||||
Skeleton,
|
Skeleton,
|
||||||
SkeletonText,
|
SkeletonText,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { SearchIcon, CloseIcon, ArrowForwardIcon, TrendingUpIcon, InfoIcon, ChevronRightIcon, CalendarIcon } from '@chakra-ui/icons';
|
import { Search, X, ArrowRight, TrendingUp, Info, ChevronRight, Calendar, LineChart, Flame, Rocket, Brain, ArrowUp, ArrowDown, BarChart2, Tag as TagIcon, Layers, Zap } from 'lucide-react';
|
||||||
import { FaChartLine, FaFire, FaRocket, FaBrain, FaCalendarAlt, FaChevronRight, FaArrowUp, FaArrowDown, FaChartBar, FaTag, FaLayerGroup, FaBolt } from 'react-icons/fa';
|
|
||||||
import ConceptStocksModal from '@components/ConceptStocksModal';
|
import ConceptStocksModal from '@components/ConceptStocksModal';
|
||||||
import TradeDatePicker from '@components/TradeDatePicker';
|
import TradeDatePicker from '@components/TradeDatePicker';
|
||||||
import HotspotOverview from './components/HotspotOverview';
|
import HotspotOverview from './components/HotspotOverview';
|
||||||
import FlexScreen from './components/FlexScreen';
|
import FlexScreen from './components/FlexScreen';
|
||||||
import { BsGraphUp, BsLightningFill } from 'react-icons/bs';
|
|
||||||
import { echarts } from '@lib/echarts';
|
import { echarts } from '@lib/echarts';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
import tradingDays from '../../data/tradingDays.json';
|
import tradingDays from '../../data/tradingDays.json';
|
||||||
@@ -652,7 +650,7 @@ const StockOverview = () => {
|
|||||||
<VStack spacing={8} align="center">
|
<VStack spacing={8} align="center">
|
||||||
<VStack spacing={4} textAlign="center" maxW="3xl">
|
<VStack spacing={4} textAlign="center" maxW="3xl">
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Icon as={BsGraphUp} boxSize={12} color={colorMode === 'dark' ? goldColor : 'white'} />
|
<Icon as={TrendingUp} boxSize={12} color={colorMode === 'dark' ? goldColor : 'white'} />
|
||||||
<Heading
|
<Heading
|
||||||
as="h1"
|
as="h1"
|
||||||
size="2xl"
|
size="2xl"
|
||||||
@@ -680,7 +678,7 @@ const StockOverview = () => {
|
|||||||
borderColor={colorMode === 'dark' ? goldColor : 'transparent'}
|
borderColor={colorMode === 'dark' ? goldColor : 'transparent'}
|
||||||
>
|
>
|
||||||
<InputLeftElement pointerEvents="none">
|
<InputLeftElement pointerEvents="none">
|
||||||
<SearchIcon color={colorMode === 'dark' ? goldColor : 'gray.400'} />
|
<Search size={16} color={colorMode === 'dark' ? goldColor : 'gray.400'} />
|
||||||
</InputLeftElement>
|
</InputLeftElement>
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索股票代码、名称或拼音首字母..."
|
placeholder="搜索股票代码、名称或拼音首字母..."
|
||||||
@@ -702,7 +700,7 @@ const StockOverview = () => {
|
|||||||
<InputRightElement>
|
<InputRightElement>
|
||||||
<IconButton
|
<IconButton
|
||||||
size="sm"
|
size="sm"
|
||||||
icon={<CloseIcon />}
|
icon={<X size={16} />}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={handleClearSearch}
|
onClick={handleClearSearch}
|
||||||
aria-label="清空搜索"
|
aria-label="清空搜索"
|
||||||
@@ -771,7 +769,7 @@ const StockOverview = () => {
|
|||||||
</VStack>
|
</VStack>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
rightIcon={<ArrowForwardIcon />}
|
rightIcon={<ArrowRight size={16} />}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
colorScheme={colorMode === 'dark' ? 'yellow' : 'purple'}
|
colorScheme={colorMode === 'dark' ? 'yellow' : 'purple'}
|
||||||
_hover={{
|
_hover={{
|
||||||
@@ -923,14 +921,14 @@ const StockOverview = () => {
|
|||||||
<Box mb={10}>
|
<Box mb={10}>
|
||||||
<Flex align="center" mb={6}>
|
<Flex align="center" mb={6}>
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Icon as={FaFire} boxSize={6} color={colorMode === 'dark' ? goldColor : 'orange.500'} />
|
<Icon as={Flame} boxSize={6} color={colorMode === 'dark' ? goldColor : 'orange.500'} />
|
||||||
<Heading size="lg" color={textColor}>今日热门概念</Heading>
|
<Heading size="lg" color={textColor}>今日热门概念</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
rightIcon={<ChevronRightIcon />}
|
rightIcon={<ChevronRight size={16} />}
|
||||||
onClick={() => navigate('/concepts')}
|
onClick={() => navigate('/concepts')}
|
||||||
color={colorMode === 'dark' ? goldColor : 'purple.600'}
|
color={colorMode === 'dark' ? goldColor : 'purple.600'}
|
||||||
_hover={{
|
_hover={{
|
||||||
@@ -997,7 +995,7 @@ const StockOverview = () => {
|
|||||||
>
|
>
|
||||||
<HStack spacing={1}>
|
<HStack spacing={1}>
|
||||||
<Icon
|
<Icon
|
||||||
as={concept.change_percent > 0 ? FaArrowUp : FaArrowDown}
|
as={concept.change_percent > 0 ? ArrowUp : ArrowDown}
|
||||||
boxSize={3}
|
boxSize={3}
|
||||||
/>
|
/>
|
||||||
<Text>{formatChangePercent(concept.change_percent)}</Text>
|
<Text>{formatChangePercent(concept.change_percent)}</Text>
|
||||||
@@ -1014,7 +1012,7 @@ const StockOverview = () => {
|
|||||||
{/* 层级信息 */}
|
{/* 层级信息 */}
|
||||||
{concept.hierarchy && (
|
{concept.hierarchy && (
|
||||||
<HStack spacing={1} flexWrap="wrap">
|
<HStack spacing={1} flexWrap="wrap">
|
||||||
<Icon as={FaLayerGroup} boxSize={3} color="gray.400" />
|
<Icon as={Layers} boxSize={3} color="gray.400" />
|
||||||
<Text fontSize="xs" color="gray.500">
|
<Text fontSize="xs" color="gray.500">
|
||||||
{[concept.hierarchy.lv1, concept.hierarchy.lv2, concept.hierarchy.lv3]
|
{[concept.hierarchy.lv1, concept.hierarchy.lv2, concept.hierarchy.lv3]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
@@ -1039,7 +1037,7 @@ const StockOverview = () => {
|
|||||||
colorScheme="blue"
|
colorScheme="blue"
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
>
|
>
|
||||||
<Icon as={FaTag} boxSize={2} mr={1} />
|
<Icon as={Tag} boxSize={2} mr={1} />
|
||||||
<TagLabel fontSize="xs">{tag}</TagLabel>
|
<TagLabel fontSize="xs">{tag}</TagLabel>
|
||||||
</Tag>
|
</Tag>
|
||||||
))}
|
))}
|
||||||
@@ -1054,7 +1052,7 @@ const StockOverview = () => {
|
|||||||
{/* 爆发日期 */}
|
{/* 爆发日期 */}
|
||||||
{concept.outbreak_dates && concept.outbreak_dates.length > 0 && (
|
{concept.outbreak_dates && concept.outbreak_dates.length > 0 && (
|
||||||
<HStack spacing={2} fontSize="xs" color="orange.500">
|
<HStack spacing={2} fontSize="xs" color="orange.500">
|
||||||
<Icon as={FaBolt} />
|
<Icon as={Zap} />
|
||||||
<Text>
|
<Text>
|
||||||
近期爆发: {concept.outbreak_dates.slice(0, 2).join(', ')}
|
近期爆发: {concept.outbreak_dates.slice(0, 2).join(', ')}
|
||||||
{concept.outbreak_dates.length > 2 && ` 等${concept.outbreak_dates.length}次`}
|
{concept.outbreak_dates.length > 2 && ` 等${concept.outbreak_dates.length}次`}
|
||||||
@@ -1110,7 +1108,7 @@ const StockOverview = () => {
|
|||||||
size="sm"
|
size="sm"
|
||||||
colorScheme="purple"
|
colorScheme="purple"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
rightIcon={<FaChevronRight />}
|
rightIcon={<ChevronRight />}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleConceptClick(concept, index);
|
handleConceptClick(concept, index);
|
||||||
@@ -1131,12 +1129,12 @@ const StockOverview = () => {
|
|||||||
<Box mb={10}>
|
<Box mb={10}>
|
||||||
<Flex align="center" mb={6}>
|
<Flex align="center" mb={6}>
|
||||||
<HStack spacing={3}>
|
<HStack spacing={3}>
|
||||||
<Icon as={FaChartBar} boxSize={6} color={accentColor} />
|
<Icon as={BarChart2} boxSize={6} color={accentColor} />
|
||||||
<Heading size="lg" color={textColor}>市值热力图</Heading>
|
<Heading size="lg" color={textColor}>市值热力图</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Tooltip label="基于市值大小和涨跌幅展示的市场全景图">
|
<Tooltip label="基于市值大小和涨跌幅展示的市场全景图">
|
||||||
<Icon as={InfoIcon} color={subTextColor} />
|
<Icon as={Info} color={subTextColor} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
CardBody,
|
CardBody,
|
||||||
CardHeader
|
CardHeader
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FiTrendingUp, FiTrendingDown, FiDollarSign, FiPieChart, FiTarget, FiActivity } from 'react-icons/fi';
|
import { TrendingUp, TrendingDown, DollarSign, PieChart, Target, Activity } from 'lucide-react';
|
||||||
|
|
||||||
// 导入图表组件
|
// 导入图表组件
|
||||||
import { AssetAllocationChart } from './AssetAllocationChart';
|
import { AssetAllocationChart } from './AssetAllocationChart';
|
||||||
@@ -96,7 +96,7 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
h={"45px"}
|
h={"45px"}
|
||||||
w={"45px"}
|
w={"45px"}
|
||||||
bg="linear-gradient(90deg, #4481EB 0%, #04BEFE 100%)"
|
bg="linear-gradient(90deg, #4481EB 0%, #04BEFE 100%)"
|
||||||
icon={<Icon as={FiDollarSign} color="white" w="24px" h="24px" />}
|
icon={<Icon as={DollarSign} color="white" w="24px" h="24px" />}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
@@ -139,7 +139,7 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
}
|
}
|
||||||
icon={
|
icon={
|
||||||
<Icon
|
<Icon
|
||||||
as={(account?.totalProfit || 0) >= 0 ? FiTrendingUp : FiTrendingDown}
|
as={(account?.totalProfit || 0) >= 0 ? TrendingUp : TrendingDown}
|
||||||
color="white"
|
color="white"
|
||||||
w="24px"
|
w="24px"
|
||||||
h="24px"
|
h="24px"
|
||||||
@@ -177,7 +177,7 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
h={"45px"}
|
h={"45px"}
|
||||||
w={"45px"}
|
w={"45px"}
|
||||||
bg="linear-gradient(90deg, #FFE57F 0%, #FFB74D 100%)"
|
bg="linear-gradient(90deg, #FFE57F 0%, #FFB74D 100%)"
|
||||||
icon={<Icon as={FiTarget} color="white" w="24px" h="24px" />}
|
icon={<Icon as={Target} color="white" w="24px" h="24px" />}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
@@ -210,7 +210,7 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
h={"45px"}
|
h={"45px"}
|
||||||
w={"45px"}
|
w={"45px"}
|
||||||
bg="linear-gradient(90deg, #9F7AEA 0%, #805AD5 100%)"
|
bg="linear-gradient(90deg, #9F7AEA 0%, #805AD5 100%)"
|
||||||
icon={<Icon as={FiPieChart} color="white" w="24px" h="24px" />}
|
icon={<Icon as={PieChart} color="white" w="24px" h="24px" />}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
@@ -228,7 +228,7 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
h={"35px"}
|
h={"35px"}
|
||||||
w={"35px"}
|
w={"35px"}
|
||||||
bg="linear-gradient(90deg, #F093FB 0%, #F5576C 100%)"
|
bg="linear-gradient(90deg, #F093FB 0%, #F5576C 100%)"
|
||||||
icon={<Icon as={FiActivity} color="white" w="16px" h="16px" />}
|
icon={<Icon as={Activity} color="white" w="16px" h="16px" />}
|
||||||
/>
|
/>
|
||||||
<VStack align="start" spacing={0}>
|
<VStack align="start" spacing={0}>
|
||||||
<Text fontSize="sm" fontWeight="bold" color={textColor}>账户状态</Text>
|
<Text fontSize="sm" fontWeight="bold" color={textColor}>账户状态</Text>
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ import {
|
|||||||
Icon
|
Icon
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
FiTrendingUp,
|
TrendingUp,
|
||||||
FiTrendingDown,
|
TrendingDown,
|
||||||
FiDollarSign,
|
DollarSign,
|
||||||
FiAlertTriangle,
|
AlertTriangle,
|
||||||
FiInfo,
|
Info,
|
||||||
FiShield
|
Shield
|
||||||
} from 'react-icons/fi';
|
} from 'lucide-react';
|
||||||
|
|
||||||
export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
||||||
const [activeTab, setActiveTab] = useState(0); // 0: 融资买入, 1: 融券卖出
|
const [activeTab, setActiveTab] = useState(0); // 0: 融资买入, 1: 融券卖出
|
||||||
@@ -161,7 +161,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
<Card bg={warningBg} border="1px solid" borderColor="orange.200">
|
<Card bg={warningBg} border="1px solid" borderColor="orange.200">
|
||||||
<CardHeader pb={2}>
|
<CardHeader pb={2}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FiTrendingUp} color="orange.500" />
|
<Icon as={TrendingUp} color="orange.500" />
|
||||||
<Heading size="sm">融资信息</Heading>
|
<Heading size="sm">融资信息</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
@@ -209,7 +209,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
<Card bg={errorBg} border="1px solid" borderColor="red.200">
|
<Card bg={errorBg} border="1px solid" borderColor="red.200">
|
||||||
<CardHeader pb={2}>
|
<CardHeader pb={2}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FiTrendingDown} color="red.500" />
|
<Icon as={TrendingDown} color="red.500" />
|
||||||
<Heading size="sm">融券信息</Heading>
|
<Heading size="sm">融券信息</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
@@ -265,13 +265,13 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
<TabList>
|
<TabList>
|
||||||
<Tab color="orange.500" _selected={{ color: 'orange.600', borderColor: 'orange.500' }}>
|
<Tab color="orange.500" _selected={{ color: 'orange.600', borderColor: 'orange.500' }}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FiTrendingUp} />
|
<Icon as={TrendingUp} />
|
||||||
<Text>融资买入</Text>
|
<Text>融资买入</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab color="red.500" _selected={{ color: 'red.600', borderColor: 'red.500' }}>
|
<Tab color="red.500" _selected={{ color: 'red.600', borderColor: 'red.500' }}>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FiTrendingDown} />
|
<Icon as={TrendingDown} />
|
||||||
<Text>融券卖出</Text>
|
<Text>融券卖出</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Tab>
|
</Tab>
|
||||||
@@ -301,7 +301,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
{formatCurrency(marginData.availableMarginCredit)}
|
{formatCurrency(marginData.availableMarginCredit)}
|
||||||
</StatNumber>
|
</StatNumber>
|
||||||
<StatHelpText>
|
<StatHelpText>
|
||||||
<Icon as={FiDollarSign} mr={1} />
|
<Icon as={DollarSign} mr={1} />
|
||||||
杠杆比例: 1:1
|
杠杆比例: 1:1
|
||||||
</StatHelpText>
|
</StatHelpText>
|
||||||
</Stat>
|
</Stat>
|
||||||
@@ -331,7 +331,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
colorScheme="orange"
|
colorScheme="orange"
|
||||||
size="lg"
|
size="lg"
|
||||||
isDisabled={true}
|
isDisabled={true}
|
||||||
leftIcon={<Icon as={FiAlertTriangle} />}
|
leftIcon={<Icon as={AlertTriangle} />}
|
||||||
>
|
>
|
||||||
融资买入功能(演示版本暂不可用)
|
融资买入功能(演示版本暂不可用)
|
||||||
</Button>
|
</Button>
|
||||||
@@ -361,7 +361,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
{formatCurrency(marginData.availableShortCredit)}
|
{formatCurrency(marginData.availableShortCredit)}
|
||||||
</StatNumber>
|
</StatNumber>
|
||||||
<StatHelpText>
|
<StatHelpText>
|
||||||
<Icon as={FiDollarSign} mr={1} />
|
<Icon as={DollarSign} mr={1} />
|
||||||
杠杆比例: 1:0.5
|
杠杆比例: 1:0.5
|
||||||
</StatHelpText>
|
</StatHelpText>
|
||||||
</Stat>
|
</Stat>
|
||||||
@@ -399,7 +399,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
colorScheme="red"
|
colorScheme="red"
|
||||||
size="lg"
|
size="lg"
|
||||||
isDisabled={true}
|
isDisabled={true}
|
||||||
leftIcon={<Icon as={FiAlertTriangle} />}
|
leftIcon={<Icon as={AlertTriangle} />}
|
||||||
>
|
>
|
||||||
融券卖出功能(演示版本暂不可用)
|
融券卖出功能(演示版本暂不可用)
|
||||||
</Button>
|
</Button>
|
||||||
@@ -414,7 +414,7 @@ export default function MarginTrading({ account, onMarginBuy, onShortSell }) {
|
|||||||
<Card bg={cardBg} shadow="lg">
|
<Card bg={cardBg} shadow="lg">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack>
|
<HStack>
|
||||||
<Icon as={FiInfo} color="blue.500" />
|
<Icon as={Info} color="blue.500" />
|
||||||
<Heading size="md">融资融券知识</Heading>
|
<Heading size="md">融资融券知识</Heading>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import {
|
|||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Flex
|
Flex
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FiTrendingUp, FiTrendingDown, FiMinus, FiBarChart2, FiPieChart } from 'react-icons/fi';
|
import { TrendingUp, TrendingDown, Minus, BarChart2, PieChart } from 'lucide-react';
|
||||||
|
|
||||||
// 导入图表组件
|
// 导入图表组件
|
||||||
import { PositionDistributionChart } from './PositionDistributionChart';
|
import { PositionDistributionChart } from './PositionDistributionChart';
|
||||||
@@ -260,7 +260,7 @@ export default function PositionsList({ positions, account, onSellStock, trading
|
|||||||
<Card bg={cardBg} shadow="lg">
|
<Card bg={cardBg} shadow="lg">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<VStack spacing={4} py={8}>
|
<VStack spacing={4} py={8}>
|
||||||
<Icon as={FiMinus} size="48px" color={secondaryColor} />
|
<Icon as={Minus} size="48px" color={secondaryColor} />
|
||||||
<Text color={secondaryColor} fontSize="lg">暂无持仓</Text>
|
<Text color={secondaryColor} fontSize="lg">暂无持仓</Text>
|
||||||
<Text color={secondaryColor} fontSize="sm">
|
<Text color={secondaryColor} fontSize="sm">
|
||||||
请前往交易面板买入股票
|
请前往交易面板买入股票
|
||||||
@@ -309,7 +309,7 @@ export default function PositionsList({ positions, account, onSellStock, trading
|
|||||||
h={"40px"}
|
h={"40px"}
|
||||||
w={"40px"}
|
w={"40px"}
|
||||||
bg="linear-gradient(90deg, #4481EB 0%, #04BEFE 100%)"
|
bg="linear-gradient(90deg, #4481EB 0%, #04BEFE 100%)"
|
||||||
icon={<Icon as={FiBarChart2} color="white" w="20px" h="20px" />}
|
icon={<Icon as={BarChart2} color="white" w="20px" h="20px" />}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
@@ -341,7 +341,7 @@ export default function PositionsList({ positions, account, onSellStock, trading
|
|||||||
}
|
}
|
||||||
icon={
|
icon={
|
||||||
<Icon
|
<Icon
|
||||||
as={totalProfit >= 0 ? FiTrendingUp : FiTrendingDown}
|
as={totalProfit >= 0 ? TrendingUp : TrendingDown}
|
||||||
color="white"
|
color="white"
|
||||||
w="20px"
|
w="20px"
|
||||||
h="20px"
|
h="20px"
|
||||||
@@ -361,7 +361,7 @@ export default function PositionsList({ positions, account, onSellStock, trading
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<Text fontSize="lg" fontWeight="bold" color={textColor}>持仓分布</Text>
|
<Text fontSize="lg" fontWeight="bold" color={textColor}>持仓分布</Text>
|
||||||
<Icon as={FiPieChart} color="blue.500" />
|
<Icon as={PieChart} color="blue.500" />
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
@@ -451,7 +451,7 @@ export default function PositionsList({ positions, account, onSellStock, trading
|
|||||||
<Td isNumeric>
|
<Td isNumeric>
|
||||||
<HStack justify="end" spacing={1}>
|
<HStack justify="end" spacing={1}>
|
||||||
<Icon
|
<Icon
|
||||||
as={profit >= 0 ? FiTrendingUp : FiTrendingDown}
|
as={profit >= 0 ? TrendingUp : TrendingDown}
|
||||||
color={profit >= 0 ? 'green.500' : 'red.500'}
|
color={profit >= 0 ? 'green.500' : 'red.500'}
|
||||||
/>
|
/>
|
||||||
<Text color={(profit || 0) >= 0 ? 'green.500' : 'red.500'}>
|
<Text color={(profit || 0) >= 0 ? 'green.500' : 'red.500'}>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
useToast
|
useToast
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FiSearch, FiFilter, FiClock, FiTrendingUp, FiTrendingDown } from 'react-icons/fi';
|
import { Search, Filter, Clock, TrendingUp, TrendingDown } from 'lucide-react';
|
||||||
import { logger } from '../../../utils/logger';
|
import { logger } from '../../../utils/logger';
|
||||||
|
|
||||||
export default function TradingHistory({ history, onCancelOrder, tradingEvents }) {
|
export default function TradingHistory({ history, onCancelOrder, tradingEvents }) {
|
||||||
@@ -197,7 +197,7 @@ export default function TradingHistory({ history, onCancelOrder, tradingEvents }
|
|||||||
<Card bg={cardBg} shadow="lg">
|
<Card bg={cardBg} shadow="lg">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<VStack spacing={4} py={8}>
|
<VStack spacing={4} py={8}>
|
||||||
<Icon as={FiClock} size="48px" color={secondaryColor} />
|
<Icon as={Clock} size="48px" color={secondaryColor} />
|
||||||
<Text color={secondaryColor} fontSize="lg">暂无交易记录</Text>
|
<Text color={secondaryColor} fontSize="lg">暂无交易记录</Text>
|
||||||
<Text color={secondaryColor} fontSize="sm">
|
<Text color={secondaryColor} fontSize="sm">
|
||||||
完成首笔交易后,历史记录将在这里显示
|
完成首笔交易后,历史记录将在这里显示
|
||||||
@@ -253,7 +253,7 @@ export default function TradingHistory({ history, onCancelOrder, tradingEvents }
|
|||||||
<Text fontSize="sm" color={secondaryColor} mb={2}>搜索</Text>
|
<Text fontSize="sm" color={secondaryColor} mb={2}>搜索</Text>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputLeftElement>
|
<InputLeftElement>
|
||||||
<Icon as={FiSearch} color={secondaryColor} />
|
<Icon as={Search} color={secondaryColor} />
|
||||||
</InputLeftElement>
|
</InputLeftElement>
|
||||||
<Input
|
<Input
|
||||||
placeholder="搜索股票代码、名称或订单号..."
|
placeholder="搜索股票代码、名称或订单号..."
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import {
|
|||||||
InputLeftElement,
|
InputLeftElement,
|
||||||
Flex
|
Flex
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { FiSearch, FiTrendingUp, FiTrendingDown, FiDollarSign, FiZap, FiTarget } from 'react-icons/fi';
|
import { Search, TrendingUp, TrendingDown, DollarSign, Zap, Target } from 'lucide-react';
|
||||||
|
|
||||||
// 导入现有的高质量组件
|
// 导入现有的高质量组件
|
||||||
import IconBox from '../../../components/Icons/IconBox';
|
import IconBox from '../../../components/Icons/IconBox';
|
||||||
@@ -311,7 +311,7 @@ export default function TradingPanel({ account, onBuyStock, onSellStock, searchS
|
|||||||
h={"40px"}
|
h={"40px"}
|
||||||
w={"40px"}
|
w={"40px"}
|
||||||
bg="whiteAlpha.200"
|
bg="whiteAlpha.200"
|
||||||
icon={<Icon as={FiZap} color="white" w="20px" h="20px" />}
|
icon={<Icon as={Zap} color="white" w="20px" h="20px" />}
|
||||||
/>
|
/>
|
||||||
<VStack align="start" spacing={0}>
|
<VStack align="start" spacing={0}>
|
||||||
<Heading size="md">智能交易面板</Heading>
|
<Heading size="md">智能交易面板</Heading>
|
||||||
@@ -344,7 +344,7 @@ export default function TradingPanel({ account, onBuyStock, onSellStock, searchS
|
|||||||
<Box position="relative">
|
<Box position="relative">
|
||||||
<InputGroup size="lg">
|
<InputGroup size="lg">
|
||||||
<InputLeftElement>
|
<InputLeftElement>
|
||||||
<Icon as={FiSearch} color="gray.400" />
|
<Icon as={Search} color="gray.400" />
|
||||||
</InputLeftElement>
|
</InputLeftElement>
|
||||||
<Input
|
<Input
|
||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
@@ -544,7 +544,7 @@ export default function TradingPanel({ account, onBuyStock, onSellStock, searchS
|
|||||||
transform: "translateY(0)"
|
transform: "translateY(0)"
|
||||||
}}
|
}}
|
||||||
transition="all 0.2s"
|
transition="all 0.2s"
|
||||||
leftIcon={<Icon as={FiTarget} />}
|
leftIcon={<Icon as={Target} />}
|
||||||
>
|
>
|
||||||
立即买入
|
立即买入
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user