first commit

This commit is contained in:
2026-01-17 14:17:42 +05:30
commit 0f194eb9e7
328 changed files with 73544 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
'use client'
import { useState, useEffect } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { X, Download, Smartphone } from 'lucide-react'
interface BeforeInstallPromptEvent extends Event {
prompt(): Promise<void>
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>
}
export default function PWAInstallPrompt() {
const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null)
const [showPrompt, setShowPrompt] = useState(false)
const [isInstalled, setIsInstalled] = useState(false)
useEffect(() => {
// Check if app is already installed
const checkInstalled = () => {
const isStandalone = window.matchMedia('(display-mode: standalone)').matches
const isInWebAppiOS = (window.navigator as any).standalone === true
const isAndroidInstalled = document.referrer.includes('android-app://')
setIsInstalled(isStandalone || isInWebAppiOS || isAndroidInstalled)
}
checkInstalled()
const handleBeforeInstallPrompt = (e: Event) => {
e.preventDefault()
setDeferredPrompt(e as BeforeInstallPromptEvent)
// Don't show prompt immediately, wait a bit for user engagement
setTimeout(() => {
if (!isInstalled && !localStorage.getItem('pwa-install-dismissed')) {
setShowPrompt(true)
}
}, 10000) // Show after 10 seconds
}
const handleAppInstalled = () => {
setShowPrompt(false)
setIsInstalled(true)
setDeferredPrompt(null)
}
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.addEventListener('appinstalled', handleAppInstalled)
return () => {
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.removeEventListener('appinstalled', handleAppInstalled)
}
}, [isInstalled])
const handleInstallClick = async () => {
if (!deferredPrompt) return
try {
await deferredPrompt.prompt()
const choiceResult = await deferredPrompt.userChoice
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the install prompt')
} else {
console.log('User dismissed the install prompt')
}
setDeferredPrompt(null)
setShowPrompt(false)
} catch (error) {
console.error('Error showing install prompt:', error)
}
}
const handleDismiss = () => {
setShowPrompt(false)
localStorage.setItem('pwa-install-dismissed', 'true')
// Show again after 7 days
setTimeout(() => {
localStorage.removeItem('pwa-install-dismissed')
}, 7 * 24 * 60 * 60 * 1000)
}
if (isInstalled || !showPrompt || !deferredPrompt) {
return null
}
return (
<AnimatePresence>
<motion.div
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 100 }}
className="fixed bottom-4 left-4 right-4 z-50 max-w-sm mx-auto"
>
<Card className="bg-gradient-to-r from-green-500 to-emerald-600 text-white border-0 shadow-2xl">
<CardContent className="p-4">
<div className="flex items-start space-x-3">
<div className="flex-shrink-0">
<div className="w-12 h-12 bg-white/20 rounded-full flex items-center justify-center">
<Smartphone className="h-6 w-6 text-white" />
</div>
</div>
<div className="flex-1 min-w-0">
<h3 className="text-sm font-semibold text-white mb-1">
Install Padmaaja Rasooi App
</h3>
<p className="text-xs text-green-100 mb-3">
Get the full experience with offline access, faster loading, and push notifications.
</p>
<div className="flex space-x-2">
<Button
onClick={handleInstallClick}
size="sm"
variant="secondary"
className="flex-1 text-green-700 hover:text-green-800"
>
<Download className="h-3 w-3 mr-1" />
Install
</Button>
<Button
onClick={handleDismiss}
size="sm"
variant="ghost"
className="text-white hover:bg-white/20"
>
Later
</Button>
</div>
</div>
<Button
onClick={handleDismiss}
size="sm"
variant="ghost"
className="flex-shrink-0 text-white hover:bg-white/20 p-1"
>
<X className="h-4 w-4" />
</Button>
</div>
</CardContent>
</Card>
</motion.div>
</AnimatePresence>
)
}
// Alternative iOS Safari install instructions
export function IOSInstallPrompt() {
const [showIOS, setShowIOS] = useState(false)
useEffect(() => {
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
const isInStandaloneMode = (window.navigator as any).standalone === true
const hasPromptBeenShown = localStorage.getItem('ios-install-prompt-shown')
if (isIOS && !isInStandaloneMode && !hasPromptBeenShown) {
setTimeout(() => setShowIOS(true), 15000) // Show after 15 seconds on iOS
}
}, [])
const handleDismiss = () => {
setShowIOS(false)
localStorage.setItem('ios-install-prompt-shown', 'true')
}
if (!showIOS) return null
return (
<AnimatePresence>
<motion.div
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 100 }}
className="fixed bottom-4 left-4 right-4 z-50 max-w-sm mx-auto"
>
<Card className="bg-blue-600 text-white border-0 shadow-2xl">
<CardContent className="p-4">
<div className="flex items-start space-x-3">
<div className="flex-shrink-0">
<div className="w-12 h-12 bg-white/20 rounded-full flex items-center justify-center">
<Smartphone className="h-6 w-6 text-white" />
</div>
</div>
<div className="flex-1 min-w-0">
<h3 className="text-sm font-semibold text-white mb-1">
Add to Home Screen
</h3>
<p className="text-xs text-blue-100 mb-2">
Tap the share button <span className="inline-block w-4 h-4 bg-white/20 rounded text-center text-xs"></span> below and select "Add to Home Screen"
</p>
<Button
onClick={handleDismiss}
size="sm"
variant="secondary"
className="text-blue-700 hover:text-blue-800"
>
Got it
</Button>
</div>
<Button
onClick={handleDismiss}
size="sm"
variant="ghost"
className="flex-shrink-0 text-white hover:bg-white/20 p-1"
>
<X className="h-4 w-4" />
</Button>
</div>
</CardContent>
</Card>
</motion.div>
</AnimatePresence>
)
}