"use client"; import { format } from "date-fns"; import { PlusIcon, Trash2Icon } from "lucide-react"; import { useState } from "react"; import { deleteIntegration, testIntegrationConnection, updateIntegration, } from "@/actions/integrations"; import { AmazonS3Icon } from "@/components/icons/services/IconServices"; import { IntegrationActionButtons, IntegrationCardHeader, IntegrationSkeleton, } from "@/components/integrations/shared"; import { Button, useToast, Card, CardContent, CardHeader, } from "@/components/shadcn"; import { Modal } from "@/components/shadcn/modal"; import { DataTablePagination } from "@/components/shadcn/table/data-table-pagination"; import { triggerTestConnectionWithDelay } from "@/lib/integrations/test-connection-helper"; import { MetaDataProps } from "@/types"; import { IntegrationProps } from "@/types/integrations"; import { ProviderProps } from "@/types/providers"; import { S3IntegrationForm } from "./s3-integration-form"; interface S3IntegrationsManagerProps { integrations: IntegrationProps[]; providers: ProviderProps[]; metadata?: MetaDataProps; } export const S3IntegrationsManager = ({ integrations, providers, metadata, }: S3IntegrationsManagerProps) => { const [isModalOpen, setIsModalOpen] = useState(false); const [editingIntegration, setEditingIntegration] = useState(null); const [editMode, setEditMode] = useState< "configuration" | "credentials" | null >(null); const [isDeleting, setIsDeleting] = useState(null); const [isTesting, setIsTesting] = useState(null); const [isOperationLoading, setIsOperationLoading] = useState(false); const [isDeleteOpen, setIsDeleteOpen] = useState(false); const [integrationToDelete, setIntegrationToDelete] = useState(null); const { toast } = useToast(); const handleAddIntegration = () => { setEditingIntegration(null); setEditMode(null); // Creation mode setIsModalOpen(true); }; const handleEditConfiguration = (integration: IntegrationProps) => { setEditingIntegration(integration); setEditMode("configuration"); setIsModalOpen(true); }; const handleEditCredentials = (integration: IntegrationProps) => { setEditingIntegration(integration); setEditMode("credentials"); setIsModalOpen(true); }; const handleOpenDeleteModal = (integration: IntegrationProps) => { setIntegrationToDelete(integration); setIsDeleteOpen(true); }; const handleDeleteIntegration = async (id: string) => { setIsDeleting(id); try { const result = await deleteIntegration(id, "amazon_s3"); if (result.success) { toast({ title: "Success!", description: "S3 integration deleted successfully.", }); } else if (result.error) { toast({ variant: "destructive", title: "Delete Failed", description: result.error, }); } } catch (_error) { toast({ variant: "destructive", title: "Error", description: "Failed to delete S3 integration. Please try again.", }); } finally { setIsDeleting(null); setIsDeleteOpen(false); setIntegrationToDelete(null); } }; const handleTestConnection = async (id: string) => { setIsTesting(id); try { const result = await testIntegrationConnection(id); if (result.success) { toast({ title: "Connection test successful!", description: result.message || "Connection test completed successfully.", }); } else if (result.error) { toast({ variant: "destructive", title: "Connection test failed", description: result.error, }); } } catch (_error) { toast({ variant: "destructive", title: "Error", description: "Failed to test connection. Please try again.", }); } finally { setIsTesting(null); } }; const handleToggleEnabled = async (integration: IntegrationProps) => { try { const newEnabledState = !integration.attributes.enabled; const formData = new FormData(); formData.append( "integration_type", integration.attributes.integration_type, ); formData.append("enabled", JSON.stringify(newEnabledState)); const result = await updateIntegration(integration.id, formData); if (result && "success" in result) { toast({ title: "Success!", description: `Integration ${newEnabledState ? "enabled" : "disabled"} successfully.`, }); } else if (result && "error" in result) { toast({ variant: "destructive", title: "Toggle Failed", description: result.error, }); } } catch (_error) { toast({ variant: "destructive", title: "Error", description: "Failed to toggle integration. Please try again.", }); } }; const handleModalClose = () => { setIsModalOpen(false); setEditingIntegration(null); setEditMode(null); }; const handleFormSuccess = async ( integrationId?: string, shouldTestConnection?: boolean, ) => { // Close the modal immediately setIsModalOpen(false); setEditingIntegration(null); setEditMode(null); setIsOperationLoading(true); // Set testing state for server-triggered test connections if (integrationId && shouldTestConnection) { setIsTesting(integrationId); } // Trigger test connection if needed triggerTestConnectionWithDelay( integrationId, shouldTestConnection, "s3", toast, 200, () => { // Clear testing state when server-triggered test completes setIsTesting(null); }, ); // Reset loading state after a short delay to show the skeleton briefly setTimeout(() => { setIsOperationLoading(false); }, 1500); }; return ( <>
{/* Header with Add Button */}

Configured S3 Integrations

{integrations.length === 0 ? "Not configured yet" : `${integrations.length} integration${integrations.length !== 1 ? "s" : ""} configured`}

{/* Integrations List */} {isOperationLoading ? ( } title="Amazon S3" subtitle="Export security findings to Amazon S3 buckets." /> ) : integrations.length > 0 ? (
{integrations.map((integration) => ( } title={ integration.attributes.configuration.bucket_name || "Unknown Bucket" } subtitle={`Output directory: ${ integration.attributes.configuration.output_directory || integration.attributes.configuration.path || "/" }`} connectionStatus={{ connected: integration.attributes.connected, }} navigationUrl={`https://console.aws.amazon.com/s3/buckets/${integration.attributes.configuration.bucket_name}`} />
{integration.attributes.connection_last_checked_at && (

Last checked:{" "} {format( new Date( integration.attributes.connection_last_checked_at, ), "yyyy/MM/dd", )}

)}
))}
) : null} {metadata && integrations.length > 0 && (
)}
); };