import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Switch } from "@/components/ui/switch" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Textarea } from "@/components/ui/textarea" import { TemplateGrid, Template } from "@/components/ui/template-grid" import { LivePreview as LivePreviewContainer } from "@/components/ui/live-preview" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" import { GlobalColorPicker } from "@/components/ui/global-color-picker" import { GlobalTypographyPicker } from "@/components/ui/global-typography-picker" import { StyleSettings, FormSettings } from "../../types" import { Palette, FileText, LayoutTemplate, Bell, Square, MousePointer, RectangleHorizontal, ChevronDown, Minus, Plus, Layout, Type } from "lucide-react" import { useState } from "react" import { usePro } from "@/contexts/pro-context" import { ProIndicator } from "@/components/pro/pro-indicator" type FormDesignType = StyleSettings['formDesign'] interface CustomizationTabProps { styleSettings: StyleSettings formSettings: FormSettings updateStyleSettings: (key: K, value: StyleSettings[K]) => void updateFormSettings: (key: K, value: FormSettings[K]) => void } // Template configurations with metadata interface StylePreset { id: FormDesignType name: string description: string config?: Partial } const stylePresets: StylePreset[] = [ { id: 'modern-minimal', name: 'Modern Minimal', description: 'Clean and simple design', config: { primaryColor: '#000000', textColor: '#1f2937', backgroundColor: '#ffffff', borderRadius: 8, buttonStyle: 'filled', formLayout: 'inline', showIcon: false, padding: 20, margin: 16, borderWidth: 1, borderColor: '#e5e7eb', }, }, { id: 'classic-card', name: 'Classic Card', description: 'Traditional with icon', config: { primaryColor: '#2563eb', textColor: '#374151', backgroundColor: '#f3f4f6', borderRadius: 12, buttonStyle: 'filled', formLayout: 'stacked', showIcon: true, padding: 24, margin: 16, borderWidth: 0, borderColor: 'transparent', }, }, { id: 'bold-gradient', name: 'Compact Banner', description: 'Slim horizontal bar layout', config: { primaryColor: '#059669', textColor: '#1f2937', backgroundColor: '#ecfdf5', borderRadius: 6, buttonStyle: 'filled', formLayout: 'inline', showIcon: false, padding: 14, margin: 12, borderWidth: 1, borderColor: '#059669', }, }, ] // Form Preview Component function FormPreview({ styleSettings, formSettings }: { styleSettings: StyleSettings formSettings: FormSettings }) { const isCompactBanner = styleSettings.formDesign === 'bold-gradient' return (
{styleSettings.showIcon && (
)}

{formSettings.formTitle || 'Get Notified When Available'}

) } /** Compact number input with +/- buttons — replaces Slider */ function NumberStepper({ label, value, onChange, min, max, step = 1, unit = 'px', }: { label: string value: number onChange: (v: number) => void min: number max: number step?: number unit?: string }) { const clamp = (v: number) => Math.min(max, Math.max(min, v)) return (
{label && }
{ const parsed = parseInt(e.target.value, 10) if (!isNaN(parsed)) onChange(clamp(parsed)) }} className="h-8 w-14 text-center text-sm border-x bg-transparent outline-none" />
) } export function CustomizationTab({ styleSettings, formSettings, updateStyleSettings, updateFormSettings, }: CustomizationTabProps) { const { isPro } = usePro() // Accordion state for custom styling sections const [expandedSections, setExpandedSections] = useState>({ layout: true, colors: false, typography: false, containerStyling: false, iconStyling: false, buttonStyling: false, inputStyling: false, formContent: false, }) const toggleSection = (key: string) => { setExpandedSections(prev => ({ ...prev, [key]: !prev[key] })) } // Build templates list — 3 Free presets (no Custom) const templates: Template[] = stylePresets.map(preset => ({ id: preset.id, name: preset.name, description: preset.description, })) // Apply a preset template const applyPreset = (presetId: string) => { updateStyleSettings('formDesign', presetId as FormDesignType) const preset = stylePresets.find(p => p.id === presetId) if (preset?.config) { Object.entries(preset.config).forEach(([key, value]) => { if (value !== undefined) { updateStyleSettings(key as keyof StyleSettings, value as StyleSettings[keyof StyleSettings]) } }) } } return (
{/* Left Column - Templates + Settings */}
{/* Template Selection */} Templates Choose a pre-designed style for your notification form {/* Customize Design — always visible */} Customize Design {isPro ? 'Fine-tune every aspect of your form design' : 'Customize the colors of your form design'} {/* ── Layout & Display — FREE ──────────────────────────────── */} toggleSection('layout')}> Layout & Display

Display notification bell icon in the form

updateStyleSettings('showIcon', checked)} />
{/* Colors Section — Always Free */} toggleSection('colors')}> Colors
updateStyleSettings('primaryColor', v)} globalTokenId="primary" featureDefault="#2563eb" /> updateStyleSettings('textColor', v)} globalTokenId="text" featureDefault="#1f2937" /> updateStyleSettings('backgroundColor', v)} globalTokenId="background" featureDefault="#f3f4f6" /> updateStyleSettings('borderRadius', value)} min={0} max={20} step={1} />
{/* Free user upgrade nudge */} {!isPro && (

For full customization control including typography, container styling, icon, button, and input field customization, upgrade to Swift Commerce Pro.

)} {/* Typography — Pro */} {isPro && ( toggleSection('typography')}> Typography
updateStyleSettings('fontFamily', v)} globalTokenId="body" featureDefault="" />
)} {/* Container Styling — Pro */} {isPro && ( toggleSection('containerStyling')}> Container Styling
updateStyleSettings('padding', value)} min={0} max={48} step={2} /> updateStyleSettings('margin', value)} min={0} max={48} step={2} /> updateStyleSettings('borderWidth', value)} min={0} max={4} step={1} /> updateStyleSettings('borderColor', v)} featureDefault="#e5e7eb" />
)} {/* Icon Styling — Pro */} {isPro && ( toggleSection('iconStyling')}> Icon Styling
updateStyleSettings('iconBackgroundColor', v)} featureDefault="#2563eb" /> updateStyleSettings('iconColor', v)} featureDefault="#ffffff" />
updateStyleSettings('iconSize', value)} min={12} max={32} step={1} /> updateStyleSettings('iconBorderRadius', value)} min={0} max={50} step={5} unit="%" />
)} {/* Button Styling — Pro */} {isPro && ( toggleSection('buttonStyling')}> Button Styling
updateStyleSettings('primaryColor', v)} globalTokenId="primary" featureDefault="#2563eb" /> updateStyleSettings('buttonTextColor', v)} featureDefault="#ffffff" />
updateStyleSettings('buttonBorderRadius', value)} min={0} max={24} step={1} /> updateStyleSettings('buttonPadding', value)} min={4} max={24} step={2} />
)} {/* Input Field Styling — Pro */} {isPro && ( toggleSection('inputStyling')}> Input Field Styling
updateStyleSettings('inputBackgroundColor', v)} featureDefault="#ffffff" /> updateStyleSettings('inputTextColor', v)} featureDefault="#1f2937" /> updateStyleSettings('inputBorderColor', v)} featureDefault="#d1d5db" />
updateStyleSettings('inputBorderRadius', value)} min={0} max={16} step={1} />
)} {/* Form Content — Pro */} {isPro && ( toggleSection('formContent')}> Form Content
updateFormSettings('formTitle', e.target.value)} placeholder="Get notified when available" />
updateFormSettings('emailPlaceholder', e.target.value)} placeholder="Enter your email address" />
updateFormSettings('buttonText', e.target.value)} placeholder="Notify Me" />