Settings updates #53
					 5 changed files with 136 additions and 154 deletions
				
			
		|  | @ -1,148 +1,104 @@ | |||
| import React, { useState, useEffect } from 'react'; | ||||
| 
 | ||||
| // Define the available model options
 | ||||
| const offlineModels = [ | ||||
|   'Offline Fast', | ||||
|   'Offline Fast (FOSS)', | ||||
|   'Offline Slow', | ||||
|   'Offline Slow (FOSS)', | ||||
| ]; | ||||
| const modelDropdown = { | ||||
|   offlineModels: [ | ||||
|     'Offline Fast', | ||||
|     'Offline Fast (FOSS)', | ||||
|     'Offline Slow', | ||||
|     'Offline Slow (FOSS)', | ||||
|   ], | ||||
| 
 | ||||
| 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)', | ||||
| ]; | ||||
|   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 fossModels = [ | ||||
|   'Offline Fast (FOSS)', | ||||
|   'Offline Slow (FOSS)', | ||||
|   'Online (FOSS) (La Plateforme)', | ||||
| ]; | ||||
|   fossModels: [ | ||||
|     'Offline Fast (FOSS)', | ||||
|     'Offline Slow (FOSS)', | ||||
|     'Online (FOSS) (La Plateforme)', | ||||
|   ], | ||||
| }; | ||||
| 
 | ||||
| // Define the properties passed to the Models component
 | ||||
| interface ModelsProps { | ||||
|   selectedOption: string;  // Privacy setting: "Offline", "AI Online", "None"
 | ||||
| } | ||||
| const Models: React.FC = () => { | ||||
|   // Initialize state with value from localStorage or default to ''
 | ||||
|   const [radioSelection, setRadioSelection] = useState(() => localStorage.getItem('radioSelection') || ''); | ||||
| 
 | ||||
| const Models: React.FC<ModelsProps> = ({ selectedOption }) => { | ||||
|   const [selectedModel, setSelectedModel] = useState<string>(() => { | ||||
|     return localStorage.getItem('selectedModel') || 'Offline Fast'; | ||||
|   }); | ||||
|   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 handleModelChange = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||||
|     const newModel = event.target.value; | ||||
|     setSelectedModel(newModel); | ||||
|     setRadioSelection(newModel); | ||||
|     localStorage.setItem('radioSelection', newModel); // Update localStorage directly
 | ||||
|   }; | ||||
| 
 | ||||
|   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]); | ||||
| 
 | ||||
|   // Determine the filtered models based on current radioSelection
 | ||||
|   const filteredModels = (() => { | ||||
|     switch (selectedOption) { | ||||
|     switch (radioSelection) { | ||||
|       case 'Offline': | ||||
|         return offlineModels; // Show only offline models
 | ||||
|         return modelDropdown.offlineModels; // Show only offline models
 | ||||
|       case 'AI Online': | ||||
|         return onlineModels; // Show only online models
 | ||||
|         return modelDropdown.onlineModels; // Show only online models
 | ||||
|       case 'FOSS': | ||||
|         return modelDropdown.fossModels; // Show only FOSS models
 | ||||
|       default: | ||||
|         return [...offlineModels, ...onlineModels]; // Show all models
 | ||||
|         return [...modelDropdown.offlineModels, ...modelDropdown.onlineModels, ...modelDropdown.fossModels]; // Show all models if nothing matches
 | ||||
|     } | ||||
|   })(); | ||||
| 
 | ||||
|   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={selectedModel} 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={radioSelection} onChange={handleModelChange}> | ||||
|           {filteredModels.map((model) => ( | ||||
|             <option key={model} value={model}> | ||||
|               {model} | ||||
|             </option> | ||||
|           ))} | ||||
|         </select> | ||||
|       </div> | ||||
| 
 | ||||
|         {/* Model Grid with Cards */} | ||||
|         <div className="grid"> | ||||
|           <button className="code-model model-box"> | ||||
|       {/* 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`}> | ||||
|             <div className="overlay"> | ||||
|               <h3>Code</h3> | ||||
|               {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} | ||||
|               <h3>{category}</h3> | ||||
|               {isOfflineModel(radioSelection) && <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>  | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -398,30 +398,36 @@ 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' : ''}`} | ||||
|                   onClick={() => handleRadioChange('Offline')} // Handle selection
 | ||||
|                   className={`slider-option ${selectedOption === 'Offline' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} | ||||
|                   onClick={() => !openSourceMode && handleRadioChange('Offline')} // Handle selection only if not in open source mode
 | ||||
|                 > | ||||
|                   Offline tools | ||||
|                 </div> | ||||
|                 <div | ||||
|                   className={`slider-option ${selectedOption === 'AI Online' ? 'active' : ''}`} | ||||
|                   onClick={() => handleRadioChange('AI Online')} | ||||
|                   className={`slider-option ${selectedOption === 'AI Online' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} | ||||
|                   onClick={() => !openSourceMode && handleRadioChange('AI Online')} | ||||
|                 > | ||||
|                   Online tools | ||||
|                 </div> | ||||
|                 <div | ||||
|                   className={`slider-option ${selectedOption === 'None' ? 'active' : ''}`} | ||||
|                   onClick={() => handleRadioChange('None')} | ||||
|                   className={`slider-option ${selectedOption === 'None' ? 'active' : ''} ${openSourceMode ? 'disabled' : ''}`} | ||||
|                   onClick={() => !openSourceMode && 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 */} | ||||
|  | @ -450,6 +456,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
|           </div> | ||||
|         ); | ||||
| 
 | ||||
