From 3e468d8885f514bd661ba86103654a8330bdefbc Mon Sep 17 00:00:00 2001 From: Michael SCHAL Date: Fri, 6 Feb 2026 15:28:24 +0100 Subject: [PATCH] style(web): improve ArticleCard UX and add Back to Top button --- web/src/components/ArticleCard.tsx | 4 ++-- web/src/pages/DashboardPage.tsx | 33 +++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/web/src/components/ArticleCard.tsx b/web/src/components/ArticleCard.tsx index 32ff22e..1553754 100644 --- a/web/src/components/ArticleCard.tsx +++ b/web/src/components/ArticleCard.tsx @@ -49,10 +49,10 @@ export function ArticleCard({ article, onClick, onToggleRead, onToggleFavorite } {/* Meta on top of image */}
- + {article.feed_title || 'Journal'} - + {timeToRead} min
diff --git a/web/src/pages/DashboardPage.tsx b/web/src/pages/DashboardPage.tsx index 9c0fca8..39e5aa3 100644 --- a/web/src/pages/DashboardPage.tsx +++ b/web/src/pages/DashboardPage.tsx @@ -125,6 +125,26 @@ export function DashboardPage({ selectedFeedId }: DashboardPageProps) { onSuccess: () => queryClient.invalidateQueries({ queryKey: ['articles'] }), }); + const [showScrollTop, setShowScrollTop] = useState(false); + const mainRef = useRef(null); + + // Visibility logic for "Back to Top" button + useEffect(() => { + const handleScroll = (e: Event) => { + const target = e.target as HTMLElement; + setShowScrollTop(target.scrollTop > 1000); + }; + const mainElement = mainRef.current; + if (mainElement) { + mainElement.addEventListener('scroll', handleScroll); + } + return () => mainElement?.removeEventListener('scroll', handleScroll); + }, []); + + const scrollToTop = () => { + mainRef.current?.scrollTo({ top: 0, behavior: 'smooth' }); + }; + if (isLoading) { return (
@@ -135,7 +155,18 @@ export function DashboardPage({ selectedFeedId }: DashboardPageProps) { } return ( -
+
+ {/* Back to Top Button */} + +
{/* Header */}