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