diff --git a/src/App.jsx b/src/App.jsx index 04b0a21..067ae8b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,13 +2,14 @@ import { BrowserRouter } from 'react-router-dom'; import { ThemeProvider } from './hooks/useTheme'; import { ToastProvider } from './components/ui/Toast'; import AppRoutes from './routes/AppRoutes'; - +import ScrollToTop from "./components/ui/ScrollToTop"; export default function App() { return ( + diff --git a/src/components/ui/ScrollToTop.jsx b/src/components/ui/ScrollToTop.jsx new file mode 100644 index 0000000..bade780 --- /dev/null +++ b/src/components/ui/ScrollToTop.jsx @@ -0,0 +1,44 @@ +import { useEffect, useState } from "react"; + +function ScrollToTop() { + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + const toggleVisibility = () => { + if (window.scrollY > 300) { + setIsVisible(true); + } else { + setIsVisible(false); + } + }; + + window.addEventListener("scroll", toggleVisibility); + + return () => { + window.removeEventListener("scroll", toggleVisibility); + }; + }, []); + + const scrollToTop = () => { + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + }; + + return ( + <> + {isVisible && ( + + )} + + ); +} + +export default ScrollToTop; \ No newline at end of file diff --git a/src/styles/index.css b/src/styles/index.css index 992732a..745f946 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -3556,3 +3556,24 @@ body.light-mode .gh-preview { .faq-question { font-size: 14px; padding: 16px; } .faq-answer { padding: 0 16px 16px; padding-top: 12px; } } + +.scroll-to-top { + position: fixed; + bottom: 24px; + right: 24px; + width: 56px; + height: 56px; + border: none; + border-radius: 50%; + background: linear-gradient(135deg, #38bdf8, #2563eb); + color: white; + font-size: 26px; + cursor: pointer; + z-index: 1000; + box-shadow: 0 0 20px rgba(56, 189, 248, 0.5); + transition: all 0.3s ease; +} + +.scroll-to-top:hover { + transform: translateY(-4px) scale(1.05); +} \ No newline at end of file