Bläddra i källkod

Feat: settings dark mode (#15184)

KVOJJJin 1 månad sedan
förälder
incheckning
f588ccff72
34 ändrade filer med 447 tillägg och 424 borttagningar
  1. 9 9
      web/app/components/billing/billing-page/index.tsx
  2. 49 76
      web/app/components/billing/plan/index.tsx
  3. 0 1
      web/app/components/billing/pricing/index.tsx
  4. 5 3
      web/app/components/billing/progress-bar/index.tsx
  5. 8 19
      web/app/components/billing/upgrade-btn/index.tsx
  6. 4 2
      web/app/components/billing/usage-info/apps-info.tsx
  7. 25 30
      web/app/components/billing/usage-info/index.tsx
  8. 4 2
      web/app/components/billing/usage-info/vector-space-info.tsx
  9. 18 26
      web/app/components/custom/custom-page/index.tsx
  10. 149 61
      web/app/components/custom/custom-web-app-brand/index.tsx
  11. 1 1
      web/app/components/datasets/create/website/base/field.tsx
  12. 10 8
      web/app/components/header/account-setting/api-based-extension-page/empty.tsx
  13. 6 4
      web/app/components/header/account-setting/api-based-extension-page/index.tsx
  14. 13 12
      web/app/components/header/account-setting/api-based-extension-page/item.tsx
  15. 2 2
      web/app/components/header/account-setting/api-based-extension-page/modal.tsx
  16. 15 27
      web/app/components/header/account-setting/data-source-page/data-source-notion/operate/index.tsx
  17. 8 8
      web/app/components/header/account-setting/data-source-page/data-source-website/config-firecrawl-modal.tsx
  18. 8 8
      web/app/components/header/account-setting/data-source-page/data-source-website/config-jina-reader-modal.tsx
  19. 2 2
      web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx
  20. 2 2
      web/app/components/header/account-setting/data-source-page/panel/config-item.tsx
  21. 9 11
      web/app/components/header/account-setting/data-source-page/panel/index.tsx
  22. 6 6
      web/app/components/header/account-setting/index.tsx
  23. 21 17
      web/app/components/header/account-setting/members-page/index.tsx
  24. 8 9
      web/app/components/header/account-setting/members-page/invite-modal/index.tsx
  25. 20 20
      web/app/components/header/account-setting/members-page/invite-modal/role-selector.tsx
  26. 1 1
      web/app/components/header/account-setting/members-page/invited-modal/index.module.css
  27. 6 6
      web/app/components/header/account-setting/members-page/invited-modal/index.tsx
  28. 6 6
      web/app/components/header/account-setting/members-page/invited-modal/invitation-link.tsx
  29. 0 3
      web/app/components/header/account-setting/members-page/operation/index.module.css
  30. 14 40
      web/app/components/header/account-setting/members-page/operation/index.tsx
  31. 7 1
      web/i18n/en-US/billing.ts
  32. 2 0
      web/i18n/en-US/custom.ts
  33. 7 1
      web/i18n/zh-Hans/billing.ts
  34. 2 0
      web/i18n/zh-Hans/custom.ts

+ 9 - 9
web/app/components/billing/billing-page/index.tsx

@@ -4,10 +4,10 @@ import React from 'react'
 import { useTranslation } from 'react-i18next'
 import useSWR from 'swr'
 import {
-  RiExternalLinkLine,
+  RiArrowRightUpLine,
 } from '@remixicon/react'
 import PlanComp from '../plan'
-import { ReceiptList } from '../../base/icons/src/vender/line/financeAndECommerce'
+import Divider from '@/app/components/base/divider'
 import { fetchBillingUrl } from '@/service/billing'
 import { useAppContext } from '@/context/app-context'
 import { useProviderContext } from '@/context/provider-context'
@@ -25,13 +25,13 @@ const Billing: FC = () => {
     <div>
       <PlanComp loc={'billing-page'} />
       {enableBilling && isCurrentWorkspaceManager && billingUrl && (
-        <a className='mt-5 flex px-6 justify-between h-12 items-center bg-gray-50 rounded-xl cursor-pointer' href={billingUrl} target='_blank' rel='noopener noreferrer'>
-          <div className='flex items-center'>
-            <ReceiptList className='w-4 h-4 text-gray-700' />
-            <div className='ml-2 text-sm font-normal text-gray-700'>{t('billing.viewBilling')}</div>
-          </div>
-          <RiExternalLinkLine className='w-3 h-3' />
-        </a>
+        <>
+          <Divider className='my-4' />
+          <a className='flex items-center text-text-accent-light-mode-only system-xs-medium cursor-pointer' href={billingUrl} target='_blank' rel='noopener noreferrer'>
+            <span className='pr-0.5'>{t('billing.viewBilling')}</span>
+            <RiArrowRightUpLine className='w-4 h-4' />
+          </a>
+        </>
       )}
     </div>
   )

+ 49 - 76
web/app/components/billing/plan/index.tsx

@@ -2,36 +2,21 @@
 import type { FC } from 'react'
 import React from 'react'
 import { useTranslation } from 'react-i18next'
+import {
+  RiBook2Line,
+  RiBox3Line,
+  RiFileEditLine,
+  RiGroup3Line,
+  RiGroupLine,
+  RiSquareLine,
+} from '@remixicon/react'
 import { Plan, SelfHostedPlan } from '../type'
 import VectorSpaceInfo from '../usage-info/vector-space-info'
 import AppsInfo from '../usage-info/apps-info'
 import UpgradeBtn from '../upgrade-btn'
-import { User01 } from '../../base/icons/src/vender/line/users'
-import { MessageFastPlus } from '../../base/icons/src/vender/line/communication'
-import { FileUpload } from '../../base/icons/src/vender/line/files'
-import cn from '@/utils/classnames'
 import { useProviderContext } from '@/context/provider-context'
 import UsageInfo from '@/app/components/billing/usage-info'
 
-const typeStyle = {
-  [Plan.sandbox]: {
-    textClassNames: 'text-gray-900',
-    bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #EAECF0',
-  },
-  [Plan.professional]: {
-    textClassNames: 'text-[#026AA2]',
-    bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #E0F2FE',
-  },
-  [Plan.team]: {
-    textClassNames: 'text-[#3538CD]',
-    bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #E0EAFF',
-  },
-  [SelfHostedPlan.enterprise]: {
-    textClassNames: 'text-[#DC6803]',
-    bg: 'linear-gradient(113deg, rgba(255, 255, 255, 0.51) 3.51%, rgba(255, 255, 255, 0.00) 111.71%), #FFEED3',
-  },
-}
-
 type Props = {
   loc: string
 }
@@ -50,74 +35,62 @@ const PlanComp: FC<Props> = ({
     total,
   } = plan
 
-  const isInHeader = loc === 'header'
-
   return (
-    <div
-      className='rounded-xl border border-white select-none'
-      style={{
-        background: typeStyle[type].bg,
-        boxShadow: '5px 7px 12px 0px rgba(0, 0, 0, 0.06)',
-      }}
-    >
-      <div className='flex justify-between px-6 py-5 items-center'>
-        <div>
-          <div
-            className='leading-[18px] text-xs font-normal opacity-70'
-            style={{
-              color: 'rgba(0, 0, 0, 0.64)',
-            }}
-          >
-            {t('billing.currentPlan')}
-          </div>
-          <div className={cn(typeStyle[type].textClassNames, 'leading-[125%] text-lg font-semibold uppercase')}>
-            {t(`billing.plans.${type}.name`)}
+    <div className='bg-background-section-burn rounded-2xl border-[0.5px] border-effects-highlight-lightmode-off'>
+      <div className='p-6 pb-2'>
+        {plan.type === Plan.sandbox && (
+          <RiBox3Line className='w-7 h-7 text-text-primary'/>
+        )}
+        {plan.type === Plan.professional && (
+          <RiSquareLine className='w-7 h-7 rotate-90 text-util-colors-blue-brand-blue-brand-600'/>
+        )}
+        {plan.type === Plan.team && (
+          <RiGroup3Line className='w-7 h-7 text-util-colors-indigo-indigo-600'/>
+        )}
+        {(plan.type as any) === SelfHostedPlan.enterprise && (
+          <RiGroup3Line className='w-7 h-7 text-util-colors-indigo-indigo-600'/>
+        )}
+        <div className='mt-1 flex items-center'>
+          <div className='grow'>
+            <div className='mb-1 flex items-center gap-1'>
+              <div className='text-text-primary system-md-semibold-uppercase'>{t(`billing.plans.${type}.name`)}</div>
+              <div className='px-1 py-0.5 border border-divider-deep rounded-[5px] text-text-tertiary system-2xs-medium-uppercase'>{t('billing.currentPlan')}</div>
+            </div>
+            <div className='system-xs-regular text-util-colors-gray-gray-600'>{t(`billing.plans.${type}.for`)}</div>
           </div>
+          {(plan.type as any) !== SelfHostedPlan.enterprise && (
+            <UpgradeBtn
+              className='shrink-0'
+              isPlain={type === Plan.team}
+              isShort
+              loc={loc}
+            />
+          )}
         </div>
-        {(!isInHeader || (isInHeader && type !== Plan.sandbox)) && (
-          <UpgradeBtn
-            className='flex-shrink-0'
-            isPlain={type !== Plan.sandbox}
-            loc={loc}
-          />
-        )}
       </div>
-
       {/* Plan detail */}
-      <div className='rounded-xl bg-white px-6 py-3'>
-
+      <div className='p-2 grid content-start grid-cols-3 gap-1'>
+        <AppsInfo />
         <UsageInfo
-          className='py-3'
-          Icon={User01}
+          Icon={RiGroupLine}
           name={t('billing.usagePage.teamMembers')}
           usage={usage.teamMembers}
           total={total.teamMembers}
         />
-        <AppsInfo className='py-3' />
-        <VectorSpaceInfo className='py-3' />
         <UsageInfo
-          className='py-3'
-          Icon={MessageFastPlus}
-          name={t('billing.usagePage.annotationQuota')}
-          usage={usage.annotatedResponse}
-          total={total.annotatedResponse}
-        />
-        <UsageInfo
-          className='py-3'
-          Icon={FileUpload}
+          Icon={RiBook2Line}
           name={t('billing.usagePage.documentsUploadQuota')}
           usage={usage.documentsUploadQuota}
           total={total.documentsUploadQuota}
         />
-        {isInHeader && type === Plan.sandbox && (
-          <UpgradeBtn
-            className='flex-shrink-0 my-3'
-            isFull
-            size='lg'
-            isPlain={type !== Plan.sandbox}
-            loc={loc}
-          />
-        )}
+        <VectorSpaceInfo />
+        <UsageInfo
+          Icon={RiFileEditLine}
+          name={t('billing.usagePage.annotationQuota')}
+          usage={usage.annotatedResponse}
+          total={total.annotatedResponse}
+        />
+
       </div>
     </div>
   )

+ 0 - 1
web/app/components/billing/pricing/index.tsx

@@ -60,7 +60,6 @@ const Pricing: FC<Props> = ({
             <div className='py-2 flex items-center justify-between h-[64px]'>
               <TabSlider
                 value={currentPlan}
-                itemWidth={170}
                 className='inline-flex'
                 options={[
                   {

+ 5 - 3
web/app/components/billing/progress-bar/index.tsx

@@ -1,18 +1,20 @@
+import cn from '@/utils/classnames'
+
 type ProgressBarProps = {
   percent: number
   color: string
 }
+
 const ProgressBar = ({
   percent = 0,
   color = '#2970FF',
 }: ProgressBarProps) => {
   return (
-    <div className='bg-[#F2F4F7] rounded-[4px] overflow-hidden'>
+    <div className='bg-components-progress-bar-bg rounded-[6px] overflow-hidden'>
       <div
-        className='h-2 rounded-[4px]'
+        className={cn('h-1 rounded-[6px]', color)}
         style={{
           width: `${Math.min(percent, 100)}%`,
-          backgroundColor: color,
         }}
       />
     </div>

+ 8 - 19
web/app/components/billing/upgrade-btn/index.tsx

@@ -3,8 +3,8 @@ import type { FC } from 'react'
 import React from 'react'
 import { useTranslation } from 'react-i18next'
 import PremiumBadge from '../../base/premium-badge'
+import Button from '@/app/components/base/button'
 import { SparklesSoft } from '@/app/components/base/icons/src/public/common'
-import cn from '@/utils/classnames'
 import { useModalContext } from '@/context/modal-context'
 
 type Props = {
@@ -17,23 +17,7 @@ type Props = {
   loc?: string
 }
 
-const PlainBtn = ({ className, onClick }: { className?: string; onClick: () => void }) => {
-  const { t } = useTranslation()
-
-  return (
-    <div
-      className={cn(className, 'flex items-center h-8 px-3 rounded-lg border border-gray-200 bg-white shadow-sm cursor-pointer')}
-      onClick={onClick}
-    >
-      <div className='leading-[18px] text-[13px] font-medium text-gray-700'>
-        {t('billing.upgradeBtn.plain')}
-      </div>
-    </div>
-  )
-}
-
 const UpgradeBtn: FC<Props> = ({
-  className,
   isPlain = false,
   isShort = false,
   onClick: _onClick,
@@ -56,8 +40,13 @@ const UpgradeBtn: FC<Props> = ({
     }
   }
 
-  if (isPlain)
-    return <PlainBtn onClick={onClick} className={className} />
+  if (isPlain) {
+    return (
+      <Button onClick={onClick}>
+        {t('billing.upgradeBtn.plain')}
+      </Button>
+    )
+  }
 
   return (
     <PremiumBadge

+ 4 - 2
web/app/components/billing/usage-info/apps-info.tsx

@@ -2,7 +2,9 @@
 import type { FC } from 'react'
 import React from 'react'
 import { useTranslation } from 'react-i18next'
-import { ChatBot } from '../../base/icons/src/vender/line/communication'
+import {
+  RiApps2Line,
+} from '@remixicon/react'
 import UsageInfo from '../usage-info'
 import { useProviderContext } from '@/context/provider-context'
 
@@ -22,7 +24,7 @@ const AppsInfo: FC<Props> = ({
   return (
     <UsageInfo
       className={className}
-      Icon={ChatBot}
+      Icon={RiApps2Line}
       name={t('billing.usagePage.buildApps')}
       usage={usage.buildApps}
       total={total.buildApps}

+ 25 - 30
web/app/components/billing/usage-info/index.tsx

@@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next'
 import ProgressBar from '../progress-bar'
 import { NUM_INFINITE } from '../config'
 import Tooltip from '@/app/components/base/tooltip'
+import cn from '@/utils/classnames'
 
 type Props = {
   className?: string
@@ -33,43 +34,37 @@ const UsageInfo: FC<Props> = ({
   const percent = usage / total * 100
   const color = (() => {
     if (percent < LOW)
-      return '#155EEF'
+      return 'bg-components-progress-bar-progress-solid'
 
     if (percent < MIDDLE)
-      return '#F79009'
+      return 'bg-components-progress-warning-progress'
 
-    return '#F04438'
+    return 'bg-components-progress-error-progress'
   })()
   return (
-    <div className={className}>
-      <div className='flex justify-between h-5 items-center'>
-        <div className='flex items-center'>
-          <Icon className='w-4 h-4 text-gray-700' />
-          <div className='mx-1 leading-5 text-sm font-medium text-gray-700'>{name}</div>
-          {tooltip && (
-            <Tooltip
-              popupContent={
-                <div className='w-[180px]'>
-                  {tooltip}
-                </div>
-              }
-            />
-          )}
-        </div>
-        <div className='flex items-center leading-[18px] text-[13px] font-normal'>
-          <div style={{
-            color: percent < LOW ? '#344054' : color,
-          }}>{usage}{unit}</div>
-          <div className='mx-1 text-gray-300'>/</div>
-          <div className='text-gray-500'>{total === NUM_INFINITE ? t('billing.plansCommon.unlimited') : `${total}${unit}`}</div>
-        </div>
+    <div className={cn('p-4 flex flex-col gap-2 rounded-xl bg-components-panel-bg', className)}>
+      <Icon className='w-4 h-4 text-text-tertiary' />
+      <div className='flex items-center gap-1'>
+        <div className='system-xs-medium text-text-tertiary'>{name}</div>
+        {tooltip && (
+          <Tooltip
+            popupContent={
+              <div className='w-[180px]'>
+                {tooltip}
+              </div>
+            }
+          />
+        )}
       </div>
-      <div className='mt-2'>
-        <ProgressBar
-          percent={percent}
-          color={color}
-        />
+      <div className='flex items-center gap-1 system-md-semibold  text-text-primary'>
+        {usage}
+        <div className='system-md-regular text-text-quaternary'>/</div>
+        <div>{total === NUM_INFINITE ? t('billing.plansCommon.unlimited') : `${total}${unit}`}</div>
       </div>
+      <ProgressBar
+        percent={percent}
+        color={color}
+      />
     </div>
   )
 }

+ 4 - 2
web/app/components/billing/usage-info/vector-space-info.tsx

@@ -1,8 +1,10 @@
 'use client'
 import type { FC } from 'react'
 import React from 'react'
+import {
+  RiHardDrive3Line,
+} from '@remixicon/react'
 import { useTranslation } from 'react-i18next'
-import { ArtificialBrain } from '../../base/icons/src/vender/line/development'
 import UsageInfo from '../usage-info'
 import { useProviderContext } from '@/context/provider-context'
 
@@ -22,7 +24,7 @@ const VectorSpaceInfo: FC<Props> = ({
   return (
     <UsageInfo
       className={className}
-      Icon={ArtificialBrain}
+      Icon={RiHardDrive3Line}
       name={t('billing.usagePage.vectorSpace')}
       tooltip={t('billing.usagePage.vectorSpaceTooltip') as string}
       usage={usage.vectorSpace}

+ 18 - 26
web/app/components/custom/custom-page/index.tsx

@@ -1,44 +1,36 @@
 import { useTranslation } from 'react-i18next'
 import CustomWebAppBrand from '../custom-web-app-brand'
-import s from '../style.module.css'
-import GridMask from '@/app/components/base/grid-mask'
-import UpgradeBtn from '@/app/components/billing/upgrade-btn'
 import { useProviderContext } from '@/context/provider-context'
 import { Plan } from '@/app/components/billing/type'
 import { contactSalesUrl } from '@/app/components/billing/config'
+import { useModalContext } from '@/context/modal-context'
 
 const CustomPage = () => {
   const { t } = useTranslation()
   const { plan, enableBilling } = useProviderContext()
-
+  const { setShowPricingModal } = useModalContext()
   const showBillingTip = enableBilling && plan.type === Plan.sandbox
   const showContact = enableBilling && (plan.type === Plan.professional || plan.type === Plan.team)
 
   return (
     <div className='flex flex-col'>
-      {
-        showBillingTip && (
-          <GridMask canvasClassName='!rounded-xl'>
-            <div className='flex justify-between mb-1 px-6 py-5 h-[88px] shadow-md rounded-xl border-[0.5px] border-gray-200'>
-              <div className={`${s.textGradient} leading-[24px] text-base font-semibold`}>
-                <div>{t('custom.upgradeTip.prefix')}</div>
-                <div>{t('custom.upgradeTip.suffix')}</div>
-              </div>
-              <UpgradeBtn />
-            </div>
-          </GridMask>
-        )
-      }
-      <CustomWebAppBrand />
-      {
-        showContact && (
-          <div className='absolute bottom-0 h-[50px] leading-[50px] text-xs text-gray-500'>
-            {t('custom.customize.prefix')}
-            <a className='text-[#155EEF]' href={contactSalesUrl} target='_blank' rel='noopener noreferrer'>{t('custom.customize.contactUs')}</a>
-            {t('custom.customize.suffix')}
+      {showBillingTip && (
+        <div className='flex justify-between mb-1 p-4 pl-6 bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 shadow-lg backdrop-blur-sm rounded-xl'>
+          <div className='space-y-1 text-text-primary-on-surface'>
+            <div className='title-xl-semi-bold'>{t('custom.upgradeTip.title')}</div>
+            <div className='system-sm-regular'>{t('custom.upgradeTip.des')}</div>
           </div>
-        )
-      }
+          <div className='w-[120px] h-10 flex items-center justify-center bg-white rounded-3xl shadow-xs system-md-semibold text-text-accent cursor-pointer hover:opacity-95' onClick={() => setShowPricingModal()}>{t('billing.upgradeBtn.encourageShort')}</div>
+        </div>
+      )}
+      <CustomWebAppBrand />
+      {showContact && (
+        <div className='absolute bottom-0 h-[50px] leading-[50px] text-xs text-text-quaternary'>
+          {t('custom.customize.prefix')}
+          <a className='text-text-accent' href={contactSalesUrl} target='_blank' rel='noopener noreferrer'>{t('custom.customize.contactUs')}</a>
+          {t('custom.customize.suffix')}
+        </div>
+      )}
     </div>
   )
 }

+ 149 - 61
web/app/components/custom/custom-web-app-brand/index.tsx

@@ -2,22 +2,28 @@ import type { ChangeEvent } from 'react'
 import { useState } from 'react'
 import { useTranslation } from 'react-i18next'
 import {
+  RiEditBoxLine,
+  RiEqualizer2Line,
+  RiExchange2Fill,
+  RiImageAddLine,
+  RiLayoutLeft2Line,
   RiLoader2Line,
+  RiPlayLargeLine,
 } from '@remixicon/react'
-import s from './style.module.css'
 import LogoSite from '@/app/components/base/logo/logo-site'
 import Switch from '@/app/components/base/switch'
 import Button from '@/app/components/base/button'
-import { MessageDotsCircle } from '@/app/components/base/icons/src/vender/solid/communication'
-import { ImagePlus } from '@/app/components/base/icons/src/vender/line/images'
+import Divider from '@/app/components/base/divider'
 import { useProviderContext } from '@/context/provider-context'
 import { Plan } from '@/app/components/billing/type'
 import { imageUpload } from '@/app/components/base/image-uploader/utils'
 import { useToastContext } from '@/app/components/base/toast'
+import { BubbleTextMod } from '@/app/components/base/icons/src/vender/solid/communication'
 import {
   updateCurrentWorkspace,
 } from '@/service/common'
 import { useAppContext } from '@/context/app-context'
+import cn from '@/utils/classnames'
 
 const ALLOW_FILE_EXTENSIONS = ['svg', 'png']
 
@@ -107,32 +113,7 @@ const CustomWebAppBrand = () => {
 
   return (
     <div className='py-4'>
-      <div className='mb-2 text-sm font-medium text-gray-900'>{t('custom.webapp.title')}</div>
-      <div className='relative mb-4 pl-4 pb-6 pr-[119px] rounded-xl border-[0.5px] border-black/8 shadow-xs bg-gray-50 overflow-hidden'>
-        <div className={`${s.mask} absolute top-0 left-0 w-full -bottom-2 z-10`}></div>
-        <div className='flex items-center -mt-2 mb-4 p-6 bg-white rounded-xl'>
-          <div className='flex items-center px-4 w-[125px] h-9 rounded-lg bg-primary-600 border-[0.5px] border-primary-700 shadow-xs'>
-            <MessageDotsCircle className='shrink-0 mr-2 w-4 h-4 text-white' />
-            <div className='grow h-2 rounded-sm bg-white opacity-50' />
-          </div>
-        </div>
-        <div className='flex items-center h-5 justify-between'>
-          <div className='w-[369px] h-1.5 rounded-sm bg-gray-200 opacity-80' />
-          {
-            !webappBrandRemoved && (
-              <div className='flex items-center text-[10px] font-medium text-gray-400'>
-                POWERED BY
-                {
-                  webappLogo
-                    ? <img src={`${webappLogo}?hash=${imgKey}`} alt='logo' className='ml-2 block w-auto h-5' />
-                    : <LogoSite className='ml-2 !h-5' />
-                }
-              </div>
-            )
-          }
-        </div>
-      </div>
-      <div className='flex items-center justify-between mb-2 px-4 h-14 rounded-xl border-[0.5px] border-gray-200 bg-gray-50 text-sm font-medium text-gray-900'>
+      <div className='flex items-center justify-between mb-2 p-4 rounded-xl bg-background-section-burn system-md-medium text-text-primary'>
         {t('custom.webapp.removeBrand')}
         <Switch
           size='l'
@@ -141,34 +122,38 @@ const CustomWebAppBrand = () => {
           onChange={handleSwitch}
         />
       </div>
-      <div className={`
-        flex items-center justify-between px-4 py-3 rounded-xl border-[0.5px] border-gray-200 bg-gray-50
-        ${webappBrandRemoved && 'opacity-30'}
-      `}>
+      <div className={cn('flex items-center justify-between h-14 px-4 rounded-xl bg-background-section-burn', webappBrandRemoved && 'opacity-30')}>
         <div>
-          <div className='leading-5 text-sm font-medium text-gray-900'>{t('custom.webapp.changeLogo')}</div>
-          <div className='leading-[18px] text-xs text-gray-500'>{t('custom.webapp.changeLogoTip')}</div>
+          <div className='system-md-medium text-text-primary'>{t('custom.webapp.changeLogo')}</div>
+          <div className='system-xs-regular text-text-tertiary'>{t('custom.webapp.changeLogoTip')}</div>
         </div>
         <div className='flex items-center'>
+          {(uploadDisabled || (!webappLogo && !webappBrandRemoved)) && (
+            <>
+              <Button
+                variant='ghost'
+                disabled={uploadDisabled || (!webappLogo && !webappBrandRemoved)}
+                onClick={handleRestore}
+              >
+                {t('custom.restore')}
+              </Button>
+              <div className='mx-2 h-5 w-[1px] bg-divider-regular'></div>
+            </>
+          )}
           {
             !uploading && (
               <Button
-                className={`
-                  relative mr-2
-                `}
+                className='relative mr-2'
                 disabled={uploadDisabled}
               >
-                <ImagePlus className='mr-2 w-4 h-4' />
+                <RiImageAddLine className='mr-1 w-4 h-4' />
                 {
                   (webappLogo || fileId)
                     ? t('custom.change')
                     : t('custom.upload')
                 }
                 <input
-                  className={`
-                    absolute block inset-0 opacity-0 text-[0] w-full
-                    ${uploadDisabled ? 'cursor-not-allowed' : 'cursor-pointer'}
-                  `}
+                  className={cn('absolute block inset-0 opacity-0 text-[0] w-full', uploadDisabled ? 'cursor-not-allowed' : 'cursor-pointer')}
                   onClick={e => (e.target as HTMLInputElement).value = ''}
                   type='file'
                   accept={ALLOW_FILE_EXTENSIONS.map(ext => `.${ext}`).join(',')}
@@ -184,7 +169,7 @@ const CustomWebAppBrand = () => {
                 className='relative mr-2'
                 disabled={true}
               >
-                <RiLoader2Line className='animate-spin mr-2 w-4 h-4' />
+                <RiLoader2Line className='animate-spin mr-1 w-4 h-4' />
                 {t('custom.uploading')}
               </Button>
             )
@@ -193,37 +178,140 @@ const CustomWebAppBrand = () => {
             fileId && (
               <>
                 <Button
-                  variant='primary'
                   className='mr-2'
-                  onClick={handleApply}
+                  onClick={handleCancel}
                   disabled={webappBrandRemoved || !isCurrentWorkspaceManager}
                 >
-                  {t('custom.apply')}
+                  {t('common.operation.cancel')}
                 </Button>
                 <Button
+                  variant='primary'
                   className='mr-2'
-                  onClick={handleCancel}
+                  onClick={handleApply}
                   disabled={webappBrandRemoved || !isCurrentWorkspaceManager}
                 >
-                  {t('common.operation.cancel')}
+                  {t('custom.apply')}
                 </Button>
               </>
             )
           }
-          <div className='mr-2 h-5 w-[1px] bg-black/5'></div>
-          <Button
-            disabled={uploadDisabled || (!webappLogo && !webappBrandRemoved)}
-            onClick={handleRestore}
-          >
-            {t('custom.restore')}
-          </Button>
         </div>
       </div>
-      {
-        uploadProgress === -1 && (
-          <div className='mt-2 text-xs text-[#D92D20]'>{t('custom.uploadedFail')}</div>
-        )
-      }
+      {uploadProgress === -1 && (
+        <div className='mt-2 text-xs text-[#D92D20]'>{t('custom.uploadedFail')}</div>
+      )}
+      <div className='mt-5 mb-2 flex items-center gap-2'>
+        <div className='shrink-0 system-xs-medium-uppercase text-text-tertiary'>{t('appOverview.overview.appInfo.preview')}</div>
+        <Divider bgStyle='gradient' className='grow' />
+      </div>
+      <div className='relative mb-2 flex items-center gap-3'>
+        {/* chat card */}
+        <div className='grow basis-1/2 h-[320px] flex bg-background-default-burn rounded-2xl border-[0.5px] border-components-panel-border-subtle overflow-hidden'>
+          <div className='shrink-0 h-full w-[232px] p-1 pr-0 flex flex-col'>
+            <div className='p-3 pr-2 flex items-center gap-3'>
+              <div className={cn('w-8 h-8 inline-flex items-center justify-center rounded-lg border border-divider-regular', 'bg-components-icon-bg-blue-light-solid')}>
+                <BubbleTextMod className='w-4 h-4 text-components-avatar-shape-fill-stop-100' />
+              </div>
+              <div className='grow system-md-semibold text-text-secondary'>Chatflow App</div>
+              <div className='p-1.5'>
+                <RiLayoutLeft2Line className='w-4 h-4 text-text-tertiary' />
+              </div>
+            </div>
+            <div className='shrink-0 px-4 py-3'>
+              <Button variant='secondary-accent' className='w-full justify-center'>
+                <RiEditBoxLine className='w-4 h-4 mr-1' />
+                <div className='p-1 opacity-20'>
+                  <div className='h-2 w-[94px] rounded-sm bg-text-accent-light-mode-only'></div>
+                </div>
+              </Button>
+            </div>
+            <div className='grow px-3 pt-5'>
+              <div className='h-8 px-3 py-1 flex items-center'>
+                <div className='w-14 h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+              </div>
+              <div className='h-8 px-3 py-1 flex items-center'>
+                <div className='w-[168px] h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+              </div>
+              <div className='h-8 px-3 py-1 flex items-center'>
+                <div className='w-[128px] h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+              </div>
+            </div>
+            <div className='shrink-0 p-3 flex items-center justify-between'>
+              <div className='p-1.5'>
+                <RiEqualizer2Line className='w-4 h-4 text-text-tertiary' />
+              </div>
+              <div className='flex items-center gap-1.5'>
+                {!webappBrandRemoved && (
+                  <>
+                    <div className='text-text-tertiary system-2xs-medium-uppercase'>POWERED BY</div>
+                    {webappLogo
+                      ? <img src={`${webappLogo}?hash=${imgKey}`} alt='logo' className='block w-auto h-5' />
+                      : <LogoSite className='!h-5' />
+                    }
+                  </>
+                )}
+              </div>
+            </div>
+          </div>
+          <div className='grow flex flex-col justify-between w-[138px] p-2 pr-0'>
+            <div className='grow pt-16 pl-[22px] pb-4 flex flex-col justify-between bg-chatbot-bg rounded-l-2xl border-[0.5px] border-r-0 border-components-panel-border-subtle'>
+              <div className='w-[720px] px-4 py-3 bg-chat-bubble-bg rounded-2xl border border-divider-subtle'>
+                <div className='mb-1 text-text-primary body-md-regular'>Hello! How can I assist you today?</div>
+                <Button size='small'>
+                  <div className='w-[144px] h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+                </Button>
+              </div>
+              <div className='w-[578px] h-[52px] flex items-center pl-3.5 rounded-xl bg-components-panel-bg-blur backdrop-blur-sm border border-components-chat-input-border shadow-md text-text-placeholder body-lg-regular'>Talk to Dify</div>
+            </div>
+          </div>
+        </div>
+        {/* workflow card */}
+        <div className='grow basis-1/2 h-[320px] flex flex-col bg-background-default-burn rounded-2xl border-[0.5px] border-components-panel-border-subtle overflow-hidden'>
+          <div className='w-full p-4 pb-0 border-b-[0.5px] border-divider-subtle'>
+            <div className='mb-2 flex items-center gap-3'>
+              <div className={cn('w-8 h-8 inline-flex items-center justify-center rounded-lg border border-divider-regular', 'bg-components-icon-bg-indigo-solid')}>
+                <RiExchange2Fill className='w-4 h-4 text-components-avatar-shape-fill-stop-100' />
+              </div>
+              <div className='grow system-md-semibold text-text-secondary'>Workflow App</div>
+              <div className='p-1.5'>
+                <RiLayoutLeft2Line className='w-4 h-4 text-text-tertiary' />
+              </div>
+            </div>
+            <div className='flex items-center gap-4'>
+              <div className='shrink-0 h-10 flex items-center border-b-2 border-components-tab-active text-text-primary system-md-semibold-uppercase'>RUN ONCE</div>
+              <div className='grow h-10 flex items-center border-b-2 border-transparent text-text-tertiary system-md-semibold-uppercase'>RUN BATCH</div>
+            </div>
+          </div>
+          <div className='grow bg-components-panel-bg'>
+            <div className='p-4 pb-1'>
+              <div className='mb-1 py-2'>
+                <div className='w-20 h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+              </div>
+              <div className='w-full h-16 rounded-lg bg-components-input-bg-normal '></div>
+            </div>
+            <div className='px-4 py-3 flex items-center justify-between'>
+              <Button size='small'>
+                <div className='w-10 h-2 rounded-sm bg-text-quaternary opacity-20'></div>
+              </Button>
+              <Button variant='primary' size='small' disabled>
+                <RiPlayLargeLine className='mr-1 w-4 h-4' />
+                <span>Execute</span>
+              </Button>
+            </div>
+          </div>
+          <div className='shrink-0 h-12 p-4 pt-3 flex items-center gap-1.5 bg-components-panel-bg'>
+            {!webappBrandRemoved && (
+              <>
+                <div className='text-text-tertiary system-2xs-medium-uppercase'>POWERED BY</div>
+                {webappLogo
+                  ? <img src={`${webappLogo}?hash=${imgKey}`} alt='logo' className='block w-auto h-5' />
+                  : <LogoSite className='!h-5' />
+                }
+              </>
+            )}
+          </div>
+        </div>
+      </div>
     </div>
   )
 }

+ 1 - 1
web/app/components/datasets/create/website/base/field.tsx

@@ -31,7 +31,7 @@ const Field: FC<Props> = ({
   return (
     <div className={cn(className)}>
       <div className='flex py-[7px]'>
-        <div className={cn(labelClassName, 'flex items-center h-[18px] text-[13px] font-medium text-gray-900')}>{label} </div>
+        <div className={cn(labelClassName, 'flex items-center h-[18px] text-[13px] font-medium text-text-primary')}>{label} </div>
         {isRequired && <span className='ml-0.5 text-xs font-semibold text-[#D92D20]'>*</span>}
         {tooltip && (
           <Tooltip

+ 10 - 8
web/app/components/header/account-setting/api-based-extension-page/empty.tsx

@@ -1,23 +1,25 @@
 import { useTranslation } from 'react-i18next'
-import { Webhooks } from '@/app/components/base/icons/src/vender/line/development'
-import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education'
+import {
+  RiExternalLinkLine,
+  RiPuzzle2Line,
+} from '@remixicon/react'
 
 const Empty = () => {
   const { t } = useTranslation()
 
   return (
-    <div className='mb-2 p-6 rounded-2xl bg-gray-50'>
-      <div className='flex items-center justify-center mb-3 w-12 h-12 rounded-[10px] border border-[#EAECF5]'>
-        <Webhooks className='w-6 h-6 text-gray-500' />
+    <div className='mb-2 p-6 rounded-xl bg-background-section'>
+      <div className='flex items-center justify-center mb-3 w-10 h-10 rounded-[10px] bg-components-card-bg-alt backdrop-blur-sm border-[0.5px] border-components-card-border shadow-lg'>
+        <RiPuzzle2Line className='w-5 h-5 text-text-accent' />
       </div>
-      <div className='mb-2 text-sm text-gray-600'>{t('common.apiBasedExtension.title')}</div>
+      <div className='mb-1 text-text-secondary system-sm-medium'>{t('common.apiBasedExtension.title')}</div>
       <a
-        className='flex items-center mb-2 h-[18px] text-xs text-primary-600'
+        className='flex items-center system-xs-regular text-text-accent'
         href={t('common.apiBasedExtension.linkUrl') || '/'}
         target='_blank' rel='noopener noreferrer'
       >
-        <BookOpen01 className='mr-1 w-3 h-3' />
         {t('common.apiBasedExtension.link')}
+        <RiExternalLinkLine className='ml-1 w-3 h-3' />
       </a>
     </div>
   )

+ 6 - 4
web/app/components/header/account-setting/api-based-extension-page/index.tsx

@@ -5,6 +5,7 @@ import {
 } from '@remixicon/react'
 import Item from './item'
 import Empty from './empty'
+import Button from '@/app/components/base/button'
 import { useModalContext } from '@/context/modal-context'
 import { fetchApiBasedExtensionList } from '@/service/common'
 
@@ -41,13 +42,14 @@ const ApiBasedExtensionPage = () => {
           ))
         )
       }
-      <div
-        className='flex items-center justify-center px-3 h-8 text-[13px] font-medium text-gray-700 rounded-lg bg-gray-50 cursor-pointer'
+      <Button
+        variant='secondary'
+        className='w-full'
         onClick={handleOpenApiBasedExtensionModal}
       >
-        <RiAddLine className='mr-2 w-4 h-4' />
+        <RiAddLine className='mr-1 w-4 h-4' />
         {t('common.apiBasedExtension.add')}
-      </div>
+      </Button>
     </div>
   )
 }

+ 13 - 12
web/app/components/header/account-setting/api-based-extension-page/item.tsx

@@ -3,8 +3,9 @@ import { useState } from 'react'
 import { useTranslation } from 'react-i18next'
 import {
   RiDeleteBinLine,
+  RiEditLine,
 } from '@remixicon/react'
-import { Edit02 } from '@/app/components/base/icons/src/vender/line/general'
+import Button from '@/app/components/base/button'
 import type { ApiBasedExtension } from '@/models/common'
 import { useModalContext } from '@/context/modal-context'
 import { deleteApiBasedExtension } from '@/service/common'
@@ -36,25 +37,25 @@ const Item: FC<ItemProps> = ({
   }
 
   return (
-    <div className='group flex items-center mb-2 px-4 py-2 border-[0.5px] border-transparent rounded-xl bg-gray-50 hover:border-gray-200 hover:shadow-xs'>
+    <div className='group flex items-center mb-2 px-4 py-2 border-[0.5px] border-transparent rounded-xl bg-components-input-bg-normal hover:border-components-input-border-active hover:shadow-xs'>
       <div className='grow'>
-        <div className='mb-0.5 text-[13px] font-medium text-gray-700'>{data.name}</div>
-        <div className='text-xs text-gray-500'>{data.api_endpoint}</div>
+        <div className='mb-0.5 text-[13px] font-medium text-text-secondary'>{data.name}</div>
+        <div className='text-xs text-text-tertiary'>{data.api_endpoint}</div>
       </div>
       <div className='hidden group-hover:flex items-center'>
-        <div
-          className='flex items-center mr-1 px-3 h-7 bg-white text-xs font-medium text-gray-700 rounded-md border-[0.5px] border-gray-200 shadow-xs cursor-pointer'
+        <Button
+          className='mr-1'
           onClick={handleOpenApiBasedExtensionModal}
         >
-          <Edit02 className='mr-[5px] w-3.5 h-3.5' />
+          <RiEditLine className='mr-1 w-4 h-4' />
           {t('common.operation.edit')}
-        </div>
-        <div
-          className='flex items-center justify-center w-7 h-7 bg-white text-gray-700 rounded-md border-[0.5px] border-gray-200 shadow-xs cursor-pointer'
+        </Button>
+        <Button
           onClick={() => setShowDeleteConfirm(true)}
         >
-          <RiDeleteBinLine className='w-4 h-4' />
-        </div>
+          <RiDeleteBinLine className='mr-1 w-4 h-4' />
+          {t('common.operation.delete')}
+        </Button>
       </div>
       {
         showDeleteConfirm

+ 2 - 2
web/app/components/header/account-setting/api-based-extension-page/modal.tsx

@@ -101,9 +101,9 @@ const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({
           <a
             href={t('common.apiBasedExtension.linkUrl') || '/'}
             target='_blank' rel='noopener noreferrer'
-            className='group flex items-center text-xs text-text-tertiary font-normal hover:text-text-accent'
+            className='group flex items-center text-xs text-text-accent font-normal'
           >
-            <BookOpen01 className='mr-1 w-3 h-3 text-text-tertiary group-hover:text-text-accent' />
+            <BookOpen01 className='mr-1 w-3 h-3' />
             {t('common.apiBasedExtension.link')}
           </a>
         </div>

+ 15 - 27
web/app/components/header/account-setting/data-source-page/data-source-notion/operate/index.tsx

@@ -11,6 +11,7 @@ import {
 import { Menu, Transition } from '@headlessui/react'
 import { syncDataSourceNotion, updateDataSourceNotionAction } from '@/service/common'
 import Toast from '@/app/components/base/toast'
+import cn from '@/utils/classnames'
 
 type OperateProps = {
   payload: {
@@ -23,13 +24,6 @@ export default function Operate({
   payload,
   onAuthAgain,
 }: OperateProps) {
-  const itemClassName = `
-    flex px-3 py-2 hover:bg-gray-50 text-sm text-gray-700
-    cursor-pointer
-  `
-  const itemIconClassName = `
-  mr-2 mt-[2px] w-4 h-4 text-gray-500
-  `
   const { t } = useTranslation()
   const { mutate } = useSWRConfig()
 
@@ -54,8 +48,8 @@ export default function Operate({
       {
         ({ open }) => (
           <>
-            <Menu.Button className={`flex items-center justify-center w-8 h-8 rounded-lg hover:bg-gray-100 ${open && 'bg-gray-100'}`}>
-              <RiMoreFill className='w-4 h-4' />
+            <Menu.Button className={cn('flex items-center justify-center w-8 h-8 rounded-lg hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
+              <RiMoreFill className='w-4 h-4 text-text-secondary' />
             </Menu.Button>
             <Transition
               as={Fragment}
@@ -66,40 +60,34 @@ export default function Operate({
               leaveFrom="transform opacity-100 scale-100"
               leaveTo="transform opacity-0 scale-95"
             >
-              <Menu.Items
-                className="
-                  absolute right-0 top-9 w-60 max-w-80
-                  divide-y divide-gray-100 origin-top-right rounded-lg bg-white
-                  shadow-lg
-                "
-              >
+              <Menu.Items className="absolute right-0 top-9 w-60 max-w-80 origin-top-right rounded-xl bg-components-panel-bg-blur backdrop-blur-sm border-[0.5px] border-components-panel-border shadow-lg">
                 <div className="px-1 py-1">
                   <Menu.Item>
                     <div
-                      className={itemClassName}
+                      className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer'
                       onClick={onAuthAgain}
                     >
-                      <RiStickyNoteAddLine className={itemIconClassName} />
+                      <RiStickyNoteAddLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
                       <div>
-                        <div className='leading-5'>{t('common.dataSource.notion.changeAuthorizedPages')}</div>
-                        <div className='leading-5 text-xs text-gray-500'>
+                        <div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.changeAuthorizedPages')}</div>
+                        <div className='text-text-tertiary system-xs-regular'>
                           {payload.total} {t('common.dataSource.notion.pagesAuthorized')}
                         </div>
                       </div>
                     </div>
                   </Menu.Item>
                   <Menu.Item>
-                    <div className={itemClassName} onClick={handleSync}>
-                      <RiLoopLeftLine className={itemIconClassName} />
-                      <div className='leading-5'>{t('common.dataSource.notion.sync')}</div>
+                    <div className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer' onClick={handleSync}>
+                      <RiLoopLeftLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
+                      <div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.sync')}</div>
                     </div>
                   </Menu.Item>
                 </div>
                 <Menu.Item>
-                  <div className='p-1'>
-                    <div className={itemClassName} onClick={handleRemove}>
-                      <RiDeleteBinLine className={itemIconClassName} />
-                      <div className='leading-5'>{t('common.dataSource.notion.remove')}</div>
+                  <div className='p-1 border-t border-divider-subtle'>
+                    <div className='flex px-3 py-2 hover:bg-state-base-hover rounded-lg cursor-pointer' onClick={handleRemove}>
+                      <RiDeleteBinLine className='mr-2 mt-[2px] w-4 h-4 text-text-tertiary' />
+                      <div className='system-sm-semibold text-text-secondary'>{t('common.dataSource.notion.remove')}</div>
                     </div>
                   </div>
                 </Menu.Item>

+ 8 - 8
web/app/components/header/account-setting/data-source-page/data-source-website/config-firecrawl-modal.tsx

@@ -89,11 +89,11 @@ const ConfigFirecrawlModal: FC<Props> = ({
   return (
     <PortalToFollowElem open>
       <PortalToFollowElemContent className='w-full h-full z-[60]'>
-        <div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
-          <div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
+        <div className='fixed inset-0 flex items-center justify-center bg-background-overlay'>
+          <div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-components-panel-bg shadow-xl rounded-2xl overflow-y-auto'>
             <div className='px-8 pt-8'>
               <div className='flex justify-between items-center mb-4'>
-                <div className='text-xl font-semibold text-gray-900'>{t(`${I18N_PREFIX}.configFirecrawl`)}</div>
+                <div className='system-xl-semibold text-text-primary'>{t(`${I18N_PREFIX}.configFirecrawl`)}</div>
               </div>
 
               <div className='space-y-4'>
@@ -114,7 +114,7 @@ const ConfigFirecrawlModal: FC<Props> = ({
                 />
               </div>
               <div className='my-8 flex justify-between items-center h-8'>
-                <a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-[#155EEF]' target='_blank' href='https://www.firecrawl.dev/account'>
+                <a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-text-accent' target='_blank' href='https://www.firecrawl.dev/account'>
                   <span>{t(`${I18N_PREFIX}.getApiKeyLinkText`)}</span>
                   <LinkExternal02 className='w-3 h-3' />
                 </a>
@@ -138,12 +138,12 @@ const ConfigFirecrawlModal: FC<Props> = ({
 
               </div>
             </div>
-            <div className='border-t-[0.5px] border-t-black/5'>
-              <div className='flex justify-center items-center py-3 bg-gray-50 text-xs text-gray-500'>
-                <Lock01 className='mr-1 w-3 h-3 text-gray-500' />
+            <div className='border-t-[0.5px] border-t-divider-regular'>
+              <div className='flex justify-center items-center py-3 bg-background-section-burn text-xs text-text-tertiary'>
+                <Lock01 className='mr-1 w-3 h-3 text-text-tertiary' />
                 {t('common.modelProvider.encrypted.front')}
                 <a
-                  className='text-primary-600 mx-1'
+                  className='text-text-accent mx-1'
                   target='_blank' rel='noopener noreferrer'
                   href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
                 >

+ 8 - 8
web/app/components/header/account-setting/data-source-page/data-source-website/config-jina-reader-modal.tsx

@@ -75,11 +75,11 @@ const ConfigJinaReaderModal: FC<Props> = ({
   return (
     <PortalToFollowElem open>
       <PortalToFollowElemContent className='w-full h-full z-[60]'>
-        <div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
-          <div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
+        <div className='fixed inset-0 flex items-center justify-center bg-background-overlay'>
+          <div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-components-panel-bg shadow-xl rounded-2xl overflow-y-auto'>
             <div className='px-8 pt-8'>
               <div className='flex justify-between items-center mb-4'>
-                <div className='text-xl font-semibold text-gray-900'>{t(`${I18N_PREFIX}.configJinaReader`)}</div>
+                <div className='system-xl-semibold text-text-primary'>{t(`${I18N_PREFIX}.configJinaReader`)}</div>
               </div>
 
               <div className='space-y-4'>
@@ -93,7 +93,7 @@ const ConfigJinaReaderModal: FC<Props> = ({
                 />
               </div>
               <div className='my-8 flex justify-between items-center h-8'>
-                <a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-[#155EEF]' target='_blank' href='https://jina.ai/reader/'>
+                <a className='flex items-center space-x-1 leading-[18px] text-xs font-normal text-text-accent' target='_blank' href='https://jina.ai/reader/'>
                   <span>{t(`${I18N_PREFIX}.getApiKeyLinkText`)}</span>
                   <LinkExternal02 className='w-3 h-3' />
                 </a>
@@ -117,12 +117,12 @@ const ConfigJinaReaderModal: FC<Props> = ({
 
               </div>
             </div>
-            <div className='border-t-[0.5px] border-t-black/5'>
-              <div className='flex justify-center items-center py-3 bg-gray-50 text-xs text-gray-500'>
-                <Lock01 className='mr-1 w-3 h-3 text-gray-500' />
+            <div className='border-t-[0.5px] border-t-divider-regular'>
+              <div className='flex justify-center items-center py-3 bg-background-section-burn text-xs text-text-tertiary'>
+                <Lock01 className='mr-1 w-3 h-3 text-text-tertiary' />
                 {t('common.modelProvider.encrypted.front')}
                 <a
-                  className='text-primary-600 mx-1'
+                  className='text-text-accent mx-1'
                   target='_blank' rel='noopener noreferrer'
                   href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
                 >

+ 2 - 2
web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx

@@ -85,10 +85,10 @@ const DataSourceWebsite: FC<Props> = ({ provider }) => {
           logo: ({ className }: { className: string }) => (
             item.provider === DataSourceProvider.fireCrawl
               ? (
-                <div className={cn(className, 'flex items-center justify-center w-5 h-5 bg-white border border-gray-100 text-xs font-medium text-gray-500 rounded ml-3')}>🔥</div>
+                <div className={cn(className, 'flex items-center justify-center w-5 h-5 !bg-background-default border border-divider-subtle text-xs font-medium text-text-tertiary rounded ml-3')}>🔥</div>
               )
               : (
-                <div className={cn(className, 'flex items-center justify-center w-5 h-5 bg-white border border-gray-100 text-xs font-medium text-gray-500 rounded ml-3')}>
+                <div className={cn(className, 'flex items-center justify-center w-5 h-5 !bg-background-default border border-divider-subtle text-xs font-medium text-text-tertiary rounded ml-3')}>
                   <span className={s.jinaLogo} />
                 </div>
               )

+ 2 - 2
web/app/components/header/account-setting/data-source-page/panel/config-item.tsx

@@ -52,7 +52,7 @@ const ConfigItem: FC<Props> = ({
           ? <Indicator className='shrink-0 mr-[6px]' color='green' />
           : <Indicator className='shrink-0 mr-[6px]' color='yellow' />
       }
-      <div className={`shrink-0 mr-3 text-xs font-medium uppercase ${payload.isActive ? 'text-util-colors-green-green-600' : 'text-util-colors-warning-warning-600'}`}>
+      <div className={`shrink-0 mr-3 system-xs-semibold-uppercase ${payload.isActive ? 'text-util-colors-green-green-600' : 'text-util-colors-warning-warning-600'}`}>
         {
           payload.isActive
             ? t(isNotion ? 'common.dataSource.notion.connected' : 'common.dataSource.website.active')
@@ -70,7 +70,7 @@ const ConfigItem: FC<Props> = ({
 
       {
         isWebsite && !readOnly && (
-          <div className='p-2 text-text-tertiary cursor-pointer rounded-md hover:bg-black/5' onClick={onRemove} >
+          <div className='p-2 text-text-tertiary cursor-pointer rounded-md hover:bg-state-base-hover' onClick={onRemove} >
             <RiDeleteBinLine className='w-4 h-4' />
           </div>
         )

+ 9 - 11
web/app/components/header/account-setting/data-source-page/panel/index.tsx

@@ -8,12 +8,13 @@ import ConfigItem from './config-item'
 
 import s from './style.module.css'
 import { DataSourceType } from './types'
+import Button from '@/app/components/base/button'
 import { DataSourceProvider } from '@/models/common'
 import cn from '@/utils/classnames'
 
 type Props = {
   type: DataSourceType
-  provider: DataSourceProvider
+  provider?: DataSourceProvider
   isConfigured: boolean
   onConfigure: () => void
   readOnly: boolean
@@ -43,13 +44,13 @@ const Panel: FC<Props> = ({
   return (
     <div className='mb-2 bg-background-section-burn rounded-xl'>
       <div className='flex items-center px-3 py-[9px]'>
-        <div className={cn(s[`${type}-icon`], 'w-8 h-8 mr-3 border border-divider-subtle rounded-lg bg-background-default')} />
+        <div className={cn(s[`${type}-icon`], 'w-8 h-8 mr-3 border border-divider-subtle rounded-lg !bg-background-default')} />
         <div className='grow'>
           <div className='flex items-center h-5'>
             <div className='text-sm font-medium text-text-primary'>{t(`common.dataSource.${type}.title`)}</div>
             {isWebsite && (
-              <div className='ml-1 leading-[18px] px-1.5 rounded-md bg-white border border-gray-100 text-xs font-medium text-gray-700'>
-                <span className='text-gray-500'>{t('common.dataSource.website.with')}</span> { provider === DataSourceProvider.fireCrawl ? '🔥 Firecrawl' : 'Jina Reader'}
+              <div className='ml-1 leading-[18px] px-1.5 rounded-md bg-components-badge-white-to-dark text-xs font-medium text-text-secondary'>
+                <span className='text-text-tertiary'>{t('common.dataSource.website.with')}</span> { provider === DataSourceProvider.fireCrawl ? '🔥 Firecrawl' : 'Jina Reader'}
               </div>
             )}
           </div>
@@ -66,16 +67,13 @@ const Panel: FC<Props> = ({
             {
               isConfigured
                 ? (
-                  <div
-                    className={
-                      `flex items-center ml-3 px-3 h-7 bg-white border border-gray-200
-                  rounded-md text-xs font-medium text-gray-700
-                  ${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
-                    }
+                  <Button
+                    disabled={readOnly}
+                    className='ml-3'
                     onClick={onConfigure}
                   >
                     {t('common.dataSource.configure')}
-                  </div>
+                  </Button>
                 )
                 : (
                   <>

+ 6 - 6
web/app/components/header/account-setting/index.tsx

@@ -194,12 +194,12 @@ export default function AccountSetting({
           </div>
           <div ref={scrollRef} className='w-full pb-4 bg-components-panel-bg overflow-y-auto'>
             <div className={cn('sticky top-0 mx-8 pt-[27px] pb-2 mb-[18px] flex items-center bg-components-panel-bg z-20', scrolled && 'border-b border-divider-regular')}>
-              <div className='shrink-0 text-text-primary title-2xl-semi-bold'>{activeItem?.name}</div>
-              {
-                activeItem?.description && (
-                  <div className='shrink-0 ml-2 text-xs text-text-tertiary'>{activeItem?.description}</div>
-                )
-              }
+              <div className='shrink-0 text-text-primary title-2xl-semi-bold'>
+                {activeItem?.name}
+                {activeItem?.description && (
+                  <div className='mt-1 system-sm-regular text-text-tertiary'>{activeItem?.description}</div>
+                )}
+              </div>
               {activeItem?.key === 'provider' && (
                 <div className='grow flex justify-end'>
                   <Input

+ 21 - 17
web/app/components/header/account-setting/members-page/index.tsx

@@ -18,9 +18,11 @@ import type { InvitationResult } from '@/models/common'
 import LogoEmbeddedChatHeader from '@/app/components/base/logo/logo-embedded-chat-header'
 import { useProviderContext } from '@/context/provider-context'
 import { Plan } from '@/app/components/billing/type'
+import Button from '@/app/components/base/button'
 import UpgradeBtn from '@/app/components/billing/upgrade-btn'
 import { NUM_INFINITE } from '@/app/components/billing/config'
 import { LanguagesSupported } from '@/i18n/language'
+import cn from '@/utils/classnames'
 dayjs.extend(relativeTime)
 
 const MembersPage = () => {
@@ -35,7 +37,13 @@ const MembersPage = () => {
   const { locale } = useContext(I18n)
 
   const { userProfile, currentWorkspace, isCurrentWorkspaceOwner, isCurrentWorkspaceManager, systemFeatures } = useAppContext()
-  const { data, mutate } = useSWR({ url: '/workspaces/current/members' }, fetchMembers)
+  const { data, mutate } = useSWR(
+    {
+      url: '/workspaces/current/members',
+      params: {},
+    },
+    fetchMembers,
+  )
   const [inviteModalVisible, setInviteModalVisible] = useState(false)
   const [invitationResults, setInvitationResults] = useState<InvitationResult[]>([])
   const [invitedModalVisible, setInvitedModalVisible] = useState(false)
@@ -47,17 +55,17 @@ const MembersPage = () => {
   return (
     <>
       <div className='flex flex-col'>
-        <div className='flex items-center mb-4 p-3 gap-1 bg-gray-50 rounded-2xl'>
-          <LogoEmbeddedChatHeader className='!w-10 !h-10' />
-          <div className='grow mx-2'>
-            <div className='text-sm font-medium text-gray-900'>{currentWorkspace?.name}</div>
+        <div className='flex items-center mb-4 p-3 pr-5 gap-3 bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 rounded-xl border-t-[0.5px] border-l-[0.5px] border-divider-subtle'>
+          <LogoEmbeddedChatHeader className='!w-12 !h-12' />
+          <div className='grow'>
+            <div className='system-md-semibold text-text-secondary'>{currentWorkspace?.name}</div>
             {enableBilling && (
-              <div className='text-xs text-gray-500'>
+              <div className='mt-1 system-xs-medium text-text-tertiary'>
                 {isNotUnlimitedMemberPlan
                   ? (
                     <div className='flex space-x-1'>
                       <div>{t('billing.plansCommon.member')}{locale !== LanguagesSupported[1] && accounts.length > 1 && 's'}</div>
-                      <div className='text-gray-700'>{accounts.length}</div>
+                      <div className=''>{accounts.length}</div>
                       <div>/</div>
                       <div>{plan.total.teamMembers === NUM_INFINITE ? t('billing.plansCommon.unlimited') : plan.total.teamMembers}</div>
                     </div>
@@ -75,14 +83,10 @@ const MembersPage = () => {
           {isMemberFull && (
             <UpgradeBtn className='mr-2' loc='member-invite' />
           )}
-          <div className={
-            `shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200
-            text-[13px] font-medium text-primary-600 bg-white
-            shadow-xs rounded-lg ${(isCurrentWorkspaceManager && !isMemberFull) ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
-          } onClick={() => (isCurrentWorkspaceManager && !isMemberFull) && setInviteModalVisible(true)}>
-            <RiUserAddLine className='w-4 h-4 mr-2 ' />
+          <Button variant='primary' className={cn('shrink-0')} disabled={!isCurrentWorkspaceManager || isMemberFull} onClick={() => setInviteModalVisible(true)}>
+            <RiUserAddLine className='w-4 h-4 mr-1' />
             {t('common.members.invite')}
-          </div>
+          </Button>
         </div>
         <div className='overflow-visible lg:overflow-visible'>
           <div className='flex items-center py-[7px] border-b border-divider-regular min-w-[480px]'>
@@ -99,18 +103,18 @@ const MembersPage = () => {
                     <div className=''>
                       <div className='text-text-secondary system-sm-medium'>
                         {account.name}
-                        {account.status === 'pending' && <span className='ml-1 system-xs-regular text-[#DC6803]'>{t('common.members.pending')}</span>}
+                        {account.status === 'pending' && <span className='ml-1 system-xs-medium text-text-warning'>{t('common.members.pending')}</span>}
                         {userProfile.email === account.email && <span className='system-xs-regular text-text-tertiary'>{t('common.members.you')}</span>}
                       </div>
                       <div className='text-text-tertiary system-xs-regular'>{account.email}</div>
                     </div>
                   </div>
-                  <div className='shrink-0 flex items-center w-[104px] py-2 system-xs-regular text-text-secondary'>{dayjs(Number((account.last_active_at || account.created_at)) * 1000).locale(locale === 'zh-Hans' ? 'zh-cn' : 'en').fromNow()}</div>
+                  <div className='shrink-0 flex items-center w-[104px] py-2 system-sm-regular text-text-secondary'>{dayjs(Number((account.last_active_at || account.created_at)) * 1000).locale(locale === 'zh-Hans' ? 'zh-cn' : 'en').fromNow()}</div>
                   <div className='shrink-0 w-[96px] flex items-center'>
                     {
                       ((isCurrentWorkspaceOwner && account.role !== 'owner') || (isCurrentWorkspaceManager && !['owner', 'admin'].includes(account.role)))
                         ? <Operation member={account} operatorRole={currentWorkspace.role} onOperate={mutate} />
-                        : <div className='px-3 system-xs-regular text-text-secondary'>{RoleMap[account.role] || RoleMap.normal}</div>
+                        : <div className='px-3 system-sm-regular text-text-secondary'>{RoleMap[account.role] || RoleMap.normal}</div>
                     }
                   </div>
                 </div>

+ 8 - 9
web/app/components/header/account-setting/members-page/invite-modal/index.tsx

@@ -1,7 +1,7 @@
 'use client'
 import { useCallback, useState } from 'react'
 import { useContext } from 'use-context-selector'
-import { XMarkIcon } from '@heroicons/react/24/outline'
+import { RiCloseLine } from '@remixicon/react'
 import { useTranslation } from 'react-i18next'
 import { ReactMultiEmail } from 'react-multi-email'
 import { RiErrorWarningFill } from '@remixicon/react'
@@ -59,10 +59,10 @@ const InviteModal = ({
     <div className={cn(s.wrap)}>
       <Modal overflowVisible isShow onClose={() => { }} className={cn(s.modal)}>
         <div className='flex justify-between mb-2'>
-          <div className='text-xl font-semibold text-gray-900'>{t('common.members.inviteTeamMember')}</div>
-          <XMarkIcon className='w-4 h-4 cursor-pointer' onClick={onCancel} />
+          <div className='text-xl font-semibold text-text-primary'>{t('common.members.inviteTeamMember')}</div>
+          <RiCloseLine className='w-4 h-4 cursor-pointer text-text-tertiary' onClick={onCancel} />
         </div>
-        <div className='mb-3 text-[13px] text-gray-500'>{t('common.members.inviteTeamMemberTip')}</div>
+        <div className='mb-3 text-[13px] text-text-tertiary'>{t('common.members.inviteTeamMemberTip')}</div>
         {!isEmailSetup && (
           <div className='grow basis-0 overflow-y-auto pb-4'>
             <div className='relative mb-1 p-2 rounded-xl border border-components-panel-border shadow-xs'>
@@ -80,19 +80,18 @@ const InviteModal = ({
         )}
 
         <div>
-          <div className='mb-2 text-sm font-medium text-gray-900'>{t('common.members.email')}</div>
+          <div className='mb-2 text-sm font-medium text-text-primary'>{t('common.members.email')}</div>
           <div className='mb-8 h-36 flex items-stretch'>
             <ReactMultiEmail
-              className={cn('w-full pt-2 px-3 outline-none border-none',
-                'appearance-none text-sm text-gray-900 rounded-lg overflow-y-auto',
-                s.emailsInput,
+              className={cn('w-full pt-2 px-3 outline-none !bg-components-input-bg-normal border-components-input-border-active',
+                'appearance-none text-sm !text-text-primary rounded-lg overflow-y-auto',
               )}
               autoFocus
               emails={emails}
               inputClassName='bg-transparent'
               onChange={setEmails}
               getLabel={(email, index, removeEmail) =>
-                <div data-tag key={index} className={cn(s.emailBackground)}>
+                <div data-tag key={index} className={cn('bg-components-button-secondary-bg')}>
                   <div data-tag-item>{email}</div>
                   <span data-tag-handle onClick={() => removeEmail(index)}>
                     ×

+ 20 - 20
web/app/components/header/account-setting/members-page/invite-modal/role-selector.tsx

@@ -34,53 +34,53 @@ const RoleSelector = ({ value, onChange }: RoleSelectorProps) => {
           onClick={() => setOpen(v => !v)}
           className='block'
         >
-          <div className={cn('flex items-center px-3 py-2 rounded-lg bg-gray-100 cursor-pointer hover:bg-gray-200', open && 'bg-gray-200')}>
-            <div className='grow mr-2 text-gray-900 text-sm leading-5'>{t('common.members.invitedAsRole', { role: t(`common.members.${toHump(value)}`) })}</div>
-            <RiArrowDownSLine className='shrink-0 w-4 h-4 text-gray-700' />
+          <div className={cn('flex items-center px-3 py-2 rounded-lg bg-components-input-bg-normal cursor-pointer hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
+            <div className='grow mr-2 text-text-primary text-sm leading-5'>{t('common.members.invitedAsRole', { role: t(`common.members.${toHump(value)}`) })}</div>
+            <RiArrowDownSLine className='shrink-0 w-4 h-4 text-text-secondary' />
           </div>
         </PortalToFollowElemTrigger>
         <PortalToFollowElemContent className='z-[1002]'>
-          <div className='relative w-[336px] bg-white rounded-lg border-[0.5px] bg-gray-200 shadow-lg'>
+          <div className='relative w-[336px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg'>
             <div className='p-1'>
-              <div className='p-2 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
+              <div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
                 onChange('normal')
                 setOpen(false)
               }}>
                 <div className='relative pl-5'>
-                  <div className='text-gray-700 text-sm leading-5'>{t('common.members.normal')}</div>
-                  <div className='text-gray-500 text-xs leading-[18px]'>{t('common.members.normalTip')}</div>
-                  {value === 'normal' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-primary-600'/>}
+                  <div className='text-text-secondary text-sm leading-5'>{t('common.members.normal')}</div>
+                  <div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.normalTip')}</div>
+                  {value === 'normal' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
                 </div>
               </div>
-              <div className='p-2 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
+              <div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
                 onChange('editor')
                 setOpen(false)
               }}>
                 <div className='relative pl-5'>
-                  <div className='text-gray-700 text-sm leading-5'>{t('common.members.editor')}</div>
-                  <div className='text-gray-500 text-xs leading-[18px]'>{t('common.members.editorTip')}</div>
-                  {value === 'editor' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-primary-600'/>}
+                  <div className='text-text-secondary text-sm leading-5'>{t('common.members.editor')}</div>
+                  <div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.editorTip')}</div>
+                  {value === 'editor' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
                 </div>
               </div>
-              <div className='p-2 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
+              <div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
                 onChange('admin')
                 setOpen(false)
               }}>
                 <div className='relative pl-5'>
-                  <div className='text-gray-700 text-sm leading-5'>{t('common.members.admin')}</div>
-                  <div className='text-gray-500 text-xs leading-[18px]'>{t('common.members.adminTip')}</div>
-                  {value === 'admin' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-primary-600'/>}
+                  <div className='text-text-secondary text-sm leading-5'>{t('common.members.admin')}</div>
+                  <div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.adminTip')}</div>
+                  {value === 'admin' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
                 </div>
               </div>
               {datasetOperatorEnabled && (
-                <div className='p-2 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => {
+                <div className='p-2 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => {
                   onChange('dataset_operator')
                   setOpen(false)
                 }}>
                   <div className='relative pl-5'>
-                    <div className='text-gray-700 text-sm leading-5'>{t('common.members.datasetOperator')}</div>
-                    <div className='text-gray-500 text-xs leading-[18px]'>{t('common.members.datasetOperatorTip')}</div>
-                    {value === 'dataset_operator' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-primary-600'/>}
+                    <div className='text-text-secondary text-sm leading-5'>{t('common.members.datasetOperator')}</div>
+                    <div className='text-text-tertiary text-xs leading-[18px]'>{t('common.members.datasetOperatorTip')}</div>
+                    {value === 'dataset_operator' && <Check className='absolute top-0.5 left-0 w-4 h-4 text-text-accent'/>}
                   </div>
                 </div>
               )}

+ 1 - 1
web/app/components/header/account-setting/members-page/invited-modal/index.module.css

@@ -1,7 +1,7 @@
 .modal {
   padding: 32px !important;
   width: 480px !important;
-  background: linear-gradient(180deg, rgba(3, 152, 85, 0.05) 0%, rgba(3, 152, 85, 0) 22.44%), #F9FAFB !important;
+  /* background: linear-gradient(180deg, rgba(3, 152, 85, 0.05) 0%, rgba(3, 152, 85, 0) 22.44%), #F9FAFB !important; */
 }
 
 .copyIcon {

+ 6 - 6
web/app/components/header/account-setting/members-page/invited-modal/index.tsx

@@ -33,25 +33,25 @@ const InvitedModal = ({
         <div className='flex justify-between mb-3'>
           <div className='
             w-12 h-12 flex items-center justify-center rounded-xl
-            bg-white border-[0.5px] border-gray-100
+            bg-background-section-burn border-[0.5px] border-components-panel-border
             shadow-xl
           '>
             <CheckCircleIcon className='w-[22px] h-[22px] text-[#039855]' />
           </div>
           <XMarkIcon className='w-4 h-4 cursor-pointer' onClick={onCancel} />
         </div>
-        <div className='mb-1 text-xl font-semibold text-gray-900'>{t('common.members.invitationSent')}</div>
+        <div className='mb-1 text-xl font-semibold text-text-primary'>{t('common.members.invitationSent')}</div>
         {!IS_CE_EDITION && (
-          <div className='mb-10 text-sm text-gray-500'>{t('common.members.invitationSentTip')}</div>
+          <div className='mb-10 text-sm text-text-tertiary'>{t('common.members.invitationSentTip')}</div>
         )}
         {IS_CE_EDITION && (
           <>
-            <div className='mb-5 text-sm text-gray-500'>{t('common.members.invitationSentTip')}</div>
+            <div className='mb-5 text-sm text-text-tertiary'>{t('common.members.invitationSentTip')}</div>
             <div className='flex flex-col gap-2 mb-9'>
               {
                 !!successInvitationResults.length
                 && <>
-                  <div className='py-2 text-sm font-Medium text-gray-900'>{t('common.members.invitationLink')}</div>
+                  <div className='py-2 text-sm font-Medium text-text-primary'>{t('common.members.invitationLink')}</div>
                   {successInvitationResults.map(item =>
                     <InvitationLink key={item.email} value={item} />)}
                 </>
@@ -59,7 +59,7 @@ const InvitedModal = ({
               {
                 !!failedInvitationResults.length
                 && <>
-                  <div className='py-2 text-sm font-Medium text-gray-900'>{t('common.members.failedInvitationEmails')}</div>
+                  <div className='py-2 text-sm font-Medium text-text-primary'>{t('common.members.failedInvitationEmails')}</div>
                   <div className='flex flex-wrap justify-between gap-y-1'>
                     {
                       failedInvitationResults.map(item =>

+ 6 - 6
web/app/components/header/account-setting/members-page/invited-modal/invitation-link.tsx

@@ -35,21 +35,21 @@ const InvitationLink = ({
   }, [isCopied])
 
   return (
-    <div className='flex rounded-lg bg-gray-100 hover:bg-gray-100 border border-gray-200 py-2 items-center'>
-      <div className="flex items-center flex-grow h-5">
-        <div className='flex-grow bg-gray-100 text-[13px] relative h-full'>
+    <div className='flex rounded-lg bg-components-input-bg-normal hover:bg-state-base-hover border border-components-input-border-active py-2 items-center'>
+      <div className="flex items-center grow h-5">
+        <div className='grow text-[13px] relative h-full'>
           <Tooltip
             popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
           >
             <div className='absolute top-0 left-0 w-full pl-2 pr-2 truncate cursor-pointer r-0' onClick={copyHandle}>{value.url}</div>
           </Tooltip>
         </div>
-        <div className="flex-shrink-0 h-4 bg-gray-200 border" />
+        <div className="shrink-0 h-4 bg-divider-regular border" />
         <Tooltip
           popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
         >
-          <div className="px-0.5 flex-shrink-0">
-            <div className={`box-border w-[30px] h-[30px] flex items-center justify-center rounded-lg hover:bg-gray-100 cursor-pointer ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>
+          <div className="px-0.5 shrink-0">
+            <div className={`box-border w-[30px] h-[30px] flex items-center justify-center rounded-lg hover:bg-state-base-hover cursor-pointer ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>
             </div>
           </div>
         </Tooltip>

+ 0 - 3
web/app/components/header/account-setting/members-page/operation/index.module.css

@@ -1,3 +0,0 @@
-.popup {
-  box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
-}

+ 14 - 40
web/app/components/header/account-setting/members-page/operation/index.tsx

@@ -4,26 +4,12 @@ import { Fragment, useMemo } from 'react'
 import { useContext } from 'use-context-selector'
 import { Menu, Transition } from '@headlessui/react'
 import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/outline'
-import s from './index.module.css'
 import { useProviderContext } from '@/context/provider-context'
 import cn from '@/utils/classnames'
 import type { Member } from '@/models/common'
 import { deleteMemberOrCancelInvitation, updateMemberRole } from '@/service/common'
 import { ToastContext } from '@/app/components/base/toast'
 
-const itemClassName = `
-  flex px-3 py-2 cursor-pointer hover:bg-gray-50 rounded-lg
-`
-const itemIconClassName = `
-  w-4 h-4 mt-[2px] mr-1 text-primary-600
-`
-const itemTitleClassName = `
-  leading-[20px] text-sm text-gray-700 whitespace-nowrap
-`
-const itemDescClassName = `
-  leading-[18px] text-xs text-gray-500 whitespace-nowrap
-`
-
 type IOperationProps = {
   member: Member
   operatorRole: string
@@ -90,15 +76,9 @@ const Operation = ({
       {
         ({ open }) => (
           <>
-            <Menu.Button className={cn(
-              `
-                  group flex items-center justify-between w-full h-full
-                  hover:bg-gray-100 cursor-pointer ${open && 'bg-gray-100'}
-                  text-[13px] text-gray-700 px-3
-                `,
-            )}>
+            <Menu.Button className={cn('group px-3 flex items-center justify-between w-full h-full system-sm-regular text-text-secondary cursor-pointer hover:bg-state-base-hover', open && 'bg-state-base-hover')}>
               {RoleMap[member.role] || RoleMap.normal}
-              <ChevronDownIcon className={`w-4 h-4 group-hover:block ${open ? 'block' : 'hidden'}`} />
+              <ChevronDownIcon className={cn('w-4 h-4 group-hover:block', open ? 'block' : 'hidden')} />
             </Menu.Button>
             <Transition
               as={Fragment}
@@ -110,27 +90,21 @@ const Operation = ({
               leaveTo="transform opacity-0 scale-95"
             >
               <Menu.Items
-                className={cn(
-                  `
-                      absolute right-0 top-[52px] z-10 bg-white border-[0.5px] border-gray-200
-                      divide-y divide-gray-100 origin-top-right rounded-lg
-                    `,
-                  s.popup,
-                )}
+                className={cn('absolute origin-top-right right-0 top-[52px] z-10 bg-components-panel-bg-blur backdrop-blur-sm rounded-xl border-[0.5px] border-components-panel-border shadow-lg')}
               >
-                <div className="px-1 py-1">
+                <div className="p-1">
                   {
                     roleList.map(role => (
                       <Menu.Item key={role}>
-                        <div className={itemClassName} onClick={() => handleUpdateMemberRole(role)}>
+                        <div className='flex px-3 py-2 cursor-pointer hover:bg-state-base-hover rounded-lg' onClick={() => handleUpdateMemberRole(role)}>
                           {
                             role === member.role
-                              ? <CheckIcon className={itemIconClassName} />
-                              : <div className={itemIconClassName} />
+                              ? <CheckIcon className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
+                              : <div className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
                           }
                           <div>
-                            <div className={itemTitleClassName}>{t(`common.members.${toHump(role)}`)}</div>
-                            <div className={itemDescClassName}>{t(`common.members.${toHump(role)}Tip`)}</div>
+                            <div className='system-sm-semibold text-text-secondary whitespace-nowrap'>{t(`common.members.${toHump(role)}`)}</div>
+                            <div className='system-xs-regular text-text-tertiary whitespace-nowrap'>{t(`common.members.${toHump(role)}Tip`)}</div>
                           </div>
                         </div>
                       </Menu.Item>
@@ -138,12 +112,12 @@ const Operation = ({
                   }
                 </div>
                 <Menu.Item>
-                  <div className='px-1 py-1'>
-                    <div className={itemClassName} onClick={handleDeleteMemberOrCancelInvitation}>
-                      <div className={itemIconClassName} />
+                  <div className='p-1 border-t border-divider-subtle'>
+                    <div className='flex px-3 py-2 cursor-pointer hover:bg-state-base-hover rounded-lg' onClick={handleDeleteMemberOrCancelInvitation}>
+                      <div className='w-4 h-4 mt-[2px] mr-1 text-text-accent' />
                       <div>
-                        <div className={itemTitleClassName}>{t('common.members.removeFromTeam')}</div>
-                        <div className={itemDescClassName}>{t('common.members.removeFromTeamTip')}</div>
+                        <div className='system-sm-semibold text-text-secondary whitespace-nowrap'>{t('common.members.removeFromTeam')}</div>
+                        <div className='system-xs-regular text-text-tertiary whitespace-nowrap'>{t('common.members.removeFromTeamTip')}</div>
                       </div>
                     </div>
                   </div>

+ 7 - 1
web/i18n/en-US/billing.ts

@@ -10,7 +10,7 @@ const translation = {
   },
   teamMembers: 'Team Members',
   upgradeBtn: {
-    plain: 'Upgrade Plan',
+    plain: 'View Plan',
     encourage: 'Upgrade Now',
     encourageShort: 'Upgrade',
   },
@@ -101,18 +101,22 @@ const translation = {
   plans: {
     sandbox: {
       name: 'Sandbox',
+      for: 'Free Trial of Core Capabilities',      
       description: 'Free Trial of Core Capabilities',
     },
     professional: {
       name: 'Professional',
+      for: 'For Independent Developers/Small Teams',
       description: 'For Independent Developers/Small Teams',
     },
     team: {
       name: 'Team',
+      for: 'For Medium-sized Teams',
       description: 'For Medium-sized Teams',
     },
     community: {
       name: 'Community',
+      for: 'For Individual Users, Small Teams, or Non-commercial Projects',
       description: 'For Individual Users, Small Teams, or Non-commercial Projects',
       price: 'Free',
       btnText: 'Get Started with Community',
@@ -125,6 +129,7 @@ const translation = {
     },
     premium: {
       name: 'Premium',
+      for: 'For Mid-sized Organizations and Teams',
       description: 'For Mid-sized Organizations and Teams',
       price: 'Scalable',
       priceTip: 'Based on Cloud Marketplace',
@@ -140,6 +145,7 @@ const translation = {
     },
     enterprise: {
       name: 'Enterprise',
+      for: 'For large-sized Teams',
       description: 'For Enterprise Require Organization-wide Security, Compliance, Scalability, Control and More Advanced Features',
       price: 'Custom',
       priceTip: 'Annual Billing Only',

+ 2 - 0
web/i18n/en-US/custom.ts

@@ -1,6 +1,8 @@
 const translation = {
   custom: 'Customization',
   upgradeTip: {
+    title: 'Upgrade your plan',
+    des: 'Upgrade your plan to customize your brand',
     prefix: 'Upgrade your plan to',
     suffix: 'customize your brand.',
   },

+ 7 - 1
web/i18n/zh-Hans/billing.ts

@@ -9,7 +9,7 @@ const translation = {
     vectorSpaceTooltip: '采用高质量索引模式的文档会消耗知识数据存储资源。当知识数据存储达到限制时,将不会上传新文档。',
   },
   upgradeBtn: {
-    plain: '升级套餐',
+    plain: '查看套餐',
     encourage: '立即升级',
     encourageShort: '升级',
   },
@@ -100,18 +100,22 @@ const translation = {
   plans: {
     sandbox: {
       name: 'Sandbox',
+      for: '核心能力的免费试用',      
       description: '核心功能免费试用',
     },
     professional: {
       name: 'Professional',
+      for: '适合独立开发者或小团队',
       description: '对于独立开发者/小团队',
     },
     team: {
       name: 'Team',
+      for: '适合中等规模的团队',
       description: '对于中型团队',
     },
     community: {
       name: 'Community',
+      for: '适用于个人用户、小型团队或非商业项目',
       description: '适用于个人用户、小型团队或非商业项目',
       price: '免费',
       btnText: '开始使用',
@@ -124,6 +128,7 @@ const translation = {
     },
     premium: {
       name: 'Premium',
+      for: '对于中型组织和团队',
       description: '对于中型组织和团队',
       price: '可扩展',
       priceTip: '基于云市场',
@@ -139,6 +144,7 @@ const translation = {
     },
     enterprise: {
       name: 'Enterprise',
+      for: '适合大人员规模的团队',
       description: '对于需要组织范围内的安全性、合规性、可扩展性、控制和更高级功能的企业',
       price: '定制',
       priceTip: '仅按年计费',

+ 2 - 0
web/i18n/zh-Hans/custom.ts

@@ -1,6 +1,8 @@
 const translation = {
   custom: '定制',
   upgradeTip: {
+    title: '升级您的计划',
+    des: '升级您的计划来定制您的品牌。',
     prefix: '升级您的计划以',
     suffix: '定制您的品牌。',
   },