fixes
This commit is contained in:
@@ -44,16 +44,12 @@ class CreditUsageLogSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ['created_at', 'account']
|
||||
|
||||
def get_client_cost(self, obj) -> str:
|
||||
"""Calculate client-facing cost from credits * default_credit_price_usd"""
|
||||
"""Calculate client-facing cost from credits * default_credit_price_usd (price per credit)"""
|
||||
from igny8_core.business.billing.models import BillingConfiguration
|
||||
try:
|
||||
config = BillingConfiguration.get_config()
|
||||
price_per_credit = config.default_credit_price_usd
|
||||
client_cost = Decimal(obj.credits_used) * price_per_credit
|
||||
return str(client_cost.quantize(Decimal('0.0001')))
|
||||
except Exception:
|
||||
# Fallback to cost_usd if billing config unavailable
|
||||
return str(obj.cost_usd) if obj.cost_usd else '0.0000'
|
||||
|
||||
def get_site_name(self, obj) -> Optional[str]:
|
||||
"""Get the site name if available"""
|
||||
|
||||
@@ -6,23 +6,17 @@ import React, { useState, useEffect } from 'react';
|
||||
import { Card } from '../ui/card';
|
||||
import Button from '../ui/button/Button';
|
||||
import IconButton from '../ui/button/IconButton';
|
||||
import Label from '../form/Label';
|
||||
import Input from '../form/input/InputField';
|
||||
import Checkbox from '../form/input/Checkbox';
|
||||
import Switch from '../form/switch/Switch';
|
||||
import { useToast } from '../ui/toast/ToastContainer';
|
||||
import { fetchAPI, API_BASE_URL } from '../../services/api';
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
AlertIcon,
|
||||
DownloadIcon,
|
||||
PlusIcon,
|
||||
CopyIcon,
|
||||
TrashBinIcon,
|
||||
GlobeIcon,
|
||||
KeyIcon,
|
||||
RefreshCwIcon,
|
||||
InfoIcon
|
||||
InfoIcon,
|
||||
} from '../../icons';
|
||||
|
||||
interface WordPressIntegrationFormProps {
|
||||
@@ -283,56 +277,40 @@ export default function WordPressIntegrationForm({
|
||||
|
||||
{/* Connection Status & Test Button */}
|
||||
{apiKey && (
|
||||
<div className="flex items-center gap-3">
|
||||
{/* Status Indicator - Uses theme colors from design-system */}
|
||||
<div className={`flex items-center gap-2 px-3 py-1.5 rounded-lg border ${
|
||||
connectionStatus === 'connected'
|
||||
? 'bg-success-50 dark:bg-success-900/20 border-success-200 dark:border-success-800'
|
||||
: connectionStatus === 'testing'
|
||||
? 'bg-brand-50 dark:bg-brand-900/20 border-brand-200 dark:border-brand-800'
|
||||
: connectionStatus === 'api_key_pending'
|
||||
? 'bg-warning-50 dark:bg-warning-900/20 border-warning-200 dark:border-warning-800'
|
||||
: connectionStatus === 'plugin_missing'
|
||||
? 'bg-warning-50 dark:bg-warning-900/20 border-warning-200 dark:border-warning-800'
|
||||
: connectionStatus === 'error'
|
||||
? 'bg-error-50 dark:bg-error-900/20 border-error-200 dark:border-error-800'
|
||||
: 'bg-gray-50 dark:bg-gray-800/50 border-gray-200 dark:border-gray-700'
|
||||
}`}>
|
||||
{connectionStatus === 'connected' && (
|
||||
<><CheckCircleIcon className="w-4 h-4 text-success-600 dark:text-success-400" />
|
||||
<span className="text-sm font-medium text-success-700 dark:text-success-300">Connected</span></>
|
||||
)}
|
||||
{connectionStatus === 'testing' && (
|
||||
<><RefreshCwIcon className="w-4 h-4 text-brand-600 dark:text-brand-400 animate-spin" />
|
||||
<span className="text-sm font-medium text-brand-700 dark:text-brand-300">Testing...</span></>
|
||||
)}
|
||||
{connectionStatus === 'api_key_pending' && (
|
||||
<><AlertIcon className="w-4 h-4 text-warning-600 dark:text-warning-400" />
|
||||
<span className="text-sm font-medium text-warning-700 dark:text-warning-300">Pending Setup</span></>
|
||||
)}
|
||||
{connectionStatus === 'plugin_missing' && (
|
||||
<><AlertIcon className="w-4 h-4 text-warning-600 dark:text-warning-400" />
|
||||
<span className="text-sm font-medium text-warning-700 dark:text-warning-300">Plugin Missing</span></>
|
||||
)}
|
||||
{connectionStatus === 'error' && (
|
||||
<><AlertIcon className="w-4 h-4 text-error-600 dark:text-error-400" />
|
||||
<span className="text-sm font-medium text-error-700 dark:text-error-300">Error</span></>
|
||||
)}
|
||||
{connectionStatus === 'unknown' && (
|
||||
<><InfoIcon className="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
<span className="text-sm font-medium text-gray-600 dark:text-gray-400">Not Tested</span></>
|
||||
)}
|
||||
<div className="flex flex-col items-end gap-2">
|
||||
{/* Connection Status Indicator */}
|
||||
<div className="flex items-center gap-3 px-4 py-2 rounded-lg bg-gray-50 dark:bg-gray-800">
|
||||
<span
|
||||
className={`inline-block w-4 h-4 rounded-full ${
|
||||
connectionStatus === 'connected' ? 'bg-success-500' :
|
||||
connectionStatus === 'testing' ? 'bg-brand-500 animate-pulse' :
|
||||
connectionStatus === 'api_key_pending' ? 'bg-warning-500' :
|
||||
connectionStatus === 'plugin_missing' ? 'bg-warning-500' :
|
||||
connectionStatus === 'error' ? 'bg-error-500' :
|
||||
'bg-brand-500'
|
||||
}`}
|
||||
/>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||
{connectionStatus === 'connected' && 'Connected'}
|
||||
{connectionStatus === 'testing' && 'Testing...'}
|
||||
{connectionStatus === 'api_key_pending' && 'Pending Setup'}
|
||||
{connectionStatus === 'plugin_missing' && 'Plugin Missing'}
|
||||
{connectionStatus === 'error' && 'Error'}
|
||||
{connectionStatus === 'unknown' && 'Configured'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Test Connection Button - IconButton only */}
|
||||
<IconButton
|
||||
{/* Test Connection Button */}
|
||||
<Button
|
||||
onClick={testConnection}
|
||||
variant="outline"
|
||||
tone="brand"
|
||||
size="sm"
|
||||
disabled={testingConnection || !apiKey}
|
||||
title="Test Connection"
|
||||
icon={<RefreshCwIcon className={`w-4 h-4 ${testingConnection ? 'animate-spin' : ''}`} />}
|
||||
/>
|
||||
startIcon={<RefreshCwIcon className={`w-4 h-4 ${testingConnection ? 'animate-spin' : ''}`} />}
|
||||
>
|
||||
Test Connection
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -499,19 +499,6 @@ export default function SiteSettings() {
|
||||
return `${months}mo ago`;
|
||||
};
|
||||
|
||||
// Integration status - tracks actual connection state
|
||||
const [integrationStatus, setIntegrationStatus] = useState<'connected' | 'configured' | 'not_configured'>('not_configured');
|
||||
|
||||
// Check integration status based on API key presence (will be updated by WordPressIntegrationForm)
|
||||
useEffect(() => {
|
||||
if (site?.wp_api_key) {
|
||||
// API key exists - mark as configured (actual connection tested in WordPressIntegrationForm)
|
||||
setIntegrationStatus('configured');
|
||||
} else {
|
||||
setIntegrationStatus('not_configured');
|
||||
}
|
||||
}, [site?.wp_api_key]);
|
||||
|
||||
// Sync Now handler - tests actual WordPress connection
|
||||
const [syncLoading, setSyncLoading] = useState(false);
|
||||
const [lastSyncTime, setLastSyncTime] = useState<string | null>(null);
|
||||
@@ -535,10 +522,8 @@ export default function SiteSettings() {
|
||||
const healthChecks = res.health_checks || {};
|
||||
|
||||
if (healthChecks.plugin_has_api_key) {
|
||||
setIntegrationStatus('connected');
|
||||
toast.success('WordPress connection verified - fully connected!');
|
||||
} else if (healthChecks.plugin_installed) {
|
||||
setIntegrationStatus('configured');
|
||||
toast.warning('Plugin found but API key not configured in WordPress');
|
||||
} else {
|
||||
toast.warning('WordPress reachable but IGNY8 plugin not installed');
|
||||
@@ -684,21 +669,6 @@ export default function SiteSettings() {
|
||||
Publishing
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Integration Status Indicator - Larger */}
|
||||
<div className="flex items-center gap-3 px-4 py-2 rounded-lg bg-gray-50 dark:bg-gray-800 flex-shrink-0">
|
||||
<span
|
||||
className={`inline-block w-3 h-3 rounded-full ${
|
||||
integrationStatus === 'connected' ? 'bg-success-500' :
|
||||
integrationStatus === 'configured' ? 'bg-brand-500' : 'bg-gray-300'
|
||||
}`}
|
||||
/>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||
{integrationStatus === 'connected' && 'Connected'}
|
||||
{integrationStatus === 'configured' && 'Configured'}
|
||||
{integrationStatus === 'not_configured' && 'Not Configured'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user