shared-features 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AdBanner-CZz8trdz.cjs → AnnouncementModal-Bqy0pn3V.cjs} +428 -3
- package/dist/AnnouncementModal-Bqy0pn3V.cjs.map +1 -0
- package/dist/{AdBanner-DF1QuMxR.js → AnnouncementModal-sxH4K5gy.js} +430 -5
- package/dist/AnnouncementModal-sxH4K5gy.js.map +1 -0
- package/dist/admin-notifications-D9n9h-eY.cjs +362 -0
- package/dist/admin-notifications-D9n9h-eY.cjs.map +1 -0
- package/dist/admin-notifications-p1dy3zIP.js +363 -0
- package/dist/admin-notifications-p1dy3zIP.js.map +1 -0
- package/dist/{analytics-CdpCtTpu.js → analytics-40-S_fHC.js} +3 -2
- package/dist/{analytics-CdpCtTpu.js.map → analytics-40-S_fHC.js.map} +1 -1
- package/dist/{analytics--ZSO9ova.cjs → analytics-lEzOx2vl.cjs} +2 -1
- package/dist/{analytics--ZSO9ova.cjs.map → analytics-lEzOx2vl.cjs.map} +1 -1
- package/dist/broadcasts-3_WfQMNL.cjs +278 -0
- package/dist/broadcasts-3_WfQMNL.cjs.map +1 -0
- package/dist/broadcasts-DgZUzqMf.js +257 -0
- package/dist/broadcasts-DgZUzqMf.js.map +1 -0
- package/dist/components/index.cjs +23 -20
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -1
- package/dist/components/notifications/AnnouncementModal.d.ts +21 -0
- package/dist/components/notifications/AnnouncementModal.d.ts.map +1 -0
- package/dist/components/notifications/BroadcastBanner.d.ts +55 -0
- package/dist/components/notifications/BroadcastBanner.d.ts.map +1 -0
- package/dist/components/notifications/index.d.ts +11 -0
- package/dist/components/notifications/index.d.ts.map +1 -0
- package/dist/hooks/index.cjs +9 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useBroadcasts.d.ts +122 -0
- package/dist/hooks/useBroadcasts.d.ts.map +1 -0
- package/dist/index.cjs +99 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -17
- package/dist/index.js.map +1 -1
- package/dist/notifications/events/index.d.ts +14 -0
- package/dist/notifications/events/index.d.ts.map +1 -0
- package/dist/notifications/events/registry.d.ts +75 -0
- package/dist/notifications/events/registry.d.ts.map +1 -0
- package/dist/notifications/events/templates/engine.d.ts +57 -0
- package/dist/notifications/events/templates/engine.d.ts.map +1 -0
- package/dist/notifications/events/templates/standard.d.ts +20 -0
- package/dist/notifications/events/templates/standard.d.ts.map +1 -0
- package/dist/notifications/events/useNotificationEvents.d.ts +36 -0
- package/dist/notifications/events/useNotificationEvents.d.ts.map +1 -0
- package/dist/notifications/index.cjs +25 -0
- package/dist/notifications/index.cjs.map +1 -0
- package/dist/notifications/index.d.ts +9 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +25 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/services/admin-notifications.d.ts +95 -0
- package/dist/services/admin-notifications.d.ts.map +1 -0
- package/dist/services/broadcasts.d.ts +55 -0
- package/dist/services/broadcasts.d.ts.map +1 -0
- package/dist/services/index.cjs +34 -1
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +35 -2
- package/dist/services/index.js.map +1 -1
- package/dist/types/index.cjs +108 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +109 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/notifications.d.ts +634 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/useBroadcasts-DzpCcbC8.js +161 -0
- package/dist/useBroadcasts-DzpCcbC8.js.map +1 -0
- package/dist/useBroadcasts-FP6ZrcY_.cjs +160 -0
- package/dist/useBroadcasts-FP6ZrcY_.cjs.map +1 -0
- package/dist/{useCampaigns-Dltisb9N.cjs → useCampaigns-BOZ9dDsG.cjs} +2 -2
- package/dist/{useCampaigns-Dltisb9N.cjs.map → useCampaigns-BOZ9dDsG.cjs.map} +1 -1
- package/dist/{useCampaigns-nwfsALsN.js → useCampaigns-D46b9zuf.js} +2 -2
- package/dist/{useCampaigns-nwfsALsN.js.map → useCampaigns-D46b9zuf.js.map} +1 -1
- package/dist/useNotificationEvents-BXeMqdak.cjs +954 -0
- package/dist/useNotificationEvents-BXeMqdak.cjs.map +1 -0
- package/dist/useNotificationEvents-D8DVxah1.js +955 -0
- package/dist/useNotificationEvents-D8DVxah1.js.map +1 -0
- package/package.json +11 -3
- package/dist/AdBanner-CZz8trdz.cjs.map +0 -1
- package/dist/AdBanner-DF1QuMxR.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNotificationEvents-D8DVxah1.js","sources":["../src/notifications/events/templates/engine.ts","../src/notifications/events/templates/standard.ts","../src/notifications/events/registry.ts","../src/notifications/events/useNotificationEvents.ts"],"sourcesContent":["/**\n * Template Engine\n *\n * Simple template interpolation for notification messages.\n * Supports {{variable}} syntax for dynamic content.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface TemplateContext {\n [key: string]: string | number | boolean | undefined | null;\n}\n\nexport interface InterpolateOptions {\n /** Whether to throw on missing variables (default: false) */\n strict?: boolean;\n /** Default value for missing variables (default: '') */\n defaultValue?: string;\n /** Custom formatters for values */\n formatters?: Record<string, (value: unknown) => string>;\n}\n\n// ============================================================================\n// INTERPOLATION\n// ============================================================================\n\n/**\n * Interpolate template variables in a string\n *\n * @example\n * ```ts\n * interpolate('Hello, {{name}}!', { name: 'John' });\n * // => 'Hello, John!'\n *\n * interpolate('You have {{count}} items', { count: 5 });\n * // => 'You have 5 items'\n * ```\n */\nexport function interpolate(\n template: string,\n context: TemplateContext,\n options: InterpolateOptions = {}\n): string {\n const { strict = false, defaultValue = '', formatters = {} } = options;\n\n // Match {{variable}} or {{variable|formatter}}\n const pattern = /\\{\\{([^}|]+)(?:\\|([^}]+))?\\}\\}/g;\n\n return template.replace(pattern, (_match, variableName, formatterName) => {\n const trimmedName = variableName.trim();\n const value = context[trimmedName];\n\n // Handle missing values\n if (value === undefined || value === null) {\n if (strict) {\n throw new Error(`Missing template variable: ${trimmedName}`);\n }\n return defaultValue;\n }\n\n // Apply formatter if specified\n if (formatterName) {\n const formatter = formatters[formatterName.trim()];\n if (formatter) {\n return formatter(value);\n }\n }\n\n // Convert to string\n return String(value);\n });\n}\n\n/**\n * Extract all variable names from a template\n *\n * @example\n * ```ts\n * extractVariables('Hello, {{name}}! You have {{count}} items.');\n * // => ['name', 'count']\n * ```\n */\nexport function extractVariables(template: string): string[] {\n const pattern = /\\{\\{([^}|]+)(?:\\|[^}]+)?\\}\\}/g;\n const variables: string[] = [];\n let match;\n\n while ((match = pattern.exec(template)) !== null) {\n const matchResult = match[1];\n if (matchResult) {\n const variableName = matchResult.trim();\n if (!variables.includes(variableName)) {\n variables.push(variableName);\n }\n }\n }\n\n return variables;\n}\n\n/**\n * Validate that all required variables are provided\n */\nexport function validateContext(\n template: string,\n context: TemplateContext\n): { valid: boolean; missing: string[] } {\n const required = extractVariables(template);\n const missing = required.filter(\n (v) => context[v] === undefined || context[v] === null\n );\n\n return {\n valid: missing.length === 0,\n missing,\n };\n}\n\n// ============================================================================\n// BUILT-IN FORMATTERS\n// ============================================================================\n\nexport const defaultFormatters: Record<string, (value: unknown) => string> = {\n /**\n * Capitalize first letter\n */\n capitalize: (value) => {\n const str = String(value);\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n },\n\n /**\n * Convert to uppercase\n */\n upper: (value) => String(value).toUpperCase(),\n\n /**\n * Convert to lowercase\n */\n lower: (value) => String(value).toLowerCase(),\n\n /**\n * Format number with commas\n */\n number: (value) => {\n const num = Number(value);\n if (isNaN(num)) return String(value);\n return num.toLocaleString();\n },\n\n /**\n * Format as date\n */\n date: (value) => {\n const date = new Date(value as string | number);\n if (isNaN(date.getTime())) return String(value);\n return date.toLocaleDateString();\n },\n\n /**\n * Format as time\n */\n time: (value) => {\n const date = new Date(value as string | number);\n if (isNaN(date.getTime())) return String(value);\n return date.toLocaleTimeString();\n },\n\n /**\n * Format as datetime\n */\n datetime: (value) => {\n const date = new Date(value as string | number);\n if (isNaN(date.getTime())) return String(value);\n return date.toLocaleString();\n },\n\n /**\n * Truncate to 50 characters\n */\n truncate: (value) => {\n const str = String(value);\n return str.length > 50 ? str.substring(0, 47) + '...' : str;\n },\n\n /**\n * Join array with commas\n */\n list: (value) => {\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n return String(value);\n },\n};\n\n/**\n * Interpolate with default formatters\n */\nexport function interpolateWithFormatters(\n template: string,\n context: TemplateContext,\n options: Omit<InterpolateOptions, 'formatters'> & {\n customFormatters?: Record<string, (value: unknown) => string>;\n } = {}\n): string {\n const { customFormatters = {}, ...restOptions } = options;\n\n return interpolate(template, context, {\n ...restOptions,\n formatters: { ...defaultFormatters, ...customFormatters },\n });\n}\n","/**\n * Standard Notification Templates\n *\n * Pre-defined templates for common notification events.\n * These can be customized or overridden by consumer projects.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport type {\n NotificationTemplate,\n StandardEventType,\n NotificationCategory,\n} from '../../../types/notifications';\n\n// ============================================================================\n// ACCOUNT EVENT TEMPLATES\n// ============================================================================\n\nexport const ACCOUNT_TEMPLATES: NotificationTemplate[] = [\n {\n id: 'tpl_account_created',\n name: 'Account Created',\n eventType: 'ACCOUNT_CREATED',\n category: 'account',\n title: 'Welcome to {{appName}}!',\n message:\n 'Hi {{userName}}, your account has been created successfully. Start exploring all the features we have to offer.',\n variables: ['appName', 'userName'],\n type: 'success',\n isImportant: true,\n actionUrl: '/getting-started',\n actionText: 'Get Started',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_account_welcome',\n name: 'Welcome Message',\n eventType: 'ACCOUNT_WELCOME',\n category: 'account',\n title: 'Tips to get started with {{appName}}',\n message:\n 'Here are some tips to help you get the most out of {{appName}}. Check out our quick start guide!',\n variables: ['appName'],\n type: 'info',\n isImportant: false,\n actionUrl: '/help/quick-start',\n actionText: 'Quick Start Guide',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_new_device_signin',\n name: 'New Device Sign-in',\n eventType: 'NEW_DEVICE_SIGNIN',\n category: 'account',\n title: 'New Sign-in Detected',\n message:\n 'Your account was accessed from a new device: {{deviceName}}{{#location}} in {{location}}{{/location}}. If this wasn\\'t you, please secure your account.',\n variables: ['deviceName', 'location'],\n type: 'warning',\n isImportant: true,\n actionUrl: '/settings/security',\n actionText: 'Review Activity',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_password_changed',\n name: 'Password Changed',\n eventType: 'PASSWORD_CHANGED',\n category: 'account',\n title: 'Password Changed Successfully',\n message:\n 'Your password was changed on {{timestamp}}. If you didn\\'t make this change, please contact support immediately.',\n variables: ['timestamp'],\n type: 'info',\n isImportant: true,\n actionUrl: '/settings/security',\n actionText: 'Security Settings',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_profile_updated',\n name: 'Profile Updated',\n eventType: 'PROFILE_UPDATED',\n category: 'account',\n title: 'Profile Updated',\n message: 'Your profile has been updated: {{changes}}.',\n variables: ['changes'],\n type: 'success',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n];\n\n// ============================================================================\n// REPORT EVENT TEMPLATES\n// ============================================================================\n\nexport const REPORT_TEMPLATES: NotificationTemplate[] = [\n {\n id: 'tpl_weekly_summary',\n name: 'Weekly Summary',\n eventType: 'WEEKLY_SUMMARY',\n category: 'report',\n title: 'Your Weekly Summary',\n message:\n 'Here\\'s your activity summary for the week of {{weekStart}}: {{summary}}',\n variables: ['weekStart', 'summary'],\n type: 'info',\n isImportant: false,\n actionUrl: '/reports/weekly',\n actionText: 'View Full Report',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_monthly_summary',\n name: 'Monthly Summary',\n eventType: 'MONTHLY_SUMMARY',\n category: 'report',\n title: 'Your Monthly Summary',\n message:\n 'Your activity summary for {{monthName}} is ready. {{summary}}',\n variables: ['monthName', 'summary'],\n type: 'info',\n isImportant: false,\n actionUrl: '/reports/monthly',\n actionText: 'View Full Report',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_quarterly_summary',\n name: 'Quarterly Summary',\n eventType: 'QUARTERLY_SUMMARY',\n category: 'report',\n title: 'Your Quarterly Review',\n message:\n 'Your Q{{quarter}} {{year}} summary is ready. See how you\\'ve progressed!',\n variables: ['quarter', 'year'],\n type: 'milestone',\n isImportant: true,\n actionUrl: '/reports/quarterly',\n actionText: 'View Report',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_yearly_summary',\n name: 'Yearly Summary',\n eventType: 'YEARLY_SUMMARY',\n category: 'report',\n title: 'Your Year in Review',\n message:\n 'Congratulations on another great year! Your {{year}} summary is ready.',\n variables: ['year'],\n type: 'milestone',\n isImportant: true,\n actionUrl: '/reports/yearly',\n actionText: 'View Year in Review',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n];\n\n// ============================================================================\n// PROMOTIONAL EVENT TEMPLATES\n// ============================================================================\n\nexport const PROMOTIONAL_TEMPLATES: NotificationTemplate[] = [\n {\n id: 'tpl_app_tip',\n name: 'App Tip',\n eventType: 'APP_TIP',\n category: 'promotional',\n title: 'Tip: {{tipTitle}}',\n message: '{{tipBody}}',\n variables: ['tipTitle', 'tipBody'],\n type: 'info',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_hidden_feature',\n name: 'Hidden Feature',\n eventType: 'HIDDEN_FEATURE',\n category: 'promotional',\n title: 'Did you know?',\n message: '{{featureDescription}}',\n variables: ['featureName', 'featureDescription'],\n type: 'info',\n isImportant: false,\n actionUrl: '{{featureUrl}}',\n actionText: 'Try it now',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_new_feature',\n name: 'New Feature Announcement',\n eventType: 'NEW_FEATURE_ANNOUNCEMENT',\n category: 'promotional',\n title: 'New Feature: {{featureName}}',\n message: '{{featureDescription}}',\n variables: ['featureName', 'featureDescription'],\n type: 'announcement',\n isImportant: true,\n actionUrl: '{{featureUrl}}',\n actionText: 'Check it out',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_holiday_greeting',\n name: 'Holiday Greeting',\n eventType: 'HOLIDAY_GREETING',\n category: 'promotional',\n title: 'Happy {{holidayName}}!',\n message: '{{greetingMessage}}',\n variables: ['holidayName', 'greetingMessage'],\n type: 'info',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n];\n\n// ============================================================================\n// SYSTEM EVENT TEMPLATES\n// ============================================================================\n\nexport const SYSTEM_TEMPLATES: NotificationTemplate[] = [\n {\n id: 'tpl_system_maintenance',\n name: 'System Maintenance',\n eventType: 'SYSTEM_MAINTENANCE',\n category: 'system',\n title: 'Scheduled Maintenance',\n message:\n 'We\\'ll be performing maintenance on {{date}} from {{startTime}} to {{endTime}} ({{timezone}}). Some features may be unavailable.',\n variables: ['date', 'startTime', 'endTime', 'timezone'],\n type: 'warning',\n isImportant: true,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_app_update',\n name: 'App Update Available',\n eventType: 'APP_UPDATE_AVAILABLE',\n category: 'system',\n title: 'Update Available',\n message:\n 'A new version ({{version}}) is available with improvements and bug fixes.',\n variables: ['version'],\n type: 'info',\n isImportant: false,\n actionUrl: '/update',\n actionText: 'Update Now',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_data_export_ready',\n name: 'Data Export Ready',\n eventType: 'DATA_EXPORT_READY',\n category: 'system',\n title: 'Your Data Export is Ready',\n message:\n 'Your requested data export is ready for download. The link will expire in {{expiryHours}} hours.',\n variables: ['expiryHours'],\n type: 'success',\n isImportant: true,\n actionUrl: '{{downloadUrl}}',\n actionText: 'Download',\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n];\n\n// ============================================================================\n// ACTIVITY EVENT TEMPLATES\n// ============================================================================\n\nexport const ACTIVITY_TEMPLATES: NotificationTemplate[] = [\n {\n id: 'tpl_item_created',\n name: 'Item Created',\n eventType: 'ITEM_CREATED',\n category: 'activity',\n title: '{{entityType}} Created',\n message: 'Your {{entityType}} \"{{entityName}}\" has been created successfully.',\n variables: ['entityType', 'entityName'],\n type: 'success',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_item_updated',\n name: 'Item Updated',\n eventType: 'ITEM_UPDATED',\n category: 'activity',\n title: '{{entityType}} Updated',\n message: 'Your {{entityType}} \"{{entityName}}\" has been updated.',\n variables: ['entityType', 'entityName'],\n type: 'info',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_item_deleted',\n name: 'Item Deleted',\n eventType: 'ITEM_DELETED',\n category: 'activity',\n title: '{{entityType}} Deleted',\n message: 'Your {{entityType}} \"{{entityName}}\" has been deleted.',\n variables: ['entityType', 'entityName'],\n type: 'info',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n {\n id: 'tpl_bulk_operation',\n name: 'Bulk Operation Complete',\n eventType: 'BULK_OPERATION_COMPLETE',\n category: 'activity',\n title: 'Bulk Operation Complete',\n message:\n 'Successfully processed {{successCount}} of {{totalCount}} items. {{#failedCount}}{{failedCount}} items failed.{{/failedCount}}',\n variables: ['successCount', 'totalCount', 'failedCount'],\n type: 'success',\n isImportant: false,\n enabled: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n },\n];\n\n// ============================================================================\n// ALL TEMPLATES\n// ============================================================================\n\nexport const ALL_STANDARD_TEMPLATES: NotificationTemplate[] = [\n ...ACCOUNT_TEMPLATES,\n ...REPORT_TEMPLATES,\n ...PROMOTIONAL_TEMPLATES,\n ...SYSTEM_TEMPLATES,\n ...ACTIVITY_TEMPLATES,\n];\n\n/**\n * Get template by event type\n */\nexport function getTemplateByEventType(\n eventType: StandardEventType | string\n): NotificationTemplate | undefined {\n return ALL_STANDARD_TEMPLATES.find((t) => t.eventType === eventType);\n}\n\n/**\n * Get templates by category\n */\nexport function getTemplatesByCategory(\n category: NotificationCategory\n): NotificationTemplate[] {\n return ALL_STANDARD_TEMPLATES.filter((t) => t.category === category);\n}\n\n/**\n * Get all enabled templates\n */\nexport function getEnabledTemplates(): NotificationTemplate[] {\n return ALL_STANDARD_TEMPLATES.filter((t) => t.enabled);\n}\n","/**\n * Event Registry\n *\n * Manages notification event definitions and provides a centralized\n * registry for all standard and custom events.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport type {\n NotificationEventDefinition,\n StandardEventType,\n NotificationCategory,\n} from '../../types/notifications';\n\n// ============================================================================\n// STANDARD EVENT DEFINITIONS\n// ============================================================================\n\n/**\n * Standard event definitions with metadata\n */\nexport const STANDARD_EVENTS: Record<StandardEventType, NotificationEventDefinition> = {\n // Account Events\n ACCOUNT_CREATED: {\n type: 'ACCOUNT_CREATED',\n name: 'Account Created',\n description: 'Triggered when a new user account is created',\n category: 'account',\n notificationType: 'success',\n priority: 'high',\n variables: ['appName', 'userName', 'email'],\n defaultEnabled: true,\n },\n ACCOUNT_WELCOME: {\n type: 'ACCOUNT_WELCOME',\n name: 'Welcome Message',\n description: 'Sent to new users with getting started tips',\n category: 'account',\n notificationType: 'info',\n priority: 'normal',\n variables: ['appName', 'userName'],\n defaultEnabled: true,\n },\n NEW_DEVICE_SIGNIN: {\n type: 'NEW_DEVICE_SIGNIN',\n name: 'New Device Sign-in',\n description: 'Alerts user when account is accessed from a new device',\n category: 'account',\n notificationType: 'warning',\n priority: 'high',\n variables: ['deviceName', 'location', 'timestamp'],\n defaultEnabled: true,\n },\n PASSWORD_CHANGED: {\n type: 'PASSWORD_CHANGED',\n name: 'Password Changed',\n description: 'Confirms password change to user',\n category: 'account',\n notificationType: 'info',\n priority: 'high',\n variables: ['timestamp'],\n defaultEnabled: true,\n },\n PROFILE_UPDATED: {\n type: 'PROFILE_UPDATED',\n name: 'Profile Updated',\n description: 'Confirms profile changes to user',\n category: 'account',\n notificationType: 'success',\n priority: 'low',\n variables: ['changes'],\n defaultEnabled: true,\n },\n ACCOUNT_DELETED: {\n type: 'ACCOUNT_DELETED',\n name: 'Account Deleted',\n description: 'Confirms account deletion',\n category: 'account',\n notificationType: 'info',\n priority: 'high',\n variables: ['deletionDate'],\n defaultEnabled: true,\n },\n\n // Report Events\n DAILY_SUMMARY: {\n type: 'DAILY_SUMMARY',\n name: 'Daily Summary',\n description: 'Daily activity summary',\n category: 'report',\n notificationType: 'info',\n priority: 'low',\n variables: ['date', 'summary'],\n defaultEnabled: false,\n },\n WEEKLY_SUMMARY: {\n type: 'WEEKLY_SUMMARY',\n name: 'Weekly Summary',\n description: 'Weekly activity summary',\n category: 'report',\n notificationType: 'info',\n priority: 'normal',\n variables: ['weekStart', 'weekEnd', 'summary'],\n defaultEnabled: true,\n },\n MONTHLY_SUMMARY: {\n type: 'MONTHLY_SUMMARY',\n name: 'Monthly Summary',\n description: 'Monthly activity summary',\n category: 'report',\n notificationType: 'info',\n priority: 'normal',\n variables: ['monthName', 'year', 'summary'],\n defaultEnabled: true,\n },\n QUARTERLY_SUMMARY: {\n type: 'QUARTERLY_SUMMARY',\n name: 'Quarterly Summary',\n description: 'Quarterly activity review',\n category: 'report',\n notificationType: 'milestone',\n priority: 'normal',\n variables: ['quarter', 'year', 'summary'],\n defaultEnabled: true,\n },\n YEARLY_SUMMARY: {\n type: 'YEARLY_SUMMARY',\n name: 'Yearly Summary',\n description: 'Year-in-review summary',\n category: 'report',\n notificationType: 'milestone',\n priority: 'high',\n variables: ['year', 'summary'],\n defaultEnabled: true,\n },\n\n // Promotional Events\n APP_TIP: {\n type: 'APP_TIP',\n name: 'App Tip',\n description: 'Helpful tips about app features',\n category: 'promotional',\n notificationType: 'info',\n priority: 'low',\n variables: ['tipTitle', 'tipBody', 'tipUrl'],\n defaultEnabled: true,\n },\n HIDDEN_FEATURE: {\n type: 'HIDDEN_FEATURE',\n name: 'Hidden Feature',\n description: 'Reveals lesser-known features to users',\n category: 'promotional',\n notificationType: 'info',\n priority: 'low',\n variables: ['featureName', 'featureDescription', 'featureUrl'],\n defaultEnabled: true,\n },\n NEW_FEATURE_ANNOUNCEMENT: {\n type: 'NEW_FEATURE_ANNOUNCEMENT',\n name: 'New Feature Announcement',\n description: 'Announces new features to users',\n category: 'promotional',\n notificationType: 'announcement',\n priority: 'high',\n variables: ['featureName', 'featureDescription', 'featureUrl'],\n defaultEnabled: true,\n },\n HOLIDAY_GREETING: {\n type: 'HOLIDAY_GREETING',\n name: 'Holiday Greeting',\n description: 'Seasonal and holiday greetings',\n category: 'promotional',\n notificationType: 'info',\n priority: 'low',\n variables: ['holidayName', 'greetingMessage'],\n defaultEnabled: true,\n },\n\n // System Events\n SYSTEM_MAINTENANCE: {\n type: 'SYSTEM_MAINTENANCE',\n name: 'System Maintenance',\n description: 'Scheduled maintenance notifications',\n category: 'system',\n notificationType: 'warning',\n priority: 'high',\n variables: ['date', 'startTime', 'endTime', 'timezone', 'description'],\n defaultEnabled: true,\n },\n APP_UPDATE_AVAILABLE: {\n type: 'APP_UPDATE_AVAILABLE',\n name: 'App Update Available',\n description: 'New version available notification',\n category: 'system',\n notificationType: 'info',\n priority: 'normal',\n variables: ['version', 'releaseNotes'],\n defaultEnabled: true,\n },\n DATA_EXPORT_READY: {\n type: 'DATA_EXPORT_READY',\n name: 'Data Export Ready',\n description: 'User data export is ready for download',\n category: 'system',\n notificationType: 'success',\n priority: 'high',\n variables: ['downloadUrl', 'expiryHours'],\n defaultEnabled: true,\n },\n\n // Activity Events\n ITEM_CREATED: {\n type: 'ITEM_CREATED',\n name: 'Item Created',\n description: 'Generic item creation notification',\n category: 'activity',\n notificationType: 'success',\n priority: 'low',\n variables: ['entityType', 'entityName', 'entityId'],\n defaultEnabled: true,\n },\n ITEM_UPDATED: {\n type: 'ITEM_UPDATED',\n name: 'Item Updated',\n description: 'Generic item update notification',\n category: 'activity',\n notificationType: 'info',\n priority: 'low',\n variables: ['entityType', 'entityName', 'entityId', 'changes'],\n defaultEnabled: true,\n },\n ITEM_DELETED: {\n type: 'ITEM_DELETED',\n name: 'Item Deleted',\n description: 'Generic item deletion notification',\n category: 'activity',\n notificationType: 'info',\n priority: 'low',\n variables: ['entityType', 'entityName'],\n defaultEnabled: true,\n },\n BULK_OPERATION_COMPLETE: {\n type: 'BULK_OPERATION_COMPLETE',\n name: 'Bulk Operation Complete',\n description: 'Bulk operation completion notification',\n category: 'activity',\n notificationType: 'success',\n priority: 'normal',\n variables: ['operationType', 'successCount', 'totalCount', 'failedCount'],\n defaultEnabled: true,\n },\n};\n\n// ============================================================================\n// REGISTRY CLASS\n// ============================================================================\n\n/**\n * Event registry for managing notification events\n */\nclass EventRegistry {\n private events: Map<string, NotificationEventDefinition> = new Map();\n private customEvents: Map<string, NotificationEventDefinition> = new Map();\n\n constructor() {\n // Register all standard events\n Object.values(STANDARD_EVENTS).forEach((event) => {\n this.events.set(event.type, event);\n });\n }\n\n /**\n * Register a custom event\n */\n register(event: NotificationEventDefinition): void {\n this.customEvents.set(event.type, event);\n this.events.set(event.type, event);\n }\n\n /**\n * Unregister a custom event\n */\n unregister(eventType: string): boolean {\n if (this.customEvents.has(eventType)) {\n this.customEvents.delete(eventType);\n this.events.delete(eventType);\n return true;\n }\n return false;\n }\n\n /**\n * Get event definition by type\n */\n get(eventType: string): NotificationEventDefinition | undefined {\n return this.events.get(eventType);\n }\n\n /**\n * Check if event type exists\n */\n has(eventType: string): boolean {\n return this.events.has(eventType);\n }\n\n /**\n * Get all events\n */\n getAll(): NotificationEventDefinition[] {\n return Array.from(this.events.values());\n }\n\n /**\n * Get events by category\n */\n getByCategory(category: NotificationCategory): NotificationEventDefinition[] {\n return this.getAll().filter((e) => e.category === category);\n }\n\n /**\n * Get all custom events\n */\n getCustomEvents(): NotificationEventDefinition[] {\n return Array.from(this.customEvents.values());\n }\n\n /**\n * Get all standard events\n */\n getStandardEvents(): NotificationEventDefinition[] {\n return Object.values(STANDARD_EVENTS);\n }\n\n /**\n * Check if event type is standard\n */\n isStandardEvent(eventType: string): boolean {\n return eventType in STANDARD_EVENTS;\n }\n\n /**\n * Reset registry to standard events only\n */\n reset(): void {\n this.customEvents.clear();\n this.events.clear();\n Object.values(STANDARD_EVENTS).forEach((event) => {\n this.events.set(event.type, event);\n });\n }\n}\n\n// ============================================================================\n// SINGLETON INSTANCE\n// ============================================================================\n\n/**\n * Global event registry instance\n */\nexport const eventRegistry = new EventRegistry();\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Get event definition\n */\nexport function getEventDefinition(\n eventType: StandardEventType | string\n): NotificationEventDefinition | undefined {\n return eventRegistry.get(eventType);\n}\n\n/**\n * Get events by category\n */\nexport function getEventsByCategory(\n category: NotificationCategory\n): NotificationEventDefinition[] {\n return eventRegistry.getByCategory(category);\n}\n\n/**\n * Register a custom event\n */\nexport function registerCustomEvent(\n event: NotificationEventDefinition\n): void {\n eventRegistry.register(event);\n}\n\n/**\n * Get all event types\n */\nexport function getAllEventTypes(): string[] {\n return eventRegistry.getAll().map((e) => e.type);\n}\n","/**\n * useNotificationEvents Hook\n *\n * React hook for triggering notification events.\n * Used by consumer projects to create notifications from standard events.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useCallback } from 'react';\nimport { getEventDefinition } from './registry';\nimport { getTemplateByEventType } from './templates/standard';\nimport { interpolate } from './templates/engine';\nimport type {\n NotificationEventPayload,\n CreateUserNotificationInput,\n UseNotificationEventsReturn,\n} from '../../types/notifications';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface UseNotificationEventsOptions {\n /** App name for templates */\n appName: string;\n /** User ID for notifications */\n userId?: string;\n /** Callback to create notification in project's Firebase */\n onCreateNotification: (input: CreateUserNotificationInput) => Promise<string>;\n /** Whether to log events (debug mode) */\n debug?: boolean;\n}\n\n// ============================================================================\n// HOOK\n// ============================================================================\n\n/**\n * Hook to trigger notification events\n *\n * @example\n * ```tsx\n * const { trigger, triggerAccountCreated } = useNotificationEvents({\n * appName: 'My App',\n * userId: currentUser?.id,\n * onCreateNotification: notificationService.create,\n * });\n *\n * // On user signup\n * await triggerAccountCreated({ userName: 'John', email: 'john@example.com' });\n *\n * // Generic trigger\n * await trigger({\n * type: 'ITEM_CREATED',\n * userId: currentUser.id,\n * data: { entityType: 'Task', entityName: 'My Task' },\n * });\n * ```\n */\nexport function useNotificationEvents(\n options: UseNotificationEventsOptions\n): UseNotificationEventsReturn {\n const { appName, userId, onCreateNotification, debug = false } = options;\n\n /**\n * Process an event and create a notification\n */\n const processEvent = useCallback(\n async (payload: NotificationEventPayload): Promise<void> => {\n const { type, userId: payloadUserId, data, titleOverride, messageOverride, actionUrl, actionText, metadata } = payload;\n\n const targetUserId = payloadUserId || userId;\n if (!targetUserId) {\n if (debug) {\n console.warn('[notification-events] No userId provided for event:', type);\n }\n return;\n }\n\n // Get event definition\n const eventDef = getEventDefinition(type);\n if (!eventDef) {\n if (debug) {\n console.warn('[notification-events] Unknown event type:', type);\n }\n return;\n }\n\n // Get template\n const template = getTemplateByEventType(type);\n\n // Build context for interpolation\n const context = {\n appName,\n ...data,\n };\n\n // Determine title and message\n let title: string;\n let message: string;\n\n if (titleOverride) {\n title = titleOverride;\n } else if (template) {\n title = interpolate(template.title, context);\n } else {\n title = eventDef.name;\n }\n\n if (messageOverride) {\n message = messageOverride;\n } else if (template) {\n message = interpolate(template.message, context);\n } else {\n message = `${eventDef.description}`;\n }\n\n // Build notification input\n const notificationInput: CreateUserNotificationInput = {\n userId: targetUserId,\n title,\n message,\n type: template?.type || eventDef.notificationType,\n category: eventDef.category,\n source: 'event',\n eventType: type,\n isImportant: template?.isImportant,\n actionUrl: actionUrl || (template?.actionUrl ? interpolate(template.actionUrl, context) : undefined),\n actionText: actionText || template?.actionText,\n metadata: {\n ...metadata,\n eventData: data,\n },\n };\n\n if (debug) {\n console.log('[notification-events] Creating notification:', notificationInput);\n }\n\n // Create the notification\n await onCreateNotification(notificationInput);\n },\n [appName, userId, onCreateNotification, debug]\n );\n\n /**\n * Main trigger function\n */\n const trigger = useCallback(\n async (payload: NotificationEventPayload): Promise<void> => {\n await processEvent(payload);\n },\n [processEvent]\n );\n\n // ============================================================================\n // CONVENIENCE METHODS\n // ============================================================================\n\n const triggerAccountCreated = useCallback(\n async (data: { userName: string; email: string }): Promise<void> => {\n if (!userId) return;\n await trigger({\n type: 'ACCOUNT_CREATED',\n userId,\n data,\n });\n },\n [userId, trigger]\n );\n\n const triggerNewDeviceSignin = useCallback(\n async (data: { deviceName: string; location?: string }): Promise<void> => {\n if (!userId) return;\n await trigger({\n type: 'NEW_DEVICE_SIGNIN',\n userId,\n data: {\n ...data,\n timestamp: new Date().toISOString(),\n },\n });\n },\n [userId, trigger]\n );\n\n const triggerPasswordChanged = useCallback(async (): Promise<void> => {\n if (!userId) return;\n await trigger({\n type: 'PASSWORD_CHANGED',\n userId,\n data: {\n timestamp: new Date().toLocaleString(),\n },\n });\n }, [userId, trigger]);\n\n const triggerProfileUpdated = useCallback(\n async (data: { changes: string[] }): Promise<void> => {\n if (!userId) return;\n await trigger({\n type: 'PROFILE_UPDATED',\n userId,\n data: {\n changes: data.changes.join(', '),\n },\n });\n },\n [userId, trigger]\n );\n\n const triggerCrudEvent = useCallback(\n async (data: {\n action: 'created' | 'updated' | 'deleted';\n entityType: string;\n entityName: string;\n }): Promise<void> => {\n if (!userId) return;\n\n const eventTypeMap = {\n created: 'ITEM_CREATED',\n updated: 'ITEM_UPDATED',\n deleted: 'ITEM_DELETED',\n } as const;\n\n await trigger({\n type: eventTypeMap[data.action],\n userId,\n data: {\n entityType: data.entityType,\n entityName: data.entityName,\n },\n });\n },\n [userId, trigger]\n );\n\n const triggerAppTip = useCallback(\n async (data: { tipId: string; title: string; body: string }): Promise<void> => {\n if (!userId) return;\n await trigger({\n type: 'APP_TIP',\n userId,\n data: {\n tipTitle: data.title,\n tipBody: data.body,\n },\n metadata: {\n tipId: data.tipId,\n },\n });\n },\n [userId, trigger]\n );\n\n return {\n trigger,\n triggerAccountCreated,\n triggerNewDeviceSignin,\n triggerPasswordChanged,\n triggerProfileUpdated,\n triggerCrudEvent,\n triggerAppTip,\n };\n}\n\nexport default useNotificationEvents;\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shared-features",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Shared features for Zaions projects - centralized ads,
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "Shared features for Zaions projects - centralized ads, notifications, broadcasts, contacts, and more",
|
|
5
5
|
"author": "Ahsan Mahmood <aoneahsan@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"shared-features",
|
|
14
14
|
"ads",
|
|
15
15
|
"campaigns",
|
|
16
|
+
"notifications",
|
|
17
|
+
"broadcasts",
|
|
18
|
+
"in-app-notifications",
|
|
16
19
|
"react",
|
|
17
20
|
"firebase",
|
|
18
21
|
"cross-promotion"
|
|
@@ -46,6 +49,11 @@
|
|
|
46
49
|
"types": "./dist/types/index.d.ts",
|
|
47
50
|
"import": "./dist/types/index.js",
|
|
48
51
|
"require": "./dist/types/index.cjs"
|
|
52
|
+
},
|
|
53
|
+
"./notifications": {
|
|
54
|
+
"types": "./dist/notifications/index.d.ts",
|
|
55
|
+
"import": "./dist/notifications/index.js",
|
|
56
|
+
"require": "./dist/notifications/index.cjs"
|
|
49
57
|
}
|
|
50
58
|
},
|
|
51
59
|
"files": [
|
|
@@ -65,7 +73,7 @@
|
|
|
65
73
|
"@radix-ui/themes": ">=3.2.1",
|
|
66
74
|
"firebase": ">=12.8.0",
|
|
67
75
|
"lucide-react": ">=0.400.0",
|
|
68
|
-
"react": ">=19.2.
|
|
76
|
+
"react": ">=19.2.3",
|
|
69
77
|
"react-dom": ">=19.2.3",
|
|
70
78
|
"zustand": ">=5.0.10"
|
|
71
79
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AdBanner-CZz8trdz.cjs","sources":["../src/components/ads/AdPanel.tsx","../src/components/ads/variants/SmallPanelVariants.tsx","../src/components/ads/AdSlider.tsx","../src/components/ads/AdModal.tsx","../src/components/ads/variants/LargePanelVariants.tsx","../src/components/ads/AdUpdateModal.tsx","../src/components/ads/AdBanner.tsx"],"sourcesContent":["/**\n * AdPanel Component\n *\n * A simple ad panel component that displays a single campaign.\n * Can be placed in sidebars, footers, or other static locations.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useEffect, useRef } from 'react';\nimport { Box, Flex, Text, Button, IconButton } from '@radix-ui/themes';\nimport { Cross2Icon } from '@radix-ui/react-icons';\nimport { useCampaign } from '../../hooks/useCampaigns';\nimport type { AdPanelProps } from '../../types/campaigns';\n\n/**\n * AdPanel displays a single campaign in a compact panel format.\n *\n * @example\n * ```tsx\n * <AdPanel placement=\"sidebar_panel\" variant=\"small_panel_2\" />\n * ```\n */\nexport function AdPanel({\n placement,\n variant: _variant = 'small_panel_2',\n className,\n}: AdPanelProps) {\n // TODO: variant will be used for different display styles in future variants\n const { campaign, loading, error, recordImpression, recordClick, recordClose } =\n useCampaign({ placement });\n\n const hasRecordedImpression = useRef(false);\n\n // Record impression when campaign is first displayed\n useEffect(() => {\n if (campaign && !hasRecordedImpression.current) {\n hasRecordedImpression.current = true;\n recordImpression(campaign);\n }\n }, [campaign, recordImpression]);\n\n if (loading || error || !campaign) {\n return null;\n }\n\n const handleClick = () => {\n recordClick(campaign);\n const url = campaign.customCtaUrl || campaign.product.url;\n window.open(url, '_blank', 'noopener,noreferrer');\n };\n\n const handleClose = () => {\n recordClose(campaign);\n // Hide the panel (could use state or CSS)\n };\n\n const title = campaign.customTitle || campaign.product.name;\n const tagline = campaign.customTagline || campaign.product.tagline;\n const ctaText = campaign.customCta || 'Learn More';\n const color = campaign.customProductColor || campaign.product.color;\n\n return (\n <Box\n className={className}\n style={{\n border: `1px solid ${color}`,\n borderRadius: '8px',\n padding: '12px',\n backgroundColor: `${color}10`,\n position: 'relative',\n }}\n >\n <IconButton\n size=\"1\"\n variant=\"ghost\"\n onClick={handleClose}\n style={{\n position: 'absolute',\n top: '4px',\n right: '4px',\n }}\n >\n <Cross2Icon />\n </IconButton>\n\n <Flex direction=\"column\" gap=\"2\">\n <Flex align=\"center\" gap=\"2\">\n {campaign.product.icon64 && (\n <Box\n dangerouslySetInnerHTML={{ __html: campaign.product.icon64 }}\n style={{ width: 32, height: 32 }}\n />\n )}\n <Text weight=\"bold\" size=\"3\" style={{ color }}>\n {title}\n </Text>\n </Flex>\n\n <Text size=\"2\" color=\"gray\">\n {tagline}\n </Text>\n\n <Button\n size=\"2\"\n onClick={handleClick}\n style={{ backgroundColor: color }}\n >\n {ctaText}\n </Button>\n </Flex>\n </Box>\n );\n}\n\nexport default AdPanel;\n","/**\n * Small Panel Variants for Advertising\n *\n * 5 variants for small promotional panels:\n * 1. Minimal - Icon + Name + Link\n * 2. Tagline - Icon + Name + Tagline + CTA\n * 3. Features - Icon + Name + Feature pills + CTA\n * 4. Gradient - Full gradient background\n * 5. Card - Elevated card with shadow\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Box, Flex, Text, Button, Link, Card, Badge } from '@radix-ui/themes';\nimport { ExternalLink, Check, X, Sparkles } from 'lucide-react';\nimport type { CampaignWithProduct, SmallPanelProps } from '../../../types/campaigns';\n\n/**\n * Helper to get display values from campaign\n */\nfunction getDisplayValues(campaign: CampaignWithProduct) {\n const isCustomProduct = !campaign.product.icon64 && campaign.customIcon;\n\n return {\n displayTitle: campaign.customTitle || campaign.product.name,\n displayTagline: campaign.customTagline || campaign.product.tagline,\n displayCta: campaign.customCta || 'Learn More',\n displayUrl: campaign.customCtaUrl || campaign.product.url,\n displayIcon: campaign.customIcon || campaign.product.icon64 || '',\n displayColor: campaign.customProductColor || campaign.product.color || '#3B82F6',\n displayFeatures: campaign.customFeatures || campaign.product.features || [],\n isCustomProduct,\n };\n}\n\n/**\n * Variant 1: Minimal - Icon + Name + Link\n */\nexport function MinimalVariant({ campaign, onCTAClick, onClose }: SmallPanelProps) {\n const { displayTitle, displayCta, displayUrl, displayIcon, displayColor } = getDisplayValues(campaign);\n\n return (\n <Card size=\"1\">\n <Flex align=\"center\" justify=\"between\" gap=\"3\" p=\"2\">\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 32,\n height: 32,\n borderRadius: 'var(--radius-2)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n <Text size=\"2\" weight=\"medium\">\n {displayTitle}\n </Text>\n </Flex>\n <Flex align=\"center\" gap=\"2\">\n <Link\n href={displayUrl}\n target=\"_blank\"\n onClick={onCTAClick}\n style={{ textDecoration: 'none' }}\n >\n <Flex align=\"center\" gap=\"1\">\n <Text size=\"2\" color=\"blue\">\n {displayCta}\n </Text>\n <ExternalLink size={14} />\n </Flex>\n </Link>\n <Button variant=\"ghost\" size=\"1\" color=\"gray\" onClick={onClose}>\n <X size={14} />\n </Button>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\n/**\n * Variant 2: Tagline - Icon + Name + Tagline + CTA Button\n */\nexport function TaglineVariant({ campaign, onCTAClick, onClose }: SmallPanelProps) {\n const { displayTitle, displayTagline, displayCta, displayUrl, displayIcon, displayColor } = getDisplayValues(campaign);\n\n return (\n <Card size=\"1\">\n <Flex align=\"center\" justify=\"between\" gap=\"3\" p=\"3\">\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 40,\n height: 40,\n borderRadius: 'var(--radius-2)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n <Box>\n <Text size=\"2\" weight=\"bold\">\n {displayTitle}\n </Text>\n <Text size=\"1\" color=\"gray\">\n {displayTagline}\n </Text>\n </Box>\n </Flex>\n <Flex align=\"center\" gap=\"2\">\n <Button\n size=\"1\"\n style={{ background: displayColor }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n </Button>\n <Button variant=\"ghost\" size=\"1\" color=\"gray\" onClick={onClose}>\n <X size={14} />\n </Button>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\n/**\n * Variant 3: Features - Icon + Name + Feature pills + CTA\n */\nexport function FeaturesVariant({ campaign, onCTAClick, onClose }: SmallPanelProps) {\n const { displayTitle, displayCta, displayUrl, displayIcon, displayColor, displayFeatures } = getDisplayValues(campaign);\n const features = displayFeatures.slice(0, 2);\n\n return (\n <Card size=\"1\">\n <Flex align=\"center\" justify=\"between\" gap=\"3\" p=\"3\">\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 40,\n height: 40,\n borderRadius: 'var(--radius-2)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n <Box>\n <Text size=\"2\" weight=\"bold\" mb=\"1\">\n {displayTitle}\n </Text>\n <Flex gap=\"1\" wrap=\"wrap\">\n {features.map((feature, i) => (\n <Badge key={i} size=\"1\" variant=\"soft\" color=\"gray\">\n <Check size={10} style={{ marginRight: 2 }} />\n {feature}\n </Badge>\n ))}\n </Flex>\n </Box>\n </Flex>\n <Flex align=\"center\" gap=\"2\">\n <Button\n size=\"1\"\n style={{ background: displayColor }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n </Button>\n <Button variant=\"ghost\" size=\"1\" color=\"gray\" onClick={onClose}>\n <X size={14} />\n </Button>\n </Flex>\n </Flex>\n </Card>\n );\n}\n\n/**\n * Variant 4: Gradient - Full gradient background\n */\nexport function GradientVariant({ campaign, onCTAClick, onClose }: SmallPanelProps) {\n const { displayTitle, displayTagline, displayCta, displayUrl, displayIcon, displayColor } = getDisplayValues(campaign);\n\n return (\n <Box\n style={{\n background: `linear-gradient(135deg, ${displayColor} 0%, color-mix(in srgb, ${displayColor} 80%, black) 100%)`,\n borderRadius: 'var(--radius-3)',\n padding: 'var(--space-3)',\n color: 'white',\n }}\n >\n <Flex align=\"center\" justify=\"between\" gap=\"3\">\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 40,\n height: 40,\n borderRadius: 'var(--radius-2)',\n background: 'rgba(255, 255, 255, 0.2)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n <Box\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n style={{\n color: 'white',\n }}\n />\n </Box>\n <Box>\n <Text size=\"2\" weight=\"bold\" style={{ color: 'white' }}>\n {displayTitle}\n </Text>\n <Text size=\"1\" style={{ color: 'rgba(255, 255, 255, 0.8)' }}>\n {displayTagline}\n </Text>\n </Box>\n </Flex>\n <Flex align=\"center\" gap=\"2\">\n <Button\n size=\"1\"\n variant=\"soft\"\n style={{\n background: 'white',\n color: displayColor,\n }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"1\"\n onClick={onClose}\n style={{ color: 'rgba(255, 255, 255, 0.8)' }}\n >\n <X size={14} />\n </Button>\n </Flex>\n </Flex>\n </Box>\n );\n}\n\n/**\n * Variant 5: Card - Elevated card with shadow and animation\n */\nexport function CardVariant({ campaign, onCTAClick, onClose }: SmallPanelProps) {\n const { displayTitle, displayTagline, displayCta, displayUrl, displayIcon, displayColor } = getDisplayValues(campaign);\n\n return (\n <Card\n size=\"2\"\n style={{\n boxShadow: '0 4px 20px rgba(0, 0, 0, 0.1)',\n transition: 'all 0.2s ease',\n border: `1px solid ${displayColor}20`,\n }}\n >\n <Flex direction=\"column\" gap=\"3\" p=\"1\">\n <Flex align=\"center\" justify=\"between\">\n <Flex align=\"center\" gap=\"1\">\n <Sparkles size={14} color={displayColor} />\n <Text size=\"1\" color=\"gray\" weight=\"medium\">\n RECOMMENDED\n </Text>\n </Flex>\n <Button variant=\"ghost\" size=\"1\" color=\"gray\" onClick={onClose}>\n <X size={14} />\n </Button>\n </Flex>\n\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 48,\n height: 48,\n borderRadius: 'var(--radius-3)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n <Box style={{ flex: 1 }}>\n <Text size=\"2\" weight=\"bold\">\n {displayTitle}\n </Text>\n <Text size=\"1\" color=\"gray\">\n {displayTagline}\n </Text>\n </Box>\n </Flex>\n\n <Button\n size=\"2\"\n style={{ background: displayColor, width: '100%' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={14} />\n </Button>\n </Flex>\n </Card>\n );\n}\n\n/**\n * Get variant component by name\n */\nexport const SMALL_PANEL_VARIANTS = {\n small_panel_1: MinimalVariant,\n small_panel_2: TaglineVariant,\n small_panel_3: FeaturesVariant,\n small_panel_4: GradientVariant,\n small_panel_5: CardVariant,\n};\n\nexport type SmallPanelVariantName = keyof typeof SMALL_PANEL_VARIANTS;\n\nexport function getSmallPanelVariant(variantName: string) {\n return SMALL_PANEL_VARIANTS[variantName as SmallPanelVariantName] || TaglineVariant;\n}\n","/**\n * AdSlider Component\n *\n * Small promotional slider panel for consumer apps.\n * Displays eligible ad campaigns using 5 small panel variants.\n *\n * Placement: Footer, sidebar, between sections\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useEffect, useCallback, useRef } from 'react';\nimport { Box } from '@radix-ui/themes';\nimport { useCampaign } from '../../hooks/useCampaigns';\nimport { getSmallPanelVariant } from './variants/SmallPanelVariants';\nimport type { AdPlacement } from '../../types/campaigns';\n\nexport interface AdSliderProps {\n /** Ad placement (defaults to footer_slider) */\n placement?: AdPlacement;\n /** Custom CSS class */\n className?: string;\n /** Custom styles */\n style?: React.CSSProperties;\n}\n\n/**\n * AdSlider - Small promotional panel\n *\n * @example\n * ```tsx\n * <AdSlider placement=\"footer_slider\" />\n * <AdSlider placement=\"sidebar_panel\" className=\"my-ad\" />\n * ```\n */\nexport function AdSlider({\n placement = 'footer_slider',\n className,\n style,\n}: AdSliderProps) {\n const hasTrackedImpression = useRef(false);\n\n const {\n campaign,\n loading,\n recordImpression,\n recordClick,\n recordClose,\n } = useCampaign({ placement });\n\n // Track impression on mount when campaign is available\n useEffect(() => {\n if (campaign && !hasTrackedImpression.current) {\n hasTrackedImpression.current = true;\n recordImpression(campaign);\n }\n }, [campaign, recordImpression]);\n\n // Handle CTA click\n const handleCTAClick = useCallback(() => {\n if (!campaign) return;\n recordClick(campaign);\n }, [campaign, recordClick]);\n\n // Handle close\n const handleClose = useCallback(() => {\n if (!campaign) return;\n recordClose(campaign);\n }, [campaign, recordClose]);\n\n // Don't render if loading or no campaign\n if (loading || !campaign) {\n return null;\n }\n\n // Get variant component\n const variantName = campaign.variant || 'small_panel_2';\n const VariantComponent = getSmallPanelVariant(variantName);\n\n return (\n <Box className={className} style={style}>\n <VariantComponent\n campaign={campaign}\n onCTAClick={handleCTAClick}\n onClose={handleClose}\n />\n </Box>\n );\n}\n\nexport default AdSlider;\n","/**\n * AdModal Component\n *\n * One-time promotional modal for consumer apps.\n * Displays on first visit to promote products.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useEffect, useCallback, useState, useRef } from 'react';\nimport { Box, Flex, Text, Heading, Button, Dialog, Checkbox } from '@radix-ui/themes';\nimport { ExternalLink, X, Gift } from 'lucide-react';\nimport { useCampaign, useOneTimeAdModal } from '../../hooks/useCampaigns';\nimport type { AdPlacement } from '../../types/campaigns';\nimport { getConfig, isInitialized } from '../../firebase/config';\n\nexport interface AdModalProps {\n /** Ad placement (defaults to onetime_modal) */\n placement?: AdPlacement;\n /** Callback when modal closes */\n onClose?: () => void;\n /** Custom welcome title (when no campaign) */\n welcomeTitle?: string;\n /** Custom welcome description (when no campaign) */\n welcomeDescription?: string;\n}\n\n/**\n * AdModal - One-time promotional modal\n *\n * @example\n * ```tsx\n * <AdModal />\n * <AdModal\n * placement=\"onetime_modal\"\n * welcomeTitle=\"Welcome to My App!\"\n * welcomeDescription=\"Discover amazing features...\"\n * />\n * ```\n */\nexport function AdModal({\n placement = 'onetime_modal',\n onClose,\n welcomeTitle,\n welcomeDescription,\n}: AdModalProps) {\n const [dontShowAgain, setDontShowAgain] = useState(false);\n const hasTrackedImpression = useRef(false);\n\n const { shouldShow, markAsShown } = useOneTimeAdModal();\n\n const {\n campaign,\n loading,\n recordImpression,\n recordClick,\n recordClose,\n } = useCampaign({ placement });\n\n // Track impression when modal shows\n useEffect(() => {\n if (shouldShow && campaign && !hasTrackedImpression.current) {\n hasTrackedImpression.current = true;\n recordImpression(campaign);\n }\n }, [shouldShow, campaign, recordImpression]);\n\n // Handle CTA click\n const handleCTAClick = useCallback(() => {\n if (!campaign) return;\n recordClick(campaign);\n const targetUrl = campaign.customCtaUrl || campaign.product.url;\n window.open(targetUrl, '_blank');\n }, [campaign, recordClick]);\n\n // Handle close\n const handleClose = useCallback(() => {\n if (campaign) {\n recordClose(campaign);\n }\n markAsShown();\n onClose?.();\n }, [campaign, recordClose, markAsShown, onClose]);\n\n // Don't render if shared-features not initialized\n if (!isInitialized()) {\n return null;\n }\n\n // Don't show if not eligible or loading\n if (!shouldShow || loading) {\n return null;\n }\n\n // Show welcome modal without campaign\n if (!campaign) {\n const config = getConfig();\n const defaultTitle = welcomeTitle || `Welcome to ${config.projectName}!`;\n const defaultDesc = welcomeDescription || 'Discover amazing features and tools at your fingertips.';\n\n return (\n <Dialog.Root open={true} onOpenChange={(open) => !open && handleClose()}>\n <Dialog.Content style={{ maxWidth: 450 }}>\n <Dialog.Title>\n <Flex align=\"center\" gap=\"2\">\n <Gift size={24} />\n {defaultTitle}\n </Flex>\n </Dialog.Title>\n <Dialog.Description size=\"2\" mb=\"4\">\n {defaultDesc}\n </Dialog.Description>\n\n <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n <Dialog.Close>\n <Button variant=\"soft\" color=\"gray\">\n Start Exploring\n </Button>\n </Dialog.Close>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n }\n\n const { product } = campaign;\n const displayTitle = campaign.customTitle || product.name;\n const displayTagline = campaign.customTagline || product.tagline;\n const displayDescription = campaign.customDescription || product.description;\n const displayCta = campaign.customCta || 'Learn More';\n const displayIcon = campaign.customIcon || product.icon128 || product.icon64 || '';\n const displayColor = campaign.customProductColor || product.color || '#3B82F6';\n const displayFeatures = campaign.customFeatures || product.features || [];\n\n return (\n <Dialog.Root open={true} onOpenChange={(open) => !open && handleClose()}>\n <Dialog.Content style={{ maxWidth: 500 }}>\n <Flex justify=\"end\" mb=\"2\">\n <Dialog.Close>\n <Button variant=\"ghost\" size=\"1\" color=\"gray\">\n <X size={16} />\n </Button>\n </Dialog.Close>\n </Flex>\n\n <Flex direction=\"column\" align=\"center\" gap=\"4\" p=\"4\" style={{ textAlign: 'center' }}>\n <Box\n style={{\n width: 96,\n height: 96,\n borderRadius: 'var(--radius-4)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n\n <Box>\n <Heading size=\"5\" weight=\"bold\" mb=\"2\">\n {displayTitle}\n </Heading>\n <Text size=\"3\" color=\"gray\">\n {displayTagline}\n </Text>\n </Box>\n\n <Text size=\"2\" color=\"gray\" style={{ maxWidth: 350, lineHeight: 1.6 }}>\n {displayDescription}\n </Text>\n\n <Flex wrap=\"wrap\" gap=\"2\" justify=\"center\">\n {displayFeatures.slice(0, 4).map((feature, i) => (\n <Box\n key={i}\n style={{\n padding: 'var(--space-1) var(--space-2)',\n borderRadius: 'var(--radius-2)',\n background: 'var(--gray-a3)',\n fontSize: 'var(--font-size-1)',\n }}\n >\n {feature}\n </Box>\n ))}\n </Flex>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, marginTop: 'var(--space-2)' }}\n onClick={handleCTAClick}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n\n <Flex align=\"center\" gap=\"2\" mt=\"2\">\n <Checkbox\n checked={dontShowAgain}\n onCheckedChange={(checked) => setDontShowAgain(checked === true)}\n />\n <Text size=\"1\" color=\"gray\">\n Don't show this again\n </Text>\n </Flex>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nexport default AdModal;\n","/**\n * Large Panel Variants for Advertising\n *\n * 5 variants for large promotional panels (modals, sliders):\n * 1. Hero - Large icon + description + CTA\n * 2. Feature Grid - 2x2 grid of features\n * 3. Testimonial - Quote + product info\n * 4. Comparison - Before/After comparison\n * 5. Video - Animated preview + play button\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { Box, Flex, Text, Heading, Button, Card, Grid } from '@radix-ui/themes';\nimport { ExternalLink, Check, X, Play, Quote } from 'lucide-react';\nimport type { CampaignWithProduct, LargePanelProps } from '../../../types/campaigns';\n\n/**\n * Helper to get display values from campaign\n */\nfunction getDisplayValues(campaign: CampaignWithProduct) {\n const isCustomProduct = !campaign.product.icon64 && campaign.customIcon;\n\n return {\n displayTitle: campaign.customTitle || campaign.product.name,\n displayTagline: campaign.customTagline || campaign.product.tagline,\n displayDescription: campaign.customDescription || campaign.product.description,\n displayCta: campaign.customCta || 'Learn More',\n displayUrl: campaign.customCtaUrl || campaign.product.url,\n displayIcon64: campaign.customIcon || campaign.product.icon64 || '',\n displayIcon128: campaign.customIcon || campaign.product.icon128 || campaign.product.icon64 || '',\n displayColor: campaign.customProductColor || campaign.product.color || '#3B82F6',\n displayFeatures: campaign.customFeatures || campaign.product.features || [],\n isCustomProduct,\n };\n}\n\n// Default testimonial quotes (can be overridden by campaign data)\nconst DEFAULT_TESTIMONIALS: Record<string, string> = {\n 'video-controls-plus':\n '\"Finally, I have complete control over video playback. The keyboard shortcuts save me so much time!\"',\n 'ztools-web':\n '\"300+ tools in one place. I use it daily for encoding, formatting, and data conversion tasks.\"',\n 'ztools-extension': '\"Quick access to all my favorite tools right from the browser. Super convenient!\"',\n 'pregnancy-pal-android':\n '\"The weekly updates and kick counter are amazing. Best pregnancy tracking app!\"',\n 'pregnancy-pal-web':\n '\"Love being able to access my pregnancy data from any device. The sync is seamless.\"',\n 'lab-system-web': '\"Streamlined our entire lab workflow. Sample tracking has never been easier.\"',\n};\n\n// Default comparison data (can be overridden by campaign data)\nconst DEFAULT_COMPARISONS: Record<string, { before: string[]; after: string[] }> = {\n 'video-controls-plus': {\n before: ['Limited playback control', 'No keyboard shortcuts', 'Manual ad skipping', 'No speed control'],\n after: ['Full playback control', 'Custom shortcuts', 'Auto ad skip', '0.1x - 16x speed'],\n },\n 'ztools-web': {\n before: ['Multiple websites', 'Scattered tools', 'No offline access', 'Ads everywhere'],\n after: ['One destination', '300+ tools', 'Works offline', 'Ad-free experience'],\n },\n 'ztools-extension': {\n before: ['Open new tabs', 'Search for tools', 'Copy/paste repeatedly', 'Time wasted'],\n after: ['Instant access', 'Quick search', 'One-click actions', 'Time saved'],\n },\n 'pregnancy-pal-android': {\n before: ['Paper tracking', 'Forget updates', 'Manual counting', 'Scattered info'],\n after: ['Digital diary', 'Weekly reminders', 'Auto tracking', 'All in one app'],\n },\n 'pregnancy-pal-web': {\n before: ['Phone only', 'No backup', 'Limited access', 'Data silos'],\n after: ['Any device', 'Cloud sync', 'Always available', 'Unified data'],\n },\n 'lab-system-web': {\n before: ['Paper records', 'Manual tracking', 'Error prone', 'Slow reports'],\n after: ['Digital records', 'Auto tracking', 'Accurate data', 'Instant reports'],\n },\n};\n\n/**\n * Variant 1: Hero - Large icon + description + CTA\n */\nexport function HeroVariant({\n campaign,\n onCTAClick,\n showIndicator,\n currentIndex,\n totalCount,\n}: LargePanelProps) {\n const { displayTitle, displayTagline, displayDescription, displayCta, displayUrl, displayIcon128, displayColor } = getDisplayValues(campaign);\n\n return (\n <Flex direction=\"column\" align=\"center\" gap=\"4\" p=\"5\" style={{ textAlign: 'center' }}>\n {showIndicator && currentIndex !== undefined && totalCount !== undefined && (\n <Text size=\"1\" color=\"gray\" style={{ position: 'absolute', top: 16, right: 16 }}>\n {currentIndex + 1} / {totalCount}\n </Text>\n )}\n\n <Box\n style={{\n width: 80,\n height: 80,\n borderRadius: 'var(--radius-4)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon128 }}\n />\n\n <Heading size=\"5\" weight=\"bold\">\n {displayTitle}\n </Heading>\n\n <Text size=\"3\" color=\"gray\">\n {displayTagline}\n </Text>\n\n <Text size=\"2\" color=\"gray\" style={{ maxWidth: 300, lineHeight: 1.6 }}>\n {displayDescription}\n </Text>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, marginTop: 'var(--space-2)' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n </Flex>\n );\n}\n\n/**\n * Variant 2: Feature Grid - 2x2 grid of features\n */\nexport function FeatureGridVariant({\n campaign,\n onCTAClick,\n showIndicator,\n currentIndex,\n totalCount,\n}: LargePanelProps) {\n const { displayTitle, displayCta, displayUrl, displayIcon64, displayColor, displayFeatures } = getDisplayValues(campaign);\n const features = displayFeatures.slice(0, 4);\n\n return (\n <Flex direction=\"column\" gap=\"4\" p=\"5\">\n {showIndicator && currentIndex !== undefined && totalCount !== undefined && (\n <Text size=\"1\" color=\"gray\" style={{ position: 'absolute', top: 16, right: 16 }}>\n {currentIndex + 1} / {totalCount}\n </Text>\n )}\n\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 48,\n height: 48,\n borderRadius: 'var(--radius-3)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon64 }}\n />\n <Heading size=\"4\" weight=\"bold\">\n {displayTitle}\n </Heading>\n </Flex>\n\n <Grid columns=\"2\" gap=\"3\">\n {features.map((feature, i) => (\n <Card key={i} size=\"1\" style={{ background: 'var(--gray-a2)' }}>\n <Flex align=\"center\" gap=\"2\" p=\"2\">\n <Flex\n align=\"center\"\n justify=\"center\"\n style={{\n width: 24,\n height: 24,\n borderRadius: '50%',\n background: displayColor,\n color: 'white',\n fontSize: 12,\n fontWeight: 'bold',\n flexShrink: 0,\n }}\n >\n {i + 1}\n </Flex>\n <Text size=\"2\">{feature}</Text>\n </Flex>\n </Card>\n ))}\n </Grid>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, width: '100%' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n </Flex>\n );\n}\n\n/**\n * Variant 3: Testimonial - Quote + product info\n */\nexport function TestimonialVariant({\n campaign,\n onCTAClick,\n showIndicator,\n currentIndex,\n totalCount,\n}: LargePanelProps) {\n const { product } = campaign;\n const { displayTitle, displayTagline, displayCta, displayUrl, displayIcon64, displayColor } = getDisplayValues(campaign);\n const quote = DEFAULT_TESTIMONIALS[product.id] || '\"An amazing tool that makes my work easier every day.\"';\n\n return (\n <Flex direction=\"column\" gap=\"4\" p=\"5\" style={{ background: 'var(--gray-a2)', borderRadius: 'var(--radius-3)' }}>\n {showIndicator && currentIndex !== undefined && totalCount !== undefined && (\n <Text size=\"1\" color=\"gray\" style={{ position: 'absolute', top: 16, right: 16 }}>\n {currentIndex + 1} / {totalCount}\n </Text>\n )}\n\n <Box style={{ position: 'relative', padding: 'var(--space-3)' }}>\n <Quote\n size={32}\n style={{\n position: 'absolute',\n top: 0,\n left: '50%',\n transform: 'translateX(-50%)',\n opacity: 0.15,\n color: displayColor,\n }}\n />\n <Text size=\"3\" style={{ fontStyle: 'italic', textAlign: 'center', lineHeight: 1.6 }}>\n {quote}\n </Text>\n <Text size=\"2\" color=\"gray\" style={{ textAlign: 'center', marginTop: 'var(--space-2)' }}>\n — Happy User\n </Text>\n </Box>\n\n <Card size=\"1\">\n <Flex align=\"center\" gap=\"3\" p=\"3\">\n <Box\n style={{\n width: 48,\n height: 48,\n borderRadius: 'var(--radius-3)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon64 }}\n />\n <Box>\n <Text size=\"2\" weight=\"bold\">\n {displayTitle}\n </Text>\n <Text size=\"1\" color=\"gray\">\n {displayTagline}\n </Text>\n </Box>\n </Flex>\n </Card>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, width: '100%' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n </Flex>\n );\n}\n\n/**\n * Variant 4: Comparison - Before/After comparison\n */\nexport function ComparisonVariant({\n campaign,\n onCTAClick,\n showIndicator,\n currentIndex,\n totalCount,\n}: LargePanelProps) {\n const { product } = campaign;\n const { displayTitle, displayCta, displayUrl, displayIcon64, displayColor } = getDisplayValues(campaign);\n const comparison = DEFAULT_COMPARISONS[product.id] || {\n before: ['Old way', 'Manual process', 'Time consuming', 'Limited features'],\n after: ['Better way', 'Automated', 'Fast & easy', 'Full features'],\n };\n\n return (\n <Flex direction=\"column\" gap=\"4\" p=\"5\">\n {showIndicator && currentIndex !== undefined && totalCount !== undefined && (\n <Text size=\"1\" color=\"gray\" style={{ position: 'absolute', top: 16, right: 16 }}>\n {currentIndex + 1} / {totalCount}\n </Text>\n )}\n\n <Flex align=\"center\" gap=\"3\">\n <Box\n style={{\n width: 48,\n height: 48,\n borderRadius: 'var(--radius-3)',\n background: `color-mix(in srgb, ${displayColor} 15%, transparent)`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon64 }}\n />\n <Heading size=\"4\" weight=\"bold\">\n {displayTitle}\n </Heading>\n </Flex>\n\n <Flex gap=\"3\">\n <Box\n style={{\n flex: 1,\n padding: 'var(--space-3)',\n borderRadius: 'var(--radius-2)',\n background: 'rgba(239, 68, 68, 0.1)',\n }}\n >\n <Text size=\"1\" weight=\"bold\" color=\"red\" mb=\"2\" style={{ textTransform: 'uppercase' }}>\n Before\n </Text>\n {comparison.before.map((item, i) => (\n <Flex key={i} align=\"center\" gap=\"2\" mb=\"1\">\n <X size={12} color=\"var(--red-9)\" />\n <Text size=\"1\">{item}</Text>\n </Flex>\n ))}\n </Box>\n\n <Box\n style={{\n flex: 1,\n padding: 'var(--space-3)',\n borderRadius: 'var(--radius-2)',\n background: 'rgba(16, 185, 129, 0.1)',\n }}\n >\n <Text size=\"1\" weight=\"bold\" color=\"green\" mb=\"2\" style={{ textTransform: 'uppercase' }}>\n After\n </Text>\n {comparison.after.map((item, i) => (\n <Flex key={i} align=\"center\" gap=\"2\" mb=\"1\">\n <Check size={12} color=\"var(--green-9)\" />\n <Text size=\"1\">{item}</Text>\n </Flex>\n ))}\n </Box>\n </Flex>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, width: '100%' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n </Flex>\n );\n}\n\n/**\n * Variant 5: Video - Animated preview + play button\n */\nexport function VideoVariant({\n campaign,\n onCTAClick,\n showIndicator,\n currentIndex,\n totalCount,\n}: LargePanelProps) {\n const { displayTitle, displayTagline, displayCta, displayUrl, displayIcon128, displayColor } = getDisplayValues(campaign);\n\n return (\n <Flex direction=\"column\" align=\"center\" gap=\"4\" p=\"5\" style={{ textAlign: 'center' }}>\n {showIndicator && currentIndex !== undefined && totalCount !== undefined && (\n <Text size=\"1\" color=\"gray\" style={{ position: 'absolute', top: 16, right: 16 }}>\n {currentIndex + 1} / {totalCount}\n </Text>\n )}\n\n <Box\n style={{\n position: 'relative',\n width: 140,\n height: 140,\n borderRadius: 'var(--radius-4)',\n background: `linear-gradient(135deg, color-mix(in srgb, ${displayColor} 20%, transparent), color-mix(in srgb, ${displayColor} 40%, transparent))`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <Box\n style={{\n animation: 'shared-features-pulse 2s ease-in-out infinite',\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon128 }}\n />\n <Flex\n align=\"center\"\n justify=\"center\"\n style={{\n position: 'absolute',\n width: 56,\n height: 56,\n borderRadius: '50%',\n background: 'rgba(255, 255, 255, 0.95)',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)',\n cursor: 'pointer',\n transition: 'transform 0.2s ease',\n }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n <Play size={24} fill={displayColor} color={displayColor} />\n </Flex>\n </Box>\n\n <Heading size=\"5\" weight=\"bold\">\n {displayTitle}\n </Heading>\n\n <Text size=\"2\" color=\"gray\">\n {displayTagline}\n </Text>\n\n <Button\n size=\"3\"\n style={{ background: displayColor, marginTop: 'var(--space-2)' }}\n onClick={() => {\n onCTAClick?.();\n window.open(displayUrl, '_blank');\n }}\n >\n {displayCta}\n <ExternalLink size={16} />\n </Button>\n\n <style>{`\n @keyframes shared-features-pulse {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(1.1); }\n }\n `}</style>\n </Flex>\n );\n}\n\n/**\n * Get variant component by name\n */\nexport const LARGE_PANEL_VARIANTS = {\n large_slider_1: HeroVariant,\n large_slider_2: FeatureGridVariant,\n large_slider_3: TestimonialVariant,\n large_slider_4: ComparisonVariant,\n large_slider_5: VideoVariant,\n};\n\nexport type LargePanelVariantName = keyof typeof LARGE_PANEL_VARIANTS;\n\nexport function getLargePanelVariant(variantName: string) {\n return LARGE_PANEL_VARIANTS[variantName as LargePanelVariantName] || HeroVariant;\n}\n","/**\n * AdUpdateModal Component\n *\n * Big slider modal shown when the app updates.\n * Displays a carousel of promotional campaigns with 5 large variants.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useEffect, useCallback, useState, useRef } from 'react';\nimport { Box, Flex, Text, Button, Dialog, IconButton } from '@radix-ui/themes';\nimport { ChevronLeft, ChevronRight, X } from 'lucide-react';\nimport { useCampaigns, useUpdateAdModal } from '../../hooks/useCampaigns';\nimport { getLargePanelVariant } from './variants/LargePanelVariants';\nimport type { AdPlacement } from '../../types/campaigns';\n\nexport interface AdUpdateModalProps {\n /** Ad placement (defaults to update_modal) */\n placement?: AdPlacement;\n /** Maximum number of campaigns to show */\n maxCampaigns?: number;\n /** Auto-advance interval in ms (0 to disable) */\n autoAdvanceInterval?: number;\n /** Callback when modal closes */\n onClose?: () => void;\n}\n\n/**\n * AdUpdateModal - Big slider promotional modal\n *\n * @example\n * ```tsx\n * <AdUpdateModal />\n * <AdUpdateModal\n * placement=\"update_modal\"\n * maxCampaigns={5}\n * autoAdvanceInterval={5000}\n * />\n * ```\n */\nexport function AdUpdateModal({\n placement = 'update_modal',\n maxCampaigns = 5,\n autoAdvanceInterval = 5000,\n onClose,\n}: AdUpdateModalProps) {\n const [currentIndex, setCurrentIndex] = useState(0);\n const autoAdvanceRef = useRef<NodeJS.Timeout | null>(null);\n const trackedImpressions = useRef<Set<string>>(new Set());\n\n const { shouldShow, currentVersion, markAsShown } = useUpdateAdModal();\n\n const {\n campaigns,\n loading,\n recordImpression,\n recordClick,\n recordClose,\n } = useCampaigns({ placement, maxCampaigns });\n\n // Track impression for current campaign\n useEffect(() => {\n if (shouldShow && campaigns.length > 0 && currentIndex < campaigns.length) {\n const campaign = campaigns[currentIndex];\n if (campaign && !trackedImpressions.current.has(campaign.id)) {\n trackedImpressions.current.add(campaign.id);\n recordImpression(campaign);\n }\n }\n }, [shouldShow, campaigns, currentIndex, recordImpression]);\n\n // Auto-advance carousel\n useEffect(() => {\n if (!shouldShow || campaigns.length <= 1 || autoAdvanceInterval <= 0) return;\n\n autoAdvanceRef.current = setInterval(() => {\n setCurrentIndex((prev) => (prev + 1) % campaigns.length);\n }, autoAdvanceInterval);\n\n return () => {\n if (autoAdvanceRef.current) {\n clearInterval(autoAdvanceRef.current);\n }\n };\n }, [shouldShow, campaigns.length, autoAdvanceInterval]);\n\n // Reset auto-advance on manual navigation\n const resetAutoAdvance = useCallback(() => {\n if (autoAdvanceRef.current) {\n clearInterval(autoAdvanceRef.current);\n }\n if (autoAdvanceInterval > 0 && campaigns.length > 1) {\n autoAdvanceRef.current = setInterval(() => {\n setCurrentIndex((prev) => (prev + 1) % campaigns.length);\n }, autoAdvanceInterval);\n }\n }, [autoAdvanceInterval, campaigns.length]);\n\n // Navigate to previous slide\n const goToPrevious = useCallback(() => {\n setCurrentIndex((prev) => (prev - 1 + campaigns.length) % campaigns.length);\n resetAutoAdvance();\n }, [campaigns.length, resetAutoAdvance]);\n\n // Navigate to next slide\n const goToNext = useCallback(() => {\n setCurrentIndex((prev) => (prev + 1) % campaigns.length);\n resetAutoAdvance();\n }, [campaigns.length, resetAutoAdvance]);\n\n // Navigate to specific slide\n const goToSlide = useCallback(\n (index: number) => {\n setCurrentIndex(index);\n resetAutoAdvance();\n },\n [resetAutoAdvance]\n );\n\n // Handle keyboard navigation\n useEffect(() => {\n if (!shouldShow) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowLeft') {\n goToPrevious();\n } else if (e.key === 'ArrowRight') {\n goToNext();\n } else if (e.key === 'Escape') {\n handleClose();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldShow, goToPrevious, goToNext]);\n\n // Handle CTA click\n const handleCTAClick = useCallback(() => {\n const campaign = campaigns[currentIndex];\n if (!campaign) return;\n recordClick(campaign);\n }, [campaigns, currentIndex, recordClick]);\n\n // Handle close\n const handleClose = useCallback(() => {\n campaigns.forEach((campaign) => {\n recordClose(campaign);\n });\n markAsShown();\n onClose?.();\n }, [campaigns, recordClose, markAsShown, onClose]);\n\n // Don't show if not eligible or loading\n if (!shouldShow || loading || campaigns.length === 0) {\n return null;\n }\n\n const currentCampaign = campaigns[currentIndex];\n if (!currentCampaign) return null;\n\n const variantName = currentCampaign.variant || 'large_slider_1';\n const VariantComponent = getLargePanelVariant(variantName);\n\n return (\n <Dialog.Root open={true} onOpenChange={(open) => !open && handleClose()}>\n <Dialog.Content\n style={{\n maxWidth: 550,\n padding: 0,\n overflow: 'hidden',\n }}\n >\n {/* Header */}\n <Flex\n align=\"center\"\n justify=\"between\"\n p=\"3\"\n style={{\n borderBottom: '1px solid var(--gray-a5)',\n }}\n >\n <Text size=\"2\" color=\"gray\">\n What's New in v{currentVersion}\n </Text>\n <Dialog.Close>\n <IconButton variant=\"ghost\" size=\"1\" color=\"gray\">\n <X size={16} />\n </IconButton>\n </Dialog.Close>\n </Flex>\n\n {/* Slider Content */}\n <Box style={{ position: 'relative', minHeight: 350 }}>\n <VariantComponent\n campaign={currentCampaign}\n onCTAClick={handleCTAClick}\n showIndicator={campaigns.length > 1}\n currentIndex={currentIndex}\n totalCount={campaigns.length}\n />\n\n {/* Navigation Arrows */}\n {campaigns.length > 1 && (\n <>\n <IconButton\n variant=\"soft\"\n size=\"2\"\n style={{\n position: 'absolute',\n left: 8,\n top: '50%',\n transform: 'translateY(-50%)',\n opacity: 0.8,\n }}\n onClick={goToPrevious}\n >\n <ChevronLeft size={20} />\n </IconButton>\n <IconButton\n variant=\"soft\"\n size=\"2\"\n style={{\n position: 'absolute',\n right: 8,\n top: '50%',\n transform: 'translateY(-50%)',\n opacity: 0.8,\n }}\n onClick={goToNext}\n >\n <ChevronRight size={20} />\n </IconButton>\n </>\n )}\n </Box>\n\n {/* Footer with Dots */}\n {campaigns.length > 1 && (\n <Flex\n align=\"center\"\n justify=\"center\"\n gap=\"2\"\n p=\"3\"\n style={{\n borderTop: '1px solid var(--gray-a5)',\n }}\n >\n {campaigns.map((_, index) => (\n <Box\n key={index}\n onClick={() => goToSlide(index)}\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n background:\n index === currentIndex ? 'var(--accent-9)' : 'var(--gray-a6)',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n }}\n />\n ))}\n </Flex>\n )}\n\n {/* Skip All Button */}\n <Flex justify=\"center\" pb=\"3\">\n <Button variant=\"ghost\" size=\"1\" color=\"gray\" onClick={handleClose}>\n Skip All\n </Button>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nexport default AdUpdateModal;\n","/**\n * AdBanner Component (Permanent)\n *\n * A sleek, modern advertising banner that showcases products.\n * Clean design with smooth animations and auto-rotation.\n *\n * @author Ahsan Mahmood <aoneahsan@gmail.com>\n */\n\nimport { useEffect, useState, useCallback, useRef } from 'react';\nimport { Box, Flex, Text, Button, Badge } from '@radix-ui/themes';\nimport { ExternalLink, Sparkles, Check } from 'lucide-react';\nimport { useCampaigns } from '../../hooks/useCampaigns';\nimport type { AdPlacement, CampaignWithProduct } from '../../types/campaigns';\n\nexport interface AdBannerProps {\n /** Ad placement (defaults to home_banner) */\n placement?: AdPlacement;\n /** Rotation interval in ms (default: 10000 = 10 seconds) */\n rotationInterval?: number;\n /** Maximum number of campaigns to fetch */\n maxCampaigns?: number;\n /** Custom CSS class */\n className?: string;\n /** Custom styles */\n style?: React.CSSProperties;\n}\n\n/**\n * AdBanner - Permanent promotional banner with rotation\n *\n * @example\n * ```tsx\n * <AdBanner />\n * <AdBanner placement=\"home_banner\" rotationInterval={5000} />\n * ```\n */\nexport function AdBanner({\n placement = 'home_banner',\n rotationInterval = 10000,\n maxCampaigns = 5,\n className,\n style,\n}: AdBannerProps) {\n const [currentIndex, setCurrentIndex] = useState(0);\n const [isAnimating, setIsAnimating] = useState(false);\n const [progress, setProgress] = useState(0);\n const trackedImpressions = useRef<Set<string>>(new Set());\n\n const {\n campaigns,\n loading,\n recordImpression,\n recordClick,\n } = useCampaigns({ placement, maxCampaigns });\n\n // Track impression for current campaign\n useEffect(() => {\n if (campaigns.length === 0) return;\n const campaign = campaigns[currentIndex];\n if (!campaign || trackedImpressions.current.has(campaign.id)) return;\n\n trackedImpressions.current.add(campaign.id);\n recordImpression(campaign);\n }, [currentIndex, campaigns, recordImpression]);\n\n // Progress bar animation\n useEffect(() => {\n if (campaigns.length <= 1) return;\n\n setProgress(0);\n const progressInterval = 50;\n const steps = rotationInterval / progressInterval;\n let currentStep = 0;\n\n const progressTimer = setInterval(() => {\n currentStep++;\n setProgress((currentStep / steps) * 100);\n\n if (currentStep >= steps) {\n setIsAnimating(true);\n setTimeout(() => {\n setCurrentIndex((prev) => (prev + 1) % campaigns.length);\n setProgress(0);\n currentStep = 0;\n setTimeout(() => setIsAnimating(false), 50);\n }, 200);\n }\n }, progressInterval);\n\n return () => clearInterval(progressTimer);\n }, [campaigns.length, rotationInterval, currentIndex]);\n\n // Handle click\n const handleClick = useCallback(\n (campaign: CampaignWithProduct) => {\n recordClick(campaign);\n const targetUrl = campaign.customCtaUrl || campaign.product.url;\n window.open(targetUrl, '_blank');\n },\n [recordClick]\n );\n\n // Go to specific slide\n const goToSlide = useCallback((index: number) => {\n if (index === currentIndex) return;\n setIsAnimating(true);\n setTimeout(() => {\n setCurrentIndex(index);\n setProgress(0);\n setTimeout(() => setIsAnimating(false), 50);\n }, 200);\n }, [currentIndex]);\n\n if (loading || campaigns.length === 0) return null;\n\n const campaign = campaigns[currentIndex];\n if (!campaign) return null;\n\n const { product } = campaign;\n const displayTitle = campaign.customTitle || product.name;\n const displayTagline = campaign.customTagline || product.tagline;\n const displayCta = campaign.customCta || 'Learn More';\n const displayColor = campaign.customProductColor || product.color || '#3B82F6';\n const displayIcon = campaign.customIcon || product.icon64 || '';\n const displayFeatures = campaign.customFeatures || product.features || [];\n\n return (\n <Box\n className={className}\n style={{\n background: 'var(--color-background)',\n borderBottom: '1px solid var(--gray-a4)',\n position: 'relative',\n ...style,\n }}\n >\n {/* Colored accent bar */}\n <Box style={{ height: 3, background: displayColor }} />\n\n {/* Main content wrapper */}\n <Box\n style={{\n background: `linear-gradient(90deg, ${displayColor}08 0%, ${displayColor}12 50%, ${displayColor}08 100%)`,\n }}\n >\n {/* Label */}\n <Flex align=\"center\" justify=\"center\" gap=\"2\" py=\"2\">\n <Sparkles size={12} color={displayColor} />\n <Text\n size=\"1\"\n weight=\"medium\"\n style={{\n color: displayColor,\n fontSize: '11px',\n letterSpacing: '1.5px',\n textTransform: 'uppercase',\n }}\n >\n Discover Our Products\n </Text>\n <Sparkles size={12} color={displayColor} />\n </Flex>\n\n {/* Content */}\n <Box px=\"4\" py=\"3\">\n <Flex\n direction={{ initial: 'column', sm: 'row' }}\n align=\"center\"\n justify=\"between\"\n gap={{ initial: '3', sm: '4' }}\n style={{\n opacity: isAnimating ? 0 : 1,\n transform: isAnimating ? 'translateX(-10px)' : 'translateX(0)',\n transition: 'all 0.2s ease-out',\n }}\n >\n {/* Left: Product Info */}\n <Flex align=\"center\" gap=\"3\" style={{ flex: 1, minWidth: 0 }}>\n {/* Icon */}\n <Box\n style={{\n width: 56,\n height: 56,\n borderRadius: 12,\n background: `${displayColor}15`,\n border: `1.5px solid ${displayColor}30`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n dangerouslySetInnerHTML={{ __html: displayIcon }}\n />\n\n {/* Text */}\n <Flex direction=\"column\" gap=\"0\" style={{ minWidth: 0 }}>\n <Flex align=\"center\" gap=\"2\">\n <Text size=\"3\" weight=\"bold\">\n {displayTitle}\n </Text>\n <Badge\n size=\"1\"\n style={{\n background: `${displayColor}18`,\n color: displayColor,\n fontSize: '11px',\n fontWeight: 600,\n padding: '3px 8px',\n }}\n >\n {product.type === 'extension' ? 'Extension' : product.type === 'android' ? 'App' : 'Web'}\n </Badge>\n </Flex>\n\n <Text\n size=\"2\"\n color=\"gray\"\n style={{\n marginTop: 4,\n display: '-webkit-box',\n WebkitLineClamp: 1,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {displayTagline}\n </Text>\n\n {/* Features - Desktop */}\n <Flex gap=\"4\" mt=\"2\" display={{ initial: 'none', md: 'flex' }}>\n {displayFeatures.slice(0, 3).map((feature, i) => (\n <Flex key={i} align=\"center\" gap=\"1\">\n <Check size={12} color={displayColor} strokeWidth={3} />\n <Text size=\"2\" style={{ color: 'var(--gray-10)' }}>\n {feature}\n </Text>\n </Flex>\n ))}\n </Flex>\n </Flex>\n </Flex>\n\n {/* Right: CTA Button */}\n <Flex align=\"center\" style={{ flexShrink: 0 }}>\n <Button\n size=\"2\"\n onClick={() => handleClick(campaign)}\n style={{\n background: displayColor,\n color: 'white',\n fontWeight: 600,\n fontSize: '14px',\n padding: '0 20px',\n height: 38,\n boxShadow: `0 2px 8px ${displayColor}40`,\n }}\n >\n {displayCta}\n <ExternalLink size={14} style={{ marginLeft: 6 }} />\n </Button>\n </Flex>\n </Flex>\n </Box>\n\n {/* Progress dots with progress bar */}\n {campaigns.length > 1 && (\n <Flex justify=\"center\" align=\"center\" gap=\"2\" py=\"3\">\n {campaigns.map((c, i) => (\n <Box\n key={i}\n onClick={() => goToSlide(i)}\n style={{\n width: 40,\n height: 4,\n borderRadius: 2,\n background: 'var(--gray-a4)',\n cursor: 'pointer',\n overflow: 'hidden',\n position: 'relative',\n }}\n >\n {/* Progress fill */}\n <Box\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n height: '100%',\n width: i === currentIndex ? `${progress}%` : i < currentIndex ? '100%' : '0%',\n background: c.product?.color || displayColor,\n borderRadius: 2,\n transition: i === currentIndex ? 'none' : 'width 0.3s ease',\n }}\n />\n </Box>\n ))}\n </Flex>\n )}\n </Box>\n </Box>\n );\n}\n\nexport default AdBanner;\n"],"names":["useCampaign","useRef","useEffect","jsxs","Box","jsx","IconButton","Cross2Icon","Flex","Text","Button","getDisplayValues","Card","Link","ExternalLink","X","Badge","Check","Sparkles","useCallback","useState","useOneTimeAdModal","isInitialized","getConfig","Dialog","Gift","Heading","Checkbox","Grid","Quote","Play","useUpdateAdModal","useCampaigns","Fragment","ChevronLeft","ChevronRight","campaign"],"mappings":"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"}
|