diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml index 51c6c45..653cb97 100644 --- a/.github/workflows/firebase-hosting-pull-request.yml +++ b/.github/workflows/firebase-hosting-pull-request.yml @@ -3,6 +3,8 @@ name: Deploy to Firebase Hosting on PR 'on': pull_request +env: + VITE_FIREBASE_CONFIG: ${{ secrets.VITE_FIREBASE_CONFIG}} jobs: build_and_preview: if: '${{ github.event.pull_request.head.repo.full_name == github.repository }}' @@ -18,3 +20,5 @@ jobs: repoToken: '${{ secrets.GITHUB_TOKEN }}' firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_SCAFFOLD_TOOL }}' projectId: alzheimercalgary-v2 + env: + VITE_FIREBASE_CONFIG: ${{ secrets.VITE_FIREBASE_CONFIG}} diff --git a/.gitignore b/.gitignore index 749d71c..5fd29ca 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ package-lock.json # Local Netlify folder .netlify +config.tsx +.env \ No newline at end of file diff --git a/package.json b/package.json index e10a899..c356599 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,11 @@ "dependencies": { "@phosphor-icons/react": "^2.0.15", "clsx": "^2.1.0", + "firebase": "^10.12.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0", + "react-toastify": "^10.0.5", "tailwind-merge": "^2.2.1" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index f425d5a..724f929 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,30 +1,32 @@ //#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 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 MediaUploadStatusTestRoute from "./routes/MediaUploadStatusTestRoute"; -import ModalTestRoute from "@/routes/ModalTestRoute"; -import GalleryTestRoute from "./routes/GalleryTestRoute"; +// test routes +import ButtonTestRoute from "@/routes/test/ButtonTestRoute"; +import ProfilePictureTest from "./routes/test/ProfilePictureTestRoute"; +import Test from "./routes/test/Test"; +import SearchBarTest from "./routes/test/SearchBarTestRoute"; +import SortDropdownListTestRoute from "@/routes/test/SortDropdownListTestRoute"; +import NavigationTest from "@/routes/test/NavigationTest"; +import TooltipTestRoute from "./routes/test/TooltipTestRoute"; +import InputCodeTest from "@/routes/test/InputCodeTest"; +import ToastTestRoute from "@/routes/test/ToastTestRoute"; +import MediaUploadZoneTestRoute from "@/routes/test/MediaUploadZoneTestRoute"; +import IconOptionTest from "./routes/test/IconOptionTest"; +import ImageTestRoute from "./routes/test/ImageTestRoute"; +import { MemberTableTestRoute } from "./routes/test/MemberTableTestRoute"; +import ColorPickerTestRoute from "@/routes/test/ColorPickerTestRoute"; +import InputFieldTestRoute from "./routes/test/InputFieldTestRoute"; +import MemberHeaderTestRoute from "@/routes/test/MemberHeaderTestRoute"; +import MediaUploadStatusTestRoute from "./routes/test/MediaUploadStatusTestRoute"; +import ModalTestRoute from "@/routes/test/ModalTestRoute"; +import GalleryTestRoute from "./routes/test/GalleryTestRoute"; import { MemberInformation } from "./components/MemberInformation"; import { LoginModal } from "./components/LoginModal"; -import MemberProfilePictureTest from "@/routes/MemberProfilePictureTest"; +import MemberProfilePictureTest from "@/routes/test/MemberProfilePictureTest"; +// routes +import AdminLogin from "./routes/admin/AdminLogin"; const router = createBrowserRouter([ { @@ -99,29 +101,14 @@ const router = createBrowserRouter([ path: "/modal-test", element: , }, - { - path: "/login-modal-test", - element: ( -
- - -
- ), - }, { path: "/member-table", element: , }, - { - path: "/image-overlay", - element: - }, + { + path: "/image-overlay", + element: , + }, { path: "/MediaUploadStatusTest", element: , @@ -134,10 +121,24 @@ const router = createBrowserRouter([ path: "/member-profile-picture-test", element: , }, + + // Admin routes + { + path: "/admin", + element: ( +
+

Home Page

+
+ ), + }, + { + path: "/admin/login", + element: , + }, ]); function App() { - return ; + return ; } export default App; diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 04dcb01..712e4da 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,63 +1,63 @@ import { useRef } from "react"; import { twMerge } from "tailwind-merge"; interface ButtonProps extends React.ButtonHTMLAttributes { - onClick?: () => void; - icon?: React.ElementType; - text?: string; - rounded?: boolean; - fill?: boolean; - status?: string; - fontSize?: string; - color?: string; + onClick?: React.MouseEventHandler; + icon?: React.ElementType; + text?: string; + rounded?: boolean; + fill?: boolean; + disabled: boolean; + fontSize?: string; + color?: string; } const Button: React.FC = ({ - text = null, - icon: Icon = null, - onClick = () => console.log("Clicked"), - rounded = false, - fill = true, - status = "enabled", - fontSize = "1em", - className = null, + text = null, + icon: Icon = null, + onClick, + rounded = false, + fill = true, + disabled = false, + fontSize = "1em", + className = null, }) => { - const buttonRef = useRef(null); - const buttonClassName = twMerge( - `flex flex-row items-center justify-center p-4 ${ - status === "disabled" - ? "bg-neutrals-light-200 text-gray-400 cursor-default" - : fill - ? "relative overflow-hidden bg-primary-main text-white z-10 active:bg-primary-main active:text-white transition-colors hover:bg-neutrals-light-100 hover:text-primary-main border-2 border-primary-main hover:border-primary-main rounded-full w-full h-full before:absolute before:right-0 before:top-0 before:w-full before:h-full before:z-0 before:bg-primary-main before:content[''] before:transition-transform before:duration-300 hover:before:transform hover:before:translate-x-full" - : "relative overflow-hidden text-primary-dark border-primary-dark border-2 active:bg-white active:text-primary-dark transition-colors before:absolute before:left-0 before:top-0 before:-z-10 before:h-full before:w-full before:origin-top-left before:scale-x-0 before:bg-primary-dark before:transition-transform before:duration-300 before:content-[''] hover:text-white before:hover:scale-x-100" - } ${rounded ? "rounded-full" : "rounded-lg"} w-full h-full`, - className - // change color --> change text-{color}, border-{color} and active:bg-{color}, active:text-{color}, before:bg-{color} - ); + const buttonRef = useRef(null); + const buttonClassName = twMerge( + `flex flex-row items-center justify-center p-4 ${ + disabled === true + ? "bg-neutrals-light-200 text-gray-400 cursor-default" + : fill + ? "relative overflow-hidden bg-primary-main text-white z-10 active:bg-primary-main active:text-white transition-colors hover:bg-neutrals-light-100 hover:text-primary-main border-2 border-primary-main hover:border-primary-main rounded-full w-full h-full before:absolute before:right-0 before:top-0 before:w-full before:h-full before:z-0 before:bg-primary-main before:content[''] before:transition-transform before:duration-300 hover:before:transform hover:before:translate-x-full" + : "relative overflow-hidden text-primary-dark border-primary-dark border-2 active:bg-white active:text-primary-dark transition-colors before:absolute before:left-0 before:top-0 before:-z-10 before:h-full before:w-full before:origin-top-left before:scale-x-0 before:bg-primary-dark before:transition-transform before:duration-300 before:content-[''] hover:text-white before:hover:scale-x-100" + } ${rounded ? "rounded-full" : "rounded-lg"} w-full h-full`, + className, + // change color --> change text-{color}, border-{color} and active:bg-{color}, active:text-{color}, before:bg-{color} + ); - return ( - - ); + return ( + + ); }; export default Button; diff --git a/src/components/InputField.tsx b/src/components/InputField.tsx index 3de1a58..32cbaba 100644 --- a/src/components/InputField.tsx +++ b/src/components/InputField.tsx @@ -3,88 +3,101 @@ import { useRef, useState } from "react"; import { Eye, EyeSlash } from "@phosphor-icons/react"; export interface InputFieldProps { - type: string; - error: boolean; - label?: string; // Optional; Default to none. - required: boolean; - placeholder?: string; + type: string; + error: boolean; + label?: string; // Optional; Default to none. + required: boolean; + placeholder?: string; - // set Field value - setInput: (input: string) => void; + // set Field value + setInput: React.Dispatch>; } function InputField({ - type, - error, - label, - required, - placeholder, - setInput, + type, + error, + label, + required, + placeholder, + setInput, }: InputFieldProps) { - const inputRef = useRef(null); - const [showPassword, setShowPassword] = useState(false); + const inputRef = useRef(null); + const [showPassword, setShowPassword] = useState(false); + const [showError, setShowError] = useState(false); - function checkLen(event: { preventDefault: () => void }) { - event.preventDefault(); - if (inputRef.current) { - if (inputRef.current.value.trim() === "" && required === true) { - console.log("Required Input is empty"); - } - } - } + function validateInput(event: { preventDefault: () => void }) { + event.preventDefault(); - return ( -
- {/* Label */} -
- - {required && *} -
+ if (inputRef.current) { + setInput(inputRef.current.value); + if (inputRef.current.value.trim() === "" && required === true) { + setShowError(true); + } + if (type === "email") { + const email = inputRef.current.value.trim(); + const emailRegex = + /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/; + const valid = emailRegex.test(email); + setShowError(!valid); + } else if (type === "password") { + const password = inputRef.current.value.trim(); + password.length < 6 ? setShowError(true) : setShowError(false); + } + } + } - {/* Input */} -
- setInput(e.target.value)} - > + return ( +
+ {/* Label */} +
+ + {required && *} +
- {type.toLowerCase() === "password" && !showPassword && ( - setShowPassword(!showPassword)} - /> - )} + {/* Input */} +
+ validateInput(e)} + > - {/* Show password button */} - {type.toLowerCase() === "password" && showPassword && ( - setShowPassword(!showPassword)} - /> - )} -
+ {type.toLowerCase() === "password" && !showPassword && ( + setShowPassword(!showPassword)} + /> + )} - {/* Error */} - {error && ( -
- - - Error {type}{" "} - -
- )} -
- ); + {/* Show password button */} + {type.toLowerCase() === "password" && showPassword && ( + setShowPassword(!showPassword)} + /> + )} +
+ + {/* Error */} + {showError && ( +
+ + + Invalid {type} + +
+ )} +
+ ); } export default InputField; diff --git a/src/components/LoginModal.tsx b/src/components/LoginModal.tsx index e0259bd..a01aaec 100644 --- a/src/components/LoginModal.tsx +++ b/src/components/LoginModal.tsx @@ -1,7 +1,7 @@ //#region Imports import logoUrl from "@/assets/images/asc_logo.svg"; import { twMerge } from "tailwind-merge"; -import { useState } from "react"; +import React, { useState } from "react"; import Button from "./Button"; import InputField from "./InputField"; @@ -10,20 +10,41 @@ import { InputCode } from "./InputCode"; //#region Interface interface LoginModalProps { - /** - * Additional TailwindCSS classes. - */ - className?: string; + /** + * Additional TailwindCSS classes. + */ + className?: string; - /** - * The title of the login modal. - */ - title: string; + /** + * The title of the login modal. + */ + title: string; - /** - * The type of the login modal. - */ - type: "admin" | "member"; + /** + * The type of the login modal. + */ + type: "admin" | "member"; + + /** + * The email of the user. + */ + email: string; + setEmail: React.Dispatch>; + + /** + * The password of the user. + */ + password?: string; + setPassword?: React.Dispatch>; + + /** + * The passcode of the user. + */ + passcode?: Record; + setPasscode?: React.Dispatch>>; + + /** */ + onClick: React.MouseEventHandler; } //#endregion @@ -32,73 +53,93 @@ interface LoginModalProps { * @param {string} title - The title of the login modal. * @param {string} className - Additional TailwindCSS. * @param {string} type - The type of the login modal. + * @param {string} email - The email of the user. + * @param {string} password - The password of the user. + * @param {Record} passcode - The passcode of the user. + * @param {Function} setEmail - Set the email of the user. + * @param {Function} setPassword - Set the password of the user. + * @param {Function} setPasscode - Set the passcode of the user. * @returns */ -const LoginModal = ({ className, title, type }: LoginModalProps) => { - // TODO: Authentication functionality - const [username, setUsername] = useState(""); - const [password, setPassword] = useState(""); - const [passcode, setPasscode] = useState>({ - 0: "", - 1: "", - 2: "", - 3: "", - 4: "", - 5: "", - }); +const LoginModal = ({ + className, + title, + type, + email, + setEmail, + password, + setPassword, + passcode, + setPasscode, + onClick, +}: LoginModalProps) => { + const [validEmail, setValidEmail] = useState(false); + // const [passcode, setPasscode] = useState>({ + // 0: "", + // 1: "", + // 2: "", + // 3: "", + // 4: "", + // 5: "", + // }); - return ( -
- {/* Logo */} - ASC Logo + return ( +
+ {/* Logo */} + ASC Logo - {/* Title */} -

{title}

+ {/* Title */} +

+ {title} +

- {/*Username field */} - + {/*Username field */} + - {/* Password field */} - {type === "admin" ? ( - - ) : ( - - )} + {/* Password field */} + {type === "admin" ? ( + + ) : ( + + )} - {/* Login Button */} -
- ); + {/* Login Button */} +
+ ); }; export { LoginModal }; diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx index 96142dd..f2a6dfe 100644 --- a/src/components/Toast.tsx +++ b/src/components/Toast.tsx @@ -1,58 +1,80 @@ import clsx from "clsx"; -import { Warning, WarningCircle, Check, Info } from "@phosphor-icons/react"; - +import { Warning, WarningCircle, Check, Info } from "@phosphor-icons/react"; interface ToastIconProps { - /** The theme of the toast */ - severity?: "success" | "error" | "warning" | "info" | "neutral", + /** The theme of the toast */ + severity?: "success" | "error" | "warning" | "info" | "neutral"; } function ToastIcon({ severity }: ToastIconProps) { - if (severity === "success") { - return ; - } else if (severity === "error") { - return ; - } else if (severity === "warning") { - return ; - } else if (severity === "info") { - return ; - } else { - return null; - } + if (severity === "success") { + return ( + + ); + } else if (severity === "error") { + return ( + + ); + } else if (severity === "warning") { + return ( + + ); + } else if (severity === "info") { + return ( + + ); + } else { + return null; + } } interface ToastProps { - /** The text to display inside the toast */ - message: string, + /** The text to display inside the toast */ + message: string; + + /** The theme of the toast */ + severity?: "success" | "error" | "warning" | "info" | "neutral"; - /** The theme of the toast */ - severity?: "success" | "error" | "warning" | "info" | "neutral", + closeToast?: () => void; } function Toast({ message, severity = "neutral" }: ToastProps) { + // Body style + const body = "w-full flex py-4 pl-4 pr-6 rounded gap-2"; + + // Themes + const success = "bg-status-green-light"; + const error = "bg-status-red-light"; + const warning = "bg-status-yellow-light"; + const info = "bg-status-blue-light"; + const neutral = "bg-neutrals-light-300"; - // Body style - const body = "flex py-2 pl-4 pr-6 rounded gap-2"; - - // Themes - const success = "bg-status-green-light"; - const error = "bg-status-red-light"; - const warning = "bg-status-yellow-light"; - const info = "bg-status-blue-light"; - const neutral = "bg-neutrals-light-300"; - - return ( -
- - { message } -
- ) + return ( +
+ + {message} +
+ ); } -export default Toast; \ No newline at end of file +export default Toast; diff --git a/src/index.css b/src/index.css index 5ec9b1c..41f3dc5 100644 --- a/src/index.css +++ b/src/index.css @@ -21,6 +21,10 @@ } @layer base { + .Toastify__toast { + background: #bbccdd; + } + .scroller { scrollbar-color: #555770 #fffff; scrollbar-width: auto; diff --git a/src/routes/ImageTestRoute.tsx b/src/routes/ImageTestRoute.tsx deleted file mode 100644 index b1fd32b..0000000 --- a/src/routes/ImageTestRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Image from "@/components/Image"; -import Overlay from '@/components/Overlay'; -import old1 from '../assets/images/old1.jpg'; - -function ImageTestRoute() { - - return ( - - old - - ); -} - -export default ImageTestRoute; \ No newline at end of file diff --git a/src/routes/NavigationTest.tsx b/src/routes/NavigationTest.tsx deleted file mode 100644 index 646e14f..0000000 --- a/src/routes/NavigationTest.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { NavigationBar } from "../components/NavigationBar"; - -function NavigationTest() { - return ( -
- {/* Using margin or padding for the parent tag can break the navigation bar. */} - -
- ); -} - -export default NavigationTest; diff --git a/src/routes/SearchBarTestRoute.tsx b/src/routes/SearchBarTestRoute.tsx deleted file mode 100644 index 8daeca4..0000000 --- a/src/routes/SearchBarTestRoute.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import SearchBar from "../components/SearchBar"; - -function SearchBarTest() { - return ( -
- - -
- ); -} - -export default SearchBarTest; diff --git a/src/routes/SortDropdownListTestRoute.tsx b/src/routes/SortDropdownListTestRoute.tsx deleted file mode 100644 index 6d359ea..0000000 --- a/src/routes/SortDropdownListTestRoute.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import DropdownItem from "../components/DropdownItem"; -import SortDropdownList from "../components/SortDropdownList"; - -function SortDropdownListTestRoute() { - return ( -
-
Hello
-
- Is this the sort dropdown list that you looking for?😩 -
-
- -
-
What happen If I do this?
-
- ); -} - -export default SortDropdownListTestRoute; diff --git a/src/routes/admin/AdminLogin.tsx b/src/routes/admin/AdminLogin.tsx new file mode 100644 index 0000000..858cb9a --- /dev/null +++ b/src/routes/admin/AdminLogin.tsx @@ -0,0 +1,79 @@ +//#region imports +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { ToastContainer, toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; + +import { initializeApp } from "firebase/app"; +import { getAuth, signInWithEmailAndPassword } from "firebase/auth"; + +import { LoginModal } from "@/components/LoginModal.js"; +import Toast from "@/components/Toast.js"; +//#endregion + +//#region firebase +// Initialize Firebase +const firebaseConfig = JSON.parse(import.meta.env.VITE_FIREBASE_CONFIG); +const app = initializeApp(firebaseConfig); + +// Initialize Firebase Authentication and get a reference to the service +const auth = getAuth(app); +//#endregion + +/** + * Admin login page + * @returns Admin login page with authentication functionality + */ +export default function AdminLogin() { + const navigate = useNavigate(); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + // sign in functionality + const signIn = () => { + signInWithEmailAndPassword(auth, email, password) + .then((userCredential) => { + const user = userCredential.user; + console.log("Signed in as: ", user.email); + navigate("/admin"); + }) + .catch((error) => { + console.log("Error signing in: ", error.code, error.message); + if (!toast.isActive("error")) + toast( + , + { + toastId: "error", + style: { + background: "transparent", + boxShadow: "none", + }, + }, + ); + }); + }; + + return ( +
+ + +
+ ); +} diff --git a/src/routes/ButtonTestRoute.tsx b/src/routes/test/ButtonTestRoute.tsx similarity index 100% rename from src/routes/ButtonTestRoute.tsx rename to src/routes/test/ButtonTestRoute.tsx diff --git a/src/routes/ColorPickerTestRoute.tsx b/src/routes/test/ColorPickerTestRoute.tsx similarity index 100% rename from src/routes/ColorPickerTestRoute.tsx rename to src/routes/test/ColorPickerTestRoute.tsx diff --git a/src/routes/GalleryTestRoute.tsx b/src/routes/test/GalleryTestRoute.tsx similarity index 100% rename from src/routes/GalleryTestRoute.tsx rename to src/routes/test/GalleryTestRoute.tsx diff --git a/src/routes/IconOptionTest.tsx b/src/routes/test/IconOptionTest.tsx similarity index 100% rename from src/routes/IconOptionTest.tsx rename to src/routes/test/IconOptionTest.tsx diff --git a/src/routes/test/ImageTestRoute.tsx b/src/routes/test/ImageTestRoute.tsx new file mode 100644 index 0000000..75db270 --- /dev/null +++ b/src/routes/test/ImageTestRoute.tsx @@ -0,0 +1,16 @@ +import Image from "@/components/Image"; +import Overlay from "@/components/Overlay"; +import old1 from "../../assets/images/old1.jpg"; + +function ImageTestRoute() { + return ( + + old + + ); +} + +export default ImageTestRoute; diff --git a/src/routes/InputCodeTest.tsx b/src/routes/test/InputCodeTest.tsx similarity index 100% rename from src/routes/InputCodeTest.tsx rename to src/routes/test/InputCodeTest.tsx diff --git a/src/routes/InputFieldTestRoute.tsx b/src/routes/test/InputFieldTestRoute.tsx similarity index 100% rename from src/routes/InputFieldTestRoute.tsx rename to src/routes/test/InputFieldTestRoute.tsx diff --git a/src/routes/MediaUploadStatusTestRoute.tsx b/src/routes/test/MediaUploadStatusTestRoute.tsx similarity index 100% rename from src/routes/MediaUploadStatusTestRoute.tsx rename to src/routes/test/MediaUploadStatusTestRoute.tsx diff --git a/src/routes/MediaUploadZoneTestRoute.tsx b/src/routes/test/MediaUploadZoneTestRoute.tsx similarity index 100% rename from src/routes/MediaUploadZoneTestRoute.tsx rename to src/routes/test/MediaUploadZoneTestRoute.tsx diff --git a/src/routes/MemberHeaderTestRoute.tsx b/src/routes/test/MemberHeaderTestRoute.tsx similarity index 100% rename from src/routes/MemberHeaderTestRoute.tsx rename to src/routes/test/MemberHeaderTestRoute.tsx diff --git a/src/routes/MemberProfilePictureTest.tsx b/src/routes/test/MemberProfilePictureTest.tsx similarity index 100% rename from src/routes/MemberProfilePictureTest.tsx rename to src/routes/test/MemberProfilePictureTest.tsx diff --git a/src/routes/MemberTableTestRoute.tsx b/src/routes/test/MemberTableTestRoute.tsx similarity index 100% rename from src/routes/MemberTableTestRoute.tsx rename to src/routes/test/MemberTableTestRoute.tsx diff --git a/src/routes/ModalTestRoute.tsx b/src/routes/test/ModalTestRoute.tsx similarity index 100% rename from src/routes/ModalTestRoute.tsx rename to src/routes/test/ModalTestRoute.tsx diff --git a/src/routes/test/NavigationTest.tsx b/src/routes/test/NavigationTest.tsx new file mode 100644 index 0000000..549a688 --- /dev/null +++ b/src/routes/test/NavigationTest.tsx @@ -0,0 +1,12 @@ +import { NavigationBar } from "../../components/NavigationBar"; + +function NavigationTest() { + return ( +
+ {/* Using margin or padding for the parent tag can break the navigation bar. */} + +
+ ); +} + +export default NavigationTest; diff --git a/src/routes/ProfilePictureTestRoute.tsx b/src/routes/test/ProfilePictureTestRoute.tsx similarity index 100% rename from src/routes/ProfilePictureTestRoute.tsx rename to src/routes/test/ProfilePictureTestRoute.tsx diff --git a/src/routes/test/SearchBarTestRoute.tsx b/src/routes/test/SearchBarTestRoute.tsx new file mode 100644 index 0000000..e95f606 --- /dev/null +++ b/src/routes/test/SearchBarTestRoute.tsx @@ -0,0 +1,12 @@ +import SearchBar from "../../components/SearchBar"; + +function SearchBarTest() { + return ( +
+ + +
+ ); +} + +export default SearchBarTest; diff --git a/src/routes/test/SortDropdownListTestRoute.tsx b/src/routes/test/SortDropdownListTestRoute.tsx new file mode 100644 index 0000000..874fc13 --- /dev/null +++ b/src/routes/test/SortDropdownListTestRoute.tsx @@ -0,0 +1,19 @@ +import DropdownItem from "../../components/DropdownItem"; +import SortDropdownList from "../../components/SortDropdownList"; + +function SortDropdownListTestRoute() { + return ( +
+
Hello
+
+ Is this the sort dropdown list that you looking for?😩 +
+
+ +
+
What happen If I do this?
+
+ ); +} + +export default SortDropdownListTestRoute; diff --git a/src/routes/Test.tsx b/src/routes/test/Test.tsx similarity index 100% rename from src/routes/Test.tsx rename to src/routes/test/Test.tsx diff --git a/src/routes/ToastTestRoute.tsx b/src/routes/test/ToastTestRoute.tsx similarity index 100% rename from src/routes/ToastTestRoute.tsx rename to src/routes/test/ToastTestRoute.tsx diff --git a/src/routes/TooltipTestRoute.tsx b/src/routes/test/TooltipTestRoute.tsx similarity index 100% rename from src/routes/TooltipTestRoute.tsx rename to src/routes/test/TooltipTestRoute.tsx