From b0ec45a8495041cdff92de998194063e7bb4a1b0 Mon Sep 17 00:00:00 2001 From: krishnendu07-code Date: Sat, 13 Jun 2026 16:30:18 +0530 Subject: [PATCH 1/2] feat: add back to top button --- src/App.tsx | 54 ++++++++++++++++-------------- src/components/BackToTopButton.tsx | 39 +++++++++++++++++++++ 2 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 src/components/BackToTopButton.tsx diff --git a/src/App.tsx b/src/App.tsx index cf051cb..28a58d8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,43 +1,45 @@ import { useState, useEffect } from "react"; import OnboardingTour from "./components/OnboardingTour"; -import { BrowserRouter, Routes, Route } from 'react-router-dom'; -import { Toaster } from 'react-hot-toast'; -import Layout from './components/Layout'; -import LandingPage from './pages/LandingPage'; -import AuthPage from './pages/AuthPage'; -import ModeSelectPage from './pages/ModeSelectPage'; -import ScannerPage from './pages/ScannerPage'; -import AnalysisDashboard from './pages/AnalysisDashboard'; -import MarketMapPage from './pages/MarketMapPage'; -import ResultsPage from './pages/ResultsPage'; -import Leaderboard from './pages/Leaderboard'; -import PostHogPageView from './components/PostHogPageView'; -import NotFound from './pages/NotFound'; -import InstallPrompt from './components/InstallPrompt'; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import { Toaster } from "react-hot-toast"; +import Layout from "./components/Layout"; +import LandingPage from "./pages/LandingPage"; +import AuthPage from "./pages/AuthPage"; +import ModeSelectPage from "./pages/ModeSelectPage"; +import ScannerPage from "./pages/ScannerPage"; +import AnalysisDashboard from "./pages/AnalysisDashboard"; +import MarketMapPage from "./pages/MarketMapPage"; +import ResultsPage from "./pages/ResultsPage"; +import Leaderboard from "./pages/Leaderboard"; +import PostHogPageView from "./components/PostHogPageView"; +import NotFound from "./pages/NotFound"; +import InstallPrompt from "./components/InstallPrompt"; import PublicReport from "./pages/PublicReport"; +import BackToTopButton from "./components/BackToTopButton"; export default function App() { const [runTour, setRunTour] = useState(false); -useEffect(() => { - const completed = localStorage.getItem("tour-completed"); + useEffect(() => { + const completed = localStorage.getItem("tour-completed"); - if (!completed) { - setTimeout(() => { - setRunTour(true); - localStorage.setItem("tour-completed", "true"); - }, 0); - } -}, []); + if (!completed) { + setTimeout(() => { + setRunTour(true); + localStorage.setItem("tour-completed", "true"); + }, 0); + } + }, []); return ( {/* Toast provider for global error notifications */} - + {/* Fires a $pageview event to PostHog on every SPA route change */} + }> } /> @@ -48,7 +50,7 @@ useEffect(() => { } /> } /> } /> - + {/* Public shareable report — MUST be before the * catchall */} } /> @@ -58,4 +60,4 @@ useEffect(() => { ); -} \ No newline at end of file +} diff --git a/src/components/BackToTopButton.tsx b/src/components/BackToTopButton.tsx new file mode 100644 index 0000000..450fa5b --- /dev/null +++ b/src/components/BackToTopButton.tsx @@ -0,0 +1,39 @@ +import { useEffect, useState } from "react"; +import { ArrowUp } from "lucide-react"; + +export default function BackToTopButton() { + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + const toggleVisibility = () => { + setIsVisible(window.scrollY > 300); + }; + + window.addEventListener("scroll", toggleVisibility); + toggleVisibility(); + + return () => window.removeEventListener("scroll", toggleVisibility); + }, []); + + const scrollToTop = () => { + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + }; + + return ( + + ); +} From 35560d2d6d42d1793bbf11096858a31e343424cb Mon Sep 17 00:00:00 2001 From: krishnendu07-code Date: Sat, 13 Jun 2026 16:43:20 +0530 Subject: [PATCH 2/2] fix: improve back to top button accessibility --- src/components/BackToTopButton.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/BackToTopButton.tsx b/src/components/BackToTopButton.tsx index 450fa5b..1ae4a23 100644 --- a/src/components/BackToTopButton.tsx +++ b/src/components/BackToTopButton.tsx @@ -27,6 +27,9 @@ export default function BackToTopButton() { type="button" onClick={scrollToTop} aria-label="Back to top" + disabled={!isVisible} + tabIndex={isVisible ? 0 : -1} + aria-hidden={!isVisible} className={`fixed bottom-6 right-6 z-50 flex h-12 w-12 items-center justify-center rounded-full border border-primary/40 bg-surface/90 text-primary shadow-lg shadow-primary/20 backdrop-blur transition-all duration-300 hover:-translate-y-1 hover:bg-primary hover:text-on-primary hover:shadow-primary/40 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 ${ isVisible ? "translate-y-0 opacity-100"