| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  | import React, { useEffect, useState } from 'react' | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  | import Button from '@/app/components/base/button' | 
					
						
							|  |  |  | import Input from '@/app/components/base/input' | 
					
						
							|  |  |  | import Textarea from '@/app/components/base/textarea' | 
					
						
							| 
									
										
										
										
											2025-03-06 17:38:50 +08:00
										 |  |  | 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' | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  | 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', | 
					
						
							| 
									
										
										
										
											2025-03-06 17:38:50 +08:00
										 |  |  |   DATE = 'date', | 
					
						
							|  |  |  |   TIME = 'time', | 
					
						
							|  |  |  |   DATETIME = 'datetime', | 
					
						
							|  |  |  |   CHECKBOX = 'checkbox', | 
					
						
							|  |  |  |   SELECT = 'select', | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | const MarkdownForm = ({ node }: any) => { | 
					
						
							|  |  |  |   const { onSend } = useChatContext() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |   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]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |   const getFormValues = (children: any) => { | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |     const values: { [key: string]: any } = {} | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |     children.forEach((child: any) => { | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |       if ([SUPPORTED_TAGS.INPUT, SUPPORTED_TAGS.TEXTAREA].includes(child.tagName)) | 
					
						
							|  |  |  |         values[child.properties.name] = formValues[child.properties.name] | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |     }) | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |     return values | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |   const onSubmit = (e: any) => { | 
					
						
							|  |  |  |     e.preventDefault() | 
					
						
							|  |  |  |     const format = node.properties.dataFormat || DATA_FORMAT.TEXT | 
					
						
							|  |  |  |     const result = getFormValues(node.children) | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |     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} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               className="system-md-semibold my-2 text-text-secondary" | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |             > | 
					
						
							|  |  |  |               {child.children[0]?.value || ''} | 
					
						
							|  |  |  |             </label> | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |         if (child.tagName === SUPPORTED_TAGS.INPUT && Object.values(SUPPORTED_TYPES).includes(child.properties.type)) { | 
					
						
							| 
									
										
										
										
											2025-03-06 17:38:50 +08:00
										 |  |  |           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 ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               <div className='mt-2 flex h-6 items-center space-x-2' key={index}> | 
					
						
							| 
									
										
										
										
											2025-03-06 17:38:50 +08:00
										 |  |  |                 <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, | 
					
						
							|  |  |  |                   })) | 
					
						
							|  |  |  |                 }} | 
					
						
							|  |  |  |               /> | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |           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, | 
					
						
							|  |  |  |                 })) | 
					
						
							|  |  |  |               }} | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           ) | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (child.tagName === SUPPORTED_TAGS.TEXTAREA) { | 
					
						
							|  |  |  |           return ( | 
					
						
							|  |  |  |             <Textarea | 
					
						
							|  |  |  |               key={index} | 
					
						
							|  |  |  |               name={child.properties.name} | 
					
						
							|  |  |  |               placeholder={child.properties.placeholder} | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |               value={formValues[child.properties.name]} | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |               onChange={(e) => { | 
					
						
							| 
									
										
										
										
											2024-11-11 11:52:32 +08:00
										 |  |  |                 setFormValues(prevValues => ({ | 
					
						
							|  |  |  |                   ...prevValues, | 
					
						
							|  |  |  |                   [child.properties.name]: e.target.value, | 
					
						
							|  |  |  |                 })) | 
					
						
							| 
									
										
										
										
											2024-10-29 13:32:50 +08:00
										 |  |  |               }} | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         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 |