diff --git a/src/App.tsx b/src/App.tsx index c42139a..50ee636 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,30 +1,34 @@ +//#region import import { createBrowserRouter, RouterProvider } from "react-router-dom"; // routes - import ButtonTestRoute from "@/routes/ButtonTestRoute"; import ProfilePictureTest from "./routes/ProfilePictureTestRoute"; import Test from "./routes/Test"; import SearchBarTest from "./routes/SearchBarTestRoute"; -import DropdownItem from "@/components/DropdownItem"; import SortDropdownListTestRoute from "@/routes/SortDropdownListTestRoute"; import NavigationTest from "@/routes/NavigationTest"; import TooltipTestRoute from "./routes/TooltipTestRoute"; import InputCodeTest from "@/routes/InputCodeTest"; import ToastTestRoute from "@/routes/ToastTestRoute"; import MediaUploadZoneTestRoute from "@/routes/MediaUploadZoneTestRoute"; - import IconOptionTest from "./routes/IconOptionTest"; import ImageTestRoute from "./routes/ImageTestRoute"; - +import { MemberTableTestRoute } from "./routes/MemberTableTestRoute"; import ColorPickerTestRoute from "@/routes/ColorPickerTestRoute"; import InputFieldTestRoute from "./routes/InputFieldTestRoute"; import MemberHeaderTestRoute from "@/routes/MemberHeaderTestRoute"; -import { MemberInformation } from "./components/MemberInformation"; +import MediaUploadStatusTestRoute from "./routes/MediaUploadStatusTestRoute"; import ModalTestRoute from "@/routes/ModalTestRoute"; + +// components +import { MemberInformation } from "./components/MemberInformation"; import { LoginModal } from "./components/LoginModal"; +//#endregion + const router = createBrowserRouter([ + { path: "/test", element: , @@ -70,6 +74,7 @@ const router = createBrowserRouter([ element: , }, { + path: "/color-picker-test", element: , }, @@ -115,6 +120,14 @@ const router = createBrowserRouter([ /> ), + }, + { + path: "/member-table", + element: , + }, + { + path: "/MediaUploadStatusTest", + element: , }, ]); diff --git a/src/components/MediaUploadStatus.tsx b/src/components/MediaUploadStatus.tsx new file mode 100644 index 0000000..1202a0f --- /dev/null +++ b/src/components/MediaUploadStatus.tsx @@ -0,0 +1,126 @@ +import React, { useEffect, useState } from "react"; +import { File, X, Check, Trash } from "@phosphor-icons/react"; + +// Props definition for MediaUploadStatus +interface MediaUploadStatusProps { + fileName: string; + fileSize: number; +} + +// Format bytes into its corresponding format +const formatBytes = (bytes: number, decimals = 2): string => { + if (bytes === 0) return '0 Bytes'; + const k = 1000; // Decimal multiple + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +}; + +// Main function +const MediaUploadStatus: React.FC = ({ fileName, fileSize }) => { + const [uploadProgress, setUploadProgress] = useState(70); // Example progress in percentage + const [isFailed, setIsFailed] = useState(false); // Example failed condition + const [isCompleted, setIsCompleted] = useState(false); + const [showDoneStatus, setShowDoneStatus] = useState(false); + + // For the trash icon to appear when it complete + useEffect(() => { + let timer: ReturnType; + if (isCompleted) { + timer = setTimeout(() => { + setShowDoneStatus(true); + }, 2500); // 2.5 sec + } else { + setShowDoneStatus(false); + } + return () => clearTimeout(timer); // Clean up the timer when isCompleted changes + }, [isCompleted]); + + // Condition to check if file is uploaded successfully + useEffect(() => { + if (uploadProgress === 100) { + setIsCompleted(true); + } else { + setIsCompleted(false); + } + }, [uploadProgress]); + + // useState for isFailed will implement here! + + + + // useState for setUploadProgress will implement here! + // This function expect to return the correct uploading percentage for the file + + + return ( +
+ {/* File Icon */} +
+ +
+ + {/* Middle Content: Filename, Progress Bar, Info Text */} +
+ {/*Filename*/} +
+
+ {fileName} +
+ + {showDoneStatus ? null : + ( +
+ {/* Progress bar */} + {isFailed ? null : ( +
+
+
+ ) + } + + {/* Uploading info text */} + {isFailed ? ( +
+
Failed to upload
+
+ ) : + (isCompleted ? ( +
+
Complete
+
+ +
+
+ ) : + ( +
+
{formatBytes((fileSize * uploadProgress) / 100)} of {formatBytes(fileSize)}
+
Uploading... {uploadProgress}%
+
+ ) + ) + } +
+ ) + } +
+
+ + {/* X Button */} + {isCompleted ? ( + showDoneStatus ? ( + ) : null + ) : ( + + )} +
+ ); +}; + +export default MediaUploadStatus; \ No newline at end of file diff --git a/src/routes/MediaUploadStatusTestRoute.tsx b/src/routes/MediaUploadStatusTestRoute.tsx new file mode 100644 index 0000000..b358cd2 --- /dev/null +++ b/src/routes/MediaUploadStatusTestRoute.tsx @@ -0,0 +1,21 @@ +import MediaUploadStatus from "@/components/MediaUploadStatus"; + + +// TODO: Add the +20% button here to test it and the fail to upload button +// +function MediaUploadStatusTestRoute() { + return ( +
+
+

Is this what you looking for?

+ {/* fileSize is in bytes */} + {/* Play around with uploadProgress in percentage and isFailed variables in MediaUploadStatus.tsx */} + +
+
+ + ) +} +export default MediaUploadStatusTestRoute; + + diff --git a/src/routes/ModalTestRoute.tsx b/src/routes/ModalTestRoute.tsx index c6c0371..a7e3f9f 100644 --- a/src/routes/ModalTestRoute.tsx +++ b/src/routes/ModalTestRoute.tsx @@ -26,23 +26,7 @@ function ModalTestRoute() { icon={} content={
- - - +
} actions={