Skip to content

Commit

Permalink
feat: upload multiple files (#116)
Browse files Browse the repository at this point in the history
* feat: add property 'multiple' to file input

* feat: sends multiple documents or images to api

* fix: show icon for each file being uploaded

* fix: refresh page after uploading all files

* chore: add semicolons

* fix: cards overflow

* chore: add EOF

* fix: prevent file name overflow in card

Co-authored-by: Kevin Nielsen <keveran@gmail.com>

* chore: fix indentation

---------

Co-authored-by: Kevin Nielsen <keveran@gmail.com>
  • Loading branch information
WallysFerreira and kevinanielsen authored Jan 27, 2024
1 parent e8e97aa commit 0fe47fe
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 51 deletions.
32 changes: 15 additions & 17 deletions ui/src/components/docs-input.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import { useState } from "react";
import { FileText } from "lucide-react";
import UploadPreview from "./upload-preview";

const DocsInput: React.FC<{
fileRef: React.RefObject<HTMLInputElement>;
}> = ({ fileRef }) => {
const [fileName, setFileName] = useState<undefined | string>(undefined);
const [fileNames, setFileNames] = useState<string[]>([]);

const getFileName = () => {
const getFileNames = () => {
if (fileRef.current?.files != null) {
setFileName(fileRef.current.files[0].name);
let names = [];

for (let file of fileRef.current.files) {
names.push(file.name);
}

setFileNames(names);
}
};

return (
<div className="my-8 flex flex-col justify-center items-center h-full">
<div className="w-full h-full mb-4 flex justify-center items-center">
{fileName ? (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex flex-col overflow-hidden justify-center items-center">
<FileText size="128" />
{fileName}
</div>
) : (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex justify-center items-center">
<FileText size="128" />
</div>
)}
<div className="my-8 flex max-h-[691px] flex-col justify-center items-center h-full">
<div className="w-full h-full mb-4 flex justify-center items-center overflow-hidden">
<UploadPreview fileNames={fileNames} type="docs"/>
</div>
<label htmlFor="document" className="flex flex-col">
Select Document
<input
onChange={getFileName}
onChange={getFileNames}
type="file"
accept="text/plain, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/pdf, application/rtf, application/x-freearc"
multiple
name="document"
id="document"
aria-label="Select document"
Expand Down
31 changes: 15 additions & 16 deletions ui/src/components/image-input.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
import { FileImage } from "lucide-react";
import { useState } from "react";
import UploadPreview from "./upload-preview";

const ImageInput: React.FC<{
fileRef: React.RefObject<HTMLInputElement>;
}> = ({ fileRef }) => {
const [fileName, setFileName] = useState<undefined | string>(undefined);
const [fileNames, setFileNames] = useState<string[]>([]);

const getFileName = () => {
const getFileNames = () => {
if (fileRef.current?.files != null) {
setFileName(fileRef.current.files[0].name);
let names = [];

for (let file of fileRef.current.files) {
names.push(file.name);
}

setFileNames(names);
}
};


return (
<div className="my-8 flex flex-col justify-center items-center h-full">
<div className="my-8 max-h-[691px] flex flex-col justify-center items-center h-full">
<div className="w-full h-full mb-4 flex justify-center items-center">
{fileName ? (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex flex-col justify-center overflow-hidden items-center">
<FileImage size="128" />
{fileName}
</div>
) : (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex justify-center items-center">
<FileImage size="128" />
</div>
)}
<UploadPreview fileNames={fileNames} type="images"/>
</div>
<label htmlFor="image" className="flex flex-col">
Select Image
<input
onChange={getFileName}
onChange={getFileNames}
type="file"
accept="image/jpeg, image/png, image/jpg, image/webp, image/gif, image/bmp"
multiple
name="image"
id="image"
aria-label="Select image"
Expand Down
33 changes: 33 additions & 0 deletions ui/src/components/upload-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FileText } from "lucide-react";
import { FileImage } from "lucide-react";

const UploadPreview = ({fileNames, type}: {fileNames: string[], type: string}) => {
if (fileNames.length >= 7) {
return (
<ul className="list-columns">
{fileNames.map(fileName => (
<li>{fileName}</li>
))}
</ul>
);
} else if (fileNames.length > 0) {
return (
<section className="flex flex-row overflow-hidden">
{fileNames.map(fileName => (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex flex-col overflow-hidden justify-center items-center">
{type == "docs" ? <FileText size="128" /> : <FileImage size="128" />}
<p className="w-full px-2 truncate text-center">{fileName}</p>
</div>
))}
</section>
);
} else {
return (
<div className="border rounded-lg w-64 min-h-[264px] max-w-[256px] flex justify-center items-center">
{type == "docs" ? <FileText size="128" /> : <FileImage size="128" />}
</div>
);
}
};

export default UploadPreview;
38 changes: 21 additions & 17 deletions ui/src/components/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,33 @@ const Upload = () => {

const file = useRef<HTMLInputElement>(null);

const uploadFile = () => {
const uploadFile = async () => {
const files = file.current?.files;

if (files !== null && files !== undefined) {
toast.loading("Uploading...");
const toUpload = files[0];
const form = new FormData();
const type = tab === "docs" ? "doc" : "image";
form.append(type, toUpload);
axios
.post<{ url: string }>(`/api/cdn/upload/${type}`, form)
.then((res) => {
if (res.status === 200) {

for (let file of files) {
const form = new FormData();
form.append(type, file);

await axios
.post<{ url: string }>(`/api/cdn/upload/${type}`, form)
.then((res) => {
if (res.status === 200) {
toast.dismiss();
toast.success("Successfully uploaded file!");
getSize(setSize, setLoading);
}
})
.catch((err: Error) => {
toast.dismiss();
toast.success("Successfully uploaded file!");
getSize(setSize, setLoading);
location.reload();
}
})
.catch((err: Error) => {
toast.dismiss();
toast.error(err.message);
});
toast.error(err.message);
});
}

location.reload();
}
};

Expand Down
6 changes: 5 additions & 1 deletion ui/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,8 @@
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
}

.list-columns {
columns: 4;
}

0 comments on commit 0fe47fe

Please sign in to comment.