Skip to content
2 changes: 2 additions & 0 deletions src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import type { ReactNode } from "react";
import { SessionProvider } from "next-auth/react";
import { AccountProvider } from "@/components/AccountContext";
import { ThemeProvider } from "@/components/ThemeContext";
import BackToTopButton from "@/components/BackToTopButton";

export default function Providers({ children }: { children: ReactNode }) {
return (
<SessionProvider>
<AccountProvider>
<ThemeProvider>
{children}
<BackToTopButton />
</ThemeProvider>
</AccountProvider>
</SessionProvider>
Expand Down
63 changes: 63 additions & 0 deletions src/components/BackToTopButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use client";

import { useEffect, useState } from "react";

export default function BackToTopButton() {
const [isVisible, setIsVisible] = useState(false);

// Show button when page is scrolled down
const toggleVisibility = () => {
if (typeof window !== "undefined") {
setIsVisible(window.scrollY > 300);
}
};

// Smooth scroll to top
const scrollToTop = () => {
if (typeof window !== "undefined") {
window.scrollTo({
top: 0,
behavior: "smooth",
});
}
};

useEffect(() => {
if (typeof window !== "undefined") {
window.addEventListener("scroll", toggleVisibility);
return () => {
window.removeEventListener("scroll", toggleVisibility);
};
}
}, []);

return (
<>
{isVisible && (
<button
onClick={scrollToTop}
type="button"
aria-label="Scroll to top"
className="fixed bottom-8 right-8 z-50 flex h-12 w-12 items-center justify-center rounded-full bg-[var(--accent)] text-[var(--accent-foreground)] shadow-lg transition-all duration-300 hover:scale-110 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-[var(--accent)] focus:ring-offset-2 focus:ring-offset-[var(--background)]"
>
{/* Up Arrow SVG */}
<svg
className="h-6 w-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M7 16l-4-4m0 0l4-4m-4 4h18"
transform="rotate(90 12 12)"
/>
</svg>
</button>
)}
</>
);
}