Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. "use client";
  2. import { useState, useEffect } from 'react'
  3. import PageTitle from '@/components/ui/PageTitle';
  4. import { Input, Typography, Select, Switch, Upload, Form, Button } from 'antd'
  5. import { UploadOutlined } from '@ant-design/icons';
  6. import type { SelectProps } from 'antd';
  7. import TextArea from 'antd/es/input/TextArea';
  8. import { useQuery } from '@tanstack/react-query';
  9. import { getPersonaStyle } from '@/app/api/user/personaService';
  10. import type { RcFile } from 'antd/es/upload';
  11. const CreatePersona: React.FC = () => {
  12. const [name, setName] = useState<string | undefined>("")
  13. const [options, setOptions] = useState<SelectProps[] | undefined>()
  14. const [imageUrl, setImageUrl] = useState<string | null>(null);
  15. const [fileList, setFileList] = useState<any[]>([]);
  16. const [enabled, setEnabled] = useState({
  17. isManualKnowledgeEntry: false,
  18. isUploadTextDocument: false,
  19. isImportWebLink: false,
  20. isCodeInterpreter: false
  21. });
  22. const { data: personaStyleList, error, isLoading } = useQuery({
  23. queryKey: ["personaStyle"],
  24. queryFn: () => getPersonaStyle()
  25. })
  26. useEffect(() => {
  27. const latestData: SelectProps[] | undefined = personaStyleList?.map(persona => {
  28. return {
  29. label: persona.name,
  30. value: persona.id
  31. }
  32. })
  33. setOptions(latestData)
  34. }, [personaStyleList])
  35. const handleBeforeUpload = (file: RcFile) => {
  36. const isImage = file.type.startsWith('image/');
  37. if (!isImage) {
  38. // message.error('Only image files are allowed!');
  39. }
  40. const isLt2M = file.size / 1024 / 1024 < 2;
  41. if (!isLt2M) {
  42. //message.error('Image must be smaller than 2MB!');
  43. }
  44. if (isImage && isLt2M) {
  45. const reader = new FileReader();
  46. reader.onload = () => setImageUrl(reader.result as string);
  47. reader.readAsDataURL(file);
  48. }
  49. // prevent automatic upload
  50. return false;
  51. };
  52. return (
  53. <div className="flex flex-col bg-white">
  54. <PageTitle title='CREATE PERSONA' />
  55. <div className='px-4 py-6'>
  56. <Form layout="vertical">
  57. <Form.Item label="Profile Name">
  58. <Input
  59. style={{ padding: 10 }}
  60. value={name}
  61. onChange={(e) => setName(e.target.value)}
  62. />
  63. </Form.Item>
  64. <Form.Item label="Persona Image">
  65. <Upload
  66. beforeUpload={handleBeforeUpload}
  67. fileList={fileList}
  68. onRemove={() => {
  69. setFileList([]);
  70. setImageUrl(null);
  71. }}
  72. onChange={({ fileList }) => setFileList(fileList)}
  73. maxCount={1}
  74. accept="image/*"
  75. listType="picture"
  76. >
  77. <button className='border border-gray-300 px-4 py-2 rounded hover:bg-gray-50'>
  78. <UploadOutlined /> Click to Upload
  79. </button>
  80. </Upload>
  81. {imageUrl && (
  82. <img
  83. src={imageUrl}
  84. alt="Uploaded Preview"
  85. className="mt-2 w-32 h-32 object-cover border rounded"
  86. />
  87. )}
  88. </Form.Item>
  89. <Form.Item label="Role / Department">
  90. <Input
  91. style={{ padding: 10 }}
  92. value={name}
  93. onChange={(e) => setName(e.target.value)}
  94. />
  95. </Form.Item>
  96. <Form.Item label="Description">
  97. <TextArea
  98. style={{ padding: 10 }}
  99. rows={6}
  100. value={name}
  101. onChange={(e) => setName(e.target.value)}
  102. />
  103. </Form.Item>
  104. <Form.Item label="Persona Style">
  105. <Select
  106. mode="multiple"
  107. allowClear
  108. style={{ width: '100%' }}
  109. placeholder="Please select"
  110. options={options}
  111. />
  112. </Form.Item>
  113. <Form.Item label="Greeting Message">
  114. <TextArea
  115. style={{ padding: 10 }}
  116. rows={3}
  117. value={name}
  118. onChange={(e) => setName(e.target.value)}
  119. />
  120. </Form.Item>
  121. <Form.Item label="Persona Training Center">
  122. <div className='flex flex-col gap-2'>
  123. <div className='flex items-center gap-2'>
  124. <Switch
  125. checked={enabled.isManualKnowledgeEntry}
  126. onChange={(checked) =>
  127. setEnabled({ ...enabled, isManualKnowledgeEntry: checked })
  128. }
  129. />
  130. <span className='font-bold'>Manual Knowledge Entry</span>
  131. </div>
  132. <div className='flex items-center gap-2'>
  133. <Switch
  134. checked={enabled.isUploadTextDocument}
  135. onChange={(checked) =>
  136. setEnabled({ ...enabled, isUploadTextDocument: checked })
  137. }
  138. />
  139. <span className='font-bold'>Upload Text Document</span>
  140. </div>
  141. <div className='flex items-center gap-2'>
  142. <Switch
  143. checked={enabled.isImportWebLink}
  144. onChange={(checked) =>
  145. setEnabled({ ...enabled, isImportWebLink: checked })
  146. }
  147. />
  148. <span className='font-bold'>Import from Web Link</span>
  149. </div>
  150. <div className='flex items-center gap-2'>
  151. <Switch
  152. checked={enabled.isCodeInterpreter}
  153. onChange={(checked) =>
  154. setEnabled({ ...enabled, isCodeInterpreter: checked })
  155. }
  156. />
  157. <span className='font-bold'>Code Interpreter & Data Analysis</span>
  158. </div>
  159. </div>
  160. </Form.Item>
  161. <div className='text-center'>
  162. <Button type="primary" className='!w-fit !py-3 !text-xs !font-bold !px-10'>SUBMIT</Button>
  163. </div>
  164. </Form>
  165. </div>
  166. </div>
  167. )
  168. }
  169. export default CreatePersona