stlyes fixes

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-29 19:52:51 +00:00
parent c91175fdcb
commit 4f7ab9c606
155 changed files with 1576 additions and 2489 deletions

View File

@@ -51,7 +51,7 @@ const ActivityLog: React.FC<ActivityLogProps> = ({ runId }) => {
</select>
</div>
</div>
<div className="bg-gray-900 dark:bg-gray-950 text-green-400 p-4 rounded-lg font-mono text-xs overflow-auto max-h-96 border border-gray-700">
<div className="bg-gray-900 dark:bg-gray-950 text-success-400 p-4 rounded-lg font-mono text-xs overflow-auto max-h-96 border border-gray-700">
<pre className="whitespace-pre-wrap">{logs || 'No logs available'}</pre>
</div>
</ComponentCard>

View File

@@ -58,8 +58,8 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
if (error) {
return (
<div className="bg-red-50 dark:bg-red-900/20 border-2 border-red-500 rounded-lg p-4 mb-6">
<p className="text-red-700 dark:text-red-300 text-sm">{error}</p>
<div className="bg-error-50 dark:bg-error-900/20 border-2 border-error-500 rounded-lg p-4 mb-6">
<p className="text-error-700 dark:text-error-300 text-sm">{error}</p>
</div>
);
}
@@ -71,13 +71,13 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
const percentage = processingState.percentage;
return (
<div className="bg-blue-50 dark:bg-blue-900/20 border-2 border-blue-500 rounded-lg p-6 mb-6">
<div className="bg-brand-50 dark:bg-brand-900/20 border-2 border-brand-500 rounded-lg p-6 mb-6">
{/* Header */}
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<div className="animate-pulse">
<svg
className="w-8 h-8 text-blue-600 dark:text-blue-400"
className="w-8 h-8 text-brand-600 dark:text-brand-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
@@ -96,14 +96,14 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">
Stage {currentStage}: {processingState.stage_name}
<span className="ml-2 px-2 py-0.5 bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300 rounded text-xs">
<span className="ml-2 px-2 py-0.5 bg-brand-100 dark:bg-brand-900 text-brand-700 dark:text-brand-300 rounded text-xs">
{processingState.stage_type}
</span>
</p>
</div>
</div>
<div className="text-right">
<div className="text-4xl font-bold text-blue-600 dark:text-blue-400">
<div className="text-4xl font-bold text-brand-600 dark:text-brand-400">
{percentage}%
</div>
<div className="text-sm text-gray-600 dark:text-gray-400">
@@ -116,7 +116,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="mb-6">
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-3">
<div
className="bg-blue-600 dark:bg-blue-500 h-3 rounded-full transition-all duration-500"
className="bg-brand-600 dark:bg-brand-500 h-3 rounded-full transition-all duration-500"
style={{ width: `${Math.min(percentage, 100)}%` }}
/>
</div>
@@ -133,7 +133,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
{processingState.currently_processing.length > 0 ? (
processingState.currently_processing.map((item, idx) => (
<div key={idx} className="flex items-start gap-2 text-sm">
<span className="text-blue-600 dark:text-blue-400 mt-1"></span>
<span className="text-brand-600 dark:text-brand-400 mt-1"></span>
<span className="text-gray-800 dark:text-gray-200 font-medium line-clamp-2">
{item.title}
</span>

View File

@@ -240,12 +240,12 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
if (error) {
return (
<div className="bg-red-50 dark:bg-red-900/20 border-2 border-red-500 rounded-lg p-4 mb-6">
<div className="bg-error-50 dark:bg-error-900/20 border-2 border-error-500 rounded-lg p-4 mb-6">
<div className="flex items-center justify-between">
<p className="text-red-700 dark:text-red-300 text-sm">{error}</p>
<p className="text-error-700 dark:text-error-300 text-sm">{error}</p>
<button
onClick={onClose}
className="text-red-500 hover:text-red-700 dark:hover:text-red-300"
className="text-error-500 hover:text-error-700 dark:hover:text-error-300"
>
<XMarkIcon className="w-5 h-5" />
</button>
@@ -321,21 +321,21 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
// Choose stage accent color (simple map matching AutomationPage STAGE_CONFIG)
const stageColors = [
'from-blue-500 to-blue-600',
'from-brand-500 to-brand-600',
'from-purple-500 to-purple-600',
'from-indigo-500 to-indigo-600',
'from-green-500 to-green-600',
'from-amber-500 to-amber-600',
'from-pink-500 to-pink-600',
'from-teal-500 to-teal-600',
'from-purple-500 to-purple-600',
'from-success-500 to-success-600',
'from-warning-500 to-warning-600',
'from-purple-500 to-purple-600',
'from-success-500 to-success-600',
];
const stageColorClass = stageColors[(currentRun.current_stage || 1) - 1] || 'from-blue-500 to-blue-600';
const stageColorClass = stageColors[(currentRun.current_stage || 1) - 1] || 'from-brand-500 to-brand-600';
return (
<div className={`border-2 rounded-lg p-6 mb-6 ${
isPaused
? 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-500'
: 'bg-blue-50 dark:bg-blue-900/20 border-blue-500'
? 'bg-warning-50 dark:bg-warning-900/20 border-warning-500'
: 'bg-brand-50 dark:bg-brand-900/20 border-brand-500'
}`}>
{/* Header Row with Main Info and Close */}
<div className="flex items-start justify-between mb-4">
@@ -344,9 +344,9 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="flex items-center gap-3 mb-4">
<div className={isPaused ? '' : 'animate-pulse'}>
{isPaused ? (
<PauseIcon className="w-8 h-8 text-yellow-600 dark:text-yellow-400" />
<PauseIcon className="w-8 h-8 text-warning-600 dark:text-warning-400" />
) : (
<BoltIcon className="w-8 h-8 text-blue-600 dark:text-blue-400" />
<BoltIcon className="w-8 h-8 text-brand-600 dark:text-brand-400" />
)}
</div>
<div className="flex-1">
@@ -361,8 +361,8 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
Stage {currentRun.current_stage}: {displayState.stage_name}
<span className={`ml-2 px-2 py-0.5 rounded text-xs ${
isPaused
? 'bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300'
: 'bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300'
? 'bg-warning-100 dark:bg-warning-900 text-warning-700 dark:text-warning-300'
: 'bg-brand-100 dark:bg-brand-900 text-brand-700 dark:text-brand-300'
}`}>
{displayState.stage_type}
</span>
@@ -396,7 +396,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<>
<div className="mb-4">
<div className="flex items-center justify-between mb-2">
<div className="text-3xl font-bold text-blue-600 dark:text-blue-400">
<div className="text-3xl font-bold text-brand-600 dark:text-brand-400">
{percentage}%
</div>
<div className="text-sm text-gray-600 dark:text-gray-400">
@@ -408,8 +408,8 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div
className={`h-3 rounded-full transition-all duration-500 ${
isPaused
? 'bg-yellow-600 dark:bg-yellow-500'
: 'bg-blue-600 dark:bg-blue-500'
? 'bg-warning-600 dark:bg-warning-500'
: 'bg-brand-600 dark:bg-brand-500'
}`}
style={{ width: `${Math.min(percentage, 100)}%` }}
/>
@@ -427,7 +427,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
{((displayState.currently_processing && displayState.currently_processing.length > 0) ? displayState.currently_processing : fetchedCurrently).length > 0 ? (
((displayState.currently_processing && displayState.currently_processing.length > 0) ? displayState.currently_processing : fetchedCurrently).map((item, idx) => (
<div key={idx} className="flex items-start gap-2 text-sm">
<span className={isPaused ? 'text-yellow-600 dark:text-yellow-400 mt-1' : 'text-blue-600 dark:text-blue-400 mt-1'}></span>
<span className={isPaused ? 'text-warning-600 dark:text-warning-400 mt-1' : 'text-brand-600 dark:text-brand-400 mt-1'}></span>
<span className="text-gray-800 dark:text-gray-200 font-medium line-clamp-2">
{item.title}
</span>
@@ -536,10 +536,10 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="bg-white dark:bg-gray-800 rounded-lg p-3 border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between mb-0">
<div className="flex items-center gap-2">
<BoltIcon className="w-4 h-4 text-amber-500" />
<BoltIcon className="w-4 h-4 text-warning-500" />
<div className="text-xs text-gray-500 dark:text-gray-400 uppercase font-semibold">Credits Used</div>
</div>
<div className="text-sm font-bold text-amber-600 dark:text-amber-400">{currentRun.total_credits_used}</div>
<div className="text-sm font-bold text-warning-600 dark:text-warning-400">{currentRun.total_credits_used}</div>
</div>
</div>
@@ -555,7 +555,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="bg-white dark:bg-gray-800 rounded-lg p-3 border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between mb-0">
<div className="text-xs text-gray-500 dark:text-gray-400 uppercase font-semibold">Status</div>
<div className={`text-sm font-semibold ${isPaused ? 'text-yellow-600 dark:text-yellow-400' : 'text-blue-600 dark:text-blue-400'}`}>
<div className={`text-sm font-semibold ${isPaused ? 'text-warning-600 dark:text-warning-400' : 'text-brand-600 dark:text-brand-400'}`}>
{isPaused ? 'Paused' : 'Running'}
</div>
</div>
@@ -567,7 +567,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<button
type="button"
onClick={() => setShowDebugTable(!showDebugTable)}
className="text-xs text-slate-600 hover:underline"
className="text-xs text-gray-600 hover:underline"
>
{showDebugTable ? 'Hide' : 'Show'} debug table
</button>

View File

@@ -193,16 +193,16 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
return (
<div className={`rounded-xl p-5 mb-6 border-2 transition-all ${
isPaused
? 'bg-gradient-to-r from-amber-50 to-amber-100 dark:from-amber-900/20 dark:to-amber-800/20 border-amber-400'
: 'bg-gradient-to-r from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20 border-blue-400'
? 'bg-gradient-to-r from-warning-50 to-warning-100 dark:from-warning-900/20 dark:to-warning-800/20 border-warning-400'
: 'bg-gradient-to-r from-brand-50 to-brand-100 dark:from-brand-900/20 dark:to-brand-800/20 border-brand-400'
}`}>
{/* Header Row */}
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
<div className={`size-10 rounded-lg flex items-center justify-center shadow-md ${
isPaused
? 'bg-gradient-to-br from-amber-500 to-amber-600'
: 'bg-gradient-to-br from-blue-500 to-blue-600'
? 'bg-gradient-to-br from-warning-500 to-warning-600'
: 'bg-gradient-to-br from-brand-500 to-brand-600'
}`}>
{isPaused ? (
<PauseIcon className="w-5 h-5 text-white" />
@@ -217,7 +217,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="text-sm text-gray-600 dark:text-gray-400">
Stage {currentRun.current_stage}: {stageName}
<span className={`ml-2 px-1.5 py-0.5 rounded text-xs ${
isPaused ? 'bg-amber-200 text-amber-800' : 'bg-blue-200 text-blue-800'
isPaused ? 'bg-warning-200 text-warning-800' : 'bg-brand-200 text-brand-800'
}`}>
{stageOverview?.type || 'AI'}
</span>
@@ -241,7 +241,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
{/* Progress Text */}
<div className="flex items-baseline justify-between mb-2">
<div className="flex items-baseline gap-3">
<span className={`text-4xl font-bold ${isPaused ? 'text-amber-600' : 'text-blue-600'}`}>
<span className={`text-4xl font-bold ${isPaused ? 'text-warning-600' : 'text-brand-600'}`}>
{displayPercent}%
</span>
<span className="text-sm text-gray-500">
@@ -258,8 +258,8 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div
className={`h-3 rounded-full transition-all duration-300 ${
isPaused
? 'bg-gradient-to-r from-amber-400 to-amber-600'
: 'bg-gradient-to-r from-blue-400 to-blue-600'
? 'bg-gradient-to-r from-warning-400 to-warning-600'
: 'bg-gradient-to-r from-brand-400 to-brand-600'
} ${!isPaused && displayPercent < 100 ? 'animate-pulse' : ''}`}
style={{ width: `${Math.min(displayPercent, 100)}%` }}
/>
@@ -292,7 +292,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<button
onClick={handleCancel}
disabled={isCancelling}
className="text-sm text-gray-500 hover:text-red-600 transition-colors"
className="text-sm text-gray-500 hover:text-error-600 transition-colors"
>
<XMarkIcon className="w-4 h-4 inline mr-1" />
{isCancelling ? 'Cancelling...' : 'Cancel'}
@@ -312,10 +312,10 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="bg-white dark:bg-gray-800 rounded-lg px-3 py-2 border border-gray-200 dark:border-gray-700 flex items-center justify-between">
<div className="flex items-center gap-1.5">
<BoltIcon className="w-4 h-4 text-amber-500" />
<BoltIcon className="w-4 h-4 text-warning-500" />
<span className="text-xs text-gray-500 uppercase">Credits</span>
</div>
<span className="text-sm font-bold text-amber-600">{currentRun.total_credits_used}</span>
<span className="text-sm font-bold text-warning-600">{currentRun.total_credits_used}</span>
</div>
<div className="bg-white dark:bg-gray-800 rounded-lg px-3 py-2 border border-gray-200 dark:border-gray-700 flex items-center justify-between">
@@ -325,7 +325,7 @@ const CurrentProcessingCard: React.FC<CurrentProcessingCardProps> = ({
<div className="bg-white dark:bg-gray-800 rounded-lg px-3 py-2 border border-gray-200 dark:border-gray-700 flex items-center justify-between">
<span className="text-xs text-gray-500 uppercase">Status</span>
<span className={`text-sm font-bold ${isPaused ? 'text-amber-600' : 'text-green-600'}`}>
<span className={`text-sm font-bold ${isPaused ? 'text-warning-600' : 'text-success-600'}`}>
{isPaused ? 'Paused' : 'Running'}
</span>
</div>

View File

@@ -9,13 +9,13 @@ import { BoltIcon, CheckCircleIcon, PauseIcon } from '../../icons';
// Stage colors matching AutomationPage STAGE_CONFIG
const STAGE_COLORS = [
'from-blue-500 to-blue-600', // Stage 1: Keywords → Clusters
'from-brand-500 to-brand-600', // Stage 1: Keywords → Clusters
'from-purple-500 to-purple-600', // Stage 2: Clusters → Ideas
'from-indigo-500 to-indigo-600', // Stage 3: Ideas → Tasks
'from-green-500 to-green-600', // Stage 4: Tasks → Content
'from-amber-500 to-amber-600', // Stage 5: Content → Image Prompts
'from-pink-500 to-pink-600', // Stage 6: Image Prompts → Images
'from-teal-500 to-teal-600', // Stage 7: Manual Review Gate
'from-purple-500 to-purple-600', // Stage 3: Ideas → Tasks
'from-success-500 to-success-600', // Stage 4: Tasks → Content
'from-warning-500 to-warning-600', // Stage 5: Content → Image Prompts
'from-purple-500 to-purple-600', // Stage 6: Image Prompts → Images
'from-success-500 to-success-600', // Stage 7: Manual Review Gate
];
const STAGE_NAMES = [
@@ -141,7 +141,7 @@ const GlobalProgressBar: React.FC<GlobalProgressBarProps> = ({
<div className={`
rounded-xl p-4 mb-6 border-2 transition-all
${isPaused
? 'bg-gradient-to-r from-amber-50 to-amber-100 dark:from-amber-900/20 dark:to-amber-800/20 border-amber-300 dark:border-amber-700'
? 'bg-gradient-to-r from-warning-50 to-warning-100 dark:from-warning-900/20 dark:to-warning-800/20 border-warning-300 dark:border-warning-700'
: 'bg-gradient-to-r from-brand-50 to-brand-100 dark:from-brand-900/20 dark:to-brand-800/20 border-brand-300 dark:border-brand-700'
}
`}>
@@ -151,7 +151,7 @@ const GlobalProgressBar: React.FC<GlobalProgressBarProps> = ({
<div className={`
size-10 rounded-lg flex items-center justify-center shadow-md
${isPaused
? 'bg-gradient-to-br from-amber-500 to-amber-600'
? 'bg-gradient-to-br from-warning-500 to-warning-600'
: 'bg-gradient-to-br from-brand-500 to-brand-600'
}
`}>
@@ -164,7 +164,7 @@ const GlobalProgressBar: React.FC<GlobalProgressBarProps> = ({
)}
</div>
<div>
<div className={`font-bold ${isPaused ? 'text-amber-800 dark:text-amber-200' : 'text-brand-800 dark:text-brand-200'}`}>
<div className={`font-bold ${isPaused ? 'text-warning-800 dark:text-warning-200' : 'text-brand-800 dark:text-brand-200'}`}>
{isPaused ? 'Pipeline Paused' : 'Full Pipeline Progress'}
</div>
<div className="text-xs text-gray-600 dark:text-gray-400">
@@ -172,7 +172,7 @@ const GlobalProgressBar: React.FC<GlobalProgressBarProps> = ({
</div>
</div>
</div>
<div className={`text-3xl font-bold ${isPaused ? 'text-amber-600 dark:text-amber-400' : 'text-brand-600 dark:text-brand-400'}`}>
<div className={`text-3xl font-bold ${isPaused ? 'text-warning-600 dark:text-warning-400' : 'text-brand-600 dark:text-brand-400'}`}>
{percentage}%
</div>
</div>
@@ -216,8 +216,8 @@ const GlobalProgressBar: React.FC<GlobalProgressBarProps> = ({
<span
key={stageNum}
className={`
${status === 'completed' ? 'text-green-600 dark:text-green-400 font-medium' : ''}
${status === 'active' ? `${isPaused ? 'text-amber-600 dark:text-amber-400' : 'text-brand-600 dark:text-brand-400'} font-bold` : ''}
${status === 'completed' ? 'text-success-600 dark:text-success-400 font-medium' : ''}
${status === 'active' ? `${isPaused ? 'text-warning-600 dark:text-warning-400' : 'text-brand-600 dark:text-brand-400'} font-bold` : ''}
${status === 'pending' ? 'text-gray-400 dark:text-gray-500' : ''}
`}
>

View File

@@ -32,10 +32,10 @@ const RunHistory: React.FC<RunHistoryProps> = ({ siteId }) => {
const getStatusBadge = (status: string) => {
const colors: Record<string, string> = {
completed: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
running: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
paused: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400',
failed: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
completed: 'bg-success-100 text-success-800 dark:bg-success-900/30 dark:text-success-400',
running: 'bg-brand-100 text-brand-800 dark:bg-brand-900/30 dark:text-brand-400',
paused: 'bg-warning-100 text-warning-800 dark:bg-warning-900/30 dark:text-warning-400',
failed: 'bg-error-100 text-error-800 dark:bg-error-900/30 dark:text-error-400',
};
return colors[status] || 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300';
};

View File

@@ -25,8 +25,8 @@ const StageCard: React.FC<StageCardProps> = ({
const isComplete = stageNumber < currentStage || (result !== null && stageNumber <= 7);
const getStatusColor = () => {
if (isActive) return 'border-blue-500 bg-blue-50 dark:bg-blue-900/20 dark:border-blue-400';
if (isComplete) return 'border-green-500 bg-green-50 dark:bg-green-900/20 dark:border-green-400';
if (isActive) return 'border-brand-500 bg-brand-50 dark:bg-brand-900/20 dark:border-brand-400';
if (isComplete) return 'border-success-500 bg-success-50 dark:bg-success-900/20 dark:border-success-400';
if (pipelineData && pipelineData.pending > 0) return 'border-purple-400 bg-purple-50 dark:bg-purple-900/20 dark:border-purple-400';
return 'border-gray-300 bg-gray-50 dark:bg-gray-800 dark:border-gray-600';
};
@@ -78,8 +78,8 @@ const StageCard: React.FC<StageCardProps> = ({
{/* Show processing indicator when active */}
{isActive && !result && (
<div className="mt-2 pt-2 border-t border-blue-200 dark:border-blue-600">
<div className="text-xs text-blue-600 dark:text-blue-400 animate-pulse">Processing...</div>
<div className="mt-2 pt-2 border-t border-brand-200 dark:border-brand-600">
<div className="text-xs text-brand-600 dark:text-brand-400 animate-pulse">Processing...</div>
</div>
)}
</div>

View File

@@ -93,8 +93,8 @@ export default function ProtectedRoute({ children }: ProtectedRouteProps) {
</p>
{showError && (
<div className="mt-4 p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
<p className="text-sm text-yellow-800 dark:text-yellow-200 mb-3">
<div className="mt-4 p-4 bg-warning-50 dark:bg-warning-900/20 border border-warning-200 dark:border-warning-800 rounded-lg">
<p className="text-sm text-warning-800 dark:text-warning-200 mb-3">
{errorMessage}
</p>
<button
@@ -103,7 +103,7 @@ export default function ProtectedRoute({ children }: ProtectedRouteProps) {
setShowError(false);
window.location.reload();
}}
className="px-4 py-2 text-sm bg-yellow-600 text-white rounded hover:bg-yellow-700"
className="px-4 py-2 text-sm bg-warning-600 text-white rounded hover:bg-warning-700"
>
Retry or Reload Page
</button>

View File

@@ -169,22 +169,22 @@ export default function SignInForm() {
<div className="space-y-6">
{/* Logout Reason Display */}
{logoutReason && (
<div className="p-4 bg-yellow-50 border border-yellow-200 rounded-lg dark:bg-yellow-900/20 dark:border-yellow-800">
<div className="p-4 bg-warning-50 border border-warning-200 rounded-lg dark:bg-warning-900/20 dark:border-warning-800">
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-2 mb-2">
<svg className="w-5 h-5 text-yellow-600 dark:text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
<svg className="w-5 h-5 text-warning-600 dark:text-warning-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
<h4 className="font-semibold text-yellow-800 dark:text-yellow-300">
<h4 className="font-semibold text-warning-800 dark:text-warning-300">
Session Ended
</h4>
</div>
<p className="text-sm text-yellow-700 dark:text-yellow-400 mb-2">
<p className="text-sm text-warning-700 dark:text-warning-400 mb-2">
{logoutReason.message}
</p>
{logoutReason.path && logoutReason.path !== '/signin' && (
<p className="text-xs text-yellow-600 dark:text-yellow-500">
<p className="text-xs text-warning-600 dark:text-warning-500">
Original page: <span className="font-mono">{logoutReason.path}</span>
</p>
)}
@@ -192,7 +192,7 @@ export default function SignInForm() {
<button
type="button"
onClick={() => setShowLogoutDetails(!showLogoutDetails)}
className="ml-2 p-1 text-yellow-600 hover:text-yellow-800 dark:text-yellow-400 dark:hover:text-yellow-300"
className="ml-2 p-1 text-warning-600 hover:text-warning-800 dark:text-warning-400 dark:hover:text-warning-300"
title="Toggle technical details"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
@@ -203,18 +203,18 @@ export default function SignInForm() {
{/* Expandable Technical Details */}
{showLogoutDetails && (
<div className="mt-3 pt-3 border-t border-yellow-300 dark:border-yellow-700">
<p className="text-xs font-semibold text-yellow-800 dark:text-yellow-300 mb-2">
<div className="mt-3 pt-3 border-t border-warning-300 dark:border-warning-700">
<p className="text-xs font-semibold text-warning-800 dark:text-warning-300 mb-2">
Technical Details:
</p>
<div className="space-y-1 text-xs font-mono text-yellow-700 dark:text-yellow-400">
<div className="space-y-1 text-xs font-mono text-warning-700 dark:text-warning-400">
<div><span className="font-bold">Code:</span> {logoutReason.code}</div>
<div><span className="font-bold">Source:</span> {logoutReason.source}</div>
<div><span className="font-bold">Time:</span> {new Date(logoutReason.timestamp).toLocaleString()}</div>
{logoutReason.context && Object.keys(logoutReason.context).length > 0 && (
<div className="mt-2">
<span className="font-bold">Context:</span>
<pre className="mt-1 p-2 bg-yellow-100 dark:bg-yellow-900/30 rounded text-xs overflow-x-auto">
<pre className="mt-1 p-2 bg-warning-100 dark:bg-warning-900/30 rounded text-xs overflow-x-auto">
{JSON.stringify(logoutReason.context, null, 2)}
</pre>
</div>
@@ -227,22 +227,22 @@ export default function SignInForm() {
{/* Session Conflict Alert */}
{sessionConflict && (
<div className="p-4 bg-orange-50 border border-orange-200 rounded-lg dark:bg-orange-900/20 dark:border-orange-800">
<div className="p-4 bg-warning-50 border border-warning-200 rounded-lg dark:bg-warning-900/20 dark:border-warning-800">
<div className="flex items-center gap-2 mb-3">
<svg className="w-5 h-5 text-orange-600 dark:text-orange-400" fill="currentColor" viewBox="0 0 20 20">
<svg className="w-5 h-5 text-warning-600 dark:text-warning-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
<h4 className="font-semibold text-orange-800 dark:text-orange-300">
<h4 className="font-semibold text-warning-800 dark:text-warning-300">
Active Session Detected
</h4>
</div>
<p className="text-sm text-orange-700 dark:text-orange-400 mb-2">
<p className="text-sm text-warning-700 dark:text-warning-400 mb-2">
You have an active session for:
</p>
<p className="text-sm font-semibold text-orange-800 dark:text-orange-300 mb-3">
<p className="text-sm font-semibold text-warning-800 dark:text-warning-300 mb-3">
{sessionConflict.existingUser.email}
</p>
<p className="text-sm text-orange-700 dark:text-orange-400 mb-4">
<p className="text-sm text-warning-700 dark:text-warning-400 mb-4">
You're trying to login as: <strong>{sessionConflict.requestedUser.email}</strong>
</p>
<div className="flex gap-3">
@@ -250,14 +250,14 @@ export default function SignInForm() {
type="button"
onClick={handleForceLogout}
disabled={loading}
className="flex-1 px-4 py-2 text-sm font-medium text-white bg-orange-600 rounded-lg hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
className="flex-1 px-4 py-2 text-sm font-medium text-white bg-warning-600 rounded-lg hover:bg-warning-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{loading ? 'Logging out...' : 'Logout Previous & Continue'}
</button>
<button
type="button"
onClick={() => setSessionConflict(null)}
className="flex-1 px-4 py-2 text-sm font-medium text-orange-700 bg-orange-100 rounded-lg hover:bg-orange-200 dark:bg-orange-900/40 dark:text-orange-300 dark:hover:bg-orange-900/60 transition-colors"
className="flex-1 px-4 py-2 text-sm font-medium text-warning-700 bg-warning-100 rounded-lg hover:bg-warning-200 dark:bg-warning-900/40 dark:text-warning-300 dark:hover:bg-warning-900/60 transition-colors"
>
Cancel
</button>
@@ -266,7 +266,7 @@ export default function SignInForm() {
)}
{error && (
<div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}

View File

@@ -188,7 +188,7 @@ export default function SignUpForm({ planDetails: planDetailsProp, planLoading:
<form onSubmit={handleSubmit}>
<div className="space-y-5">
{error && (
<div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}

View File

@@ -231,7 +231,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
${step === currentStep
? 'bg-brand-500 text-white'
: step < currentStep
? 'bg-green-500 text-white'
? 'bg-success-500 text-white'
: 'bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-400'
}
`}
@@ -245,7 +245,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
</div>
</div>
{step < 3 && (
<div className={`flex-1 h-0.5 mx-4 ${step < currentStep ? 'bg-green-500' : 'bg-gray-200 dark:bg-gray-700'}`} />
<div className={`flex-1 h-0.5 mx-4 ${step < currentStep ? 'bg-success-500' : 'bg-gray-200 dark:bg-gray-700'}`} />
)}
</div>
))}
@@ -282,7 +282,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
{renderStepIndicator()}
{error && (
<div className="mb-4 p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="mb-4 p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}

View File

@@ -231,7 +231,7 @@ export default function SignUpFormSimplified({ planDetails: planDetailsProp, pla
</div>
{error && (
<div className="mb-4 p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="mb-4 p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}
@@ -357,7 +357,7 @@ export default function SignUpFormSimplified({ planDetails: planDetailsProp, pla
<span className="text-sm text-gray-600 dark:text-gray-400">Loading payment options...</span>
</div>
) : paymentMethods.length === 0 ? (
<div className="p-4 bg-amber-50 border border-amber-200 rounded-lg text-amber-800 dark:bg-amber-900/20 dark:border-amber-800 dark:text-amber-200">
<div className="p-4 bg-warning-50 border border-warning-200 rounded-lg text-warning-800 dark:bg-warning-900/20 dark:border-warning-800 dark:text-warning-200">
<p className="text-sm">No payment methods available. Please contact support.</p>
</div>
) : (

View File

@@ -305,7 +305,7 @@ export default function SignUpFormUnified({
</button>
</div>
<div className="h-6 flex items-center justify-center">
<span className={`inline-flex items-center gap-1.5 text-xs text-green-600 dark:text-green-400 font-semibold bg-green-50 dark:bg-green-900/20 px-2 py-1 rounded-full transition-opacity duration-200 ${
<span className={`inline-flex items-center gap-1.5 text-xs text-success-600 dark:text-success-400 font-semibold bg-success-50 dark:bg-success-900/20 px-2 py-1 rounded-full transition-opacity duration-200 ${
billingPeriod === 'annually' ? 'opacity-100' : 'opacity-0'
}`}>
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -374,7 +374,7 @@ export default function SignUpFormUnified({
</div>
{error && (
<div className="mb-4 p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="mb-4 p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}
@@ -453,7 +453,7 @@ export default function SignUpFormUnified({
<Loader2 className="w-4 h-4 animate-spin text-brand-500" />
</div>
) : paymentMethods.length === 0 ? (
<div className="p-3 bg-amber-50 border border-amber-200 rounded-lg text-amber-800 dark:bg-amber-900/20 dark:border-amber-800 dark:text-amber-200">
<div className="p-3 bg-warning-50 border border-warning-200 rounded-lg text-warning-800 dark:bg-warning-900/20 dark:border-warning-800 dark:text-warning-200">
<p className="text-xs">No payment methods available</p>
</div>
) : (
@@ -565,7 +565,7 @@ export default function SignUpFormUnified({
</button>
</div>
<div className="h-7 flex items-center justify-center">
<p className={`inline-flex items-center gap-1.5 text-green-600 dark:text-green-400 text-sm font-semibold bg-green-50 dark:bg-green-900/20 px-3 py-1.5 rounded-full transition-opacity duration-200 ${
<p className={`inline-flex items-center gap-1.5 text-success-600 dark:text-success-400 text-sm font-semibold bg-success-50 dark:bg-success-900/20 px-3 py-1.5 rounded-full transition-opacity duration-200 ${
billingPeriod === 'annually' ? 'opacity-100' : 'opacity-0'
}`}>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -599,7 +599,7 @@ export default function SignUpFormUnified({
>
{isPopular && !isSelected && (
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
<span className="bg-gradient-to-r from-green-500 to-emerald-500 text-white text-xs font-bold px-3 py-1 rounded-full shadow-lg">
<span className="bg-gradient-to-r from-success-500 to-success-500 text-white text-xs font-bold px-3 py-1 rounded-full shadow-lg">
⭐ POPULAR
</span>
</div>
@@ -638,7 +638,7 @@ export default function SignUpFormUnified({
<div className="flex-1 grid grid-cols-2 gap-x-6 gap-y-2.5">
{features.map((feature, idx) => (
<div key={idx} className="flex items-center gap-2">
<CheckCircle className="w-4 h-4 text-green-500 dark:text-green-400 flex-shrink-0" />
<CheckCircle className="w-4 h-4 text-success-500 dark:text-success-400 flex-shrink-0" />
<span className="text-sm text-gray-700 dark:text-gray-300 leading-tight">{feature}</span>
</div>
))}

View File

@@ -39,7 +39,7 @@ export default function BillingBalancePanel() {
</div>
{error && !balance && (
<div className="p-4 rounded-lg border border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-800 dark:bg-amber-900/20 dark:text-amber-200">
<div className="p-4 rounded-lg border border-warning-200 bg-warning-50 text-warning-800 dark:border-warning-800 dark:bg-warning-900/20 dark:text-warning-200">
Usage unavailable. {error}
<div className="mt-3">
<Button variant="outline" size="sm" onClick={loadBalance}>
@@ -88,7 +88,7 @@ export default function BillingBalancePanel() {
)}
{error && balance && (
<div className="text-sm text-amber-600 dark:text-amber-400">
<div className="text-sm text-warning-600 dark:text-warning-400">
Latest balance may be stale: {error}
</div>
)}

View File

@@ -88,7 +88,7 @@ export default function BillingFormStep({
return (
<div className="space-y-5">
{error && (
<div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}

View File

@@ -62,7 +62,7 @@ export default function BillingRecentTransactions({ limit = 10, variant = 'card'
</div>
</div>
<div className="text-right">
<div className={`font-bold ${transaction.amount > 0 ? 'text-green-600' : 'text-red-600'}`}>
<div className={`font-bold ${transaction.amount > 0 ? 'text-success-600' : 'text-error-600'}`}>
{transaction.amount > 0 ? '+' : ''}{transaction.amount}
</div>
</div>

View File

@@ -89,7 +89,7 @@ export default function BillingUsagePanel({ showOnlyActivity = false }: BillingU
<td className="py-3 px-4">
<Badge variant="soft" tone={txn.amount >= 0 ? 'success' : 'danger'}>{txn.transaction_type}</Badge>
</td>
<td className={`py-3 px-4 text-sm font-medium ${txn.amount >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
<td className={`py-3 px-4 text-sm font-medium ${txn.amount >= 0 ? 'text-success-600 dark:text-success-400' : 'text-error-600 dark:text-error-400'}`}>
{txn.amount >= 0 ? '+' : ''}{txn.amount}
</td>
<td className="py-3 px-4 text-sm text-gray-600 dark:text-gray-400">{txn.description}</td>
@@ -178,7 +178,7 @@ export default function BillingUsagePanel({ showOnlyActivity = false }: BillingU
{usageLimits.credits_remaining?.toLocaleString?.() || 0}
</div>
{usageLimits.approaching_limit && (
<div className="text-sm text-amber-600 dark:text-amber-400 mt-1">Approaching limit</div>
<div className="text-sm text-warning-600 dark:text-warning-400 mt-1">Approaching limit</div>
)}
</div>
<div className="p-4 rounded-lg border border-gray-200 dark:border-gray-700">
@@ -236,7 +236,7 @@ export default function BillingUsagePanel({ showOnlyActivity = false }: BillingU
<td className="py-3 px-4">
<Badge variant="light" color={txn.amount >= 0 ? 'success' : 'error'}>{txn.transaction_type}</Badge>
</td>
<td className={`py-3 px-4 text-sm font-medium ${txn.amount >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
<td className={`py-3 px-4 text-sm font-medium ${txn.amount >= 0 ? 'text-success-600 dark:text-success-400' : 'text-error-600 dark:text-error-400'}`}>
{txn.amount >= 0 ? '+' : ''}{txn.amount}
</td>
<td className="py-3 px-4 text-sm text-gray-600 dark:text-gray-400">{txn.description}</td>

View File

@@ -72,7 +72,7 @@ export default function CreditCostBreakdownPanel() {
if (error || !summary) {
return (
<Card className="p-6 text-center">
<AlertCircle className="w-12 h-12 text-red-500 mx-auto mb-4" />
<AlertCircle className="w-12 h-12 text-error-500 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
Failed to Load Cost Data
</h3>
@@ -110,7 +110,7 @@ export default function CreditCostBreakdownPanel() {
{ bg: 'bg-info-50 dark:bg-info-900/20', text: 'text-info-600 dark:text-info-400', border: 'border-info-500 dark:border-info-400' },
{ bg: 'bg-purple-50 dark:bg-purple-900/20', text: 'text-purple-600 dark:text-purple-400', border: 'border-purple-500 dark:border-purple-400' },
{ bg: 'bg-warning-50 dark:bg-warning-900/20', text: 'text-warning-600 dark:text-warning-400', border: 'border-warning-500 dark:border-warning-400' },
{ bg: 'bg-teal-50 dark:bg-teal-900/20', text: 'text-teal-600 dark:text-teal-400', border: 'border-teal-500 dark:border-teal-400' },
{ bg: 'bg-purple-50 dark:bg-purple-900/20', text: 'text-purple-600 dark:text-purple-400', border: 'border-purple-500 dark:border-purple-400' },
];
return (

View File

@@ -174,7 +174,7 @@ export default function PaymentConfirmationModal({
<div className="p-6 sm:p-8">
{success ? (
<div className="text-center py-8">
<CheckCircle className="w-16 h-16 text-green-500 mx-auto mb-4" />
<CheckCircle className="w-16 h-16 text-success-500 mx-auto mb-4" />
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-2">
Payment Submitted!
</h3>
@@ -193,7 +193,7 @@ export default function PaymentConfirmationModal({
</p>
{error && (
<div className="mb-4 p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="mb-4 p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}
@@ -288,7 +288,7 @@ export default function PaymentConfirmationModal({
) : (
<div className="mt-2 flex items-center justify-between p-3 bg-gray-50 border border-gray-200 rounded-lg dark:bg-gray-800 dark:border-gray-700">
<div className="flex items-center gap-2">
<CheckCircle className="w-5 h-5 text-green-500" />
<CheckCircle className="w-5 h-5 text-success-500" />
<span className="text-sm text-gray-700 dark:text-gray-300">
{uploadedFileName}
</span>

View File

@@ -53,11 +53,11 @@ export default function PaymentHistory() {
const getStatusIcon = (status: string) => {
switch (status) {
case 'succeeded':
return <CheckCircle className="w-5 h-5 text-green-500" />;
return <CheckCircle className="w-5 h-5 text-success-500" />;
case 'failed':
return <XCircle className="w-5 h-5 text-red-500" />;
return <XCircle className="w-5 h-5 text-error-500" />;
case 'pending_approval':
return <Clock className="w-5 h-5 text-yellow-500" />;
return <Clock className="w-5 h-5 text-warning-500" />;
default:
return <Clock className="w-5 h-5 text-gray-500" />;
}
@@ -65,9 +65,9 @@ export default function PaymentHistory() {
const getStatusBadge = (status: string) => {
const badges = {
succeeded: 'bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400',
failed: 'bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400',
pending_approval: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-400',
succeeded: 'bg-success-100 text-success-800 dark:bg-success-900/20 dark:text-success-400',
failed: 'bg-error-100 text-error-800 dark:bg-error-900/20 dark:text-error-400',
pending_approval: 'bg-warning-100 text-warning-800 dark:bg-warning-900/20 dark:text-warning-400',
refunded: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-400',
};
return badges[status as keyof typeof badges] || badges.pending_approval;
@@ -104,7 +104,7 @@ export default function PaymentHistory() {
</div>
{error && (
<div className="p-4 bg-red-50 border border-red-200 rounded-lg text-red-600 dark:bg-red-900/20 dark:border-red-800">
<div className="p-4 bg-error-50 border border-error-200 rounded-lg text-error-600 dark:bg-error-900/20 dark:border-error-800">
{error}
</div>
)}

View File

@@ -84,7 +84,7 @@ export default function PaymentMethodSelect({
if (fetchError) {
return (
<div className="p-4 rounded-lg border border-red-200 bg-red-50 text-red-800 dark:border-red-800 dark:bg-red-900/20 dark:text-red-200">
<div className="p-4 rounded-lg border border-error-200 bg-error-50 text-error-800 dark:border-error-800 dark:bg-error-900/20 dark:text-error-200">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 flex-shrink-0 mt-0.5" />
<div>
@@ -104,7 +104,7 @@ export default function PaymentMethodSelect({
if (methods.length === 0) {
return (
<div className="p-4 rounded-lg border border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-800 dark:bg-amber-900/20 dark:text-amber-200">
<div className="p-4 rounded-lg border border-warning-200 bg-warning-50 text-warning-800 dark:border-warning-800 dark:bg-warning-900/20 dark:text-warning-200">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 flex-shrink-0 mt-0.5" />
<div>
@@ -123,7 +123,7 @@ export default function PaymentMethodSelect({
return (
<div className="space-y-4">
{error && (
<div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg dark:bg-red-900/20 dark:text-red-400 dark:border-red-800">
<div className="p-3 text-sm text-error-600 bg-error-50 border border-error-200 rounded-lg dark:bg-error-900/20 dark:text-error-400 dark:border-error-800">
{error}
</div>
)}
@@ -198,8 +198,8 @@ export default function PaymentMethodSelect({
))}
</div>
<div className="mt-4 p-4 rounded-lg bg-blue-50 border border-blue-200 dark:bg-blue-900/20 dark:border-blue-800">
<p className="text-sm text-blue-800 dark:text-blue-200">
<div className="mt-4 p-4 rounded-lg bg-brand-50 border border-brand-200 dark:bg-brand-900/20 dark:border-brand-800">
<p className="text-sm text-brand-800 dark:text-brand-200">
<span className="font-medium">Note:</span> For manual payment methods (bank transfer, local wallets),
you'll need to complete the payment and then submit proof of payment for admin approval.
</p>

View File

@@ -115,15 +115,15 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
// If no invoice found, show simplified banner
if (!invoice) {
return (
<div className={`relative border-l-4 border-amber-500 bg-amber-50 dark:bg-amber-900/20 ${className}`}>
<div className={`relative border-l-4 border-warning-500 bg-warning-50 dark:bg-warning-900/20 ${className}`}>
<div className="p-4">
<div className="flex items-start gap-4">
<AlertCircle className="w-6 h-6 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" />
<AlertCircle className="w-6 h-6 text-warning-600 dark:text-warning-400 flex-shrink-0 mt-0.5" />
<div className="flex-1">
<h3 className="font-semibold text-amber-900 dark:text-amber-100">
<h3 className="font-semibold text-warning-900 dark:text-warning-100">
Payment Required
</h3>
<p className="mt-1 text-sm text-amber-800 dark:text-amber-200">
<p className="mt-1 text-sm text-warning-800 dark:text-warning-200">
Your account is pending payment. Please complete your payment to activate your subscription.
</p>
<div className="mt-3 flex gap-2">
@@ -141,9 +141,9 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
</div>
<button
onClick={handleDismiss}
className="p-1 hover:bg-amber-100 dark:hover:bg-amber-800/40 rounded transition-colors"
className="p-1 hover:bg-warning-100 dark:hover:bg-warning-800/40 rounded transition-colors"
>
<X className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<X className="w-5 h-5 text-warning-600 dark:text-warning-400" />
</button>
</div>
</div>
@@ -167,59 +167,59 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
return (
<>
<div className={`relative border-l-4 ${isOverdue ? 'border-red-500 bg-red-50 dark:bg-red-900/20' : 'border-amber-500 bg-amber-50 dark:bg-amber-900/20'} ${className}`}>
<div className={`relative border-l-4 ${isOverdue ? 'border-error-500 bg-error-50 dark:bg-error-900/20' : 'border-warning-500 bg-warning-50 dark:bg-warning-900/20'} ${className}`}>
<div className="p-4">
<div className="flex items-start gap-4">
<AlertCircle
className={`w-6 h-6 flex-shrink-0 mt-0.5 ${isOverdue ? 'text-red-600 dark:text-red-400' : 'text-amber-600 dark:text-amber-400'}`}
className={`w-6 h-6 flex-shrink-0 mt-0.5 ${isOverdue ? 'text-error-600 dark:text-error-400' : 'text-warning-600 dark:text-warning-400'}`}
/>
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className={`font-semibold ${isOverdue ? 'text-red-900 dark:text-red-100' : 'text-amber-900 dark:text-amber-100'}`}>
<h3 className={`font-semibold ${isOverdue ? 'text-error-900 dark:text-error-100' : 'text-warning-900 dark:text-warning-100'}`}>
{isOverdue ? 'Payment Overdue' : 'Payment Required'}
</h3>
{isDueSoon && !isOverdue && (
<span className="px-2 py-0.5 text-xs font-medium rounded bg-amber-200 text-amber-900 dark:bg-amber-700 dark:text-amber-100">
<span className="px-2 py-0.5 text-xs font-medium rounded bg-warning-200 text-warning-900 dark:bg-warning-700 dark:text-warning-100">
Due Soon
</span>
)}
</div>
<p className={`mt-1 text-sm ${isOverdue ? 'text-red-800 dark:text-red-200' : 'text-amber-800 dark:text-amber-200'}`}>
<p className={`mt-1 text-sm ${isOverdue ? 'text-error-800 dark:text-error-200' : 'text-warning-800 dark:text-warning-200'}`}>
Your subscription is pending payment confirmation. Complete your payment to activate your account and unlock all features.
</p>
{/* Invoice Details */}
<div className="mt-3 grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
<div>
<span className={`block font-medium ${isOverdue ? 'text-red-700 dark:text-red-300' : 'text-amber-700 dark:text-amber-300'}`}>
<span className={`block font-medium ${isOverdue ? 'text-error-700 dark:text-error-300' : 'text-warning-700 dark:text-warning-300'}`}>
Invoice
</span>
<span className={`${isOverdue ? 'text-red-900 dark:text-red-100' : 'text-amber-900 dark:text-amber-100'}`}>
<span className={`${isOverdue ? 'text-error-900 dark:text-error-100' : 'text-warning-900 dark:text-warning-100'}`}>
#{invoice.invoice_number}
</span>
</div>
<div>
<span className={`block font-medium ${isOverdue ? 'text-red-700 dark:text-red-300' : 'text-amber-700 dark:text-amber-300'}`}>
<span className={`block font-medium ${isOverdue ? 'text-error-700 dark:text-error-300' : 'text-warning-700 dark:text-warning-300'}`}>
Amount
</span>
<span className={`${isOverdue ? 'text-red-900 dark:text-red-100' : 'text-amber-900 dark:text-amber-100'}`}>
<span className={`${isOverdue ? 'text-error-900 dark:text-error-100' : 'text-warning-900 dark:text-warning-100'}`}>
{invoice.currency} {invoice.total_amount}
</span>
</div>
<div>
<span className={`block font-medium ${isOverdue ? 'text-red-700 dark:text-red-300' : 'text-amber-700 dark:text-amber-300'}`}>
<span className={`block font-medium ${isOverdue ? 'text-error-700 dark:text-error-300' : 'text-warning-700 dark:text-warning-300'}`}>
Status
</span>
<span className={`${isOverdue ? 'text-red-900 dark:text-red-100' : 'text-amber-900 dark:text-amber-100'} capitalize`}>
<span className={`${isOverdue ? 'text-error-900 dark:text-error-100' : 'text-warning-900 dark:text-warning-100'} capitalize`}>
{invoice.status}
</span>
</div>
<div>
<span className={`block font-medium ${isOverdue ? 'text-red-700 dark:text-red-300' : 'text-amber-700 dark:text-amber-300'}`}>
<span className={`block font-medium ${isOverdue ? 'text-error-700 dark:text-error-300' : 'text-warning-700 dark:text-warning-300'}`}>
{isOverdue ? 'Was Due' : 'Due Date'}
</span>
<span className={`${isOverdue ? 'text-red-900 dark:text-red-100' : 'text-amber-900 dark:text-amber-100'}`}>
<span className={`${isOverdue ? 'text-error-900 dark:text-error-100' : 'text-warning-900 dark:text-warning-100'}`}>
{formatDate(invoice.due_date)}
</span>
</div>
@@ -248,8 +248,8 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
onClick={handleDismiss}
className={`p-1 rounded transition-colors ${
isOverdue
? 'hover:bg-red-100 dark:hover:bg-red-800/40 text-red-600 dark:text-red-400'
: 'hover:bg-amber-100 dark:hover:bg-amber-800/40 text-amber-600 dark:text-amber-400'
? 'hover:bg-error-100 dark:hover:bg-error-800/40 text-error-600 dark:text-error-400'
: 'hover:bg-warning-100 dark:hover:bg-warning-800/40 text-warning-600 dark:text-warning-400'
}`}
>
<X className="w-5 h-5" />

View File

@@ -29,18 +29,18 @@ function LimitCard({ title, icon, usage, type, daysUntilReset, accentColor = 'br
let badgeVariant: 'soft' = 'soft';
let badgeTone: 'brand' | 'warning' | 'danger' | 'success' | 'info' | 'purple' | 'indigo' | 'pink' | 'teal' | 'cyan' = accentColor;
// Color mapping for progress bars
// Color mapping for progress bars - using CSS variables
const colorMap: Record<string, string> = {
brand: '#0693e3',
success: '#0bbf87',
info: '#3b82f6',
warning: '#ff7a00',
danger: '#ef4444',
purple: '#8b5cf6',
indigo: '#6366f1',
pink: '#ec4899',
teal: '#14b8a6',
cyan: '#06b6d4',
brand: 'var(--color-primary)',
success: 'var(--color-success)',
info: 'var(--color-primary)',
warning: 'var(--color-warning)',
danger: 'var(--color-danger)',
purple: 'var(--color-purple)',
indigo: 'var(--color-purple)',
pink: 'var(--color-purple)',
teal: 'var(--color-success)',
cyan: 'var(--color-primary)',
};
if (isDanger) {
@@ -104,7 +104,7 @@ function LimitCard({ title, icon, usage, type, daysUntilReset, accentColor = 'br
{/* Warning Message */}
{isWarning && (
<div className={`mt-3 flex items-start gap-2 text-xs ${
isDanger ? 'text-red-600 dark:text-red-400' : 'text-yellow-600 dark:text-yellow-400'
isDanger ? 'text-error-600 dark:text-error-400' : 'text-warning-600 dark:text-warning-400'
}`}>
<AlertCircle className="w-4 h-4 mt-0.5 flex-shrink-0" />
<span>
@@ -158,7 +158,7 @@ export default function UsageLimitsPanel() {
if (error || !summary) {
return (
<Card className="p-6 text-center">
<AlertCircle className="w-12 h-12 text-red-500 mx-auto mb-4" />
<AlertCircle className="w-12 h-12 text-error-500 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
Failed to Load Usage Data
</h3>

View File

@@ -3,7 +3,7 @@ import { ApexOptions } from "apexcharts";
export default function BarChartOne() {
const options: ApexOptions = {
colors: ["#465fff"],
colors: ["var(--color-primary)"],
chart: {
fontFamily: "Outfit, sans-serif",
type: "bar",

View File

@@ -8,7 +8,7 @@ export default function LineChartOne() {
position: "top",
horizontalAlign: "left",
},
colors: ["#465FFF", "#9CB9FF"], // Define line colors
colors: ["var(--color-primary)", "var(--color-brand-300)"], // Define line colors
chart: {
fontFamily: "Outfit, sans-serif",
height: 310,
@@ -88,7 +88,7 @@ export default function LineChartOne() {
labels: {
style: {
fontSize: "12px", // Adjust font size for y-axis labels
colors: ["#6B7280"], // Color of the labels
colors: ["var(--color-gray-500)"], // Color of the labels
},
},
title: {

View File

@@ -36,8 +36,8 @@ export default function BulkExportModal({
<div className="p-6">
{/* Header with icon */}
<div className="flex items-center gap-3 mb-4">
<div className="flex items-center justify-center w-10 h-10 bg-blue-50 rounded-xl dark:bg-blue-500/10">
<InfoIcon className="w-5 h-5 text-blue-500" />
<div className="flex items-center justify-center w-10 h-10 bg-brand-50 rounded-xl dark:bg-brand-500/10">
<InfoIcon className="w-5 h-5 text-brand-500" />
</div>
<h2 className="text-xl font-bold text-gray-800 dark:text-white">
{title}

View File

@@ -55,8 +55,8 @@ export default function BulkStatusUpdateModal({
<div className="p-6">
{/* Header with icon */}
<div className="flex items-center gap-3 mb-4">
<div className="flex items-center justify-center w-10 h-10 bg-blue-50 rounded-xl dark:bg-blue-500/10">
<InfoIcon className="w-5 h-5 text-blue-500" />
<div className="flex items-center justify-center w-10 h-10 bg-brand-50 rounded-xl dark:bg-brand-500/10">
<InfoIcon className="w-5 h-5 text-brand-500" />
</div>
<h2 className="text-xl font-bold text-gray-800 dark:text-white">
{title}

View File

@@ -143,10 +143,10 @@ export default function ContentImageCell({ image, maxPromptLength = 100, showPro
)}
{image.status === 'failed' && (
<div className="w-full h-24 bg-red-100 dark:bg-red-900/20 rounded border border-red-300 dark:border-red-700 flex items-center justify-center">
<div className="w-full h-24 bg-error-100 dark:bg-error-900/20 rounded border border-error-300 dark:border-error-700 flex items-center justify-center">
<div className="text-center">
<svg
className="w-6 h-6 mx-auto text-red-500 mb-1"
className="w-6 h-6 mx-auto text-error-500 mb-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
@@ -158,7 +158,7 @@ export default function ContentImageCell({ image, maxPromptLength = 100, showPro
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<p className="text-xs text-red-700 dark:text-red-400">Failed</p>
<p className="text-xs text-error-700 dark:text-error-400">Failed</p>
</div>
</div>
)}

View File

@@ -18,25 +18,25 @@ export default function GlobalErrorDisplay() {
{errors.map((error, index) => (
<div
key={index}
className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg shadow-lg p-4 animate-in slide-in-from-right"
className="bg-error-50 dark:bg-error-900/20 border border-error-200 dark:border-error-800 rounded-lg shadow-lg p-4 animate-in slide-in-from-right"
>
<div className="flex items-start justify-between gap-2">
<div className="flex-1">
<div className="flex items-center gap-2 mb-1">
<span className="text-red-600 dark:text-red-400 text-lg"></span>
<span className="text-sm font-semibold text-red-800 dark:text-red-200">
<span className="text-error-600 dark:text-error-400 text-lg"></span>
<span className="text-sm font-semibold text-error-800 dark:text-error-200">
{error.source}
</span>
</div>
<p className="text-sm text-red-700 dark:text-red-300 mb-2">
<p className="text-sm text-error-700 dark:text-error-300 mb-2">
{error.message}
</p>
{error.stack && (
<details className="mt-2">
<summary className="text-xs text-red-600 dark:text-red-400 cursor-pointer hover:underline">
<summary className="text-xs text-error-600 dark:text-error-400 cursor-pointer hover:underline">
Show stack trace
</summary>
<pre className="mt-2 text-xs bg-red-100 dark:bg-red-900/40 p-2 rounded overflow-auto max-h-32">
<pre className="mt-2 text-xs bg-error-100 dark:bg-error-900/40 p-2 rounded overflow-auto max-h-32">
{error.stack}
</pre>
</details>
@@ -44,7 +44,7 @@ export default function GlobalErrorDisplay() {
</div>
<button
onClick={() => clearError(index)}
className="text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-200 text-xl leading-none"
className="text-error-600 dark:text-error-400 hover:text-error-800 dark:hover:text-error-200 text-xl leading-none"
aria-label="Dismiss error"
>
×
@@ -55,7 +55,7 @@ export default function GlobalErrorDisplay() {
{errors.length > 1 && (
<button
onClick={clearAllErrors}
className="w-full px-3 py-2 text-xs bg-red-600 text-white rounded hover:bg-red-700"
className="w-full px-3 py-2 text-xs bg-error-600 text-white rounded hover:bg-error-700"
>
Clear All Errors
</button>

View File

@@ -265,14 +265,14 @@ export default function ImageGenerationCard({
<div className="border-t border-gray-200 p-5 dark:border-gray-800">
<div className="space-y-5">
{/* API Provider and Model Display */}
<div className="flex items-center gap-3 rounded-lg bg-blue-50 px-4 py-3 dark:bg-blue-900/20">
<div className="flex items-center gap-3 rounded-lg bg-brand-50 px-4 py-3 dark:bg-brand-900/20">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
className="text-blue-600 dark:text-blue-400"
className="text-brand-600 dark:text-brand-400"
>
<path
d="M10 2L3 7V17C3 17.5304 3.21071 18.0391 3.58579 18.4142C3.96086 18.7893 4.46957 19 5 19H15C15.5304 19 16.0391 18.7893 16.4142 18.4142C16.7893 18.0391 17 17.5304 17 17V7L10 2Z"
@@ -283,8 +283,8 @@ export default function ImageGenerationCard({
/>
</svg>
<div>
<p className="text-xs font-medium text-blue-600 dark:text-blue-400">Provider & Model</p>
<p className="text-sm font-semibold text-blue-900 dark:text-blue-200">
<p className="text-xs font-medium text-brand-600 dark:text-brand-400">Provider & Model</p>
<p className="text-sm font-semibold text-brand-900 dark:text-brand-200">
{getProviderDisplay()}
</p>
</div>
@@ -299,7 +299,7 @@ export default function ImageGenerationCard({
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
rows={6}
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
placeholder="Describe the visual elements, style, mood, and composition you want in the image..."
/>
<p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
@@ -316,7 +316,7 @@ export default function ImageGenerationCard({
value={negativePrompt}
onChange={(e) => setNegativePrompt(e.target.value)}
rows={2}
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
className="w-full rounded-lg border border-gray-300 px-4 py-3 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
placeholder="Describe what you DON'T want in the image..."
/>
<p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
@@ -334,7 +334,7 @@ export default function ImageGenerationCard({
<select
value={imageType}
onChange={(e) => setImageType(e.target.value)}
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
>
{typeOptions.map((option) => (
<option key={option.value} value={option.value}>
@@ -352,7 +352,7 @@ export default function ImageGenerationCard({
<select
value={imageSize}
onChange={(e) => setImageSize(e.target.value)}
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
>
{sizeOptions.map((option) => (
<option key={option.value} value={option.value}>
@@ -370,7 +370,7 @@ export default function ImageGenerationCard({
<select
value={imageFormat}
onChange={(e) => setImageFormat(e.target.value)}
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
className="w-full rounded-lg border border-gray-300 px-4 py-2.5 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-white"
>
{formatOptions.map((option) => (
<option key={option.value} value={option.value}>
@@ -440,8 +440,8 @@ export default function ImageGenerationCard({
{/* Error display */}
{error && (
<div className="mt-4 rounded-lg border border-red-200 bg-red-50 p-4 dark:border-red-800 dark:bg-red-900/20">
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
<div className="mt-4 rounded-lg border border-error-200 bg-error-50 p-4 dark:border-error-800 dark:bg-error-900/20">
<p className="text-sm text-error-600 dark:text-error-400">{error}</p>
</div>
)}
</article>

View File

@@ -446,11 +446,11 @@ export default function ImageQueueModal({
const getProgressColor = (status: string) => {
switch (status) {
case 'completed':
return 'bg-green-500';
return 'bg-success-500';
case 'failed':
return 'bg-red-500';
return 'bg-error-500';
case 'processing':
return 'bg-blue-500';
return 'bg-brand-500';
default:
return 'bg-gray-300';
}
@@ -471,7 +471,7 @@ export default function ImageQueueModal({
{/* Header */}
<div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
<div className="flex items-center gap-3">
<FileIcon className="w-6 h-6 text-blue-500" />
<FileIcon className="w-6 h-6 text-brand-500" />
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Generating Images
@@ -496,11 +496,11 @@ export default function ImageQueueModal({
key={item.index}
className={`p-4 rounded-lg border-2 transition-colors ${
item.status === 'processing'
? 'bg-blue-50 dark:bg-blue-900/20 border-blue-500'
? 'bg-brand-50 dark:bg-brand-900/20 border-brand-500'
: item.status === 'completed'
? 'bg-green-50 dark:bg-green-900/20 border-green-500'
? 'bg-success-50 dark:bg-success-900/20 border-success-500'
: item.status === 'failed'
? 'bg-red-50 dark:bg-red-900/20 border-red-500'
? 'bg-error-50 dark:bg-error-900/20 border-error-500'
: 'bg-gray-50 dark:bg-gray-700/50 border-gray-300 dark:border-gray-600'
}`}
>
@@ -509,7 +509,7 @@ export default function ImageQueueModal({
<div className="flex-1">
{/* Header Row */}
<div className="flex items-center gap-3 mb-2">
<span className="flex items-center justify-center w-6 h-6 rounded-full bg-blue-500 text-white text-xs font-bold">
<span className="flex items-center justify-center w-6 h-6 rounded-full bg-brand-500 text-white text-xs font-bold">
{item.index}
</span>
<span className="font-semibold text-sm text-gray-900 dark:text-white">
@@ -551,7 +551,7 @@ export default function ImageQueueModal({
{/* Error Message */}
{item.error && (
<div className="mt-2 p-2 bg-red-100 dark:bg-red-900/30 border-l-4 border-red-500 rounded text-xs text-red-700 dark:text-red-300">
<div className="mt-2 p-2 bg-error-100 dark:bg-error-900/30 border-l-4 border-error-500 rounded text-xs text-error-700 dark:text-error-300">
{item.error}
</div>
)}
@@ -595,7 +595,7 @@ export default function ImageQueueModal({
{allDone && (
<button
onClick={onClose}
className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
className="px-4 py-2 bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors"
>
Close
</button>

View File

@@ -79,7 +79,7 @@ export default function ImageResultCard({
<div className="border-t border-gray-200 p-5 dark:border-gray-800">
{errorState ? (
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="mb-4 rounded-full bg-red-100 p-4 dark:bg-red-900/20">
<div className="mb-4 rounded-full bg-error-100 p-4 dark:bg-error-900/20">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
@@ -90,7 +90,7 @@ export default function ImageResultCard({
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-red-600 dark:text-red-400"
className="text-error-600 dark:text-error-400"
>
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
<line x1="12" y1="9" x2="12" y2="13" />

View File

@@ -100,10 +100,10 @@ export default function IntegrationCard({
return 'bg-gray-400 dark:bg-gray-500 animate-pulse'; // Grey while validating (with pulse)
}
if (validationStatus === 'success') {
return 'bg-green-500 dark:bg-green-600'; // Green for success
return 'bg-success-500 dark:bg-success-600'; // Green for success
}
if (validationStatus === 'error') {
return 'bg-red-500 dark:bg-red-600'; // Red for error
return 'bg-error-500 dark:bg-error-600'; // Red for error
}
return 'bg-gray-400 dark:bg-gray-500'; // Default grey
};
@@ -120,7 +120,7 @@ export default function IntegrationCard({
return { text: 'Enabled', color: 'text-gray-800 dark:text-white', bold: true };
}
if (validationStatus === 'error') {
return { text: 'Error', color: 'text-red-600 dark:text-red-400', bold: false };
return { text: 'Error', color: 'text-error-600 dark:text-error-400', bold: false };
}
return { text: 'Disabled', color: 'text-gray-400 dark:text-gray-500', bold: false };
};

View File

@@ -100,18 +100,18 @@ export default function PageHeader({
}, [activeSite?.id, activeSite?.is_active, hideSiteSector, loadSectorsForSite, addError]);
const badgeColors = {
blue: { bg: 'bg-blue-600 dark:bg-blue-500', light: 'bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300' },
green: { bg: 'bg-green-600 dark:bg-green-500', light: 'bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-300' },
blue: { bg: 'bg-brand-600 dark:bg-brand-500', light: 'bg-brand-100 text-brand-700 dark:bg-brand-500/20 dark:text-brand-300' },
green: { bg: 'bg-success-600 dark:bg-success-500', light: 'bg-success-100 text-success-700 dark:bg-success-500/20 dark:text-success-300' },
purple: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
orange: { bg: 'bg-orange-600 dark:bg-orange-500', light: 'bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-300' },
red: { bg: 'bg-red-600 dark:bg-red-500', light: 'bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-300' },
indigo: { bg: 'bg-indigo-600 dark:bg-indigo-500', light: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-500/20 dark:text-indigo-300' },
yellow: { bg: 'bg-yellow-600 dark:bg-yellow-500', light: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-500/20 dark:text-yellow-300' },
pink: { bg: 'bg-pink-600 dark:bg-pink-500', light: 'bg-pink-100 text-pink-700 dark:bg-pink-500/20 dark:text-pink-300' },
emerald: { bg: 'bg-emerald-600 dark:bg-emerald-500', light: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-300' },
cyan: { bg: 'bg-cyan-600 dark:bg-cyan-500', light: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-500/20 dark:text-cyan-300' },
amber: { bg: 'bg-amber-600 dark:bg-amber-500', light: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300' },
teal: { bg: 'bg-teal-600 dark:bg-teal-500', light: 'bg-teal-100 text-teal-700 dark:bg-teal-500/20 dark:text-teal-300' },
orange: { bg: 'bg-warning-600 dark:bg-warning-500', light: 'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-300' },
red: { bg: 'bg-error-600 dark:bg-error-500', light: 'bg-error-100 text-error-700 dark:bg-error-500/20 dark:text-error-300' },
indigo: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
yellow: { bg: 'bg-warning-600 dark:bg-warning-500', light: 'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-300' },
pink: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
emerald: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
cyan: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
amber: { bg: 'bg-warning-600 dark:bg-warning-500', light: 'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-300' },
teal: { bg: 'bg-purple-600 dark:bg-purple-500', light: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-300' },
};
return (

View File

@@ -775,7 +775,7 @@ export default function ProgressModal({
<div className="mb-6">
{/* Big centered check icon */}
<div className="flex justify-center mb-4">
<div className="w-16 h-16 rounded-full bg-green-600 dark:bg-green-700 flex items-center justify-center">
<div className="w-16 h-16 rounded-full bg-success-600 dark:bg-success-700 flex items-center justify-center">
<svg className="w-10 h-10 text-white" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
@@ -783,7 +783,7 @@ export default function ProgressModal({
</div>
{/* Dark success alert box with centered text */}
<div className="p-5 rounded-lg bg-green-600 dark:bg-green-700 border border-green-700 dark:border-green-600">
<div className="p-5 rounded-lg bg-success-600 dark:bg-success-700 border border-success-700 dark:border-success-600">
<div className="text-base font-semibold text-white text-center whitespace-pre-line">
{successMessage}
</div>
@@ -798,14 +798,14 @@ export default function ProgressModal({
key={index}
className={`flex items-center gap-3 p-3 rounded-lg border transition-all ${
item.completed
? 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800'
? 'bg-success-50 dark:bg-success-900/20 border-success-200 dark:border-success-800'
: 'bg-gray-50 dark:bg-gray-800 border-gray-200 dark:border-gray-700 opacity-60'
}`}
>
{/* Icon - only checkmark for completed, gray circle for pending */}
<div className="flex-shrink-0">
{item.completed ? (
<svg className="w-5 h-5 text-green-600 dark:text-green-400" fill="currentColor" viewBox="0 0 20 20">
<svg className="w-5 h-5 text-success-600 dark:text-success-400" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
) : (
@@ -817,7 +817,7 @@ export default function ProgressModal({
<span
className={`flex-1 text-sm font-medium ${
item.completed
? 'text-green-800 dark:text-green-300'
? 'text-success-800 dark:text-success-300'
: 'text-gray-500 dark:text-gray-400'
}`}
>
@@ -834,7 +834,7 @@ export default function ProgressModal({
variant="primary"
size="lg"
onClick={onClose}
className="bg-green-600 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-800 text-white px-8 py-3 text-base font-semibold"
className="bg-success-600 hover:bg-success-700 dark:bg-success-700 dark:hover:bg-success-800 text-white px-8 py-3 text-base font-semibold"
>
Close
</Button>

View File

@@ -97,14 +97,14 @@ export default function SectorSelector() {
onItemClick={() => handleSectorSelect(null)}
className={`flex items-center gap-3 px-3 py-2 font-medium rounded-lg text-sm text-left ${
!activeSector
? "bg-blue-50 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300"
? "bg-brand-50 text-brand-700 dark:bg-brand-500/20 dark:text-brand-300"
: "text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-300"
}`}
>
<span className="flex-1">All Sectors</span>
{!activeSector && (
<svg
className="w-4 h-4 text-blue-600 dark:text-blue-400"
className="w-4 h-4 text-brand-600 dark:text-brand-400"
fill="currentColor"
viewBox="0 0 20 20"
>
@@ -122,14 +122,14 @@ export default function SectorSelector() {
onItemClick={() => handleSectorSelect(sector.id)}
className={`flex items-center gap-3 px-3 py-2 font-medium rounded-lg text-sm text-left ${
activeSector?.id === sector.id
? "bg-blue-50 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300"
? "bg-brand-50 text-brand-700 dark:bg-brand-500/20 dark:text-brand-300"
: "text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-300"
}`}
>
<span className="flex-1">{sector.name}</span>
{activeSector?.id === sector.id && (
<svg
className="w-4 h-4 text-blue-600 dark:text-blue-400"
className="w-4 h-4 text-brand-600 dark:text-brand-400"
fill="currentColor"
viewBox="0 0 20 20"
>

View File

@@ -55,8 +55,8 @@ export default function SingleRecordStatusUpdateModal({
<div className="p-6">
{/* Header with icon */}
<div className="flex items-center gap-3 mb-4">
<div className="flex items-center justify-center w-10 h-10 bg-blue-50 rounded-xl dark:bg-blue-500/10">
<InfoIcon className="w-5 h-5 text-blue-500" />
<div className="flex items-center justify-center w-10 h-10 bg-brand-50 rounded-xl dark:bg-brand-500/10">
<InfoIcon className="w-5 h-5 text-brand-500" />
</div>
<h2 className="text-xl font-bold text-gray-800 dark:text-white">
{title}

View File

@@ -28,14 +28,14 @@ export default function SiteCard({
const getStatusColor = () => {
if (site.is_active) {
return 'bg-green-500 dark:bg-green-600';
return 'bg-success-500 dark:bg-success-600';
}
return 'bg-gray-400 dark:bg-gray-500';
};
const getStatusText = () => {
if (site.is_active) {
return { text: 'Active', color: 'text-green-600 dark:text-green-400', bold: true };
return { text: 'Active', color: 'text-success-600 dark:text-success-400', bold: true };
}
return { text: 'Inactive', color: 'text-gray-400 dark:text-gray-500', bold: false };
};

View File

@@ -335,7 +335,7 @@ export const ToggleButton: React.FC<ToggleButtonProps> = ({
onClick={onClick}
className={`inline-flex items-center justify-center w-8 h-8 rounded-lg transition-all duration-200 ${
isExpanded
? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20'
? 'text-brand-600 dark:text-brand-400 bg-brand-50 dark:bg-brand-900/20'
: 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800'
} ${className}`}
aria-label={isExpanded ? 'Collapse content' : 'Expand content'}

View File

@@ -161,7 +161,7 @@ export default function ValidationCard({
<div className="space-y-3">
{/* Success Message */}
{testResult.success && (
<div className="flex items-center gap-2 text-green-600 dark:text-green-400">
<div className="flex items-center gap-2 text-success-600 dark:text-success-400">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
@@ -171,7 +171,7 @@ export default function ValidationCard({
{/* Error Message */}
{!testResult.success && (
<div className="flex items-center gap-2 text-red-600 dark:text-red-400">
<div className="flex items-center gap-2 text-error-600 dark:text-error-400">
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
</svg>
@@ -181,7 +181,7 @@ export default function ValidationCard({
{/* Detailed Results Box */}
{testResult.success && (
<div className="bg-blue-50 dark:bg-blue-900/20 border-l-4 border-blue-500 p-4 rounded">
<div className="bg-brand-50 dark:bg-brand-900/20 border-l-4 border-brand-500 p-4 rounded">
<div className="space-y-2 text-sm">
{integrationId === 'openai' && withResponse ? (
// OpenAI response test details
@@ -241,7 +241,7 @@ export default function ValidationCard({
href={testResult.full_response.image_url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 dark:text-blue-400 hover:underline"
className="text-brand-600 dark:text-brand-400 hover:underline"
>
View Image
</a>

View File

@@ -27,32 +27,32 @@ export const WorkflowInsights: React.FC<WorkflowInsightsProps> = ({ insights, cl
const notificationColors = hasCritical
? {
bg: 'bg-amber-50 dark:bg-amber-500/10',
border: 'border-amber-300 dark:border-amber-700',
iconBg: 'bg-amber-100 dark:bg-amber-500/20',
bg: 'bg-warning-50 dark:bg-warning-500/10',
border: 'border-warning-300 dark:border-warning-700',
iconBg: 'bg-warning-100 dark:bg-warning-500/20',
}
: hasSuccess
? {
bg: 'bg-green-50 dark:bg-green-500/10',
border: 'border-green-300 dark:border-green-700',
iconBg: 'bg-green-100 dark:bg-green-500/20',
bg: 'bg-success-50 dark:bg-success-500/10',
border: 'border-success-300 dark:border-success-700',
iconBg: 'bg-success-100 dark:bg-success-500/20',
}
: {
bg: 'bg-blue-50 dark:bg-blue-500/10',
border: 'border-blue-300 dark:border-blue-700',
iconBg: 'bg-blue-100 dark:bg-blue-500/20',
bg: 'bg-brand-50 dark:bg-brand-500/10',
border: 'border-brand-300 dark:border-brand-700',
iconBg: 'bg-brand-100 dark:bg-brand-500/20',
};
const getIcon = (type: string) => {
switch (type) {
case 'success':
return <CheckCircleIcon className="w-5 h-5 text-green-600 dark:text-green-400" />;
return <CheckCircleIcon className="w-5 h-5 text-success-600 dark:text-success-400" />;
case 'warning':
return <AlertIcon className="w-5 h-5 text-amber-600 dark:text-amber-400" />;
return <AlertIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />;
case 'action':
return <BoltIcon className="w-5 h-5 text-blue-600 dark:text-blue-400" />;
return <BoltIcon className="w-5 h-5 text-brand-600 dark:text-brand-400" />;
default:
return <InfoIcon className="w-5 h-5 text-blue-600 dark:text-blue-400" />;
return <InfoIcon className="w-5 h-5 text-brand-600 dark:text-brand-400" />;
}
};

View File

@@ -39,7 +39,7 @@ export const ContentFilter: React.FC<ContentFilterProps> = ({ onFilterChange, cl
placeholder="Search content..."
value={filters.search}
onChange={handleSearchChange}
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-800 dark:border-gray-600 dark:text-white"
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-brand-500 focus:border-transparent dark:bg-gray-800 dark:border-gray-600 dark:text-white"
/>
</div>
@@ -51,7 +51,7 @@ export const ContentFilter: React.FC<ContentFilterProps> = ({ onFilterChange, cl
onClick={() => handleSourceChange('all')}
className={`px-3 py-1 rounded-full text-sm font-medium transition-colors ${
filters.source === 'all'
? 'bg-blue-500 text-white'
? 'bg-brand-500 text-white'
: 'bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600'
}`}
>
@@ -63,7 +63,7 @@ export const ContentFilter: React.FC<ContentFilterProps> = ({ onFilterChange, cl
onClick={() => handleSourceChange(source)}
className={`px-3 py-1 rounded-full text-sm font-medium transition-colors ${
filters.source === source
? 'bg-blue-500 text-white'
? 'bg-brand-500 text-white'
: 'bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600'
}`}
>

View File

@@ -8,9 +8,9 @@ interface SourceBadgeProps {
}
const sourceConfig = {
igny8: { label: 'IGNY8', color: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300' },
igny8: { label: 'IGNY8', color: 'bg-brand-100 text-brand-800 dark:bg-brand-900 dark:text-brand-300' },
wordpress: { label: 'WordPress', color: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300' },
shopify: { label: 'Shopify', color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300' },
shopify: { label: 'Shopify', color: 'bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-300' },
custom: { label: 'Custom', color: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300' },
};

View File

@@ -8,9 +8,9 @@ interface SyncStatusBadgeProps {
}
const statusConfig = {
native: { label: 'Native', color: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-300' },
imported: { label: 'Imported', color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300' },
synced: { label: 'Synced', color: 'bg-teal-100 text-teal-800 dark:bg-teal-900 dark:text-teal-300' },
native: { label: 'Native', color: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300' },
imported: { label: 'Imported', color: 'bg-warning-100 text-warning-800 dark:bg-warning-900 dark:text-warning-300' },
synced: { label: 'Synced', color: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300' },
};
export const SyncStatusBadge: React.FC<SyncStatusBadgeProps> = ({ status, className = '' }) => {

View File

@@ -35,13 +35,16 @@ interface AIOperationsWidgetProps {
loading?: boolean;
}
const operationConfig = {
const operationConfig: Record<string, { label: string; icon: typeof GroupIcon; color: string }> = {
clustering: { label: 'Clustering', icon: GroupIcon, color: 'text-purple-600 dark:text-purple-400' },
ideas: { label: 'Ideas', icon: BoltIcon, color: 'text-orange-600 dark:text-orange-400' },
content: { label: 'Content', icon: FileTextIcon, color: 'text-green-600 dark:text-green-400' },
images: { label: 'Images', icon: FileIcon, color: 'text-pink-600 dark:text-pink-400' },
ideas: { label: 'Ideas', icon: BoltIcon, color: 'text-warning-600 dark:text-warning-400' },
content: { label: 'Content', icon: FileTextIcon, color: 'text-success-600 dark:text-success-400' },
images: { label: 'Images', icon: FileIcon, color: 'text-purple-600 dark:text-purple-400' },
};
// Default config for unknown operation types
const defaultConfig = { label: 'Other', icon: BoltIcon, color: 'text-gray-600 dark:text-gray-400' };
const periods = [
{ value: '7d', label: '7 days' },
{ value: '30d', label: '30 days' },
@@ -105,7 +108,7 @@ export default function AIOperationsWidget({ data, onPeriodChange, loading }: AI
{/* Operation Rows */}
{data.operations.map((op) => {
const config = operationConfig[op.type];
const config = operationConfig[op.type] || defaultConfig;
const Icon = config.icon;
return (
@@ -144,7 +147,7 @@ export default function AIOperationsWidget({ data, onPeriodChange, loading }: AI
{/* Stats Footer */}
<div className="flex items-center justify-between mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="text-sm text-gray-600 dark:text-gray-400">
Success Rate: <span className="font-semibold text-green-600 dark:text-green-400">
Success Rate: <span className="font-semibold text-success-600 dark:text-success-400">
{loading ? '—' : `${data.totals.successRate}%`}
</span>
</div>

View File

@@ -37,8 +37,8 @@ interface AutomationStatusWidgetProps {
const statusConfig = {
active: {
label: 'Active',
color: 'text-green-600 dark:text-green-400',
bgColor: 'bg-green-500',
color: 'text-success-600 dark:text-success-400',
bgColor: 'bg-success-500',
icon: CheckCircleIcon,
},
paused: {
@@ -49,8 +49,8 @@ const statusConfig = {
},
failed: {
label: 'Failed',
color: 'text-red-600 dark:text-red-400',
bgColor: 'bg-red-500',
color: 'text-error-600 dark:text-error-400',
bgColor: 'bg-error-500',
icon: AlertIcon,
},
not_configured: {

View File

@@ -95,11 +95,11 @@ export default function ContentVelocityWidget({ data, loading }: ContentVelocity
<div className="flex items-center justify-between mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="flex items-center gap-2">
{isPositiveTrend ? (
<TrendingUpIcon className="w-5 h-5 text-green-600" />
<TrendingUpIcon className="w-5 h-5 text-success-600" />
) : (
<TrendingDownIcon className="w-5 h-5 text-red-600" />
<TrendingDownIcon className="w-5 h-5 text-error-600" />
)}
<span className={`text-sm font-semibold ${isPositiveTrend ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
<span className={`text-sm font-semibold ${isPositiveTrend ? 'text-success-600 dark:text-success-400' : 'text-error-600 dark:text-error-400'}`}>
{isPositiveTrend ? '+' : ''}{data.trend}% vs last week
</span>
</div>

View File

@@ -21,9 +21,9 @@ interface CreditAvailabilityWidgetProps {
// Average credit costs per operation
const OPERATION_COSTS = {
clustering: { label: 'Clustering Runs', cost: 10, icon: GroupIcon, color: 'text-purple-600 dark:text-purple-400' },
ideas: { label: 'Content Ideas', cost: 2, icon: BoltIcon, color: 'text-orange-600 dark:text-orange-400' },
content: { label: 'Articles', cost: 50, icon: FileTextIcon, color: 'text-green-600 dark:text-green-400' },
images: { label: 'Images', cost: 5, icon: FileIcon, color: 'text-pink-600 dark:text-pink-400' },
ideas: { label: 'Content Ideas', cost: 2, icon: BoltIcon, color: 'text-warning-600 dark:text-warning-400' },
content: { label: 'Articles', cost: 50, icon: FileTextIcon, color: 'text-success-600 dark:text-success-400' },
images: { label: 'Images', cost: 5, icon: FileIcon, color: 'text-purple-600 dark:text-purple-400' },
};
export default function CreditAvailabilityWidget({
@@ -70,7 +70,7 @@ export default function CreditAvailabilityWidget({
<div className="w-full bg-white dark:bg-gray-800 rounded-full h-2 mb-1">
<div
className={`h-2 rounded-full transition-all ${
usagePercent > 90 ? 'bg-red-500' : usagePercent > 75 ? 'bg-amber-500' : 'bg-green-500'
usagePercent > 90 ? 'bg-error-500' : usagePercent > 75 ? 'bg-warning-500' : 'bg-success-500'
}`}
style={{ width: `${Math.max(100 - usagePercent, 0)}%` }}
></div>
@@ -119,8 +119,8 @@ export default function CreditAvailabilityWidget({
</p>
</div>
<span className={`text-lg font-bold ${
op.available > 10 ? 'text-green-600 dark:text-green-400' :
op.available > 0 ? 'text-amber-600 dark:text-amber-400' :
op.available > 10 ? 'text-success-600 dark:text-success-400' :
op.available > 0 ? 'text-warning-600 dark:text-warning-400' :
'text-gray-400 dark:text-gray-600'
}`}>
{op.available === 0 ? '—' : op.available > 999 ? '999+' : op.available}
@@ -134,7 +134,7 @@ export default function CreditAvailabilityWidget({
{/* Warning if low */}
{!loading && availableCredits > 0 && availableCredits < 100 && (
<div className="mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="flex items-start gap-2 text-amber-600 dark:text-amber-400">
<div className="flex items-start gap-2 text-warning-600 dark:text-warning-400">
<DollarLineIcon className="w-4 h-4 mt-0.5" />
<p className="text-xs">
You're running low on credits. Consider purchasing more to avoid interruptions.

View File

@@ -21,7 +21,7 @@ export default function CreditBalanceWidget() {
if (error && !balance) {
return (
<ComponentCard title="Content Usage" desc="Usage unavailable">
<div className="text-sm text-red-600 dark:text-red-400 mb-3">
<div className="text-sm text-error-600 dark:text-error-400 mb-3">
Usage unavailable. Please retry.
</div>
<Button variant="outline" size="sm" onClick={loadBalance}>
@@ -68,7 +68,7 @@ export default function CreditBalanceWidget() {
<span className="text-sm font-medium text-success">{balance.credits_remaining}</span>
</div>
{error && (
<div className="mt-2 text-xs text-amber-600 dark:text-amber-400">
<div className="mt-2 text-xs text-warning-600 dark:text-warning-400">
Usage may be outdated. {error}
</div>
)}

View File

@@ -19,20 +19,20 @@ export interface MetricCardProps {
const accentColors = {
blue: {
bg: "bg-blue-50 dark:bg-blue-500/10",
hover: "hover:bg-blue-100 dark:hover:bg-blue-500/20",
bg: "bg-brand-50 dark:bg-brand-500/10",
hover: "hover:bg-brand-100 dark:hover:bg-brand-500/20",
border: "bg-brand-500",
icon: "text-brand-500",
},
green: {
bg: "bg-green-50 dark:bg-green-500/10",
hover: "hover:bg-green-100 dark:hover:bg-green-500/20",
bg: "bg-success-50 dark:bg-success-500/10",
hover: "hover:bg-success-100 dark:hover:bg-success-500/20",
border: "bg-success-500",
icon: "text-success-500",
},
orange: {
bg: "bg-amber-50 dark:bg-amber-500/10",
hover: "hover:bg-amber-100 dark:hover:bg-amber-500/20",
bg: "bg-warning-50 dark:bg-warning-500/10",
hover: "hover:bg-warning-100 dark:hover:bg-warning-500/20",
border: "bg-warning-500",
icon: "text-warning-500",
},
@@ -43,14 +43,14 @@ const accentColors = {
icon: "text-purple-500",
},
red: {
bg: "bg-red-50 dark:bg-red-500/10",
hover: "hover:bg-red-100 dark:hover:bg-red-500/20",
bg: "bg-error-50 dark:bg-error-500/10",
hover: "hover:bg-error-100 dark:hover:bg-error-500/20",
border: "bg-error-500",
icon: "text-error-500",
},
success: {
bg: "bg-green-50 dark:bg-green-500/10",
hover: "hover:bg-green-100 dark:hover:bg-green-500/20",
bg: "bg-success-50 dark:bg-success-500/10",
hover: "hover:bg-success-100 dark:hover:bg-success-500/20",
border: "bg-success-500",
icon: "text-success-500",
},

View File

@@ -35,38 +35,38 @@ interface NeedsAttentionBarProps {
const typeConfig = {
pending_review: {
icon: CheckCircleIcon,
bgColor: 'bg-amber-50 dark:bg-amber-900/20',
borderColor: 'border-amber-200 dark:border-amber-800',
iconColor: 'text-amber-500',
titleColor: 'text-amber-800 dark:text-amber-200',
bgColor: 'bg-warning-50 dark:bg-warning-900/20',
borderColor: 'border-warning-200 dark:border-warning-800',
iconColor: 'text-warning-500',
titleColor: 'text-warning-800 dark:text-warning-200',
},
sync_failed: {
icon: AlertIcon,
bgColor: 'bg-red-50 dark:bg-red-900/20',
borderColor: 'border-red-200 dark:border-red-800',
iconColor: 'text-red-500',
titleColor: 'text-red-800 dark:text-red-200',
bgColor: 'bg-error-50 dark:bg-error-900/20',
borderColor: 'border-error-200 dark:border-error-800',
iconColor: 'text-error-500',
titleColor: 'text-error-800 dark:text-error-200',
},
setup_incomplete: {
icon: AlertIcon,
bgColor: 'bg-blue-50 dark:bg-blue-900/20',
borderColor: 'border-blue-200 dark:border-blue-800',
iconColor: 'text-blue-500',
titleColor: 'text-blue-800 dark:text-blue-200',
bgColor: 'bg-brand-50 dark:bg-brand-900/20',
borderColor: 'border-brand-200 dark:border-brand-800',
iconColor: 'text-brand-500',
titleColor: 'text-brand-800 dark:text-brand-200',
},
automation_failed: {
icon: AlertIcon,
bgColor: 'bg-red-50 dark:bg-red-900/20',
borderColor: 'border-red-200 dark:border-red-800',
iconColor: 'text-red-500',
titleColor: 'text-red-800 dark:text-red-200',
bgColor: 'bg-error-50 dark:bg-error-900/20',
borderColor: 'border-error-200 dark:border-error-800',
iconColor: 'text-error-500',
titleColor: 'text-error-800 dark:text-error-200',
},
credits_low: {
icon: AlertIcon,
bgColor: 'bg-orange-50 dark:bg-orange-900/20',
borderColor: 'border-orange-200 dark:border-orange-800',
iconColor: 'text-orange-500',
titleColor: 'text-orange-800 dark:text-orange-200',
bgColor: 'bg-warning-50 dark:bg-warning-900/20',
borderColor: 'border-warning-200 dark:border-warning-800',
iconColor: 'text-warning-500',
titleColor: 'text-warning-800 dark:text-warning-200',
},
};
@@ -82,24 +82,24 @@ export default function NeedsAttentionBar({ items, onDismiss }: NeedsAttentionBa
{/* Header */}
<button
onClick={() => setIsCollapsed(!isCollapsed)}
className="w-full flex items-center justify-between px-5 py-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-t-xl hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-colors"
className="w-full flex items-center justify-between px-5 py-3 bg-warning-50 dark:bg-warning-900/20 border border-warning-200 dark:border-warning-800 rounded-t-xl hover:bg-warning-100 dark:hover:bg-warning-900/30 transition-colors"
>
<div className="flex items-center gap-2.5">
<AlertIcon className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<span className="text-base font-semibold text-amber-800 dark:text-amber-200">
<AlertIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />
<span className="text-base font-semibold text-warning-800 dark:text-warning-200">
Needs Attention ({items.length})
</span>
</div>
{isCollapsed ? (
<ChevronDownIcon className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<ChevronDownIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />
) : (
<ChevronUpIcon className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<ChevronUpIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />
)}
</button>
{/* Content */}
{!isCollapsed && (
<div className="border border-t-0 border-amber-200 dark:border-amber-800 rounded-b-xl bg-white dark:bg-gray-900 p-4">
<div className="border border-t-0 border-warning-200 dark:border-warning-800 rounded-b-xl bg-white dark:bg-gray-900 p-4">
<div className="flex flex-wrap gap-3">
{items.map((item) => {
const config = typeConfig[item.type];

View File

@@ -34,19 +34,19 @@ const operationConfig = {
ideas: {
label: 'Ideas',
icon: BoltIcon,
color: 'text-orange-600 dark:text-orange-400',
color: 'text-warning-600 dark:text-warning-400',
href: '/planner/ideas',
},
content: {
label: 'Content',
icon: FileTextIcon,
color: 'text-green-600 dark:text-green-400',
color: 'text-success-600 dark:text-success-400',
href: '/writer/content',
},
images: {
label: 'Images',
icon: FileIcon,
color: 'text-pink-600 dark:text-pink-400',
color: 'text-purple-600 dark:text-purple-400',
href: '/writer/images',
},
};

View File

@@ -28,7 +28,7 @@ const workflowSteps = [
description: 'Import your target keywords manually or from CSV',
href: '/planner/keyword-opportunities',
actionLabel: 'Add',
color: 'text-blue-600 dark:text-blue-400',
color: 'text-brand-600 dark:text-brand-400',
},
{
num: 2,
@@ -46,7 +46,7 @@ const workflowSteps = [
description: 'Create content ideas from your keyword clusters',
href: '/planner/ideas',
actionLabel: 'Ideas',
color: 'text-orange-600 dark:text-orange-400',
color: 'text-warning-600 dark:text-warning-400',
},
{
num: 4,
@@ -55,7 +55,7 @@ const workflowSteps = [
description: 'Convert approved ideas into content tasks',
href: '/writer/tasks',
actionLabel: 'Tasks',
color: 'text-indigo-600 dark:text-indigo-400',
color: 'text-purple-600 dark:text-purple-400',
},
{
num: 5,
@@ -64,7 +64,7 @@ const workflowSteps = [
description: 'AI writes SEO-optimized articles from tasks',
href: '/writer/content',
actionLabel: 'Write',
color: 'text-green-600 dark:text-green-400',
color: 'text-success-600 dark:text-success-400',
},
{
num: 6,
@@ -73,7 +73,7 @@ const workflowSteps = [
description: 'Create featured images and media for articles',
href: '/writer/images',
actionLabel: 'Images',
color: 'text-pink-600 dark:text-pink-400',
color: 'text-purple-600 dark:text-purple-400',
},
{
num: 7,
@@ -82,7 +82,7 @@ const workflowSteps = [
description: 'Quality check and approve generated content',
href: '/writer/review',
actionLabel: 'Review',
color: 'text-amber-600 dark:text-amber-400',
color: 'text-warning-600 dark:text-warning-400',
},
{
num: 8,
@@ -91,7 +91,7 @@ const workflowSteps = [
description: 'Push approved content to your WordPress site',
href: '/writer/published',
actionLabel: 'Publish',
color: 'text-emerald-600 dark:text-emerald-400',
color: 'text-purple-600 dark:text-purple-400',
},
];

View File

@@ -30,17 +30,20 @@ interface RecentActivityWidgetProps {
loading?: boolean;
}
const activityConfig = {
const activityConfig: Record<string, { icon: typeof GroupIcon; color: string; bgColor: string }> = {
clustering: { icon: GroupIcon, color: 'text-purple-600 dark:text-purple-400', bgColor: 'bg-purple-100 dark:bg-purple-900/40' },
ideas: { icon: BoltIcon, color: 'text-orange-600 dark:text-orange-400', bgColor: 'bg-orange-100 dark:bg-orange-900/40' },
content: { icon: FileTextIcon, color: 'text-green-600 dark:text-green-400', bgColor: 'bg-green-100 dark:bg-green-900/40' },
images: { icon: FileIcon, color: 'text-pink-600 dark:text-pink-400', bgColor: 'bg-pink-100 dark:bg-pink-900/40' },
published: { icon: PaperPlaneIcon, color: 'text-emerald-600 dark:text-emerald-400', bgColor: 'bg-emerald-100 dark:bg-emerald-900/40' },
keywords: { icon: ListIcon, color: 'text-blue-600 dark:text-blue-400', bgColor: 'bg-blue-100 dark:bg-blue-900/40' },
error: { icon: AlertIcon, color: 'text-red-600 dark:text-red-400', bgColor: 'bg-red-100 dark:bg-red-900/40' },
sync: { icon: CheckCircleIcon, color: 'text-teal-600 dark:text-teal-400', bgColor: 'bg-teal-100 dark:bg-teal-900/40' },
ideas: { icon: BoltIcon, color: 'text-warning-600 dark:text-warning-400', bgColor: 'bg-warning-100 dark:bg-warning-900/40' },
content: { icon: FileTextIcon, color: 'text-success-600 dark:text-success-400', bgColor: 'bg-success-100 dark:bg-success-900/40' },
images: { icon: FileIcon, color: 'text-purple-600 dark:text-purple-400', bgColor: 'bg-purple-100 dark:bg-purple-900/40' },
published: { icon: PaperPlaneIcon, color: 'text-purple-600 dark:text-purple-400', bgColor: 'bg-purple-100 dark:bg-purple-900/40' },
keywords: { icon: ListIcon, color: 'text-brand-600 dark:text-brand-400', bgColor: 'bg-brand-100 dark:bg-brand-900/40' },
error: { icon: AlertIcon, color: 'text-error-600 dark:text-error-400', bgColor: 'bg-error-100 dark:bg-error-900/40' },
sync: { icon: CheckCircleIcon, color: 'text-purple-600 dark:text-purple-400', bgColor: 'bg-purple-100 dark:bg-purple-900/40' },
};
// Default config for unknown activity types
const defaultActivityConfig = { icon: BoltIcon, color: 'text-gray-600 dark:text-gray-400', bgColor: 'bg-gray-100 dark:bg-gray-900/40' };
function formatRelativeTime(date: Date): string {
const now = new Date();
const diffMs = now.getTime() - date.getTime();
@@ -87,7 +90,7 @@ export default function RecentActivityWidget({ activities, loading }: RecentActi
</div>
) : (
activities.slice(0, 5).map((activity) => {
const config = activityConfig[activity.type];
const config = activityConfig[activity.type] || defaultActivityConfig;
const Icon = config.icon;
const content = (

View File

@@ -80,7 +80,7 @@ export default function SiteConfigWidget({
<h3 className="text-base font-semibold text-gray-800 dark:text-gray-200 uppercase tracking-wide">
Site Configuration
</h3>
<span className={`text-lg font-bold ${completionPercent === 100 ? 'text-green-600' : 'text-amber-600'}`}>
<span className={`text-lg font-bold ${completionPercent === 100 ? 'text-success-600' : 'text-warning-600'}`}>
{configuredCount}/{totalCount}
</span>
</div>
@@ -97,13 +97,13 @@ export default function SiteConfigWidget({
>
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${
item.configured
? 'bg-green-100 dark:bg-green-900/30'
: 'bg-amber-100 dark:bg-amber-900/30'
? 'bg-success-100 dark:bg-success-900/30'
: 'bg-warning-100 dark:bg-warning-900/30'
}`}>
<Icon className={`w-5 h-5 ${
item.configured
? 'text-green-600 dark:text-green-400'
: 'text-amber-600 dark:text-amber-400'
? 'text-success-600 dark:text-success-400'
: 'text-warning-600 dark:text-warning-400'
}`} />
</div>
<div className="flex-1 min-w-0">
@@ -113,15 +113,15 @@ export default function SiteConfigWidget({
<p className={`text-xs ${
item.configured
? 'text-gray-600 dark:text-gray-400'
: 'text-amber-600 dark:text-amber-400'
: 'text-warning-600 dark:text-warning-400'
}`}>
{item.detail}
</p>
</div>
{item.configured ? (
<CheckCircleIcon className="w-5 h-5 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-5 h-5 text-success-600 dark:text-success-400" />
) : (
<AlertIcon className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<AlertIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />
)}
</Link>
);
@@ -137,7 +137,7 @@ export default function SiteConfigWidget({
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div
className={`h-2 rounded-full transition-all ${
completionPercent === 100 ? 'bg-green-500' : 'bg-amber-500'
completionPercent === 100 ? 'bg-success-500' : 'bg-warning-500'
}`}
style={{ width: `${completionPercent}%` }}
></div>

View File

@@ -34,13 +34,13 @@ interface WorkflowPipelineWidgetProps {
}
const stages = [
{ key: 'sites', label: 'Sites', icon: GridIcon, href: '/sites', color: 'text-blue-600 dark:text-blue-400' },
{ key: 'keywords', label: 'Keywords', icon: ListIcon, href: '/planner/keywords', color: 'text-blue-600 dark:text-blue-400' },
{ key: 'sites', label: 'Sites', icon: GridIcon, href: '/sites', color: 'text-brand-600 dark:text-brand-400' },
{ key: 'keywords', label: 'Keywords', icon: ListIcon, href: '/planner/keywords', color: 'text-brand-600 dark:text-brand-400' },
{ key: 'clusters', label: 'Clusters', icon: GroupIcon, href: '/planner/clusters', color: 'text-purple-600 dark:text-purple-400' },
{ key: 'ideas', label: 'Ideas', icon: BoltIcon, href: '/planner/ideas', color: 'text-orange-600 dark:text-orange-400' },
{ key: 'tasks', label: 'Tasks', icon: CheckCircleIcon, href: '/writer/tasks', color: 'text-indigo-600 dark:text-indigo-400' },
{ key: 'drafts', label: 'Drafts', icon: FileTextIcon, href: '/writer/content', color: 'text-green-600 dark:text-green-400' },
{ key: 'published', label: 'Published', icon: PaperPlaneIcon, href: '/writer/published', color: 'text-emerald-600 dark:text-emerald-400' },
{ key: 'ideas', label: 'Ideas', icon: BoltIcon, href: '/planner/ideas', color: 'text-warning-600 dark:text-warning-400' },
{ key: 'tasks', label: 'Tasks', icon: CheckCircleIcon, href: '/writer/tasks', color: 'text-purple-600 dark:text-purple-400' },
{ key: 'drafts', label: 'Drafts', icon: FileTextIcon, href: '/writer/content', color: 'text-success-600 dark:text-success-400' },
{ key: 'published', label: 'Published', icon: PaperPlaneIcon, href: '/writer/published', color: 'text-purple-600 dark:text-purple-400' },
] as const;
// Small filled arrow triangle component

View File

@@ -14,7 +14,7 @@ const CountryMap: React.FC<CountryMapProps> = ({ mapColor }) => {
backgroundColor="transparent"
markerStyle={{
initial: {
fill: "#465FFF",
fill: "var(--color-primary)",
r: 4, // Custom radius for markers
} as any, // Type assertion to bypass strict CSS property checks
}}
@@ -24,27 +24,27 @@ const CountryMap: React.FC<CountryMapProps> = ({ mapColor }) => {
latLng: [37.2580397, -104.657039],
name: "United States",
style: {
fill: "#465FFF",
fill: "var(--color-primary)",
borderWidth: 1,
borderColor: "white",
stroke: "#383f47",
stroke: "var(--color-gray-700)",
},
},
{
latLng: [20.7504374, 73.7276105],
name: "India",
style: { fill: "#465FFF", borderWidth: 1, borderColor: "white" },
style: { fill: "var(--color-primary)", borderWidth: 1, borderColor: "white" },
},
{
latLng: [53.613, -11.6368],
name: "United Kingdom",
style: { fill: "#465FFF", borderWidth: 1, borderColor: "white" },
style: { fill: "var(--color-primary)", borderWidth: 1, borderColor: "white" },
},
{
latLng: [-25.0304388, 115.2092761],
name: "Sweden",
style: {
fill: "#465FFF",
fill: "var(--color-primary)",
borderWidth: 1,
borderColor: "white",
strokeOpacity: 0,
@@ -58,7 +58,7 @@ const CountryMap: React.FC<CountryMapProps> = ({ mapColor }) => {
zoomStep={1.5}
regionStyle={{
initial: {
fill: mapColor || "#D0D5DD",
fill: mapColor || "var(--color-gray-300)",
fillOpacity: 1,
fontFamily: "Outfit",
stroke: "none",
@@ -68,17 +68,17 @@ const CountryMap: React.FC<CountryMapProps> = ({ mapColor }) => {
hover: {
fillOpacity: 0.7,
cursor: "pointer",
fill: "#465fff",
fill: "var(--color-primary)",
stroke: "none",
},
selected: {
fill: "#465FFF",
fill: "var(--color-primary)",
},
selectedHover: {},
}}
regionLabelStyle={{
initial: {
fill: "#35373e",
fill: "var(--color-gray-700)",
fontWeight: 500,
fontSize: "13px",
stroke: "none",

View File

@@ -7,7 +7,7 @@ import { useState } from "react";
export default function MonthlySalesChart() {
const options: ApexOptions = {
colors: ["#465fff"],
colors: ["var(--color-primary)"],
chart: {
fontFamily: "Outfit, sans-serif",
type: "bar",

View File

@@ -8,7 +8,7 @@ import { MoreDotIcon } from "../../icons";
export default function MonthlyTarget() {
const series = [75.55];
const options: ApexOptions = {
colors: ["#465FFF"],
colors: ["var(--color-primary)"],
chart: {
fontFamily: "Outfit, sans-serif",
type: "radialBar",
@@ -25,7 +25,7 @@ export default function MonthlyTarget() {
size: "80%",
},
track: {
background: "#E4E7EC",
background: "var(--color-gray-200)",
strokeWidth: "100%",
margin: 5, // margin is in pixels
},
@@ -37,7 +37,7 @@ export default function MonthlyTarget() {
fontSize: "36px",
fontWeight: "600",
offsetY: -40,
color: "#1D2939",
color: "var(--color-gray-800)",
formatter: function (val) {
return val + "%";
},
@@ -47,7 +47,7 @@ export default function MonthlyTarget() {
},
fill: {
type: "solid",
colors: ["#465FFF"],
colors: ["var(--color-primary)"],
},
stroke: {
lineCap: "round",

View File

@@ -9,7 +9,7 @@ export default function StatisticsChart() {
position: "top",
horizontalAlign: "left",
},
colors: ["#465FFF", "#9CB9FF"], // Define line colors
colors: ["var(--color-primary)", "var(--color-brand-300)"], // Define line colors
chart: {
fontFamily: "Outfit, sans-serif",
height: 310,
@@ -89,7 +89,7 @@ export default function StatisticsChart() {
labels: {
style: {
fontSize: "12px", // Adjust font size for y-axis labels
colors: ["#6B7280"], // Color of the labels
colors: ["var(--color-gray-500)"], // Color of the labels
},
},
title: {

View File

@@ -134,9 +134,9 @@ export default function NotificationDropdown() {
>
{/* Notification badge */}
{unreadCount > 0 && (
<span className="absolute -right-0.5 -top-0.5 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-orange-500 text-[10px] font-semibold text-white">
<span className="absolute -right-0.5 -top-0.5 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-warning-500 text-[10px] font-semibold text-white">
{unreadCount > 9 ? '9+' : unreadCount}
<span className="absolute inline-flex w-full h-full bg-orange-400 rounded-full opacity-75 animate-ping"></span>
<span className="absolute inline-flex w-full h-full bg-warning-400 rounded-full opacity-75 animate-ping"></span>
</span>
)}
<svg
@@ -243,7 +243,7 @@ export default function NotificationDropdown() {
notification.actionHref
)}
className={`flex gap-3 rounded-lg border-b border-gray-100 p-3 hover:bg-gray-50 dark:border-gray-800 dark:hover:bg-white/5 ${
!notification.read ? 'bg-blue-50/50 dark:bg-blue-900/10' : ''
!notification.read ? 'bg-brand-50/50 dark:bg-brand-900/10' : ''
}`}
>
{/* Icon */}

View File

@@ -105,9 +105,9 @@ export default function NotificationDropdown() {
>
{/* Notification badge */}
{unreadCount > 0 && (
<span className="absolute -right-0.5 -top-0.5 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-orange-500 text-[10px] font-semibold text-white">
<span className="absolute -right-0.5 -top-0.5 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-warning-500 text-[10px] font-semibold text-white">
{unreadCount > 9 ? '9+' : unreadCount}
<span className="absolute inline-flex w-full h-full bg-orange-400 rounded-full opacity-75 animate-ping"></span>
<span className="absolute inline-flex w-full h-full bg-warning-400 rounded-full opacity-75 animate-ping"></span>
</span>
)}
<svg
@@ -205,7 +205,7 @@ export default function NotificationDropdown() {
notification.actionHref
)}
className={`flex gap-3 rounded-lg border-b border-gray-100 p-3 hover:bg-gray-50 dark:border-gray-800 dark:hover:bg-white/5 ${
!notification.read ? 'bg-blue-50/50 dark:bg-blue-900/10' : ''
!notification.read ? 'bg-brand-50/50 dark:bg-brand-900/10' : ''
}`}
>
{/* Icon */}

View File

@@ -194,14 +194,14 @@ export default function SiteSwitcher({ hiddenPaths }: SiteSwitcherProps) {
onItemClick={() => handleSiteSelect(site.id)}
className={`flex items-center gap-3 px-3 py-2 font-medium rounded-lg text-sm text-left ${
activeSite?.id === site.id
? "bg-blue-50 text-blue-700 dark:bg-blue-500/20 dark:text-blue-300"
? "bg-brand-50 text-brand-700 dark:bg-brand-500/20 dark:text-brand-300"
: "text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-300"
}`}
>
<span className="flex-1">{site.name}</span>
{activeSite?.id === site.id && (
<svg
className="w-4 h-4 text-blue-600 dark:text-blue-400"
className="w-4 h-4 text-brand-600 dark:text-brand-400"
fill="currentColor"
viewBox="0 0 20 20"
>

View File

@@ -21,11 +21,11 @@ export default function IntegrationStatus({
const getStatusIcon = () => {
switch (syncStatus) {
case 'success':
return <CheckCircleIcon className="w-5 h-5 text-green-500" />;
return <CheckCircleIcon className="w-5 h-5 text-success-500" />;
case 'failed':
return <XCircleIcon className="w-5 h-5 text-red-500" />;
return <XCircleIcon className="w-5 h-5 text-error-500" />;
case 'syncing':
return <RefreshCw className="w-5 h-5 text-blue-500 animate-spin" />;
return <RefreshCw className="w-5 h-5 text-brand-500 animate-spin" />;
default:
return <ClockIcon className="w-5 h-5 text-gray-400" />;
}
@@ -65,7 +65,7 @@ export default function IntegrationStatus({
<div className="text-xs text-gray-600 dark:text-gray-400">
<div>Last sync: {formatDate(lastSyncAt)}</div>
{syncError && (
<div className="text-red-600 dark:text-red-400 mt-1">
<div className="text-error-600 dark:text-error-400 mt-1">
Error: {syncError}
</div>
)}

View File

@@ -29,7 +29,7 @@ export const LinkResults: React.FC<LinkResultsProps> = ({
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Linking Results</h3>
<div className="flex items-center gap-2">
<PlugInIcon className="w-5 h-5 text-blue-500" />
<PlugInIcon className="w-5 h-5 text-brand-500" />
<span className="text-sm text-gray-600 dark:text-gray-400">Version {linkerVersion}</span>
</div>
</div>
@@ -46,14 +46,14 @@ export const LinkResults: React.FC<LinkResultsProps> = ({
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Linking Results</h3>
<div className="flex items-center gap-2">
<PlugInIcon className="w-5 h-5 text-blue-500" />
<PlugInIcon className="w-5 h-5 text-brand-500" />
<span className="text-sm text-gray-600 dark:text-gray-400">Version {linkerVersion}</span>
</div>
</div>
{linksAdded > 0 ? (
<div className="space-y-4">
<div className="flex items-center gap-2 text-green-600 dark:text-green-400">
<div className="flex items-center gap-2 text-success-600 dark:text-success-400">
<CheckCircleIcon className="w-5 h-5" />
<span className="font-medium">{linksAdded} link{linksAdded !== 1 ? 's' : ''} added</span>
</div>
@@ -63,15 +63,15 @@ export const LinkResults: React.FC<LinkResultsProps> = ({
{/* Stage 3: Group links by cluster match */}
{links.some(l => l.cluster_match) && (
<div className="mb-4">
<div className="text-xs font-semibold text-blue-600 dark:text-blue-400 mb-2">
<div className="text-xs font-semibold text-brand-600 dark:text-brand-400 mb-2">
Cluster Matches (High Priority)
</div>
<ul className="space-y-2">
{links.filter(l => l.cluster_match).map((link, index) => (
<li key={`cluster-${index}`} className="flex items-center gap-2 text-sm pl-2 border-l-2 border-blue-500">
<li key={`cluster-${index}`} className="flex items-center gap-2 text-sm pl-2 border-l-2 border-brand-500">
<span className="text-gray-600 dark:text-gray-400">"{link.anchor_text || 'Untitled'}"</span>
<span className="text-gray-400"></span>
<span className="text-blue-600 dark:text-blue-400">
<span className="text-brand-600 dark:text-brand-400">
Content #{link.target_content_id || 'N/A'}
</span>
{link.relevance_score !== undefined && (
@@ -96,7 +96,7 @@ export const LinkResults: React.FC<LinkResultsProps> = ({
<li key={`other-${index}`} className="flex items-center gap-2 text-sm">
<span className="text-gray-600 dark:text-gray-400">"{link.anchor_text || 'Untitled'}"</span>
<span className="text-gray-400"></span>
<span className="text-blue-600 dark:text-blue-400">
<span className="text-brand-600 dark:text-brand-400">
Content #{link.target_content_id || 'N/A'}
</span>
{link.relevance_score !== undefined && (
@@ -117,7 +117,7 @@ export const LinkResults: React.FC<LinkResultsProps> = ({
<li key={index} className="flex items-center gap-2 text-sm">
<span className="text-gray-600 dark:text-gray-400">"{link.anchor_text}"</span>
<span className="text-gray-400"></span>
<span className="text-blue-600 dark:text-blue-400">
<span className="text-brand-600 dark:text-brand-400">
Content #{link.target_content_id}
</span>
</li>

View File

@@ -200,12 +200,12 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
return (
<div className="mb-8">
<Card className="rounded-2xl border-2 border-orange-200 bg-gradient-to-br from-orange-50 to-white dark:from-orange-950/20 dark:to-gray-900 dark:border-orange-800 p-6 md:p-8">
<Card className="rounded-2xl border-2 border-warning-200 bg-gradient-to-br from-warning-50 to-white dark:from-warning-950/20 dark:to-gray-900 dark:border-warning-800 p-6 md:p-8">
{/* Header */}
<div className="flex items-start justify-between mb-6">
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<div className="size-12 rounded-xl bg-gradient-to-br from-orange-500 to-orange-600 flex items-center justify-center text-white shadow-lg">
<div className="size-12 rounded-xl bg-gradient-to-br from-warning-500 to-warning-600 flex items-center justify-center text-white shadow-lg">
<BoltIcon className="h-6 w-6" />
</div>
<div>
@@ -230,9 +230,9 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
{/* Site Integration Option */}
<div className="mb-6">
<Card className="p-6 border-2 border-blue-200 dark:border-blue-800">
<Card className="p-6 border-2 border-brand-200 dark:border-brand-800">
<div className="flex items-start gap-4 mb-6">
<div className="size-12 rounded-xl bg-gradient-to-br from-blue-500 to-blue-600 flex items-center justify-center text-white flex-shrink-0">
<div className="size-12 rounded-xl bg-gradient-to-br from-brand-500 to-brand-600 flex items-center justify-center text-white flex-shrink-0">
<PlugInIcon className="h-6 w-6" />
</div>
<div className="flex-1">
@@ -252,12 +252,12 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
onClick={handleWordPressCardClick}
className={`flex items-center justify-between p-4 rounded-lg border-2 transition-all duration-200 group ${
isWordPressExpanded
? 'border-blue-500 bg-blue-50 dark:bg-blue-900/20'
: 'border-gray-200 dark:border-gray-700 hover:border-blue-400 dark:hover:border-blue-600 bg-white dark:bg-gray-800'
? 'border-brand-500 bg-brand-50 dark:bg-brand-900/20'
: 'border-gray-200 dark:border-gray-700 hover:border-brand-400 dark:hover:border-brand-600 bg-white dark:bg-gray-800'
}`}
>
<div className="flex items-center gap-3">
<PlugInIcon className={`w-5 h-5 ${isWordPressExpanded ? 'text-blue-600 dark:text-blue-400' : 'text-blue-600 dark:text-blue-400'}`} />
<PlugInIcon className={`w-5 h-5 ${isWordPressExpanded ? 'text-brand-600 dark:text-brand-400' : 'text-brand-600 dark:text-brand-400'}`} />
<div className="text-left">
<div className="font-semibold text-gray-900 dark:text-white">
WordPress Site
@@ -269,8 +269,8 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
</div>
<ArrowRightIcon className={`w-5 h-5 transition-transform ${isWordPressExpanded ? 'transform rotate-90' : ''} ${
isWordPressExpanded
? 'text-blue-600 dark:text-blue-400'
: 'text-gray-400 group-hover:text-blue-600 dark:group-hover:text-blue-400'
? 'text-brand-600 dark:text-brand-400'
: 'text-gray-400 group-hover:text-brand-600 dark:group-hover:text-brand-400'
}`} />
</button>
@@ -302,7 +302,7 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
value={siteName}
onChange={(e) => setSiteName(e.target.value)}
placeholder="Enter site name"
className="w-full px-4 py-2.5 border-2 border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white text-base focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
className="w-full px-4 py-2.5 border-2 border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white text-base focus:border-brand-500 focus:ring-2 focus:ring-brand-200 dark:focus:ring-brand-800"
/>
</div>
@@ -316,7 +316,7 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
value={websiteAddress}
onChange={(e) => setWebsiteAddress(e.target.value)}
placeholder="https://example.com"
className="w-full px-4 py-2.5 border-2 border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white text-base focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
className="w-full px-4 py-2.5 border-2 border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white text-base focus:border-brand-500 focus:ring-2 focus:ring-brand-200 dark:focus:ring-brand-800"
/>
</div>
@@ -359,7 +359,7 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
key={sector.slug}
className={`p-4 hover:shadow-lg transition-all duration-200 border-2 cursor-pointer ${
selectedSectors.includes(sector.slug)
? 'border-[var(--color-primary)] bg-blue-50 dark:bg-blue-900/20'
? 'border-[var(--color-primary)] bg-brand-50 dark:bg-brand-900/20'
: 'border-gray-200 dark:border-gray-700'
}`}
onClick={() => handleSectorToggle(sector.slug)}

View File

@@ -29,22 +29,22 @@ export const OptimizationScores: React.FC<OptimizationScoresProps> = ({
className = '',
}) => {
const getScoreColor = (score: number) => {
if (score >= 80) return 'text-green-600 dark:text-green-400';
if (score >= 60) return 'text-yellow-600 dark:text-yellow-400';
return 'text-red-600 dark:text-red-400';
if (score >= 80) return 'text-success-600 dark:text-success-400';
if (score >= 60) return 'text-warning-600 dark:text-warning-400';
return 'text-error-600 dark:text-error-400';
};
const getScoreBgColor = (score: number) => {
if (score >= 80) return 'bg-green-100 dark:bg-green-900';
if (score >= 60) return 'bg-yellow-100 dark:bg-yellow-900';
return 'bg-red-100 dark:bg-red-900';
if (score >= 80) return 'bg-success-100 dark:bg-success-900';
if (score >= 60) return 'bg-warning-100 dark:bg-warning-900';
return 'bg-error-100 dark:bg-error-900';
};
const getChangeIcon = (current: number, previous?: number) => {
if (!previous) return null;
const diff = current - previous;
if (diff > 0) return <ArrowUpIcon className="w-4 h-4 text-green-600" />;
if (diff < 0) return <ArrowDownIcon className="w-4 h-4 text-red-600" />;
if (diff > 0) return <ArrowUpIcon className="w-4 h-4 text-success-600" />;
if (diff < 0) return <ArrowDownIcon className="w-4 h-4 text-error-600" />;
return <span className="w-4 h-4 text-gray-400"></span>;
};
@@ -182,7 +182,7 @@ export const OptimizationScores: React.FC<OptimizationScoresProps> = ({
{/* Metadata indicators */}
<div className="mt-3 flex flex-wrap gap-2 text-xs">
{scores.has_cluster_mapping && (
<span className="px-2 py-0.5 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded">
<span className="px-2 py-0.5 bg-brand-100 dark:bg-brand-900 text-brand-800 dark:text-brand-200 rounded">
Cluster
</span>
)}
@@ -192,7 +192,7 @@ export const OptimizationScores: React.FC<OptimizationScoresProps> = ({
</span>
)}
{scores.has_attributes && (
<span className="px-2 py-0.5 bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 rounded">
<span className="px-2 py-0.5 bg-success-100 dark:bg-success-900 text-success-800 dark:text-success-200 rounded">
Attributes
</span>
)}

View File

@@ -37,9 +37,9 @@ export const ScoreComparison: React.FC<ScoreComparisonProps> = ({
<span
className={`text-lg font-bold ${
overallImprovement.diff > 0
? 'text-green-600 dark:text-green-400'
? 'text-success-600 dark:text-success-400'
: overallImprovement.diff < 0
? 'text-red-600 dark:text-red-400'
? 'text-error-600 dark:text-error-400'
: 'text-gray-600 dark:text-gray-400'
}`}
>
@@ -84,9 +84,9 @@ export const ScoreComparison: React.FC<ScoreComparisonProps> = ({
<span
className={`text-sm font-medium ${
improvement.diff > 0
? 'text-green-600 dark:text-green-400'
? 'text-success-600 dark:text-success-400'
: improvement.diff < 0
? 'text-red-600 dark:text-red-400'
? 'text-error-600 dark:text-error-400'
: 'text-gray-600 dark:text-gray-400'
}`}
>
@@ -95,9 +95,9 @@ export const ScoreComparison: React.FC<ScoreComparisonProps> = ({
<span
className={`text-xs ${
improvement.diff > 0
? 'text-green-600 dark:text-green-400'
? 'text-success-600 dark:text-success-400'
: improvement.diff < 0
? 'text-red-600 dark:text-red-400'
? 'text-error-600 dark:text-error-400'
: 'text-gray-500'
}`}
>

View File

@@ -50,7 +50,7 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
return (
<Card className="p-4">
<div className="text-center py-4">
<div className="inline-block animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mb-2"></div>
<div className="inline-block animate-spin rounded-full h-6 w-6 border-b-2 border-brand-500 mb-2"></div>
<div className="text-gray-500 dark:text-gray-400">Loading progress...</div>
</div>
</Card>
@@ -61,12 +61,12 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
return (
<Card className="p-4">
<div className="text-center py-4">
<AlertCircleIcon className="w-8 h-8 text-red-500 mx-auto mb-2" />
<div className="text-sm text-red-600 dark:text-red-400 mb-3">{error}</div>
<AlertCircleIcon className="w-8 h-8 text-error-500 mx-auto mb-2" />
<div className="text-sm text-error-600 dark:text-error-400 mb-3">{error}</div>
<button
onClick={handleRetry}
disabled={retryCount >= 3}
className="px-4 py-2 bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 text-white rounded-lg text-sm font-medium transition-colors"
className="px-4 py-2 bg-brand-500 hover:bg-brand-600 disabled:bg-gray-400 text-white rounded-lg text-sm font-medium transition-colors"
aria-label="Retry loading site progress"
>
{retryCount >= 3 ? 'Max retries reached' : 'Retry'}
@@ -185,7 +185,7 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
key={cluster.cluster_id}
className={`p-4 rounded-lg border-2 ${
cluster.is_complete
? 'border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-900/20'
? 'border-success-200 dark:border-success-800 bg-success-50 dark:bg-success-900/20'
: 'border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800'
}`}
>
@@ -199,9 +199,9 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
{cluster.role}
</Badge>
{cluster.is_complete ? (
<CheckCircleIcon className="w-4 h-4 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
) : (
<AlertCircleIcon className="w-4 h-4 text-amber-600 dark:text-amber-400" />
<AlertCircleIcon className="w-4 h-4 text-warning-600 dark:text-warning-400" />
)}
</div>
<div className="text-xs text-gray-600 dark:text-gray-400">
@@ -210,7 +210,7 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
</div>
<button
onClick={() => navigate(`/planner/clusters/${cluster.cluster_id}`)}
className="text-xs text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1 transition-colors"
className="text-xs text-brand-600 dark:text-brand-400 hover:underline flex items-center gap-1 transition-colors"
aria-label={`View cluster ${cluster.cluster_name}`}
>
View <ArrowRightIcon className="w-3 h-3" />
@@ -227,8 +227,8 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
<div
className={`h-2 rounded-full ${
cluster.is_complete
? 'bg-green-500 dark:bg-green-400'
: 'bg-blue-500 dark:bg-blue-400'
? 'bg-success-500 dark:bg-success-400'
: 'bg-brand-500 dark:bg-brand-400'
}`}
style={{ width: `${completionPercent}%` }}
/>
@@ -254,13 +254,13 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
{/* Validation Messages */}
{cluster.validation_messages && cluster.validation_messages.length > 0 && (
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
<div className="text-xs font-medium text-red-600 dark:text-red-400 mb-1">
<div className="text-xs font-medium text-error-600 dark:text-error-400 mb-1">
Issues:
</div>
<ul className="text-xs text-gray-600 dark:text-gray-400 space-y-1">
{cluster.validation_messages.map((msg, idx) => (
<li key={idx} className="flex items-start gap-1">
<XCircleIcon className="w-3 h-3 text-red-500 mt-0.5 flex-shrink-0" />
<XCircleIcon className="w-3 h-3 text-error-500 mt-0.5 flex-shrink-0" />
<span>{msg}</span>
</li>
))}
@@ -286,33 +286,33 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div className="flex items-center gap-2">
{validationFlags.clusters_attached ? (
<CheckCircleIcon className="w-4 h-4 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
) : (
<XCircleIcon className="w-4 h-4 text-red-600 dark:text-red-400" />
<XCircleIcon className="w-4 h-4 text-error-600 dark:text-error-400" />
)}
<span className="text-sm text-gray-700 dark:text-gray-300">Clusters Attached</span>
</div>
<div className="flex items-center gap-2">
{validationFlags.taxonomies_defined ? (
<CheckCircleIcon className="w-4 h-4 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
) : (
<XCircleIcon className="w-4 h-4 text-red-600 dark:text-red-400" />
<XCircleIcon className="w-4 h-4 text-error-600 dark:text-error-400" />
)}
<span className="text-sm text-gray-700 dark:text-gray-300">Taxonomies Defined</span>
</div>
<div className="flex items-center gap-2">
{validationFlags.sitemap_generated ? (
<CheckCircleIcon className="w-4 h-4 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
) : (
<XCircleIcon className="w-4 h-4 text-red-600 dark:text-red-400" />
<XCircleIcon className="w-4 h-4 text-error-600 dark:text-error-400" />
)}
<span className="text-sm text-gray-700 dark:text-gray-300">Sitemap Generated</span>
</div>
<div className="flex items-center gap-2">
{validationFlags.all_pages_generated ? (
<CheckCircleIcon className="w-4 h-4 text-green-600 dark:text-green-400" />
<CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
) : (
<XCircleIcon className="w-4 h-4 text-red-600 dark:text-red-400" />
<XCircleIcon className="w-4 h-4 text-error-600 dark:text-error-400" />
)}
<span className="text-sm text-gray-700 dark:text-gray-300">All Pages Generated</span>
</div>
@@ -322,10 +322,10 @@ export default function SiteProgressWidget({ blueprintId, siteId }: SiteProgress
{/* Error banner if data loaded but has errors */}
{error && progress && (
<div className="mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
<div className="mt-4 p-3 bg-warning-50 dark:bg-warning-900/20 border border-warning-200 dark:border-warning-800 rounded-lg">
<div className="flex items-start gap-2">
<AlertCircleIcon className="w-4 h-4 text-yellow-600 dark:text-yellow-400 mt-0.5 flex-shrink-0" />
<div className="text-xs text-yellow-800 dark:text-yellow-300">
<AlertCircleIcon className="w-4 h-4 text-warning-600 dark:text-warning-400 mt-0.5 flex-shrink-0" />
<div className="text-xs text-warning-800 dark:text-warning-300">
Some data may be outdated. <button onClick={handleRetry} className="underline font-medium">Refresh</button>
</div>
</div>

View File

@@ -81,7 +81,7 @@ export default function SiteSetupChecklist({
key={item.id}
className={`w-2 h-2 rounded-full ${
item.completed
? 'bg-green-500'
? 'bg-success-500'
: 'bg-gray-300 dark:bg-gray-600'
}`}
title={item.label}
@@ -92,7 +92,7 @@ export default function SiteSetupChecklist({
{completedCount}/{totalCount}
</span>
{isComplete && (
<span className="text-xs text-green-600 dark:text-green-400 font-medium">
<span className="text-xs text-success-600 dark:text-success-400 font-medium">
Ready
</span>
)}
@@ -116,7 +116,7 @@ export default function SiteSetupChecklist({
<div className="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full mb-4">
<div
className={`h-full rounded-full transition-all duration-500 ${
isComplete ? 'bg-green-500' : 'bg-blue-500'
isComplete ? 'bg-success-500' : 'bg-brand-500'
}`}
style={{ width: `${progressPercent}%` }}
/>
@@ -133,7 +133,7 @@ export default function SiteSetupChecklist({
<div
className={`flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center ${
item.completed
? 'bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400'
? 'bg-success-100 dark:bg-success-900/30 text-success-600 dark:text-success-400'
: 'bg-gray-100 dark:bg-gray-800 text-gray-400 dark:text-gray-500'
}`}
>
@@ -158,9 +158,9 @@ export default function SiteSetupChecklist({
{/* Action button */}
{isComplete ? (
<div className="flex items-center gap-2 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
<CheckLineIcon className="w-5 h-5 text-green-600 dark:text-green-400" />
<span className="text-sm font-medium text-green-700 dark:text-green-300">
<div className="flex items-center gap-2 p-3 bg-success-50 dark:bg-success-900/20 border border-success-200 dark:border-success-800 rounded-lg">
<CheckLineIcon className="w-5 h-5 text-success-600 dark:text-success-400" />
<span className="text-sm font-medium text-success-700 dark:text-success-300">
Ready to create content!
</span>
<Button

View File

@@ -179,7 +179,7 @@ export default function TemplateLibrary({
</div>
)}
{template.featured && (
<span className="absolute top-2 left-2 bg-yellow-500 text-white text-xs px-2 py-1 rounded">
<span className="absolute top-2 left-2 bg-warning-500 text-white text-xs px-2 py-1 rounded">
Featured
</span>
)}

View File

@@ -48,8 +48,8 @@ export default function WordPressIntegrationCard({
<Card className="p-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="p-3 bg-indigo-100 dark:bg-indigo-900/30 rounded-lg">
<Globe className="w-6 h-6 text-indigo-600 dark:text-indigo-400" />
<div className="p-3 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
<Globe className="w-6 h-6 text-purple-600 dark:text-purple-400" />
</div>
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
@@ -73,8 +73,8 @@ export default function WordPressIntegrationCard({
<div className="space-y-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="p-3 bg-indigo-100 dark:bg-indigo-900/30 rounded-lg">
<Globe className="w-6 h-6 text-indigo-600 dark:text-indigo-400" />
<div className="p-3 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
<Globe className="w-6 h-6 text-purple-600 dark:text-purple-400" />
</div>
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
@@ -101,13 +101,13 @@ export default function WordPressIntegrationCard({
<p className="text-xs text-gray-500 dark:text-gray-400 mb-1">Sync Status</p>
<div className="flex items-center gap-2">
{integration.sync_status === 'success' || integration.sync_status === 'healthy' ? (
<CheckCircle className="w-4 h-4 text-green-500" />
<CheckCircle className="w-4 h-4 text-success-500" />
) : integration.sync_status === 'failed' || integration.sync_status === 'error' ? (
<XCircle className="w-4 h-4 text-red-500" />
<XCircle className="w-4 h-4 text-error-500" />
) : integration.sync_status === 'warning' ? (
<AlertCircle className="w-4 h-4 text-yellow-500" />
<AlertCircle className="w-4 h-4 text-warning-500" />
) : (
<RefreshCw className="w-4 h-4 text-yellow-500 animate-spin" />
<RefreshCw className="w-4 h-4 text-warning-500 animate-spin" />
)}
<span className="text-sm font-medium text-gray-900 dark:text-white capitalize">
{integration.sync_status === 'healthy' ? 'Healthy' :
@@ -132,7 +132,7 @@ export default function WordPressIntegrationCard({
<div className="pt-2 border-t border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<AlertCircle className="w-4 h-4 text-yellow-500" />
<AlertCircle className="w-4 h-4 text-warning-500" />
<span className="text-sm text-gray-600 dark:text-gray-400">
{integration.mismatch_count} sync mismatch{integration.mismatch_count !== 1 ? 'es' : ''} detected
</span>
@@ -153,14 +153,14 @@ export default function WordPressIntegrationCard({
{integration.sync_error && (
<div className="pt-2 border-t border-gray-200 dark:border-gray-700">
<div className="p-2 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
<div className="p-2 bg-error-50 dark:bg-error-900/20 border border-error-200 dark:border-error-800 rounded-lg">
<div className="flex items-start gap-2">
<XCircle className="w-4 h-4 text-red-500 mt-0.5 flex-shrink-0" />
<XCircle className="w-4 h-4 text-error-500 mt-0.5 flex-shrink-0" />
<div className="flex-1">
<p className="text-xs font-medium text-red-800 dark:text-red-300 mb-1">
<p className="text-xs font-medium text-error-800 dark:text-error-300 mb-1">
Sync Error
</p>
<p className="text-xs text-red-700 dark:text-red-400">
<p className="text-xs text-error-700 dark:text-error-400">
{integration.sync_error}
</p>
</div>

View File

@@ -201,8 +201,8 @@ export default function WordPressIntegrationForm({
{/* Header with Toggle */}
<div className="flex items-center justify-between gap-3">
<div className="flex items-center gap-3">
<div className="p-3 bg-indigo-100 dark:bg-indigo-900/30 rounded-lg">
<Globe className="w-6 h-6 text-indigo-600 dark:text-indigo-400" />
<div className="p-3 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
<Globe className="w-6 h-6 text-purple-600 dark:text-purple-400" />
</div>
<div>
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
@@ -343,7 +343,7 @@ export default function WordPressIntegrationForm({
</div>
</td>
<td className="px-5 py-3 whitespace-nowrap">
<span className="inline-flex items-center justify-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium bg-green-50 text-green-600 dark:bg-green-500/15 dark:text-green-500">
<span className="inline-flex items-center justify-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium bg-success-50 text-success-600 dark:bg-success-500/15 dark:text-success-500">
Active
</span>
</td>
@@ -387,7 +387,7 @@ export default function WordPressIntegrationForm({
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
<DownloadIcon className="w-5 h-5 text-indigo-600 dark:text-indigo-400" />
<DownloadIcon className="w-5 h-5 text-purple-600 dark:text-purple-400" />
IGNY8 WP Bridge Plugin
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">

View File

@@ -69,8 +69,8 @@ export default function WordPressIntegrationModal({
<div className="p-6">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-3">
<div className="p-2 bg-indigo-100 dark:bg-indigo-900/30 rounded-lg">
<Globe className="w-5 h-5 text-indigo-600 dark:text-indigo-400" />
<div className="p-2 bg-purple-100 dark:bg-purple-900/30 rounded-lg">
<Globe className="w-5 h-5 text-purple-600 dark:text-purple-400" />
</div>
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
{initialData ? 'Edit WordPress Integration' : 'Connect WordPress Site'}
@@ -85,10 +85,10 @@ export default function WordPressIntegrationModal({
</div>
<form onSubmit={handleSubmit} className="space-y-4">
<div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4 mb-4">
<div className="bg-brand-50 dark:bg-brand-900/20 border border-brand-200 dark:border-brand-800 rounded-lg p-4 mb-4">
<div className="flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" />
<div className="text-sm text-blue-800 dark:text-blue-300">
<AlertCircle className="w-5 h-5 text-brand-600 dark:text-brand-400 mt-0.5 flex-shrink-0" />
<div className="text-sm text-brand-800 dark:text-brand-300">
<p className="font-medium mb-1">WordPress Application Password Required</p>
<p>
You need to create an Application Password in WordPress. Go to Users Profile

View File

@@ -298,7 +298,7 @@ const KanbanColumn: React.FC<KanbanColumnProps> = ({
}) => {
const getCountBadgeClass = () => {
if (status === "in_progress") {
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-orange-400";
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-warning-400";
}
if (status === "completed") {
return "bg-success-50 text-success-700 dark:bg-success-500/15 dark:text-success-500";
@@ -378,9 +378,9 @@ const TaskCard: React.FC<TaskCardProps> = ({ task, onClick, onDragStart }) => {
case "success":
return "bg-success-50 text-success-700 dark:bg-success-500/15 dark:text-success-500";
case "warning":
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-orange-400";
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-warning-400";
case "orange":
return "bg-orange-400/10 text-orange-400";
return "bg-warning-400/10 text-warning-400";
default:
return "bg-gray-100 text-gray-700 dark:bg-white/[0.03] dark:text-white/80";
}

View File

@@ -238,7 +238,7 @@ const TaskListSection: React.FC<TaskListSectionProps> = ({
}) => {
const getCountBadgeClass = () => {
if (title === "In Progress") {
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-orange-400";
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-warning-400";
}
if (title === "Completed") {
return "bg-success-50 text-success-700 dark:bg-success-500/15 dark:text-success-500";
@@ -313,9 +313,9 @@ const TaskListItem: React.FC<TaskListItemProps> = ({ task, checked, onClick, onC
case "success":
return "bg-success-50 text-success-700 dark:bg-success-500/15 dark:text-success-500";
case "warning":
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-orange-400";
return "bg-warning-50 text-warning-700 dark:bg-warning-500/15 dark:text-warning-400";
case "orange":
return "bg-orange-400/10 text-orange-400";
return "bg-warning-400/10 text-warning-400";
default:
return "bg-gray-100 text-gray-700 dark:bg-white/[0.03] dark:text-white/80";
}

View File

@@ -73,34 +73,34 @@ const toneStyles: Record<
"text-purple-700 ring-1 ring-purple-200 dark:ring-purple-500/30 dark:text-purple-400",
},
indigo: {
solid: "bg-indigo-600 text-white",
soft: "bg-indigo-50 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-400",
solid: "bg-purple-600 text-white",
soft: "bg-purple-50 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400",
outline:
"text-indigo-700 ring-1 ring-indigo-200 dark:ring-indigo-500/30 dark:text-indigo-400",
"text-purple-700 ring-1 ring-purple-200 dark:ring-purple-500/30 dark:text-purple-400",
},
pink: {
solid: "bg-pink-600 text-white",
soft: "bg-pink-50 text-pink-700 dark:bg-pink-500/15 dark:text-pink-400",
solid: "bg-purple-600 text-white",
soft: "bg-purple-50 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400",
outline:
"text-pink-700 ring-1 ring-pink-200 dark:ring-pink-500/30 dark:text-pink-400",
"text-purple-700 ring-1 ring-purple-200 dark:ring-purple-500/30 dark:text-purple-400",
},
teal: {
solid: "bg-teal-600 text-white",
soft: "bg-teal-50 text-teal-700 dark:bg-teal-500/15 dark:text-teal-400",
solid: "bg-purple-600 text-white",
soft: "bg-purple-50 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400",
outline:
"text-teal-700 ring-1 ring-teal-200 dark:ring-teal-500/30 dark:text-teal-400",
"text-purple-700 ring-1 ring-purple-200 dark:ring-purple-500/30 dark:text-purple-400",
},
cyan: {
solid: "bg-cyan-600 text-white",
soft: "bg-cyan-50 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400",
solid: "bg-purple-600 text-white",
soft: "bg-purple-50 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400",
outline:
"text-cyan-700 ring-1 ring-cyan-200 dark:ring-cyan-500/30 dark:text-cyan-400",
"text-purple-700 ring-1 ring-purple-200 dark:ring-purple-500/30 dark:text-purple-400",
},
blue: {
solid: "bg-blue-600 text-white",
soft: "bg-blue-50 text-blue-700 dark:bg-blue-500/15 dark:text-blue-400",
solid: "bg-brand-600 text-white",
soft: "bg-brand-50 text-brand-700 dark:bg-brand-500/15 dark:text-brand-400",
outline:
"text-blue-700 ring-1 ring-blue-200 dark:ring-blue-500/30 dark:text-blue-400",
"text-brand-700 ring-1 ring-brand-200 dark:ring-brand-500/30 dark:text-brand-400",
},
};

View File

@@ -102,7 +102,7 @@ const gradientTone: Record<ButtonTone, string> = {
danger:
"text-white shadow-[0_20px_45px_-30px_rgba(239,68,68,0.9)] bg-[linear-gradient(135deg,var(--color-danger)_0%,var(--color-danger-dark)_100%)]",
neutral:
"text-white shadow-theme-lg bg-[linear-gradient(135deg,#0f172a,#1e293b)]",
"text-white shadow-theme-lg bg-[linear-gradient(135deg,var(--color-gray-900),var(--color-gray-800))]",
};
const sizeClasses: Record<ButtonSize, string> = {

View File

@@ -104,9 +104,8 @@ export default function PricingTable({
<div className="relative inline-flex items-center justify-center">
<div className="relative inline-flex p-1 bg-gray-200 rounded-full dark:bg-gray-800 shadow-sm">
<span
className="absolute top-1 left-1 flex h-11 w-[130px] rounded-full shadow-theme-xs duration-200 ease-linear"
className="absolute top-1 left-1 flex h-11 w-[130px] rounded-full shadow-theme-xs duration-200 ease-linear bg-gradient-to-br from-brand-500 to-brand-700"
style={{
background: 'linear-gradient(to bottom right, #0693e3, #0472b8)',
transform: billingPeriod === 'monthly' ? 'translateX(0)' : 'translateX(130px)',
}}
></span>
@@ -134,7 +133,7 @@ export default function PricingTable({
</button>
</div>
{billingPeriod === 'annually' && (
<span className="absolute left-[calc(100%+1rem)] whitespace-nowrap inline-flex items-center gap-1.5 text-green-600 dark:text-green-400 font-semibold bg-green-50 dark:bg-green-900/20 px-3 py-1.5 rounded-full text-sm">
<span className="absolute left-[calc(100%+1rem)] whitespace-nowrap inline-flex items-center gap-1.5 text-success-600 dark:text-success-400 font-semibold bg-success-50 dark:bg-success-900/20 px-3 py-1.5 rounded-full text-sm">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
strokeLinecap="round"

View File

@@ -141,7 +141,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
<ul className="space-y-3 mb-6 flex-grow">
{plan.features.map((feature, index) => (
<li key={index} className="flex items-start gap-2">
<Check className="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5" />
<Check className="w-5 h-5 text-success-500 flex-shrink-0 mt-0.5" />
<span className="text-sm text-gray-700 dark:text-gray-300">{feature}</span>
</li>
))}
@@ -152,7 +152,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
<div className="text-xs font-semibold text-gray-500 dark:text-gray-400 mb-2">LIMITS</div>
{plan.max_sites && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{plan.max_sites === 99999 ? 'Unlimited' : plan.max_sites} Sites
</span>
@@ -160,7 +160,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
)}
{plan.max_users && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{plan.max_users === 99999 ? 'Unlimited' : plan.max_users} Team Members
</span>
@@ -168,7 +168,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
)}
{plan.max_content_words && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{(plan.max_content_words / 1000).toLocaleString()}K Words/month
</span>
@@ -176,7 +176,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
)}
{plan.max_content_ideas && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{plan.max_content_ideas} Ideas/month
</span>
@@ -184,7 +184,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
)}
{plan.max_images_basic && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{plan.max_images_basic} Images/month
</span>
@@ -192,7 +192,7 @@ export function PricingTable({ variant = '1', title, plans, showToggle = false,
)}
{plan.included_credits && (
<li className="flex items-start gap-2">
<Check className="w-4 h-4 text-blue-500 flex-shrink-0 mt-0.5" />
<Check className="w-4 h-4 text-brand-500 flex-shrink-0 mt-0.5" />
<span className="text-xs text-gray-600 dark:text-gray-400">
{plan.included_credits.toLocaleString()} Content pieces/month
</span>