feat: option card component

chore: upd
This commit is contained in:
AkaraChen 2024-11-20 10:13:29 +08:00
parent 3087913b74
commit ca4d0fb4cc
15 changed files with 290 additions and 230 deletions

View File

@ -26,12 +26,14 @@ const RadioCard: FC<Props> = ({
onChosen = () => { },
chosenConfig,
chosenConfigWrapClassName,
className,
}) => {
return (
<div
className={cn(
'border border-components-option-card-option-border bg-components-option-card-option-bg rounded-xl hover:shadow-xs cursor-pointer',
isChosen && 'bg-components-option-card-option-selected-bg border-components-panel-border shadow-xs',
className,
)}
>
<div className='flex py-3 pl-3 pr-4' onClick={onChosen}>

View File

@ -3,10 +3,10 @@ import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import RetrievalParamConfig from '../retrieval-param-config'
import { OptionCard } from '../../create/step-two/option-card'
import { RETRIEVE_METHOD } from '@/types/app'
import RadioCard from '@/app/components/base/radio-card'
import { HighPriority } from '@/app/components/base/icons/src/vender/solid/arrows'
import type { RetrievalConfig } from '@/types/app'
import { HighPriority } from '@/app/components/base/icons/src/vender/solid/arrows'
type Props = {
value: RetrievalConfig
@ -21,19 +21,15 @@ const EconomicalRetrievalMethodConfig: FC<Props> = ({
return (
<div className='space-y-2'>
<RadioCard
icon={<HighPriority className='w-4 h-4 text-[#7839EE]' />}
<OptionCard icon={<HighPriority className='w-4 h-4 text-[#7839EE]' />}
title={t('dataset.retrieval.invertedIndex.title')}
description={t('dataset.retrieval.invertedIndex.description')}
noRadio
chosenConfig={
<RetrievalParamConfig
type={RETRIEVE_METHOD.invertedIndex}
value={value}
onChange={onChange}
/>
}
/>
description={t('dataset.retrieval.invertedIndex.description')} isActive>
<RetrievalParamConfig
type={RETRIEVE_METHOD.invertedIndex}
value={value}
onChange={onChange}
/>
</OptionCard>
</div>
)
}

View File

@ -3,11 +3,9 @@ import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import RetrievalParamConfig from '../retrieval-param-config'
import { OptionCard } from '../../create/step-two/option-card'
import type { RetrievalConfig } from '@/types/app'
import { RETRIEVE_METHOD } from '@/types/app'
import RadioCard from '@/app/components/base/radio-card'
import { PatternRecognition, Semantic } from '@/app/components/base/icons/src/vender/solid/development'
import { FileSearch02 } from '@/app/components/base/icons/src/vender/solid/files'
import { useProviderContext } from '@/context/provider-context'
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
@ -16,6 +14,8 @@ import {
RerankingModeEnum,
WeightedScoreEnum,
} from '@/models/datasets'
import { PatternRecognition, Semantic } from '@/app/components/base/icons/src/vender/solid/development'
import { FileSearch02 } from '@/app/components/base/icons/src/vender/solid/files'
type Props = {
value: RetrievalConfig
@ -56,67 +56,66 @@ const RetrievalMethodConfig: FC<Props> = ({
return (
<div className='space-y-2'>
{supportRetrievalMethods.includes(RETRIEVE_METHOD.semantic) && (
<RadioCard
icon={<Semantic className='w-4 h-4 text-[#7839EE]' />}
<OptionCard icon={<Semantic className='w-4 h-4 text-[#7839EE]' />}
title={t('dataset.retrieval.semantic_search.title')}
description={t('dataset.retrieval.semantic_search.description')}
isChosen={value.search_method === RETRIEVE_METHOD.semantic}
onChosen={() => onChange({
isActive={
value.search_method === RETRIEVE_METHOD.semantic
}
onClick={() => onChange({
...value,
search_method: RETRIEVE_METHOD.semantic,
})}
chosenConfig={
<RetrievalParamConfig
type={RETRIEVE_METHOD.semantic}
value={value}
onChange={onChange}
/>
}
/>
>
<RetrievalParamConfig
type={RETRIEVE_METHOD.semantic}
value={value}
onChange={onChange}
/>
</OptionCard>
)}
{supportRetrievalMethods.includes(RETRIEVE_METHOD.semantic) && (
<RadioCard
icon={<FileSearch02 className='w-4 h-4 text-[#7839EE]' />}
<OptionCard icon={<FileSearch02 className='w-4 h-4 text-[#7839EE]' />}
title={t('dataset.retrieval.full_text_search.title')}
description={t('dataset.retrieval.full_text_search.description')}
isChosen={value.search_method === RETRIEVE_METHOD.fullText}
onChosen={() => onChange({
isActive={
value.search_method === RETRIEVE_METHOD.fullText
}
onClick={() => onChange({
...value,
search_method: RETRIEVE_METHOD.fullText,
})}
chosenConfig={
<RetrievalParamConfig
type={RETRIEVE_METHOD.fullText}
value={value}
onChange={onChange}
/>
}
/>
>
<RetrievalParamConfig
type={RETRIEVE_METHOD.fullText}
value={value}
onChange={onChange}
/>
</OptionCard>
)}
{supportRetrievalMethods.includes(RETRIEVE_METHOD.semantic) && (
<RadioCard
icon={<PatternRecognition className='w-4 h-4 text-[#7839EE]' />}
<OptionCard icon={<PatternRecognition className='w-4 h-4 text-[#7839EE]' />}
title={
<div className='flex items-center space-x-1'>
<div>{t('dataset.retrieval.hybrid_search.title')}</div>
<div className='flex h-full items-center px-1.5 rounded-md border border-[#E0EAFF] text-xs font-medium text-[#444CE7]'>{t('dataset.retrieval.hybrid_search.recommend')}</div>
</div>
}
description={t('dataset.retrieval.hybrid_search.description')}
isChosen={value.search_method === RETRIEVE_METHOD.hybrid}
onChosen={() => onChange({
description={t('dataset.retrieval.hybrid_search.description')} isActive={
value.search_method === RETRIEVE_METHOD.hybrid
}
onClick={() => onChange({
...value,
search_method: RETRIEVE_METHOD.hybrid,
reranking_enable: true,
})}
chosenConfig={
<RetrievalParamConfig
type={RETRIEVE_METHOD.hybrid}
value={value}
onChange={onChange}
/>
}
/>
>
<RetrievalParamConfig
type={RETRIEVE_METHOD.hybrid}
value={value}
onChange={onChange}
/>
</OptionCard>
)}
</div>
)

View File

@ -20,6 +20,7 @@ import {
} from '@/models/datasets'
import WeightedScore from '@/app/components/app/configuration/dataset-config/params-config/weighted-score'
import Toast from '@/app/components/base/toast'
import RadioCard from '@/app/components/base/radio-card'
type Props = {
type: RETRIEVE_METHOD
@ -201,24 +202,18 @@ const RetrievalParamConfig: FC<Props> = ({
{
isHybridSearch && (
<>
<div className='flex items-center justify-between'>
<div className='flex gap-2 mb-4'>
{
rerankingModeOptions.map(option => (
<div
<RadioCard
key={option.value}
className={cn(
'flex items-center justify-center mb-4 w-[calc((100%-8px)/2)] h-8 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg cursor-pointer system-sm-medium text-text-secondary',
value.reranking_mode === RerankingModeEnum.WeightedScore && option.value === RerankingModeEnum.WeightedScore && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary',
value.reranking_mode !== RerankingModeEnum.WeightedScore && option.value !== RerankingModeEnum.WeightedScore && 'border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg text-text-primary',
)}
onClick={() => handleChangeRerankMode(option.value)}
>
<div className='truncate'>{option.label}</div>
<Tooltip
popupContent={<div className='w-[200px]'>{option.tips}</div>}
triggerClassName='ml-0.5 w-3.5 h-3.5'
/>
</div>
isChosen={value.reranking_mode === option.value}
onChosen={() => handleChangeRerankMode(option.value)}
icon={<div className='w-4 h-4 text-[#7839EE]' />}
title={option.label}
description={option.tips}
className='flex-1'
/>
))
}
</div>

View File

@ -0,0 +1,6 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.18055 6.45828C7.52291 6.45828 8.61111 5.37008 8.61111 4.02772C8.61111 2.68536 7.52291 1.59717 6.18055 1.59717C4.8382 1.59717 3.75 2.68536 3.75 4.02772C3.75 5.37008 4.8382 6.45828 6.18055 6.45828Z" fill="#EF6820"/>
<path d="M13.8192 6.45828C15.1616 6.45828 16.2498 5.37008 16.2498 4.02772C16.2498 2.68536 15.1616 1.59717 13.8192 1.59717C12.4769 1.59717 11.3887 2.68536 11.3887 4.02772C11.3887 5.37008 12.4769 6.45828 13.8192 6.45828Z" fill="#EF6820"/>
<path d="M13.8193 7.84719C13.0627 7.84805 12.3185 8.03933 11.6552 8.40341C10.992 8.7675 10.4311 9.29267 10.0241 9.93053C10.5745 9.93695 11.1 10.1609 11.4858 10.5535C11.8716 10.9461 12.0864 11.4755 12.0831 12.0259C12.0799 12.5763 11.859 13.1031 11.4687 13.4911C11.0783 13.8792 10.5503 14.097 9.99984 14.097C9.44942 14.097 8.92135 13.8792 8.53101 13.4911C8.14066 13.1031 7.91976 12.5763 7.91655 12.0259C7.91334 11.4755 8.12808 10.9461 8.51387 10.5535C8.89966 10.1609 9.42515 9.93695 9.97554 9.93053C9.45127 9.10686 8.67371 8.47572 7.75983 8.13205C6.84596 7.78839 5.84519 7.75078 4.9081 8.0249C3.97101 8.29902 3.14828 8.87003 2.56368 9.65203C1.97908 10.434 1.66424 11.3847 1.66652 12.3611V16.875C1.66652 17.0591 1.73968 17.2358 1.86991 17.366C2.00015 17.4962 2.17678 17.5694 2.36096 17.5694H7.22207V15.8333L4.72207 13.9583C4.64911 13.9036 4.58765 13.835 4.54118 13.7566C4.49472 13.6781 4.46417 13.5912 4.45127 13.501C4.42522 13.3186 4.47267 13.1334 4.58318 12.9861C4.69369 12.8387 4.8582 12.7413 5.04053 12.7153C5.22285 12.6892 5.40806 12.7367 5.5554 12.8472L8.14776 14.7916H11.8519L14.4443 12.8472C14.5916 12.7367 14.7768 12.6892 14.9592 12.7153C15.1415 12.7413 15.306 12.8387 15.4165 12.9861C15.527 13.1334 15.5745 13.3186 15.5484 13.501C15.5224 13.6833 15.425 13.8478 15.2776 13.9583L12.7776 15.8333V17.5694H17.6387C17.8229 17.5694 17.9995 17.4962 18.1298 17.366C18.26 17.2358 18.3332 17.0591 18.3332 16.875V12.3611C18.3317 11.1644 17.8557 10.0171 17.0095 9.17091C16.1633 8.32471 15.016 7.84867 13.8193 7.84719Z" fill="#EF6820"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99984 1.66663C8.35166 1.66663 6.7405 2.15537 5.37009 3.07105C3.99968 3.98672 2.93157 5.28821 2.30084 6.81093C1.67011 8.33365 1.50509 10.0092 1.82663 11.6257C2.14817 13.2422 2.94185 14.7271 4.10728 15.8925C5.27272 17.058 6.75758 17.8516 8.37409 18.1732C9.9906 18.4947 11.6662 18.3297 13.1889 17.699C14.7116 17.0682 16.0131 16.0001 16.9288 14.6297C17.8444 13.2593 18.3332 11.6481 18.3332 9.99996C18.3332 7.78982 17.4552 5.67021 15.8924 4.1074C14.3296 2.5446 12.21 1.66663 9.99984 1.66663ZM12.295 5.65899L13.1116 4.53538C13.1653 4.46155 13.2329 4.39901 13.3107 4.35133C13.3885 4.30365 13.4749 4.27175 13.565 4.25747C13.6551 4.24319 13.7472 4.24679 13.8359 4.26809C13.9246 4.28938 14.0083 4.32793 14.0821 4.38156C14.156 4.43518 14.2185 4.50282 14.2662 4.58061C14.3139 4.6584 14.3458 4.74482 14.36 4.83494C14.3743 4.92506 14.3707 5.01711 14.3494 5.10583C14.3281 5.19456 14.2896 5.27822 14.236 5.35204L13.4193 6.47565C13.311 6.62474 13.1479 6.72471 12.9659 6.75356C12.7839 6.7824 12.5979 6.73777 12.4488 6.62947C12.2997 6.52118 12.1997 6.35809 12.1709 6.17609C12.142 5.99408 12.1867 5.80808 12.295 5.65899ZM5.9179 4.3819C5.99174 4.32795 6.07551 4.28911 6.1644 4.26761C6.25329 4.24612 6.34556 4.2424 6.43589 4.25666C6.52623 4.27092 6.61286 4.30288 6.69081 4.35071C6.76875 4.39854 6.83649 4.4613 6.89012 4.53538L7.70817 5.65899C7.81647 5.80854 7.86092 5.99499 7.83175 6.17731C7.80258 6.35964 7.70217 6.52291 7.55262 6.63121C7.40307 6.73951 7.21662 6.78396 7.03429 6.75478C6.85196 6.72561 6.68869 6.62521 6.5804 6.47565L5.76373 5.35204C5.71013 5.27823 5.6716 5.19457 5.65034 5.10586C5.62908 5.01715 5.62551 4.92512 5.63983 4.83503C5.65414 4.74494 5.68607 4.65855 5.73378 4.5808C5.78149 4.50306 5.84406 4.43547 5.9179 4.3819ZM5.59151 12.1597L4.27206 12.5888C4.18433 12.6215 4.0909 12.6361 3.99739 12.6317C3.90388 12.6273 3.81222 12.6041 3.72791 12.5634C3.64361 12.5227 3.56841 12.4654 3.50682 12.3949C3.44524 12.3244 3.39854 12.2421 3.36954 12.1531C3.34055 12.0641 3.32984 11.9702 3.33808 11.8769C3.34631 11.7837 3.37332 11.693 3.41747 11.6105C3.46162 11.528 3.522 11.4552 3.59499 11.3966C3.66798 11.3379 3.75207 11.2947 3.8422 11.2694L5.16165 10.8402C5.24947 10.8072 5.34308 10.7924 5.43681 10.7965C5.53054 10.8007 5.62245 10.8238 5.707 10.8645C5.79154 10.9052 5.86697 10.9626 5.92872 11.0332C5.99047 11.1039 6.03727 11.1863 6.06629 11.2755C6.09531 11.3647 6.10595 11.4589 6.09757 11.5524C6.08919 11.6458 6.06195 11.7366 6.01752 11.8192C5.97308 11.9018 5.91236 11.9746 5.83902 12.0331C5.76568 12.0916 5.68194 12.1347 5.59151 12.1597ZM10.6943 16.25C10.6943 16.4341 10.6211 16.6108 10.4909 16.741C10.3607 16.8712 10.184 16.9444 9.99984 16.9444C9.81566 16.9444 9.63903 16.8712 9.50879 16.741C9.37856 16.6108 9.3054 16.4341 9.3054 16.25V14.8611C9.3054 14.6769 9.37856 14.5003 9.50879 14.37C9.63903 14.2398 9.81566 14.1666 9.99984 14.1666C10.184 14.1666 10.3607 14.2398 10.4909 14.37C10.6211 14.5003 10.6943 14.6769 10.6943 14.8611V16.25ZM9.99984 12.2222L7.38595 13.5972L7.88526 10.6868L5.77067 8.62565L8.6929 8.20135L9.99984 5.55551L11.3068 8.20135L14.229 8.62565L12.1144 10.6868L12.6137 13.5972L9.99984 12.2222ZM15.729 12.5902L14.4096 12.1611C14.3191 12.1361 14.2347 12.093 14.1614 12.0345C14.088 11.976 14.0273 11.9032 13.9829 11.8206C13.9384 11.738 13.9112 11.6472 13.9028 11.5537C13.8944 11.4603 13.9051 11.3661 13.9341 11.2769C13.9631 11.1877 14.0099 11.1053 14.0717 11.0346C14.1334 10.964 14.2088 10.9066 14.2934 10.8659C14.3779 10.8252 14.4698 10.8021 14.5636 10.7979C14.6573 10.7938 14.7509 10.8086 14.8387 10.8416L16.1582 11.2708C16.2483 11.2961 16.3324 11.3393 16.4054 11.398C16.4784 11.4566 16.5388 11.5293 16.5829 11.6119C16.6271 11.6944 16.6541 11.7851 16.6623 11.8783C16.6705 11.9716 16.6598 12.0655 16.6308 12.1545C16.6018 12.2435 16.5551 12.3258 16.4936 12.3963C16.432 12.4668 16.3568 12.5241 16.2725 12.5648C16.1882 12.6055 16.0965 12.6287 16.003 12.6331C15.9095 12.6375 15.8167 12.6229 15.729 12.5902Z" fill="#EF6820"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,12 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.93923 18.3333C3.48973 18.3333 3.05032 18.2 2.67657 17.9503C2.30282 17.7006 2.01152 17.3456 1.83951 16.9303C1.66749 16.515 1.62248 16.0581 1.71017 15.6172C1.79787 15.1763 2.01432 14.7714 2.33217 14.4535C2.65002 14.1357 3.05498 13.9192 3.49584 13.8315C3.93671 13.7438 4.39368 13.7889 4.80897 13.9609C5.22425 14.1329 5.5792 14.4242 5.82894 14.7979C6.07867 15.1717 6.21196 15.6111 6.21196 16.0606C6.21196 16.6634 5.97251 17.2414 5.54629 17.6677C5.12007 18.0939 4.542 18.3333 3.93923 18.3333Z" fill="#6938EF"/>
<path d="M9.99978 7.72726C9.55028 7.72726 9.11087 7.86056 8.73712 8.11029C8.36337 8.36002 8.07207 8.71497 7.90005 9.13026C7.72804 9.54554 7.68303 10.0025 7.77072 10.4434C7.85842 10.8842 8.07487 11.2892 8.39272 11.6071C8.71056 11.9249 9.11553 12.1414 9.55639 12.229C9.99726 12.3167 10.4542 12.2717 10.8695 12.0997C11.2848 11.9277 11.6398 11.6364 11.8895 11.2627C12.1392 10.8889 12.2725 10.4495 12.2725 9.99999C12.2725 9.39723 12.0331 8.81915 11.6068 8.39293C11.1806 7.96671 10.6025 7.72726 9.99978 7.72726Z" fill="#6938EF"/>
<path d="M3.93923 1.66666C3.48973 1.66666 3.05032 1.79995 2.67657 2.04968C2.30282 2.29941 2.01152 2.65436 1.83951 3.06965C1.66749 3.48494 1.62248 3.9419 1.71017 4.38277C1.79787 4.82364 2.01432 5.2286 2.33217 5.54644C2.65002 5.86429 3.05498 6.08075 3.49585 6.16844C3.93671 6.25613 4.39368 6.21113 4.80897 6.03911C5.22425 5.86709 5.57921 5.57579 5.82894 5.20204C6.07867 4.8283 6.21196 4.38889 6.21196 3.93938C6.21196 3.33662 5.97251 2.75854 5.54629 2.33232C5.12007 1.9061 4.542 1.66666 3.93923 1.66666Z" fill="#6938EF"/>
<path d="M16.0603 1.66666C15.6108 1.66666 15.1714 1.79995 14.7977 2.04968C14.4239 2.29941 14.1326 2.65436 13.9606 3.06965C13.7886 3.48494 13.7436 3.9419 13.8313 4.38277C13.919 4.82364 14.1354 5.2286 14.4533 5.54644C14.7711 5.86429 15.1761 6.08075 15.6169 6.16844C16.0578 6.25613 16.5148 6.21113 16.9301 6.03911C17.3453 5.86709 17.7003 5.57579 17.95 5.20204C18.1998 4.8283 18.3331 4.38889 18.3331 3.93938C18.3331 3.33662 18.0936 2.75854 17.6674 2.33232C17.2412 1.9061 16.6631 1.66666 16.0603 1.66666Z" fill="#6938EF"/>
<path d="M16.0603 13.7879C15.6108 13.7879 15.1714 13.9212 14.7977 14.1709C14.4239 14.4206 14.1326 14.7756 13.9606 15.1909C13.7886 15.6062 13.7436 16.0631 13.8313 16.504C13.919 16.9449 14.1354 17.3498 14.4533 17.6677C14.7711 17.9855 15.1761 18.202 15.6169 18.2897C16.0578 18.3774 16.5148 18.3323 16.9301 18.1603C17.3453 17.9883 17.7003 17.697 17.95 17.3233C18.1998 16.9495 18.3331 16.5101 18.3331 16.0606C18.3331 15.4578 18.0936 14.8798 17.6674 14.4535C17.2412 14.0273 16.6631 13.7879 16.0603 13.7879Z" fill="#6938EF"/>
<path d="M6.21196 7.72726H1.6665V12.2727H6.21196V7.72726Z" fill="#6938EF"/>
<path d="M18.3331 7.72726H13.7876V12.2727H18.3331V7.72726Z" fill="#6938EF"/>
<path d="M12.2725 1.66666H7.72705V6.21211H12.2725V1.66666Z" fill="#6938EF"/>
<path d="M12.2725 13.7879H7.72705V18.3333H12.2725V13.7879Z" fill="#6938EF"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,7 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.91672 15.2028V17.9805H6.52783V15.2028H7.91672Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.1667 15.2028V17.9805H12.7778V15.2028H14.1667Z" fill="#444CE7"/>
<path d="M14.1666 2.0083C14.1666 3.54243 12.923 4.78608 11.3889 4.78608C9.85476 4.78608 8.61108 3.54243 8.61108 2.0083L14.1666 2.0083Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.8864 5.23918C6.9718 4.92907 8.12598 5.30791 8.81883 6.17498H13.1251C16.0015 6.17498 18.3334 8.50683 18.3334 11.3833C18.3334 14.2598 16.0015 16.5916 13.1251 16.5916H7.39252C6.14908 16.5916 4.97062 16.0363 4.1791 15.0773L3.32342 14.0407L1.66675 13.3448V9.93061L3.65692 9.40957L4.44453 8.40703V5.65114L5.8864 5.23918ZM8.61119 8.25831H14.1667V9.64721H8.61119V8.25831ZM6.52786 9.99443C6.52786 10.5697 6.06149 11.0361 5.48619 11.0361C4.91089 11.0361 4.44453 10.5697 4.44453 9.99443C4.44453 9.41915 4.91089 8.95276 5.48619 8.95276C6.06149 8.95276 6.52786 9.41915 6.52786 9.99443Z" fill="#444CE7"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,6 @@
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6752 4.83333H9.91553V1.07361L13.6752 4.83333Z" fill="#6938EF"/>
<path d="M7.2003 13.8611H2.62391C2.53183 13.8611 2.44351 13.8245 2.37839 13.7594C2.31327 13.6943 2.27669 13.606 2.27669 13.5139V12.8195C2.27669 12.7274 2.31327 12.6391 2.37839 12.5739C2.44351 12.5088 2.53183 12.4722 2.62391 12.4722H7.2003C7.33176 11.6964 7.68097 10.9739 8.20725 10.3889H2.62391C2.53183 10.3889 2.44351 10.3523 2.37839 10.2872C2.31327 10.2221 2.27669 10.1338 2.27669 10.0417V9.34724C2.27669 9.25515 2.31327 9.16684 2.37839 9.10172C2.44351 9.0366 2.53183 9.00002 2.62391 9.00002H11.3045C12.3309 9.0003 13.3207 9.38137 14.0822 10.0695V6.22224H9.22114C9.03696 6.22224 8.86032 6.14908 8.73009 6.01884C8.59986 5.88861 8.52669 5.71198 8.52669 5.5278V0.666687H0.887804C0.703626 0.666687 0.526991 0.739851 0.396757 0.870085C0.266524 1.00032 0.193359 1.17695 0.193359 1.36113V16.6389C0.193359 16.8231 0.266524 16.9997 0.396757 17.13C0.526991 17.2602 0.703626 17.3334 0.887804 17.3334H10.61C9.73337 17.224 8.91945 16.8214 8.30046 16.1911C7.68146 15.5607 7.29375 14.7396 7.2003 13.8611ZM2.62391 5.5278H6.09614C6.18823 5.5278 6.27654 5.56438 6.34166 5.6295C6.40678 5.69461 6.44336 5.78293 6.44336 5.87502V6.56947C6.44336 6.66155 6.40678 6.74987 6.34166 6.81499C6.27654 6.88011 6.18823 6.91669 6.09614 6.91669H2.62391C2.53183 6.91669 2.44351 6.88011 2.37839 6.81499C2.31327 6.74987 2.27669 6.66155 2.27669 6.56947V5.87502C2.27669 5.78293 2.31327 5.69461 2.37839 5.6295C2.44351 5.56438 2.53183 5.5278 2.62391 5.5278Z" fill="#6938EF"/>
<path d="M15.2678 16.1479L13.6887 14.5688C13.9439 14.1455 14.08 13.661 14.0824 13.1667C14.0824 12.6173 13.9195 12.0802 13.6143 11.6234C13.309 11.1666 12.8752 10.8106 12.3676 10.6004C11.8601 10.3901 11.3016 10.3351 10.7627 10.4423C10.2239 10.5495 9.72893 10.814 9.34045 11.2025C8.95197 11.591 8.68741 12.0859 8.58023 12.6248C8.47305 13.1636 8.52806 13.7221 8.7383 14.2297C8.94855 14.7373 9.30458 15.1711 9.76138 15.4763C10.2182 15.7816 10.7552 15.9445 11.3046 15.9445C11.799 15.9421 12.2834 15.806 12.7067 15.5507L14.2859 17.1299C14.4169 17.2564 14.5923 17.3264 14.7744 17.3248C14.9564 17.3232 15.1306 17.2502 15.2594 17.1214C15.3881 16.9927 15.4612 16.8185 15.4627 16.6364C15.4643 16.4543 15.3943 16.2789 15.2678 16.1479ZM9.91575 13.1667C9.91575 12.892 9.9972 12.6235 10.1498 12.3951C10.3024 12.1667 10.5193 11.9887 10.7731 11.8835C11.0269 11.7784 11.3062 11.7509 11.5756 11.8045C11.845 11.8581 12.0925 11.9904 12.2867 12.1846C12.481 12.3788 12.6132 12.6263 12.6668 12.8957C12.7204 13.1652 12.6929 13.4444 12.5878 13.6982C12.4827 13.952 12.3047 14.1689 12.0763 14.3215C11.8479 14.4741 11.5793 14.5556 11.3046 14.5556C10.9363 14.5556 10.583 14.4093 10.3225 14.1488C10.0621 13.8883 9.91575 13.5351 9.91575 13.1667Z" fill="#6938EF"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,12 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.83317 18.3334H1.6665V14.1667H5.83317V18.3334Z" fill="#6938EF"/>
<path d="M12.0832 12.0834H7.9165V7.91669H12.0832V12.0834Z" fill="#6938EF"/>
<path d="M5.83317 12.0834H1.6665V7.91669H5.83317V12.0834Z" fill="#6938EF"/>
<path d="M12.0832 5.83335H7.9165V1.66669H12.0832V5.83335Z" fill="#6938EF"/>
<path d="M5.83317 5.83335H1.6665V1.66669H5.83317V5.83335Z" fill="#6938EF"/>
<path d="M18.3332 5.83335H14.1665V1.66669H18.3332V5.83335Z" fill="#6938EF"/>
<path d="M17.6386 14.8611H14.8608V17.6389H17.6386V14.8611Z" fill="#6938EF"/>
<path d="M17.6386 8.61115H14.8608V11.3889H17.6386V8.61115Z" fill="#6938EF"/>
<path d="M11.3886 14.8611H8.61084V17.6389H11.3886V14.8611Z" fill="#6938EF"/>
</svg>

After

Width:  |  Height:  |  Size: 835 B

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0002 0.833374C10.4604 0.833374 10.8335 1.20647 10.8335 1.66671V2.54597C11.5977 2.63056 12.328 2.8301 13.0061 3.12703L13.4452 2.36666C13.6752 1.96808 14.1849 1.83152 14.5835 2.06164C14.9821 2.29176 15.1186 2.80142 14.8885 3.2L14.4488 3.96146C15.0552 4.40877 15.5915 4.94516 16.0388 5.55143L16.8003 5.11177C17.1989 4.88165 17.7086 5.01821 17.9387 5.41679C18.1688 5.81537 18.0322 6.32502 17.6337 6.55514L16.8732 6.99418C17.1702 7.67226 17.3697 8.40254 17.4543 9.16679H18.3335C18.7937 9.16679 19.1668 9.53987 19.1668 10.0001C19.1668 10.4604 18.7937 10.8335 18.3335 10.8335H17.4543C17.3697 11.5977 17.1702 12.328 16.8732 13.0061L17.6337 13.4452C18.0322 13.6753 18.1688 14.185 17.9387 14.5835C17.7086 14.9821 17.1989 15.1187 16.8003 14.8885L16.0388 14.4489C15.5915 15.0551 15.0551 15.5915 14.4488 16.0388L14.8885 16.8004C15.1186 17.1989 14.9821 17.7085 14.5835 17.9387C14.1849 18.1688 13.6752 18.0322 13.4452 17.6337L13.0061 16.8732C12.328 17.1701 11.5977 17.3697 10.8335 17.4543V18.3334C10.8335 18.7936 10.4604 19.1667 10.0002 19.1667C9.53991 19.1667 9.16683 18.7936 9.16683 18.3334V17.4543C8.40258 17.3697 7.6723 17.1701 6.99424 16.8732L6.55516 17.6337C6.32505 18.0323 5.81539 18.1689 5.41681 17.9388C5.01824 17.7086 4.88167 17.199 5.11179 16.8005L5.55149 16.0388C4.94519 15.5915 4.40878 15.0551 3.96145 14.4488L3.19993 14.8885C2.80135 15.1186 2.2917 14.982 2.06158 14.5835C1.83145 14.1849 1.96802 13.6752 2.3666 13.4451L3.12704 13.006C2.83011 12.328 2.63056 11.5977 2.54598 10.8335L1.66679 10.8334C1.20655 10.8334 0.833474 10.4602 0.833496 10C0.833521 9.53979 1.20663 9.16671 1.66687 9.16671L2.54599 9.16679C2.63058 8.40254 2.8301 7.67229 3.12701 6.99424L2.3666 6.55523C1.96802 6.32512 1.83145 5.81546 2.06157 5.41687C2.29169 5.0183 2.80135 4.88173 3.19992 5.11185L3.96142 5.55148C4.40874 4.94518 4.94515 4.40877 5.55145 3.96144L5.11179 3.19991C4.88167 2.80133 5.01823 2.29167 5.41681 2.06156C5.81539 1.83144 6.32505 1.968 6.55516 2.36657L6.9942 3.12702C7.67228 2.83009 8.40258 2.63055 9.16683 2.54597V1.66671C9.16683 1.20647 9.53991 0.833374 10.0002 0.833374ZM6.39156 5.41655C5.81089 5.87442 5.31917 6.44029 4.94695 7.08361C4.45095 7.94087 4.16681 8.93604 4.16681 10.0001C4.16681 11.0642 4.45096 12.0594 4.94698 12.9167C5.3192 13.56 5.81091 14.1259 6.39159 14.5837L8.1 11.6246C7.72651 11.1881 7.50015 10.6208 7.50015 10.0001C7.50015 9.37946 7.72651 8.81212 8.09999 8.37562L6.39156 5.41655ZM9.54316 7.54194L7.83418 4.5819C8.50325 4.31416 9.23383 4.16679 10.0002 4.16679C11.0642 4.16679 12.0594 4.45095 12.9167 4.94697C13.8022 5.45932 14.541 6.19807 15.0533 7.08357C15.4173 7.71277 15.6673 8.41629 15.7745 9.16679H12.3579C12.0147 8.19579 11.0887 7.50012 10.0002 7.50012C9.84433 7.50012 9.69149 7.51446 9.54316 7.54194ZM12.3579 10.8335C12.0147 11.8045 11.0887 12.5001 10.0002 12.5001C9.84433 12.5001 9.69149 12.4858 9.54316 12.4583L7.8342 15.4184C8.50325 15.6861 9.23383 15.8335 10.0002 15.8335C11.0642 15.8335 12.0594 15.5493 12.9167 15.0533C13.8022 14.541 14.5409 13.8022 15.0532 12.9167C15.4173 12.2875 15.6673 11.584 15.7745 10.8335H12.3579Z" fill="#444CE7"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -3,7 +3,6 @@ import React, { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import AppUnavailable from '../../base/app-unavailable'
import { ModelTypeEnum } from '../../header/account-setting/model-provider-page/declarations'
import StepsNavBar from './steps-nav-bar'
import StepOne from './step-one'
import StepTwo from './step-two'
import StepThree from './step-three'
@ -119,9 +118,6 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => {
return (
<div className='flex' style={{ height: 'calc(100vh - 56px)' }}>
<div className="flex flex-col w-11 sm:w-56 overflow-y-auto bg-white border-r border-gray-200 shrink-0">
<StepsNavBar step={step} datasetId={datasetId} />
</div>
<div className="grow bg-white">
<div className={step === 1 ? 'block h-full' : 'hidden'}>
<StepOne

View File

@ -146,7 +146,7 @@
}
.typeIcon.economical {
background-image: url(../assets/piggy-bank-01.svg);
background-image: url(../assets/piggy-bank-mod.svg);
}
.radioItem .radio {
@ -432,4 +432,4 @@
font-size: 12px;
line-height: 18px;
}
}
}

View File

@ -1,20 +1,24 @@
'use client'
import type { ComponentProps, FC, PropsWithChildren, ReactNode } from 'react'
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { useBoolean } from 'ahooks'
import { XMarkIcon } from '@heroicons/react/20/solid'
import { MagnifyingGlassCircleIcon, XMarkIcon } from '@heroicons/react/20/solid'
import { RocketLaunchIcon } from '@heroicons/react/24/outline'
import {
RiCloseLine,
} from '@remixicon/react'
import Link from 'next/link'
import { groupBy } from 'lodash-es'
import Image from 'next/image'
import SettingCog from '../assets/setting-gear-mod.svg'
import PreviewItem, { PreviewType } from './preview-item'
import LanguageSelect from './language-select'
import s from './index.module.css'
import unescape from './unescape'
import escape from './escape'
import { OptionCard } from './option-card'
import cn from '@/utils/classnames'
import type { CrawlOptions, CrawlResultItem, CreateDocumentReq, CustomFile, FileIndexingEstimateResponse, FullDocumentDetail, IndexingEstimateParams, NotionInfo, PreProcessingRule, ProcessRule, Rules, createDocumentResponse } from '@/models/datasets'
import {
@ -32,11 +36,9 @@ import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/ec
import { type RetrievalConfig } from '@/types/app'
import { ensureRerankModelSelected, isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
import Toast from '@/app/components/base/toast'
import { formatNumber } from '@/utils/format'
import type { NotionPage } from '@/models/common'
import { DataSourceProvider } from '@/models/common'
import { DataSourceType, DocForm } from '@/models/datasets'
import NotionIcon from '@/app/components/base/notion-icon'
import Switch from '@/app/components/base/switch'
import { MessageChatSquare } from '@/app/components/base/icons/src/public/common'
import { useDatasetDetailContext } from '@/context/dataset-detail'
@ -50,7 +52,7 @@ import { LanguagesSupported } from '@/i18n/language'
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { Globe01 } from '@/app/components/base/icons/src/vender/line/mapsAndTravel'
import Checkbox from '@/app/components/base/checkbox'
type ValueOf<T> = T[keyof T]
type StepTwoProps = {
@ -577,6 +579,26 @@ const StepTwo = ({
}
}, [segmentationType, indexType])
const Label: FC<PropsWithChildren> = (props) => {
return <label className='text-[#354052] text-xs font-semibold leading-none'>{props.children}</label>
}
const FormItem: FC<PropsWithChildren<{ label: ReactNode }>> = (props) => {
return <div className='space-y-2 flex-1'>
<Label>{props.label}</Label>
{props.children}
</div>
}
const CheckboxWithLabel: FC<PropsWithChildren<ComponentProps<typeof Checkbox> & {
label: string
}>> = (props) => {
return <div className='flex items-center gap-2'>
<Checkbox />
<Label>{props.label}</Label>
</div>
}
const [retrievalConfig, setRetrievalConfig] = useState(currentDataset?.retrieval_model_dict || {
search_method: RETRIEVE_METHOD.semantic,
reranking_enable: false,
@ -611,61 +633,46 @@ const StepTwo = ({
<div className={cn(s.form, isMobile && '!px-4')}>
<div className={s.label}>{t('datasetCreation.stepTwo.segmentation')}</div>
<div className='max-w-[640px]'>
<div
className={cn(
s.radioItem,
s.segmentationItem,
segmentationType === SegmentType.AUTO && s.active,
)}
onClick={() => setSegmentationType(SegmentType.AUTO)}
>
<span className={cn(s.typeIcon, s.auto)} />
<span className={cn(s.radio)} />
<div className={s.typeHeader}>
<div className={s.title}>{t('datasetCreation.stepTwo.auto')}</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.autoDescription')}</div>
</div>
</div>
<div
className={cn(
s.radioItem,
s.segmentationItem,
segmentationType === SegmentType.CUSTOM && s.active,
segmentationType === SegmentType.CUSTOM && s.custom,
)}
onClick={() => setSegmentationType(SegmentType.CUSTOM)}
>
<span className={cn(s.typeIcon, s.customize)} />
<span className={cn(s.radio)} />
<div className={s.typeHeader}>
<div className={s.title}>{t('datasetCreation.stepTwo.custom')}</div>
<div className={s.tip}>{t('datasetCreation.stepTwo.customDescription')}</div>
</div>
{segmentationType === SegmentType.CUSTOM && (
<div className={s.typeFormBody}>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>
{t('datasetCreation.stepTwo.separator')}
<Tooltip
popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.separatorTip')}
</div>
}
/>
</div>
<div className='space-y-4'>
<OptionCard
title={'General'}
icon={<Image src={SettingCog} alt='General' />}
activeHeaderClassName='bg-gradient-to-r from-blue-50/40 to-[#ffffff]'
description={'General text chunking mode, the chunks retrieved and recalled are the same.'}
isActive={SegmentType.AUTO === segmentationType}
onClick={() => setSegmentationType(SegmentType.AUTO)}
actions={
<>
<Button variant={'secondary-accent'}>
<MagnifyingGlassCircleIcon className='size-4 mr-2' />
Preview Chunk
</Button>
<Button variant={'ghost'} disabled>Reset</Button>
</>
}
>
<div className='space-y-4'>
<div className='flex gap-2'>
<FormItem label={<div className='flex'>
{t('datasetCreation.stepTwo.separator')}
<Tooltip
popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.separatorTip')}
</div>
}
/>
</div>}>
<Input
type="text"
className='h-9'
placeholder={t('datasetCreation.stepTwo.separatorPlaceholder') || ''} value={segmentIdentifier}
onChange={e => setSegmentIdentifier(e.target.value)}
/>
</div>
</div>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>{t('datasetCreation.stepTwo.maxLength')}</div>
</FormItem>
<FormItem label={<div>
{t('datasetCreation.stepTwo.maxLength')}
</div>}>
<Input
type="number"
className='h-9'
@ -675,47 +682,59 @@ const StepTwo = ({
min={1}
onChange={e => setMax(parseInt(e.target.value.replace(/^0+/, ''), 10))}
/>
</div>
</div>
<div className={s.formRow}>
<div className='w-full'>
<div className={s.label}>
{t('datasetCreation.stepTwo.overlap')}
<Tooltip
popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.overlapTip')}
</div>
}
/>
</div>
</FormItem>
<FormItem label={<div className='flex'>
{t('datasetCreation.stepTwo.overlap')}
<Tooltip
popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.overlapTip')}
</div>
}
/>
</div>}>
<Input
type="number"
className='h-9'
placeholder={t('datasetCreation.stepTwo.overlap') || ''}
value={overlap}
min={1}
onChange={e => setOverlap(parseInt(e.target.value.replace(/^0+/, ''), 10))}
/>
</div>
onChange={e => setOverlap(parseInt(e.target.value.replace(/^0+/, ''), 10))} />
</FormItem>
</div>
<div className={s.formRow}>
<div className='w-full flex flex-col gap-1'>
<div className={s.label}>{t('datasetCreation.stepTwo.rules')}</div>
{rules.map(rule => (
<div key={rule.id} className={s.ruleItem}>
<input id={rule.id} type="checkbox" checked={rule.enabled} onChange={() => ruleChangeHandle(rule.id)} className="w-4 h-4 rounded border-gray-300 text-blue-700 focus:ring-blue-700" />
<label htmlFor={rule.id} className="ml-2 text-sm font-normal cursor-pointer text-gray-800">{getRuleName(rule.id)}</label>
</div>
))}
<div className='space-y-2'>
<div className='w-full flex flex-col'>
<Label>{t('datasetCreation.stepTwo.rules')}</Label>
<div className='mt-4 space-y-2'>
{rules.map(rule => (
<div key={rule.id} className={s.ruleItem} onClick={() => {
ruleChangeHandle(rule.id)
}}>
<Checkbox
checked={rule.enabled}
/>
<label className="ml-2 text-sm font-normal cursor-pointer text-gray-800">{getRuleName(rule.id)}</label>
</div>
))}
</div>
</div>
</div>
<div className={s.formFooter}>
<Button variant="primary" className={cn(s.button)} onClick={confirmChangeCustomConfig}>{t('datasetCreation.stepTwo.preview')}</Button>
<Button className={cn(s.button, 'ml-2')} onClick={resetRules}>{t('datasetCreation.stepTwo.reset')}</Button>
</div>
</div>
)}
</OptionCard>
<OptionCard
title={'Parent-child'}
icon={undefined}
activeHeaderClassName='bg-gradient-to-r from-red-50/40 to-[#ffffff]'
description={'When using the parent-child mode, the child-chunk is used for retrieval and the parent-chunk is used for recall as context.'}
isActive={SegmentType.CUSTOM === segmentationType}
onClick={() => setSegmentationType(SegmentType.CUSTOM)}
>
<div className='space-y-4'>
<Label>
Parent-chunk for Context
</Label>
</div>
</OptionCard>
</div>
</div>
<div className={s.label}>{t('datasetCreation.stepTwo.indexMode')}</div>
@ -866,77 +885,6 @@ const StepTwo = ({
</div>
</div>
<div className={s.source}>
<div className={s.sourceContent}>
{dataSourceType === DataSourceType.FILE && (
<>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.fileSource')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
<span className={cn(s.fileIcon, files.length && s[files[0].extension || ''])} />
{getFileName(files[0].name || '')}
{files.length > 1 && (
<span className={s.sourceCount}>
<span>{t('datasetCreation.stepTwo.other')}</span>
<span>{files.length - 1}</span>
<span>{t('datasetCreation.stepTwo.fileUnit')}</span>
</span>
)}
</div>
</>
)}
{dataSourceType === DataSourceType.NOTION && (
<>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.notionSource')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
<NotionIcon
className='shrink-0 mr-1'
type='page'
src={notionPages[0]?.page_icon}
/>
{notionPages[0]?.page_name}
{notionPages.length > 1 && (
<span className={s.sourceCount}>
<span>{t('datasetCreation.stepTwo.other')}</span>
<span>{notionPages.length - 1}</span>
<span>{t('datasetCreation.stepTwo.notionUnit')}</span>
</span>
)}
</div>
</>
)}
{dataSourceType === DataSourceType.WEB && (
<>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.websiteSource')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
<Globe01 className='shrink-0 mr-1' />
<span className='grow w-0 truncate'>{websitePages[0].source_url}</span>
{websitePages.length > 1 && (
<span className={s.sourceCount}>
<span>{t('datasetCreation.stepTwo.other')}</span>
<span>{websitePages.length - 1}</span>
<span>{t('datasetCreation.stepTwo.webpageUnit')}</span>
</span>
)}
</div>
</>
)}
</div>
<div className={s.divider} />
<div className={s.segmentCount}>
<div className='mb-2 text-xs font-medium text-gray-500'>{t('datasetCreation.stepTwo.estimateSegment')}</div>
<div className='flex items-center text-sm leading-6 font-medium text-gray-800'>
{
fileIndexingEstimate
? (
<div className='text-xs font-medium text-gray-800'>{formatNumber(fileIndexingEstimate.total_segments)} </div>
)
: (
<div className={s.calculating}>{t('datasetCreation.stepTwo.calculating')}</div>
)
}
</div>
</div>
</div>
{!isSetting
? (
<div className='flex items-center mt-8 py-2'>

View File

@ -0,0 +1,73 @@
import { type ComponentProps, type FC, type ReactNode } from 'react'
import Image from 'next/image'
import piggyBank from '../assets/piggy-bank-01.svg'
import classNames from '@/utils/classnames'
const TriangleArrow = () => (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="11" viewBox="0 0 24 11" fill="none">
<path d="M9.87868 1.12132C11.0503 -0.0502525 12.9497 -0.0502525 14.1213 1.12132L23.3137 10.3137H0.686292L9.87868 1.12132Z" fill="white"/>
</svg>
)
type OptionCardHeaderProps = {
icon: ReactNode
title: ReactNode
description: string
isActive?: boolean
activeClassName?: string
}
export const OptionCardHeader: FC<OptionCardHeaderProps> = (props) => {
const { icon, title, description, isActive, activeClassName } = props
return <div className={classNames(
'h-20 flex py-3 px-4 items-center gap-4',
isActive && activeClassName,
)}>
<div className='size-8 rounded-lg border p-1.5 shadow border-[#101828]/10 justify-center flex'>
{icon || <Image src={piggyBank.src} className='size-5' alt={description} width={20} height={20} />}
</div>
<div className='flex-1 space-y-1'>
<div className='text-[#354052] text-sm font-semibold leading-tight'>{title}</div>
<div className='text-[#676f83] text-xs font-normal leading-none'>{description}</div>
</div>
</div>
}
type OptionCardProps = {
icon: ReactNode
className?: string
activeHeaderClassName?: string
title: ReactNode
description: string
isActive?: boolean
actions?: ReactNode
} & Omit<ComponentProps<'div'>, 'title'>
export const OptionCard: FC<OptionCardProps> = (props) => {
const { icon, className, title, description, isActive, children, actions, activeHeaderClassName, style, ...rest } = props
return <div
className={classNames(
'rounded-xl overflow-hidden',
isActive ? 'border-[#296cff] bg-white' : 'border-[#e9ebf0] bg-[#FCFCFD]',
className,
)}
style={{
...style,
borderWidth: 1.5,
}}
{...rest}>
<OptionCardHeader
icon={icon}
title={title}
description={description}
isActive={isActive}
activeClassName={activeHeaderClassName}
/>
{/** Body */}
{isActive && <div className='p-3'>{children}
{actions && <div className='flex gap-2 mt-3'>
{actions}
</div>}
</div>}
</div>
}