style(Profile): 用户中心 UI 紧凑化与布局优化

This commit is contained in:
zdl
2025-12-23 17:45:03 +08:00
parent d9dbf65e7d
commit 602dcf8eee
7 changed files with 83 additions and 83 deletions

View File

@@ -42,47 +42,49 @@ const CommunityFeedCard = ({
</HStack> </HStack>
{/* 内容区 */} {/* 内容区 */}
<Box p={4}> <Box p={3}>
<VStack spacing={3} align="stretch"> <VStack spacing={2} align="stretch">
{/* Tab 切换 */} {/* Tab 切换 - 更紧凑 */}
<HStack spacing={4}> <HStack spacing={3} mb={1}>
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="xs"
color={activeTab === 'my' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'} color={activeTab === 'my' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'}
fontWeight={activeTab === 'my' ? 'bold' : 'normal'} fontWeight={activeTab === 'my' ? 'bold' : 'normal'}
_hover={{ color: 'rgba(212, 175, 55, 0.9)' }} _hover={{ color: 'rgba(212, 175, 55, 0.9)' }}
onClick={() => setActiveTab('my')} onClick={() => setActiveTab('my')}
px={2} px={2}
h="24px"
> >
[我发布的] [我发布的]
</Button> </Button>
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="xs"
color={activeTab === 'participated' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'} color={activeTab === 'participated' ? 'rgba(212, 175, 55, 0.9)' : 'rgba(255, 255, 255, 0.5)'}
fontWeight={activeTab === 'participated' ? 'bold' : 'normal'} fontWeight={activeTab === 'participated' ? 'bold' : 'normal'}
_hover={{ color: 'rgba(212, 175, 55, 0.9)' }} _hover={{ color: 'rgba(212, 175, 55, 0.9)' }}
onClick={() => setActiveTab('participated')} onClick={() => setActiveTab('participated')}
px={2} px={2}
h="24px"
> >
[我参与的] [我参与的]
</Button> </Button>
</HStack> </HStack>
{/* 帖子列表 */} {/* 帖子列表 */}
<VStack spacing={3} align="stretch"> <VStack spacing={2} align="stretch">
{currentPosts.map((post) => ( {currentPosts.map((post) => (
<Box <Box
key={post.id} key={post.id}
p={3} py={2.5}
bg="rgba(37, 37, 64, 0.5)" px={2}
borderRadius="md"
cursor="pointer" cursor="pointer"
transition="all 0.2s" transition="all 0.2s"
borderRadius="md"
_hover={{ _hover={{
bg: 'rgba(37, 37, 64, 0.8)', bg: 'rgba(212, 175, 55, 0.08)',
transform: 'translateX(4px)', pl: 3,
}} }}
onClick={() => onPostClick?.(post)} onClick={() => onPostClick?.(post)}
> >

View File

@@ -35,14 +35,14 @@ const PredictionCard = ({
</Text> </Text>
</HStack> </HStack>
{/* 内容区 */} {/* 内容区 - 更紧凑 */}
<Box p={4}> <Box p={3}>
<VStack spacing={4} align="stretch"> <VStack spacing={3} align="stretch">
{/* 预测问题 - 带渐变背景 */} {/* 预测问题 - 带渐变背景 */}
<Box <Box
bg="linear-gradient(135deg, rgba(30, 30, 50, 0.9) 0%, rgba(20, 20, 35, 0.95) 100%)" bg="linear-gradient(135deg, rgba(30, 30, 50, 0.9) 0%, rgba(20, 20, 35, 0.95) 100%)"
borderRadius="lg" borderRadius="md"
p={4} p={3}
textAlign="center" textAlign="center"
position="relative" position="relative"
overflow="hidden" overflow="hidden"
@@ -53,17 +53,17 @@ const PredictionCard = ({
top="50%" top="50%"
left="50%" left="50%"
transform="translate(-50%, -50%)" transform="translate(-50%, -50%)"
w="120px" w="100px"
h="60px" h="50px"
borderRadius="50%" borderRadius="50%"
border="2px solid" border="1px solid"
borderColor="rgba(212, 175, 55, 0.2)" borderColor="rgba(212, 175, 55, 0.15)"
borderBottomColor="transparent" borderBottomColor="transparent"
borderLeftColor="transparent" borderLeftColor="transparent"
/> />
<Text <Text
fontSize="lg" fontSize="md"
fontWeight="bold" fontWeight="bold"
color="rgba(255, 255, 255, 0.95)" color="rgba(255, 255, 255, 0.95)"
position="relative" position="relative"
@@ -72,42 +72,42 @@ const PredictionCard = ({
{question} {question}
</Text> </Text>
{/* 看涨/看跌按钮 */} {/* 看涨/看跌按钮 - 更紧凑 */}
<HStack spacing={3} mt={4} justify="center"> <HStack spacing={2} mt={3} justify="center">
<Button <Button
flex={1} flex={1}
maxW="140px" maxW="110px"
h="40px" h="34px"
bg="linear-gradient(135deg, #DC2626 0%, #EF4444 100%)" bg="linear-gradient(135deg, #DC2626 0%, #EF4444 100%)"
color="white" color="white"
fontWeight="bold" fontWeight="bold"
fontSize="md" fontSize="sm"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'linear-gradient(135deg, #B91C1C 0%, #DC2626 100%)', bg: 'linear-gradient(135deg, #B91C1C 0%, #DC2626 100%)',
transform: 'scale(1.02)', transform: 'scale(1.02)',
}} }}
_active={{ transform: 'scale(0.98)' }} _active={{ transform: 'scale(0.98)' }}
leftIcon={<Icon as={TrendingUp} boxSize={4} />} leftIcon={<Icon as={TrendingUp} boxSize={3.5} />}
onClick={onBullish} onClick={onBullish}
> >
看涨 看涨
</Button> </Button>
<Button <Button
flex={1} flex={1}
maxW="140px" maxW="110px"
h="40px" h="34px"
bg="linear-gradient(135deg, #16A34A 0%, #22C55E 100%)" bg="linear-gradient(135deg, #16A34A 0%, #22C55E 100%)"
color="white" color="white"
fontWeight="bold" fontWeight="bold"
fontSize="md" fontSize="sm"
borderRadius="full" borderRadius="full"
_hover={{ _hover={{
bg: 'linear-gradient(135deg, #15803D 0%, #16A34A 100%)', bg: 'linear-gradient(135deg, #15803D 0%, #16A34A 100%)',
transform: 'scale(1.02)', transform: 'scale(1.02)',
}} }}
_active={{ transform: 'scale(0.98)' }} _active={{ transform: 'scale(0.98)' }}
leftIcon={<Icon as={TrendingDown} boxSize={4} />} leftIcon={<Icon as={TrendingDown} boxSize={3.5} />}
onClick={onBearish} onClick={onBearish}
> >
看跌 看跌
@@ -115,37 +115,13 @@ const PredictionCard = ({
</HStack> </HStack>
</Box> </Box>
{/* 底部信息 */} {/* 底部信息 - 合并为两行紧凑布局 */}
<HStack justify="space-between" fontSize="xs" px={1}> <HStack justify="space-between" fontSize="xs" px={1}>
<HStack spacing={4}> <HStack spacing={1}>
<HStack spacing={1}> <Text color="rgba(255, 255, 255, 0.5)">我的下注:</Text>
<Text color="rgba(255, 255, 255, 0.5)">我的下注:</Text> <Text color="#EF4444" fontWeight="medium">{myBet.type}</Text>
<Text color="#EF4444" fontWeight="medium"> <Text color="rgba(212, 175, 55, 0.9)" fontWeight="medium">{myBet.points}积分</Text>
{myBet.type}
</Text>
<Text color="rgba(212, 175, 55, 0.9)" fontWeight="medium">
{myBet.points}积分
</Text>
</HStack>
</HStack> </HStack>
</HStack>
<HStack justify="space-between" fontSize="xs" px={1}>
<HStack spacing={4}>
<HStack spacing={1}>
<Text color="rgba(255, 255, 255, 0.5)">当前胜率:</Text>
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">
{winRate}%
</Text>
</HStack>
<HStack spacing={1}>
<Text color="rgba(255, 255, 255, 0.5)">赔率:</Text>
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">
{odds}
</Text>
</HStack>
</HStack>
<Button <Button
size="xs" size="xs"
variant="ghost" variant="ghost"
@@ -156,10 +132,23 @@ const PredictionCard = ({
bg: 'rgba(212, 175, 55, 0.1)', bg: 'rgba(212, 175, 55, 0.1)',
}} }}
onClick={onViewHistory} onClick={onViewHistory}
px={2}
h="22px"
> >
历史战绩 历史战绩
</Button> </Button>
</HStack> </HStack>
<HStack fontSize="xs" px={1} spacing={4}>
<HStack spacing={1}>
<Text color="rgba(255, 255, 255, 0.5)">当前胜率:</Text>
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">{winRate}%</Text>
</HStack>
<HStack spacing={1}>
<Text color="rgba(255, 255, 255, 0.5)">赔率:</Text>
<Text color="rgba(255, 255, 255, 0.9)" fontWeight="medium">{odds}</Text>
</HStack>
</HStack>
</VStack> </VStack>
</Box> </Box>
</Box> </Box>

View File

@@ -37,8 +37,15 @@ const ForumCenter = () => {
/> />
</HStack> </HStack>
{/* 两列布局:预测卡片 + 社区动态 */} {/* 两列布局:预测卡片(2) + 社区动态(3) */}
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}> <SimpleGrid
columns={{ base: 1, md: 5 }}
spacing={4}
sx={{
'& > *:first-of-type': { gridColumn: { md: 'span 2' } },
'& > *:last-of-type': { gridColumn: { md: 'span 3' } },
}}
>
<PredictionCard /> <PredictionCard />
<CommunityFeedCard /> <CommunityFeedCard />
</SimpleGrid> </SimpleGrid>

View File

@@ -1,45 +1,43 @@
// 市场概况组件 - 顶部横条(与事件中心头部保持一致) // 市场概况组件 - 三列等宽布局
// 布局:市场概况 | 上证指数 | 深证成指 | 创业板指+涨跌分布
import React from 'react'; import React from 'react';
import { Box, SimpleGrid } from '@chakra-ui/react'; import { Box, Grid } from '@chakra-ui/react';
import { import {
IndexKLineCard, IndexKLineCard,
GemIndexCard, GemIndexCard,
MarketSummaryCard,
} from './atoms'; } from './atoms';
const MarketOverview = ({ marketStats = {} }) => { const MarketOverview = ({ marketStats = {} }) => {
return ( return (
<Box borderRadius="xl"> <Box borderRadius="xl">
{/* 4列网格布局市场概况 | 上证指数 | 深证成指 | 创业板指+涨跌 */} {/* 三列等宽网格布局 */}
<SimpleGrid <Grid
columns={{ base: 2, md: 4 }} templateColumns={{ base: '1fr', sm: '1fr 1fr', md: '1fr 1fr 1fr' }}
spacing={3} gap={3}
> >
{/* 市场概况 - 上证/深证/总市值/成交额 */}
<MarketSummaryCard />
{/* 上证指数 - K线卡片 */} {/* 上证指数 - K线卡片 */}
<IndexKLineCard <IndexKLineCard
indexCode="sh000001" indexCode="sh000001"
name="上证指数" name="上证指数"
height="220px"
/> />
{/* 深证成指 - K线卡片 */} {/* 深证成指 - K线卡片 */}
<IndexKLineCard <IndexKLineCard
indexCode="sz399001" indexCode="sz399001"
name="深证成指" name="深证成指"
height="220px"
/> />
{/* 创业板指 + 涨跌分布(垂直组合) */} {/* 创业板指 + 涨跌分布 */}
<GemIndexCard <GemIndexCard
indexCode="sz399006" indexCode="sz399006"
name="创业板指" name="创业板指"
riseCount={marketStats.riseCount || 2156} riseCount={marketStats.riseCount || 2156}
fallCount={marketStats.fallCount || 2034} fallCount={marketStats.fallCount || 2034}
flatCount={marketStats.flatCount || 312} flatCount={marketStats.flatCount || 312}
height="220px"
/> />
</SimpleGrid> </Grid>
</Box> </Box>
); );
}; };

View File

@@ -59,6 +59,7 @@ const fetchIndexLatest = async (indexCode) => {
* @param {number} riseCount - 上涨家数 * @param {number} riseCount - 上涨家数
* @param {number} fallCount - 下跌家数 * @param {number} fallCount - 下跌家数
* @param {number} flatCount - 平盘家数(可选) * @param {number} flatCount - 平盘家数(可选)
* @param {string} height - 卡片高度(默认 '180px'
*/ */
const GemIndexCard = ({ const GemIndexCard = ({
indexCode = 'sz399006', indexCode = 'sz399006',
@@ -66,6 +67,7 @@ const GemIndexCard = ({
riseCount = 0, riseCount = 0,
fallCount = 0, fallCount = 0,
flatCount = 0, flatCount = 0,
height = '180px',
}) => { }) => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [latestData, setLatestData] = useState(null); const [latestData, setLatestData] = useState(null);
@@ -116,7 +118,7 @@ const GemIndexCard = ({
border="1px solid" border="1px solid"
borderColor={THEME.border} borderColor={THEME.border}
p={3} p={3}
h="140px" h={height}
> >
<Center h="100%"> <Center h="100%">
<VStack spacing={2}> <VStack spacing={2}>
@@ -138,7 +140,7 @@ const GemIndexCard = ({
border="1px solid" border="1px solid"
borderColor={THEME.border} borderColor={THEME.border}
p={3} p={3}
h="140px" h={height}
transition="all 0.3s" transition="all 0.3s"
_hover={{ _hover={{
borderColor: `${accentColor}40`, borderColor: `${accentColor}40`,

View File

@@ -41,8 +41,9 @@ const fetchIndexKline = async (indexCode) => {
* K线指数卡片组件 * K线指数卡片组件
* @param {string} indexCode - 指数代码(如 'sh000001', 'sz399001' * @param {string} indexCode - 指数代码(如 'sh000001', 'sz399001'
* @param {string} name - 指数名称(如 '上证指数' * @param {string} name - 指数名称(如 '上证指数'
* @param {string} height - 卡片高度(默认 '180px'
*/ */
const IndexKLineCard = ({ indexCode, name }) => { const IndexKLineCard = ({ indexCode, name, height = '180px' }) => {
const [chartData, setChartData] = useState(null); const [chartData, setChartData] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [latestData, setLatestData] = useState(null); const [latestData, setLatestData] = useState(null);
@@ -60,7 +61,7 @@ const IndexKLineCard = ({ indexCode, name }) => {
const loadChartData = useCallback(async () => { const loadChartData = useCallback(async () => {
const data = await fetchIndexKline(apiIndexCode); const data = await fetchIndexKline(apiIndexCode);
if (data?.data?.length > 0) { if (data?.data?.length > 0) {
const recentData = data.data.slice(-30); // 最近30天 const recentData = data.data.slice(-20); // 最近20天提高K线清晰度
setChartData({ setChartData({
dates: recentData.map(item => item.time), dates: recentData.map(item => item.time),
klineData: recentData.map(item => [item.open, item.close, item.low, item.high]), klineData: recentData.map(item => [item.open, item.close, item.low, item.high]),
@@ -214,7 +215,7 @@ const IndexKLineCard = ({ indexCode, name }) => {
border="1px solid" border="1px solid"
borderColor={THEME.border} borderColor={THEME.border}
p={3} p={3}
h="140px" h={height}
> >
<Center h="100%"> <Center h="100%">
<VStack spacing={2}> <VStack spacing={2}>
@@ -236,7 +237,7 @@ const IndexKLineCard = ({ indexCode, name }) => {
border="1px solid" border="1px solid"
borderColor={THEME.border} borderColor={THEME.border}
p={3} p={3}
h="140px" h={height}
transition="all 0.3s" transition="all 0.3s"
_hover={{ _hover={{
borderColor: `${accentColor}40`, borderColor: `${accentColor}40`,

View File

@@ -38,6 +38,7 @@ import { motion } from 'framer-motion';
import { forumColors } from '@theme/forumTheme'; import { forumColors } from '@theme/forumTheme';
import { getTopicDetail, getUserAccount } from '@services/predictionMarketService.api'; import { getTopicDetail, getUserAccount } from '@services/predictionMarketService.api';
import { useAuth } from '@contexts/AuthContext'; import { useAuth } from '@contexts/AuthContext';
import { LAYOUT_SIZE } from '@/layouts/config/layoutConfig';
import TradeModal from './components/TradeModal'; import TradeModal from './components/TradeModal';
import PredictionCommentSection from './components/PredictionCommentSection'; import PredictionCommentSection from './components/PredictionCommentSection';
import CommentInvestModal from './components/CommentInvestModal'; import CommentInvestModal from './components/CommentInvestModal';
@@ -222,7 +223,7 @@ const PredictionTopicDetail = () => {
}; };
return ( return (
<Box minH="100vh" bg={forumColors.background.main} pt={{ base: "60px", md: "80px" }} pb={{ base: "6", md: "20" }}> <Box minH="100vh" bg={forumColors.background.main} pt={LAYOUT_SIZE.navbarHeight} pb={{ base: "6", md: "20" }}>
<Container maxW="container.xl" px={{ base: "3", sm: "4", md: "6" }}> <Container maxW="container.xl" px={{ base: "3", sm: "4", md: "6" }}>
{/* 头部:返回按钮 */} {/* 头部:返回按钮 */}
<Button <Button