omnify-onboarding-package
Version:
A comprehensive onboarding flow component for React applications with 5-step process including profile setup, company setup, analytics connection, asset upload, and brand guidelines.
668 lines (654 loc) • 46.4 kB
JavaScript
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
// ============================================================================
// ONBOARDING STEP DEFINITIONS
// ============================================================================
const ONBOARDING_STEPS = [
{
id: 1,
key: 'profile',
title: 'Welcome & Profile',
description: "Let's get to know you better to personalize your experience.",
icon: '👤',
isCompleted: false,
isActive: true
},
{
id: 2,
key: 'company',
title: 'Company Setup',
description: 'Tell us about your company to tailor recommendations.',
icon: '🏢',
isCompleted: false,
isActive: false
},
{
id: 3,
key: 'analytics',
title: 'Connect Analytics',
description: 'Connect your data source or use demo data.',
icon: '📊',
isCompleted: false,
isActive: false
},
{
id: 4,
key: 'assets',
title: 'Upload Assets',
description: 'Upload past campaign assets for AI analysis.',
icon: '📁',
isCompleted: false,
isActive: false
},
{
id: 5,
key: 'brand',
title: 'Brand Guidelines',
description: 'Set your brand voice and style preferences.',
icon: '🎨',
isCompleted: false,
isActive: false
}
];
// ============================================================================
// ROLE OPTIONS
// ============================================================================
const ROLE_OPTIONS = [
{ value: 'CEO', label: 'CEO / Founder' },
{ value: 'CMO', label: 'CMO / Marketing Director' },
{ value: 'Marketing', label: 'Marketing Manager' },
{ value: 'MarketingTeam', label: 'Marketing Team Member' },
{ value: 'General', label: 'General User' }
];
// ============================================================================
// INDUSTRY OPTIONS
// ============================================================================
const INDUSTRY_OPTIONS = [
'E-commerce & Retail',
'Technology & SaaS',
'Healthcare & Wellness',
'Finance & Insurance',
'Education & Training',
'Real Estate',
'Travel & Hospitality',
'Food & Beverage',
'Fashion & Beauty',
'Automotive',
'Entertainment & Media',
'Professional Services',
'Manufacturing',
'Non-profit',
'Other'
];
// ============================================================================
// MARKETING OBJECTIVES
// ============================================================================
const MARKETING_OBJECTIVES = [
'Increase brand awareness and drive sales',
'Generate leads and conversions',
'Improve customer retention',
'Launch new products/services',
'Expand to new markets',
'Build thought leadership',
'Increase website traffic',
'Improve social media engagement',
'Optimize marketing ROI',
'Other'
];
// ============================================================================
// PLATFORM OPTIONS
// ============================================================================
const PLATFORM_OPTIONS = [
{ value: 'All Platforms', label: 'All Platforms', icon: '🌐' },
{ value: 'Instagram', label: 'Instagram', icon: '📷' },
{ value: 'Facebook', label: 'Facebook', icon: '📘' },
{ value: 'TikTok', label: 'TikTok', icon: '🎵' },
{ value: 'LinkedIn', label: 'LinkedIn', icon: '💼' },
{ value: 'Twitter', label: 'Twitter', icon: '🐦' },
{ value: 'YouTube', label: 'YouTube', icon: '📺' },
{ value: 'Pinterest', label: 'Pinterest', icon: '📌' },
{ value: 'Google Ads', label: 'Google Ads', icon: '🔍' },
{ value: 'Microsoft Ads', label: 'Microsoft Ads', icon: '💻' }
];
// ============================================================================
// TONE OF VOICE OPTIONS
// ============================================================================
const TONE_OF_VOICE_OPTIONS = [
'Professional & Authoritative',
'Friendly & Approachable',
'Bold & Confident',
'Playful & Creative',
'Minimalist & Clean',
'Warm & Personal',
'Technical & Precise',
'Luxury & Premium'
];
// ============================================================================
// TARGET AUDIENCE OPTIONS
// ============================================================================
const TARGET_AUDIENCE_OPTIONS = [
'Young Professionals (22-35)',
'Tech-savvy Millennials (25-40)',
'Business Executives (35-55)',
'Creative Professionals (25-45)',
'Small Business Owners (30-50)',
'Students & Graduates (18-28)',
'Healthcare Professionals (25-50)',
'E-commerce Entrepreneurs (25-45)'
];
// ============================================================================
// BRAND STYLE OPTIONS
// ============================================================================
const BRAND_STYLE_OPTIONS = [
{ value: 'Modern', label: 'Modern', icon: '⭐' },
{ value: 'Classic', label: 'Classic', icon: '🏛️' },
{ value: 'Playful', label: 'Playful', icon: '🎈' },
{ value: 'Minimal', label: 'Minimal', icon: '⚪' },
{ value: 'Bold', label: 'Bold', icon: '💪' },
{ value: 'Elegant', label: 'Elegant', icon: '💎' },
{ value: 'Tech', label: 'Tech', icon: '⚙️' },
{ value: 'Organic', label: 'Organic', icon: '🌱' }
];
// ============================================================================
// BRAND COLORS
// ============================================================================
const BRAND_COLORS = {
primary: [
'#4F69FF', '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4',
'#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE'
],
neutral: [
'#FFFFFF', '#F8F9FA', '#E9ECEF', '#DEE2E6', '#CED4DA',
'#ADB5BD', '#6C757D', '#495057', '#343A40', '#212529'
]
};
// ============================================================================
// FILE UPLOAD CONFIGURATION
// ============================================================================
const FILE_UPLOAD_CONFIG = {
maxFileSize: 10 * 1024 * 1024, // 10MB
acceptedFileTypes: {
'image/*': ['.jpg', '.jpeg', '.png', '.gif', '.webp'],
'application/pdf': ['.pdf'],
'text/csv': ['.csv'],
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
'application/vnd.ms-excel': ['.xls']
},
maxFiles: 20
};
// ============================================================================
// VALIDATION FUNCTIONS FOR EACH STEP
// ============================================================================
const validateProfileStep = (data) => {
const errors = [];
if (!data.firstName.trim()) {
errors.push('First name is required');
}
if (!data.lastName.trim()) {
errors.push('Last name is required');
}
if (!data.role.trim()) {
errors.push('Role is required');
}
return {
isValid: errors.length === 0,
errors
};
};
const validateCompanyStep = (data) => {
const errors = [];
if (!data.companyName.trim()) {
errors.push('Company name is required');
}
if (!data.industry.trim()) {
errors.push('Industry is required');
}
if (!data.objective.trim()) {
errors.push('Marketing objective is required');
}
return {
isValid: errors.length === 0,
errors
};
};
const validateAnalyticsStep = (data) => {
const errors = [];
if (!data.analyticsConnected && data.selectedPlatforms.length === 0) {
errors.push('Please connect analytics or select platforms');
}
return {
isValid: errors.length === 0,
errors
};
};
const validateAssetsStep = (data) => {
const errors = [];
if (data.assets.length === 0 && !data.adCopy.trim()) {
errors.push('Please upload assets or provide ad copy');
}
return {
isValid: errors.length === 0,
errors
};
};
const validateBrandStep = (data) => {
const errors = [];
if (data.brandGuidelines.colors.length === 0) {
errors.push('Please select at least one brand color');
}
if (!data.brandGuidelines.toneOfVoice.trim()) {
errors.push('Please select a tone of voice');
}
if (!data.brandGuidelines.targetAudience.trim()) {
errors.push('Please select a target audience');
}
return {
isValid: errors.length === 0,
errors
};
};
// ============================================================================
// COMPREHENSIVE VALIDATION
// ============================================================================
const validateStep = (step, data) => {
switch (step) {
case 1:
return validateProfileStep(data);
case 2:
return validateCompanyStep(data);
case 3:
return validateAnalyticsStep(data);
case 4:
return validateAssetsStep(data);
case 5:
return validateBrandStep(data);
default:
return { isValid: true, errors: [] };
}
};
const validateAllSteps = (data) => {
const allErrors = [];
const profileValidation = validateProfileStep(data);
const companyValidation = validateCompanyStep(data);
const analyticsValidation = validateAnalyticsStep(data);
const assetsValidation = validateAssetsStep(data);
const brandValidation = validateBrandStep(data);
if (!profileValidation.isValid) {
allErrors.push(...profileValidation.errors);
}
if (!companyValidation.isValid) {
allErrors.push(...companyValidation.errors);
}
if (!analyticsValidation.isValid) {
allErrors.push(...analyticsValidation.errors);
}
if (!assetsValidation.isValid) {
allErrors.push(...assetsValidation.errors);
}
if (!brandValidation.isValid) {
allErrors.push(...brandValidation.errors);
}
return {
isValid: allErrors.length === 0,
errors: allErrors
};
};
const ProfileStep = ({ data, onNext, onDataChange }) => {
const handleInputChange = (field, value) => {
onDataChange({ [field]: value });
};
const isFormValid = () => {
return data.firstName.trim() && data.lastName.trim() && data.role.trim();
};
return (jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-lg p-8 max-w-2xl mx-auto", children: [jsxRuntime.jsxs("div", { className: "text-center mb-8", children: [jsxRuntime.jsx("h2", { className: "text-3xl font-bold text-gray-900 mb-2", children: "Welcome to Omnify!" }), jsxRuntime.jsx("p", { className: "text-gray-600 text-lg", children: "Let's get to know you better to personalize your experience." })] }), jsxRuntime.jsxs("div", { className: "space-y-6", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "firstName", className: "block text-sm font-medium text-gray-700 mb-2", children: "First Name" }), jsxRuntime.jsx("input", { type: "text", id: "firstName", value: data.firstName, onChange: (e) => handleInputChange('firstName', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", placeholder: "Enter your first name" })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "lastName", className: "block text-sm font-medium text-gray-700 mb-2", children: "Last Name" }), jsxRuntime.jsx("input", { type: "text", id: "lastName", value: data.lastName, onChange: (e) => handleInputChange('lastName', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", placeholder: "Enter your last name" })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "role", className: "block text-sm font-medium text-gray-700 mb-2", children: "Your Role" }), jsxRuntime.jsx("select", { id: "role", value: data.role, onChange: (e) => handleInputChange('role', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", children: ROLE_OPTIONS.map((option) => (jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value))) })] })] }), jsxRuntime.jsx("div", { className: "mt-8 flex justify-end", children: jsxRuntime.jsx("button", { onClick: onNext, disabled: !isFormValid(), className: `
px-6 py-3 rounded-md font-medium transition-colors
${isFormValid()
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}
`, children: "Continue \u2192" }) })] }));
};
const CompanyStep = ({ data, onNext, onBack, onDataChange }) => {
const handleInputChange = (field, value) => {
onDataChange({ [field]: value });
};
const isFormValid = () => {
return data.companyName.trim() && data.industry.trim() && data.objective.trim();
};
return (jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-lg p-8 max-w-2xl mx-auto", children: [jsxRuntime.jsxs("div", { className: "text-center mb-8", children: [jsxRuntime.jsx("h2", { className: "text-3xl font-bold text-gray-900 mb-2", children: "Tell us about your company" }), jsxRuntime.jsx("p", { className: "text-gray-600 text-lg", children: "This helps us tailor recommendations and insights for your business." })] }), jsxRuntime.jsxs("div", { className: "space-y-6", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "companyName", className: "block text-sm font-medium text-gray-700 mb-2", children: "Company Name" }), jsxRuntime.jsx("input", { type: "text", id: "companyName", value: data.companyName, onChange: (e) => handleInputChange('companyName', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", placeholder: "Enter your company name" })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "industry", className: "block text-sm font-medium text-gray-700 mb-2", children: "Industry" }), jsxRuntime.jsxs("select", { id: "industry", value: data.industry, onChange: (e) => handleInputChange('industry', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", children: [jsxRuntime.jsx("option", { value: "", children: "Select your industry" }), INDUSTRY_OPTIONS.map((industry) => (jsxRuntime.jsx("option", { value: industry, children: industry }, industry)))] })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "objective", className: "block text-sm font-medium text-gray-700 mb-2", children: "Primary Marketing Objective" }), jsxRuntime.jsx("select", { id: "objective", value: data.objective, onChange: (e) => handleInputChange('objective', e.target.value), className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500", children: MARKETING_OBJECTIVES.map((objective) => (jsxRuntime.jsx("option", { value: objective, children: objective }, objective))) })] })] }), jsxRuntime.jsxs("div", { className: "mt-8 flex justify-between", children: [jsxRuntime.jsx("button", { onClick: onBack, className: "px-6 py-3 border border-gray-300 text-gray-700 rounded-md font-medium hover:bg-gray-50 transition-colors", children: "\u2190 Back" }), jsxRuntime.jsx("button", { onClick: onNext, disabled: !isFormValid(), className: `
px-6 py-3 rounded-md font-medium transition-colors
${isFormValid()
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}
`, children: "Next \u2192" })] })] }));
};
const AnalyticsStep = ({ data, onNext, onBack, onDataChange }) => {
const handlePlatformToggle = (platform) => {
if (platform === 'All Platforms') {
onDataChange({ selectedPlatforms: ['All Platforms'] });
}
else {
const currentPlatforms = data.selectedPlatforms.filter(p => p !== 'All Platforms');
if (data.selectedPlatforms.includes(platform)) {
onDataChange({ selectedPlatforms: currentPlatforms.filter(p => p !== platform) });
}
else {
onDataChange({ selectedPlatforms: [...currentPlatforms, platform] });
}
}
};
const handleAnalyticsToggle = (connected) => {
onDataChange({ analyticsConnected: connected });
};
const isFormValid = () => {
return data.analyticsConnected || data.selectedPlatforms.length > 0;
};
return (jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-lg p-8 max-w-2xl mx-auto", children: [jsxRuntime.jsxs("div", { className: "text-center mb-8", children: [jsxRuntime.jsx("h2", { className: "text-3xl font-bold text-gray-900 mb-2", children: "Connect your data source" }), jsxRuntime.jsx("p", { className: "text-gray-600 text-lg", children: "Use a Google Analytics connection, pick a demo dataset, or upload analytics files (PDF/CSV)." })] }), jsxRuntime.jsxs("div", { className: "space-y-8", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Upload your analytics data" }), jsxRuntime.jsxs("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-400 transition-colors cursor-pointer", children: [jsxRuntime.jsx("div", { className: "text-4xl mb-4", children: "\uD83D\uDCC1" }), jsxRuntime.jsx("p", { className: "text-gray-600", children: "Click to upload or drag and drop CSV, PDF, or Excel files" })] }), jsxRuntime.jsx("div", { className: "text-center mt-4", children: jsxRuntime.jsx("span", { className: "text-gray-500", children: "OR" }) }), jsxRuntime.jsx("div", { className: "text-center mt-4", children: jsxRuntime.jsxs("button", { className: "inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors", children: [jsxRuntime.jsx("span", { className: "mr-2", children: "\uD83D\uDDC4\uFE0F" }), "Use Demo Data"] }) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Select platforms (optional)" }), jsxRuntime.jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-3", children: PLATFORM_OPTIONS.map((platform) => (jsxRuntime.jsx("button", { onClick: () => handlePlatformToggle(platform.value), className: `
p-3 rounded-lg border-2 transition-all duration-200 text-sm font-medium
${data.selectedPlatforms.includes(platform.value)
? 'border-blue-600 bg-blue-50 text-blue-700'
: 'border-gray-200 hover:border-gray-300 text-gray-700'}
`, children: jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2", children: [jsxRuntime.jsx("span", { className: "text-lg", children: platform.icon }), jsxRuntime.jsx("span", { children: platform.label })] }) }, platform.value))) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Connect Analytics" }), jsxRuntime.jsxs("div", { className: "flex items-center space-x-4", children: [jsxRuntime.jsx("button", { onClick: () => handleAnalyticsToggle(true), className: `
px-4 py-2 rounded-md font-medium transition-colors
${data.analyticsConnected
? 'bg-green-600 text-white'
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'}
`, children: "Connect Google Analytics" }), jsxRuntime.jsx("button", { onClick: () => handleAnalyticsToggle(false), className: `
px-4 py-2 rounded-md font-medium transition-colors
${!data.analyticsConnected
? 'bg-blue-600 text-white'
: 'bg-gray-200 text-gray-700 hover:bg-gray-300'}
`, children: "Skip for now" })] })] })] }), jsxRuntime.jsxs("div", { className: "mt-8 flex justify-between", children: [jsxRuntime.jsx("button", { onClick: onBack, className: "px-6 py-3 border border-gray-300 text-gray-700 rounded-md font-medium hover:bg-gray-50 transition-colors", children: "\u2190 Back" }), jsxRuntime.jsx("button", { onClick: onNext, disabled: !isFormValid(), className: `
px-6 py-3 rounded-md font-medium transition-colors
${isFormValid()
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}
`, children: "Next \u2192" })] })] }));
};
const AssetsStep = ({ data, onNext, onBack, onDataChange }) => {
const handleFileUpload = (files) => {
if (!files)
return;
const newAssets = Array.from(files).map((file, index) => ({
id: `asset-${Date.now()}-${index}`,
type: getAssetType(file.type),
name: file.name,
file,
size: file.size,
uploadedAt: new Date().toISOString()
}));
onDataChange({ assets: [...data.assets, ...newAssets] });
};
const handleAdCopyChange = (adCopy) => {
onDataChange({ adCopy });
};
const handleRemoveAsset = (assetId) => {
onDataChange({
assets: data.assets.filter(asset => asset.id !== assetId)
});
};
const getAssetType = (mimeType) => {
if (mimeType.startsWith('image/'))
return 'image';
if (mimeType.startsWith('video/'))
return 'video';
if (mimeType.startsWith('text/'))
return 'text';
return 'document';
};
const isFormValid = () => {
return data.assets.length > 0 || data.adCopy.trim().length > 0;
};
const formatFileSize = (bytes) => {
if (bytes === 0)
return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
return (jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-lg p-8 max-w-2xl mx-auto", children: [jsxRuntime.jsxs("div", { className: "text-center mb-8", children: [jsxRuntime.jsx("h2", { className: "text-3xl font-bold text-gray-900 mb-2", children: "Upload past campaign assets" }), jsxRuntime.jsx("p", { className: "text-gray-600 text-lg", children: "Our AI will analyze these to learn what works. Upload your creatives and campaign briefs." })] }), jsxRuntime.jsxs("div", { className: "space-y-8", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Upload your campaign assets" }), jsxRuntime.jsxs("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-400 transition-colors", children: [jsxRuntime.jsx("div", { className: "text-4xl mb-4", children: "\uD83D\uDCC1" }), jsxRuntime.jsx("p", { className: "text-gray-600 mb-4", children: "Click to upload or drag and drop Images, PDFs, or documents" }), jsxRuntime.jsx("input", { type: "file", multiple: true, accept: Object.values(FILE_UPLOAD_CONFIG.acceptedFileTypes).flat().join(','), onChange: (e) => handleFileUpload(e.target.files), className: "hidden", id: "file-upload" }), jsxRuntime.jsxs("label", { htmlFor: "file-upload", className: "inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors cursor-pointer", children: [jsxRuntime.jsx("span", { className: "mr-2", children: "\uD83D\uDCE4" }), "Choose Files"] })] }), jsxRuntime.jsx("div", { className: "text-center mt-4", children: jsxRuntime.jsx("span", { className: "text-gray-500", children: "OR" }) }), jsxRuntime.jsx("div", { className: "text-center mt-4", children: jsxRuntime.jsxs("button", { className: "inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors", children: [jsxRuntime.jsx("span", { className: "mr-2", children: "\u26A0\uFE0F" }), "Use Demo Campaign"] }) })] }), data.assets.length > 0 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: ["Uploaded Assets (", data.assets.length, ")"] }), jsxRuntime.jsx("div", { className: "space-y-3", children: data.assets.map((asset) => (jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-3 bg-gray-50 rounded-lg border", children: [jsxRuntime.jsxs("div", { className: "flex items-center space-x-3", children: [jsxRuntime.jsx("span", { className: "text-2xl", children: asset.type === 'image' ? '🖼️' :
asset.type === 'video' ? '🎥' :
asset.type === 'text' ? '📄' : '📁' }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-medium text-gray-900", children: asset.name }), jsxRuntime.jsxs("p", { className: "text-sm text-gray-500", children: [asset.type, " \u2022 ", asset.size ? formatFileSize(asset.size) : 'Unknown size'] })] })] }), jsxRuntime.jsx("button", { onClick: () => handleRemoveAsset(asset.id), className: "text-red-500 hover:text-red-700 transition-colors", children: "\u2715" })] }, asset.id))) })] })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Campaign Ad Copy (Optional)" }), jsxRuntime.jsx("textarea", { value: data.adCopy, onChange: (e) => handleAdCopyChange(e.target.value), placeholder: "Paste your campaign ad copy here...", rows: 4, className: "w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500 mt-2", children: "This helps our AI understand your messaging style and tone." })] })] }), jsxRuntime.jsxs("div", { className: "mt-8 flex justify-between", children: [jsxRuntime.jsx("button", { onClick: onBack, className: "px-6 py-3 border border-gray-300 text-gray-700 rounded-md font-medium hover:bg-gray-50 transition-colors", children: "\u2190 Back" }), jsxRuntime.jsx("button", { onClick: onNext, disabled: !isFormValid(), className: `
px-6 py-3 rounded-md font-medium transition-colors
${isFormValid()
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}
`, children: "Next \u2192" })] })] }));
};
const BrandStep = ({ data, onNext, onBack, onDataChange }) => {
const [selectedColors, setSelectedColors] = React.useState(data.brandGuidelines.colors);
const [selectedTone, setSelectedTone] = React.useState(data.brandGuidelines.toneOfVoice);
const [selectedAudience, setSelectedAudience] = React.useState(data.brandGuidelines.targetAudience);
const [selectedStyle, setSelectedStyle] = React.useState(data.brandGuidelines.style || '');
const handleColorToggle = (color) => {
const newColors = selectedColors.includes(color)
? selectedColors.filter(c => c !== color)
: [...selectedColors, color];
setSelectedColors(newColors);
onDataChange({
brandGuidelines: {
...data.brandGuidelines,
colors: newColors
}
});
};
const handleToneChange = (tone) => {
setSelectedTone(tone);
onDataChange({
brandGuidelines: {
...data.brandGuidelines,
toneOfVoice: tone
}
});
};
const handleAudienceChange = (audience) => {
setSelectedAudience(audience);
onDataChange({
brandGuidelines: {
...data.brandGuidelines,
targetAudience: audience
}
});
};
const handleStyleChange = (style) => {
setSelectedStyle(style);
onDataChange({
brandGuidelines: {
...data.brandGuidelines,
style
}
});
};
const isFormValid = () => {
return selectedColors.length > 0 && selectedTone && selectedAudience;
};
return (jsxRuntime.jsxs("div", { className: "bg-white rounded-lg shadow-lg p-8 max-w-2xl mx-auto", children: [jsxRuntime.jsxs("div", { className: "text-center mb-8", children: [jsxRuntime.jsx("h2", { className: "text-3xl font-bold text-gray-900 mb-2", children: "Set your brand guidelines" }), jsxRuntime.jsx("p", { className: "text-gray-600 text-lg", children: "Help our AI understand your brand voice and style preferences." })] }), jsxRuntime.jsxs("div", { className: "space-y-8", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Brand Colors" }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-medium text-gray-700 mb-3", children: "Primary Colors" }), jsxRuntime.jsx("div", { className: "grid grid-cols-10 gap-2", children: BRAND_COLORS.primary.map((color) => (jsxRuntime.jsx("button", { onClick: () => handleColorToggle(color), className: `
w-8 h-8 rounded border-2 transition-all duration-200
${selectedColors.includes(color)
? 'border-gray-800 scale-110'
: 'border-gray-300 hover:border-gray-400'}
`, style: { backgroundColor: color }, title: color }, color))) })] }), jsxRuntime.jsxs("div", { className: "mb-4", children: [jsxRuntime.jsx("h4", { className: "text-sm font-medium text-gray-700 mb-3", children: "Neutral Colors" }), jsxRuntime.jsx("div", { className: "grid grid-cols-10 gap-2", children: BRAND_COLORS.neutral.map((color) => (jsxRuntime.jsx("button", { onClick: () => handleColorToggle(color), className: `
w-8 h-8 rounded border-2 transition-all duration-200
${selectedColors.includes(color)
? 'border-gray-800 scale-110'
: 'border-gray-300 hover:border-gray-400'}
`, style: { backgroundColor: color }, title: color }, color))) })] }), selectedColors.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-4 p-3 bg-gray-50 rounded-lg", children: [jsxRuntime.jsxs("p", { className: "text-sm text-gray-600 mb-2", children: ["Selected Colors (", selectedColors.length, "/5):"] }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: selectedColors.map((color) => (jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [jsxRuntime.jsx("div", { className: "w-4 h-4 rounded border border-gray-300", style: { backgroundColor: color } }), jsxRuntime.jsx("span", { className: "text-xs font-mono text-gray-700", children: color }), jsxRuntime.jsx("button", { onClick: () => handleColorToggle(color), className: "text-red-500 hover:text-red-700 text-xs", children: "\u2715" })] }, color))) })] }))] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Tone of Voice" }), jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: TONE_OF_VOICE_OPTIONS.map((tone) => (jsxRuntime.jsx("button", { onClick: () => handleToneChange(tone), className: `
p-3 rounded-lg border-2 transition-all duration-200 text-sm font-medium text-left
${selectedTone === tone
? 'border-blue-600 bg-blue-50 text-blue-700'
: 'border-gray-200 hover:border-gray-300 text-gray-700'}
`, children: tone }, tone))) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Target Audience" }), jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: TARGET_AUDIENCE_OPTIONS.map((audience) => (jsxRuntime.jsx("button", { onClick: () => handleAudienceChange(audience), className: `
p-3 rounded-lg border-2 transition-all duration-200 text-sm font-medium text-left
${selectedAudience === audience
? 'border-blue-600 bg-blue-50 text-blue-700'
: 'border-gray-200 hover:border-gray-300 text-gray-700'}
`, children: audience }, audience))) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-lg font-medium text-gray-900 mb-4", children: "Brand Style" }), jsxRuntime.jsx("div", { className: "grid grid-cols-4 gap-3", children: BRAND_STYLE_OPTIONS.map((style) => (jsxRuntime.jsxs("button", { onClick: () => handleStyleChange(style.value), className: `
p-3 rounded-lg border-2 transition-all duration-200 text-center
${selectedStyle === style.value
? 'border-blue-600 bg-blue-50 text-blue-700'
: 'border-gray-200 hover:border-gray-300 text-gray-700'}
`, children: [jsxRuntime.jsx("div", { className: "text-2xl mb-2", children: style.icon }), jsxRuntime.jsx("div", { className: "text-xs font-medium", children: style.label })] }, style.value))) })] })] }), jsxRuntime.jsxs("div", { className: "mt-8 flex justify-between", children: [jsxRuntime.jsx("button", { onClick: onBack, className: "px-6 py-3 border border-gray-300 text-gray-700 rounded-md font-medium hover:bg-gray-50 transition-colors", children: "\u2190 Back" }), jsxRuntime.jsx("button", { onClick: onNext, disabled: !isFormValid(), className: `
px-6 py-3 rounded-md font-medium transition-colors
${isFormValid()
? 'bg-blue-600 text-white hover:bg-blue-700 cursor-pointer'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'}
`, children: "\u26A1 Finish & Power Up AI" })] })] }));
};
const ProgressIndicator = ({ steps, currentStep, onStepClick }) => {
return (jsxRuntime.jsx("div", { className: "w-full", children: jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: steps.map((step, index) => (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [jsxRuntime.jsx("button", { onClick: () => onStepClick(step.id), disabled: step.id > currentStep, className: `
w-12 h-12 rounded-full flex items-center justify-center text-lg font-medium transition-all duration-200
${step.isCompleted
? 'bg-blue-600 text-white cursor-pointer hover:bg-blue-700'
: step.isActive
? 'bg-blue-600 text-white cursor-pointer'
: 'bg-gray-200 text-gray-500 cursor-not-allowed'}
`, children: step.isCompleted ? '✓' : step.icon }), jsxRuntime.jsxs("div", { className: "mt-2 text-center", children: [jsxRuntime.jsx("div", { className: `
text-sm font-medium
${step.isCompleted || step.isActive ? 'text-blue-600' : 'text-gray-500'}
`, children: step.title }), jsxRuntime.jsx("div", { className: "text-xs text-gray-400 mt-1 max-w-24", children: step.description })] })] }), index < steps.length - 1 && (jsxRuntime.jsx("div", { className: `
flex-1 h-0.5 mx-4 transition-colors duration-200
${step.isCompleted ? 'bg-blue-600' : 'bg-gray-200'}
` }))] }, step.id))) }) }));
};
const Header = ({ user }) => {
return (jsxRuntime.jsx("header", { className: "bg-blue-900 text-white shadow-lg", children: jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: jsxRuntime.jsxs("div", { className: "flex items-center justify-between h-16", children: [jsxRuntime.jsxs("div", { className: "flex items-center", children: [jsxRuntime.jsx("div", { className: "flex-shrink-0", children: jsxRuntime.jsx("img", { src: "/assets/landing-page-assets/Logo (with name).png", alt: "Omnify Marketing Cloud", className: "h-8 w-auto" }) }), jsxRuntime.jsx("div", { className: "ml-3", children: jsxRuntime.jsx("h1", { className: "text-xl font-bold", children: "OMNIFY MARKETING CLOUD" }) })] }), jsxRuntime.jsx("nav", { className: "hidden md:block", children: jsxRuntime.jsxs("div", { className: "flex items-center space-x-8", children: [jsxRuntime.jsx("a", { href: "#", className: "text-white hover:text-blue-200 transition-colors", children: "Home" }), jsxRuntime.jsx("a", { href: "#", className: "text-white hover:text-blue-200 transition-colors", children: "Why Omnify" }), jsxRuntime.jsx("a", { href: "#", className: "text-white hover:text-blue-200 transition-colors", children: "Features" })] }) }), jsxRuntime.jsxs("div", { className: "flex items-center space-x-4", children: [user && (jsxRuntime.jsxs("div", { className: "text-sm", children: [jsxRuntime.jsxs("span", { children: ["Welcome, ", user.name || user.email] }), user.companyName && (jsxRuntime.jsxs("span", { className: "ml-2 text-blue-200", children: ["- ", user.companyName] }))] })), jsxRuntime.jsx("button", { className: "bg-blue-800 hover:bg-blue-700 px-4 py-2 rounded-md text-sm font-medium transition-colors", children: "Join Waitlist" })] })] }) }) }));
};
const Footer = () => {
return (jsxRuntime.jsx("footer", { className: "bg-gray-800 text-gray-300 mt-16", children: jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto py-8 px-4 sm:px-6 lg:px-8", children: [jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "flex items-center mb-4", children: [jsxRuntime.jsx("div", { className: "w-6 h-6 bg-blue-600 rounded mr-2" }), jsxRuntime.jsx("span", { className: "text-lg font-semibold text-white", children: "OMNIFY MARKETING CLOUD" })] }), jsxRuntime.jsx("p", { className: "text-sm text-gray-400", children: "The autonomous AI platform that turns your marketing data into predictable revenue." })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-white font-semibold mb-4", children: "Quick Links" }), jsxRuntime.jsxs("ul", { className: "space-y-2", children: [jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Home" }) }), jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Why Omnify" }) }), jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Join Waitlist" }) })] })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-white font-semibold mb-4", children: "Support" }), jsxRuntime.jsxs("ul", { className: "space-y-2", children: [jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Help Center" }) }), jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Privacy Policy" }) }), jsxRuntime.jsx("li", { children: jsxRuntime.jsx("a", { href: "#", className: "text-gray-400 hover:text-white transition-colors", children: "Terms of Service" }) })] })] })] }), jsxRuntime.jsx("div", { className: "border-t border-gray-700 mt-8 pt-8 text-center", children: jsxRuntime.jsx("p", { className: "text-sm text-gray-400", children: "\u00A9 2025 Omnify Marketing Cloud. All rights reserved." }) })] }) }));
};
const OnboardingFlow = ({ user, onComplete, onStepChange, initialData, showHeader = true, showFooter = true, className = '' }) => {
const [currentStep, setCurrentStep] = React.useState(1);
const [onboardingData, setOnboardingData] = React.useState({
firstName: '',
lastName: '',
role: 'General',
companyName: '',
industry: '',
objective: 'Increase brand awareness and drive sales',
analyticsConnected: false,
selectedPlatforms: ['All Platforms'],
assets: [],
adCopy: '',
brandGuidelines: {
colors: ['#4F69FF', '#FFFFFF', '#0B2447'],
toneOfVoice: 'Confident, modern, and slightly playful',
targetAudience: 'Tech-savvy professionals aged 25-45',
},
...initialData
});
const [steps, setSteps] = React.useState(ONBOARDING_STEPS);
// Initialize form with user data
React.useEffect(() => {
if (user) {
const nameParts = user.name ? user.name.split(' ') : [];
const userFirstName = nameParts[0] || '';
const userLastName = nameParts.slice(1).join(' ') || '';
setOnboardingData(prev => ({
...prev,
firstName: userFirstName,
lastName: userLastName,
companyName: user.companyName || '',
role: user.role || 'General'
}));
}
}, [user]);
// Update step completion status
React.useEffect(() => {
setSteps(prevSteps => prevSteps.map(step => ({
...step,
isActive: step.id === currentStep,
isCompleted: step.id < currentStep
})));
}, [currentStep]);
const handleDataChange = (data) => {
const newData = { ...onboardingData, ...data };
setOnboardingData(newData);
// Call onStepChange callback if provided
if (onStepChange) {
onStepChange(currentStep, data);
}
};
const handleNext = () => {
const validation = validateStep(currentStep, onboardingData);
if (!validation.isValid) {
console.error('Step validation failed:', validation.errors);
return;
}
if (currentStep < steps.length) {
const nextStep = currentStep + 1;
setCurrentStep(nextStep);
// Mark current step as completed
setSteps(prevSteps => prevSteps.map(step => step.id === currentStep
? { ...step, isCompleted: true }
: step));
}
else {
// Complete onboarding
onComplete(onboardingData);
}
};
const handleBack = () => {
if (currentStep > 1) {
setCurrentStep(currentStep - 1);
}
};
const handleStepClick = (stepId) => {
// Only allow navigation to completed steps or current step
if (stepId <= currentStep) {
setCurrentStep(stepId);
}
};
const renderCurrentStep = () => {
const stepProps = {
step: currentStep,
data: onboardingData,
onNext: handleNext,
onBack: handleBack,
onDataChange: handleDataChange,
isLastStep: currentStep === steps.length
};
switch (currentStep) {
case 1:
return jsxRuntime.jsx(ProfileStep, { ...stepProps });
case 2:
return jsxRuntime.jsx(CompanyStep, { ...stepProps });
case 3:
return jsxRuntime.jsx(AnalyticsStep, { ...stepProps });
case 4:
return jsxRuntime.jsx(AssetsStep, { ...stepProps });
case 5:
return jsxRuntime.jsx(BrandStep, { ...stepProps });
default:
return jsxRuntime.jsx("div", { children: "Unknown step" });
}
};
return (jsxRuntime.jsxs("div", { className: `min-h-screen bg-gray-50 ${className}`, children: [showHeader && jsxRuntime.jsx(Header, { user: user }), jsxRuntime.jsxs("div", { className: "max-w-4xl mx-auto py-8 px-4 sm:px-6 lg:px-8", children: [jsxRuntime.jsx(ProgressIndicator, { steps: steps, currentStep: currentStep, onStepClick: handleStepClick }), jsxRuntime.jsx("div", { className: "mt-8", children: renderCurrentStep() })] }), showFooter && jsxRuntime.jsx(Footer, {})] }));
};
exports.AnalyticsStep = AnalyticsStep;
exports.AssetsStep = AssetsStep;
exports.BRAND_COLORS = BRAND_COLORS;
exports.BRAND_STYLE_OPTIONS = BRAND_STYLE_OPTIONS;
exports.BrandStep = BrandStep;
exports.CompanyStep = CompanyStep;
exports.FILE_UPLOAD_CONFIG = FILE_UPLOAD_CONFIG;
exports.Footer = Footer;
exports.Header = Header;
exports.INDUSTRY_OPTIONS = INDUSTRY_OPTIONS;
exports.MARKETING_OBJECTIVES = MARKETING_OBJECTIVES;
exports.ONBOARDING_STEPS = ONBOARDING_STEPS;
exports.OnboardingFlow = OnboardingFlow;
exports.PLATFORM_OPTIONS = PLATFORM_OPTIONS;
exports.ProfileStep = ProfileStep;
exports.ProgressIndicator = ProgressIndicator;
exports.ROLE_OPTIONS = ROLE_OPTIONS;
exports.TARGET_AUDIENCE_OPTIONS = TARGET_AUDIENCE_OPTIONS;
exports.TONE_OF_VOICE_OPTIONS = TONE_OF_VOICE_OPTIONS;
exports.validateAllSteps = validateAllSteps;
exports.validateAnalyticsStep = validateAnalyticsStep;
exports.validateAssetsStep = validateAssetsStep;
exports.validateBrandStep = validateBrandStep;
exports.validateCompanyStep = validateCompanyStep;
exports.validateProfileStep = validateProfileStep;
exports.validateStep = validateStep;
//# sourceMappingURL=index.js.map