mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-20 18:40:17 -04:00
loading for sign out
This commit is contained in:
parent
e1fd04f963
commit
3ed505bcf3
|
@ -15,6 +15,8 @@ export default function RootLayout({
|
||||||
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
|
||||||
const [user, setUser] = useState<User>();
|
const [user, setUser] = useState<User>();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getUser() {
|
async function getUser() {
|
||||||
|
@ -35,6 +37,7 @@ export default function RootLayout({
|
||||||
);
|
);
|
||||||
|
|
||||||
setUser(await userData.json());
|
setUser(await userData.json());
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUser();
|
getUser();
|
||||||
|
@ -50,6 +53,7 @@ export default function RootLayout({
|
||||||
setIsSidebarOpen={setIsSidebarOpen}
|
setIsSidebarOpen={setIsSidebarOpen}
|
||||||
isSidebarOpen={isSidebarOpen}
|
isSidebarOpen={isSidebarOpen}
|
||||||
isAdmin={user.role === Role.ADMIN}
|
isAdmin={user.role === Role.ADMIN}
|
||||||
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`flex-1 transition duration-300 ease-in-out ${
|
className={`flex-1 transition duration-300 ease-in-out ${
|
||||||
|
|
20
compass/components/Sidebar/LoadingIcon.module.css
Normal file
20
compass/components/Sidebar/LoadingIcon.module.css
Normal file
|
@ -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 */
|
||||||
|
}
|
||||||
|
}
|
14
compass/components/Sidebar/LoadingIcon.tsx
Normal file
14
compass/components/Sidebar/LoadingIcon.tsx
Normal file
|
@ -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;
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import {
|
import {
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
ChevronDoubleLeftIcon,
|
ChevronDoubleLeftIcon,
|
||||||
|
@ -9,7 +9,9 @@ import {
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
} from "@heroicons/react/24/solid";
|
} from "@heroicons/react/24/solid";
|
||||||
import { SidebarItem } from "./SidebarItem";
|
import { SidebarItem } from "./SidebarItem";
|
||||||
|
import styles from "./LoadingIcon.module.css"
|
||||||
import { UserProfile } from "../resource/UserProfile";
|
import { UserProfile } from "../resource/UserProfile";
|
||||||
|
import LoadingIcon from "./LoadingIcon";
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
@ -17,6 +19,7 @@ interface SidebarProps {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Sidebar: React.FC<SidebarProps> = ({
|
const Sidebar: React.FC<SidebarProps> = ({
|
||||||
|
@ -25,7 +28,9 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
isAdmin: admin,
|
isAdmin: admin,
|
||||||
|
loading,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Button to open the sidebar. */}
|
{/* Button to open the sidebar. */}
|
||||||
|
@ -62,11 +67,18 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col space-y-8">
|
{/* Loading indicator*/}
|
||||||
{/* user + logout button */}
|
{isLoading && (
|
||||||
<div className="flex items-center p-4 space-x-2 border border-gray-200 rounded-md ">
|
<div className="fixed top-2 left-2">
|
||||||
<UserProfile name={name} email={email} />
|
<LoadingIcon/>{/* Spinner */}
|
||||||
</div>
|
</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 */}
|
{/* navigation menu */}
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
<h4 className="text-xs font-semibold text-gray-500">
|
<h4 className="text-xs font-semibold text-gray-500">
|
||||||
|
|
|
@ -1,48 +1,35 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { signOut } from "@/app/auth/actions";
|
import { signOut } from "@/app/auth/actions";
|
||||||
import LoggingOut from "../auth/LoggingOut";
|
|
||||||
|
|
||||||
interface UserProfileProps {
|
interface UserProfileProps {
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = async (
|
const handleClick = async (
|
||||||
event: React.MouseEvent<HTMLButtonElement>,
|
event: React.MouseEvent<HTMLButtonElement>,
|
||||||
setLoading: React.Dispatch<React.SetStateAction<boolean>>
|
setLoading: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
) => {
|
) => {
|
||||||
setLoading(true); // Set loading state to true
|
setLoading(true); // Set loading to true
|
||||||
|
|
||||||
// Call signOut and wait for the process to complete before redirecting
|
|
||||||
await signOut();
|
await signOut();
|
||||||
|
setLoading(false); // Reset loading after sign-out completes
|
||||||
// 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserProfile = ({ name, email }: UserProfileProps) => {
|
export const UserProfile = ({ name, email, setLoading }: UserProfileProps) => {
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
// Show the "Logging out" screen while the sign-out process is in progress
|
|
||||||
return <LoggingOut />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-start space-y-2">
|
<div className="flex flex-col items-start space-y-2">
|
||||||
<div className="flex flex-col">
|
<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>
|
<span className="text-xs text-gray-500">{email}</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={(event) => handleClick(event, setLoading)}
|
onClick={(event) => handleClick(event, setLoading)}
|
||||||
className="text-red-600 font-semibold text-xs hover:underline mt-1"
|
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>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user