update ui
This commit is contained in:
@@ -423,15 +423,15 @@ const CompactSearchBox = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
padding: '16px 20px',
|
padding: window.innerWidth < 768 ? '12px 16px' : '16px 20px',
|
||||||
background: PROFESSIONAL_COLORS.background.card,
|
background: PROFESSIONAL_COLORS.background.card,
|
||||||
borderRadius: '12px',
|
borderRadius: '12px',
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3), 0 0 20px rgba(255, 195, 0, 0.1)',
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3), 0 0 20px rgba(255, 195, 0, 0.1)',
|
||||||
border: `1px solid ${PROFESSIONAL_COLORS.border.default}`,
|
border: `1px solid ${PROFESSIONAL_COLORS.border.default}`,
|
||||||
backdropFilter: 'blur(10px)'
|
backdropFilter: 'blur(10px)'
|
||||||
}}>
|
}}>
|
||||||
{/* 单行紧凑布局 */}
|
{/* 单行紧凑布局 - 移动端自动换行 */}
|
||||||
<Space wrap style={{ width: '100%' }} size="medium">
|
<Space wrap style={{ width: '100%' }} size={window.innerWidth < 768 ? 'small' : 'medium'}>
|
||||||
{/* 搜索框 */}
|
{/* 搜索框 */}
|
||||||
<AutoComplete
|
<AutoComplete
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
@@ -446,7 +446,7 @@ const CompactSearchBox = ({
|
|||||||
handleMainSearch();
|
handleMainSearch();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{ width: 240 }}
|
style={{ width: window.innerWidth < 768 ? '100%' : 240, minWidth: window.innerWidth < 768 ? 0 : 240 }}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
prefix={<SearchOutlined style={{ color: PROFESSIONAL_COLORS.gold[500] }} />}
|
prefix={<SearchOutlined style={{ color: PROFESSIONAL_COLORS.gold[500] }} />}
|
||||||
@@ -492,7 +492,8 @@ const CompactSearchBox = ({
|
|||||||
displayRender={(labels) => labels[labels.length - 1] || '行业'}
|
displayRender={(labels) => labels[labels.length - 1] || '行业'}
|
||||||
disabled={industryLoading}
|
disabled={industryLoading}
|
||||||
style={{
|
style={{
|
||||||
width: 120,
|
width: window.innerWidth < 768 ? '100%' : 120,
|
||||||
|
minWidth: window.innerWidth < 768 ? 0 : 120,
|
||||||
borderRadius: '8px'
|
borderRadius: '8px'
|
||||||
}}
|
}}
|
||||||
suffixIcon={<FilterOutlined style={{ fontSize: 14, color: PROFESSIONAL_COLORS.gold[500] }} />}
|
suffixIcon={<FilterOutlined style={{ fontSize: 14, color: PROFESSIONAL_COLORS.gold[500] }} />}
|
||||||
@@ -506,7 +507,8 @@ const CompactSearchBox = ({
|
|||||||
value={importance}
|
value={importance}
|
||||||
onChange={handleImportanceChange}
|
onChange={handleImportanceChange}
|
||||||
style={{
|
style={{
|
||||||
width: 120,
|
width: window.innerWidth < 768 ? '100%' : 120,
|
||||||
|
minWidth: window.innerWidth < 768 ? 0 : 120,
|
||||||
borderRadius: '8px'
|
borderRadius: '8px'
|
||||||
}}
|
}}
|
||||||
placeholder="事件等级"
|
placeholder="事件等级"
|
||||||
@@ -526,7 +528,8 @@ const CompactSearchBox = ({
|
|||||||
value={sort}
|
value={sort}
|
||||||
onChange={handleSortChange}
|
onChange={handleSortChange}
|
||||||
style={{
|
style={{
|
||||||
width: 130,
|
width: window.innerWidth < 768 ? '100%' : 130,
|
||||||
|
minWidth: window.innerWidth < 768 ? 0 : 130,
|
||||||
borderRadius: '8px'
|
borderRadius: '8px'
|
||||||
}}
|
}}
|
||||||
suffixIcon={<SortAscendingOutlined style={{ fontSize: 14, color: PROFESSIONAL_COLORS.gold[500] }} />}
|
suffixIcon={<SortAscendingOutlined style={{ fontSize: 14, color: PROFESSIONAL_COLORS.gold[500] }} />}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// 纵向分栏模式布局组件
|
// 纵向分栏模式布局组件
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Box, VStack, Flex, Center, Text } from '@chakra-ui/react';
|
import { Box, VStack, Flex, Center, Text, useBreakpointValue } from '@chakra-ui/react';
|
||||||
import { InfoIcon } from '@chakra-ui/icons';
|
import { InfoIcon } from '@chakra-ui/icons';
|
||||||
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
|
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
|
||||||
import EventDetailScrollPanel from './EventDetailScrollPanel';
|
import EventDetailScrollPanel from './EventDetailScrollPanel';
|
||||||
@@ -33,6 +33,11 @@ const VerticalModeLayout = ({
|
|||||||
// 详情面板重置 key(预留,用于未来功能)
|
// 详情面板重置 key(预留,用于未来功能)
|
||||||
const [detailPanelKey] = useState(0);
|
const [detailPanelKey] = useState(0);
|
||||||
|
|
||||||
|
// 响应式布局
|
||||||
|
const isMobile = useBreakpointValue({ base: true, lg: false });
|
||||||
|
const flexDirection = useBreakpointValue({ base: 'column', lg: 'row' });
|
||||||
|
const gap = useBreakpointValue({ base: 3, lg: 6 });
|
||||||
|
|
||||||
// 固定布局比例:左侧(4),右侧(6)- 平衡布局,确保左侧有足够空间显示内容
|
// 固定布局比例:左侧(4),右侧(6)- 平衡布局,确保左侧有足够空间显示内容
|
||||||
const leftFlex = '4';
|
const leftFlex = '4';
|
||||||
const rightFlex = '6';
|
const rightFlex = '6';
|
||||||
@@ -40,7 +45,8 @@ const VerticalModeLayout = ({
|
|||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
display={display}
|
display={display}
|
||||||
gap={6}
|
direction={flexDirection}
|
||||||
|
gap={gap}
|
||||||
position="relative"
|
position="relative"
|
||||||
transition="all 0.3s ease-in-out"
|
transition="all 0.3s ease-in-out"
|
||||||
h="100%"
|
h="100%"
|
||||||
@@ -48,8 +54,9 @@ const VerticalModeLayout = ({
|
|||||||
>
|
>
|
||||||
{/* 左侧:事件列表 - 独立滚动 */}
|
{/* 左侧:事件列表 - 独立滚动 */}
|
||||||
<Box
|
<Box
|
||||||
flex={leftFlex}
|
flex={isMobile ? '1' : leftFlex}
|
||||||
minWidth={0}
|
minWidth={0}
|
||||||
|
w={isMobile ? '100%' : 'auto'}
|
||||||
overflowY="auto"
|
overflowY="auto"
|
||||||
h="100%"
|
h="100%"
|
||||||
data-event-list-container="true"
|
data-event-list-container="true"
|
||||||
@@ -109,7 +116,8 @@ const VerticalModeLayout = ({
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 右侧:事件详情 - 独立滚动 */}
|
{/* 右侧:事件详情 - 独立滚动 - 移动端隐藏 */}
|
||||||
|
{!isMobile && (
|
||||||
<Box
|
<Box
|
||||||
flex={rightFlex}
|
flex={rightFlex}
|
||||||
minHeight={0}
|
minHeight={0}
|
||||||
@@ -124,6 +132,7 @@ const VerticalModeLayout = ({
|
|||||||
selectedEvent={selectedEvent}
|
selectedEvent={selectedEvent}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -205,23 +205,25 @@ const DynamicNewsDetailPanel = ({ event, showHeader = true }) => {
|
|||||||
// 🎯 加载事件详情(增加浏览量)
|
// 🎯 加载事件详情(增加浏览量)
|
||||||
loadEventDetail();
|
loadEventDetail();
|
||||||
|
|
||||||
|
// 重置所有加载状态
|
||||||
|
setHasLoadedStocks(false);
|
||||||
|
setHasLoadedHistorical(false);
|
||||||
|
setHasLoadedTransmission(false);
|
||||||
|
|
||||||
// 相关股票默认展开(有权限时)
|
// 相关股票默认展开(有权限时)
|
||||||
if (canAccessStocks) {
|
if (canAccessStocks) {
|
||||||
setIsStocksOpen(true);
|
setIsStocksOpen(true);
|
||||||
if (!hasLoadedStocks) {
|
// 立即加载股票数据
|
||||||
|
console.log('%c📊 [相关股票] 事件切换,加载股票数据', 'color: #10B981; font-weight: bold;', { eventId: event?.id });
|
||||||
loadStocksData();
|
loadStocksData();
|
||||||
setHasLoadedStocks(true);
|
setHasLoadedStocks(true);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setIsStocksOpen(false);
|
setIsStocksOpen(false);
|
||||||
setHasLoadedStocks(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsConceptsOpen(false);
|
setIsConceptsOpen(false);
|
||||||
setIsHistoricalOpen(false);
|
setIsHistoricalOpen(false);
|
||||||
setHasLoadedHistorical(false);
|
|
||||||
setIsTransmissionOpen(false);
|
setIsTransmissionOpen(false);
|
||||||
setHasLoadedTransmission(false);
|
|
||||||
}, [event?.id, canAccessStocks, userTier, loadStocksData, loadEventDetail]);
|
}, [event?.id, canAccessStocks, userTier, loadStocksData, loadEventDetail]);
|
||||||
|
|
||||||
// 切换关注状态
|
// 切换关注状态
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
|
useBreakpointValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
import { getImportanceConfig } from '../../../../constants/importanceLevels';
|
||||||
import { PROFESSIONAL_COLORS } from '../../../../constants/professionalTheme';
|
import { PROFESSIONAL_COLORS } from '../../../../constants/professionalTheme';
|
||||||
@@ -62,6 +63,13 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
const linkColor = PROFESSIONAL_COLORS.text.primary;
|
const linkColor = PROFESSIONAL_COLORS.text.primary;
|
||||||
const borderColor = PROFESSIONAL_COLORS.border.default;
|
const borderColor = PROFESSIONAL_COLORS.border.default;
|
||||||
|
|
||||||
|
// 响应式布局
|
||||||
|
const showTimeline = useBreakpointValue({ base: false, md: true }); // 移动端隐藏时间轴
|
||||||
|
const cardPadding = useBreakpointValue({ base: 2, md: 3 }); // 移动端减小内边距
|
||||||
|
const titleFontSize = useBreakpointValue({ base: 'sm', md: 'md' }); // 移动端减小标题字体
|
||||||
|
const titlePaddingRight = useBreakpointValue({ base: '80px', md: '120px' }); // 为关键词留空间
|
||||||
|
const spacing = useBreakpointValue({ base: 2, md: 3 }); // 间距
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据平均涨幅计算背景色(专业配色 - 深色主题)
|
* 根据平均涨幅计算背景色(专业配色 - 深色主题)
|
||||||
* @param {number} avgChange - 平均涨跌幅
|
* @param {number} avgChange - 平均涨跌幅
|
||||||
@@ -97,8 +105,9 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HStack align="stretch" spacing={3} w="full">
|
<HStack align="stretch" spacing={spacing} w="full">
|
||||||
{/* 左侧时间轴 */}
|
{/* 左侧时间轴 - 移动端隐藏 */}
|
||||||
|
{showTimeline && (
|
||||||
<EventTimeline
|
<EventTimeline
|
||||||
createdAt={event.created_at}
|
createdAt={event.created_at}
|
||||||
timelineStyle={timelineStyle}
|
timelineStyle={timelineStyle}
|
||||||
@@ -106,6 +115,7 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
minHeight={layout === 'four-row' ? '60px' : 0}
|
minHeight={layout === 'four-row' ? '60px' : 0}
|
||||||
importance={importance}
|
importance={importance}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 右侧事件卡片容器 */}
|
{/* 右侧事件卡片容器 */}
|
||||||
<Box flex="1" position="relative">
|
<Box flex="1" position="relative">
|
||||||
@@ -148,9 +158,9 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => onEventClick?.(event)}
|
onClick={() => onEventClick?.(event)}
|
||||||
>
|
>
|
||||||
<CardBody p={3} pb={2}>
|
<CardBody p={cardPadding} pb={2}>
|
||||||
{/* 右上角:关注按钮 */}
|
{/* 右上角:关注按钮 */}
|
||||||
<Box position="absolute" top={2} right={2} zIndex={2}>
|
<Box position="absolute" top={{ base: 1, md: 2 }} right={{ base: 1, md: 2 }} zIndex={2}>
|
||||||
<EventFollowButton
|
<EventFollowButton
|
||||||
isFollowing={isFollowing}
|
isFollowing={isFollowing}
|
||||||
followerCount={followerCount}
|
followerCount={followerCount}
|
||||||
@@ -189,10 +199,10 @@ const HorizontalDynamicNewsEventCard = ({
|
|||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={(e) => onTitleClick?.(e, event)}
|
onClick={(e) => onTitleClick?.(e, event)}
|
||||||
mt={1}
|
mt={1}
|
||||||
paddingRight="120px"
|
paddingRight={titlePaddingRight}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
fontSize="md"
|
fontSize={titleFontSize}
|
||||||
fontWeight="semibold"
|
fontWeight="semibold"
|
||||||
color={linkColor}
|
color={linkColor}
|
||||||
lineHeight="1.4"
|
lineHeight="1.4"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
VStack,
|
VStack,
|
||||||
Text,
|
Text,
|
||||||
|
useBreakpointValue,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
|
||||||
// 导入组件
|
// 导入组件
|
||||||
@@ -52,6 +53,23 @@ const Community = () => {
|
|||||||
// Ref:用于首次滚动到内容区域
|
// Ref:用于首次滚动到内容区域
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
|
|
||||||
|
// 响应式容器宽度
|
||||||
|
const containerMaxW = useBreakpointValue({
|
||||||
|
base: '100%', // 移动端:全宽
|
||||||
|
sm: '100%', // 小屏:全宽
|
||||||
|
md: '100%', // 中屏:全宽
|
||||||
|
lg: '1200px', // 大屏:1200px
|
||||||
|
xl: '1400px', // 超大屏:1400px
|
||||||
|
});
|
||||||
|
|
||||||
|
// 响应式内边距
|
||||||
|
const containerPx = useBreakpointValue({
|
||||||
|
base: 2, // 移动端:最小内边距
|
||||||
|
sm: 3,
|
||||||
|
md: 4,
|
||||||
|
lg: 6,
|
||||||
|
});
|
||||||
|
|
||||||
// ⚡ 通知权限引导
|
// ⚡ 通知权限引导
|
||||||
const { browserPermission, requestBrowserPermission } = useNotification();
|
const { browserPermission, requestBrowserPermission } = useNotification();
|
||||||
|
|
||||||
@@ -145,7 +163,7 @@ const Community = () => {
|
|||||||
return (
|
return (
|
||||||
<Box minH="100vh" bg={bgColor}>
|
<Box minH="100vh" bg={bgColor}>
|
||||||
{/* 主内容区域 */}
|
{/* 主内容区域 */}
|
||||||
<Container ref={containerRef} maxW="1400px" pt={6} pb={8}>
|
<Container ref={containerRef} maxW={containerMaxW} px={containerPx} pt={{ base: 3, md: 6 }} pb={{ base: 4, md: 8 }}>
|
||||||
{/* 通知权限提示横幅 */}
|
{/* 通知权限提示横幅 */}
|
||||||
{showNotificationBanner && (
|
{showNotificationBanner && (
|
||||||
<Alert
|
<Alert
|
||||||
|
|||||||
Reference in New Issue
Block a user