import { useEffect, useState } from 'react'; import { IoIosLink, IoIosTrash } from 'react-icons/io'; import { MdModeEdit } from 'react-icons/md'; import { GoUnlink } from 'react-icons/go'; import React from 'react'; import { useConnections, useOAuthConnect, useDisconnect } from '../../hooks/useConnections'; import { useLanguage } from '../../contexts/LanguageContext'; import { ColumnConfig } from '../FormGenerator'; import { EditFieldConfig } from '../Popup'; import { Connection, CreateConnectionData, ConnectionsLogicReturn, TableAction } from './interfaces'; export function useConnectionsLogic(): ConnectionsLogicReturn { const { t } = useLanguage(); // Hooks const { connections, fetchConnections, createConnection, updateConnection, connectService, disconnectService, deleteConnection, isLoading, error } = useConnections(); const { connectWithPopup, isConnecting, error: connectError } = useOAuthConnect(); const { disconnect, isDisconnecting, error: disconnectError } = useDisconnect(); // Local state const [editPopupOpen, setEditPopupOpen] = useState(false); const [editingConnection, setEditingConnection] = useState(null); // Define field configuration for editing connections const connectionEditFields: EditFieldConfig[] = [ { key: 'authority', label: t('connections.field.service', 'Service'), type: 'readonly', editable: false, formatter: (value: string) => { if (!value) return t('connections.unknown', 'Unknown'); const labels = { 'google': t('connections.service.google', 'Google'), 'msft': t('connections.service.microsoft', 'Microsoft'), 'local': t('connections.service.local', 'Local') }; return labels[value as keyof typeof labels] || value; } }, { key: 'status', label: t('connections.field.status', 'Status'), type: 'readonly', editable: false, formatter: (value: string) => value ? value.charAt(0).toUpperCase() + value.slice(1) : t('connections.unknown', 'Unknown') }, { key: 'externalUsername', label: t('connections.field.external_username', 'External Username'), type: 'string', editable: true, required: false, placeholder: t('connections.placeholder.external_username', 'Enter external username') }, { key: 'externalEmail', label: t('connections.field.external_email', 'External Email'), type: 'email', editable: true, required: false, placeholder: t('connections.placeholder.external_email', 'Enter external email address') }, { key: 'connectedAt', label: t('connections.field.connected_at', 'Connected At'), type: 'readonly', editable: false, formatter: (value: string) => { if (!value) return t('connections.not_available', 'N/A'); try { return new Date(value).toLocaleString(); } catch { return t('connections.invalid_date', 'Invalid Date'); } } }, { key: 'lastChecked', label: t('connections.field.last_checked', 'Last Checked'), type: 'readonly', editable: false, formatter: (value: string) => { if (!value) return t('connections.not_available', 'N/A'); try { return new Date(value).toLocaleString(); } catch { return t('connections.invalid_date', 'Invalid Date'); } } } ]; // Define custom columns for the connections table const connectionColumns: ColumnConfig[] = [ { key: 'authority', label: t('connections.field.service', 'Service'), type: 'enum', filterOptions: ['google', 'msft', 'local'], formatter: (value: string) => { if (!value) return t('connections.unknown', 'Unknown'); const labels = { 'google': t('connections.service.google', 'Google'), 'msft': t('connections.service.microsoft', 'Microsoft'), 'local': t('connections.service.local', 'Local') }; return labels[value as keyof typeof labels] || value; }, width: 150, sortable: true, filterable: true }, { key: 'status', label: t('connections.field.status', 'Status'), type: 'enum', filterOptions: ['active', 'pending', 'expired', 'revoked'], formatter: (value: string) => { return value?.charAt(0).toUpperCase() + value?.slice(1) || t('connections.unknown', 'Unknown'); }, width: 120, sortable: true, filterable: true }, { key: 'externalUsername', label: t('connections.field.external_username', 'External Username'), type: 'string', width: 200, sortable: true, filterable: false, searchable: true }, { key: 'externalEmail', label: t('connections.field.external_email', 'External Email'), type: 'string', width: 250, sortable: true, filterable: false, searchable: true }, { key: 'connectedAt', label: t('connections.field.connected_at', 'Connected At'), type: 'date', width: 150, sortable: true, filterable: false, searchable: true }, { key: 'lastChecked', label: t('connections.field.last_checked', 'Last Checked'), type: 'date', width: 150, sortable: true, filterable: true, searchable: true }, { key: 'expiresAt', label: t('connections.field.expires_at', 'Expires At'), type: 'date', width: 150, sortable: true, filterable: true } ]; // Fetch connections on mount useEffect(() => { fetchConnections(); }, []); // Handler functions const handleCreateConnection = async (type: 'msft' | 'google') => { console.log('Creating connection for type:', type); try { const connectionData: CreateConnectionData = { type: type, status: 'pending', connectedAt: new Date().toISOString(), lastChecked: new Date().toISOString() }; console.log('Sending connection data to backend:', connectionData); const newConnection = await createConnection(connectionData); console.log('Connection created successfully:', newConnection); await fetchConnections(); } catch (error) { console.error('Error creating connection:', error); } }; const handleConnect = async (connection: Connection) => { console.log('Connecting to service:', connection); try { await connectWithPopup(connection.id); await fetchConnections(); } catch (error) { console.error('Error connecting to service:', error); } }; const handleDisconnect = async (connection: Connection) => { console.log('Disconnecting from service:', connection); try { await disconnect(connection.id); await fetchConnections(); } catch (error) { console.error('Error disconnecting from service:', error); } }; const handleDelete = async (connection: Connection) => { const serviceName = connection.authority?.charAt(0).toUpperCase() + connection.authority?.slice(1) || t('connections.unknown', 'Unknown'); const confirmMessage = t('connections.confirm_delete', 'Are you sure you want to delete the {service} connection?').replace('{service}', serviceName); if (window.confirm(confirmMessage)) { try { await deleteConnection(connection.id); await fetchConnections(); } catch (error) { console.error('Error deleting connection:', error); } } }; const handleConnectOrDisconnect = async (connection: Connection) => { if (connection.status === 'active') { await handleDisconnect(connection); } else { await handleConnect(connection); } }; const handleEditConnection = async (connection: Connection) => { console.log('Editing connection:', connection); setEditingConnection(connection); setEditPopupOpen(true); }; const handleSaveConnection = async (updatedConnection: Connection) => { if (!editingConnection) return; try { const updateData = { externalUsername: updatedConnection.externalUsername, externalEmail: updatedConnection.externalEmail }; await updateConnection(editingConnection.id, updateData); console.log('Connection updated successfully'); await fetchConnections(); setEditPopupOpen(false); setEditingConnection(null); } catch (error) { console.error('Error updating connection:', error); } }; const handleCancelEdit = () => { setEditPopupOpen(false); setEditingConnection(null); }; // Table actions const tableActions: TableAction[] = [ { label: t('connections.action.edit', 'Edit'), onClick: handleEditConnection, icon: }, { label: t('connections.action.toggle_connection', 'Toggle Connection'), onClick: handleConnectOrDisconnect, icon: (connection: Connection) => connection.status === 'active' ? : }, { label: t('connections.action.delete', 'Delete'), onClick: handleDelete, icon: } ]; return { // Data connections, isLoading, isConnecting, isDisconnecting, error, connectError, disconnectError, editPopupOpen, editingConnection, connectionColumns, connectionEditFields, tableActions, // Handlers handleCreateConnection, handleConnect, handleDisconnect, handleDelete, handleConnectOrDisconnect, handleEditConnection, handleSaveConnection, handleCancelEdit }; }