'use client';
import { Button } from './ui/button';
import { StatusBadge } from './Badge';
import { getContrastColor } from '../../lib/colorUtils';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuSeparator,
} from './ui/dropdown-menu';
interface InstalledScript {
id: number;
script_name: string;
script_path: string;
container_id: string | null;
server_id: number | null;
server_name: string | null;
server_ip: string | null;
server_user: string | null;
server_password: string | null;
server_auth_type: string | null;
server_ssh_key: string | null;
server_ssh_key_passphrase: string | null;
server_ssh_port: number | null;
server_color: string | null;
installation_date: string;
status: 'in_progress' | 'success' | 'failed';
output_log: string | null;
execution_mode: 'local' | 'ssh';
container_status?: 'running' | 'stopped' | 'unknown';
web_ui_ip: string | null;
web_ui_port: number | null;
is_vm?: boolean;
}
interface ScriptInstallationCardProps {
script: InstalledScript;
isEditing: boolean;
editFormData: { script_name: string; container_id: string; web_ui_ip: string; web_ui_port: string };
onInputChange: (field: 'script_name' | 'container_id' | 'web_ui_ip' | 'web_ui_port', value: string) => void;
onEdit: () => void;
onSave: () => void;
onCancel: () => void;
onUpdate: () => void;
onBackup?: () => void;
onClone?: () => void;
onShell: () => void;
onDelete: () => void;
isUpdating: boolean;
isDeleting: boolean;
// New container control props
containerStatus?: 'running' | 'stopped' | 'unknown';
onStartStop: (action: 'start' | 'stop') => void;
onDestroy: () => void;
isControlling: boolean;
// Web UI props
onOpenWebUI: () => void;
onAutoDetectWebUI: () => void;
isAutoDetecting: boolean;
}
export function ScriptInstallationCard({
script,
isEditing,
editFormData,
onInputChange,
onEdit,
onSave,
onCancel,
onUpdate,
onBackup,
onClone,
onShell,
onDelete,
isUpdating,
isDeleting,
containerStatus,
onStartStop,
onDestroy,
isControlling,
onOpenWebUI,
onAutoDetectWebUI,
isAutoDetecting
}: ScriptInstallationCardProps) {
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleString();
};
// Helper function to check if a script has any actions available
const hasActions = (script: InstalledScript) => {
if (script.container_id && script.execution_mode === 'ssh') return true;
if (script.web_ui_ip != null) return true;
if (!script.container_id || script.execution_mode !== 'ssh') return true;
return false;
};
return (
{/* Header with Script Name and Status */}
{isEditing ? (
) : (
{script.script_name}
{script.script_path}
)}
{script.status.replace('_', ' ').toUpperCase()}
{/* Details Grid */}
{/* Container ID */}
Container ID
{isEditing ? (
onInputChange('container_id', e.target.value)}
className="w-full px-2 py-1 text-sm font-mono border border-border rounded bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
placeholder="Container ID"
/>
) : (
{script.container_id ? (
{script.container_id}
{script.container_status && (
{script.container_status === 'running' ? 'Running' :
script.container_status === 'stopped' ? 'Stopped' :
'Unknown'}
)}
) : '-'}
)}
{/* Web UI */}
IP:PORT
{isEditing ? (
onInputChange('web_ui_ip', e.target.value)}
className="flex-1 px-2 py-1 text-sm font-mono border border-border rounded bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
placeholder="IP"
/>
:
onInputChange('web_ui_port', e.target.value)}
className="w-20 px-2 py-1 text-sm font-mono border border-border rounded bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
placeholder="Port"
/>
) : (
{script.web_ui_ip ? (
{script.container_id && script.execution_mode === 'ssh' && (
)}
) : (
-
{script.container_id && script.execution_mode === 'ssh' && (
)}
)}
)}
{/* Server */}
Server
{script.server_name ?? '-'}
{/* Installation Date */}
Installation Date
{formatDate(String(script.installation_date))}
{/* Action Buttons */}
{isEditing ? (
<>
>
) : (
<>
{hasActions(script) && (
{script.container_id && !script.is_vm && (
Update
)}
{script.container_id && script.execution_mode === 'ssh' && onBackup && (
Backup
)}
{script.container_id && script.execution_mode === 'ssh' && onClone && (
Clone
)}
{script.container_id && script.execution_mode === 'ssh' && (
Shell
)}
{script.web_ui_ip && (
Open UI
)}
{script.container_id && script.execution_mode === 'ssh' && (
<>
onStartStop(containerStatus === 'running' ? 'stop' : 'start')}
disabled={isControlling || containerStatus === 'unknown'}
className={containerStatus === 'running'
? "text-error hover:text-error-foreground hover:bg-error/20 focus:bg-error/20"
: "text-success hover:text-success-foreground hover:bg-success/20 focus:bg-success/20"
}
>
{isControlling ? 'Working...' : containerStatus === 'running' ? 'Stop' : 'Start'}
{isControlling ? 'Working...' : 'Destroy'}
>
)}
{(!script.container_id || script.execution_mode !== 'ssh') && (
<>
{isDeleting ? 'Deleting...' : 'Delete'}
>
)}
)}
>
)}
);
}