diff --git a/web/app/components/base/file-uploader/file-type-icon.tsx b/web/app/components/base/file-uploader/file-type-icon.tsx
new file mode 100644
index 0000000000..6ca32928aa
--- /dev/null
+++ b/web/app/components/base/file-uploader/file-type-icon.tsx
@@ -0,0 +1,86 @@
+import { memo } from 'react'
+import {
+ RiFile3Fill,
+ RiFileCodeFill,
+ RiFileExcelFill,
+ RiFileGifFill,
+ RiFileImageFill,
+ RiFileMusicFill,
+ RiFilePdf2Fill,
+ RiFilePpt2Fill,
+ RiFileTextFill,
+ RiFileVideoFill,
+ RiFileWordFill,
+ RiMarkdownFill,
+} from '@remixicon/react'
+import { FileTypeEnum } from './types'
+import cn from '@/utils/classnames'
+
+const FILE_TYPE_ICON_MAP = {
+ [FileTypeEnum.PDF]: {
+ component: RiFilePdf2Fill,
+ color: 'text-[#EA3434]',
+ },
+ [FileTypeEnum.IMAGE]: {
+ component: RiFileImageFill,
+ color: 'text-[#00B2EA]',
+ },
+ [FileTypeEnum.VIDEO]: {
+ component: RiFileVideoFill,
+ color: 'text-[#844FDA]',
+ },
+ [FileTypeEnum.AUDIO]: {
+ component: RiFileMusicFill,
+ color: 'text-[#FF3093]',
+ },
+ [FileTypeEnum.DOCUMENT]: {
+ component: RiFileTextFill,
+ color: 'text-[#6F8BB5]',
+ },
+ [FileTypeEnum.CODE]: {
+ component: RiFileCodeFill,
+ color: 'text-[#BCC0D1]',
+ },
+ [FileTypeEnum.MARKDOWN]: {
+ component: RiMarkdownFill,
+ color: 'text-[#309BEC]',
+ },
+ [FileTypeEnum.OTHER]: {
+ component: RiFile3Fill,
+ color: 'text-[#BCC0D1]',
+ },
+ [FileTypeEnum.EXCEL]: {
+ component: RiFileExcelFill,
+ color: 'text-[#01AC49]',
+ },
+ [FileTypeEnum.WORD]: {
+ component: RiFileWordFill,
+ color: 'text-[#2684FF]',
+ },
+ [FileTypeEnum.PPT]: {
+ component: RiFilePpt2Fill,
+ color: 'text-[#FF650F]',
+ },
+ [FileTypeEnum.GIF]: {
+ component: RiFileGifFill,
+ color: 'text-[#00B2EA]',
+ },
+}
+type FileTypeIconProps = {
+ type: keyof typeof FileTypeEnum
+ className?: string
+}
+const FileTypeIcon = ({
+ type,
+ className,
+}: FileTypeIconProps) => {
+ const Icon = FILE_TYPE_ICON_MAP[type].component
+ const color = FILE_TYPE_ICON_MAP[type].color
+
+ if (!Icon)
+ return null
+
+ return
+}
+
+export default memo(FileTypeIcon)
diff --git a/web/app/components/base/file-uploader/file-uploader-in-attachment/file-in-attachment-item.tsx b/web/app/components/base/file-uploader/file-uploader-in-attachment/file-in-attachment-item.tsx
new file mode 100644
index 0000000000..ee3460039d
--- /dev/null
+++ b/web/app/components/base/file-uploader/file-uploader-in-attachment/file-in-attachment-item.tsx
@@ -0,0 +1,29 @@
+import { memo } from 'react'
+import {
+ RiDeleteBinLine,
+} from '@remixicon/react'
+import FileTypeIcon from '../file-type-icon'
+import ActionButton from '@/app/components/base/action-button'
+
+const FileInAttachmentItem = () => {
+ return (
+
+
+
+
+
+
Yellow mountain range.jpg
+
+ JPG
+ •
+ 21.5 MB
+
+
+
+
+
+
+ )
+}
+
+export default memo(FileInAttachmentItem)
diff --git a/web/app/components/base/file-uploader/file-uploader-in-attachment/index.tsx b/web/app/components/base/file-uploader/file-uploader-in-attachment/index.tsx
new file mode 100644
index 0000000000..87841b3a18
--- /dev/null
+++ b/web/app/components/base/file-uploader/file-uploader-in-attachment/index.tsx
@@ -0,0 +1,47 @@
+import { memo } from 'react'
+import {
+ RiLink,
+ RiUploadCloud2Line,
+} from '@remixicon/react'
+import FileInAttachmentItem from './file-in-attachment-item'
+import Button from '@/app/components/base/button'
+
+const FileUploaderInAttachment = () => {
+ const options = [
+ {
+ value: 'local',
+ label: 'Local upload',
+ icon: ,
+ },
+ {
+ value: 'link',
+ label: 'Paste file link',
+ icon: ,
+ },
+ ]
+
+ return (
+
+
+ {
+ options.map(option => (
+
+ ))
+ }
+
+
+
+
+
+
+ )
+}
+
+export default memo(FileUploaderInAttachment)
diff --git a/web/app/components/base/file-uploader/file-uploader-in-chat-input/index.tsx b/web/app/components/base/file-uploader/file-uploader-in-chat-input/index.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/web/app/components/base/file-uploader/index.ts b/web/app/components/base/file-uploader/index.ts
new file mode 100644
index 0000000000..c8111581c9
--- /dev/null
+++ b/web/app/components/base/file-uploader/index.ts
@@ -0,0 +1,2 @@
+export { default as FileUploaderInAttachment } from './file-uploader-in-attachment'
+export { default as FileTypeIcon } from './file-type-icon'
diff --git a/web/app/components/base/file-uploader/types.ts b/web/app/components/base/file-uploader/types.ts
new file mode 100644
index 0000000000..8a17505eaa
--- /dev/null
+++ b/web/app/components/base/file-uploader/types.ts
@@ -0,0 +1,14 @@
+export enum FileTypeEnum {
+ IMAGE = 'IMAGE',
+ VIDEO = 'VIDEO',
+ AUDIO = 'AUDIO',
+ DOCUMENT = 'DOCUMENT',
+ CODE = 'CODE',
+ PDF = 'PDF',
+ MARKDOWN = 'MARKDOWN',
+ EXCEL = 'EXCEL',
+ WORD = 'WORD',
+ PPT = 'PPT',
+ GIF = 'GIF',
+ OTHER = 'OTHER',
+}