Skip to content

Commit

Permalink
feat: show more usage info in billing page (langgenius#4808)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamjoel authored and Sakura4036 committed Jun 4, 2024
1 parent 38f7a84 commit 42b3527
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 23 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "file-upload"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M20 10.5V6.8C20 5.11984 20 4.27976 19.673 3.63803C19.3854 3.07354 18.9265 2.6146 18.362 2.32698C17.7202 2 16.8802 2 15.2 2H8.8C7.11984 2 6.27976 2 5.63803 2.32698C5.07354 2.6146 4.6146 3.07354 4.32698 3.63803C4 4.27976 4 5.11984 4 6.8V17.2C4 18.8802 4 19.7202 4.32698 20.362C4.6146 20.9265 5.07354 21.3854 5.63803 21.673C6.27976 22 7.11984 22 8.8 22H12M14 11H8M10 15H8M16 7H8",
"stroke": "currentColor",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon_2",
"d": "M15 18L18 15M18 15L21 18M18 15L18 21",
"stroke": "currentColor",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "FileUpload"
}
16 changes: 16 additions & 0 deletions web/app/components/base/icons/src/vender/line/files/FileUpload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// GENERATE BY script
// DON NOT EDIT IT MANUALLY

import * as React from 'react'
import data from './FileUpload.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'

const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)

Icon.displayName = 'FileUpload'

export default Icon
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export { default as FileDownload02 } from './FileDownload02'
export { default as FilePlus01 } from './FilePlus01'
export { default as FilePlus02 } from './FilePlus02'
export { default as FileText } from './FileText'
export { default as FileUpload } from './FileUpload'
export { default as Folder } from './Folder'
2 changes: 2 additions & 0 deletions web/app/components/billing/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ export const defaultPlan = {
buildApps: 1,
teamMembers: 1,
annotatedResponse: 1,
documentsUploadQuota: 1,
},
total: {
vectorSpace: 10,
buildApps: 10,
teamMembers: 1,
annotatedResponse: 10,
documentsUploadQuota: 50,
},
}
33 changes: 32 additions & 1 deletion web/app/components/billing/plan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { Plan } 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 { useProviderContext } from '@/context/provider-context'
import UsageInfo from '@/app/components/billing/usage-info'

