feat: implement PWA install prompt banner for investor dashboard

This commit is contained in:
sazzadulalambd
2026-05-16 19:46:43 +06:00
parent bd18c265ca
commit 4b1ff96db2

View File

@@ -1,5 +1,8 @@
'use client';
import { useState, useEffect } from 'react';
import { investors, bikes, transactions } from '@/data/mockData'; import { investors, bikes, transactions } from '@/data/mockData';
import { Wallet, TrendingUp, Bike, Target, DollarSign, FileText, Phone, BarChart3, Clock, ArrowRight, ShieldCheck, Zap, AlertCircle } from 'lucide-react'; import { Wallet, TrendingUp, Bike, Target, DollarSign, FileText, Phone, BarChart3, Clock, ArrowRight, ShieldCheck, Zap, AlertCircle, Download, X, ExternalLink } from 'lucide-react';
import Link from 'next/link'; import Link from 'next/link';
import TransactionList from '@/components/TransactionList'; import TransactionList from '@/components/TransactionList';
import InvestorNotification from '@/components/InvestorNotification'; import InvestorNotification from '@/components/InvestorNotification';
@@ -11,6 +14,40 @@ export default function InvestorDashboardPage() {
const availableBalance = investor.totalEarnings - investor.totalWithdrawn - investor.withdrawalPending; const availableBalance = investor.totalEarnings - investor.totalWithdrawn - investor.withdrawalPending;
const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
const [showInstallBanner, setShowInstallBanner] = useState(false);
useEffect(() => {
const handler = (e: Event) => {
e.preventDefault();
setDeferredPrompt(e);
setShowInstallBanner(true);
};
window.addEventListener('beforeinstallprompt', handler);
return () => window.removeEventListener('beforeinstallprompt', handler);
}, []);
const handleInstall = async () => {
if (!deferredPrompt) return;
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
if (outcome === 'accepted') {
setDeferredPrompt(null);
}
setShowInstallBanner(false);
};
const dismissBanner = () => {
setShowInstallBanner(false);
localStorage.setItem('pwa_install_dismissed', 'true');
};
useEffect(() => {
if (localStorage.getItem('pwa_install_dismissed') === 'true') {
setShowInstallBanner(false);
}
}, []);
return ( return (
<div className="min-h-screen lg:pt-6 pt-0"> <div className="min-h-screen lg:pt-6 pt-0">
<InvestorNotification isMobile /> <InvestorNotification isMobile />
@@ -82,6 +119,29 @@ export default function InvestorDashboardPage() {
</div> </div>
</div> </div>
{/* PWA Install Banner */}
{showInstallBanner && (
<div className="bg-gradient-to-r from-investor/10 to-purple-50 border border-investor/20 rounded-2xl p-4 mb-6 animate-in fade-in slide-in-from-bottom-4">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-gradient-to-br from-investor to-investor-light rounded-xl flex items-center justify-center shrink-0 shadow-lg">
<Download className="w-6 h-6 text-white" />
</div>
<div className="flex-1 min-w-0">
<p className="font-bold text-slate-800">Install JML Investor App</p>
<p className="text-xs text-slate-500 mt-0.5">Add to home screen for quick access & offline support</p>
</div>
<div className="flex items-center gap-2 shrink-0">
<button onClick={dismissBanner} className="p-2 hover:bg-slate-100 rounded-lg text-slate-400 transition-colors">
<X className="w-5 h-5" />
</button>
<button onClick={handleInstall} className="px-4 py-2 bg-investor text-white rounded-lg font-bold text-sm hover:bg-investor-dark transition-colors flex items-center gap-2 shadow-sm">
<ExternalLink className="w-4 h-4" /> Install
</button>
</div>
</div>
</div>
)}
<div className="grid lg:grid-cols-3 gap-6 mb-6"> <div className="grid lg:grid-cols-3 gap-6 mb-6">
<div className="lg:col-span-2 bg-white rounded-2xl border border-slate-200 shadow-sm flex flex-col"> <div className="lg:col-span-2 bg-white rounded-2xl border border-slate-200 shadow-sm flex flex-col">
<div className="p-5 border-b border-slate-100 flex items-center justify-between"> <div className="p-5 border-b border-slate-100 flex items-center justify-between">