import { useState, useRef, useEffect } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { promoApi } from '../api/promo'; const SparklesIcon = () => ( ); const ClockIcon = () => ( ); const formatTimeLeft = (expiresAt: string, t: (key: string) => string): string => { const now = new Date(); // Ensure UTC parsing - if no timezone specified, assume UTC let expires: Date; if (expiresAt.includes('Z') || expiresAt.includes('+') || expiresAt.includes('-', 10)) { expires = new Date(expiresAt); } else { // No timezone - treat as UTC expires = new Date(expiresAt + 'Z'); } const diffMs = expires.getTime() - now.getTime(); if (diffMs <= 0) return ''; const hours = Math.floor(diffMs / (1000 * 60 * 60)); const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60)); if (hours > 24) { const days = Math.floor(hours / 24); return `${days}${t('promo.time.days')}`; } if (hours > 0) { return `${hours}${t('promo.time.hours')} ${minutes}${t('promo.time.minutes')}`; } return `${minutes}${t('promo.time.minutes')}`; }; export default function PromoDiscountBadge() { const { t } = useTranslation(); const navigate = useNavigate(); const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); const { data: activeDiscount } = useQuery({ queryKey: ['active-discount'], queryFn: promoApi.getActiveDiscount, staleTime: 30000, refetchInterval: 60000, // Refresh every minute }); // Close dropdown on click outside useEffect(() => { function handleClickOutside(event: MouseEvent) { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); } } document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Don't render if no active discount if (!activeDiscount || !activeDiscount.is_active || !activeDiscount.discount_percent) { return null; } const timeLeft = activeDiscount.expires_at ? formatTimeLeft(activeDiscount.expires_at, t) : null; const handleClick = () => { setIsOpen(!isOpen); }; const handleGoToSubscription = () => { setIsOpen(false); navigate('/subscription'); }; return ( {/* Badge button */} -{activeDiscount.discount_percent}% {/* Dropdown - mobile: fixed centered, desktop: absolute right */} {isOpen && ( <> {/* Mobile backdrop */} setIsOpen(false)} /> {/* Header */} {t('promo.discountActive')} -{activeDiscount.discount_percent}% {/* Content */} {t('promo.discountDescription')} {/* Time remaining */} {timeLeft && ( {t('promo.expiresIn')}:{' '} {timeLeft} )} {/* CTA Button */} {t('promo.useNow')} > )} ); }
{t('promo.discountDescription')}