diff --git a/frontend/src/components/fileUpload.module.css b/frontend/src/components/fileUpload.module.css new file mode 100644 index 00000000..ea0be203 --- /dev/null +++ b/frontend/src/components/fileUpload.module.css @@ -0,0 +1,91 @@ +.uploadButton_container { + position: relative; + display: flex; + align-items: flex-start; + justify-content: center; + background-color: transparent; + border-radius: 50%; + height: 36px; + width: 36px; + margin-right: 16px; + margin-left: 10px; + margin-top: 5px; +} + +.uploadButton { + background: transparent; + border: none; + height: 36px; + width: 36px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.uploadButton img { + width: 24px; + height: 24px; +} + +.uploadButton:not(:disabled):hover { + cursor: pointer; +} + +.uploadButton:active { + background-color: var(--grey-400); + border-radius: 50%; +} + +.uploadButton_container:has(.uploadButton:disabled) { + color: var(--grey-900); + opacity: 0.5; +} + +.uploadButton_container:has(.uploadButton:not(:disabled)):hover { + background-color: var(--grey-300); +} + +.sendButtonContainer { + display: flex; + align-items: flex-start; + justify-content: center; + height: 100%; +} + +.tooltip { + position: absolute; + bottom: 130%; + left: 50%; + transform: translateX(-50%); + width: 220px; + background-color: #333333; + color: #f2f2f2; + padding: 8px; + border-radius: 8px; + font-family: 'Roboto', sans-serif; + font-size: 14px; + line-height: 16px; + text-align: left; + box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); + z-index: 10; +} + +.tooltip p { + margin: 0 0 8px 0; +} + +.tooltip p:last-child { + margin-bottom: 0; +} + +.tooltip::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + border-width: 8px; + border-style: solid; + border-color: #333333 transparent transparent transparent; +} diff --git a/frontend/src/components/fileUpload.tsx b/frontend/src/components/fileUpload.tsx new file mode 100644 index 00000000..1c3e716f --- /dev/null +++ b/frontend/src/components/fileUpload.tsx @@ -0,0 +1,62 @@ +import React, { ChangeEvent, useState } from 'react'; +import styles from './fileUpload.module.css'; +import UploadIcon from '../icons/upload.svg'; +import UploadInProgressIcon from '../icons/upload-in-progress.svg'; +import CheckCircleIcon from '../icons/check-circle.svg'; + +interface FileUploaderProps { + onFileUpload: (file: File) => Promise; + uploadInProgress: boolean; + disabled: boolean; +} + +export const FileUpload = ({ + onFileUpload, + uploadInProgress, + disabled, +}: FileUploaderProps) => { + const [showTooltip, setShowTooltip] = useState(false); + + const handleFileChange = (event: ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + onFileUpload(file); + } + }; + + const tooltipContent = disabled ? ( + <> +

You already uploaded one file.

+

You can upload a different file by starting a new chat.

+

Starting a new chat will reset your existing conversation history.

+ + ) : ( +

You can only upload one .csv, .pdf or .txt file to this chat.

+ ); + + return ( +
setShowTooltip(true)} + onMouseLeave={() => setShowTooltip(false)} + > + + {showTooltip &&
{tooltipContent}
} +
+ ); +}; diff --git a/frontend/src/components/input.module.css b/frontend/src/components/input.module.css index b0bfa307..c05d0826 100644 --- a/frontend/src/components/input.module.css +++ b/frontend/src/components/input.module.css @@ -1,7 +1,6 @@ .inputContainer { box-sizing: border-box; display: flex; - margin: 1rem 0 0 0; position: relative; width: 100%; } @@ -76,56 +75,16 @@ textarea::placeholder { font-family: 'Roboto', sans-serif; } -.uploadButton_container { +.sendButtonContainer { display: flex; align-items: flex-start; justify-content: center; - background-color: transparent; - border-radius: 50%; - height: 36px; - width: 36px; - margin-right: 16px; - margin-left: 10px; - margin-top: 5px; -} - -.uploadButton { - background: transparent; - color: var(--grey-900); - border: none; height: 100%; - width: 100%; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; } -.uploadButton img { - width: 24px; - height: 24px; -} - -.uploadButton:not(:disabled):hover { - cursor: pointer; -} - -.uploadButton:active { - background-color: var(--grey-400); -} - -.uploadButton_container:has(.uploadButton:disabled) { - color: var(--grey-900); - opacity: 0.5; -} - -.uploadButton_container:has(.uploadButton:not(:disabled)):hover { - background-color: var(--grey-300); -} - -.sendButtonContainer { +.inputRow { display: flex; - align-items: flex-start; - justify-content: center; - height: 100%; + justify-content: space-between; + align-items: center; + width: 100%; } diff --git a/frontend/src/components/input.tsx b/frontend/src/components/input.tsx index 9e657c2b..431ec6cf 100644 --- a/frontend/src/components/input.tsx +++ b/frontend/src/components/input.tsx @@ -8,9 +8,11 @@ import React, { } from 'react'; import styles from './input.module.css'; import RightArrowIcon from '../icons/send.svg'; -import UploadIcon from '../icons/upload.svg'; +import { FileUpload } from './fileUpload'; +import { UploadedFileDisplay } from './uploadedFileDisplay'; import { Suggestions } from './suggestions'; import { Button } from './button'; +import { uploadFileToServer } from '../server'; export interface InputProps { sendMessage: (message: string) => void; @@ -20,6 +22,8 @@ export interface InputProps { export const Input = ({ sendMessage, waiting, suggestions }: InputProps) => { const [userInput, setUserInput] = useState(''); + const [uploadedFile, setUploadedFile] = useState(null); + const [uploadInProgress, setUploadInProgress] = useState(false); const textareaRef = useRef(null); const onChange = useCallback((event: ChangeEvent) => { @@ -52,26 +56,43 @@ export const Input = ({ sendMessage, waiting, suggestions }: InputProps) => { [sendMessage, userInput, waiting], ); + const uploadFile = async (file: File) => { + setUploadInProgress(true); + + try { + const { filename, id } = await uploadFileToServer(file); + console.log(`File uploaded successfully: ${filename} with id ${id}`); + setUploadedFile(file); + } catch (error) { + console.error(error); + } finally { + setUploadInProgress(false); + } + }; + return ( <> + {uploadedFile && }
-
-