push notification implemented
need testing
This commit is contained in:
1 parent
26a17b5a4c
commit
0bbf2ab56f
19 files changed
+907
-84
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usePushNotifications } from '@/hooks/usePushNotifications';
|
||||
import { Bell, X } from 'lucide-react';
|
||||
|
||||
const DISMISSED_KEY = 'push-banner-dismissed';
|
||||
const SHOW_DELAY = 3000;
|
||||
|
||||
function getInitiallyDismissed(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
return !!localStorage.getItem(DISMISSED_KEY);
|
||||
}
|
||||
|
||||
export function NotificationBanner() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [isDismissed, setIsDismissed] = useState(getInitiallyDismissed);
|
||||
const { isSupported, isSubscribed, isLoading, subscribe } =
|
||||
usePushNotifications();
|
||||
|
||||
useEffect(() => {
|
||||
if (isSupported && !isSubscribed && !isDismissed) {
|
||||
const timer = setTimeout(() => {
|
||||
setIsVisible(true);
|
||||
}, SHOW_DELAY);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [isSupported, isSubscribed, isDismissed]);
|
||||
|
||||
const handleDismiss = () => {
|
||||
setIsVisible(false);
|
||||
localStorage.setItem(DISMISSED_KEY, 'true');
|
||||
setIsDismissed(true);
|
||||
};
|
||||
|
||||
const handleSubscribe = async () => {
|
||||
const success = await subscribe();
|
||||
if (success) {
|
||||
setIsVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isVisible || isSubscribed || isDismissed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-4 right-4 z-50 max-w-sm animate-slide-in-right">
|
||||
<div className="flex items-start gap-3 rounded-lg border-2 border-foreground bg-card p-4 shadow-brutal">
|
||||
<div className="flex-shrink-0">
|
||||
<Bell className="h-5 w-5 text-accent" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-body text-sm font-medium uppercase tracking-wider">
|
||||
Останете информирани
|
||||
</p>
|
||||
<p className="mt-1 font-body text-xs text-muted-foreground">
|
||||
Добијте известувања за нови статии и live ажурирања
|
||||
</p>
|
||||
<div className="mt-3 flex gap-2">
|
||||
<button
|
||||
onClick={handleSubscribe}
|
||||
disabled={isLoading}
|
||||
className="border-2 border-foreground bg-foreground px-3 py-1.5 font-body text-xs font-medium uppercase tracking-wider text-background transition-all hover:bg-accent hover:text-foreground disabled:opacity-50"
|
||||
>
|
||||
{isLoading ? 'Се вклучува...' : 'Вклучи'}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDismiss}
|
||||
className="border-2 border-foreground px-3 py-1.5 font-body text-xs font-medium uppercase tracking-wider transition-all hover:bg-muted"
|
||||
>
|
||||
Не сега
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleDismiss}
|
||||
className="flex-shrink-0 text-muted-foreground transition-colors hover:text-foreground"
|
||||
aria-label="Затвори"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user