import React, { useState, useEffect, useMemo } from 'react'; import { Clock, ExternalLink } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { getStatusBadge } from '@/utils/statusHelpers.jsx'; import { supabase } from '@/lib/supabaseClient'; const CouponCard = ({ coupon, handleCouponClick }) => { const [logoUrl, setLogoUrl] = useState(null); const [imageError, setImageError] = useState(false); useEffect(() => { setImageError(false); const imagePath = coupon?.logo; if (coupon && imagePath) { if (imagePath.startsWith('http') || imagePath.startsWith('data:')) { setLogoUrl(imagePath); } else { const { data } = supabase.storage.from('coupon_images').getPublicUrl(imagePath); setLogoUrl(data?.publicUrl || 'https://via.placeholder.com/128x96?text=Image+Not+Found'); } } else { setLogoUrl('https://via.placeholder.com/128x96?text=No+Image'); } }, [coupon?.logo, coupon?.id]); const ctaText = useMemo(() => coupon.action_type === 'Get Deal' ? 'View Promo' : (coupon.action_type || 'View Offer'), [coupon.action_type]); const formatDiscountForCard = (discountString, currency, discountType) => { if (!discountString) return { main: '', sub: '' }; let mainText = discountString; let subText = ''; const lowerDiscountString = discountString.toLowerCase(); const lowerDiscountType = discountType ? discountType.toLowerCase() : ''; if (lowerDiscountType.includes('percentage')) { mainText = discountString.replace(/%/g, '') + '%'; subText = 'off'; } else if (lowerDiscountType.includes('points')) { mainText = discountString.replace(/\s*points/i, ''); subText = 'Points'; } else if (lowerDiscountType.includes('fixed amount')) { mainText = discountString; if (currency) { subText = currency; } else { subText = 'off'; } } else if (lowerDiscountString === 'free shipping' || lowerDiscountString === 'buy 1 get 1') { mainText = discountString; subText = ''; } if (lowerDiscountType.includes('up to')) { mainText = mainText.replace(/up to\s*/i, ''); if (subText) { subText = `up to ${subText}`; } else { subText = 'up to'; } } if (currency && (lowerDiscountType.includes('fixed amount') || (lowerDiscountType === 'other' && /^\d/.test(mainText)))) { mainText = `${currency} ${mainText.replace(currency, '').trim()}`; subText = 'off'; if (lowerDiscountType.includes('up to')) { mainText = mainText.replace(/up to\s*/i, ''); subText = `up to ${currency}`; } } if (mainText.includes(subText) && subText !== 'off' && subText !== 'up to' && !subText.includes('Points')) { mainText = mainText.replace(subText, '').trim(); } if (subText === 'Points' && mainText.toLowerCase().endsWith(' points')) { mainText = mainText.substring(0, mainText.toLowerCase().lastIndexOf(' points')).trim(); } if (subText.toLowerCase().startsWith('up to') && mainText.toLowerCase().startsWith('up to')) { mainText = mainText.substring(5).trim(); } if (currency && mainText.startsWith(currency)) { subText = currency; mainText = mainText.substring(currency.length).trim(); if (lowerDiscountType.includes('up to')) { subText = `up to ${currency}`; } } return { main: mainText.trim(), sub: subText.trim() }; }; const { main: mainDiscount, sub: subDiscount } = useMemo(() => formatDiscountForCard(coupon.discount, coupon.currency, coupon.discount_type), [coupon.discount, coupon.currency, coupon.discount_type]); const placeholderSrc = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22128%22%20height%3D%2296%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20128%2096%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_15f1a3c913a%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_15f1a3c913a%22%3E%3Crect%20width%3D%22128%22%20height%3D%2296%22%20fill%3D%22%23EEEEEE%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2236.5%22%20y%3D%2252.8%22%3ENo%20Image%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'; return (
{`${coupon.brand setImageError(true)} style={{aspectRatio: '128/96'}} />

{coupon.brand}

{coupon.title}

{getStatusBadge(coupon.status, coupon.status_type, 'base', 'sm:text-xs')}
{mainDiscount && (
{mainDiscount} {subDiscount && ( {subDiscount} )}
)}
); }; export default React.memo(CouponCard);