const typeStyle = {
[Plan.sandbox]: {
Expand Down Expand Up @@ -41,6 +45,11 @@ const PlanComp: FC<Props> = ({
type,
} = plan

const {
usage,
total,
} = plan

const isInHeader = loc === 'header'

return (
Expand Down Expand Up @@ -76,8 +85,30 @@ const PlanComp: FC<Props> = ({

{/* Plan detail */}
<div className='rounded-xl bg-white px-6 py-3'>
<VectorSpaceInfo className='py-3' />

<UsageInfo
className='py-3'
Icon={User01}
name={t('billing.plansCommon.teamMembers')}
usage={usage.teamMembers}
total={total.teamMembers}
/>
<AppsInfo className='py-3' />
<VectorSpaceInfo className='py-3' />
<UsageInfo
className='py-3'
Icon={MessageFastPlus}
name={t('billing.plansCommon.annotationQuota')}
usage={usage.annotatedResponse}
total={total.annotatedResponse}
/>
<UsageInfo
className='py-3'
Icon={FileUpload}
name={t('billing.plansCommon.documentsUploadQuota')}
usage={usage.documentsUploadQuota}
total={total.documentsUploadQuota}
/>
{isInHeader && type === Plan.sandbox && (
<UpgradeBtn
className='flex-shrink-0 my-3'
Expand Down
6 changes: 5 additions & 1 deletion web/app/components/billing/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type PlanInfo = {
annotatedResponse: number
}

export type UsagePlanInfo = Pick<PlanInfo, 'vectorSpace' | 'buildApps' | 'teamMembers' | 'annotatedResponse'>
export type UsagePlanInfo = Pick<PlanInfo, 'vectorSpace' | 'buildApps' | 'teamMembers' | 'annotatedResponse' | 'documentsUploadQuota'>

export enum DocumentProcessingPriority {
standard = 'standard',
Expand Down Expand Up @@ -59,6 +59,10 @@ export type CurrentPlanInfoBackend = {
size: number
limit: number // total. 0 means unlimited
}
documents_upload_quota: {
size: number
limit: number // total. 0 means unlimited
}
docs_processing: DocumentProcessingPriority
can_replace_logo: boolean
}
Expand Down
2 changes: 2 additions & 0 deletions web/app/components/billing/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ export const parseCurrentPlan = (data: CurrentPlanInfoBackend) => {
buildApps: data.apps?.size || 0,
teamMembers: data.members.size,
annotatedResponse: data.annotation_quota_limit.size,
documentsUploadQuota: data.documents_upload_quota.size,
},
total: {
vectorSpace: parseLimit(data.vector_space.limit),
buildApps: parseLimit(data.apps?.limit) || 0,
teamMembers: parseLimit(data.members.limit),
annotatedResponse: parseLimit(data.annotation_quota_limit.limit),
documentsUploadQuota: parseLimit(data.documents_upload_quota.limit),
},
}
}
33 changes: 14 additions & 19 deletions web/app/components/header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { useCallback, useEffect } from 'react'
import Link from 'next/link'
import { useBoolean, useClickAway } from 'ahooks'
import { useBoolean } from 'ahooks'
import { useSelectedLayoutSegment } from 'next/navigation'
import { Bars3Icon } from '@heroicons/react/20/solid'
import HeaderBillingBtn from '../billing/header-billing-btn'
Expand All @@ -15,9 +15,9 @@ import GithubStar from './github-star'
import { WorkspaceProvider } from '@/context/workspace-context'
import { useAppContext } from '@/context/app-context'
import LogoSite from '@/app/components/base/logo/logo-site'
import PlanComp from '@/app/components/billing/plan'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useProviderContext } from '@/context/provider-context'
import { useModalContext } from '@/context/modal-context'

const navClassName = `
flex items-center relative mr-0 sm:mr-3 px-3 h-8 rounded-xl
Expand All @@ -26,18 +26,21 @@ const navClassName = `
`

const Header = () => {
const { isCurrentWorkspaceManager, langeniusVersionInfo } = useAppContext()
const [showUpgradePanel, setShowUpgradePanel] = useState(false)
const upgradeBtnRef = useRef<HTMLElement>(null)
useClickAway(() => {
setShowUpgradePanel(false)
}, upgradeBtnRef)
const { isCurrentWorkspaceManager } = useAppContext()

const selectedSegment = useSelectedLayoutSegment()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [isShowNavMenu, { toggle, setFalse: hideNavMenu }] = useBoolean(false)
const { enableBilling } = useProviderContext()
const { enableBilling, plan } = useProviderContext()
const { setShowPricingModal, setShowAccountSettingModal } = useModalContext()
const isFreePlan = plan.type === 'sandbox'
const handlePlanClick = useCallback(() => {
if (isFreePlan)
setShowPricingModal()
else
setShowAccountSettingModal({ payload: 'billing' })
}, [isFreePlan, setShowAccountSettingModal, setShowPricingModal])

useEffect(() => {
hideNavMenu()
Expand Down Expand Up @@ -79,15 +82,7 @@ const Header = () => {
<EnvNav />
{enableBilling && (
<div className='mr-3 select-none'>
<HeaderBillingBtn onClick={() => setShowUpgradePanel(true)} />
{showUpgradePanel && (
<div
ref={upgradeBtnRef as any}
className='fixed z-10 top-12 right-1 w-[360px]'
>
<PlanComp loc='header' />
</div>
)}
<HeaderBillingBtn onClick={handlePlanClick} />
</div>
)}
<WorkspaceProvider>
Expand Down
4 changes: 2 additions & 2 deletions web/context/modal-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const ModalContext = createContext<{
setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>>
setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>>
setShowExternalDataToolModal: Dispatch<SetStateAction<ModalState<ExternalDataTool> | null>>
setShowPricingModal: Dispatch<SetStateAction<any>>
setShowPricingModal: () => void
setShowAnnotationFullModal: () => void
setShowModelModal: Dispatch<SetStateAction<ModalState<ModelModalType> | null>>
}>({
Expand All @@ -50,7 +50,7 @@ const ModalContext = createContext<{
setShowExternalDataToolModal: () => { },
setShowPricingModal: () => { },
setShowAnnotationFullModal: () => { },
setShowModelModal: () => {},
setShowModelModal: () => { },
})

export const useModalContext = () => useContext(ModalContext)
Expand Down
1 change: 1 addition & 0 deletions web/i18n/en-US/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const translation = {
talkToSales: 'Talk to Sales',
modelProviders: 'Model Providers',
teamMembers: 'Team Members',
annotationQuota: 'Annotation Quota',
buildApps: 'Build Apps',
vectorSpace: 'Vector Space',
vectorSpaceBillingTooltip: 'Each 1MB can store about 1.2million characters of vectorized data(estimated using OpenAI Embeddings, varies across models).',
Expand Down
1 change: 1 addition & 0 deletions web/i18n/zh-Hans/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const translation = {
modelProviders: '支持的模型提供商',
teamMembers: '团队成员',
buildApps: '构建应用程序数',
annotationQuota: '标注回复数',
vectorSpace: '向量空间',
vectorSpaceTooltip: '向量空间是 LLMs 理解您的数据所需的长期记忆系统。',
vectorSpaceBillingTooltip: '向量存储是将知识库向量化处理后为让 LLMs 理解数据而使用的长期记忆存储,1MB 大约能满足1.2 million character 的向量化后数据存储(以 OpenAI Embedding 模型估算,不同模型计算方式有差异)。在向量化过程中,实际的压缩或尺寸减小取决于内容的复杂性和冗余性。',
Expand Down

0 comments on commit 42b3527

Please sign in to comment.