import React, { useState, useEffect } from "react"; // import Alert from "./Alert"; // Re-enabled for the merged version import DashboardHeader from "./DashboardHeader"; import { SimpleAreaChart } from "./ui/simple-area-chart"; import { activeStatusIcon, draftStatusIcon, inactiveStatusIcon, scheduledStatusIcon, sendingStatusIcon, pausedStatusIcon, sentStatusIcon, tableChevronRight, formsChevronRightIcon, // onboardingVideoThumbnail, // Uncomment when onboarding section is enabled // freeEmailIconOnboarding // Uncomment when onboarding section is enabled } from "@/assets/images"; import { getDashboardData, type DashboardData, parseIntSafe, parseFloatSafe, formatNumber, formatPercentage, getPluginButtonInfo, createDashboardWorkflow, canCreateAbandonedCartWorkflow, getPricingPageUrl, getSubscribersStats, getOnboardingSteps, type OnboardingOptions } from "../api/dashboard"; import { getBaseUrl } from "../api/client"; const adminData = (window as any).icegramExpressAdminData; const images = { chartIconDashboard: `${adminData.baseUrl}/images/chart-icon-dashboard.svg`, trendingUpIcon: `${adminData.baseUrl}/images/trending-up-icon.svg`, workflowIcon: `${adminData.baseUrl}/images/workflow-icon.svg`, workflowInfoIcon: `${adminData.baseUrl}/images/workflow-info-icon.svg`, workflowBuildIcon: `${adminData.baseUrl}/images/workflow-build-icon.svg`, workflowWelcomeContactsIcon: `${adminData.baseUrl}/images/workflow-welcome-contacts-icon.svg`, workflowSubscriberWelcomeIcon: `${adminData.baseUrl}/images/workflow-subscriber-welcome-icon.svg`, workflowTaggedCustomersIcon: `${adminData.baseUrl}/images/workflow-tagged-customers-icon.svg`, workflowChevronRightIcon: `${adminData.baseUrl}/images/workflow-chevron-right-icon.svg`, helpCircleHelpIcon: `${adminData.baseUrl}/images/help-circle-help-icon.svg`, helpAccordionChevronIcon: `${adminData.baseUrl}/images/help-accordion-chevron-icon.svg`, helpMessageCircleQuestionIcon: `${adminData.baseUrl}/images/help-message-circle-question-icon.svg`, helpMailIcon: `${adminData.baseUrl}/images/help-mail-icon.svg`, emailDeliveryMistakes: `${adminData.baseUrl}/images/email-delivery-mistakes.png`, monthlyNewsletter: `${adminData.baseUrl}/images/monthly-newsletter.png`, reliableWordpressEmailDelivery: `${adminData.baseUrl}/images/reliable-wordpress-email-delivery.png`, emailTemplateForNewSubscriber: `${adminData.baseUrl}/images/email-template-for-new-subscriber.png`, popularContentViewAllIcon: `${adminData.baseUrl}/images/popular-content-view-all-icon.svg`, icegramExpressIcon: `${adminData.baseUrl}/images/icegram-express-icon.svg`, icegramEngageIcon: `${adminData.baseUrl}/images/icegram-engage-icon.svg`, icegramCollectIcon: `${adminData.baseUrl}/images/icegram-collect-icon.svg`, emailCampaignBg: `${adminData.baseUrl}/images/email-campaign-bg.png`, postSidebarImage: `${adminData.baseUrl}/images/post-sidebar-image.png`, wordpressIcon: `${adminData.baseUrl}/images/wordpress-icon.png`, emailConfigSvg: `${adminData.baseUrl}/images/email-config.svg`, emailProvider1: `${adminData.baseUrl}/images/email-provider-1.png`, emailProvider2: `${adminData.baseUrl}/images/email-provider-2.png`, emailProvider3: `${adminData.baseUrl}/images/email-provider-3.png`, emailProvider4: `${adminData.baseUrl}/images/email-provider-4.png`, freeEmailIconOnboarding: `${adminData.baseUrl}/images/free-email-icon-onboarding.svg`, onboardingVideoThumbnail: `${adminData.baseUrl}/images/onboarding-video-thumbnail.png`, audience: `${adminData.baseUrl}/images/audience.png`, }; export default function Dashboard() { const [dashboardData, setDashboardData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [workflowCreating, setWorkflowCreating] = useState(null); // Email performance filter state const [selectedPeriod, setSelectedPeriod] = useState<7 | 30 | 60>(7); const [isLoadingStats, setIsLoadingStats] = useState(false); // Onboarding checklist state const [onboardingSteps, setOnboardingSteps] = useState({ sendFirstCampaign: false, // Will be loaded from WordPress options importContacts: false, createSubscriptionForm: false, createWorkflow: false }); // Track which onboarding task is expanded const [expandedTask, setExpandedTask] = useState(null); const handleWorkflowCreate = async (workflowType: 'welcome-email' | 'confirmation-email') => { try { setWorkflowCreating(workflowType); const response = await createDashboardWorkflow(workflowType); // Check if we have a valid workflow_id if (!response.workflow_id) { console.error('No workflow ID in response:', response); console.error('Response structure:', JSON.stringify(response, null, 2)); alert(`Workflow creation failed: No workflow ID returned. Check console for details.`); return; } if (response.edit_url && response.edit_url.startsWith('http')) { alert(`${response.message}\nRedirecting to edit page...`); setTimeout(() => { window.location.href = response.edit_url; }, 1000); } else { console.error('Invalid edit URL received:', response.edit_url); console.error('Full response:', JSON.stringify(response, null, 2)); alert(`Workflow created successfully (ID: ${response.workflow_id}), but redirect URL is invalid: "${response.edit_url}"\n\nCheck console for details.`); } } catch (error) { console.error('Workflow creation error:', error); const errorMessage = error instanceof Error ? error.message : 'Failed to create workflow'; alert(`Error: ${errorMessage}\n\nCheck console for details.`); } finally { setWorkflowCreating(null); } }; const handleAbandonedCartClick = async () => { const userPlan = dashboardData?.plan || 'lite'; if (canCreateAbandonedCartWorkflow(userPlan)) { // User has Pro plan - create workflow and redirect to edit page try { setWorkflowCreating('abandoned-cart'); const response = await createDashboardWorkflow('abandoned-cart'); // Check if we have a valid workflow_id if (!response.workflow_id) { console.error('No workflow ID in abandoned cart response:', response); alert(`Workflow creation failed: No workflow ID returned. Check console for details.`); return; } if (response.edit_url && response.edit_url.startsWith('http')) { alert(`${response.message}\nRedirecting to edit page...`); setTimeout(() => { window.location.href = response.edit_url; }, 1000); } else { console.error('Invalid edit URL received for abandoned cart:', response.edit_url); console.error('Full response:', JSON.stringify(response, null, 2)); alert(`Workflow created successfully (ID: ${response.workflow_id}), but redirect URL is invalid: "${response.edit_url}"\n\nCheck console for details.`); } } catch (error) { console.error('Abandoned cart workflow creation error:', error); const errorMessage = error instanceof Error ? error.message : 'Failed to create abandoned cart workflow'; alert(`Error: ${errorMessage}\n\nCheck console for details.`); } finally { setWorkflowCreating(null); } } else { // User doesn't have Pro plan - redirect to pricing page const pricingUrl = getPricingPageUrl(); window.location.href = pricingUrl; } }; const handleGetFreeEmailSendingClick = () => { setShowIcegramMailerPopup(true); }; const [openFaqItems, setOpenFaqItems] = useState([]); const [showIcegramMailerPopup, setShowIcegramMailerPopup] = useState(false); const toggleFaqItem = (index: number) => { setOpenFaqItems(prev => prev.includes(index) ? prev.filter(i => i !== index) : [...prev, index] ); }; // Handle task label click to expand/collapse const handleTaskLabelClick = (step: keyof OnboardingOptions) => { setExpandedTask(expandedTask === step ? null : step); }; // Calculate onboarding completion const getOnboardingCompletion = () => { const completedSteps = Object.values(onboardingSteps).filter(Boolean).length; const totalSteps = Object.keys(onboardingSteps).length; return { completed: completedSteps, total: totalSteps }; }; // Handle period filter change and fetch new stats const handlePeriodChange = async (days: 7 | 30 | 60) => { if (days === selectedPeriod) return; setSelectedPeriod(days); setIsLoadingStats(true); try { const newStats = await getSubscribersStats(days); setDashboardData(prev => prev ? { ...prev, dashboard_kpi: { ...prev.dashboard_kpi, total_subscribed: newStats.total_subscribed, total_email_opens: newStats.total_email_opens, total_links_clicks: newStats.total_links_clicks, total_message_sent: newStats.total_message_sent, total_unsubscribed: newStats.total_unsubscribed, avg_open_rate: newStats.avg_open_rate, avg_click_rate: newStats.avg_click_rate, avg_unsubscribe_rate: newStats.avg_unsubscribe_rate, contacts_growth: newStats.contacts_growth, avg_bounce_rate: newStats.avg_bounce_rate, total_hard_bounced_contacts: newStats.total_hard_bounced_contacts, hard_bounces_before_two_months: newStats.hard_bounces_before_two_months, hard_bounces_percentage_growth: newStats.hard_bounces_percentage_growth, sent_percentage_growth: newStats.sent_percentage_growth, sent_before_two_months: newStats.sent_before_two_months, open_percentage_growth: newStats.open_percentage_growth, open_before_two_months: newStats.open_before_two_months, click_percentage_growth: newStats.click_percentage_growth, click_before_two_months: newStats.click_before_two_months, unsubscribe_percentage_growth: newStats.unsubscribe_percentage_growth } } : null); } catch (error) { console.error('Failed to fetch stats:', error); // Could add error handling UI here } finally { setIsLoadingStats(false); } }; useEffect(() => { const loadDashboardDataAndStats = async () => { try { setIsLoading(true); const [data, stats, onboardingData] = await Promise.all([ getDashboardData(), getSubscribersStats(selectedPeriod), getOnboardingSteps() ]); setDashboardData({ ...data, dashboard_kpi: { ...data.dashboard_kpi, ...stats } }); console.log('🔍 Loaded onboarding data from API:', onboardingData); setOnboardingSteps(onboardingData); } catch (error) { setDashboardData({ campaigns: [], audience_activity: [], forms: [], lists: [], dashboard_kpi: { campaigns: [], total_subscribed: "0", total_email_opens: "0", total_links_clicks: "0", total_message_sent: "0", total_unsubscribed: "0", avg_open_rate: "0", avg_click_rate: "0", avg_unsubscribe_rate: "0", contacts_growth: {}, avg_bounce_rate: 0, total_hard_bounced_contacts: "0", hard_bounces_before_two_months: "0", hard_bounces_percentage_growth: 0, sent_percentage_growth: 0, sent_before_two_months: "0", open_percentage_growth: 0, open_before_two_months: "0", click_percentage_growth: 0, click_before_two_months: "0", unsubscribe_percentage_growth: 0, } }); } finally { setIsLoading(false); } }; loadDashboardDataAndStats(); }, []); if (!dashboardData) { return null; } const rawData = dashboardData.dashboard_kpi.contacts_growth; const chartData = Object.entries(rawData).map(([key, value]) => { const [year, month] = key.split("-"); const date = new Date(Number(year), Number(month) - 1); // month index is 0-based const monthName = date.toLocaleString("default", { month: "short" }); // "Jan", "Feb" etc. return { month: `${monthName} ${year}`, // e.g. "Sep 2024" desktop: value, }; }).slice(-6); return (
{/* Onboarding Section - Hidden for now */}
Finish your onboarding and receive 200 free emails/month
{getOnboardingCompletion().completed}/{getOnboardingCompletion().total} steps completed
{/* Task 1 - Send First Campaign */}
{onboardingSteps.sendFirstCampaign && ( )}
handleTaskLabelClick('sendFirstCampaign')} className="text-left cursor-pointer hover:text-[#5e19cf] transition-colors focus:outline-none" >
Send your first campaign
{expandedTask === 'sendFirstCampaign' && (
Create and send your first email campaign to connect with your audience.
)}
{expandedTask === 'sendFirstCampaign' && ( )}
{/* Task 2 - Import Contacts */}
{onboardingSteps.importContacts && ( )}
handleTaskLabelClick('importContacts')} className="text-left cursor-pointer hover:text-[#5e19cf] transition-colors focus:outline-none" >
Import contacts
{expandedTask === 'importContacts' && (
Easily upload your existing contacts to start engaging with your audience right away.
)}
{expandedTask === 'importContacts' && ( )}
{/* Task 3 - Create Subscription Form */}
{onboardingSteps.createSubscriptionForm && ( )}
{expandedTask === 'createSubscriptionForm' && ( )}
{/* Task 4 - Create Workflow */}
{onboardingSteps.createWorkflow && ( )}
handleTaskLabelClick('createWorkflow')} className="text-left cursor-pointer hover:text-[#5e19cf] transition-colors focus:outline-none" >
Create a workflow
{expandedTask === 'createWorkflow' && (
Set up automated workflows to streamline your email marketing campaigns.
)}
{expandedTask === 'createWorkflow' && ( )}
{/* Bonus Item */}