design: redesign homepage with tech-minimalist style, remove blur-ball and shine-text
Docker Build / Build and Push Docker Image (push) Successful in 4m27s
Docker Build / Build and Push Docker Image (push) Successful in 4m27s
This commit is contained in:
Vendored
+11
@@ -1379,6 +1379,17 @@
|
||||
"已复制:{{name}}": "Copied: {{name}}",
|
||||
"已复制全部数据": "All data copied",
|
||||
"已复制到剪切板": "Copied to clipboard",
|
||||
"统一 AI 接入": "Unified AI Access",
|
||||
"大模型": "LLM",
|
||||
"统一接口网关": "Unified API Gateway",
|
||||
"一个端点,接入所有模型。兼容 OpenAI 格式,即换即用。": "One endpoint for all models. OpenAI-compatible, switch and go.",
|
||||
"登录控制台": "Console",
|
||||
"availability": "Availability",
|
||||
"latency": "Latency",
|
||||
"compatibility": "Compatibility",
|
||||
"providers": "Providers",
|
||||
"Supported Providers": "Supported Providers",
|
||||
"加载首页内容失败...": "Failed to load homepage content...",
|
||||
"已复制到剪贴板": "Copied to clipboard",
|
||||
"已复制到剪贴板!": "Copied to clipboard!",
|
||||
"已复制字段:{{name}}": "Field copied: {{name}}",
|
||||
|
||||
Vendored
+11
@@ -920,6 +920,17 @@
|
||||
"已复制:{{name}}": "已复制:{{name}}",
|
||||
"已复制全部数据": "已复制全部数据",
|
||||
"已复制到剪切板": "已复制到剪切板",
|
||||
"统一 AI 接入": "统一 AI 接入",
|
||||
"大模型": "大模型",
|
||||
"统一接口网关": "统一接口网关",
|
||||
"一个端点,接入所有模型。兼容 OpenAI 格式,即换即用。": "一个端点,接入所有模型。兼容 OpenAI 格式,即换即用。",
|
||||
"登录控制台": "登录控制台",
|
||||
"availability": "可用性",
|
||||
"latency": "延迟",
|
||||
"compatibility": "兼容性",
|
||||
"providers": "供应商",
|
||||
"Supported Providers": "支持的供应商",
|
||||
"加载首页内容失败...": "加载首页内容失败...",
|
||||
"已复制到剪贴板": "已复制到剪贴板",
|
||||
"已复制到剪贴板!": "已复制到剪贴板!",
|
||||
"已复制模型名称": "已复制模型名称",
|
||||
|
||||
Vendored
+202
-25
@@ -769,40 +769,217 @@ html.dark .sbg-variant-green {
|
||||
}
|
||||
|
||||
/* ==================== Banner 背景模糊球 ==================== */
|
||||
.blur-ball {
|
||||
|
||||
/* ==================== Home Page Styles ==================== */
|
||||
.home-hero {
|
||||
flex: 1 0 auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Grid background - tech feel */
|
||||
.home-grid-bg {
|
||||
position: absolute;
|
||||
width: 360px;
|
||||
height: 360px;
|
||||
border-radius: 50%;
|
||||
filter: blur(120px);
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(rgba(var(--semi-grey-1), 0.06) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(var(--semi-grey-1), 0.06) 1px, transparent 1px);
|
||||
background-size: 60px 60px;
|
||||
mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, black 30%, transparent 100%);
|
||||
-webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, black 30%, transparent 100%);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.blur-ball-indigo {
|
||||
background: #6366f1;
|
||||
/* indigo-500 */
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
html.dark .home-grid-bg {
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* Tag badge */
|
||||
.home-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 16px;
|
||||
border-radius: 9999px;
|
||||
border: 1px solid var(--semi-color-border);
|
||||
background: var(--semi-color-bg-1);
|
||||
font-size: 13px;
|
||||
color: var(--semi-color-text-1);
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.home-tag-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #10b981;
|
||||
box-shadow: 0 0 6px #10b981;
|
||||
}
|
||||
|
||||
/* Title */
|
||||
.home-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: var(--semi-color-text-0);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-title {
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.home-title {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.home-title-accent {
|
||||
background: linear-gradient(135deg, var(--semi-color-primary) 0%, #06b6d4 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
/* Subtitle */
|
||||
.home-subtitle {
|
||||
margin-top: 16px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
color: var(--semi-color-text-2);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-subtitle {
|
||||
font-size: 1.125rem;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* URL bar */
|
||||
.home-url-bar {
|
||||
margin-top: 24px;
|
||||
width: 100%;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.home-url-input {
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
.home-url-input .semi-input-wrapper {
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
/* CTA button */
|
||||
.home-cta-btn {
|
||||
border-radius: 10px !important;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
/* Metrics */
|
||||
.home-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 0;
|
||||
margin-top: 48px;
|
||||
width: 100%;
|
||||
max-width: 520px;
|
||||
border: 1px solid var(--semi-color-border);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: var(--semi-color-bg-1);
|
||||
}
|
||||
|
||||
.home-metric-item {
|
||||
padding: 16px 12px;
|
||||
text-align: center;
|
||||
border-right: 1px solid var(--semi-color-border);
|
||||
}
|
||||
|
||||
.home-metric-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.home-metric-value {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--semi-color-text-0);
|
||||
font-variant-numeric: tabular-nums;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-metric-value {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.home-metric-suffix {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: var(--semi-color-text-1);
|
||||
}
|
||||
|
||||
.home-metric-label {
|
||||
font-size: 12px;
|
||||
color: var(--semi-color-text-2);
|
||||
margin-top: 4px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* Providers */
|
||||
.home-providers {
|
||||
margin-top: 48px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.home-provider-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.home-provider-grid {
|
||||
gap: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-provider-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.blur-ball-teal {
|
||||
background: #14b8a6;
|
||||
/* teal-400 */
|
||||
top: 200px;
|
||||
left: 30%;
|
||||
opacity: 0.4;
|
||||
.home-provider-icon:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 浅色主题下让模糊球更柔和 */
|
||||
html:not(.dark) .blur-ball-indigo {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
html:not(.dark) .blur-ball-teal {
|
||||
opacity: 0.2;
|
||||
@media (min-width: 768px) {
|
||||
.home-provider-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 卡片马卡龙模糊球(类封装) ==================== */
|
||||
|
||||
Vendored
+102
-185
@@ -22,49 +22,57 @@ import {
|
||||
Button,
|
||||
Typography,
|
||||
Input,
|
||||
ScrollList,
|
||||
ScrollItem,
|
||||
} 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,
|
||||
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,
|
||||
Zhipu,
|
||||
Volcengine,
|
||||
Hunyuan,
|
||||
Wenxin,
|
||||
Minimax,
|
||||
Spark,
|
||||
Grok,
|
||||
Cohere,
|
||||
Moonshot,
|
||||
Midjourney,
|
||||
Suno,
|
||||
AzureAI,
|
||||
Xinference,
|
||||
Qingyan,
|
||||
XAI,
|
||||
} 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 PROVIDERS = [
|
||||
OpenAI, Claude, Gemini, DeepSeek, Qwen, Zhipu, Volcengine,
|
||||
Hunyuan, Wenxin, Minimax, Spark, Grok, Cohere, Moonshot,
|
||||
Midjourney, Suno, AzureAI, Xinference, Qingyan, XAI,
|
||||
];
|
||||
|
||||
const Home = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [statusState] = useContext(StatusContext);
|
||||
@@ -73,12 +81,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 () => {
|
||||
@@ -93,7 +97,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 +108,7 @@ const Home = () => {
|
||||
}
|
||||
} else {
|
||||
showError(message);
|
||||
setHomePageContent('加载首页内容失败...');
|
||||
setHomePageContent(t('加载首页内容失败...'));
|
||||
}
|
||||
setHomePageContentLoaded(true);
|
||||
};
|
||||
@@ -133,7 +136,6 @@ const Home = () => {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
checkNoticeAndShow();
|
||||
}, []);
|
||||
|
||||
@@ -141,13 +143,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
|
||||
@@ -157,176 +152,98 @@ const Home = () => {
|
||||
/>
|
||||
{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' : ''}`}
|
||||
>
|
||||
<>
|
||||
{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 className='home-hero w-full relative'>
|
||||
{/* Grid background */}
|
||||
<div className='home-grid-bg' />
|
||||
|
||||
<div className='flex items-center justify-center px-4 pt-20 pb-16 md:pt-28 md:pb-24'>
|
||||
<div className='flex flex-col items-center justify-center text-center max-w-3xl mx-auto relative z-10'>
|
||||
{/* Tag */}
|
||||
<div className='home-tag mb-6'>
|
||||
<span className='home-tag-dot' />
|
||||
<span>{t('统一 AI 接入')}</span>
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div className='flex flex-row gap-4 justify-center items-center'>
|
||||
{/* Title */}
|
||||
<h1 className='home-title'>
|
||||
{t('大模型')}
|
||||
<br />
|
||||
<span className='home-title-accent'>{t('统一接口网关')}</span>
|
||||
</h1>
|
||||
|
||||
{/* Subtitle */}
|
||||
<p className='home-subtitle'>
|
||||
{t('一个端点,接入所有模型。兼容 OpenAI 格式,即换即用。')}
|
||||
</p>
|
||||
|
||||
{/* Base URL */}
|
||||
<div className='home-url-bar'>
|
||||
<Input
|
||||
readonly
|
||||
value={serverAddress}
|
||||
className='home-url-input'
|
||||
size={isMobile ? 'default' : 'large'}
|
||||
suffix={
|
||||
<Button
|
||||
type='primary'
|
||||
onClick={handleCopyBaseURL}
|
||||
icon={<IconCopy />}
|
||||
className='!rounded-lg'
|
||||
size={isMobile ? 'default' : 'large'}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div className='flex flex-row gap-3 justify-center items-center mt-6'>
|
||||
<Link to='/console'>
|
||||
<Button
|
||||
theme='solid'
|
||||
type='primary'
|
||||
size={isMobile ? 'default' : 'large'}
|
||||
className='!rounded-3xl px-8 py-2'
|
||||
icon={<IconPlay />}
|
||||
className='home-cta-btn'
|
||||
icon={<IconArrowRight />}
|
||||
iconPosition='right'
|
||||
>
|
||||
{t('获取密钥')}
|
||||
</Button>
|
||||
</Link>
|
||||
{isDemoSiteMode && statusState?.status?.version ? (
|
||||
<Link to='/login'>
|
||||
<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',
|
||||
)
|
||||
}
|
||||
className='!rounded-lg px-6'
|
||||
>
|
||||
{statusState.status.version}
|
||||
{t('登录控制台')}
|
||||
</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>
|
||||
)
|
||||
)}
|
||||
</Link>
|
||||
</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} />
|
||||
{/* Metrics */}
|
||||
<div className='home-metrics'>
|
||||
{METRICS.map((m) => (
|
||||
<div key={m.key} className='home-metric-item'>
|
||||
<div className='home-metric-value'>
|
||||
{m.value}<span className='home-metric-suffix'>{m.suffix}</span>
|
||||
</div>
|
||||
<div className='home-metric-label'>{t(m.key)}</div>
|
||||
</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>
|
||||
|
||||
{/* Providers */}
|
||||
<div className='home-providers'>
|
||||
<Text type='tertiary' className='!text-xs !tracking-widest !uppercase'>
|
||||
{t('Supported Providers')}
|
||||
</Text>
|
||||
<div className='home-provider-grid'>
|
||||
{PROVIDERS.map((Icon, i) => (
|
||||
<div key={i} className='home-provider-icon'>
|
||||
<Icon size={isMobile ? 24 : 28} />
|
||||
</div>
|
||||
))}
|
||||
<div className='home-provider-icon'>
|
||||
<Text className='!text-sm !font-semibold'>30+</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user