Spaces:
Paused
Paused
| import { useState, useEffect } from 'react'; | |
| import { Download, Check } from 'lucide-react'; | |
| import { Button } from '@/components/ui/button'; | |
| import { Link } from 'react-router-dom'; | |
| import { | |
| Tooltip, | |
| TooltipContent, | |
| TooltipTrigger, | |
| } from '@/components/ui/tooltip'; | |
| interface BeforeInstallPromptEvent extends Event { | |
| prompt: () => Promise<void>; | |
| userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>; | |
| } | |
| export function InstallButton() { | |
| const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null); | |
| const [isInstalled, setIsInstalled] = useState(false); | |
| const [isIOS, setIsIOS] = useState(false); | |
| useEffect(() => { | |
| // Check if already installed | |
| if (window.matchMedia('(display-mode: standalone)').matches) { | |
| setIsInstalled(true); | |
| return; | |
| } | |
| // Check if iOS | |
| setIsIOS(/iPad|iPhone|iPod/.test(navigator.userAgent)); | |
| // Listen for install prompt | |
| const handler = (e: Event) => { | |
| e.preventDefault(); | |
| setDeferredPrompt(e as BeforeInstallPromptEvent); | |
| }; | |
| window.addEventListener('beforeinstallprompt', handler); | |
| // Listen for successful install | |
| window.addEventListener('appinstalled', () => setIsInstalled(true)); | |
| return () => { | |
| window.removeEventListener('beforeinstallprompt', handler); | |
| }; | |
| }, []); | |
| const handleInstall = async () => { | |
| if (!deferredPrompt) return; | |
| await deferredPrompt.prompt(); | |
| const { outcome } = await deferredPrompt.userChoice; | |
| if (outcome === 'accepted') { | |
| setIsInstalled(true); | |
| } | |
| setDeferredPrompt(null); | |
| }; | |
| // Already installed - show check mark | |
| if (isInstalled) { | |
| return ( | |
| <Tooltip> | |
| <TooltipTrigger asChild> | |
| <Button variant="ghost" size="sm" className="text-green-500" disabled> | |
| <Check className="w-4 h-4" /> | |
| </Button> | |
| </TooltipTrigger> | |
| <TooltipContent> | |
| <p>App installeret</p> | |
| </TooltipContent> | |
| </Tooltip> | |
| ); | |
| } | |
| // Can prompt directly (Chrome/Edge) | |
| if (deferredPrompt) { | |
| return ( | |
| <Tooltip> | |
| <TooltipTrigger asChild> | |
| <Button | |
| variant="ghost" | |
| size="sm" | |
| onClick={handleInstall} | |
| className="text-primary hover:text-primary hover:bg-primary/10" | |
| > | |
| <Download className="w-4 h-4" /> | |
| </Button> | |
| </TooltipTrigger> | |
| <TooltipContent> | |
| <p>Installer app</p> | |
| </TooltipContent> | |
| </Tooltip> | |
| ); | |
| } | |
| // iOS or other - link to install page | |
| return ( | |
| <Tooltip> | |
| <TooltipTrigger asChild> | |
| <Link to="/install"> | |
| <Button | |
| variant="ghost" | |
| size="sm" | |
| className="text-muted-foreground hover:text-primary" | |
| > | |
| <Download className="w-4 h-4" /> | |
| </Button> | |
| </Link> | |
| </TooltipTrigger> | |
| <TooltipContent> | |
| <p>{isIOS ? 'Installer på iPhone' : 'Installer app'}</p> | |
| </TooltipContent> | |
| </Tooltip> | |
| ); | |
| } | |