diff --git a/app/components/Models.tsx b/app/components/Models.tsx index 15b3bc8..7647753 100644 --- a/app/components/Models.tsx +++ b/app/components/Models.tsx @@ -1,104 +1,148 @@ import React, { useState, useEffect } from 'react'; // Define the available model options -const modelDropdown = { - offlineModels: [ - 'Offline Fast', - 'Offline Fast (FOSS)', - 'Offline Slow', - 'Offline Slow (FOSS)', - ], +const offlineModels = [ + 'Offline Fast', + 'Offline Fast (FOSS)', + 'Offline Slow', + 'Offline Slow (FOSS)', +]; - onlineModels: [ - 'Online (La Plateforme)', - 'Online (FOSS) (La Plateforme)', - 'Online Cheap (OpenAI)', - 'Online Expensive (OpenAI)', - 'Online Cheap (Anthropic)', - 'Online Expensive (Anthropic)', - 'Online Cheap (Google)', - 'Online Expensive (Google)', - ], +const onlineModels = [ + 'Online (La Plateforme)', + 'Online (FOSS) (La Plateforme)', + 'Online Cheap (OpenAI)', + 'Online Expensive (OpenAI)', + 'Online Cheap (Anthropic)', + 'Online Expensive (Anthropic)', + 'Online Cheap (Google)', + 'Online Expensive (Google)', +]; - fossModels: [ - 'Offline Fast (FOSS)', - 'Offline Slow (FOSS)', - 'Online (FOSS) (La Plateforme)', - ], -}; +const fossModels = [ + 'Offline Fast (FOSS)', + 'Offline Slow (FOSS)', + 'Online (FOSS) (La Plateforme)', +]; -const Models: React.FC = () => { - // Initialize state with value from localStorage or default to '' - const [radioSelection, setRadioSelection] = useState(() => localStorage.getItem('radioSelection') || ''); +// Define the properties passed to the Models component +interface ModelsProps { + selectedOption: string; // Privacy setting: "Offline", "AI Online", "None" +} - useEffect(() => { - const handleStorageChange = () => { - setRadioSelection(localStorage.getItem('radioSelection') || ''); - }; - - // Update dropdown immediately when localStorage changes internally or externally - window.addEventListener('storage', handleStorageChange); - - // Cleanup listener on component unmount - return () => { - window.removeEventListener('storage', handleStorageChange); - }; - }, []); +const Models: React.FC<ModelsProps> = ({ selectedOption }) => { + const [selectedModel, setSelectedModel] = useState<string>(() => { + return localStorage.getItem('selectedModel') || 'Offline Fast'; + }); const handleModelChange = (event: React.ChangeEvent<HTMLSelectElement>) => { const newModel = event.target.value; - setRadioSelection(newModel); - localStorage.setItem('radioSelection', newModel); // Update localStorage directly + setSelectedModel(newModel); }; - // Determine the filtered models based on current radioSelection + const isOfflineModel = (model: string) => offlineModels.includes(model); + const isOnlineModel = (model: string) => onlineModels.includes(model); + const isFossModel = (model: string) => fossModels.includes(model); + + useEffect(() => { + localStorage.setItem('selectedModel', selectedModel); + }, [selectedModel]); + const filteredModels = (() => { - switch (radioSelection) { + switch (selectedOption) { case 'Offline': - return modelDropdown.offlineModels; // Show only offline models + return offlineModels; // Show only offline models case 'AI Online': - return modelDropdown.onlineModels; // Show only online models - case 'FOSS': - return modelDropdown.fossModels; // Show only FOSS models + return onlineModels; // Show only online models default: - return [...modelDropdown.offlineModels, ...modelDropdown.onlineModels, ...modelDropdown.fossModels]; // Show all models if nothing matches + return [...offlineModels, ...onlineModels]; // Show all models } })(); - const isOfflineModel = (model: string) => modelDropdown.offlineModels.includes(model); - return ( <div className="model-background"> - <div className="models"> - <div className="title"> - <h3>Different AI Models</h3> - </div> + <div className="models"> + <div className="title"> + <h3>Different AI models</h3> + </div> - {/* Model Selection Dropdown */} - <div className="model-dropdown"> - <label htmlFor="model-select">Select AI Model:</label> - <select id="model-select" value={radioSelection} onChange={handleModelChange}> - {filteredModels.map((model) => ( - <option key={model} value={model}> - {model} - </option> - ))} - </select> - </div> + {/* Model Selection Dropdown */} + <div className="model-dropdown"> + <label htmlFor="model-select">Select AI Model:</label> + <select id="model-select" value={selectedModel} onChange={handleModelChange}> + {filteredModels.map((model) => ( + <option key={model} value={model}> + {model} + </option> + ))} + </select> + </div> - {/* Model Grid with Cards */} - <div className="grid"> - {['Code', 'Math', 'Language', 'Character', 'Finance', 'Weather', 'Time', 'Image', 'Custom1', 'Custom2'].map((category) => ( - <button key={category} className={`${category.toLowerCase()}-model model-box`}> + {/* Model Grid with Cards */} + <div className="grid"> + <button className="code-model model-box"> <div className="overlay"> - <h3>{category}</h3> - {isOfflineModel(radioSelection) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + <h3>Code</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} </div> </button> - ))} + <button className="math-model model-box"> + <div className="overlay"> + <h3>Math</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="language-model model-box"> + <div className="overlay"> + <h3>Language</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="character-model model-box"> + <div className="overlay"> + <h3>Character</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="financial-model model-box"> + <div className="overlay"> + <h3>Finance</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="weather-model model-box"> + <div className="overlay"> + <h3>Weather</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="time-planner-model model-box"> + <div className="overlay"> + <h3>Time</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="image-model model-box"> + <div className="overlay"> + <h3>Image</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="default-model model-box"> + <div className="overlay"> + <h3>Custom1</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + <button className="default-model model-box"> + <div className="overlay"> + <h3>Custom2</h3> + {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} + </div> + </button> + </div> </div> </div> - </div> ); }; diff --git a/app/components/Settings.tsx b/app/components/Settings.tsx index 3a86df3..631a19e 100644 --- a/app/components/Settings.tsx +++ b/app/components/Settings.tsx @@ -398,36 +398,30 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( return ( <div className="settings-section"> <h2>Privacy Settings</h2> + {/* AI Mode Radio Options */} <div className="settings-option"> <p>Disable Options:</p> <div className="slider"> <div - className={`slider-option ${selectedOption === 'Offline' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} - onClick={() => !openSourceMode && handleRadioChange('Offline')} // Handle selection only if not in open source mode + className={`slider-option ${selectedOption === 'Offline' ? 'active' : ''}`} + onClick={() => handleRadioChange('Offline')} // Handle selection > Offline tools </div> <div - className={`slider-option ${selectedOption === 'AI Online' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} - onClick={() => !openSourceMode && handleRadioChange('AI Online')} + className={`slider-option ${selectedOption === 'AI Online' ? 'active' : ''}`} + onClick={() => handleRadioChange('AI Online')} > Online tools </div> <div - className={`slider-option ${selectedOption === 'None' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} - onClick={() => !openSourceMode && handleRadioChange('None')} + className={`slider-option ${selectedOption === 'None' ? 'active' : ''}`} + onClick={() => handleRadioChange('None')} > None </div> </div> - <br /> - {openSourceMode && ( - <p style={{ color: 'grey' }}>These options are deactivated because you are in FOSS mode.</p> - )} - <p> - After changing the preferred settings, please reload the website so it can update itself properly. - </p> </div> {/* Disable Chat History Checkbox */} @@ -456,7 +450,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( </div> ); - case 'theme': return ( <div className="settings-section"> @@ -785,34 +778,22 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( ); - case 'foss': - return ( - <div className="settings-section"> - <h2>Open Source Settings</h2> - <div className="settings-option"> - <label> - <input - type="checkbox" - checked={openSourceMode} - onChange={() => { - const newValue = !openSourceMode; - setOpenSourceMode(newValue); - // Update radio selection based on the new openSourceMode value - if (newValue) { - setSelectedOption('FOSS'); // Set to FOSS if enabling open source mode - localStorage.setItem('radioSelection', 'FOSS'); // Update localStorage - } else { - setSelectedOption('None'); // Or any other default value when disabling - localStorage.setItem('radioSelection', 'None'); // Update localStorage - } - }} - /> - Enable Open Source Mode - </label> - </div> - </div> - ); - + case 'foss': + return ( + <div className="settings-section"> + <h2>Open Source Settings</h2> + <div className="settings-option"> + <label> + <input + type="checkbox" + checked={openSourceMode} + onChange={() => setOpenSourceMode(!openSourceMode)} + /> + Enable Open Source Mode + </label> + </div> + </div> + ); case 'account': return ( diff --git a/app/styles/Settings.css b/app/styles/Settings.css index 89c9ea7..b840248 100644 --- a/app/styles/Settings.css +++ b/app/styles/Settings.css @@ -183,10 +183,5 @@ input[type="radio"] { display: none; /* Hide the default radio buttons */ -} - -.slider-option.disabled { - opacity: 0.5; /* Make the option appear greyed out */ - pointer-events: none; /* Prevent clicks */ -} + } \ No newline at end of file diff --git a/app/styles/history.css b/app/styles/history.css index 7bc9bcd..83e5271 100644 --- a/app/styles/history.css +++ b/app/styles/history.css @@ -1,7 +1,7 @@ .history-background { grid-column: 1/2; grid-row: 1/2; - height: 40vh; + height: 45vh; overflow: hidden; background-color: var(--history-background-color); padding: 1em; diff --git a/app/styles/models.css b/app/styles/models.css index 0706c93..e2d01ec 100644 --- a/app/styles/models.css +++ b/app/styles/models.css @@ -1,20 +1,19 @@ .model-background { - grid-column: 1/2; - grid-row: 1/2; - height: 45vh; - overflow: hidden; - background-color: var(--history-background-color); - padding: 1em; - margin: 1em; - margin-right: 0; + grid-column: 1 / 2; + grid-row: 2 / 5; + overflow-y: scroll; + background-color: var(--models-background-color); /* Ensure this variable is defined */ border-radius: 2em; + padding: 1em; + margin-left: 1em; + height: 40vh; + box-sizing: border-box; } .models { display: flex; flex-direction: column; height: 100%; - overflow-y: scroll; } .models .titel { @@ -48,7 +47,7 @@ justify-content: center; color: var(--text-color); /* Use variable for text color */ border-radius: 5%; - overflow: scroll; + overflow: hidden; position: relative; height: 18vh; width: 18vh; @@ -117,7 +116,7 @@ background-position: center; } -.finance-model { +.financial-model { background-image: url(/img/financial.jpg); background-color: #72cce4; background-repeat: no-repeat; @@ -133,7 +132,7 @@ background-position: center; } -.time-model { +.time-planner-model { background-image: url(/img/time.jpg); background-color: #72cce4; background-repeat: no-repeat; @@ -149,8 +148,7 @@ background-position: center; } -.custom1-model, -.custom2-model { +.default-model { background-image: url(/img/default.jpg); background-repeat: no-repeat; background-size: cover;