Spaces:
Paused
Paused
| import { useState } from 'react' | |
| import Operate from './Operate' | |
| import KeyInput from './KeyInput' | |
| import { useValidate } from './hooks' | |
| import type { Form, KeyFrom, Status, ValidateValue } from './declarations' | |
| import { useEventEmitterContextContext } from '@/context/event-emitter' | |
| import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' | |
| export type KeyValidatorProps = { | |
| type: string | |
| title: React.ReactNode | |
| status: Status | |
| forms: Form[] | |
| keyFrom: KeyFrom | |
| onSave: (v: ValidateValue) => Promise<boolean | undefined> | |
| disabled?: boolean | |
| } | |
| const KeyValidator = ({ | |
| type, | |
| title, | |
| status, | |
| forms, | |
| keyFrom, | |
| onSave, | |
| disabled, | |
| }: KeyValidatorProps) => { | |
| const triggerKey = `plugins/${type}` | |
| const { eventEmitter } = useEventEmitterContextContext() | |
| const [isOpen, setIsOpen] = useState(false) | |
| const prevValue = forms.reduce((prev: ValidateValue, next: Form) => { | |
| prev[next.key] = next.value | |
| return prev | |
| }, {}) | |
| const [value, setValue] = useState(prevValue) | |
| const [validate, validating, validatedStatusState] = useValidate(value) | |
| eventEmitter?.useSubscription((v) => { | |
| if (v !== triggerKey) { | |
| setIsOpen(false) | |
| setValue(prevValue) | |
| validate({ before: () => false }) | |
| } | |
| }) | |
| const handleCancel = () => { | |
| eventEmitter?.emit('') | |
| } | |
| const handleSave = async () => { | |
| if (await onSave(value)) | |
| eventEmitter?.emit('') | |
| } | |
| const handleAdd = () => { | |
| setIsOpen(true) | |
| eventEmitter?.emit(triggerKey) | |
| } | |
| const handleEdit = () => { | |
| setIsOpen(true) | |
| eventEmitter?.emit(triggerKey) | |
| } | |
| const handleChange = (form: Form, val: string) => { | |
| setValue({ ...value, [form.key]: val }) | |
| if (form.validate) | |
| validate(form.validate) | |
| } | |
| const handleFocus = (form: Form) => { | |
| if (form.handleFocus) | |
| form.handleFocus(value, setValue) | |
| } | |
| return ( | |
| <div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-md'> | |
| <div className={ | |
| `flex items-center justify-between px-4 h-[52px] cursor-pointer ${isOpen && 'border-b-[0.5px] border-b-gray-200'}` | |
| }> | |
| {title} | |
| <Operate | |
| isOpen={isOpen} | |
| status={status} | |
| onCancel={handleCancel} | |
| onSave={handleSave} | |
| onAdd={handleAdd} | |
| onEdit={handleEdit} | |
| disabled={disabled} | |
| /> | |
| </div> | |
| { | |
| isOpen && !disabled && ( | |
| <div className='px-4 py-3'> | |
| { | |
| forms.map(form => ( | |
| <KeyInput | |
| key={form.key} | |
| className='mb-4' | |
| name={form.title} | |
| placeholder={form.placeholder} | |
| value={value[form.key] as string || ''} | |
| onChange={v => handleChange(form, v)} | |
| onFocus={() => handleFocus(form)} | |
| validating={validating} | |
| validatedStatusState={validatedStatusState} | |
| /> | |
| )) | |
| } | |
| <a className="flex items-center text-xs cursor-pointer text-primary-600" href={keyFrom.link} target='_blank' rel='noopener noreferrer'> | |
| {keyFrom.text} | |
| <LinkExternal02 className='w-3 h-3 ml-1 text-primary-600' /> | |
| </a> | |
| </div> | |
| ) | |
| } | |
| </div> | |
| ) | |
| } | |
| export default KeyValidator | |