Commit 63cd9fdf authored by StyleZhang's avatar StyleZhang

feat: add model-card

parent 2197f976
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="plus">
<path id="Icon" d="M8.00004 3.83337V13.1667M3.33337 8.50004H12.6667" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "17",
"viewBox": "0 0 16 17",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "plus"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M8.00004 3.83337V13.1667M3.33337 8.50004H12.6667",
"stroke": "currentColor",
"stroke-width": "1.25",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "Plus"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Plus.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} />)
export default Icon
...@@ -4,6 +4,7 @@ export { default as Hash02 } from './Hash02' ...@@ -4,6 +4,7 @@ export { default as Hash02 } from './Hash02'
export { default as LinkExternal02 } from './LinkExternal02' export { default as LinkExternal02 } from './LinkExternal02'
export { default as Loading02 } from './Loading02' export { default as Loading02 } from './Loading02'
export { default as LogOut01 } from './LogOut01' export { default as LogOut01 } from './LogOut01'
export { default as Plus } from './Plus'
export { default as SearchLg } from './SearchLg' export { default as SearchLg } from './SearchLg'
export { default as Trash03 } from './Trash03' export { default as Trash03 } from './Trash03'
export { default as XClose } from './XClose' export { default as XClose } from './XClose'
......
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import ModelSelector from './model-selector' import ModelSelector from './model-selector'
import ModelCard from './model-card'
const ModelPage = () => { const ModelPage = () => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<div className='pt-1'> <div className='pt-1'>
<div className='grid grid-cols-2 gap-4'> <div className='grid grid-cols-2 gap-4 mb-4'>
<div className='w-full'> <div className='w-full'>
<div className='py-2 text-sm font-medium text-gray-900'> <div className='py-2 text-sm font-medium text-gray-900'>
{t('common.modelProvider.systemReasoningModel.key')} {t('common.modelProvider.systemReasoningModel.key')}
...@@ -16,6 +17,12 @@ const ModelPage = () => { ...@@ -16,6 +17,12 @@ const ModelPage = () => {
</div> </div>
</div> </div>
</div> </div>
<div className='mb-4 h-[0.5px] bg-gray-100' />
<div className='mb-3 text-sm font-medium text-gray-800'>{t('common.modelProvider.models')}</div>
<div className='grid grid-cols-2 gap-4 mb-6'>
<ModelCard />
<ModelCard type='anthropic' />
</div>
</div> </div>
) )
} }
......
.card {
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
}
\ No newline at end of file
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import s from './index.module.css'
import Button from '@/app/components/base/button'
import { Plus } from '@/app/components/base/icons/src/vender/line/general'
type ModelCardProps = {
type?: 'openai' | 'anthropic'
}
const ModelCard: FC<ModelCardProps> = ({
type = 'openai',
}) => {
const { t } = useTranslation()
return (
<div className={cn(
s.card,
'rounded-xl border-[0.5px] border-gray-200',
)}>
<div className='flex px-4 pt-4 pb-3 bg-gray-200 rounded-t-lg'>
<div className='mr-3'>
<div className='mb-1'></div>
<div className='text-xs text-black opacity-60'>{t(`common.modelProvider.card.${type}.desc`)}</div>
</div>
<div className='w-6 h-6' />
</div>
<div className='flex justify-between px-4 py-3 border-b-[0.5px] border-b-[rgba(0, 0, 0, 0.5)]'>
<div>
<div className='flex items-center mb-1 h-5'>
<div className='mr-1 text-xs font-medium text-gray-500'>{t('common.modelProvider.card.quota')}</div>
<div className='px-1.5 bg-primary-50 rounded-md text-xs font-semibold text-primary-600'>{t('common.modelProvider.card.onTrial')}</div>
</div>
<div className='flex items-center'>
<div className='mr-1 text-sm font-medium text-gray-700'>200</div>
<div className='mr-1 text-sm text-gray-700'>{t('common.modelProvider.card.callTimes')}</div>
</div>
</div>
<Button className='mt-1.5 !px-3 !h-8 !text-[13px] font-medium rounded-lg' type='primary'>{t('common.modelProvider.card.buyQuota')}</Button>
</div>
<div className='flex items-center px-4 h-12'>
<Plus className='mr-1.5 w-4 h-4 text-gray-500' />
<div className='text-xs font-medium text-gray-500'>{t('common.modelProvider.addApiKey')}</div>
</div>
</div>
)
}
export default ModelCard
...@@ -46,7 +46,7 @@ const ModelSelector = () => { ...@@ -46,7 +46,7 @@ const ModelSelector = () => {
> >
<Popover.Panel className={cn( <Popover.Panel className={cn(
s.options, s.options,
'absolute top-10 p-1 w-full max-h-[366px] border-[0.5px] border-gray-200 rounded-lg overflow-auto', 'absolute top-10 p-1 w-full max-h-[366px] bg-white border-[0.5px] border-gray-200 rounded-lg overflow-auto z-10',
)}> )}>
<div className='px-2 pt-2 pb-1'> <div className='px-2 pt-2 pb-1'>
<div className='flex items-center px-2 h-8 bg-gray-100 rounded-lg'> <div className='flex items-center px-2 h-8 bg-gray-100 rounded-lg'>
......
...@@ -215,6 +215,22 @@ const translation = { ...@@ -215,6 +215,22 @@ const translation = {
noModelFound: 'No model found for {{model}}', noModelFound: 'No model found for {{model}}',
models: 'Models', models: 'Models',
showMoreModelProvider: 'Show more model provider', showMoreModelProvider: 'Show more model provider',
card: {
openai: {
desc: 'Models provided by OpenAI, such as GPT-3.5-Turbo and GPT-4.',
},
anthropic: {
desc: 'Anthropic’s powerful models, such as Claude 2 and Claude Instant.',
},
quota: 'QUOTA',
onTrial: 'On Trial',
paid: 'Paid',
callTimes: 'Call times',
tokens: 'Tokens',
buyQuota: 'Buy Quota',
},
addApiKey: 'Add your API key',
invalidApiKey: 'Invalid API key',
}, },
dataSource: { dataSource: {
add: 'Add a data source', add: 'Add a data source',
......
...@@ -215,6 +215,22 @@ const translation = { ...@@ -215,6 +215,22 @@ const translation = {
noModelFound: 'No model found for {{model}}', noModelFound: 'No model found for {{model}}',
models: 'Models', models: 'Models',
showMoreModelProvider: 'Show more model provider', showMoreModelProvider: 'Show more model provider',
card: {
openai: {
desc: 'Models provided by OpenAI, such as GPT-3.5-Turbo and GPT-4.',
},
anthropic: {
desc: 'Anthropic’s powerful models, such as Claude 2 and Claude Instant.',
},
quota: 'QUOTA',
onTrial: 'On Trial',
paid: 'Paid',
callTimes: 'Call times',
tokens: 'Tokens',
buyQuota: 'Buy Quota',
},
addApiKey: 'Add your API key',
invalidApiKey: 'Invalid API key',
}, },
dataSource: { dataSource: {
add: '添加数据源', add: '添加数据源',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment