feat(web): Index/model/space/tool ui upgrade

This commit is contained in:
zhaoying
2026-03-23 11:37:04 +08:00
parent 0775fad5f0
commit 4dbb2bf2e2
47 changed files with 1094 additions and 1123 deletions

View File

@@ -9,10 +9,8 @@
import React, { useState, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import guideBgImg from '@/assets/images/index/guide_bg@2x.png'
import { Button, Tour } from 'antd';
import type { TourProps } from 'antd';
import arrowRight from '@/assets/images/index/arrow_right_blue.svg'
const GuideCard: React.FC = () => {
const { t } = useTranslation();
@@ -67,22 +65,18 @@ const GuideCard: React.FC = () => {
return (
<>
<div className='rb:w-full rb:p-4' style={{ backgroundImage: `url(${guideBgImg})`, backgroundSize: '100% 100%' }}>
<div className='rb:flex rb:justify-start rb:text-white rb:text-base rb:font-semibold' >
{ t('index.getStarted')}
<div className='rb:w-full rb:bg-white rb:rounded-xl rb:pb-3'>
<div className='rb:font-[MiSans-Bold] rb:font-bold rb:leading-5 rb:p-3 rb:bg-cover rb:rounded-tl-xl rb:rounded-tr-xl rb:bg-[url("@/assets/images/index/guide_bg@2x.png")]' >
{ t('index.getStarted')}
</div>
<div className='rb:flex rb:text-xs rb:text-white rb:leading-[18px] rb:mt-3'>
<div className='rb:leading-4.5 rb:text-[12px] rb:-mt-2 rb:pl-3 rb:pr-1.75'>
{ t('index.startedDesc')}
</div>
<div className='rb:flex rb:w-full rb:items-center rb:justify-between rb:gap-3 rb:mt-4'>
<Button ref={startButtonRef} className='rb:gap-2 rb:w-full rb:flex rb:items-center rb:text-[#155EEF]' onClick={handleStartGuide}>
<span className='rb:text-xs'>{ t('index.viewGuide')}</span>
<img src={arrowRight} className='rb:size-4' />
</Button>
{/* <Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#155EEF]'>
<span className='rb:text-xs'>{ t('index.watchVideo')}</span>
<img src={arrowRight} className='rb:size-4' />
</Button> */}
<div className="rb:mt-2 rb:pl-3 rb:pr-4">
<Button ref={startButtonRef} block className='rb:gap-1 rb:flex rb:items-center' onClick={handleStartGuide}>
<span className='rb:text-xs'>{t('index.viewGuide')}</span>
<div className="rb:size-4 rb:bg-cover rb:bg-[url('src/assets/images/common/arrow_right_dark.svg')]"></div>
</Button>
</div>
</div>

View File

@@ -1,5 +1,6 @@
import { type FC } from 'react';
import { useTranslation } from 'react-i18next';
import { Flex } from 'antd'
import modelIcon from '@/assets/images/index/model_mgt.svg'
import spaceIcon from '@/assets/images/index/space_mgt.svg'
@@ -89,25 +90,30 @@ const QuickActions: FC<QuickActionsProps> = ({ onNavigate }) => {
];
return (
<div className='rb:w-full rb:p-4 rb:bg-[#FBFDFF] rb:border-1 rb:border-[#DFE4ED] rb:rounded-xl'>
<div className='rb:flex rb:justify-start rb:text-base rb:font-medium rb:text-[#212332]'>
{ t('quickActions.title') }
</div>
<div className="rb:grid rb:grid-cols-3 md:rb:grid-cols-4 rb:gap-4 rb:mt-4">
{quickActions.map((action) => (
<div key={action.key}
className="rb:flex rb:flex-col rb:items-center rb:text-center rb:cursor-pointer rb:group"
onClick={action.onClick}
>
<img src={action.icon} className='rb:size-10 rb:mx-auto' />
<div className="rb:mt-2 rb:text-xs rb:max-w-[74px] rb:text-[#5B6167] rb:text-center rb:leading-[14px]">
{action.title}
</div>
</div>
))}
</div>
</div>);
<div className='rb:w-full rb:bg-white rb:rounded-xl rb:mt-2.5 rb:py-3'>
<div className='rb:font-[MiSans-Bold] rb:font-bold rb:leading-5 rb:px-4 rb:pb-3.5'>
{ t('quickActions.title') }
</div>
<div className="rb:grid rb:grid-cols-3 md:rb:grid-cols-4 rb:gap-4">
{quickActions.map((action) => (
<Flex
key={action.key}
vertical
gap={8}
align="center"
justify="center"
className="rb:cursor-pointer"
onClick={action.onClick}
>
<img src={action.icon} className='rb:size-10 rb:mx-auto' />
<div className="rb:text-[12px] rb:max-w-18.25 rb:text-[#5B6167] rb:text-center rb:leading-3.5">
{action.title}
</div>
</Flex>
))}
</div>
</div>
);
};
export default QuickActions;

View File

@@ -1,20 +1,15 @@
import { type FC } from 'react'
import { useTranslation } from 'react-i18next'
import totalModels from '@/assets/images/index/models.svg';
import totalSpaces from '@/assets/images/index/spaces.svg';
import totalUsers from '@/assets/images/index/users.svg';
import totalApps from '@/assets/images/index/apps.svg';
import arrowUpDb from '@/assets/images/index/arrow_up_d.svg'
import arrowDownDb from '@/assets/images/index/arrow_down_d.svg'
import arrowUp from '@/assets/images/index/arrow_up.svg'
import arrowDown from '@/assets/images/index/arrow_down.svg'
import styles from './index.module.css'
import { Flex } from 'antd';
import clsx from 'clsx';
import { type DataResponse } from '@/api/common'
import Tag from '@/components/Tag'
const list = [
{
key: 'models',
icon: totalModels,
icon: 'rb:bg-[url("@/assets/images/index/models.svg")]',
value: '24',
// trendValue: '12.5%',
trend: 'up',
@@ -25,7 +20,7 @@ const list = [
},
{
key: 'spaces',
icon: totalSpaces,
icon: 'rb:bg-[url("@/assets/images/index/spaces.svg")]',
value: '156',
trendValue: '+8',
trend: 'down',
@@ -36,7 +31,7 @@ const list = [
},
{
key: 'users',
icon: totalUsers,
icon: 'rb:bg-[url("@/assets/images/index/users.svg")]',
value: '1,248',
trendValue: '+42',
trend: 'up',
@@ -47,7 +42,7 @@ const list = [
},
{
key: 'running_apps',
icon: totalApps,
icon: 'rb:bg-[url("@/assets/images/index/apps.svg")]',
value: '12.8k',
trendValue: '98.7%',
trend: 'up',
@@ -60,70 +55,106 @@ const list = [
const TopCardList: FC<{data?: DataResponse}> = ({ data }) => {
const { t } = useTranslation()
return (
<div className="rb:grid rb:grid-cols-4 rb:gap-[16px]">
<div className="rb:grid rb:grid-cols-4 rb:gap-3 rb:mt-3">
{list.map((item) => {
return (
<div
key={item.key}
className={styles.card}
style={{
background: item.background,
}}
>
<div className={styles.header}>
<div className="rb:text-xs rb:font-medium rb:text-[#212332] rb:w-[96px]">{t(`dashboard.${'total_' + item.key}`)}</div>
<div className={styles.avatar}><img src={item.icon} /></div>
</div>
<div
key={item.key}
className="rb:bg-white rb:rounded-xl rb:p-4"
>
<Flex justify="space-between" align="center" gap={24}>
<div className="rb:text-[12pxx] rb:font-medium rb:flex-1">{t(`dashboard.${'total_' + item.key}`)}</div>
<div className={`rb:size-8 rb:bg-cover ${item.icon}`}></div>
</Flex>
<div className={styles.content}>
<div className="rb:mt-5 rb:font-[MiSans-Bold] rb:font-bold rb:text-[24px] rb:leading-8">
{item.key === 'spaces' && String(data?.active_workspaces)}
{item.key === 'running_apps' && String(data?.[`${item.key}` as keyof DataResponse] || item.value || 0)}
{item.key !== 'spaces' && item.key !== 'running_apps' && String(data?.[`total_${item.key}` as keyof DataResponse] || item.value || 0)}
</div>
<div className='rb:flex rb:flex-col rb:items-start'>
{item.key === 'models' ? (
<div className='rb:text-xs rb:leading-4 rb:text-[#5F6266] rb:w-[130px]'>
{t(`dashboard.${'desc_' + item.key}`, { account: data?.total_llm, nums: data?.total_embedding })}
<div className='rb:flex rb:flex-col rb:items-start rb:mt-2'>
{item.key === 'models'
? (
<div className='rb:text-xs rb:leading-4 rb:text-[#5F6266] rb:w-32.25'>
{t(`dashboard.${'desc_' + item.key}`, { account: data?.total_llm, nums: data?.total_embedding })}
</div>
) : (<>
)
: (<>
<div className='rb:flex rb:items-center rb:text-xs rb:leading-4 rb:gap-1'>
{item.key === 'spaces' && (<>
<img src={Number(data?.new_workspaces_this_week || 0) >= 0 ? arrowUpDb : arrowDownDb} className='rb:size-3'/>
<span className={Number(data?.new_workspaces_this_week || 0) >= 0 ? 'rb:text-[#369F21]' : 'rb:text-[#FF5D34]'}>{Number(data?.new_workspaces_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_workspaces_this_week || 0))}</span>
<div className={clsx("rb:size-3 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up_d.svg')]": Number(data?.new_workspaces_this_week || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down_d.svg')]": Number(data?.new_workspaces_this_week || 0) < 0,
})}></div>
<span className={clsx('rb:font-medium', {
"rb:text-[#369F21]": Number(data?.new_workspaces_this_week || 0) >= 0,
"rb:text-[#FF5D34]": Number(data?.new_workspaces_this_week || 0) < 0,
})}>{Number(data?.new_workspaces_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_workspaces_this_week || 0))}</span>
</>)}
{item.key === 'users' && (<>
<img src={Number(data?.new_users_this_week || 0) >= 0 ? arrowUpDb : arrowDownDb} className='rb:size-3'/>
<span className={Number(data?.new_users_this_week || 0) >= 0 ? 'rb:text-[#369F21]' : 'rb:text-[#FF5D34]'}>{Number(data?.new_users_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_users_this_week || 0))}</span>
<div className={clsx("rb:size-3 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up_d.svg')]": Number(data?.new_users_this_week || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down_d.svg')]": Number(data?.new_users_this_week || 0) < 0,
})}></div>
<span className={clsx('rb:font-medium', {
"rb:text-[#369F21]": Number(data?.new_users_this_week || 0) >= 0,
"rb:text-[#FF5D34]": Number(data?.new_users_this_week || 0) < 0,
})}>{Number(data?.new_users_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_users_this_week || 0))}</span>
</>)}
{item.key === 'running_apps' && (<>
<img src={Number(data?.new_apps_this_week || 0) >= 0 ? arrowUpDb : arrowDownDb} className='rb:size-3'/>
<span className={Number(data?.new_apps_this_week || 0) >= 0 ? 'rb:text-[#369F21]' : 'rb:text-[#FF5D34]'}>{Number(data?.new_apps_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_apps_this_week || 0))}</span>
<div className={clsx("rb:size-3 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up_d.svg')]": Number(data?.new_apps_this_week || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down_d.svg')]": Number(data?.new_apps_this_week || 0) < 0,
})}></div>
<span className={clsx('rb:font-medium', {
"rb:text-[#369F21]": Number(data?.new_apps_this_week || 0) >= 0,
"rb:text-[#FF5D34]": Number(data?.new_apps_this_week || 0) < 0,
})}>{Number(data?.new_apps_this_week || 0) >= 0 ? '+' : '-'}{Math.abs(Number(data?.new_apps_this_week || 0))}</span>
</>)}
</div>
<div className='rb:text-xs rb:leading-4 rb:text-[#5F6266]'>
<div className='rb:text-[12px] rb:leading-4 rb:text-[#5F6266]'>
{t(`dashboard.${'desc_' + item.key}`)}
</div>
</>)}
</>)
}
</div>
{item.key === 'models' && (<div className={`rb:flex rb:max-w-40 rb:text-xs rb:mt-2 rb:items-center rb:gap-1 rb:border-1 rb:rounded rb:px-2 rb:py-0.5 ${Number(data?.model_week_growth_rate || 0) >= 0 ? 'rb:text-[#369F21] rb:border-[#369F21] rb:bg-[rgba(54, 159, 33, 0.25)]' : 'rb:text-[#FF5D34] rb:border-[#FF5D34] rb:bg-[rgba(255, 93, 52, 0.25)]'}`}>
<img src={Number(data?.model_week_growth_rate || 0) >= 0 ? arrowUp : arrowDown} className='rb:size-3'/>
<span>{Math.abs(Number(data?.model_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</div>)}
{item.key === 'spaces' && (<div className={`rb:flex rb:max-w-40 rb:text-xs rb:mt-2 rb:items-center rb:gap-1 rb:border-1 rb:rounded rb:px-2 rb:py-0.5 ${Number(data?.workspace_week_growth_rate || 0) >= 0 ? 'rb:text-[#369F21] rb:border-[#369F21] rb:bg-[rgba(54, 159, 33, 0.25)]' : 'rb:text-[#FF5D34] rb:border-[#FF5D34] rb:bg-[rgba(255, 93, 52, 0.25)]'}`}>
<img src={Number(data?.workspace_week_growth_rate || 0) >= 0 ? arrowUp : arrowDown} className='rb:size-3'/>
<span>{Math.abs(Number(data?.workspace_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</div>)}
{item.key === 'users' && (<div className={`rb:flex rb:max-w-40 rb:text-xs rb:mt-2 rb:items-center rb:gap-1 rb:border-1 rb:rounded rb:px-2 rb:py-0.5 ${Number(data?.user_week_growth_rate || 0) >= 0 ? 'rb:text-[#369F21] rb:border-[#369F21] rb:bg-[rgba(54, 159, 33, 0.25)]' : 'rb:text-[#FF5D34] rb:border-[#FF5D34] rb:bg-[rgba(255, 93, 52, 0.25)]'}`}>
<img src={Number(data?.user_week_growth_rate || 0) >= 0 ? arrowUp : arrowDown} className='rb:size-3'/>
<span>{Math.abs(Number(data?.user_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</div>)}
{item.key === 'running_apps' && (<div className={`rb:flex rb:max-w-40 rb:text-xs rb:mt-2 rb:items-center rb:gap-1 rb:border-1 rb:rounded rb:px-2 rb:py-0.5 ${Number(data?.app_week_growth_rate || 0) >= 0 ? 'rb:text-[#369F21] rb:border-[#369F21] rb:bg-[rgba(54, 159, 33, 0.25)]' : 'rb:text-[#FF5D34] rb:border-[#FF5D34] rb:bg-[rgba(255, 93, 52, 0.25)]'}`}>
<img src={Number(data?.app_week_growth_rate || 0) >= 0 ? arrowUp : arrowDown} className='rb:size-3'/>
<span>{Math.abs(Number(data?.app_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</div>)}
{item.key === 'models' && (<Tag color={Number(data?.model_week_growth_rate || 0) >= 0 ? "success" : "warning"} className="rb:mt-2">
<Flex align="center">
<div className={clsx("rb:size-3.5 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up.svg')]": Number(data?.model_week_growth_rate || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down.svg')]": Number(data?.model_week_growth_rate || 0) < 0,
})}></div>
<span>{Math.abs(Number(data?.model_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</Flex>
</Tag>)}
{item.key === 'spaces' && (<Tag color={Number(data?.workspace_week_growth_rate || 0) >= 0 ? "success" : "warning"} className="rb:mt-2">
<Flex align="center">
<div className={clsx("rb:size-3.5 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up.svg')]": Number(data?.workspace_week_growth_rate || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down.svg')]": Number(data?.workspace_week_growth_rate || 0) < 0,
})}></div>
<span>{Math.abs(Number(data?.workspace_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</Flex>
</Tag>)}
{item.key === 'users' && (<Tag color={Number(data?.user_week_growth_rate || 0) >= 0 ? "success" : "warning"} className="rb:mt-2">
<Flex align="center">
<div className={clsx("rb:size-3.5 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up.svg')]": Number(data?.user_week_growth_rate || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down.svg')]": Number(data?.user_week_growth_rate || 0) < 0,
})}></div>
<span>{Math.abs(Number(data?.user_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</Flex>
</Tag>)}
{item.key === 'running_apps' && (<Tag color={Number(data?.app_week_growth_rate || 0) >= 0 ? "success" : "warning"} className="rb:mt-2">
<Flex align="center">
<div className={clsx("rb:size-3.5 rb:bg-cover rb:mr-0.5", {
"rb:bg-[url('@/assets/images/index/arrow_up.svg')]": Number(data?.app_week_growth_rate || 0) >= 0,
"rb:bg-[url('@/assets/images/index/arrow_down.svg')]": Number(data?.app_week_growth_rate || 0) < 0,
})}></div>
<span>{Math.abs(Number(data?.app_week_growth_rate || 0))}% {t('dashboard.thisWeek')}</span>
</Flex>
</Tag>)}
</div>
)
})}

View File

@@ -8,11 +8,11 @@
*/
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Divider } from 'antd';
// import arrowRight from '@/assets/images/index/arrow_right.svg'
import { Flex } from 'antd';
import { getVersion, type versionResponse } from '@/api/common'
const GuideCard: React.FC = () => {
const VersionCard: React.FC = () => {
const { t, i18n } = useTranslation();
const [versionInfo, setVersionInfo] = useState<versionResponse | null>(null);
@@ -23,13 +23,6 @@ const GuideCard: React.FC = () => {
return currentLang === 'zh' ? versionInfo.introduction : (versionInfo.introduction_en || versionInfo.introduction);
};
// 解析换行符和HTML的方法
const parseContent = (text: string) => {
if (!text) return '';
// 将 \n 转换为 <br/> 标签
return text.replace(/\\n/g, '<br/>');
};
useEffect(() => {
const fetchVersion = async () => {
try {
@@ -44,58 +37,36 @@ const GuideCard: React.FC = () => {
}, []);
return (
<div className='rb:w-full rb:p-4 rb:border-1 rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded-xl'>
<div className='rb:flex rb:items-center rb:justify-start rb:text-[#5B6167] rb:text-base rb:font-semibold rb:gap-2'>
{ t('index.latestUpdate')}
<span className='rb:text-xs rb:text-[#1890FF]'>
{versionInfo?.version}
</span>
</div>
<div className='rb:flex rb:flex-col rb:max-h-[400px] rb:overflow-y-auto rb:text-[#5B6167]'>
{versionInfo && (() => {
const introduction = getIntroduction();
return introduction ? (<>
<div className='rb:flex rb:items-center rb:gap-2 rb:text-sm rb:text-[#5B6167] rb:leading-5 '>
<span className='rb:text-xs rb:text-[#5B6167]'>
{t('version.releaseDate')}: {introduction.releaseDate}
</span>
<Divider type='vertical' />
<span className='rb:text-xs rb:text-[#5B6167]'>
{t('version.name')}: {introduction.codeName}
</span>
</div>
<p
className='rb:text-sm rb:text-[#5B6167] rb:leading-5 rb:mt-2'
dangerouslySetInnerHTML={{ __html: introduction.upgradePosition }}
/>
{introduction.coreUpgrades?.map((item: string, index: number) => (
<p
key={index}
className='rb:text-sm rb:text-[#5B6167] rb:leading-5'
dangerouslySetInnerHTML={{ __html: item }}
/>
))}
</>) : null;
})()}
{/* {loading ? (
t('index.loading')
) : (
versionInfo?.introduction || t('index.latestUpdateDesc')
)} */}
</div>
{/* <div className='rb:flex rb:w-full rb:items-center rb:justify-between rb:gap-3 rb:mt-4'>
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#212332] '>
<span className='rb:text-xs'>{ t('index.viewDetails')}</span>
<img src={arrowRight} className='rb:size-4' />
</Button>
<Button className='rb:gap-2 rb:flex rb:items-center rb:text-[#212332]'>
<span className='rb:text-xs'>{ t('index.changeLog')}</span>
<img src={arrowRight} className='rb:size-4' />
</Button>
</div> */}
<div className='rb:w-full rb:p-3 rb:bg-white rb:rounded-xl rb:mt-3'>
<Flex gap={4} className="rb:mb-3">
<span className="rb:font-[MiSans-Bold] rb:font-bold rb:leading-5">{t('index.latestUpdate')}</span>
<span className='rb:text-[12px] rb:text-white rb:leading-4.25 rb:pt-px rb:pl-2 rb:pr-1.75 rb:bg-[#171719] rb:rounded-lg rb:rounded-bl-none '>
{versionInfo?.version}
</span>
</Flex>
{versionInfo && (() => {
const introduction = getIntroduction();
return introduction ? (<>
<div className="rb:text-[#5B6167] rb:text-[12px] rb:leading-4.5 rb:mt-1 rb:mb-2">
{t('version.releaseDate')}: {introduction.releaseDate} | {t('version.name')}: {introduction.codeName}
</div>
<div className="rb:max-h-76 rb:overflow-y-auto">
<p
className='rb:text-[12px] rb:leading-4.5'
dangerouslySetInnerHTML={{ __html: introduction.upgradePosition }}
/>
{introduction.coreUpgrades?.map((item: string, index: number) => (
<p
key={index}
className='rb:text-[12px] rb:leading-4.5 rb:mt-2'
dangerouslySetInnerHTML={{ __html: item }}
/>
))}
</div>
</>) : null;
})()}
</div>
);
};
export default GuideCard;
export default VersionCard;

View File

@@ -1,12 +1,12 @@
import { useEffect, useState, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { Space, Button } from 'antd';
import { Space, Button, Row, Col, Flex } from 'antd';
import TopCardList from './components/TopCardList';
import GuideCard from './components/GuideCard';
import VersionCard from './components/VersionCard';
import QuickActions from './components/QuickActions';
import bgImg from '@/assets/images/index/index_bg@2x.png'
import Table, { type TableRef } from '@/components/Table'
import type { ColumnsType } from 'antd/es/table';
import { formatDateTime } from '@/utils/format';
@@ -42,16 +42,15 @@ const Index = () => {
dataIndex: 'name',
key: 'name',
},
{
title: t('space.spaceIcon'),
dataIndex: 'icon',
key: 'icon',
render:(value: string, record: any) => {
return value ? (
<img src={value} alt="icon" className='rb:w-[24px] rb:h-[24px]' />
<img src={value} alt="icon" className='rb:size-6' />
) : (
<div className='rb:w-[24px] rb:h-[24px] rb:bg-blue-500 rb:text-white rb:rounded rb:flex rb:items-center rb:justify-center rb:text-xs rb:font-medium'>
<div className='rb:size-6 rb:bg-[#155EEF] rb:text-white rb:rounded rb:flex rb:items-center rb:justify-center rb:text-xs rb:font-medium'>
{record.name?.charAt(0)?.toUpperCase() || '?'}
</div>
)
@@ -84,7 +83,7 @@ const Index = () => {
width: 100,
render: (_, record) => (
<Space size="middle">
<Button onClick={() => handleJump(record.id)} color="primary" variant="text">{t('space.enterSpace')}</Button>
<Button type="link" onClick={() => handleJump(record.id)}>{t('space.enterSpace')}</Button>
</Space>
),
},
@@ -99,44 +98,40 @@ const Index = () => {
return (
<div className="rb:pb-[24px]">
<div className="rb:mt-[16px] rb:flex rb:gap-4">
<div className='rb:flex-1'>
<div className='rb:flex-col rb:w-full rb:h-[120px] rb:mb-4 rb:p-6 rb:leading-[30px]' style={{backgroundImage: `url(${bgImg})`, backgroundSize: '100% 100%'}}>
<div className='rb:flex rb:text-[22px] rb:text-[#0041C3] rb:font-semibold'>
{ t('index.spaceTitle' )}
</div>
<div className='rb:flex rb:mt-2 rb:text-xs rb:leading-[18px] rb:text-[#5F6266] rb:max-w-[560px]'>
{ t('index.spaceSubTitle' )}
</div>
<Row gutter={12}>
<Col flex="1">
<Flex vertical>
<div className='rb:w-full rb:h-26 rb:p-4 rb:bg-cover rb:bg-[url("@/assets/images/index/index_bg@2x.png")]'>
<div className="rb:font-[MiSans-Bold] rb:font-bold rb:text-white rb:text-[18px] rb:leading-7">
{t('index.spaceTitle')}
</div>
<div className='rb:mt-2 rb:text-[12px] rb:leading-4.5 rb:text-white rb:max-w-139.75'>
{t('index.spaceSubTitle')}
</div>
</div>
{/* 统计卡片 */}
<TopCardList data={dashboardData} />
<div className="rb:rounded rb:max-h-[calc(100%-100px)] rb:overflow-y-auto rb:mt-4">
<div className="rb:rounded-xl rb:bg-white rb:pt-3 rb:px-3 rb:overflow-y-hidden rb:my-3 rb:flex-1">
<Table
ref={tableRef}
apiUrl={tableApi}
columns={columns}
rowKey="id"
bordered={false}
scrollY="100%"
className="rb:-mb-3!"
// scroll={{ y: 'calc(100vh - 340px)' }}
/>
</div>
</div>
<div className='rb:flex-0 rb:min-w-80'>
{/* 引导 */}
<GuideCard />
<div className='rb:w-full rb:mt-4 '>
<VersionCard />
</div>
{/* 快捷操作 */}
<div className='rb:w-full rb:mt-4'>
<QuickActions onNavigate={navigate} />
</div>
</div>
</div>
</div>
</div>
</Flex>
</Col>
<Col flex="328px">
{/* 引导 */}
<GuideCard />
<VersionCard />
<QuickActions onNavigate={navigate} />
</Col>
</Row>
);
}