import { useState, useEffect } from "react"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { useSettings } from "@/hooks/useSettings"; import { showError, showSuccess } from "@/lib/toast"; import { IpcClient } from "@/ipc/ipc_client"; import { FolderOpen, RotateCcw, CheckCircle, AlertCircle } from "lucide-react"; export function NodePathSelector() { const { settings, updateSettings } = useSettings(); const [isSelectingPath, setIsSelectingPath] = useState(false); const [nodeStatus, setNodeStatus] = useState<{ version: string | null; isValid: boolean; }>({ version: null, isValid: false, }); const [isCheckingNode, setIsCheckingNode] = useState(false); const [systemPath, setSystemPath] = useState("Loading..."); // Check Node.js status when component mounts or path changes useEffect(() => { checkNodeStatus(); }, [settings?.customNodePath]); const fetchSystemPath = async () => { try { const debugInfo = await IpcClient.getInstance().getSystemDebugInfo(); setSystemPath(debugInfo.nodePath || "System PATH (not available)"); } catch (err) { console.error("Failed to fetch system path:", err); setSystemPath("System PATH (not available)"); } }; useEffect(() => { // Fetch system path on mount fetchSystemPath(); }, []); const checkNodeStatus = async () => { if (!settings) return; setIsCheckingNode(true); try { const status = await IpcClient.getInstance().getNodejsStatus(); setNodeStatus({ version: status.nodeVersion, isValid: !!status.nodeVersion, }); } catch (error) { console.error("Failed to check Node.js status:", error); setNodeStatus({ version: null, isValid: false }); } finally { setIsCheckingNode(false); } }; const handleSelectNodePath = async () => { setIsSelectingPath(true); try { // Call the IPC method to select folder const result = await IpcClient.getInstance().selectNodeFolder(); if (result.path) { // Save the custom path to settings await updateSettings({ customNodePath: result.path }); // Update the environment PATH await IpcClient.getInstance().reloadEnvPath(); // Recheck Node.js status await checkNodeStatus(); showSuccess("Node.js path updated successfully"); } else if (result.path === null && result.canceled === false) { showError( `Could not find Node.js at the path "${result.selectedPath}"`, ); } } catch (error: any) { showError(`Failed to set Node.js path: ${error.message}`); } finally { setIsSelectingPath(false); } }; const handleResetToDefault = async () => { try { // Clear the custom path await updateSettings({ customNodePath: null }); // Reload environment to use system PATH await IpcClient.getInstance().reloadEnvPath(); // Recheck Node.js status await fetchSystemPath(); await checkNodeStatus(); showSuccess("Reset to system Node.js path"); } catch (error: any) { showError(`Failed to reset Node.js path: ${error.message}`); } }; if (!settings) { return null; } const currentPath = settings.customNodePath || systemPath; const isCustomPath = !!settings.customNodePath; return (
{isCustomPath && ( )}
{isCustomPath ? "Custom Path:" : "System PATH:"} {isCustomPath && ( Custom )}

{currentPath}

{/* Status Indicator */}
{isCheckingNode ? (
) : nodeStatus.isValid ? (
{nodeStatus.version}
) : (
Not found
)}
{/* Help Text */}
{nodeStatus.isValid ? (

Node.js is properly configured and ready to use.

) : ( <>

Select the folder where Node.js is installed if it's not in your system PATH.

)}
); }