import { useState, useEffect } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { Cloud, TestTube } from "lucide-react"; import { toast } from "sonner"; import { apiClient } from "../lib/api"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; import { Label } from "./ui/label"; import { Switch } from "./ui/switch"; import { EditButton } from "./ui/edit-button"; import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, } from "./ui/drawer"; import type { BackupSettings, S3Config } from "../types/api"; interface S3BackupConfigDrawerProps { settings?: BackupSettings; trigger?: React.ReactNode; } export default function S3BackupConfigDrawer({ settings, trigger, }: S3BackupConfigDrawerProps) { const [open, setOpen] = useState(false); const [config, setConfig] = useState({ access_key_id: "", secret_access_key: "", bucket_name: "", region: "us-east-1", endpoint_url: "", path_style: false, enabled: true, }); const queryClient = useQueryClient(); useEffect(() => { if (settings?.s3) { setConfig({ ...settings.s3 }); } }, [settings]); const updateMutation = useMutation({ mutationFn: (s3Config: S3Config) => apiClient.updateBackupSettings({ s3: s3Config, }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["backupSettings"] }); setOpen(false); toast.success("S3 backup configuration saved successfully"); }, onError: (error: Error & { response?: { data?: { detail?: string } } }) => { console.error("Failed to update S3 backup configuration:", error); const message = error?.response?.data?.detail || "Failed to save S3 configuration. Please check your settings and try again."; toast.error(message); }, }); const testMutation = useMutation({ mutationFn: () => apiClient.testBackupConnection({ service: "s3", config: config, }), onSuccess: (response) => { if (response.success) { console.log("S3 connection test successful"); toast.success( "S3 connection test successful! Your configuration is working correctly.", ); } else { console.error("S3 connection test failed:", response.message); toast.error(response.message || "S3 connection test failed. Please verify your credentials and settings."); } }, onError: (error: Error & { response?: { data?: { detail?: string } } }) => { console.error("Failed to test S3 connection:", error); const message = error?.response?.data?.detail || "S3 connection test failed. Please verify your credentials and settings."; toast.error(message); }, }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); updateMutation.mutate(config); }; const handleTest = () => { testMutation.mutate(); }; const isConfigValid = config.access_key_id.trim().length > 0 && config.secret_access_key.trim().length > 0 && config.bucket_name.trim().length > 0; return ( {trigger || }
S3 Backup Configuration Configure S3 settings for automatic database backups
setConfig({ ...config, enabled: checked }) } />
{config.enabled && ( <>
setConfig({ ...config, access_key_id: e.target.value }) } placeholder="Your AWS Access Key ID" required />
setConfig({ ...config, secret_access_key: e.target.value, }) } placeholder="Your AWS Secret Access Key" required />
setConfig({ ...config, bucket_name: e.target.value }) } placeholder="my-backup-bucket" required />
setConfig({ ...config, region: e.target.value }) } placeholder="us-east-1" required />
setConfig({ ...config, endpoint_url: e.target.value }) } placeholder="https://custom-s3-endpoint.com" />

For S3-compatible services like MinIO or DigitalOcean Spaces

setConfig({ ...config, path_style: checked }) } />

Enable for older S3 implementations or certain S3-compatible services

)}
{config.enabled && isConfigValid && ( )}
); }