import React, { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Input } from '../../components/ui/input'; import { Label } from '../../components/ui/label'; import { AlertCircle, CheckCircle, Settings as SettingsIcon, RefreshCw, Zap, Edit, Save, X, Copy, Eye, EyeOff, ExternalLink } from 'lucide-react'; import api from '../../utils/api'; import { toast } from 'sonner'; export default function AdminSettings() { const [stripeStatus, setStripeStatus] = useState(null); const [loadingStatus, setLoadingStatus] = useState(true); const [testing, setTesting] = useState(false); const [isEditing, setIsEditing] = useState(false); const [saving, setSaving] = useState(false); // Form state const [formData, setFormData] = useState({ secret_key: '', webhook_secret: '' }); // Show/hide sensitive values const [showSecretKey, setShowSecretKey] = useState(false); const [showWebhookSecret, setShowWebhookSecret] = useState(false); useEffect(() => { fetchStripeStatus(); }, []); const fetchStripeStatus = async () => { setLoadingStatus(true); try { const response = await api.get('/admin/settings/stripe/status'); setStripeStatus(response.data); } catch (error) { console.error('Failed to fetch Stripe status:', error); toast.error('Failed to load Stripe status'); } finally { setLoadingStatus(false); } }; const handleTestConnection = async () => { setTesting(true); try { const response = await api.post('/admin/settings/stripe/test-connection'); toast.success(response.data.message); } catch (error) { const message = error.response?.data?.detail || 'Connection test failed'; toast.error(message); } finally { setTesting(false); } }; const handleEditClick = () => { setIsEditing(true); setFormData({ secret_key: '', webhook_secret: '' }); }; const handleCancelEdit = () => { setIsEditing(false); setFormData({ secret_key: '', webhook_secret: '' }); setShowSecretKey(false); setShowWebhookSecret(false); }; const handleSave = async () => { // Validate inputs if (!formData.secret_key || !formData.webhook_secret) { toast.error('Both Secret Key and Webhook Secret are required'); return; } if (!formData.secret_key.startsWith('sk_test_') && !formData.secret_key.startsWith('sk_live_')) { toast.error('Invalid Secret Key format. Must start with sk_test_ or sk_live_'); return; } if (!formData.webhook_secret.startsWith('whsec_')) { toast.error('Invalid Webhook Secret format. Must start with whsec_'); return; } setSaving(true); try { await api.put('/admin/settings/stripe', formData); toast.success('Stripe settings updated successfully'); setIsEditing(false); setFormData({ secret_key: '', webhook_secret: '' }); setShowSecretKey(false); setShowWebhookSecret(false); // Refresh status await fetchStripeStatus(); } catch (error) { const message = error.response?.data?.detail || 'Failed to update Stripe settings'; toast.error(message); } finally { setSaving(false); } }; const copyToClipboard = (text, label) => { navigator.clipboard.writeText(text); toast.success(`${label} copied to clipboard`); }; if (loadingStatus) { return (
Manage system configuration and integrations
Get this from your Stripe Dashboard → Developers → API keys
Get this from your Stripe Dashboard → Developers → Webhooks → Add endpoint
Configuration Status
Credentials stored in database (encrypted)
Environment
Detected from secret key prefix
Secret Key
{stripeStatus.secret_key_prefix}...
Webhook Secret
Webhook endpoint configuration
Configure this webhook endpoint in your Stripe Dashboard:
Webhook Events to Configure:
✅ Required (Configure in Stripe):
🔔 Automatically Triggered:
These fire automatically with checkout.session.completed
🔄 Coming Soon (Recurring Subscriptions):
Configuration Required
Click "Edit Settings" above to configure your Stripe credentials.
Get your API keys from{' '} Stripe Dashboard
After configuring your API keys, set up this webhook endpoint in your Stripe Dashboard:
Webhook Events to Configure:
✅ Required (Configure in Stripe):
🔔 Automatically Triggered:
These fire automatically with checkout.session.completed
🔄 Coming Soon (Recurring Subscriptions):
Additional settings sections will be added here
(Email, Storage, Notifications, etc.)