181 lines
9.3 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Download, Share, Plus, MoreVertical, Smartphone } from 'lucide-react';
interface BeforeInstallPromptEvent extends Event {
prompt: () => Promise<void>;
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
}
export function InstallAppButton() {
const [showInstructions, setShowInstructions] = useState(false);
const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null);
const [isIOS, setIsIOS] = useState(false);
const [isAndroid, setIsAndroid] = useState(false);
const [isStandalone, setIsStandalone] = useState(false);
useEffect(() => {
// Check if already installed as PWA
const isAppInstalled = window.matchMedia('(display-mode: standalone)').matches ||
(window.navigator as Navigator & { standalone?: boolean }).standalone === true;
setIsStandalone(isAppInstalled);
// Detect platform
const userAgent = window.navigator.userAgent.toLowerCase();
const isIOSDevice = /iphone|ipad|ipod/.test(userAgent);
const isAndroidDevice = /android/.test(userAgent);
setIsIOS(isIOSDevice);
setIsAndroid(isAndroidDevice);
// Listen for beforeinstallprompt (Android/Chrome)
const handleBeforeInstallPrompt = (e: Event) => {
e.preventDefault();
setDeferredPrompt(e as BeforeInstallPromptEvent);
};
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
return () => {
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
};
}, []);
const handleInstallClick = async () => {
if (deferredPrompt) {
// Use the native install prompt (Android/Chrome)
await deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
if (outcome === 'accepted') {
setDeferredPrompt(null);
}
} else {
// Show manual instructions
setShowInstructions(true);
}
};
// Don't show if already installed as PWA
if (isStandalone) {
return null;
}
return (
<>
<Button
variant="outline"
size="sm"
onClick={handleInstallClick}
className="gap-2 border-purple-500/30 hover:bg-purple-500/10 hover:border-purple-500/50"
>
<Smartphone className="h-4 w-4 text-purple-400" />
<span className="hidden sm:inline">Add to Home Screen</span>
<span className="sm:hidden">Install</span>
</Button>
<Dialog open={showInstructions} onOpenChange={setShowInstructions}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Download className="h-5 w-5 text-purple-400" />
Add QuitTraq to Home Screen
</DialogTitle>
<DialogDescription>
Get quick access to track your progress right from your phone&apos;s home screen.
</DialogDescription>
</DialogHeader>
<div className="space-y-6 py-4">
{isIOS ? (
// iOS Instructions
<div className="space-y-4">
<p className="text-sm font-medium text-purple-400">For iPhone / iPad (Safari):</p>
<ol className="space-y-4 text-sm">
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">1</span>
<div>
<p>Tap the <strong>Share</strong> button</p>
<div className="mt-1 inline-flex items-center gap-1 rounded bg-muted px-2 py-1">
<Share className="h-4 w-4" />
</div>
</div>
</li>
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">2</span>
<div>
<p>Scroll down and tap <strong>&quot;Add to Home Screen&quot;</strong></p>
<div className="mt-1 inline-flex items-center gap-1 rounded bg-muted px-2 py-1">
<Plus className="h-4 w-4" /> Add to Home Screen
</div>
</div>
</li>
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">3</span>
<p>Tap <strong>&quot;Add&quot;</strong> to confirm</p>
</li>
</ol>
</div>
) : isAndroid ? (
// Android Instructions
<div className="space-y-4">
<p className="text-sm font-medium text-purple-400">For Android (Chrome):</p>
<ol className="space-y-4 text-sm">
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">1</span>
<div>
<p>Tap the <strong>menu</strong> button (3 dots)</p>
<div className="mt-1 inline-flex items-center gap-1 rounded bg-muted px-2 py-1">
<MoreVertical className="h-4 w-4" />
</div>
</div>
</li>
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">2</span>
<div>
<p>Tap <strong>&quot;Add to Home screen&quot;</strong> or <strong>&quot;Install app&quot;</strong></p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-purple-500/20 text-purple-400 text-xs font-bold">3</span>
<p>Tap <strong>&quot;Add&quot;</strong> or <strong>&quot;Install&quot;</strong> to confirm</p>
</li>
</ol>
</div>
) : (
// Desktop / Unknown
<div className="space-y-4">
<p className="text-sm font-medium text-purple-400">On mobile device:</p>
<ul className="space-y-2 text-sm text-muted-foreground">
<li> <strong>iPhone/iPad:</strong> Use Safari, tap Share Add to Home Screen</li>
<li> <strong>Android:</strong> Use Chrome, tap Menu Add to Home screen</li>
</ul>
<p className="text-xs text-muted-foreground mt-4">
Open this page on your phone to add QuitTraq to your home screen for quick access!
</p>
</div>
)}
<div className="pt-2 border-t">
<p className="text-xs text-muted-foreground text-center">
📱 Once added, tap the QuitTraq icon to quickly log your usage!
</p>
</div>
</div>
<Button onClick={() => setShowInstructions(false)} className="w-full">
Got it!
</Button>
</DialogContent>
</Dialog>
</>
);
}