import { Alert, AlertDescription, AlertTitle, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@plunk/ui'; import {AlertCircle, Mail, Send, TrendingUp, Users} from 'lucide-react'; import {NextSeo} from 'next-seo'; import Link from 'next/link'; import {useState} from 'react'; import {ApiKeyDisplay} from '../components/ApiKeyDisplay'; import {DashboardLayout} from '../components/DashboardLayout'; import {QuickStart} from '../components/QuickStart'; import {SecurityWarningBanner} from '../components/SecurityWarningBanner'; import {useActiveProject} from '../lib/contexts/ActiveProjectProvider'; import {useDashboardStats} from '../lib/hooks/useDashboardStats'; import {useProjectSetupState} from '../lib/hooks/useProjectSetupState'; import {useProjectSecurity} from '../lib/hooks/useProjectSecurity'; import {useConfig} from '../lib/hooks/useConfig'; import {useUser} from '../lib/hooks/useUser'; import {network} from '../lib/network'; export default function Index() { const {activeProject} = useActiveProject(); const {totalContacts, totalEmailsSent, totalCampaigns, openRate, isLoading} = useDashboardStats(); const {setupState, isLoading: isLoadingSetupState} = useProjectSetupState(activeProject?.id); const {securityMetrics} = useProjectSecurity(activeProject?.id); const {data: config} = useConfig(); const {data: user} = useUser(); const [isResending, setIsResending] = useState(false); const [resendMessage, setResendMessage] = useState(''); const stats = [ { name: 'Total Contacts', value: totalContacts.toLocaleString(), icon: Users, }, { name: 'Emails Sent', value: totalEmailsSent.toLocaleString(), icon: Mail, }, { name: 'Campaigns', value: totalCampaigns.toLocaleString(), icon: Send, }, { name: 'Open Rate', value: `${openRate.toFixed(1)}%`, icon: TrendingUp, }, ]; async function handleResendVerification() { setIsResending(true); setResendMessage(''); try { const response = await network.fetch<{success: boolean}>('POST', '/auth/request-verification'); if (response.success) { setResendMessage('Verification email sent! Please check your inbox.'); } else { setResendMessage('Failed to send verification email. Please try again.'); } } catch { setResendMessage('Failed to send verification email. Please try again.'); } finally { setIsResending(false); } } return ( <>
{/* Project Disabled Banner */} {activeProject && activeProject.disabled && ( Project Disabled - Read-Only Mode

This project has been disabled due to security violations. All scheduled campaigns and workflows have been cancelled. The project is now in read-only mode - you can view your data but cannot create, update, or delete anything.

{securityMetrics && securityMetrics.status.violations.length > 0 && ( <>

Security violations that caused suspension:

    {securityMetrics.status.violations.map((violation, idx) => (
  • {violation}
  • ))}
)}

Please contact support to resolve this issue and get your project re-enabled.

)} {/* Email Verification Banner */} {user && user.type === 'PASSWORD' && !user.emailVerified && ( Verify your email address Please verify your email address to unlock all features. Check your inbox for the verification link.
{resendMessage && (

{resendMessage}

)}
)} {/* Security Warning Banner */} {activeProject && !activeProject.disabled && securityMetrics && ( )} {/* Subscription Warning Banner */} {activeProject && !activeProject.disabled && !activeProject.subscription && config?.features.billing.enabled && ( Upgrade to remove Plunk branding Your emails currently include Plunk branding. Upgrade to a subscription to remove it. )} {/* Header */}

Dashboard

{/* Stats Grid */}
{stats.map(stat => { const Icon = stat.icon; return (
{stat.name}
{isLoading ? (
) : ( stat.value )} ); })}
{/* Quick Actions & API Keys */}
{/* Quick Start */} {/* API Keys */} API Keys Use these keys to integrate with Plunk
{activeProject ? ( <> ) : (

No project selected

)}
); }