| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 | import React, { useEffect, useState } from 'react'import Button from '@/app/components/base/button'import Input from '@/app/components/base/input'import Textarea from '@/app/components/base/textarea'import DatePicker from '@/app/components/base/date-and-time-picker/date-picker'import TimePicker from '@/app/components/base/date-and-time-picker/time-picker'import Checkbox from '@/app/components/base/checkbox'import Select from '@/app/components/base/select'import { useChatContext } from '@/app/components/base/chat/chat/context'enum DATA_FORMAT {  TEXT = 'text',  JSON = 'json',}enum SUPPORTED_TAGS {  LABEL = 'label',  INPUT = 'input',  TEXTAREA = 'textarea',  BUTTON = 'button',}enum SUPPORTED_TYPES {  TEXT = 'text',  PASSWORD = 'password',  EMAIL = 'email',  NUMBER = 'number',  DATE = 'date',  TIME = 'time',  DATETIME = 'datetime',  CHECKBOX = 'checkbox',  SELECT = 'select',}const MarkdownForm = ({ node }: any) => {  const { onSend } = useChatContext()  const [formValues, setFormValues] = useState<{ [key: string]: any }>({})  useEffect(() => {    const initialValues: { [key: string]: any } = {}    node.children.forEach((child: any) => {      if ([SUPPORTED_TAGS.INPUT, SUPPORTED_TAGS.TEXTAREA].includes(child.tagName))        initialValues[child.properties.name] = child.properties.value    })    setFormValues(initialValues)  }, [node.children])  const getFormValues = (children: any) => {    const values: { [key: string]: any } = {}    children.forEach((child: any) => {      if ([SUPPORTED_TAGS.INPUT, SUPPORTED_TAGS.TEXTAREA].includes(child.tagName))        values[child.properties.name] = formValues[child.properties.name]    })    return values  }  const onSubmit = (e: any) => {    e.preventDefault()    const format = node.properties.dataFormat || DATA_FORMAT.TEXT    const result = getFormValues(node.children)    if (format === DATA_FORMAT.JSON) {      onSend?.(JSON.stringify(result))    }    else {      const textResult = Object.entries(result)        .map(([key, value]) => `${key}: ${value}`)        .join('\n')      onSend?.(textResult)    }  }  return (    <form      autoComplete="off"      className='flex flex-col self-stretch'      onSubmit={(e: any) => {        e.preventDefault()        e.stopPropagation()      }}    >      {node.children.filter((i: any) => i.type === 'element').map((child: any, index: number) => {        if (child.tagName === SUPPORTED_TAGS.LABEL) {          return (            <label              key={index}              htmlFor={child.properties.for}              className="system-md-semibold my-2 text-text-secondary"            >              {child.children[0]?.value || ''}            </label>          )        }        if (child.tagName === SUPPORTED_TAGS.INPUT && Object.values(SUPPORTED_TYPES).includes(child.properties.type)) {          if (child.properties.type === SUPPORTED_TYPES.DATE || child.properties.type === SUPPORTED_TYPES.DATETIME) {            return (              <DatePicker                key={index}                value={formValues[child.properties.name]}                needTimePicker={child.properties.type === SUPPORTED_TYPES.DATETIME}                onChange={(date) => {                  setFormValues(prevValues => ({                    ...prevValues,                    [child.properties.name]: date,                  }))                }}                onClear={() => {                  setFormValues(prevValues => ({                    ...prevValues,                    [child.properties.name]: undefined,                  }))                }}              />            )          }          if (child.properties.type === SUPPORTED_TYPES.TIME) {            return (              <TimePicker                key={index}                value={formValues[child.properties.name]}                onChange={(time) => {                  setFormValues(prevValues => ({                    ...prevValues,                    [child.properties.name]: time,                  }))                }}                onClear={() => {                  setFormValues(prevValues => ({                    ...prevValues,                    [child.properties.name]: undefined,                  }))                }}              />            )          }          if (child.properties.type === SUPPORTED_TYPES.CHECKBOX) {            return (              <div className='mt-2 flex h-6 items-center space-x-2' key={index}>                <Checkbox                  key={index}                  checked={formValues[child.properties.name]}                  onCheck={() => {                    setFormValues(prevValues => ({                      ...prevValues,                      [child.properties.name]: !prevValues[child.properties.name],                    }))                  }}                />                <span>{child.properties.dataTip || child.properties['data-tip'] || ''}</span>              </div>            )          }          if (child.properties.type === SUPPORTED_TYPES.SELECT) {            return (              <Select                key={index}                allowSearch={false}                className="w-full"                items={(() => {                  let options = child.properties.dataOptions || child.properties['data-options'] || []                  if (typeof options === 'string') {                    try {                      options = JSON.parse(options)                    }                    catch (e) {                      console.error('Failed to parse options:', e)                      options = []                    }                  }                  return options.map((option: string) => ({                    name: option,                    value: option,                  }))                })()}                defaultValue={formValues[child.properties.name]}                onSelect={(item) => {                  setFormValues(prevValues => ({                    ...prevValues,                    [child.properties.name]: item.value,                  }))                }}              />            )          }          return (            <Input              key={index}              type={child.properties.type}              name={child.properties.name}              placeholder={child.properties.placeholder}              value={formValues[child.properties.name]}              onChange={(e) => {                setFormValues(prevValues => ({                  ...prevValues,                  [child.properties.name]: e.target.value,                }))              }}            />          )        }        if (child.tagName === SUPPORTED_TAGS.TEXTAREA) {          return (            <Textarea              key={index}              name={child.properties.name}              placeholder={child.properties.placeholder}              value={formValues[child.properties.name]}              onChange={(e) => {                setFormValues(prevValues => ({                  ...prevValues,                  [child.properties.name]: e.target.value,                }))              }}            />          )        }        if (child.tagName === SUPPORTED_TAGS.BUTTON) {          const variant = child.properties.dataVariant          const size = child.properties.dataSize          return (            <Button              variant={variant}              size={size}              className='mt-4'              key={index}              onClick={onSubmit}            >              <span className='text-[13px]'>{child.children[0]?.value || ''}</span>            </Button>          )        }        return <p key={index}>Unsupported tag: {child.tagName}</p>      })}    </form>  )}MarkdownForm.displayName = 'MarkdownForm'export default MarkdownForm
 |