From 3ed505bcf37d93340e1e6c683392b5fca65d84ab Mon Sep 17 00:00:00 2001
From: emmalynf <efoster@unc.edu>
Date: Fri, 15 Nov 2024 21:33:13 -0500
Subject: [PATCH] loading for sign out

---
 compass/app/home/layout.tsx                   |  4 +++
 .../components/Sidebar/LoadingIcon.module.css | 20 ++++++++++++
 compass/components/Sidebar/LoadingIcon.tsx    | 14 +++++++++
 compass/components/Sidebar/Sidebar.tsx        | 22 ++++++++++---
 compass/components/resource/UserProfile.tsx   | 31 ++++++-------------
 5 files changed, 64 insertions(+), 27 deletions(-)
 create mode 100644 compass/components/Sidebar/LoadingIcon.module.css
 create mode 100644 compass/components/Sidebar/LoadingIcon.tsx

diff --git a/compass/app/home/layout.tsx b/compass/app/home/layout.tsx
index 236616e..ec67157 100644
--- a/compass/app/home/layout.tsx
+++ b/compass/app/home/layout.tsx
@@ -15,6 +15,8 @@ export default function RootLayout({
     const [isSidebarOpen, setIsSidebarOpen] = useState(true);
     const [user, setUser] = useState<User>();
     const router = useRouter();
+    const [loading, setLoading] = useState(true); 
+
 
     useEffect(() => {
         async function getUser() {
@@ -35,6 +37,7 @@ export default function RootLayout({
             );
 
             setUser(await userData.json());
+            setLoading(false);
         }
 
         getUser();
@@ -50,6 +53,7 @@ export default function RootLayout({
                         setIsSidebarOpen={setIsSidebarOpen}
                         isSidebarOpen={isSidebarOpen}
                         isAdmin={user.role === Role.ADMIN}
+                        loading={loading}
                     />
                     <div
                         className={`flex-1 transition duration-300 ease-in-out ${
diff --git a/compass/components/Sidebar/LoadingIcon.module.css b/compass/components/Sidebar/LoadingIcon.module.css
new file mode 100644
index 0000000..2b0c9d2
--- /dev/null
+++ b/compass/components/Sidebar/LoadingIcon.module.css
@@ -0,0 +1,20 @@
+/* components/LoadingIcon.module.css */
+.loader {
+    width: 24px; /* Larger for better visibility */
+    height: 24px;
+    border: 4px solid #5b21b6; /* Primary color */
+    border-top: 4px solid #ffffff; /* Contrasting color */
+    border-radius: 50%;
+    animation: spin 1s linear infinite; /* Smooth continuous spin */
+    margin-bottom: 20px;
+}
+
+
+@keyframes spin {
+    0% {
+        transform: rotate(0deg); /* Start position */
+    }
+    100% {
+        transform: rotate(360deg); /* Full rotation */
+    }
+}
diff --git a/compass/components/Sidebar/LoadingIcon.tsx b/compass/components/Sidebar/LoadingIcon.tsx
new file mode 100644
index 0000000..ddf3eb3
--- /dev/null
+++ b/compass/components/Sidebar/LoadingIcon.tsx
@@ -0,0 +1,14 @@
+// components/Loading.js
+import styles from "./LoadingIcon.module.css";
+
+const LoadingIcon = () => {
+    return (
+        <div className={styles.loadingOverlay}>
+            <div className={styles.loadingContent}>
+                <div className={styles.loader}></div>
+            </div>
+        </div>
+    );
+};
+
+export default LoadingIcon;
\ No newline at end of file
diff --git a/compass/components/Sidebar/Sidebar.tsx b/compass/components/Sidebar/Sidebar.tsx
index d82ab69..232eda7 100644
--- a/compass/components/Sidebar/Sidebar.tsx
+++ b/compass/components/Sidebar/Sidebar.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useState } from "react";
 import {
     HomeIcon,
     ChevronDoubleLeftIcon,
@@ -9,7 +9,9 @@ import {
     LockClosedIcon,
 } from "@heroicons/react/24/solid";
 import { SidebarItem } from "./SidebarItem";
+import styles from "./LoadingIcon.module.css"
 import { UserProfile } from "../resource/UserProfile";
+import LoadingIcon from "./LoadingIcon";
 
 interface SidebarProps {
     setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
@@ -17,6 +19,7 @@ interface SidebarProps {
     name: string;
     email: string;
     isAdmin: boolean;
+    loading: boolean;
 }
 
 const Sidebar: React.FC<SidebarProps> = ({
@@ -25,7 +28,9 @@ const Sidebar: React.FC<SidebarProps> = ({
     name,
     email,
     isAdmin: admin,
+    loading,
 }) => {
+    const [isLoading, setIsLoading] = useState(false);
     return (
         <>
             {/* Button to open the sidebar. */}
@@ -62,11 +67,18 @@ const Sidebar: React.FC<SidebarProps> = ({
                     </button>
                 </div>
 
-                <div className="flex flex-col space-y-8">
-                    {/* user + logout button  */}
-                    <div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
-                        <UserProfile name={name} email={email} />
+                   {/* Loading indicator*/}
+                   {isLoading && (
+                    <div className="fixed top-2 left-2">
+                        <LoadingIcon/>{/* Spinner */}
                     </div>
+                )}
+
+                <div className="flex flex-col space-y-8">
+                    <div className="flex items-center p-4 space-x-2 border rounded-md">
+                        <UserProfile name={name} email={email} setLoading={setIsLoading} />
+                    </div>
+
                     {/* navigation menu  */}
                     <div className="flex flex-col space-y-2">
                         <h4 className="text-xs font-semibold text-gray-500">
diff --git a/compass/components/resource/UserProfile.tsx b/compass/components/resource/UserProfile.tsx
index ee88eae..3d9f544 100644
--- a/compass/components/resource/UserProfile.tsx
+++ b/compass/components/resource/UserProfile.tsx
@@ -1,49 +1,36 @@
 import { useState } from "react";
 import { signOut } from "@/app/auth/actions";
-import LoggingOut from "../auth/LoggingOut";
 
 interface UserProfileProps {
     name: string;
     email: string;
+    setLoading: React.Dispatch<React.SetStateAction<boolean>>;
 }
 
 const handleClick = async (
     event: React.MouseEvent<HTMLButtonElement>,
     setLoading: React.Dispatch<React.SetStateAction<boolean>>
 ) => {
-    setLoading(true);  // Set loading state to true
-
-    // Call signOut and wait for the process to complete before redirecting
+    setLoading(true);  // Set loading to true
     await signOut();
-
-    // Once signOut is complete, the redirect should happen, but let's delay it to allow the loading state to be visible for a short time
-    setTimeout(() => {
-        // The signOut already handles the redirect, so we don't need to redirect here again.
-        setLoading(false);  // Reset the loading state after the timeout (just in case)
-    }, 1000);  // You can adjust this delay as needed
+    setLoading(false);  // Reset loading after sign-out completes
 };
 
-export const UserProfile = ({ name, email }: UserProfileProps) => {
-    const [loading, setLoading] = useState(false);
-
-    if (loading) {
-        // Show the "Logging out" screen while the sign-out process is in progress
-        return <LoggingOut />;
-    }
-
+export const UserProfile = ({ name, email, setLoading }: UserProfileProps) => {
     return (
         <div className="flex flex-col items-start space-y-2">
             <div className="flex flex-col">
-                <span className="text-sm font-semibold text-gray-800">{name}</span>
+                <span className="text-sm font-semibold text-gray-800">
+                    {name}
+                </span>
                 <span className="text-xs text-gray-500">{email}</span>
             </div>
             <button
                 onClick={(event) => handleClick(event, setLoading)}
                 className="text-red-600 font-semibold text-xs hover:underline mt-1"
-                disabled={loading} // Disable button while loading
             >
-                 {loading ? "Signing out..." : "Sign out"} {/* Show appropriate text */}
+                Sign out
             </button>
         </div>
     );
-};
\ No newline at end of file
+};