Skip to content

Commit

Permalink
Merge pull request #26 from Saifullah-dev/feature/upload-files
Browse files Browse the repository at this point in the history
Feature/upload files
  • Loading branch information
Saifullah-dev authored Aug 17, 2024
2 parents d4811eb + f54ebdd commit 5123733
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 31 deletions.
22 changes: 13 additions & 9 deletions src/File Manager/Actions/Actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Modal from "../../components/Modal/Modal";
import CreateFolderAction from "./CreateFolder.action";
import RenameAction from "./Rename.action";
import DeleteAction from "./Delete.action";
import UploadFileAction from "./UploadFile.action";

const Actions = ({
triggerAction,
Expand All @@ -13,8 +14,8 @@ const Actions = ({
handleFileRename,
handleDelete,
}) => {
const [actionHeading, setActionHeading] = useState("");
const [actionComponent, setActionComponent] = useState(null);
const [activeAction, setActiveAction] = useState(null);

const actionTypes = {
createFolder: {
title: "Create Folder",
Expand All @@ -26,9 +27,12 @@ const Actions = ({
handleCreateFolder={handleCreateFolder}
/>
),
width: "25%",
},
uploadFile: {
title: "Upload File",
component: <UploadFileAction />,
width: "35%",
},
rename: {
title: "Rename",
Expand All @@ -40,6 +44,7 @@ const Actions = ({
handleFileRename={handleFileRename}
/>
),
width: "25%",
},
delete: {
title: "Delete",
Expand All @@ -50,6 +55,7 @@ const Actions = ({
handleDelete={handleDelete}
/>
),
width: "25%",
},
preview: {
title: "Preview",
Expand All @@ -59,21 +65,19 @@ const Actions = ({
useEffect(() => {
if (triggerAction.isActive) {
const actionType = triggerAction.actionType;
setActionHeading(actionTypes[actionType].title);
setActionComponent(actionTypes[actionType].component);
setActiveAction(actionTypes[actionType]);
} else {
setActionHeading("");
setActionComponent(null);
setActiveAction(null);
}
}, [triggerAction.isActive]);
return (
<Modal
heading={actionHeading}
heading={activeAction?.title}
show={triggerAction.isActive}
setShow={triggerAction.close}
dialogClassName={"w-25"}
dialogWidth={activeAction?.width}
>
{actionComponent}
{activeAction?.component}
</Modal>
);
};
Expand Down
90 changes: 90 additions & 0 deletions src/File Manager/Actions/UploadFile.action.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { useState } from "react";
import Button from "../../components/Button/Button";
import { AiOutlineClose, AiOutlineCloudUpload } from "react-icons/ai";
import { getFileExtension } from "../../utils/getFileExtension";
import { useFileIcons } from "../../hooks/useFileIcons";
import { FaRegFile } from "react-icons/fa6";
import Progress from "../../components/Progress/Progress";

const UploadFileAction = ({ onFilesSelected }) => {
const [files, setFiles] = useState([]);
const [isDragging, setIsDragging] = useState(false);
const fileIcons = useFileIcons(33);

const handleDrop = (e) => {
e.preventDefault();
setIsDragging(false);
const droppedFiles = e.dataTransfer.files;
if (droppedFiles.length > 0) {
setFiles((prev) => [...prev, ...droppedFiles]);
}
};

const handleChooseFile = (e) => {
const selectedFiles = e.target.files;
if (selectedFiles.length > 0) {
setFiles((prev) => [...prev, ...selectedFiles]);
}
};

return (
<div className={`fm-upload-file ${files.length > 0 ? "file-selcted" : ""}`}>
<div className="select-files">
<div
className={`draggable-file-input ${isDragging ? "dragging" : ""}`}
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
onDragEnter={() => setIsDragging(true)}
onDragLeave={() => setIsDragging(false)}
>
<div className="input-text">
<AiOutlineCloudUpload size={30} />
<span>Drag files to upload</span>
</div>
</div>
<div className="btn-choose-file">
<Button padding="0">
<label htmlFor="chooseFile">Choose File</label>
<input
type="file"
id="chooseFile"
className="choose-file-input"
onChange={handleChooseFile}
multiple
/>
</Button>
</div>
</div>
{files.length > 0 && (
<div className="files-progress">
<h2>Uploading</h2>
<ul>
{files.map((file, index) => (
<li key={index}>
<div className="file-icon">
{fileIcons[getFileExtension(file.name)] ?? <FaRegFile size={33} />}
</div>
<div className="file">
<div className="file-details">
<div className="file-info">
<span className="file-name text-truncate" title={file.name}>
{file.name}
</span>
<span className="file-size"> {file.size / 1000} KB</span>
</div>
<div className="rm-file" title="remove">
<AiOutlineClose />
</div>
</div>
<Progress percent={20} />
</div>
</li>
))}
</ul>
</div>
)}
</div>
);
};

export default UploadFileAction;
133 changes: 133 additions & 0 deletions src/File Manager/FileManager.scss
Original file line number Diff line number Diff line change
Expand Up @@ -576,3 +576,136 @@ svg {
padding: 8px 8px 0 0;
}
}

.fm-upload-file {
padding: 18px 15px;
display: flex;
gap: 18px;

.select-files {
width: 100%;
.draggable-file-input {
color: #696969;
margin-bottom: 18px;
height: 220px;
border: 2px dashed #ccc;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;

.input-text {
pointer-events: none; // This ensures that the drag and drop event isn't binded with it's children
display: flex;
flex-direction: column;
align-items: center;
}

&:hover {
border-color: $primary-color;
}
}

.draggable-file-input.dragging {
border-color: $primary-color;
}

.btn-choose-file {
display: flex;
justify-content: center;

label {
display: inline-block;
padding: 0.4rem 0.8rem;
&:hover {
cursor: pointer;
}
}

.choose-file-input {
display: none;
}
}
}

.files-progress {
width: 60%;
h2 {
font-size: 0.9em;
margin: 0;
}

ul {
padding-left: 0px;
padding-right: 5px;
padding-bottom: 10px;
margin-top: 0.7rem;
height: 220px;
overflow-y: auto !important;
font-weight: 500;

&::-webkit-scrollbar {
width: 3px;
height: 8px;
padding-top: 2px;
}

&::-webkit-scrollbar-thumb {
background: $primary-color !important;
}

li {
list-style: none;
border-bottom: 1px solid #c6c6c6;
display: flex;
gap: 5px;
margin-bottom: 18px;
padding-bottom: 12px;

.file-icon {
width: 10%;
}

.file {
width: 90%;

.file-details {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 5px;

.file-info {
width: 90%;
display: flex;
align-items: baseline;

.file-name {
display: inline-block;
max-width: 72%;
margin-right: 8px;
}
}

.file-size {
font-size: 0.7em;
}

.rm-file {
&:hover {
cursor: pointer;
color: red;
}
}
}
}
}
}
}
}

.file-selcted {
.select-files {
width: 40%;
}
}
13 changes: 3 additions & 10 deletions src/File Manager/Files/FileItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,7 @@ import { useDetectOutsideClick } from "../../hooks/useDetectOutsideClick";
import { BiRename } from "react-icons/bi";
import { BsCopy, BsScissors } from "react-icons/bs";
import { createFolderTree } from "../../utils/createFolderTree";

const fileIcons = {
pdf: <FaRegFilePdf size={48} />,
jpg: <FaRegFileImage size={48} />,
jpeg: <FaRegFileImage size={48} />,
png: <FaRegFileImage size={48} />,
txt: <FaRegFileLines size={48} />,
doc: <FaRegFileWord size={48} />,
docx: <FaRegFileWord size={48} />,
};
import { useFileIcons } from "../../hooks/useFileIcons";

const FileItem = ({
file,
Expand All @@ -42,6 +33,8 @@ const FileItem = ({
files,
triggerAction,
}) => {
const fileIcons = useFileIcons(48);

const [visible, setVisible] = useState(false);
const [fileSelected, setFileSelected] = useState(false);
const [lastClickTime, setLastClickTime] = useState(0);
Expand Down
2 changes: 1 addition & 1 deletion src/File Manager/Toolbar/Toolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const Toolbar = ({
icon: <MdOutlineFileUpload size={18} />,
text: "Upload File",
permission: allowUploadFile,
onClick: () => setShowUploadFile(true),
onClick: () => triggerAction.show("uploadFile"),
},
]);

Expand Down
8 changes: 6 additions & 2 deletions src/components/Button/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import "./Button.scss";

const Button = ({ onClick, type = "primary", children }) => {
const Button = ({ onClick, type = "primary", padding = "0.4rem 0.8rem", children }) => {
return (
<button onClick={onClick} className={`fm-button fm-button-${type}`}>
<button
onClick={onClick}
className={`fm-button fm-button-${type}`}
style={{ padding: padding }}
>
{children}
</button>
);
Expand Down
1 change: 0 additions & 1 deletion src/components/Button/Button.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.fm-button {
padding: 0.4rem 0.8rem;
border-radius: 5px;
font-weight: 600;
border: none;
Expand Down
11 changes: 3 additions & 8 deletions src/components/Modal/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const Modal = ({
show,
setShow,
heading,
dialogClassName,
dialogWidth = "25%",
contentClassName = "",
}) => {
const modalRef = useRef(null);
Expand All @@ -21,15 +21,10 @@ const Modal = ({
}, [show]);

return (
<dialog ref={modalRef} className={`fm-modal ${dialogClassName} dialog`}>
<dialog ref={modalRef} className={`fm-modal dialog`} style={{ width: dialogWidth }}>
<div className="fm-modal-header">
<span className="fm-modal-heading">{heading}</span>
<MdClose
size={18}
onClick={() => setShow(false)}
className="close-icon"
title="Close"
/>
<MdClose size={18} onClick={() => setShow(false)} className="close-icon" title="Close" />
</div>
{children}
</dialog>
Expand Down
Loading

0 comments on commit 5123733

Please sign in to comment.