feat: add Cloud and SelfHosted components with updated PlanSwitcher integration

This commit is contained in:
twwu 2025-08-14 15:54:07 +08:00
parent 8a5bcd11f2
commit 46224724a2
5 changed files with 80 additions and 10 deletions

View File

@ -0,0 +1,32 @@
type CloudProps = {
isActive: boolean
}
const Cloud = ({
isActive,
}: CloudProps) => {
const color = isActive ? 'var(--color-saas-dify-blue-accessible)' : 'var(--color-text-primary)'
return (
<svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'>
<g clip-path='url(#clip0_1_4630)'>
<rect y='0.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='6' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='12' y='0.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' y='6.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='6' y='6.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='12' y='6.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect y='12.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='6' y='12.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='12' y='12.5' width='4' height='4' rx='2' fill={color} />
</g>
<defs>
<clipPath id='clip0_1_4630'>
<rect width='16' height='16' fill='white' transform='translate(0 0.5)' />
</clipPath>
</defs>
</svg>
)
}
export default Cloud

View File

@ -0,0 +1,2 @@
export { default as Cloud } from './cloud'
export { default as SelfHosted } from './self-hosted'

View File

@ -0,0 +1,32 @@
type SelfHostedProps = {
isActive: boolean
}
const SelfHosted = ({
isActive,
}: SelfHostedProps) => {
const color = isActive ? 'var(--color-saas-dify-blue-accessible)' : 'var(--color-text-primary)'
return (
<svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'>
<g clip-path='url(#clip0_1_4644)'>
<rect opacity='0.18' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='6' y='0.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='12' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect y='6.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='6' y='6.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='12' y='6.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' y='12.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='6' y='12.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='12' y='12.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
</g>
<defs>
<clipPath id='clip0_1_4644'>
<rect width='16' height='16' fill='white' transform='translate(0 0.5)' />
</clipPath>
</defs>
</svg>
)
}
export default SelfHosted

View File

@ -2,7 +2,7 @@ import type { FC } from 'react'
import React from 'react'
import type { Category } from '../index'
import { useTranslation } from 'react-i18next'
import { Ri24HoursFill, RiTerminalBoxFill } from '@remixicon/react'
import { Cloud, SelfHosted } from '../assets'
import Tab from './tab'
import Divider from '@/app/components/base/divider'
import type { PlanRange } from './plan-range-switcher'
@ -27,12 +27,12 @@ const PlanSwitcher: FC<PlanSwitcherProps> = ({
cloud: {
value: 'cloud' as Category,
label: t('billing.plansCommon.cloud'),
Icon: Ri24HoursFill,
Icon: Cloud,
},
self: {
value: 'self' as Category,
label: t('billing.plansCommon.self'),
Icon: RiTerminalBoxFill,
Icon: SelfHosted,
},
}

View File

@ -2,7 +2,7 @@ import React, { useCallback } from 'react'
import cn from '@/utils/classnames'
type TabProps<T> = {
Icon: React.ComponentType<any>
Icon: React.ComponentType<{ isActive: boolean }>
value: T
label: string
isActive: boolean
@ -22,14 +22,18 @@ const Tab = <T,>({
return (
<div
className={cn(
'flex cursor-pointer items-center justify-center gap-x-2 px-5 py-3 text-text-secondary',
isActive && 'text-saas-dify-blue-accessible',
)}
className='flex cursor-pointer items-center justify-center gap-x-2 px-5 py-3'
onClick={handleClick}
>
<Icon className='size-4' />
<span className='system-xl-semibold'>{label}</span>
<Icon isActive={isActive} />
<span
className={cn(
'system-xl-semibold text-text-secondary',
isActive && 'text-saas-dify-blue-accessible',
)}
>
{label}
</span>
</div>
)
}