GLobal Styling part 1
This commit is contained in:
@@ -8,8 +8,7 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon } from '../../icons';
|
||||
import { ChevronRight, Check } from 'lucide-react';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon, ChevronRightIcon, CheckIcon } from '../../icons';
|
||||
import Label from '../form/Label';
|
||||
import Input from '../form/input/InputField';
|
||||
import Checkbox from '../form/input/Checkbox';
|
||||
@@ -236,7 +235,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
|
||||
}
|
||||
`}
|
||||
>
|
||||
{step < currentStep ? <Check className="w-5 h-5" /> : step}
|
||||
{step < currentStep ? <CheckIcon className="w-5 h-5" /> : step}
|
||||
</div>
|
||||
<div className="ml-3">
|
||||
<div className={`text-sm font-medium ${step === currentStep ? 'text-gray-900 dark:text-white' : 'text-gray-500 dark:text-gray-400'}`}>
|
||||
@@ -379,7 +378,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
|
||||
{isPaidPlan ? (
|
||||
<Button type="button" variant="primary" onClick={handleNextStep} className="w-full">
|
||||
Continue to Billing
|
||||
<ChevronRight className="w-4 h-4 ml-2" />
|
||||
<ChevronRightIcon className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
) : (
|
||||
<Button type="submit" variant="primary" disabled={loading} className="w-full">
|
||||
@@ -404,7 +403,7 @@ export default function SignUpFormEnhanced({ planDetails: planDetailsProp, planL
|
||||
</Button>
|
||||
<Button type="button" variant="primary" onClick={handleNextStep} className="flex-1">
|
||||
Continue to Payment
|
||||
<ChevronRight className="w-4 h-4 ml-2" />
|
||||
<ChevronRightIcon className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon } from '../../icons';
|
||||
import { CreditCard, Building2, Wallet, Check, Loader2 } from 'lucide-react';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon, CreditCardIcon, Building2Icon, WalletIcon, CheckIcon, Loader2Icon } from '../../icons';
|
||||
import Label from '../form/Label';
|
||||
import Input from '../form/input/InputField';
|
||||
import Checkbox from '../form/input/Checkbox';
|
||||
@@ -195,13 +194,13 @@ export default function SignUpFormSimplified({ planDetails: planDetailsProp, pla
|
||||
const getPaymentIcon = (method: string) => {
|
||||
switch (method) {
|
||||
case 'stripe':
|
||||
return <CreditCard className="w-5 h-5" />;
|
||||
return <CreditCardIcon className="w-5 h-5" />;
|
||||
case 'bank_transfer':
|
||||
return <Building2 className="w-5 h-5" />;
|
||||
return <Building2Icon className="w-5 h-5" />;
|
||||
case 'local_wallet':
|
||||
return <Wallet className="w-5 h-5" />;
|
||||
return <WalletIcon className="w-5 h-5" />;
|
||||
default:
|
||||
return <CreditCard className="w-5 h-5" />;
|
||||
return <CreditCardIcon className="w-5 h-5" />;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -353,7 +352,7 @@ export default function SignUpFormSimplified({ planDetails: planDetailsProp, pla
|
||||
|
||||
{paymentMethodsLoading ? (
|
||||
<div className="flex items-center justify-center p-6 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<Loader2 className="w-5 h-5 animate-spin text-brand-500 mr-2" />
|
||||
<Loader2Icon className="w-5 h-5 animate-spin text-brand-500 mr-2" />
|
||||
<span className="text-sm text-gray-600 dark:text-gray-400">Loading payment options...</span>
|
||||
</div>
|
||||
) : paymentMethods.length === 0 ? (
|
||||
@@ -390,7 +389,7 @@ export default function SignUpFormSimplified({ planDetails: planDetailsProp, pla
|
||||
{method.display_name}
|
||||
</h4>
|
||||
{selectedPaymentMethod === method.payment_method && (
|
||||
<Check className="w-5 h-5 text-brand-500" />
|
||||
<CheckIcon className="w-5 h-5 text-brand-500" />
|
||||
)}
|
||||
</div>
|
||||
{method.instructions && (
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon } from '../../icons';
|
||||
import { CreditCard, Building2, Wallet, Check, Loader2, CheckCircle } from 'lucide-react';
|
||||
import { ChevronLeftIcon, EyeCloseIcon, EyeIcon, CreditCardIcon, Building2Icon, WalletIcon, CheckIcon, Loader2Icon, CheckCircleIcon } from '../../icons';
|
||||
import Label from '../form/Label';
|
||||
import Input from '../form/input/InputField';
|
||||
import Checkbox from '../form/input/Checkbox';
|
||||
@@ -234,13 +233,13 @@ export default function SignUpFormUnified({
|
||||
const getPaymentIcon = (method: string) => {
|
||||
switch (method) {
|
||||
case 'stripe':
|
||||
return <CreditCard className="w-5 h-5" />;
|
||||
return <CreditCardIcon className="w-5 h-5" />;
|
||||
case 'bank_transfer':
|
||||
return <Building2 className="w-5 h-5" />;
|
||||
return <Building2Icon className="w-5 h-5" />;
|
||||
case 'local_wallet':
|
||||
return <Wallet className="w-5 h-5" />;
|
||||
return <WalletIcon className="w-5 h-5" />;
|
||||
default:
|
||||
return <CreditCard className="w-5 h-5" />;
|
||||
return <CreditCardIcon className="w-5 h-5" />;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -359,7 +358,7 @@ export default function SignUpFormUnified({
|
||||
<span className={`font-semibold text-sm ${isSelected ? 'text-brand-600 dark:text-brand-400' : 'text-gray-900 dark:text-white'}`}>
|
||||
{plan.name}
|
||||
</span>
|
||||
{isSelected && <CheckCircle className="w-4 h-4 text-brand-500" />}
|
||||
{isSelected && <CheckCircleIcon className="w-4 h-4 text-brand-500" />}
|
||||
</div>
|
||||
<div className="text-lg font-bold text-gray-900 dark:text-white">
|
||||
{isFree ? 'Free' : `$${displayPrice.toFixed(2)}`}
|
||||
@@ -450,7 +449,7 @@ export default function SignUpFormUnified({
|
||||
</Label>
|
||||
{paymentMethodsLoading ? (
|
||||
<div className="flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-800 rounded-lg h-[52px]">
|
||||
<Loader2 className="w-4 h-4 animate-spin text-brand-500" />
|
||||
<Loader2Icon className="w-4 h-4 animate-spin text-brand-500" />
|
||||
</div>
|
||||
) : paymentMethods.length === 0 ? (
|
||||
<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">
|
||||
@@ -514,7 +513,7 @@ export default function SignUpFormUnified({
|
||||
<Button type="submit" variant="primary" disabled={loading} className="w-full">
|
||||
{loading ? (
|
||||
<span className="flex items-center justify-center">
|
||||
<Loader2 className="w-4 h-4 animate-spin mr-2" />
|
||||
<Loader2Icon className="w-4 h-4 animate-spin mr-2" />
|
||||
Creating your account...
|
||||
</span>
|
||||
) : isPaidPlan ? (
|
||||
@@ -613,7 +612,7 @@ export default function SignUpFormUnified({
|
||||
{isSelected && (
|
||||
<div className="absolute -top-4 -right-4">
|
||||
<div className="bg-brand-500 rounded-full p-2 shadow-lg">
|
||||
<CheckCircle className="w-8 h-8 text-white" />
|
||||
<CheckCircleIcon className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -621,7 +620,7 @@ export default function SignUpFormUnified({
|
||||
{/* Header: Plan name, price, and features in horizontal layout */}
|
||||
<div className="flex items-center gap-6">
|
||||
{/* Plan Name & Price */}
|
||||
<div className="flex-shrink-0" style={{ minWidth: '200px' }}>
|
||||
<div className="flex-shrink-0 min-w-[200px]">
|
||||
<h3 className="text-lg font-bold text-gray-900 dark:text-white mb-1">{plan.name}</h3>
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="text-3xl font-bold text-gray-900 dark:text-white">
|
||||
@@ -644,7 +643,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-success-500 dark:text-success-400 flex-shrink-0" />
|
||||
<CheckCircleIcon 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>
|
||||
))}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Card } from '../ui/card';
|
||||
import { DollarSign, TrendingUp, AlertCircle } from 'lucide-react';
|
||||
import { DollarSignIcon, TrendingUpIcon, AlertCircleIcon } from '../../icons';
|
||||
import Badge from '../ui/badge/Badge';
|
||||
import { getCreditUsageSummary } from '../../services/billing.api';
|
||||
import { useToast } from '../ui/toast/ToastContainer';
|
||||
@@ -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-error-500 mx-auto mb-4" />
|
||||
<AlertCircleIcon 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>
|
||||
@@ -120,7 +120,7 @@ export default function CreditCostBreakdownPanel() {
|
||||
<Card className="p-6 border-l-4 border-brand-500 dark:border-brand-400">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2 bg-brand-50 dark:bg-brand-900/20 rounded-lg">
|
||||
<DollarSign className="w-5 h-5 text-brand-500 dark:text-brand-400" />
|
||||
<DollarSignIcon className="w-5 h-5 text-brand-500 dark:text-brand-400" />
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 dark:text-gray-400">Total Cost</div>
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@ export default function CreditCostBreakdownPanel() {
|
||||
<Card className="p-6 border-l-4 border-success-500 dark:border-success-400">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2 bg-success-50 dark:bg-success-900/20 rounded-lg">
|
||||
<TrendingUp className="w-5 h-5 text-success-500 dark:text-success-400" />
|
||||
<TrendingUpIcon className="w-5 h-5 text-success-500 dark:text-success-400" />
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 dark:text-gray-400">Avg Cost/Day</div>
|
||||
</div>
|
||||
@@ -146,7 +146,7 @@ export default function CreditCostBreakdownPanel() {
|
||||
<Card className="p-6 border-l-4 border-purple-500 dark:border-purple-400">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<TrendingUp className="w-5 h-5 text-purple-500 dark:text-purple-400" />
|
||||
<TrendingUpIcon className="w-5 h-5 text-purple-500 dark:text-purple-400" />
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 dark:text-gray-400">Total Operations</div>
|
||||
</div>
|
||||
@@ -159,7 +159,7 @@ export default function CreditCostBreakdownPanel() {
|
||||
<Card className="p-6 border-l-4 border-info-500 dark:border-info-400">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="p-2 bg-info-50 dark:bg-info-900/20 rounded-lg">
|
||||
<DollarSign className="w-5 h-5 text-info-500 dark:text-info-400" />
|
||||
<DollarSignIcon className="w-5 h-5 text-info-500 dark:text-info-400" />
|
||||
</div>
|
||||
<div className="text-sm text-gray-600 dark:text-gray-400">Total Credits</div>
|
||||
</div>
|
||||
@@ -231,7 +231,7 @@ export default function CreditCostBreakdownPanel() {
|
||||
|
||||
{operationsList.length === 0 && (
|
||||
<div className="col-span-4 text-center py-12">
|
||||
<DollarSign className="w-12 h-12 text-gray-300 dark:text-gray-600 mx-auto mb-3" />
|
||||
<DollarSignIcon className="w-12 h-12 text-gray-300 dark:text-gray-600 mx-auto mb-3" />
|
||||
<p className="text-gray-500 dark:text-gray-400">
|
||||
No cost data available for this period
|
||||
</p>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Modal } from '../ui/modal';
|
||||
import Button from '../ui/button/Button';
|
||||
import Label from '../form/Label';
|
||||
import Input from '../form/input/InputField';
|
||||
import { Loader2, Upload, X, CheckCircle } from 'lucide-react';
|
||||
import { Loader2Icon, UploadIcon, XIcon, CheckCircleIcon } from '../../icons';
|
||||
import { API_BASE_URL } from '../../services/api';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
|
||||
@@ -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-success-500 mx-auto mb-4" />
|
||||
<CheckCircleIcon 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>
|
||||
@@ -267,7 +267,7 @@ export default function PaymentConfirmationModal({
|
||||
className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:border-brand-500 hover:bg-brand-50 dark:border-gray-700 dark:hover:border-brand-400 dark:hover:bg-brand-500/10 transition-colors"
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center pt-5 pb-6">
|
||||
<Upload className="w-10 h-10 mb-3 text-gray-400" />
|
||||
<UploadIcon className="w-10 h-10 mb-3 text-gray-400" />
|
||||
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
<span className="font-semibold">Click to upload</span> or drag and drop
|
||||
</p>
|
||||
@@ -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-success-500" />
|
||||
<CheckCircleIcon className="w-5 h-5 text-success-500" />
|
||||
<span className="text-sm text-gray-700 dark:text-gray-300">
|
||||
{uploadedFileName}
|
||||
</span>
|
||||
@@ -299,13 +299,13 @@ export default function PaymentConfirmationModal({
|
||||
disabled={loading}
|
||||
className="p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
|
||||
>
|
||||
<X className="w-4 h-4 text-gray-500" />
|
||||
<XIcon className="w-4 h-4 text-gray-500" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{uploading && (
|
||||
<div className="mt-2 flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
<Loader2Icon className="w-4 h-4 animate-spin" />
|
||||
<span>Uploading...</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -330,7 +330,7 @@ export default function PaymentConfirmationModal({
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
||||
<Loader2Icon className="w-4 h-4 mr-2 animate-spin" />
|
||||
Submitting...
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { API_BASE_URL } from '../../services/api';
|
||||
import Button from '../ui/button/Button';
|
||||
import { CheckCircle, XCircle, Clock, RefreshCw } from 'lucide-react';
|
||||
import { CheckCircleIcon, XCircleIcon, ClockIcon, RefreshCwIcon } from '../../icons';
|
||||
|
||||
interface Payment {
|
||||
id: number;
|
||||
@@ -53,13 +53,13 @@ export default function PaymentHistory() {
|
||||
const getStatusIcon = (status: string) => {
|
||||
switch (status) {
|
||||
case 'succeeded':
|
||||
return <CheckCircle className="w-5 h-5 text-success-500" />;
|
||||
return <CheckCircleIcon className="w-5 h-5 text-success-500" />;
|
||||
case 'failed':
|
||||
return <XCircle className="w-5 h-5 text-error-500" />;
|
||||
return <XCircleIcon className="w-5 h-5 text-error-500" />;
|
||||
case 'pending_approval':
|
||||
return <Clock className="w-5 h-5 text-warning-500" />;
|
||||
return <ClockIcon className="w-5 h-5 text-warning-500" />;
|
||||
default:
|
||||
return <Clock className="w-5 h-5 text-gray-500" />;
|
||||
return <ClockIcon className="w-5 h-5 text-gray-500" />;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -86,7 +86,7 @@ export default function PaymentHistory() {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center p-12">
|
||||
<RefreshCw className="w-8 h-8 animate-spin text-gray-400" />
|
||||
<RefreshCwIcon className="w-8 h-8 animate-spin text-gray-400" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ export default function PaymentHistory() {
|
||||
Payment History
|
||||
</h2>
|
||||
<Button onClick={loadPayments} variant="outline" size="sm">
|
||||
<RefreshCw className="w-4 h-4 mr-2" />
|
||||
<RefreshCwIcon className="w-4 h-4 mr-2" />
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { CheckCircle, Loader2, AlertCircle } from 'lucide-react';
|
||||
import { CheckCircleIcon, Loader2Icon, AlertCircleIcon } from '../../icons';
|
||||
import { API_BASE_URL } from '../../services/api';
|
||||
|
||||
export interface PaymentMethodConfig {
|
||||
@@ -76,7 +76,7 @@ export default function PaymentMethodSelect({
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-8">
|
||||
<Loader2 className="w-6 h-6 animate-spin text-brand-500" />
|
||||
<Loader2Icon className="w-6 h-6 animate-spin text-brand-500" />
|
||||
<span className="ml-3 text-gray-600 dark:text-gray-400">Loading payment methods...</span>
|
||||
</div>
|
||||
);
|
||||
@@ -86,7 +86,7 @@ export default function PaymentMethodSelect({
|
||||
return (
|
||||
<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" />
|
||||
<AlertCircleIcon className="w-5 h-5 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium">Failed to load payment methods</p>
|
||||
<p className="text-sm mt-1">{fetchError}</p>
|
||||
@@ -106,7 +106,7 @@ export default function PaymentMethodSelect({
|
||||
return (
|
||||
<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" />
|
||||
<AlertCircleIcon className="w-5 h-5 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="font-medium">No payment methods available</p>
|
||||
<p className="text-sm mt-1">
|
||||
@@ -157,7 +157,7 @@ export default function PaymentMethodSelect({
|
||||
{/* Radio indicator */}
|
||||
<div className="flex-shrink-0 mt-0.5">
|
||||
{selectedMethod === method.payment_method ? (
|
||||
<CheckCircle className="w-5 h-5 text-brand-500 dark:text-brand-400" />
|
||||
<CheckCircleIcon className="w-5 h-5 text-brand-500 dark:text-brand-400" />
|
||||
) : (
|
||||
<div className="w-5 h-5 rounded-full border-2 border-gray-300 dark:border-gray-600" />
|
||||
)}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { AlertCircle, CreditCard, X } from 'lucide-react';
|
||||
import { AlertCircleIcon, CreditCardIcon, XIcon } from '../../icons';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Button from '../ui/button/Button';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
@@ -118,7 +118,7 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
<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-warning-600 dark:text-warning-400 flex-shrink-0 mt-0.5" />
|
||||
<AlertCircleIcon 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-warning-900 dark:text-warning-100">
|
||||
Payment Required
|
||||
@@ -143,7 +143,7 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
onClick={handleDismiss}
|
||||
className="p-1 hover:bg-warning-100 dark:hover:bg-warning-800/40 rounded transition-colors"
|
||||
>
|
||||
<X className="w-5 h-5 text-warning-600 dark:text-warning-400" />
|
||||
<XIcon className="w-5 h-5 text-warning-600 dark:text-warning-400" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -170,7 +170,7 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
<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
|
||||
<AlertCircleIcon
|
||||
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">
|
||||
@@ -230,7 +230,7 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
startIcon={<CreditCard className="w-4 h-4" />}
|
||||
startIcon={<CreditCardIcon className="w-4 h-4" />}
|
||||
onClick={() => setShowPaymentModal(true)}
|
||||
>
|
||||
Confirm Payment
|
||||
@@ -252,7 +252,7 @@ export default function PendingPaymentBanner({ className = '' }: PendingPaymentB
|
||||
: 'hover:bg-warning-100 dark:hover:bg-warning-800/40 text-warning-600 dark:text-warning-400'
|
||||
}`}
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
<XIcon className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Card } from '../ui/card';
|
||||
import { AlertCircle, TrendingUp, Users, Globe, Tag, FileText, Image, Zap } from 'lucide-react';
|
||||
import { AlertCircleIcon, TrendingUpIcon, UsersIcon, GlobeIcon, TagIcon, FileTextIcon, ImageIcon, ZapIcon } from '../../icons';
|
||||
import Badge from '../ui/badge/Badge';
|
||||
import { getUsageSummary, type UsageSummary, type LimitUsage } from '../../services/billing.api';
|
||||
import { useToast } from '../ui/toast/ToastContainer';
|
||||
@@ -106,7 +106,7 @@ function LimitCard({ title, icon, usage, type, daysUntilReset, accentColor = 'br
|
||||
<div className={`mt-3 flex items-start gap-2 text-xs ${
|
||||
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" />
|
||||
<AlertCircleIcon className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
<span>
|
||||
{isDanger
|
||||
? 'Limit almost reached! Consider upgrading your plan.'
|
||||
@@ -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-error-500 mx-auto mb-4" />
|
||||
<AlertCircleIcon 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>
|
||||
@@ -174,18 +174,18 @@ export default function UsageLimitsPanel() {
|
||||
}
|
||||
|
||||
const hardLimitConfig = {
|
||||
sites: { icon: <Globe className="w-5 h-5" />, color: 'success' as const },
|
||||
users: { icon: <Users className="w-5 h-5" />, color: 'info' as const },
|
||||
keywords: { icon: <Tag className="w-5 h-5" />, color: 'purple' as const },
|
||||
clusters: { icon: <TrendingUp className="w-5 h-5" />, color: 'warning' as const },
|
||||
sites: { icon: <GlobeIcon className="w-5 h-5" />, color: 'success' as const },
|
||||
users: { icon: <UsersIcon className="w-5 h-5" />, color: 'info' as const },
|
||||
keywords: { icon: <TagIcon className="w-5 h-5" />, color: 'purple' as const },
|
||||
clusters: { icon: <TrendingUpIcon className="w-5 h-5" />, color: 'warning' as const },
|
||||
};
|
||||
|
||||
const monthlyLimitConfig = {
|
||||
content_ideas: { icon: <FileText className="w-5 h-5" />, color: 'brand' as const },
|
||||
content_words: { icon: <FileText className="w-5 h-5" />, color: 'indigo' as const },
|
||||
images_basic: { icon: <Image className="w-5 h-5" />, color: 'teal' as const },
|
||||
images_premium: { icon: <Zap className="w-5 h-5" />, color: 'cyan' as const },
|
||||
image_prompts: { icon: <Image className="w-5 h-5" />, color: 'pink' as const },
|
||||
content_ideas: { icon: <FileTextIcon className="w-5 h-5" />, color: 'brand' as const },
|
||||
content_words: { icon: <FileTextIcon className="w-5 h-5" />, color: 'indigo' as const },
|
||||
images_basic: { icon: <ImageIcon className="w-5 h-5" />, color: 'teal' as const },
|
||||
images_premium: { icon: <ZapIcon className="w-5 h-5" />, color: 'cyan' as const },
|
||||
image_prompts: { icon: <ImageIcon className="w-5 h-5" />, color: 'pink' as const },
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -256,7 +256,7 @@ export default function UsageLimitsPanel() {
|
||||
<Card className="p-6 bg-gradient-to-r from-brand-50 to-brand-100 dark:from-brand-900/20 dark:to-brand-800/10 border-brand-200 dark:border-brand-700">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="p-3 bg-brand-500 rounded-lg text-white">
|
||||
<TrendingUp className="w-6 h-6" />
|
||||
<TrendingUpIcon className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
||||
|
||||
@@ -109,8 +109,7 @@ export default function ImageResultCard({
|
||||
<img
|
||||
src={imageData.url}
|
||||
alt="Generated image"
|
||||
className="w-full object-contain"
|
||||
style={{ maxHeight: '400px' }}
|
||||
className="w-full object-contain max-h-[400px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Phase 6: Site Integration & Multi-Destination Publishing
|
||||
*/
|
||||
import React from 'react';
|
||||
import { CheckCircleIcon, XCircleIcon, ClockIcon, RefreshCw } from 'lucide-react';
|
||||
import { CheckCircleIcon, XCircleIcon, ClockIcon, RefreshCwIcon } from '../../icons';
|
||||
|
||||
interface IntegrationStatusProps {
|
||||
syncEnabled: boolean;
|
||||
@@ -25,7 +25,7 @@ export default function IntegrationStatus({
|
||||
case 'failed':
|
||||
return <XCircleIcon className="w-5 h-5 text-error-500" />;
|
||||
case 'syncing':
|
||||
return <RefreshCw className="w-5 h-5 text-brand-500 animate-spin" />;
|
||||
return <RefreshCwIcon className="w-5 h-5 text-brand-500 animate-spin" />;
|
||||
default:
|
||||
return <ClockIcon className="w-5 h-5 text-gray-400" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Phase 6: Site Integration & Multi-Destination Publishing
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { PlusIcon, TrashIcon, TestTubeIcon, RefreshCw } from 'lucide-react';
|
||||
import { PlusIcon, TrashIcon, TestTubeIcon, RefreshCwIcon } from '../../icons';
|
||||
import Button from '../ui/button/Button';
|
||||
import { Modal } from '../ui/modal';
|
||||
import FormModal, { FormField } from '../common/FormModal';
|
||||
@@ -302,7 +302,7 @@ export default function SiteIntegrationsSection({ siteId }: SiteIntegrationsSect
|
||||
onClick={() => handleSync(integration)}
|
||||
className="flex-1"
|
||||
>
|
||||
<RefreshCw className="w-4 h-4 mr-1" />
|
||||
<RefreshCwIcon className="w-4 h-4 mr-1" />
|
||||
Sync
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -230,7 +230,7 @@ export default function OnboardingWizard({ onComplete, onSkip }: OnboardingWizar
|
||||
<div
|
||||
className={`size-8 rounded-full flex items-center justify-center text-sm font-medium transition-colors ${
|
||||
step.id < currentStep
|
||||
? 'bg-green-500 text-white'
|
||||
? 'bg-success-500 text-white'
|
||||
: step.id === currentStep
|
||||
? 'bg-brand-500 text-white'
|
||||
: 'bg-gray-200 dark:bg-gray-700 text-gray-500 dark:text-gray-400'
|
||||
@@ -246,7 +246,7 @@ export default function OnboardingWizard({ onComplete, onSkip }: OnboardingWizar
|
||||
<div
|
||||
className={`h-1 flex-1 mx-2 rounded transition-colors ${
|
||||
step.id < currentStep
|
||||
? 'bg-green-500'
|
||||
? 'bg-success-500'
|
||||
: 'bg-gray-200 dark:bg-gray-700'
|
||||
}`}
|
||||
/>
|
||||
|
||||
@@ -234,7 +234,7 @@ export default function Step2AddSite({
|
||||
tone={isSelected ? 'success' : 'neutral'}
|
||||
variant="soft"
|
||||
className={`cursor-pointer transition-all ${
|
||||
isSelected ? 'ring-2 ring-green-500' : 'hover:bg-gray-200 dark:hover:bg-gray-700'
|
||||
isSelected ? 'ring-2 ring-success-500' : 'hover:bg-gray-200 dark:hover:bg-gray-700'
|
||||
}`}
|
||||
>
|
||||
<span onClick={() => handleSectorToggle(sector.slug)} className="flex items-center">
|
||||
@@ -254,20 +254,20 @@ export default function Step2AddSite({
|
||||
)}
|
||||
|
||||
{/* Defaults Info */}
|
||||
<Card className="p-4 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 mb-6">
|
||||
<Card className="p-4 bg-brand-50 dark:bg-brand-900/20 border-brand-200 dark:border-brand-800 mb-6">
|
||||
<div className="flex items-start gap-3">
|
||||
<GridIcon className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5" />
|
||||
<GridIcon className="w-5 h-5 text-brand-600 dark:text-brand-400 mt-0.5" />
|
||||
<div>
|
||||
<h4 className="font-medium text-blue-900 dark:text-blue-100 text-sm mb-1">
|
||||
<h4 className="font-medium text-brand-900 dark:text-brand-100 text-sm mb-1">
|
||||
Optimized Defaults Applied
|
||||
</h4>
|
||||
<ul className="text-xs text-blue-700 dark:text-blue-300 space-y-0.5">
|
||||
<ul className="text-xs text-brand-700 dark:text-brand-300 space-y-0.5">
|
||||
<li>• Auto-approval enabled</li>
|
||||
<li>• Auto-publish to site enabled</li>
|
||||
<li>• 3 articles/day limit</li>
|
||||
<li>• Publishing Mon-Fri at 9am, 2pm, 6pm</li>
|
||||
</ul>
|
||||
<p className="text-xs text-blue-600 dark:text-blue-400 mt-2">
|
||||
<p className="text-xs text-brand-600 dark:text-brand-400 mt-2">
|
||||
You can customize these in Site Settings anytime.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -216,9 +216,9 @@ export default function Step3ConnectIntegration({
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`size-10 rounded-lg flex items-center justify-center ${
|
||||
testResult === 'success'
|
||||
? 'bg-green-100 dark:bg-green-900/50 text-green-600 dark:text-green-400'
|
||||
? 'bg-success-100 dark:bg-success-900/50 text-success-600 dark:text-success-400'
|
||||
: testResult === 'failed'
|
||||
? 'bg-red-100 dark:bg-red-900/50 text-red-600 dark:text-red-400'
|
||||
? 'bg-error-100 dark:bg-error-900/50 text-error-600 dark:text-error-400'
|
||||
: 'bg-gray-100 dark:bg-gray-800 text-gray-500'
|
||||
}`}>
|
||||
{testResult === 'success' ? (
|
||||
|
||||
@@ -216,7 +216,7 @@ export default function Step4AddKeywords({
|
||||
{keywords.length > 0 && (
|
||||
<button
|
||||
onClick={() => setKeywords([])}
|
||||
className="text-red-500 hover:text-red-600"
|
||||
className="text-error-500 hover:text-error-600"
|
||||
>
|
||||
Clear all
|
||||
</button>
|
||||
@@ -224,15 +224,15 @@ export default function Step4AddKeywords({
|
||||
</div>
|
||||
|
||||
{/* Keyword Suggestions */}
|
||||
<Card className="p-4 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 mb-6">
|
||||
<h4 className="font-medium text-blue-900 dark:text-blue-100 text-sm mb-2">
|
||||
💡 Keyword Ideas
|
||||
<Card className="p-4 bg-brand-50 dark:bg-brand-900/20 border-brand-200 dark:border-brand-800 mb-6">
|
||||
<h4 className="font-medium text-brand-900 dark:text-brand-100 text-sm mb-2">
|
||||
Keyword Ideas
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{SUGGESTIONS.map((suggestion, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="text-xs text-blue-700 dark:text-blue-300 bg-blue-100 dark:bg-blue-800/50 px-2 py-1 rounded"
|
||||
className="text-xs text-brand-700 dark:text-brand-300 bg-brand-100 dark:bg-brand-800/50 px-2 py-1 rounded"
|
||||
>
|
||||
{suggestion}
|
||||
</span>
|
||||
|
||||
@@ -57,7 +57,7 @@ export default function Step5Complete({
|
||||
<div className="text-center">
|
||||
{/* Success Animation */}
|
||||
<div className="mb-6">
|
||||
<div className="inline-flex items-center justify-center size-20 rounded-full bg-green-100 dark:bg-green-900/50 text-green-600 dark:text-green-400 mb-4">
|
||||
<div className="inline-flex items-center justify-center size-20 rounded-full bg-success-100 dark:bg-success-900/50 text-success-600 dark:text-success-400 mb-4">
|
||||
<CheckCircleIcon className="h-10 w-10" />
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
|
||||
@@ -75,14 +75,14 @@ export default function Step5Complete({
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
<li className="flex items-center gap-2 text-sm">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
Site: <span className="font-medium">{data.siteName || 'Your Site'}</span>
|
||||
</span>
|
||||
</li>
|
||||
{data.integrationTested && (
|
||||
<li className="flex items-center gap-2 text-sm">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
WordPress integration connected
|
||||
</span>
|
||||
@@ -90,20 +90,20 @@ export default function Step5Complete({
|
||||
)}
|
||||
{data.keywordsAdded && (
|
||||
<li className="flex items-center gap-2 text-sm">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
{data.keywordsCount} keyword{data.keywordsCount !== 1 ? 's' : ''} added to pipeline
|
||||
</span>
|
||||
</li>
|
||||
)}
|
||||
<li className="flex items-center gap-2 text-sm">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
Auto-approval & auto-publish enabled
|
||||
</span>
|
||||
</li>
|
||||
<li className="flex items-center gap-2 text-sm">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
Daily automation scheduled
|
||||
</span>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Phase 6: Site Integration & Multi-Destination Publishing
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { PlusIcon, TrashIcon, ArrowUpIcon, ArrowDownIcon } from 'lucide-react';
|
||||
import { PlusIcon, TrashIcon, ArrowUpIcon, ArrowDownIcon } from '../../icons';
|
||||
import Button from '../ui/button/Button';
|
||||
import Checkbox from '../form/input/Checkbox';
|
||||
import Label from '../form/Label';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Component for previewing layouts with sample content
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { EyeIcon, XIcon, Maximize2Icon } from 'lucide-react';
|
||||
import { EyeIcon, XIcon, Maximize2Icon } from '../../icons';
|
||||
import { Card } from '../../ui/card';
|
||||
import Button from '../../ui/button/Button';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Component for selecting page layouts
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { CheckIcon } from 'lucide-react';
|
||||
import { CheckIcon } from '../../icons';
|
||||
import { Card } from '../../ui/card';
|
||||
|
||||
export interface LayoutOption {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { Card } from '../ui/card';
|
||||
import Badge from '../ui/badge/Badge';
|
||||
// import { fetchSiteProgress, SiteProgress } from '../../services/api';
|
||||
import { CheckCircleIcon, XCircleIcon, AlertCircleIcon, ArrowRightIcon } from 'lucide-react';
|
||||
import { CheckCircleIcon, XCircleIcon, AlertCircleIcon, ArrowRightIcon } from '../../icons';
|
||||
|
||||
interface SiteProgressWidgetProps {
|
||||
blueprintId: number;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Displays site type indicator (Site Builder or WordPress)
|
||||
*/
|
||||
import React from 'react';
|
||||
import { Wand2, Globe } from 'lucide-react';
|
||||
import { Wand2Icon, GlobeIcon } from '../../icons';
|
||||
import Badge from '../ui/badge/Badge';
|
||||
|
||||
interface SiteTypeBadgeProps {
|
||||
@@ -18,13 +18,13 @@ export default function SiteTypeBadge({ hostingType, className = '' }: SiteTypeB
|
||||
return {
|
||||
label: 'Site Builder',
|
||||
color: 'primary' as const,
|
||||
icon: <Wand2 className="w-3 h-3" />,
|
||||
icon: <Wand2Icon className="w-3 h-3" />,
|
||||
};
|
||||
case 'wordpress':
|
||||
return {
|
||||
label: 'WordPress',
|
||||
color: 'info' as const,
|
||||
icon: <Globe className="w-3 h-3" />,
|
||||
icon: <GlobeIcon className="w-3 h-3" />,
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Component for editing CSS styles and theme customization
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { CodeIcon, PaletteIcon, TypeIcon, SaveIcon, RefreshCwIcon } from 'lucide-react';
|
||||
import { CodeIcon, PaletteIcon, TypeIcon, SaveIcon, RefreshCwIcon } from '../../icons';
|
||||
import { Card } from '../../ui/card';
|
||||
import Button from '../../ui/button/Button';
|
||||
import Label from '../../form/Label';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Component for customizing template settings and styles
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { SettingsIcon, PaletteIcon, TypeIcon, LayoutIcon } from 'lucide-react';
|
||||
import { SettingsIcon, PaletteIcon, TypeIcon, LayoutIcon } from '../../icons';
|
||||
import { Card } from '../../ui/card';
|
||||
import Label from '../../form/Label';
|
||||
import SelectDropdown from '../../form/SelectDropdown';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Component for browsing and selecting page templates
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { SearchIcon, FilterIcon, CheckIcon } from 'lucide-react';
|
||||
import { SearchIcon, FilterIcon, CheckIcon } from '../../icons';
|
||||
import { Card } from '../../ui/card';
|
||||
import Button from '../../ui/button/Button';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Globe, CheckCircle, XCircle, Settings, RefreshCw, AlertCircle, ExternalLink } from 'lucide-react';
|
||||
import { GlobeIcon, CheckCircleIcon, XCircleIcon, SettingsIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon } from '../../icons';
|
||||
import { Card } from '../ui/card';
|
||||
import Button from '../ui/button/Button';
|
||||
import Badge from '../ui/badge/Badge';
|
||||
@@ -49,7 +49,7 @@ export default function WordPressIntegrationCard({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<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" />
|
||||
<GlobeIcon 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">
|
||||
@@ -74,7 +74,7 @@ export default function WordPressIntegrationCard({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<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" />
|
||||
<GlobeIcon 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-success-500" />
|
||||
<CheckCircleIcon className="w-4 h-4 text-success-500" />
|
||||
) : integration.sync_status === 'failed' || integration.sync_status === 'error' ? (
|
||||
<XCircle className="w-4 h-4 text-error-500" />
|
||||
<XCircleIcon className="w-4 h-4 text-error-500" />
|
||||
) : integration.sync_status === 'warning' ? (
|
||||
<AlertCircle className="w-4 h-4 text-warning-500" />
|
||||
<AlertCircleIcon className="w-4 h-4 text-warning-500" />
|
||||
) : (
|
||||
<RefreshCw className="w-4 h-4 text-warning-500 animate-spin" />
|
||||
<RefreshCwIcon 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-warning-500" />
|
||||
<AlertCircleIcon 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>
|
||||
@@ -144,7 +144,7 @@ export default function WordPressIntegrationCard({
|
||||
onClick={() => navigate(`/sites/${siteId}/sync`)}
|
||||
>
|
||||
View Details
|
||||
<ExternalLink className="w-3 h-3 ml-1" />
|
||||
<ExternalLinkIcon className="w-3 h-3 ml-1" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -155,7 +155,7 @@ export default function WordPressIntegrationCard({
|
||||
<div className="pt-2 border-t border-gray-200 dark:border-gray-700">
|
||||
<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-error-500 mt-0.5 flex-shrink-0" />
|
||||
<XCircleIcon 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-error-800 dark:text-error-300 mb-1">
|
||||
Sync Error
|
||||
@@ -176,7 +176,7 @@ export default function WordPressIntegrationCard({
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
>
|
||||
<Settings className="w-4 h-4 mr-2" />
|
||||
<SettingsIcon className="w-4 h-4 mr-2" />
|
||||
Manage
|
||||
</Button>
|
||||
{siteId && (
|
||||
@@ -186,7 +186,7 @@ export default function WordPressIntegrationCard({
|
||||
size="sm"
|
||||
title="View Sync Dashboard"
|
||||
>
|
||||
<ExternalLink className="w-4 h-4" />
|
||||
<ExternalLinkIcon className="w-4 h-4" />
|
||||
</Button>
|
||||
)}
|
||||
{onSync && (
|
||||
@@ -196,7 +196,7 @@ export default function WordPressIntegrationCard({
|
||||
size="sm"
|
||||
disabled={loading}
|
||||
>
|
||||
<RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
|
||||
<RefreshCwIcon className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -17,9 +17,11 @@ import {
|
||||
DownloadIcon,
|
||||
PlusIcon,
|
||||
CopyIcon,
|
||||
TrashBinIcon
|
||||
TrashBinIcon,
|
||||
GlobeIcon,
|
||||
KeyIcon,
|
||||
RefreshCwIcon
|
||||
} from '../../icons';
|
||||
import { Globe, Key, RefreshCw } from 'lucide-react';
|
||||
|
||||
interface WordPressIntegrationFormProps {
|
||||
siteId: number;
|
||||
@@ -202,7 +204,7 @@ export default function WordPressIntegrationForm({
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<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" />
|
||||
<GlobeIcon 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">
|
||||
@@ -257,7 +259,7 @@ export default function WordPressIntegrationForm({
|
||||
>
|
||||
{generatingKey ? (
|
||||
<>
|
||||
<RefreshCw className="w-4 h-4 mr-2 animate-spin" />
|
||||
<RefreshCwIcon className="w-4 h-4 mr-2 animate-spin" />
|
||||
Generating...
|
||||
</>
|
||||
) : (
|
||||
@@ -313,7 +315,7 @@ export default function WordPressIntegrationForm({
|
||||
className="inline-flex h-11 w-11 items-center justify-center rounded-lg border border-gray-300 text-gray-700 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-50"
|
||||
title="Regenerate"
|
||||
>
|
||||
<RefreshCw className={`w-5 h-5 ${generatingKey ? 'animate-spin' : ''}`} />
|
||||
<RefreshCwIcon className={`w-5 h-5 ${generatingKey ? 'animate-spin' : ''}`} />
|
||||
</button>
|
||||
<div className="invisible absolute bottom-full left-1/2 z-50 mb-2.5 -translate-x-1/2 opacity-0 transition-opacity duration-300 group-hover:visible group-hover:opacity-100">
|
||||
<div className="relative">
|
||||
@@ -358,7 +360,7 @@ export default function WordPressIntegrationForm({
|
||||
className="text-gray-500 hover:text-brand-500 dark:text-gray-400 dark:hover:text-brand-400 disabled:opacity-50 transition-colors"
|
||||
title="Regenerate API key"
|
||||
>
|
||||
<RefreshCw className={`w-5 h-5 ${generatingKey ? 'animate-spin' : ''}`} />
|
||||
<RefreshCwIcon className={`w-5 h-5 ${generatingKey ? 'animate-spin' : ''}`} />
|
||||
</button>
|
||||
<button
|
||||
onClick={handleRevokeApiKey}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Form for connecting/managing WordPress integration
|
||||
*/
|
||||
import React, { useState } from 'react';
|
||||
import { X, Globe, AlertCircle } from 'lucide-react';
|
||||
import { XIcon, GlobeIcon, AlertCircleIcon } from '../../icons';
|
||||
import { Modal } from '../ui/modal';
|
||||
import Button from '../ui/button/Button';
|
||||
import Label from '../form/Label';
|
||||
@@ -70,7 +70,7 @@ export default function WordPressIntegrationModal({
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<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" />
|
||||
<GlobeIcon 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'}
|
||||
@@ -80,14 +80,14 @@ export default function WordPressIntegrationModal({
|
||||
onClick={onClose}
|
||||
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
<XIcon className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-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-brand-600 dark:text-brand-400 mt-0.5 flex-shrink-0" />
|
||||
<AlertCircleIcon 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>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Check } from 'lucide-react';
|
||||
import { CheckIcon } from '../../../icons';
|
||||
|
||||
export interface PricingPlan {
|
||||
id: number;
|
||||
@@ -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-success-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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-brand-500 flex-shrink-0 mt-0.5" />
|
||||
<CheckIcon 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>
|
||||
|
||||
Reference in New Issue
Block a user