diff --git a/src/App.css b/src/App.css index f161c39..48b6cc8 100644 --- a/src/App.css +++ b/src/App.css @@ -2689,3 +2689,55 @@ body[data-theme='light'] .console-separator::after { background: #3b82f6 !important; /* Standout blue badge for activities */ } +/* Scroll To Top Button */ + +.scroll-to-top { + position: fixed; + bottom: 24px; + right: 24px; + + width: 52px; + height: 52px; + + border: none; + border-radius: 50%; + + background: var(--aside-bg); + color: var(--text-color); + + cursor: pointer; + + display: flex; + align-items: center; + justify-content: center; + + box-shadow: 0 4px 12px var(--box-shadow); + + z-index: 999; + + transition: + transform 0.2s ease, + background 0.2s ease, + color 0.2s ease; +} + +.scroll-to-top:hover { + transform: translateY(-3px); + background: #4aed88; + color: #1c1e29; +} + +.scroll-to-top:active { + transform: scale(0.95); +} + +/* Mobile */ + +@media (max-width: 768px) { + .scroll-to-top { + width: 46px; + height: 46px; + bottom: 18px; + right: 18px; + } +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 8d1a809..5c460f0 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,7 @@ import NotFound from './pages/NotFound'; import {Toaster} from "react-hot-toast"; import LandingPage from './pages/LandingPage'; import ErrorBoundary from './components/ErrorBoundary'; +import ScrollToTopButton from "./components/ScrollToTopButton"; function App() { return ( @@ -33,6 +34,7 @@ function App() { }> }> + ); diff --git a/src/components/ScrollToTopButton.jsx b/src/components/ScrollToTopButton.jsx new file mode 100644 index 0000000..98e485b --- /dev/null +++ b/src/components/ScrollToTopButton.jsx @@ -0,0 +1,38 @@ +import { useEffect, useState } from "react"; +import { ChevronUp } from "lucide-react"; + +function ScrollToTop() { + const [visible, setVisible] = useState(false); + + useEffect(() => { + const toggleVisibility = () => { + setVisible(window.scrollY > 300); + }; + + window.addEventListener("scroll", toggleVisibility); + + return () => + window.removeEventListener("scroll", toggleVisibility); + }, []); + + const scrollToTop = () => { + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + }; + + if (!visible) return null; + + return ( + + ); +} + +export default ScrollToTop; \ No newline at end of file