redesign mt homepage with clean data-driven style, remove footer branding
Docker Build / Build and Push Docker Image (push) Successful in 4m16s

This commit is contained in:
2026-06-14 00:10:06 +08:00
parent 45f676514a
commit a8a96a7e60
4 changed files with 183 additions and 240 deletions
-27
View File
@@ -194,20 +194,6 @@ const FooterBar = () => {
© {currentYear} {systemName}. {t('版权所有')}
</Typography.Text>
</div>
<div className='text-sm'>
<span className='!text-semi-color-text-1'>
{t('设计与开发由')}{' '}
</span>
<a
href='https://github.com/QuantumNous/new-api'
target='_blank'
rel='noopener noreferrer'
className='!text-semi-color-primary font-medium'
>
New API
</a>
</div>
</div>
</footer>
),
@@ -227,19 +213,6 @@ const FooterBar = () => {
className='custom-footer na-cb6feafeb3990c78 text-sm !text-semi-color-text-1'
dangerouslySetInnerHTML={{ __html: footer }}
></div>
<div className='text-sm flex-shrink-0'>
<span className='!text-semi-color-text-1'>
{t('设计与开发由')}{' '}
</span>
<a
href='https://github.com/QuantumNous/new-api'
target='_blank'
rel='noopener noreferrer'
className='!text-semi-color-primary font-medium'
>
New API
</a>
</div>
</div>
</footer>
) : (
+10 -1
View File
@@ -1,4 +1,4 @@
{
{
"translation": {
" + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}_one": " + Web search {{count}} time / 1K times * {{symbol}}{{price}} * {{ratioType}} {{ratio}}",
" + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}_other": " + Web search {{count}} times / 1K times * {{symbol}}{{price}} * {{ratioType}} {{ratio}}",
@@ -3483,6 +3483,14 @@
"配置 GitHub OAuth App": "Configure GitHub OAuth App",
"配置 Linux DO OAuth": "Configure Linux DO OAuth",
"配置 OIDC": "Configure OIDC",
"统一 AI 接入": "Unified AI Access",
"运营控制台": "Operations Console",
"获取 Key": "Get Key",
"注册账号": "Register",
"availability": "Availability",
"latency": "Latency",
"compatibility": "Compatibility",
"providers": "Providers",
"配置 Passkey": "Configure Passkey",
"配置 SMTP": "Configure SMTP",
"配置 Telegram 登录": "Configure Telegram Login",
@@ -3830,3 +3838,4 @@
"、": ", "
}
}
+10 -1
View File
@@ -1,4 +1,4 @@
{
{
"translation": {
" + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}_other": " + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}",
" + 图片生成调用 {{symbol}}{{price}} / 1次 * {{ratioType}} {{ratio}}": " + 图片生成调用 {{symbol}}{{price}} / 1次 * {{ratioType}} {{ratio}}",
@@ -2422,6 +2422,14 @@
"配置 GitHub OAuth App": "配置 GitHub OAuth App",
"配置 Linux DO OAuth": "配置 Linux DO OAuth",
"配置 OIDC": "配置 OIDC",
"统一 AI 接入": "统一 AI 接入",
"运营控制台": "运营控制台",
"获取 Key": "获取 Key",
"注册账号": "注册账号",
"availability": "可用性",
"latency": "延迟",
"compatibility": "兼容性",
"providers": "供应商",
"配置 Passkey": "配置 Passkey",
"配置 SMTP": "配置 SMTP",
"配置 Telegram 登录": "配置 Telegram 登录",
@@ -2628,3 +2636,4 @@
"、": "、"
}
}
+163 -211
View File
@@ -18,53 +18,42 @@ For commercial licensing, please contact admin@modelstoken.com
*/
import React, { useContext, useEffect, useState } from 'react';
import {
Button,
Typography,
Input,
ScrollList,
ScrollItem,
} from '@douyinfe/semi-ui';
import { Button, Typography, Input } from '@douyinfe/semi-ui';
import { API, showError, copy, showSuccess } from '../../helpers';
import { useIsMobile } from '../../hooks/common/useIsMobile';
import { API_ENDPOINTS } from '../../constants/common.constant';
import { StatusContext } from '../../context/Status';
import { useActualTheme } from '../../context/Theme';
import { marked } from 'marked';
import { useTranslation } from 'react-i18next';
import {
IconGithubLogo,
IconPlay,
IconFile,
IconCopy,
} from '@douyinfe/semi-icons';
import { IconCopy, IconArrowRight } from '@douyinfe/semi-icons';
import { Link } from 'react-router-dom';
import NoticeModal from '../../components/layout/NoticeModal';
import {
Moonshot,
OpenAI,
XAI,
Zhipu,
Volcengine,
Cohere,
Claude,
Gemini,
Suno,
Minimax,
Wenxin,
Spark,
Qingyan,
DeepSeek,
Qwen,
Midjourney,
Grok,
AzureAI,
Moonshot,
Zhipu,
Volcengine,
Hunyuan,
Minimax,
Cohere,
AzureAI,
Xinference,
} from '@lobehub/icons';
const { Text } = Typography;
const METRICS = [
{ key: 'availability', value: '99.98%', suffix: '' },
{ key: 'latency', value: '≤0.25', suffix: 's' },
{ key: 'compatibility', value: '100%', suffix: '' },
{ key: 'providers', value: '30', suffix: '+' },
];
const Home = () => {
const { t, i18n } = useTranslation();
const [statusState] = useContext(StatusContext);
@@ -73,12 +62,8 @@ const Home = () => {
const [homePageContent, setHomePageContent] = useState('');
const [noticeVisible, setNoticeVisible] = useState(false);
const isMobile = useIsMobile();
const isDemoSiteMode = statusState?.status?.demo_site_enabled || false;
const docsLink = statusState?.status?.docs_link || '';
const serverAddress =
statusState?.status?.server_address || `${window.location.origin}`;
const endpointItems = API_ENDPOINTS.map((e) => ({ value: e }));
const [endpointIndex, setEndpointIndex] = useState(0);
const isChinese = i18n.language.startsWith('zh');
const displayHomePageContent = async () => {
@@ -92,8 +77,6 @@ const Home = () => {
}
setHomePageContent(content);
localStorage.setItem('home_page_content', content);
// 如果内容是 URL,则发送主题模式
if (data.startsWith('https://')) {
const iframe = document.querySelector('iframe');
if (iframe) {
@@ -105,7 +88,7 @@ const Home = () => {
}
} else {
showError(message);
setHomePageContent('加载首页内容失败...');
setHomePageContent('');
}
setHomePageContentLoaded(true);
};
@@ -133,7 +116,6 @@ const Home = () => {
}
}
};
checkNoticeAndShow();
}, []);
@@ -141,13 +123,6 @@ const Home = () => {
displayHomePageContent().then();
}, []);
useEffect(() => {
const timer = setInterval(() => {
setEndpointIndex((prev) => (prev + 1) % endpointItems.length);
}, 3000);
return () => clearInterval(timer);
}, [endpointItems.length]);
return (
<div className='classic-page-fill classic-home-page w-full overflow-x-hidden'>
<NoticeModal
@@ -156,180 +131,157 @@ const Home = () => {
isMobile={isMobile}
/>
{homePageContentLoaded && homePageContent === '' ? (
<div className='classic-home-default w-full overflow-x-hidden'>
{/* Banner 部分 */}
<div className='classic-home-hero w-full border-b border-semi-color-border relative overflow-x-hidden'>
{/* 背景模糊晕染球 */}
<div className='blur-ball blur-ball-indigo' />
<div className='blur-ball blur-ball-teal' />
<div className='flex items-center justify-center px-4 pt-24 pb-8'>
{/* 居中内容区 */}
<div className='flex flex-col items-center justify-center text-center max-w-4xl mx-auto'>
<div className='flex flex-col items-center justify-center mb-6 md:mb-8'>
<h1
className={`text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold text-semi-color-text-0 leading-tight ${isChinese ? 'tracking-wide md:tracking-wider' : ''}`}
<div className='w-full overflow-x-hidden'>
{/* Hero */}
<div className='w-full flex flex-col items-center justify-center px-4 pt-20 pb-16 md:pt-28 md:pb-20'>
<div className='flex flex-col items-center text-center max-w-3xl mx-auto'>
{/* Badge */}
<div
className='inline-flex items-center gap-2 px-4 py-1.5 rounded-full mb-6 md:mb-8'
style={{
background: 'var(--semi-color-primary-light-default)',
border: '1px solid var(--semi-color-primary-light-hover)',
}}
>
<span
className='w-2 h-2 rounded-full'
style={{ background: 'var(--semi-color-success)' }}
/>
<Text
style={{ color: 'var(--semi-color-primary)' }}
className='text-sm font-medium'
>
{t('AI Gateway')}
</Text>
</div>
{/* Title */}
<h1
className={`font-bold leading-tight mb-4 md:mb-6 ${isChinese ? 'tracking-wide' : ''}`}
style={{
fontSize: isMobile ? '2rem' : '3.5rem',
color: 'var(--semi-color-text-0)',
}}
>
{t('统一 AI 接入')}
<br />
<span style={{ color: 'var(--semi-color-primary)' }}>
{t('运营控制台')}
</span>
</h1>
{/* Subtitle */}
<p
className='text-base md:text-lg max-w-xl mb-8 md:mb-10'
style={{ color: 'var(--semi-color-text-2)' }}
>
{t('多模型统一接入,OpenAI 兼容接口,只需替换基址即可使用')}
</p>
{/* Base URL */}
<div
className='flex items-center w-full max-w-lg mb-8 rounded-xl overflow-hidden'
style={{
border: '1px solid var(--semi-color-border)',
background: 'var(--semi-color-bg-1)',
}}
>
<Input
readonly
value={serverAddress}
className='flex-1 !border-none !rounded-none'
style={{ background: 'transparent' }}
size='large'
/>
<Button
type='primary'
onClick={handleCopyBaseURL}
icon={<IconCopy />}
className='!rounded-none !px-4'
size='large'
/>
</div>
{/* CTA */}
<div className='flex gap-3'>
<Link to='/login'>
<Button
theme='solid'
type='primary'
size='large'
icon={<IconArrowRight />}
className='!rounded-lg !px-6'
>
<>
{t('统一的')}
<br />
<span className='shine-text'>{t('大模型接口网关')}</span>
</>
</h1>
<p className='text-base md:text-lg lg:text-xl text-semi-color-text-1 mt-4 md:mt-6 max-w-xl'>
{t('多模型统一接入,只需将基址替换为:')}
</p>
{/* BASE URL 与端点选择 */}
<div className='flex flex-col md:flex-row items-center justify-center gap-4 w-full mt-4 md:mt-6 max-w-md'>
<Input
readonly
value={serverAddress}
className='flex-1 !rounded-full'
size={isMobile ? 'default' : 'large'}
suffix={
<div className='flex items-center gap-2'>
<ScrollList
bodyHeight={32}
style={{ border: 'unset', boxShadow: 'unset' }}
>
<ScrollItem
mode='wheel'
cycled={true}
list={endpointItems}
selectedIndex={endpointIndex}
onSelect={({ index }) => setEndpointIndex(index)}
/>
</ScrollList>
<Button
type='primary'
onClick={handleCopyBaseURL}
icon={<IconCopy />}
className='!rounded-full'
/>
</div>
}
/>
</div>
</div>
{t('获取 Key')}
</Button>
</Link>
<Link to='/register'>
<Button
size='large'
className='!rounded-lg !px-6'
style={{
border: '1px solid var(--semi-color-border)',
}}
>
{t('注册账号')}
</Button>
</Link>
</div>
</div>
</div>
{/* 操作按钮 */}
<div className='flex flex-row gap-4 justify-center items-center'>
<Link to='/console'>
<Button
theme='solid'
type='primary'
size={isMobile ? 'default' : 'large'}
className='!rounded-3xl px-8 py-2'
icon={<IconPlay />}
>
{t('获取密钥')}
</Button>
</Link>
{isDemoSiteMode && statusState?.status?.version ? (
<Button
size={isMobile ? 'default' : 'large'}
className='flex items-center !rounded-3xl px-6 py-2'
icon={<IconGithubLogo />}
onClick={() =>
window.open(
'https://github.com/QuantumNous/new-api',
'_blank',
)
}
>
{statusState.status.version}
</Button>
) : (
docsLink && (
<Button
size={isMobile ? 'default' : 'large'}
className='flex items-center !rounded-3xl px-6 py-2'
icon={<IconFile />}
onClick={() => window.open(docsLink, '_blank')}
>
{t('文档')}
</Button>
)
)}
{/* Metrics */}
<div
className='w-full py-10 md:py-14'
style={{ background: 'var(--semi-color-bg-1)' }}
>
<div className='max-w-4xl mx-auto px-4 grid grid-cols-2 md:grid-cols-4 gap-6 md:gap-8'>
{METRICS.map((m) => (
<div key={m.key} className='text-center'>
<div
className='text-3xl md:text-4xl font-bold mb-1'
style={{ color: 'var(--semi-color-primary)' }}
>
{m.value}
<span className='text-lg font-normal'>
{m.suffix}
</span>
</div>
<Text
className='text-sm'
style={{ color: 'var(--semi-color-text-2)' }}
>
{t(m.key)}
</Text>
</div>
))}
</div>
</div>
{/* 框架兼容性图标 */}
<div className='mt-12 md:mt-16 lg:mt-20 w-full'>
<div className='flex items-center mb-6 md:mb-8 justify-center'>
<Text
type='tertiary'
className='text-lg md:text-xl lg:text-2xl font-light'
>
{t('支持众多的大模型供应商')}
</Text>
</div>
<div className='flex flex-wrap items-center justify-center gap-3 sm:gap-4 md:gap-6 lg:gap-8 max-w-5xl mx-auto px-4'>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Moonshot size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<OpenAI size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<XAI size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Zhipu.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Volcengine.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Cohere.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Claude.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Gemini.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Suno size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Minimax.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Wenxin.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Spark.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Qingyan.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<DeepSeek.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Qwen.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Midjourney size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Grok size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<AzureAI.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Hunyuan.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Xinference.Color size={40} />
</div>
<div className='w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12 flex items-center justify-center'>
<Typography.Text className='!text-lg sm:!text-xl md:!text-2xl lg:!text-3xl font-bold'>
30+
</Typography.Text>
</div>
</div>
</div>
{/* Provider Icons */}
<div className='w-full py-10 md:py-14'>
<div className='max-w-5xl mx-auto px-4'>
<Text
className='text-sm block text-center mb-8'
style={{ color: 'var(--semi-color-text-2)' }}
>
{t('支持众多的大模型供应商')}
</Text>
<div className='flex flex-wrap items-center justify-center gap-4 md:gap-6'>
<OpenAI size={32} />
<Claude.Color size={32} />
<Gemini.Color size={32} />
<DeepSeek.Color size={32} />
<Qwen.Color size={32} />
<Grok size={32} />
<Moonshot size={32} />
<Zhipu.Color size={32} />
<Volcengine.Color size={32} />
<Hunyuan.Color size={32} />
<Minimax.Color size={32} />
<Cohere.Color size={32} />
<AzureAI.Color size={32} />
<Xinference.Color size={32} />
</div>
</div>
</div>