File size: 3,478 Bytes
4304c6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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