diff --git a/client/src/App.tsx b/client/src/App.tsx index f3280bd..bf45651 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -21,6 +21,7 @@ import KontaktPage from "@/pages/kontakt"; import AdminGalleryPage from "@/pages/admin-gallery"; import AdminPushPage from "@/pages/admin-push"; import CookieConsent from "@/components/cookie-consent"; +import MobileStickyAd from "@/components/mobile-sticky-ad"; function ScrollToTop() { const [location] = useLocation(); @@ -63,6 +64,7 @@ function App() { + ); diff --git a/client/src/components/footer.tsx b/client/src/components/footer.tsx index c915918..593585a 100644 --- a/client/src/components/footer.tsx +++ b/client/src/components/footer.tsx @@ -1,5 +1,6 @@ import { Link } from "wouter"; import { SiFacebook, SiInstagram, SiYoutube, SiTiktok } from "react-icons/si"; +import { useIsMobile } from "@/hooks/use-mobile"; const SOCIAL_LINKS = [ { href: "https://www.facebook.com/folxtv/", icon: SiFacebook, label: "Facebook", testId: "link-social-facebook" }, @@ -8,7 +9,13 @@ const SOCIAL_LINKS = [ { href: "https://www.tiktok.com/@folxtv", icon: SiTiktok, label: "TikTok", testId: "link-social-tiktok" }, ]; +const STICKY_AD_DISMISS_KEY = "folx-sticky-ad-dismissed"; + export default function Footer({ narrow }: { narrow?: boolean }) { + const isMobile = useIsMobile(); + const stickyAdDismissed = typeof window !== "undefined" && sessionStorage.getItem(STICKY_AD_DISMISS_KEY); + const showStickyPadding = isMobile && !stickyAdDismissed; + return ( ); } diff --git a/client/src/components/mobile-sticky-ad.tsx b/client/src/components/mobile-sticky-ad.tsx new file mode 100644 index 0000000..4ca4df5 --- /dev/null +++ b/client/src/components/mobile-sticky-ad.tsx @@ -0,0 +1,51 @@ +import { useState, useEffect } from "react"; +import { X } from "lucide-react"; +import { useIsMobile } from "@/hooks/use-mobile"; +import AdSense from "./adsense"; + +const DISMISS_KEY = "folx-sticky-ad-dismissed"; + +export default function MobileStickyAd() { + const isMobile = useIsMobile(); + const [visible, setVisible] = useState(false); + + useEffect(() => { + if (!isMobile) return; + const dismissed = sessionStorage.getItem(DISMISS_KEY); + if (dismissed) return; + + const timer = setTimeout(() => setVisible(true), 2000); + return () => clearTimeout(timer); + }, [isMobile]); + + const close = () => { + setVisible(false); + sessionStorage.setItem(DISMISS_KEY, "1"); + }; + + if (!isMobile || !visible) return null; + + return ( +
+
+ +
Anzeige
+
+ +
+
+
+ ); +} diff --git a/replit.md b/replit.md index d8b1549..669999e 100644 --- a/replit.md +++ b/replit.md @@ -30,6 +30,7 @@ The official website for Folx Music Television (folx.tv). Dark-themed bento grid - Google AdSense integration (ca-pub-4465464714854276) - Interstitial overlay ad on article pages (3s delay, shows every other article visit, sessionStorage counter) - Parallax/reveal ad below article content (sticky background ad revealed on scroll) +- Mobile sticky banner ad at bottom of screen (2s delay, session-dismissible, mobile-only via useIsMobile hook) - Web Push Notifications (bell icon in header, auto-send on new articles, admin panel at /admin/push) - Article listing with featured carousel and category filtering - HTML content supports embedded iframes (bunny.net, YouTube, Facebook, Instagram, TikTok)