"use client" import { useEffect, useState } from "react" import { toast } from "sonner" import { credentialsApi, ConfiguredService } from "@/lib/api" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { Badge } from "@/components/ui/badge" import { Check, Loader2, Plus, Shield, Trash2, X } from "lucide-react" export default function CredentialsPage() { const [loading, setLoading] = useState(true) const [services, setServices] = useState([]) const [openDialog, setOpenDialog] = useState(false) const [selectedService, setSelectedService] = useState("") const [formData, setFormData] = useState>({}) const [saving, setSaving] = useState(false) // Predefined schemas for known services const schemas: Record = { stripe: { label: "Stripe", fields: [ { key: "secretKey", label: "Secret Key (sk_...)", type: "password" }, { key: "webhookSecret", label: "Webhook Secret (whsec_...)", type: "password" }, { key: "publishableKey", label: "Publishable Key (pk_...)", type: "text" }, ] }, storage: { label: "AWS S3 / Compatible", fields: [ { key: "endpoint", label: "Endpoint URL", type: "text" }, { key: "region", label: "Region", type: "text" }, { key: "bucket", label: "Bucket Name", type: "text" }, { key: "accessKey", label: "Access Key ID", type: "text" }, { key: "secretKey", label: "Secret Access Key", type: "password" }, ] }, cpanel: { label: "cPanel Integration", fields: [ { key: "host", label: "cPanel URL (https://domain:2083)", type: "text" }, { key: "username", label: "Username", type: "text" }, { key: "apiToken", label: "API Token", type: "password" }, ] }, cloudflare_config: { label: "Cloudflare", fields: [ { key: "apiToken", label: "API Token", type: "password" }, { key: "zoneId", label: "Zone ID", type: "text" }, ] }, smtp: { label: "SMTP Email", fields: [ { key: "host", label: "Host", type: "text" }, { key: "port", label: "Port", type: "number" }, { key: "username", label: "Username", type: "text" }, { key: "password", label: "Password", type: "password" }, { key: "from_email", label: "From Email", type: "email" }, { key: "from_name", label: "From Name", type: "text" }, { key: "secure", label: "Use TLS", type: "checkbox" } // TODO handle checkbox ] }, appwrite: { label: "Appwrite", fields: [ { key: "endpoint", label: "Endpoint", type: "text" }, { key: "projectId", label: "Project ID", type: "text" }, { key: "apiKey", label: "API Key", type: "password" }, ] }, firebase: { label: "Firebase (JSON)", fields: [ { key: "serviceAccountJson", label: "Service Account JSON Content", type: "textarea" } ] } } const availableServices = Object.keys(schemas) useEffect(() => { loadServices() }, []) const loadServices = async () => { try { setLoading(true) const res = await credentialsApi.list() // Backend returns { services: [...] } if (res && res.services) { setServices(res.services) } } catch (error) { toast.error("Failed to load credentials") console.error(error) } finally { setLoading(false) } } const handleEdit = (serviceName: string) => { setSelectedService(serviceName) setFormData({}) // Reset form, we don't load existing secrets for security setOpenDialog(true) } const handleSave = async () => { if (!selectedService) return try { setSaving(true) await credentialsApi.save(selectedService, formData) toast.success(`${schemas[selectedService]?.label || selectedService} credentials saved!`) setOpenDialog(false) loadServices() } catch (error: any) { toast.error(error.message || "Failed to save") } finally { setSaving(false) } } const handleDelete = async (serviceName: string) => { if (!confirm(`Are you sure you want to delete credentials for ${serviceName}? This will break functionality relying on it.`)) return try { await credentialsApi.delete(serviceName) toast.success("Credentials deleted") loadServices() } catch (error: any) { toast.error("Failed to delete") } } return (

System Credentials

Manage external service connections securely. Keys are encrypted in the database.

{services.map((svc) => ( {schemas[svc.service_name]?.label || svc.service_name} {svc.is_configured ? ( Active ) : ( Pending )}

{svc.is_configured ? `Last updated ${new Date(svc.updated_at).toLocaleDateString()}` : "Not configured yet"}

{svc.is_configured && ( )}
))}
Configure {schemas[selectedService]?.label || selectedService} Enter the credentials for this service. They will be encrypted before storage.
{schemas[selectedService]?.fields.map((field) => (
{field.type === 'textarea' ? (