seekr / frontend /src /Components /IntialSetting.js
Hemang Thakur
a lot of changes
85a4a41
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 './IntialSetting.css';
import { FaTimes, FaEye, FaEyeSlash } from 'react-icons/fa';
function IntialSetting(props) {
// State variables for form controls
const [selectedProvider, setSelectedProvider] = useState("OpenAI");
const [modelTemperature, setModelTemperature] = useState(0.0);
const [modelTopP, setModelTopP] = useState(1.0);
const [showPassword, setShowPassword] = useState(false);
// Ref for the form and navigation hook
const formRef = useRef(null);
const navigate = useNavigate();
// Model options for different providers
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 form and state variables
const handleReset = (e) => {
e.preventDefault();
if (formRef.current) {
formRef.current.reset();
}
setSelectedProvider("OpenAI");
setModelTemperature(0.0);
setModelTopP(1.0);
};
// Handle form submission and save settings
const handleSave = async (e) => {
e.preventDefault();
const form = formRef.current;
// Retrieve form values
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;
// Check for missing required fields
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 (missingFields.length > 0) {
props.openSnackbar(
"Please fill in the following required fields: " + missingFields.join(", "),
"error"
);
return;
}
// Build payload for backend
const payload = {
"Model_Provider": modelProvider.toLowerCase(),
"Model_Name": modelName,
"Model_API_Keys": modelAPIKeys,
"Brave_Search_API_Key": braveAPIKey,
"Model_Temperature": modelTemperature,
"Model_Top_P": modelTopP,
};
if (proxyList && proxyList.trim() !== "") {
payload["Proxy_List"] = proxyList;
}
// Show appropriate notification based on context
if (props.fromAiPage) {
props.openSnackbar(
<Box mt={1} display="flex" alignItems="center">
<Box className="re-applying-settings-custom-spinner" />
<Box ml={1} className="re-applying-settings-text">
<span>Re-applying settings. This may take a few minutes...</span>
</Box>
</Box>,
"info"
);
} else {
props.openSnackbar("Settings saved successfully!", "success");
if (props.onInitializationStart) {
props.onInitializationStart();
}
}
// Send settings to 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();
if (data.success === true) {
if (props.fromAiPage) {
props.openSnackbar("Settings saved successfully!", "success");
}
navigate("/AiPage");
} else {
props.openSnackbar("Error saving settings. Please try again.", "error");
}
} else {
props.openSnackbar("Error saving settings. Please try again.", "error");
}
} catch (error) {
console.error("Error saving settings:", error);
props.openSnackbar("Error saving settings. Please try again.", "error");
}
};
// Render the settings modal
return props.trigger ? (
<div className="showSetting" onClick={() => props.setTrigger(false)}>
<div className="showSetting-inner" onClick={(e) => e.stopPropagation()}>
<label className="setting-size">Settings</label>
<button className="close-btn" onClick={() => props.setTrigger(false)}>
<FaTimes />
</button>
<form ref={formRef}>
<div className="form-group">
<label htmlFor="model-provider">Model Provider</label>
<select
id="model-provider"
name="model-provider"
value={selectedProvider}
onChange={(e) => setSelectedProvider(e.target.value)}
>
{Object.keys(modelOptions).map(provider => (
<option key={provider} value={provider}>
{provider}
</option>
))}
</select>
</div>
<div className="form-group">
<label htmlFor="model-name">Model Name</label>
<select id="model-name" name="model-name">
{Object.entries(modelOptions[selectedProvider]).map(
([displayName, backendName]) => (
<option key={backendName} value={backendName}>
{displayName}
</option>
)
)}
</select>
</div>
<div className="form-group">
<label htmlFor="model-api">Model API Key</label>
<textarea
id="model-api"
name="model-api"
placeholder="Enter API Key, one per line"
></textarea>
</div>
<div className="form-group">
<label htmlFor="brave-api">Brave Search API Key</label>
<input
type="text"
id="brave-api"
name="brave-api"
placeholder="Enter API Key"
/>
</div>
<div className="form-group">
<label htmlFor="proxy-list">Proxy List</label>
<textarea
id="proxy-list"
name="proxy-list"
placeholder="Enter proxies, one per line"
></textarea>
</div>
{/* Commented Neo4j configuration fields */}
{/* <div className="form-group">
<label htmlFor="neo4j-url">Neo4j URL</label>
<input
type="text"
id="neo4j-url"
name="neo4j-url"
placeholder="Enter Neo4j URL"
/>
</div>
<div className="form-group">
<label htmlFor="neo4j-username">Neo4j Username</label>
<input
type="text"
id="neo4j-username"
name="neo4j-username"
placeholder="Enter Username"
/>
</div>
<div className="form-group">
<label htmlFor="neo4j-password">Neo4j Password</label>
<div className="password-wrapper">
<input
type={showPassword ? "text" : "password"}
id="neo4j-password"
name="neo4j-password"
placeholder="Enter Password"
/>
<IconButton
onClick={() => setShowPassword(prev => !prev)}
className="password-toggle"
sx={{
color: "white",
p: 0,
m: 0
}}
>
{showPassword ? <FaEyeSlash /> : <FaEye />}
</IconButton>
</div>
</div> */}
<div className="form-group">
<div className="sliders-container">
<div className="slider-item">
<label htmlFor="temperature">Temperature</label>
<Slider
id="temperature"
value={modelTemperature}
onChange={(e, newValue) => setModelTemperature(newValue)}
step={0.05}
min={0.0}
max={1.0}
valueLabelDisplay="auto"
sx={{ width: '100%', color: 'success.main' }}
/>
</div>
<div className="slider-item">
<label htmlFor="top-p">Top-P</label>
<Slider
id="top-p"
value={modelTopP}
onChange={(e, newValue) => setModelTopP(newValue)}
step={0.05}
min={0.0}
max={1.0}
valueLabelDisplay="auto"
sx={{ width: '100%', color: 'success.main' }}
/>
</div>
</div>
</div>
<Stack direction="row" spacing={2} sx={{ justifyContent: 'flex-end' }}>
<Button
type="button"
className="reset-btn"
sx={{ color: "#2196f3" }}
onClick={handleReset}
>
Reset
</Button>
<Button
type="button"
variant="contained"
color="success"
className="save-btn"
onClick={handleSave}
>
Save
</Button>
</Stack>
</form>
{props.children}
</div>
</div>
) : null;
}
export default IntialSetting;