import React, { useState, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import Box from '@mui/material/Box'; import Slider from '@mui/material/Slider'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import IconButton from '@mui/material/IconButton'; import Snackbar from '@mui/material/Snackbar'; import Alert from '@mui/material/Alert'; import './IntialSetting.css'; import { FaTimes, FaEye, FaEyeSlash } from 'react-icons/fa'; function IntialSetting(props) { // Controlled states for Model Provider and sliders const [selectedProvider, setSelectedProvider] = useState("OpenAI"); const [modelTemperature, setModelTemperature] = useState(0.0); const [modelTopP, setModelTopP] = useState(1.0); const [showPassword, setShowPassword] = useState(false); // Snackbar state for notifications const [snackbar, setSnackbar] = useState({ open: false, message: "", severity: "success", // "success", "error", "info", "warning" }); // Ref for the form element const formRef = useRef(null); // React Router hook to navigate programmatically const navigate = useNavigate(); // Define model options const modelOptions = { OpenAI: { "GPT-4 Turbo": "gpt-4-turbo", "GPT-4o": "gpt-4o", "GPT-4o Latest": "gpt-4o-2024-11-20", "GPT-4o Mini": "gpt-4o-mini", "ChatGPT": "chatgpt-4o-latest", }, Anthropic: { "Claude 3.5 Sonnet": "claude-3-5-sonnet-20241022", "Claude 3.5 Haiku": "claude-3-5-haiku-20241022", "Claude 3 Opus": "claude-3-opus-20240229", "Claude 3 Sonnet": "claude-3-sonnet-20240229", "Claude 3 Haiku": "claude-3-haiku-20240307", }, Google: { "Gemini 1.5 Pro": "gemini-1.5-pro", "Gemini 1.5 Flash": "gemini-1.5-flash", "Gemini 2.0 Flash Lite": "gemini-2.0-flash-lite-preview-02-05", "Gemini 2.0 Flash Experimental": "gemini-2.0-flash-exp", "Gemini 2.0 Flash": "gemini-2.0-flash", "Gemini 2.0 Pro Experimental": "gemini-2.0-pro-exp-02-05", }, XAI: { "Grok-2": "grok-2-latest", "Grok Beta": "grok-beta", }, }; // Reset handler: resets both the form (uncontrolled fields) and controlled states const handleReset = (e) => { e.preventDefault(); if (formRef.current) { formRef.current.reset(); } setSelectedProvider("OpenAI"); setModelTemperature(0.0); setModelTopP(1.0); }; // Snackbar close handler const handleSnackbarClose = (event, reason) => { if (reason === 'clickaway') return; setSnackbar((prev) => ({ ...prev, open: false })); }; // Save handler: validates the form, shows notifications, calls the parent's callback // to update the underlying page (spinner/initializing text), sends the API request, and // navigates to /AiPage when the backend returns success. const handleSave = async (e) => { e.preventDefault(); const form = formRef.current; // Retrieve values from form fields using their name attribute const modelProvider = form.elements["model-provider"].value; const modelName = form.elements["model-name"].value; const modelAPIKeys = form.elements["model-api"].value; const braveAPIKey = form.elements["brave-api"].value; const proxyList = form.elements["proxy-list"].value; // const neo4jURL = form.elements["neo4j-url"].value; // const neo4jUsername = form.elements["neo4j-username"].value; // const neo4jPassword = form.elements["neo4j-password"].value; // Validate required fields and collect missing field names const missingFields = []; if (!modelProvider || modelProvider.trim() === "") missingFields.push("Model Provider"); if (!modelName || modelName.trim() === "") missingFields.push("Model Name"); if (!modelAPIKeys || modelAPIKeys.trim() === "") missingFields.push("Model API Key"); if (!braveAPIKey || braveAPIKey.trim() === "") missingFields.push("Brave Search API Key"); // if (!neo4jURL || neo4jURL.trim() === "") missingFields.push("Neo4j URL"); // if (!neo4jUsername || neo4jUsername.trim() === "") missingFields.push("Neo4j Username"); // if (!neo4jPassword || neo4jPassword.trim() === "") missingFields.push("Neo4j Password"); // If any required fields are missing, show an error notification if (missingFields.length > 0) { setSnackbar({ open: true, message: "Please fill in the following required fields: " + missingFields.join(", "), severity: "error", }); return; } // Build the JSON payload const payload = { "Model_Provider": modelProvider.toLowerCase(), "Model_Name": modelName, "Model_API_Keys": modelAPIKeys, "Brave_Search_API_Key": braveAPIKey, // "Neo4j_URL": neo4jURL, // "Neo4j_Username": neo4jUsername, // "Neo4j_Password": neo4jPassword, "Model_Temperature": modelTemperature, "Model_Top_P": modelTopP, }; // Include Proxy List if provided if (proxyList && proxyList.trim() !== "") { payload["Proxy_List"] = proxyList; } // If opened from AiPage, show "Re-applying settings..." info notification with spinner if (props.fromAiPage) { setSnackbar({ open: true, message: ( Re-applying settings. This may take a few minutes... ), severity: "info", }); } else { // Original immediate success notification if opened from Home/App setSnackbar({ open: true, message: "Settings saved successfully!", severity: "success", }); // Call the parent's callback to change the underlying page's content (spinner/text) if (props.onInitializationStart) { props.onInitializationStart(); } } // Send the payload to the backend try { const response = await fetch("/settings", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(payload), }); if (response.ok) { const data = await response.json(); // When the backend returns {"success": true}, navigate to /AiPage if (data.success === true) { // If from AiPage, show the final "Settings saved successfully!" success notification if (props.fromAiPage) { setSnackbar({ open: true, message: "Settings saved successfully!", severity: "success", }); } navigate("/AiPage"); } else { // If the response is OK but success is not true setSnackbar({ open: true, message: "Error saving settings. Please try again.", severity: "error", }); } } else { // If response is not OK, display error notification setSnackbar({ open: true, message: "Error saving settings. Please try again.", severity: "error", }); } } catch (error) { console.error("Error saving settings:", error); // Show error notification setSnackbar({ open: true, message: "Error saving settings. Please try again.", severity: "error", }); } }; return props.trigger ? (
props.setTrigger(false)}>
e.stopPropagation()}>
{/* Model Provider Selection */}
{/* Model Name Selection */}
{/* API Key Inputs */}
{/* Proxy List */}
{/* Neo4j Configuration */} {/*
setShowPassword(prev => !prev)} className="password-toggle" sx={{ color: "white", // Change the color of the icon p: 0, // Remove internal padding m: 0 // Remove any margin }} > {showPassword ? : }
*/} {/* Model Temperature and Top-P */}
setModelTemperature(newValue)} step={0.05} min={0.0} max={1.0} valueLabelDisplay="auto" sx={{ width: '100%', color: 'success.main' }} />
setModelTopP(newValue)} step={0.05} min={0.0} max={1.0} valueLabelDisplay="auto" sx={{ width: '100%', color: 'success.main' }} />
{/* Buttons */}
{/* Notifications */} {snackbar.message} {props.children}
) : null; } export default IntialSetting;