1 import { useState, useEffect } from "react";
2 import { Button } from "@/components/ui/button";
3 import { Card, CardContent } from "@/components/ui/card";
4 import { installPWA, isPWAInstalled } from "@/pwa-utils";
5 import { X, Download } from "lucide-react";
6
7 export function InstallBanner() {
8 const [showBanner, setShowBanner] = useState(false);
9 const [isInstalled, setIsInstalled] = useState(false);
10
11 useEffect(() => {
12 // Check if PWA is already installed
13 const installed = isPWAInstalled();
14 setIsInstalled(installed);
15
16 // Show banner if not installed and installation is supported
17 if (!installed && 'serviceWorker' in navigator) {
18 // Wait a bit before showing the banner
19 const timer = setTimeout(() => {
20 setShowBanner(true);
21 }, 3000);
22
23 return () => clearTimeout(timer);
24 }
25 }, []);
26
27 const handleInstall = async () => {
28 try {
29 await installPWA();
30 setShowBanner(false);
31 } catch (error) {
32 console.error('Installation failed:', error);
33 }
34 };
35
36 const handleDismiss = () => {
37 setShowBanner(false);
38 // Remember user dismissed the banner
39 localStorage.setItem('pwa-banner-dismissed', 'true');
40 };
41
42 // Don't show if already installed or user dismissed
43 if (isInstalled || !showBanner || localStorage.getItem('pwa-banner-dismissed')) {
44 return null;
45 }
46
47 return (
48 <div className="fixed bottom-4 left-4 right-4 z-50 md:left-auto md:right-4 md:w-96">
49 <Card className="bg-primary-700 text-white border-primary-600">
50 <CardContent className="p-4">
51 <div className="flex items-start space-x-3">
52 <div className="flex-shrink-0">
53 <Download className="h-6 w-6" />
54 </div>
55 <div className="flex-1 min-w-0">
56 <h3 className="text-sm font-medium">Install JCRGuru</h3>
57 <p className="text-xs text-primary-100 mt-1">
58 Get instant access to repair guides offline. Install our app for the best experience.
59 </p>
60 <div className="mt-3 flex space-x-2">
61 <Button
62 onClick={handleInstall}
63 size="sm"
64 variant="secondary"
65 className="bg-white text-primary-700 hover:bg-gray-100"
66 >
67 Install
68 </Button>
69 <Button
70 onClick={handleDismiss}
71 size="sm"
72 variant="ghost"
73 className="text-primary-100 hover:text-white hover:bg-primary-600"
74 >
75 Maybe Later
76 </Button>
77 </div>
78 </div>
79 <button
80 onClick={handleDismiss}
81 className="flex-shrink-0 text-primary-200 hover:text-white"
82 >
83 <X className="h-4 w-4" />
84 </button>
85 </div>
86 </CardContent>
87 </Card>
88 </div>
89 );
90 }