| 
 | ||||
|         case 'theme': | ||||
|           return ( | ||||
|             <div className="settings-section"> | ||||
|  | @ -778,22 +785,34 @@ 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={() => setOpenSourceMode(!openSourceMode)} | ||||
|                 /> | ||||
|                 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={() => { | ||||
|                         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 'account': | ||||
|         return ( | ||||
|  |  | |||
|  | @ -183,5 +183,10 @@ | |||
|    | ||||
| 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 */ | ||||
| } | ||||
|    | ||||
|  | @ -1,7 +1,7 @@ | |||
| .history-background { | ||||
|     grid-column: 1/2; | ||||
|     grid-row: 1/2; | ||||
|     height: 45vh; | ||||
|     height: 40vh; | ||||
|     overflow: hidden; | ||||
|     background-color: var(--history-background-color); | ||||
|     padding: 1em; | ||||
|  |  | |||
|  | @ -1,19 +1,20 @@ | |||
| .model-background { | ||||
|     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; | ||||
|     grid-column: 1/2; | ||||
|     grid-row: 1/2; | ||||
|     height: 45vh; | ||||
|     overflow: hidden; | ||||
|     background-color: var(--history-background-color); | ||||
|     padding: 1em; | ||||
|     margin-left: 1em; | ||||
|     height: 40vh; | ||||
|     box-sizing: border-box; | ||||
|     margin: 1em; | ||||
|     margin-right: 0; | ||||
|     border-radius: 2em; | ||||
| } | ||||
| 
 | ||||
| .models { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     height: 100%; | ||||
|     overflow-y: scroll; | ||||
| } | ||||
| 
 | ||||
| .models .titel { | ||||
|  | @ -47,7 +48,7 @@ | |||
|     justify-content: center; | ||||
|     color: var(--text-color); /* Use variable for text color */ | ||||
|     border-radius: 5%; | ||||
|     overflow: hidden; | ||||
|     overflow: scroll; | ||||
|     position: relative; | ||||
|     height: 18vh; | ||||
|     width: 18vh; | ||||
|  | @ -116,7 +117,7 @@ | |||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| .financial-model { | ||||
| .finance-model { | ||||
|     background-image: url(/img/financial.jpg); | ||||
|     background-color: #72cce4; | ||||
|     background-repeat: no-repeat; | ||||
|  | @ -132,7 +133,7 @@ | |||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| .time-planner-model { | ||||
| .time-model { | ||||
|     background-image: url(/img/time.jpg); | ||||
|     background-color: #72cce4; | ||||
|     background-repeat: no-repeat; | ||||
|  | @ -148,7 +149,8 @@ | |||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| .default-model { | ||||
| .custom1-model, | ||||
| .custom2-model { | ||||
|     background-image: url(/img/default.jpg); | ||||
|     background-repeat: no-repeat; | ||||
|     background-size: cover; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue