import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { EmailSettings, ConfirmEmailSettings } from "../../types" import { Mail, CheckCircle, Paintbrush } from "lucide-react" import { useBackInStockSubscriptions } from "../../hooks/use-back-in-stock" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Trash2, Loader2 } from "lucide-react" import { toast } from "sonner" import { useState } from "react" import { EmailCustomizer } from "@/components/email-customizer" import type { EmailContentSettings, PlaceholderConfig, PlaceholderCategoryLabel, ProductCardConfig } from "@/components/email-customizer/sections" // --------------------------------------------------------------------------- // BIS-specific placeholders for the Email Customizer // --------------------------------------------------------------------------- const bisPlaceholders: PlaceholderConfig[] = [ { tag: '{product_name}', description: 'Product name', example: 'Blue Running Shoes', category: 'product' }, { tag: '{product_price}', description: 'Product price', example: '$49.99', category: 'product' }, { tag: '{product_url}', description: 'Product page URL', example: 'https://store.com/product/shoes', category: 'product' }, { tag: '{customer_email}', description: "Subscriber's email address", example: 'john@example.com', category: 'customer' }, { tag: '{site_name}', description: 'Your website name', example: 'My Store', category: 'site' }, { tag: '{site_url}', description: 'Your website URL', example: 'https://mystore.com', category: 'site' }, ] const bisCategoryLabels: Record = { product: { label: 'Product', color: 'bg-blue-100 text-blue-700' }, customer: { label: 'Customer', color: 'bg-green-100 text-green-700' }, site: { label: 'Site', color: 'bg-orange-100 text-orange-700' }, } /** Sample product data shown in the Email Customizer preview. */ const sampleProduct = { name: 'Blue Running Shoes', price: '$49.99', imageUrl: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 200 200'%3E%3Crect fill='%23f3f4f6' width='200' height='200'/%3E%3Cpath d='M70 130l30-50 30 50' fill='none' stroke='%23d1d5db' stroke-width='4' stroke-linejoin='round'/%3E%3Cpath d='M95 130l12-20 12 20' fill='none' stroke='%23d1d5db' stroke-width='4' stroke-linejoin='round'/%3E%3Ccircle cx='78' cy='82' r='8' fill='%23d1d5db'/%3E%3C/svg%3E", productUrl: '#', } interface NotificationsTabProps { emailSettings: EmailSettings confirmEmailSettings: ConfirmEmailSettings updateEmailSettings: (key: K, value: EmailSettings[K]) => void updateConfirmEmailSettings: (key: K, value: ConfirmEmailSettings[K]) => void } export function NotificationsTab({ emailSettings, confirmEmailSettings, updateEmailSettings, updateConfirmEmailSettings }: NotificationsTabProps) { const [subTab, setSubTab] = useState("email-settings") return ( Email Settings Subscriptions ) } function EmailSettingsContent({ emailSettings, confirmEmailSettings, updateEmailSettings, updateConfirmEmailSettings }: NotificationsTabProps) { const [activeCustomizer, setActiveCustomizer] = useState<'notification' | 'confirmation' | null>(null) // ---- Notification Email: map BIS settings ↔ EmailContentSettings ---- const notificationContent: EmailContentSettings = { subject: emailSettings.subject, heading: emailSettings.heading, body: emailSettings.bodyText, additionalContent: '', preheaderText: '', } const handleSaveNotification = (content: EmailContentSettings) => { updateEmailSettings('subject', content.subject) updateEmailSettings('heading', content.heading) if (content.body !== undefined) { updateEmailSettings('bodyText', content.body) } } // ---- Product Card config for the Notification Email ---- const notificationProductCard: ProductCardConfig = { showImage: emailSettings.includeImage, showTitle: emailSettings.includeTitle, showPrice: emailSettings.includePrice, buttonText: emailSettings.buttonText, sample: sampleProduct, } const handleSaveNotificationProductCard = (card: ProductCardConfig) => { updateEmailSettings('includeImage', card.showImage) updateEmailSettings('includeTitle', card.showTitle) updateEmailSettings('includePrice', card.showPrice) updateEmailSettings('buttonText', card.buttonText) } // ---- Confirmation Email: map BIS settings ↔ EmailContentSettings ---- const confirmationContent: EmailContentSettings = { subject: confirmEmailSettings.subject, heading: confirmEmailSettings.heading, body: confirmEmailSettings.bodyText, additionalContent: '', preheaderText: '', } const handleSaveConfirmation = (content: EmailContentSettings) => { updateConfirmEmailSettings('subject', content.subject) updateConfirmEmailSettings('heading', content.heading) if (content.body !== undefined) { updateConfirmEmailSettings('bodyText', content.body) } } return ( <> {/* Email Customizer Full-Screen Overlay — Notification Email */} {activeCustomizer === 'notification' && ( setActiveCustomizer(null)} emailType={{ id: 'back_in_stock_notification', label: 'Notification Email', defaultContent: { subject: 'Good news! {product_name} is back in stock!', heading: "It's Back!", body: "Great news! The product you've been waiting for is now back in stock. Don't miss out - grab yours before it sells out again!", additionalContent: '', preheaderText: '', }, }} initialContent={notificationContent} onSaveContent={handleSaveNotification} productCard={notificationProductCard} onSaveProductCard={handleSaveNotificationProductCard} placeholders={bisPlaceholders} placeholderCategories={bisCategoryLabels} subjectPlaceholderHint="Available: {product_name}, {site_name}" /> )} {/* Email Customizer Full-Screen Overlay — Confirmation Email */} {activeCustomizer === 'confirmation' && ( setActiveCustomizer(null)} emailType={{ id: 'back_in_stock_confirmation', label: 'Confirmation Email', defaultContent: { subject: 'Confirm your stock notification subscription', heading: 'Confirm Your Subscription', body: 'Please confirm that you want to be notified when {product_name} is back in stock.', additionalContent: '', preheaderText: '', }, }} initialContent={confirmationContent} onSaveContent={handleSaveConfirmation} placeholders={bisPlaceholders} placeholderCategories={bisCategoryLabels} subjectPlaceholderHint="Available: {product_name}, {site_name}" /> )} Email Sender Set the sender identity used for confirmation and stock notification emails
updateEmailSettings('fromName', event.target.value)} />
updateEmailSettings('fromEmail', event.target.value)} />
{/* Email Templates List */} Email Templates Customize the emails sent by the Back In Stock feature
{/* Notification Email Row */}

Notification Email

Sent to subscribers when a product is back in stock

{/* Confirmation Email Row */}

Confirmation Email

Sent when double opt-in is enabled to confirm subscription

) } function SubscriptionsContent() { const { subscriptions, total, page, pages, loading, fetchSubscriptions, deleteSubscription } = useBackInStockSubscriptions() const [deletingId, setDeletingId] = useState(null) const handleDelete = async (id: number) => { setDeletingId(id) const result = await deleteSubscription(id) if (result.success) { toast.success("Subscription deleted") } else { toast.error("Failed to delete subscription") } setDeletingId(null) } const getStatusBadge = (status: string) => { switch (status) { case 'active': return Active case 'notified': return Notified case 'unsubscribed': return Unsubscribed default: return {status} } } if (loading) { return (
) } return ( Active Subscriptions {total} total subscriptions {subscriptions.length === 0 ? (
No subscriptions yet. Customers will appear here when they subscribe.
) : ( <> Email Product Status Subscribed {subscriptions.map((sub) => ( {sub.email} {sub.product_name || `Product #${sub.product_id}`} {getStatusBadge(sub.status)} {new Date(sub.subscribed_at).toLocaleDateString()} ))}
{pages > 1 && (
Page {page} of {pages}
)} )}
) }