hide chat and accessibility buttons on mobile, add mobile action bar in footer #deploy

This commit is contained in:
martin 2026-01-24 19:01:07 +01:00
parent 012b465c30
commit c43ba0be83
5 changed files with 103 additions and 27 deletions

View File

@ -38,37 +38,20 @@
height: 52px !important;
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
bottom: 24px !important;
right: 120px !important;
right: 24px !important;
font-size: 22px !important;
position: fixed !important;
z-index: 9999 !important;
transform: none !important;
}
/* Mobile responsive positioning */
/* Hide chat button on mobile */
@media (max-width: 768px) {
html body div[class*="chat-button"],
html body div[class*="chat-launcher"],
html body button[aria-label*="chat"],
html body button[title*="chat"] {
right: 80px !important;
bottom: 24px !important;
width: 48px !important;
height: 48px !important;
font-size: 20px !important;
}
}
@media (max-width: 640px) {
html body div[class*="chat-button"],
html body div[class*="chat-launcher"],
html body button[aria-label*="chat"],
html body button[title*="chat"] {
right: 70px !important;
bottom: 24px !important;
width: 44px !important;
height: 44px !important;
font-size: 18px !important;
display: none !important;
}
}
</style>
@ -117,7 +100,7 @@
chatButtons.forEach(button => {
if (button) {
button.style.setProperty('bottom', '24px', 'important');
button.style.setProperty('right', '120px', 'important');
button.style.setProperty('right', '24px', 'important');
button.style.setProperty('position', 'fixed', 'important');
button.style.setProperty('z-index', '9999', 'important');
button.style.setProperty('transform', 'none', 'important');
@ -131,7 +114,7 @@
chatButtons.forEach(button => {
if (button) {
button.style.setProperty('bottom', '24px', 'important');
button.style.setProperty('right', '120px', 'important');
button.style.setProperty('right', '24px', 'important');
button.style.setProperty('position', 'fixed', 'important');
button.style.setProperty('z-index', '9999', 'important');
button.style.setProperty('transform', 'none', 'important');

View File

@ -49,7 +49,7 @@ const AccessibilityToggle = () => {
{/* Toggle Button */}
<Button
onClick={() => setIsOpen(!isOpen)}
className="fixed top-20 right-4 z-40 bg-blue-600 hover:bg-blue-700 text-white rounded-full p-3 shadow-lg md:right-4 sm:right-4"
className="fixed top-20 right-4 z-40 bg-blue-600 hover:bg-blue-700 text-white rounded-full p-3 shadow-lg hidden md:flex"
aria-label="Barrierefreiheitsoptionen"
>
{isOpen ? <X className="w-5 h-5" /> : <Accessibility className="w-5 h-5" />}

View File

@ -1,8 +1,10 @@
import { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { Phone, Mail, MapPin, Smartphone, Printer, Globe, Home, Shield, FileText, Truck, Link as LinkIcon } from 'lucide-react';
import { Phone, Mail, MapPin, Smartphone, Printer, Globe, Home, Shield, FileText, Truck, Link as LinkIcon, Accessibility, MessageCircle, ArrowUp } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { motion } from 'framer-motion';
import { Button } from '@/components/ui/button';
import AccessibilityBar from './AccessibilityBar';
const BrandFacebook = ({ className }: { className?: string }) => (
<svg viewBox="0 0 24 24" aria-hidden="true" className={className} fill="currentColor">
@ -32,6 +34,24 @@ const Footer = () => {
const { t } = useTranslation('footer');
const { t: tNav } = useTranslation('nav');
const baseUrl = import.meta.env.BASE_URL;
const [showToTop, setShowToTop] = useState(false);
// Scroll to top functionality
useEffect(() => {
const onScroll = () => {
setShowToTop(window.scrollY > 300);
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => {
window.removeEventListener('scroll', onScroll);
};
}, []);
// Accessibility toggle
const [isAccessibilityOpen, setIsAccessibilityOpen] = useState(false);
const storageKey = 'footerQuickLinkClicks';
const [clickCounts, setClickCounts] = useState<Record<string, number>>({});
@ -81,6 +101,63 @@ const Footer = () => {
return (
<footer className="bg-blue-50 border-t border-blue-100">
{/* Mobile Action Buttons */}
<div className="md:hidden bg-white border-b border-blue-100 sticky bottom-0 z-40">
<div className="container mx-auto px-4 py-3">
<div className="flex justify-around items-center gap-2">
<Button
asChild
variant="outline"
size="sm"
className="flex-1 h-10 text-xs bg-blue-600 text-white border-blue-600 hover:bg-blue-700"
>
<Link to="/contact#contact" className="flex items-center justify-center gap-1">
<Phone className="h-3 w-3" />
<span>Kontakt</span>
</Link>
</Button>
<Button
variant="outline"
size="sm"
className="flex-1 h-10 text-xs bg-blue-600 text-white border-blue-600 hover:bg-blue-700"
onClick={() => {
// Open n8n chat if available
const chatButton = document.querySelector('[class*="chat-button"], [class*="chat-launcher"], button[aria-label*="chat"], button[title*="chat"]') as HTMLElement;
if (chatButton) {
chatButton.click();
}
}}
>
<MessageCircle className="h-3 w-3 mr-1" />
<span>Chat</span>
</Button>
<Button
variant="outline"
size="sm"
className="flex-1 h-10 text-xs bg-blue-600 text-white border-blue-600 hover:bg-blue-700"
onClick={() => setIsAccessibilityOpen(!isAccessibilityOpen)}
>
<Accessibility className="h-3 w-3 mr-1" />
<span>A11y</span>
</Button>
{showToTop && (
<Button
variant="outline"
size="sm"
className="flex-1 h-10 text-xs bg-blue-600 text-white border-blue-600 hover:bg-blue-700"
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
>
<ArrowUp className="h-3 w-3 mr-1" />
<span>Top</span>
</Button>
)}
</div>
</div>
</div>
<div className="container mx-auto px-4 py-8">
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
{/* Logo & Description */}
@ -362,9 +439,16 @@ const Footer = () => {
</div>
</div>
{/* Mobile Accessibility Bar */}
{isAccessibilityOpen && (
<div className="md:hidden bg-white border-t border-blue-100">
<AccessibilityBar />
</div>
)}
<div className="border-t border-blue-100 mt-12 pt-8 text-center text-sm text-blue-950/70">
<p>{t('bottom.externalNotice', 'Externe Links: Wir sind nicht verantwortlich für Inhalte externer Webseiten.')}</p>
<p>© 2026. Agentur Mizera & Partner - {t('bottom.copyright', 'Alle Rechte vorbehalten.')}</p>
<p> 2026. Agentur Mizera & Partner - {t('bottom.copyright', 'Alle Rechte vorbehalten.')}</p>
</div>
</div>
</footer>

View File

@ -89,7 +89,10 @@ const Header = () => {
)}
</div>
<LanguageSwitcher />
{/* Language Switcher (Desktop only) */}
<div className="hidden md:block">
<LanguageSwitcher />
</div>
{/* Mobile menu button */}
<Button
@ -160,6 +163,12 @@ const Header = () => {
{isMenuOpen && (
<div className="md:hidden border-t py-4">
<nav className="flex flex-col space-y-2">
{/* Language Switcher (Mobile) */}
<div className="px-3 py-2 border-b border-gray-200">
<div className="text-xs font-medium text-gray-500 mb-2">Sprache / Language</div>
<LanguageSwitcher />
</div>
{[...navigation, ...rightMenuItems].map((item) => {
const Icon = item.icon;
const isActive = location.pathname === item.href;

View File

@ -102,7 +102,7 @@ const Layout = ({ children }: LayoutProps) => {
<AccessibilityToggle />
<div className="fixed bottom-6 right-6 z-50 flex flex-col items-end gap-3 md:bottom-6 md:right-6 sm:bottom-4 sm:right-4">
<div className="fixed bottom-6 right-6 z-50 flex flex-col items-end gap-3 hidden md:flex">
{showToTop ? (
<Button
type="button"