|
import type { FC } from 'react' |
|
import { useState } from 'react' |
|
import { useTranslation } from 'react-i18next' |
|
import Modal from '@/app/components/base/modal' |
|
import Button from '@/app/components/base/button' |
|
import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education' |
|
import type { ApiBasedExtension } from '@/models/common' |
|
import { |
|
addApiBasedExtension, |
|
updateApiBasedExtension, |
|
} from '@/service/common' |
|
import { useToastContext } from '@/app/components/base/toast' |
|
|
|
export type ApiBasedExtensionData = { |
|
name?: string |
|
apiEndpoint?: string |
|
apiKey?: string |
|
} |
|
|
|
type ApiBasedExtensionModalProps = { |
|
data: ApiBasedExtension |
|
onCancel: () => void |
|
onSave?: (newData: ApiBasedExtension) => void |
|
} |
|
const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({ |
|
data, |
|
onCancel, |
|
onSave, |
|
}) => { |
|
const { t } = useTranslation() |
|
const [localeData, setLocaleData] = useState(data) |
|
const [loading, setLoading] = useState(false) |
|
const { notify } = useToastContext() |
|
const handleDataChange = (type: string, value: string) => { |
|
setLocaleData({ ...localeData, [type]: value }) |
|
} |
|
const handleSave = async () => { |
|
setLoading(true) |
|
|
|
if (localeData && localeData.api_key && localeData.api_key?.length < 5) { |
|
notify({ type: 'error', message: t('common.apiBasedExtension.modal.apiKey.lengthError') }) |
|
setLoading(false) |
|
return |
|
} |
|
|
|
try { |
|
let res: ApiBasedExtension = {} |
|
if (!data.id) { |
|
res = await addApiBasedExtension({ |
|
url: '/api-based-extension', |
|
body: localeData, |
|
}) |
|
} |
|
else { |
|
res = await updateApiBasedExtension({ |
|
url: `/api-based-extension/${data.id}`, |
|
body: { |
|
...localeData, |
|
api_key: data.api_key === localeData.api_key ? '[__HIDDEN__]' : localeData.api_key, |
|
}, |
|
}) |
|
|
|
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) |
|
} |
|
|
|
if (onSave) |
|
onSave(res) |
|
} |
|
finally { |
|
setLoading(false) |
|
} |
|
} |
|
|
|
return ( |
|
<Modal |
|
isShow |
|
onClose={() => { }} |
|
className='!p-8 !pb-6 !max-w-none !w-[640px]' |
|
> |
|
<div className='mb-2 text-xl font-semibold text-gray-900'> |
|
{ |
|
data.name |
|
? t('common.apiBasedExtension.modal.editTitle') |
|
: t('common.apiBasedExtension.modal.title') |
|
} |
|
</div> |
|
<div className='py-2'> |
|
<div className='leading-9 text-sm font-medium text-gray-900'> |
|
{t('common.apiBasedExtension.modal.name.title')} |
|
</div> |
|
<input |
|
value={localeData.name || ''} |
|
onChange={e => handleDataChange('name', e.target.value)} |
|
className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none' |
|
placeholder={t('common.apiBasedExtension.modal.name.placeholder') || ''} |
|
/> |
|
</div> |
|
<div className='py-2'> |
|
<div className='flex justify-between items-center h-9 text-sm font-medium text-gray-900'> |
|
{t('common.apiBasedExtension.modal.apiEndpoint.title')} |
|
<a |
|
href={t('common.apiBasedExtension.linkUrl') || '/'} |
|
target='_blank' rel='noopener noreferrer' |
|
className='group flex items-center text-xs text-gray-500 font-normal hover:text-primary-600' |
|
> |
|
<BookOpen01 className='mr-1 w-3 h-3 text-gray-500 group-hover:text-primary-600' /> |
|
{t('common.apiBasedExtension.link')} |
|
</a> |
|
</div> |
|
<input |
|
value={localeData.api_endpoint || ''} |
|
onChange={e => handleDataChange('api_endpoint', e.target.value)} |
|
className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none' |
|
placeholder={t('common.apiBasedExtension.modal.apiEndpoint.placeholder') || ''} |
|
/> |
|
</div> |
|
<div className='py-2'> |
|
<div className='leading-9 text-sm font-medium text-gray-900'> |
|
{t('common.apiBasedExtension.modal.apiKey.title')} |
|
</div> |
|
<div className='flex items-center'> |
|
<input |
|
value={localeData.api_key || ''} |
|
onChange={e => handleDataChange('api_key', e.target.value)} |
|
className='block grow mr-2 px-3 h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none' |
|
placeholder={t('common.apiBasedExtension.modal.apiKey.placeholder') || ''} |
|
/> |
|
</div> |
|
</div> |
|
<div className='flex items-center justify-end mt-6'> |
|
<Button |
|
onClick={onCancel} |
|
className='mr-2' |
|
> |
|
{t('common.operation.cancel')} |
|
</Button> |
|
<Button |
|
variant='primary' |
|
disabled={!localeData.name || !localeData.api_endpoint || !localeData.api_key || loading} |
|
onClick={handleSave} |
|
> |
|
{t('common.operation.save')} |
|
</Button> |
|
</div> |
|
</Modal> |
|
) |
|
} |
|
|
|
export default ApiBasedExtensionModal |
|
|