| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  | import type { FC } from 'react' | 
					
						
							|  |  |  | import { useState } from 'react' | 
					
						
							|  |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							| 
									
										
										
										
											2025-06-17 16:14:53 +08:00
										 |  |  | import { useDocLink } from '@/context/i18n' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  | 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' | 
					
						
							| 
									
										
										
										
											2025-04-06 17:56:08 +08:00
										 |  |  | import { noop } from 'lodash-es' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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() | 
					
						
							| 
									
										
										
										
											2025-06-17 16:14:53 +08:00
										 |  |  |   const docLink = useDocLink() | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2025-04-06 17:56:08 +08:00
										 |  |  |       onClose={noop} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |       className='!w-[640px] !max-w-none !p-8 !pb-6' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |     > | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |       <div className='mb-2 text-xl font-semibold text-text-primary'> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |         { | 
					
						
							|  |  |  |           data.name | 
					
						
							|  |  |  |             ? t('common.apiBasedExtension.modal.editTitle') | 
					
						
							|  |  |  |             : t('common.apiBasedExtension.modal.title') | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |       <div className='py-2'> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className='text-sm font-medium leading-9 text-text-primary'> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           {t('common.apiBasedExtension.modal.name.title')} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |         <input | 
					
						
							|  |  |  |           value={localeData.name || ''} | 
					
						
							|  |  |  |           onChange={e => handleDataChange('name', e.target.value)} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           className='block h-9 w-full appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           placeholder={t('common.apiBasedExtension.modal.name.placeholder') || ''} | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |       <div className='py-2'> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className='flex h-9 items-center justify-between text-sm font-medium text-text-primary'> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           {t('common.apiBasedExtension.modal.apiEndpoint.title')} | 
					
						
							|  |  |  |           <a | 
					
						
							| 
									
										
										
										
											2025-06-17 16:14:53 +08:00
										 |  |  |             href={docLink('/guides/extension/api-based-extension/README')} | 
					
						
							| 
									
										
										
										
											2024-02-02 15:24:17 +08:00
										 |  |  |             target='_blank' rel='noopener noreferrer' | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             className='group flex items-center text-xs font-normal text-text-accent' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             <BookOpen01 className='mr-1 h-3 w-3' /> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |             {t('common.apiBasedExtension.link')} | 
					
						
							|  |  |  |           </a> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |         <input | 
					
						
							|  |  |  |           value={localeData.api_endpoint || ''} | 
					
						
							|  |  |  |           onChange={e => handleDataChange('api_endpoint', e.target.value)} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           className='block h-9 w-full appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           placeholder={t('common.apiBasedExtension.modal.apiEndpoint.placeholder') || ''} | 
					
						
							|  |  |  |         /> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |       <div className='py-2'> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className='text-sm font-medium leading-9 text-text-primary'> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           {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)} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             className='mr-2 block h-9 grow appearance-none rounded-lg bg-components-input-bg-normal px-3 text-sm text-text-primary outline-none' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |             placeholder={t('common.apiBasedExtension.modal.apiKey.placeholder') || ''} | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </div> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |       <div className='mt-6 flex items-center justify-end'> | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |         <Button | 
					
						
							|  |  |  |           onClick={onCancel} | 
					
						
							| 
									
										
										
										
											2024-06-21 14:17:45 +08:00
										 |  |  |           className='mr-2' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |         > | 
					
						
							|  |  |  |           {t('common.operation.cancel')} | 
					
						
							|  |  |  |         </Button> | 
					
						
							|  |  |  |         <Button | 
					
						
							| 
									
										
										
										
											2024-06-19 14:13:16 +08:00
										 |  |  |           variant='primary' | 
					
						
							| 
									
										
										
										
											2023-11-06 19:36:32 +08:00
										 |  |  |           disabled={!localeData.name || !localeData.api_endpoint || !localeData.api_key || loading} | 
					
						
							|  |  |  |           onClick={handleSave} | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           {t('common.operation.save')} | 
					
						
							|  |  |  |         </Button> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </Modal> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default ApiBasedExtensionModal |