BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { Card, CardHeader } from '@/components/ui/Card'
|
||||
import { Badge } from '@/components/ui/Badge'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import {
|
||||
Megaphone,
|
||||
Plus,
|
||||
BarChart3,
|
||||
Target,
|
||||
Mail,
|
||||
TrendingUp,
|
||||
Users,
|
||||
} from 'lucide-react'
|
||||
|
||||
const campaigns = [
|
||||
{ id: '1', name: 'Q4 Product Launch', status: 'active' as const, channel: 'Email', reach: 12500, engagement: 8.2, conversions: 340 },
|
||||
{ id: '2', name: 'Holiday Special', status: 'scheduled' as const, channel: 'Social', reach: 0, engagement: 0, conversions: 0 },
|
||||
{ id: '3', name: 'Customer Retention', status: 'active' as const, channel: 'Email', reach: 8400, engagement: 12.5, conversions: 520 },
|
||||
{ id: '4', name: 'Partner Webinar', status: 'completed' as const, channel: 'Webinar', reach: 3200, engagement: 45.0, conversions: 180 },
|
||||
]
|
||||
|
||||
export function MarketingPage() {
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Page Header */}
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
<h1 className="text-xl font-semibold text-text-primary">Marketing</h1>
|
||||
<p className="text-sm text-text-secondary mt-0.5">Campaigns and marketing metrics</p>
|
||||
</div>
|
||||
<Button icon={<Plus size={16} />}>New Campaign</Button>
|
||||
</div>
|
||||
|
||||
{/* Quick Stats */}
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-5">
|
||||
<Card padding="md">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-primary-light flex items-center justify-center text-primary">
|
||||
<Megaphone size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-semibold text-text-primary">4</p>
|
||||
<p className="text-xs text-text-secondary">Campaigns</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card padding="md">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-success-light flex items-center justify-center text-success">
|
||||
<Users size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-semibold text-text-primary">24.1K</p>
|
||||
<p className="text-xs text-text-secondary">Total Reach</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card padding="md">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-warning-light flex items-center justify-center text-warning">
|
||||
<Target size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-semibold text-text-primary">10.4%</p>
|
||||
<p className="text-xs text-text-secondary">Avg. Engagement</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card padding="md">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-primary-light flex items-center justify-center text-primary">
|
||||
<TrendingUp size={18} />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-semibold text-text-primary">1,040</p>
|
||||
<p className="text-xs text-text-secondary">Conversions</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Campaigns */}
|
||||
<Card>
|
||||
<CardHeader title="Campaigns" subtitle="Active and recent marketing campaigns" />
|
||||
<div className="space-y-4">
|
||||
{campaigns.map((campaign) => (
|
||||
<div
|
||||
key={campaign.id}
|
||||
className="flex items-center justify-between p-4 rounded-xl bg-bg/50 hover:bg-bg transition-colors"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-primary-light flex items-center justify-center text-primary">
|
||||
{campaign.channel === 'Email' ? <Mail size={18} /> : <BarChart3 size={18} />}
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-text-primary">{campaign.name}</span>
|
||||
<Badge
|
||||
variant={
|
||||
campaign.status === 'active'
|
||||
? 'success'
|
||||
: campaign.status === 'scheduled'
|
||||
? 'primary'
|
||||
: 'default'
|
||||
}
|
||||
size="sm"
|
||||
>
|
||||
{campaign.status}
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-xs text-text-secondary mt-0.5">{campaign.channel}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-8 text-right">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-text-primary">
|
||||
{campaign.reach > 0 ? campaign.reach.toLocaleString() : '—'}
|
||||
</p>
|
||||
<p className="text-[11px] text-text-secondary">Reach</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-text-primary">
|
||||
{campaign.engagement > 0 ? `${campaign.engagement}%` : '—'}
|
||||
</p>
|
||||
<p className="text-[11px] text-text-secondary">Engagement</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium text-text-primary">
|
||||
{campaign.conversions > 0 ? campaign.conversions.toLocaleString() : '—'}
|
||||
</p>
|
||||
<p className="text-[11px] text-text-secondary">Conversions</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user