Remove gray colours
This commit is contained in:
@@ -108,252 +108,254 @@ export default function CampaignsPage() {
|
|||||||
<NextSeo title="Campaigns" />
|
<NextSeo title="Campaigns" />
|
||||||
<DashboardLayout>
|
<DashboardLayout>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-neutral-900">Campaigns</h1>
|
<h1 className="text-3xl font-bold text-neutral-900">Campaigns</h1>
|
||||||
<p className="text-neutral-500 mt-2">
|
<p className="text-neutral-500 mt-2">
|
||||||
Send one-time email broadcasts to your contacts. {data?.total ? `${data.total} total campaigns` : ''}
|
Send one-time email broadcasts to your contacts. {data?.total ? `${data.total} total campaigns` : ''}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
<Link href="/campaigns/create">
|
|
||||||
<Button>
|
|
||||||
<Plus className="h-4 w-4" />
|
|
||||||
Create Campaign
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Filters */}
|
|
||||||
<Card>
|
|
||||||
<CardContent className="pt-6">
|
|
||||||
<div className="flex gap-4">
|
|
||||||
<div className="flex-1">
|
|
||||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="All Statuses" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="ALL">All Statuses</SelectItem>
|
|
||||||
<SelectItem value="DRAFT">Draft</SelectItem>
|
|
||||||
<SelectItem value="SCHEDULED">Scheduled</SelectItem>
|
|
||||||
<SelectItem value="SENDING">Sending</SelectItem>
|
|
||||||
<SelectItem value="SENT">Sent</SelectItem>
|
|
||||||
<SelectItem value="CANCELLED">Cancelled</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
<Link href="/campaigns/create">
|
||||||
</Card>
|
<Button>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
Create Campaign
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Campaigns List */}
|
{/* Filters */}
|
||||||
<div className="space-y-4">
|
<Card>
|
||||||
{isLoading && (
|
<CardContent className="pt-6">
|
||||||
<Card>
|
<div className="flex gap-4">
|
||||||
<CardContent className="py-8 text-center text-neutral-500">Loading campaigns...</CardContent>
|
<div className="flex-1">
|
||||||
</Card>
|
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||||
)}
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="All Statuses" />
|
||||||
{!isLoading && data?.campaigns.length === 0 && (
|
</SelectTrigger>
|
||||||
<Card className="border-2 border-dashed">
|
<SelectContent>
|
||||||
<CardContent className="py-16 text-center">
|
<SelectItem value="ALL">All Statuses</SelectItem>
|
||||||
<div className="max-w-md mx-auto">
|
<SelectItem value="DRAFT">Draft</SelectItem>
|
||||||
<div className="bg-primary/10 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
<SelectItem value="SCHEDULED">Scheduled</SelectItem>
|
||||||
<Mail className="h-8 w-8 text-primary" />
|
<SelectItem value="SENDING">Sending</SelectItem>
|
||||||
</div>
|
<SelectItem value="SENT">Sent</SelectItem>
|
||||||
<h3 className="text-xl font-semibold text-neutral-900 mb-2">
|
<SelectItem value="CANCELLED">Cancelled</SelectItem>
|
||||||
{statusFilter !== 'ALL' ? `No ${statusFilter.toLowerCase()} campaigns` : 'No campaigns yet'}
|
</SelectContent>
|
||||||
</h3>
|
</Select>
|
||||||
<p className="text-neutral-500 mb-6">
|
|
||||||
{statusFilter !== 'ALL'
|
|
||||||
? 'Try adjusting your filters or create a new campaign.'
|
|
||||||
: 'Create your first campaign to send emails to your contacts.'}
|
|
||||||
</p>
|
|
||||||
<Link href="/campaigns/create">
|
|
||||||
<Button size="lg">
|
|
||||||
<Plus className="h-4 w-4" />
|
|
||||||
Create Your First Campaign
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</CardContent>
|
||||||
)}
|
</Card>
|
||||||
|
|
||||||
{data?.campaigns.map(campaign => {
|
{/* Campaigns List */}
|
||||||
const openRate = campaign.sentCount > 0 ? (campaign.openedCount / campaign.sentCount) * 100 : 0;
|
<div className="space-y-4">
|
||||||
const clickRate = campaign.sentCount > 0 ? (campaign.clickedCount / campaign.sentCount) * 100 : 0;
|
{isLoading && (
|
||||||
const deliveryProgress =
|
<Card>
|
||||||
campaign.totalRecipients > 0 ? (campaign.sentCount / campaign.totalRecipients) * 100 : 0;
|
<CardContent className="py-8 text-center text-neutral-500">Loading campaigns...</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
return (
|
{!isLoading && data?.campaigns.length === 0 && (
|
||||||
<Card key={campaign.id} className="hover:shadow-lg transition-all hover:border-primary/20">
|
<Card>
|
||||||
<CardHeader className="pb-4">
|
<CardContent className="py-16 text-center">
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="max-w-md mx-auto">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="bg-primary/10 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||||
<div className="flex items-center gap-3 mb-2">
|
<Mail className="h-8 w-8 text-primary" />
|
||||||
<Link
|
|
||||||
href={`/campaigns/${campaign.id}`}
|
|
||||||
className="hover:text-primary transition-colors flex-1 min-w-0"
|
|
||||||
>
|
|
||||||
<CardTitle className="text-xl truncate">{campaign.name}</CardTitle>
|
|
||||||
</Link>
|
|
||||||
{getStatusBadge(campaign.status)}
|
|
||||||
</div>
|
|
||||||
{campaign.description && (
|
|
||||||
<CardDescription className="line-clamp-2">{campaign.description}</CardDescription>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<h3 className="text-xl font-semibold text-neutral-900 mb-2">
|
||||||
</CardHeader>
|
{statusFilter !== 'ALL' ? `No ${statusFilter.toLowerCase()} campaigns` : 'No campaigns yet'}
|
||||||
<CardContent className="space-y-4">
|
</h3>
|
||||||
{/* Stats Grid */}
|
<p className="text-neutral-500 mb-6">
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
{statusFilter !== 'ALL'
|
||||||
{/* Recipients */}
|
? 'Try adjusting your filters or create a new campaign.'
|
||||||
<div className="bg-blue-50 border border-blue-100 rounded-lg p-3">
|
: 'Create your first campaign to send emails to your contacts.'}
|
||||||
<div className="flex items-center gap-2 mb-1">
|
</p>
|
||||||
<Users className="h-3.5 w-3.5 text-blue-600" />
|
<Link href="/campaigns/create">
|
||||||
<span className="text-xs font-medium text-blue-900">Recipients</span>
|
<Button size="lg">
|
||||||
</div>
|
<Plus className="h-4 w-4" />
|
||||||
<p className="text-lg font-bold text-blue-900">{campaign.totalRecipients.toLocaleString()}</p>
|
Create Your First Campaign
|
||||||
{campaign.totalRecipients > 0 && (
|
|
||||||
<p className="text-xs text-blue-700 mt-1">{deliveryProgress.toFixed(0)}% sent</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Open Rate */}
|
|
||||||
{campaign.sentCount > 0 && (
|
|
||||||
<div className="bg-purple-50 border border-purple-100 rounded-lg p-3">
|
|
||||||
<div className="flex items-center gap-2 mb-1">
|
|
||||||
<Mail className="h-3.5 w-3.5 text-purple-600" />
|
|
||||||
<span className="text-xs font-medium text-purple-900">Opens</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-lg font-bold text-purple-900">{openRate.toFixed(1)}%</p>
|
|
||||||
<p className="text-xs text-purple-700 mt-1">{campaign.openedCount.toLocaleString()} opened</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Click Rate */}
|
|
||||||
{campaign.clickedCount > 0 && (
|
|
||||||
<div className="bg-orange-50 border border-orange-100 rounded-lg p-3">
|
|
||||||
<div className="flex items-center gap-2 mb-1">
|
|
||||||
<Mail className="h-3.5 w-3.5 text-orange-600" />
|
|
||||||
<span className="text-xs font-medium text-orange-900">Clicks</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-lg font-bold text-orange-900">{clickRate.toFixed(1)}%</p>
|
|
||||||
<p className="text-xs text-orange-700 mt-1">{campaign.clickedCount.toLocaleString()} clicked</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Scheduled For */}
|
|
||||||
{campaign.scheduledFor && (
|
|
||||||
<div className="bg-green-50 border border-green-100 rounded-lg p-3 md:col-span-2">
|
|
||||||
<div className="flex items-center gap-2 mb-1">
|
|
||||||
<Calendar className="h-3.5 w-3.5 text-green-600" />
|
|
||||||
<span className="text-xs font-medium text-green-900">Scheduled</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm font-semibold text-green-900">
|
|
||||||
{new Date(campaign.scheduledFor).toLocaleDateString(undefined, {
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
})}
|
|
||||||
</p>
|
|
||||||
<p className="text-xs text-green-700 mt-1">
|
|
||||||
{new Date(campaign.scheduledFor).toLocaleTimeString(undefined, {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: '2-digit',
|
|
||||||
})}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Actions */}
|
|
||||||
<div className="flex gap-2 pt-2 border-t border-neutral-100">
|
|
||||||
<Link href={`/campaigns/${campaign.id}`} className="flex-1">
|
|
||||||
<Button variant="outline" size="sm" className="w-full">
|
|
||||||
{campaign.status === 'DRAFT' ? 'Edit Campaign' : 'View Details'}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Button variant="outline" size="sm" onClick={() => handleDuplicate(campaign.id)}>
|
|
||||||
<Copy className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{campaign.status === 'DRAFT' && (
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
setCampaignToDelete(campaign.id);
|
|
||||||
setShowDeleteDialog(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Trash2 className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(campaign.status === 'SCHEDULED' || campaign.status === 'SENDING') && (
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
setCampaignToCancel(campaign.id);
|
|
||||||
setShowCancelDialog(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
)}
|
||||||
})}
|
|
||||||
|
{data?.campaigns.map(campaign => {
|
||||||
|
const openRate = campaign.sentCount > 0 ? (campaign.openedCount / campaign.sentCount) * 100 : 0;
|
||||||
|
const clickRate = campaign.sentCount > 0 ? (campaign.clickedCount / campaign.sentCount) * 100 : 0;
|
||||||
|
const deliveryProgress =
|
||||||
|
campaign.totalRecipients > 0 ? (campaign.sentCount / campaign.totalRecipients) * 100 : 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card key={campaign.id} className="hover:shadow-lg transition-all hover:border-primary/20">
|
||||||
|
<CardHeader className="pb-4">
|
||||||
|
<div className="flex items-start justify-between gap-4">
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="flex items-center gap-3 mb-2">
|
||||||
|
<Link
|
||||||
|
href={`/campaigns/${campaign.id}`}
|
||||||
|
className="hover:text-primary transition-colors flex-1 min-w-0"
|
||||||
|
>
|
||||||
|
<CardTitle className="text-xl truncate">{campaign.name}</CardTitle>
|
||||||
|
</Link>
|
||||||
|
{getStatusBadge(campaign.status)}
|
||||||
|
</div>
|
||||||
|
{campaign.description && (
|
||||||
|
<CardDescription className="line-clamp-2">{campaign.description}</CardDescription>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-4">
|
||||||
|
{/* Stats Grid */}
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
|
{/* Recipients */}
|
||||||
|
<div className="bg-blue-50 border border-blue-100 rounded-lg p-3">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<Users className="h-3.5 w-3.5 text-blue-600" />
|
||||||
|
<span className="text-xs font-medium text-blue-900">Recipients</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-lg font-bold text-blue-900">{campaign.totalRecipients.toLocaleString()}</p>
|
||||||
|
{campaign.totalRecipients > 0 && (
|
||||||
|
<p className="text-xs text-blue-700 mt-1">{deliveryProgress.toFixed(0)}% sent</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Open Rate */}
|
||||||
|
{campaign.sentCount > 0 && (
|
||||||
|
<div className="bg-purple-50 border border-purple-100 rounded-lg p-3">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<Mail className="h-3.5 w-3.5 text-purple-600" />
|
||||||
|
<span className="text-xs font-medium text-purple-900">Opens</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-lg font-bold text-purple-900">{openRate.toFixed(1)}%</p>
|
||||||
|
<p className="text-xs text-purple-700 mt-1">{campaign.openedCount.toLocaleString()} opened</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Click Rate */}
|
||||||
|
{campaign.clickedCount > 0 && (
|
||||||
|
<div className="bg-orange-50 border border-orange-100 rounded-lg p-3">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<Mail className="h-3.5 w-3.5 text-orange-600" />
|
||||||
|
<span className="text-xs font-medium text-orange-900">Clicks</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-lg font-bold text-orange-900">{clickRate.toFixed(1)}%</p>
|
||||||
|
<p className="text-xs text-orange-700 mt-1">
|
||||||
|
{campaign.clickedCount.toLocaleString()} clicked
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Scheduled For */}
|
||||||
|
{campaign.scheduledFor && (
|
||||||
|
<div className="bg-green-50 border border-green-100 rounded-lg p-3 md:col-span-2">
|
||||||
|
<div className="flex items-center gap-2 mb-1">
|
||||||
|
<Calendar className="h-3.5 w-3.5 text-green-600" />
|
||||||
|
<span className="text-xs font-medium text-green-900">Scheduled</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-semibold text-green-900">
|
||||||
|
{new Date(campaign.scheduledFor).toLocaleDateString(undefined, {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-green-700 mt-1">
|
||||||
|
{new Date(campaign.scheduledFor).toLocaleTimeString(undefined, {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: '2-digit',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Actions */}
|
||||||
|
<div className="flex gap-2 pt-2 border-t border-neutral-100">
|
||||||
|
<Link href={`/campaigns/${campaign.id}`} className="flex-1">
|
||||||
|
<Button variant="outline" size="sm" className="w-full">
|
||||||
|
{campaign.status === 'DRAFT' ? 'Edit Campaign' : 'View Details'}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Button variant="outline" size="sm" onClick={() => handleDuplicate(campaign.id)}>
|
||||||
|
<Copy className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{campaign.status === 'DRAFT' && (
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
setCampaignToDelete(campaign.id);
|
||||||
|
setShowDeleteDialog(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash2 className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(campaign.status === 'SCHEDULED' || campaign.status === 'SENDING') && (
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
setCampaignToCancel(campaign.id);
|
||||||
|
setShowCancelDialog(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Pagination */}
|
||||||
|
{data && data.totalPages > 1 && (
|
||||||
|
<div className="flex justify-center gap-2">
|
||||||
|
<Button variant="outline" onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page === 1}>
|
||||||
|
Previous
|
||||||
|
</Button>
|
||||||
|
<span className="flex items-center px-4 text-sm text-neutral-600">
|
||||||
|
Page {page} of {data.totalPages}
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => setPage(p => Math.min(data.totalPages, p + 1))}
|
||||||
|
disabled={page === data.totalPages}
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Pagination */}
|
<ConfirmDialog
|
||||||
{data && data.totalPages > 1 && (
|
open={showCancelDialog}
|
||||||
<div className="flex justify-center gap-2">
|
onOpenChange={setShowCancelDialog}
|
||||||
<Button variant="outline" onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page === 1}>
|
onConfirm={handleCancel}
|
||||||
Previous
|
title="Cancel Campaign"
|
||||||
</Button>
|
description="Are you sure you want to cancel this campaign?"
|
||||||
<span className="flex items-center px-4 text-sm text-neutral-600">
|
confirmText="Cancel Campaign"
|
||||||
Page {page} of {data.totalPages}
|
variant="destructive"
|
||||||
</span>
|
/>
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => setPage(p => Math.min(data.totalPages, p + 1))}
|
|
||||||
disabled={page === data.totalPages}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
open={showCancelDialog}
|
open={showDeleteDialog}
|
||||||
onOpenChange={setShowCancelDialog}
|
onOpenChange={setShowDeleteDialog}
|
||||||
onConfirm={handleCancel}
|
onConfirm={handleDelete}
|
||||||
title="Cancel Campaign"
|
title="Delete Campaign"
|
||||||
description="Are you sure you want to cancel this campaign?"
|
description="Are you sure you want to delete this draft campaign? This action cannot be undone."
|
||||||
confirmText="Cancel Campaign"
|
confirmText="Delete Campaign"
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
/>
|
/>
|
||||||
|
</DashboardLayout>
|
||||||
<ConfirmDialog
|
|
||||||
open={showDeleteDialog}
|
|
||||||
onOpenChange={setShowDeleteDialog}
|
|
||||||
onConfirm={handleDelete}
|
|
||||||
title="Delete Campaign"
|
|
||||||
description="Are you sure you want to delete this draft campaign? This action cannot be undone."
|
|
||||||
confirmText="Delete Campaign"
|
|
||||||
variant="destructive"
|
|
||||||
/>
|
|
||||||
</DashboardLayout>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,17 +483,17 @@ export default function Settings() {
|
|||||||
<CardContent className="pt-6 space-y-6">
|
<CardContent className="pt-6 space-y-6">
|
||||||
{/* Reset Project */}
|
{/* Reset Project */}
|
||||||
<div className="group">
|
<div className="group">
|
||||||
<div className="flex items-start justify-between gap-4 p-5 rounded-lg border border-gray-200 bg-white transition-all">
|
<div className="flex items-start justify-between gap-4 p-5 rounded-lg border border-neutral-200 bg-white transition-all">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<Database className="h-4 w-4 text-orange-600" />
|
<Database className="h-4 w-4 text-orange-600" />
|
||||||
<h4 className="font-semibold text-gray-900">Reset Project Data</h4>
|
<h4 className="font-semibold text-neutral-900">Reset Project Data</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-600 mb-3">
|
<p className="text-sm text-neutral-600 mb-3">
|
||||||
Clear all campaigns, contacts, workflows, templates, and events. This gives you a blank
|
Clear all campaigns, contacts, workflows, templates, and events. This gives you a blank
|
||||||
project to start fresh.
|
project to start fresh.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-start gap-2 text-xs text-gray-500">
|
<div className="flex items-start gap-2 text-xs text-neutral-500">
|
||||||
<span className="font-medium">Preserved:</span>
|
<span className="font-medium">Preserved:</span>
|
||||||
<span>API keys, domains, billing information</span>
|
<span>API keys, domains, billing information</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -701,7 +701,7 @@ export default function Settings() {
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="py-4">
|
<div className="py-4">
|
||||||
<label className="text-sm font-medium text-gray-700 block mb-2 text-center">
|
<label className="text-sm font-medium text-neutral-700 block mb-2 text-center">
|
||||||
Type{' '}
|
Type{' '}
|
||||||
<span className="font-mono font-semibold text-orange-600 bg-orange-50 px-2 py-0.5 rounded">RESET</span>{' '}
|
<span className="font-mono font-semibold text-orange-600 bg-orange-50 px-2 py-0.5 rounded">RESET</span>{' '}
|
||||||
to confirm
|
to confirm
|
||||||
@@ -759,7 +759,7 @@ export default function Settings() {
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="py-4">
|
<div className="py-4">
|
||||||
<label className="text-sm font-medium text-gray-700 block mb-2 text-center">
|
<label className="text-sm font-medium text-neutral-700 block mb-2 text-center">
|
||||||
Type <span className="font-mono font-semibold text-red-600 bg-red-50 px-2 py-0.5 rounded">DELETE</span>{' '}
|
Type <span className="font-mono font-semibold text-red-600 bg-red-50 px-2 py-0.5 rounded">DELETE</span>{' '}
|
||||||
to confirm
|
to confirm
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ export default function WorkflowEditorPage() {
|
|||||||
<h1 className="text-3xl font-bold text-neutral-900">{workflow.name}</h1>
|
<h1 className="text-3xl font-bold text-neutral-900">{workflow.name}</h1>
|
||||||
<span
|
<span
|
||||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
||||||
workflow.enabled ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
|
workflow.enabled ? 'bg-green-100 text-green-800' : 'bg-neutral-100 text-neutral-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{workflow.enabled ? (
|
{workflow.enabled ? (
|
||||||
@@ -618,8 +618,8 @@ export default function WorkflowEditorPage() {
|
|||||||
: execution.status === 'FAILED'
|
: execution.status === 'FAILED'
|
||||||
? 'bg-red-100 text-red-800'
|
? 'bg-red-100 text-red-800'
|
||||||
: execution.status === 'CANCELLED'
|
: execution.status === 'CANCELLED'
|
||||||
? 'bg-gray-100 text-gray-800'
|
? 'bg-neutral-100 text-neutral-800'
|
||||||
: 'bg-gray-100 text-gray-800'
|
: 'bg-neutral-100 text-neutral-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{execution.status}
|
{execution.status}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ export default function WorkflowsPage() {
|
|||||||
<CardTitle>{workflow.name}</CardTitle>
|
<CardTitle>{workflow.name}</CardTitle>
|
||||||
<span
|
<span
|
||||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
|
||||||
workflow.enabled ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
|
workflow.enabled ? 'bg-green-100 text-green-800' : 'bg-neutral-100 text-neutral-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{workflow.enabled ? (
|
{workflow.enabled ? (
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
::before,
|
::before,
|
||||||
::backdrop,
|
::backdrop,
|
||||||
::file-selector-button {
|
::file-selector-button {
|
||||||
border-color: var(--color-gray-200, currentcolor);
|
border-color: var(--color-neutral-200, currentcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user