forked from React-Group/interstellar_ai
		
	main #55
					 30 changed files with 445 additions and 500 deletions
				
			
		|  | @ -40,7 +40,8 @@ python3 api.py | |||
| ``` | ||||
| 3. In the main project folder, you will run: | ||||
| ``` | ||||
| npm run dev | ||||
| npm run build | ||||
| npm start | ||||
| npx electron . | ||||
| ``` | ||||
| 4. Open http://localhost:3000/ in your browser. | ||||
| 5. Enjoy! | ||||
| 4. Enjoy! | ||||
|  | @ -1,62 +1,24 @@ | |||
| import React from 'react'; | ||||
| 
 | ||||
| const Credits: React.FC = () => { | ||||
|   return ( | ||||
| const Credits: React.FC = () => ( | ||||
|   <div className="credits-container"> | ||||
|     <section id="credits" className="credits-section"> | ||||
|       <h1 className="title">Credits</h1> | ||||
| 
 | ||||
|       <h2 className="subtitle">Icons</h2> | ||||
|         <p className="paragraph"> | ||||
|           This project utilizes the following icon resources: | ||||
|         </p> | ||||
|         <a | ||||
|           href="https://fontawesome.com/v4/license/" | ||||
|           className="credit-btn" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           fontawesome | ||||
|         </a> | ||||
|       <p className="paragraph">This project utilizes the following icon resources:</p> | ||||
|       <CreditLink href="https://fontawesome.com/v4/license/" label="fontawesome" /> | ||||
|       <h2 className="subtitle">Fonts</h2> | ||||
|         <p className="paragraph"> | ||||
|           The fonts used in this project are provided by: | ||||
|         </p> | ||||
|         <a | ||||
|           href="https://github.com/itfoundry/Poppins" | ||||
|           className="credit-btn" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           Poppins | ||||
|         </a> | ||||
|         <a | ||||
|           href="https://openfontlicense.org" | ||||
|           className="credit-btn" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           Inconsolata, Merriweather, Noto Sans, Noto Serif, Playfair Display, Bangers, Caveat, Frederika the Great, Sofadi One, Zilla Slab Highlight | ||||
|         </a> | ||||
|         <a | ||||
|           href="http://www.apache.org/licenses/LICENSE-2.0" | ||||
|           className="credit-btn" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           Roboto, Rock Salt | ||||
|         </a> | ||||
|         <a | ||||
|           href="https://ubuntu.com/legal/font-licence" | ||||
|           className="credit-btn" | ||||
|           target="_blank" | ||||
|           rel="noopener noreferrer" | ||||
|         > | ||||
|           Ubuntu | ||||
|         </a> | ||||
|       <p className="paragraph">The fonts used in this project are provided by:</p> | ||||
|       <CreditLink href="https://github.com/itfoundry/Poppins" label="Poppins" /> | ||||
|       <CreditLink href="https://openfontlicense.org" label="Inconsolata, Merriweather, Noto Sans, Noto Serif, Playfair Display, Bangers, Caveat, Frederika the Great, Sofadi One, Zilla Slab Highlight" /> | ||||
|       <CreditLink href="http://www.apache.org/licenses/LICENSE-2.0" label="Roboto, Rock Salt" /> | ||||
|       <CreditLink href="https://ubuntu.com/legal/font-licence" label="Ubuntu" /> | ||||
|     </section> | ||||
|   </div> | ||||
|   ); | ||||
| }; | ||||
| ); | ||||
| 
 | ||||
| const CreditLink = ({ href, label }: { href: string; label: string }) => ( | ||||
|   <a href={href} className="credit-btn" target="_blank" rel="noopener noreferrer">{label}</a> | ||||
| ); | ||||
| 
 | ||||
| export default Credits; | ||||
|  |  | |||
|  | @ -20,13 +20,16 @@ const Header: React.FC<HeaderProps> = ({ | |||
|     const dropdownRef = useRef<HTMLDivElement | null>(null); | ||||
|     const toggleRef = useRef<HTMLDivElement | null>(null); | ||||
| 
 | ||||
|     // Pages that will be displayed in the menu
 | ||||
|     const pages: ('AI' | 'FAQ' | 'Documentation' | 'Credits')[] = ['AI', 'FAQ', 'Documentation', 'Credits']; | ||||
| 
 | ||||
|     // Toggle menu state
 | ||||
|     const toggleMenu = () => { | ||||
|         setMenuOpen((prevMenuOpen) => !prevMenuOpen); | ||||
|     }; | ||||
| 
 | ||||
|     // Handle button click
 | ||||
|     const buttonClicked = (page: "AI" | "Documentation" | "FAQ" | "Credits") => { | ||||
|     const handleViewChange = (page: 'AI' | 'FAQ' | 'Documentation' | 'Credits') => { | ||||
|         onViewChange(page); | ||||
|         setMenuOpen(false); // Close the menu when a button is clicked
 | ||||
|     }; | ||||
|  | @ -72,10 +75,11 @@ const Header: React.FC<HeaderProps> = ({ | |||
|                     </button> | ||||
|                 )} | ||||
|                 <nav ref={dropdownRef} className={`nav-links ${menuOpen ? "active" : ""}`}> | ||||
|                     <button onClick={() => buttonClicked("AI")} className="nav-btn">Chat</button> | ||||
|                     <button onClick={() => buttonClicked("FAQ")} className="nav-btn">FAQ</button> | ||||
|                     <button onClick={() => buttonClicked("Documentation")} className="nav-btn">Documentation</button> | ||||
|                     <button onClick={() => buttonClicked("Credits")} className="nav-btn">Credits</button> | ||||
|                     {pages.map(page => ( | ||||
|                         <button key={page} onClick={() => handleViewChange(page)} className="nav-btn"> | ||||
|                             {page} | ||||
|                         </button> | ||||
|                     ))} | ||||
|                 </nav> | ||||
|                 <div ref={toggleRef} className={`hamburger ${menuOpen ? "open" : ""}`} onClick={toggleMenu}> | ||||
|                     <span></span> | ||||
|  |  | |||
|  | @ -34,22 +34,29 @@ const History: React.FC = () => { | |||
|           {/* Populate with history items */} | ||||
|           {chatHistory.chats.map((chats, index) => ( | ||||
|             <li key={index}> | ||||
|               <a href="#" onClick={() => handleHistoryClick(index)}>{chatHistory.chats[index].name}</a> | ||||
|               <a href="#" onClick={() => handleHistoryClick(index)}> | ||||
|                 {chatHistory.chats[index].name} | ||||
|               </a> | ||||
|             </li> | ||||
|           ))} | ||||
|           <li> | ||||
|             {isEditing ? ( | ||||
|         <div> | ||||
|               <div className="input-container"> | ||||
|                 <input | ||||
|                   type="text" | ||||
|                   value={inputValue} | ||||
|                   onChange={handleInputChange} | ||||
|                   placeholder="Enter text" | ||||
|                   className="chat-input" | ||||
|                 /> | ||||
|           <button onClick={handleSaveButtonClick}>Save</button> | ||||
|                 <button onClick={handleSaveButtonClick} className="save-btn"> | ||||
|                   Save | ||||
|                 </button> | ||||
|               </div> | ||||
|             ) : ( | ||||
|         <button onClick={handleEditButtonClick}>{'New Chat'}</button> | ||||
|               <button onClick={handleEditButtonClick} className="newChat-btn"> | ||||
|                 New Chat | ||||
|               </button> | ||||
|             )} | ||||
|           </li> | ||||
|         </ul> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import React, { useState, ForwardedRef, useEffect } from 'react'; | ||||
| import "../styles/variables.css" | ||||
| import "../styles/variables.css"; | ||||
| 
 | ||||
| interface InputProps { | ||||
|   message: string; | ||||
|  | @ -13,33 +13,36 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | |||
|   ({ message, onSendClick, onMicClick, inputDisabled, isRecording }, ref: ForwardedRef<HTMLDivElement>) => { | ||||
|     const [inputValue, setInputValue] = useState(''); | ||||
| 
 | ||||
|     // Sync the inputValue state with the message prop
 | ||||
|     useEffect(() => { | ||||
|       setInputValue(message); | ||||
|     }, [message]); | ||||
| 
 | ||||
|     // Handle the input change
 | ||||
|     const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||||
|       setInputValue(e.target.value); | ||||
|     }; | ||||
| 
 | ||||
|     // Handle 'Enter' key press
 | ||||
|     const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { | ||||
|       if (!inputDisabled) { | ||||
|         if (event.key === 'Enter') { | ||||
|           onSendClick(inputValue, false); // Call the function passed via props
 | ||||
|           setInputValue(''); // Optionally clear input after submission
 | ||||
|           event.preventDefault(); // Prevent default action (e.g., form submission)
 | ||||
|         } | ||||
|       if (!inputDisabled && event.key === 'Enter') { | ||||
|         onSendClick(inputValue, false); // Send the message on Enter
 | ||||
|         setInputValue(''); // Clear the input after submission
 | ||||
|         event.preventDefault(); // Prevent the default Enter action
 | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     // Handle the Send button click
 | ||||
|     const handleSendClick = () => { | ||||
|       if (inputValue.trim() !== "") { | ||||
|         onSendClick(inputValue, false);  // Send message to parent component
 | ||||
|         onSendClick(inputValue, false);  // Send message
 | ||||
|         setInputValue('');               // Clear input after sending
 | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|       <div className="input" id="inputForm" ref={ref}> | ||||
|         {/* Input field for typing messages */} | ||||
|         <input | ||||
|           type="text" | ||||
|           name="user_message" | ||||
|  | @ -47,13 +50,22 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | |||
|           value={inputValue} | ||||
|           onChange={handleInputChange} | ||||
|           onKeyDown={handleKeyDown} | ||||
|           className='textInputField' | ||||
|           className="textInputField" | ||||
|           disabled={inputDisabled}  // Disable when inputDisabled is true
 | ||||
|         /> | ||||
|         <button type="button" onClick={handleSendClick} disabled={inputDisabled ? true : false}> | ||||
|           <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" width={20}><path d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480l0-83.6c0-4 1.5-7.8 4.2-10.8L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" /></svg> | ||||
| 
 | ||||
|         {/* Send button */} | ||||
|         <button type="button" onClick={handleSendClick} disabled={inputDisabled}> | ||||
|           <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 512 512" width={20}> | ||||
|             <path d="M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480l0-83.6c0-4 1.5-7.8 4.2-10.8L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" /> | ||||
|           </svg> | ||||
|         </button> | ||||
| 
 | ||||
|         {/* Microphone button */} | ||||
|         <button className={`microphone-button ${isRecording ? "red" : "var(--input-button-color)"}`} type="button" onClick={onMicClick}> | ||||
|           <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 384 512" width={15}><path d="M192 0C139 0 96 43 96 96l0 160c0 53 43 96 96 96s96-43 96-96l0-160c0-53-43-96-96-96zM64 216c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 89.1 66.2 162.7 152 174.4l0 33.6-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l72 0 72 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0 0-33.6c85.8-11.7 152-85.3 152-174.4l0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 70.7-57.3 128-128 128s-128-57.3-128-128l0-40z" /></svg> | ||||
|           <svg style={{ fill: "var(--text-color)" }} viewBox="0 0 384 512" width={15}> | ||||
|             <path d="M192 0C139 0 96 43 96 96l0 160c0 53 43 96 96 96s96-43 96-96l0-160c0-53-43-96-96-96zM64 216c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 89.1 66.2 162.7 152 174.4l0 33.6-48 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l72 0 72 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0 0-33.6c85.8-11.7 152-85.3 152-174.4l0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 70.7-57.3 128-128 128s-128-57.3-128-128l0-40z" /> | ||||
|           </svg> | ||||
|         </button> | ||||
|       </div> | ||||
|     ); | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import { | |||
|   getSettings | ||||
| } from '../backend/database'; | ||||
| import Settings from './settings/Settings'; // Import the Settings component
 | ||||
| import { importDatabase } from './settings/settingUtils'; | ||||
| 
 | ||||
| const Login: React.FC = () => { | ||||
|   // State to handle popup visibility
 | ||||
|  | @ -23,9 +24,9 @@ const Login: React.FC = () => { | |||
| 
 | ||||
|   // On component mount, check if there are credentials in localStorage
 | ||||
|   useEffect(() => { | ||||
|     let savedAccountName:string|null; | ||||
|     let savedAccountEmail:string|null; | ||||
|     let savedAccountPassword:string|null; | ||||
|     let savedAccountName: string | null; | ||||
|     let savedAccountEmail: string | null; | ||||
|     let savedAccountPassword: string | null; | ||||
|     if (typeof localStorage !== 'undefined') { | ||||
|       savedAccountName = localStorage.getItem('accountName'); | ||||
|       savedAccountEmail = localStorage.getItem('accountEmail'); | ||||
|  | @ -40,6 +41,14 @@ const Login: React.FC = () => { | |||
|           if (savedAccountName !== null && savedAccountPassword !== null) { | ||||
|             const success = await checkCredentials(savedAccountName, savedAccountPassword); | ||||
|             setIsLoggedIn(success); // Automatically log in
 | ||||
|             const useName = localStorage.getItem("accountName"); | ||||
|             const usePassword = localStorage.getItem("accountPassword"); | ||||
| 
 | ||||
|             if (useName && usePassword) { | ||||
|               await importDatabase(useName, usePassword); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|           } | ||||
|         }; | ||||
|         check(); | ||||
|  | @ -69,6 +78,14 @@ const Login: React.FC = () => { | |||
|           } | ||||
|         } | ||||
|         setShowLoginPopup(false); // Close the login popup
 | ||||
|         const useName = localStorage.getItem("accountName"); | ||||
|         const usePassword = localStorage.getItem("accountPassword"); | ||||
| 
 | ||||
|         if (useName && usePassword) { | ||||
|           await importDatabase(useName, usePassword); | ||||
|         } | ||||
| 
 | ||||
|         window.location.reload(); | ||||
|       } else { | ||||
|         alert('Incorrect credentials'); | ||||
|       } | ||||
|  |  | |||
|  | @ -123,50 +123,39 @@ const ModelSection: React.FC = () => { | |||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (typeof localStorage !== 'undefined') { | ||||
|       const defaultValues = { | ||||
|         selectedModelDropdown: 'Offline Fast', | ||||
|         activeSelectedAIFunction: 'Code', | ||||
|         model: 'starcoder2', | ||||
|         radioSelection: 'None', | ||||
|         type: 'local', | ||||
|       }; | ||||
|    | ||||
|       setIsOpenSourceMode(localStorage.getItem("openSourceMode")) | ||||
|       const temp = localStorage.getItem("activeSelectedAIFunction") || "" | ||||
|       setActiveSelectedAIFunction(temp) | ||||
|       if (!localStorage.getItem('selectedModelDropdown')) { | ||||
|         localStorage.setItem("selectedModelDropdown", "Offline Fast") | ||||
|       Object.entries(defaultValues).forEach(([key, value]) => { | ||||
|         if (!localStorage.getItem(key)) { | ||||
|           localStorage.setItem(key, value); | ||||
|         } | ||||
|       }); | ||||
|    | ||||
|       if (!localStorage.getItem("activeSelectedAIFunction")) { | ||||
|         setActiveSelectedAIFunction('Code') | ||||
|         localStorage.setItem('activeSelectedAIFunction', 'Code') | ||||
|       } | ||||
|        | ||||
|       if (!localStorage.getItem("model")) { | ||||
|         localStorage.setItem("model", 'starcoder2') | ||||
|       } | ||||
|        | ||||
|       if (!localStorage.getItem("radioSelection")) { | ||||
|         localStorage.setItem("radioSelection", 'None') | ||||
|       } | ||||
|        | ||||
|       if (!localStorage.getItem("type")) { | ||||
|         localStorage.setItem("type", 'local') | ||||
|       } | ||||
|       setIsOpenSourceMode(localStorage.getItem("openSourceMode")); | ||||
|       setActiveSelectedAIFunction(localStorage.getItem("activeSelectedAIFunction") || ''); | ||||
|       setRadioSelection(localStorage.getItem("radioSelection") || ''); | ||||
|       setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); | ||||
|    | ||||
|       const handleStorageChange = () => { | ||||
|         setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); | ||||
|       }; | ||||
|    | ||||
|       // Update immediately when localStorage changes
 | ||||
|       if (typeof window !== 'undefined') { | ||||
|       window.addEventListener('storage', handleStorageChange); | ||||
|       } | ||||
|        | ||||
|       setRadioSelection(localStorage.getItem('radioSelection') || ''); | ||||
|       setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); | ||||
|       // Cleanup listener on component unmount
 | ||||
|       return () => { | ||||
|         if (typeof window !== 'undefined') { | ||||
|         window.removeEventListener('storage', handleStorageChange); | ||||
|         } | ||||
|       }; | ||||
|     } | ||||
|   }, []); // Dependency array can remain empty if you only want this to run on mount
 | ||||
|   }, []); | ||||
|    | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (typeof localStorage !== 'undefined') { | ||||
|  | @ -271,7 +260,6 @@ const ModelSection: React.FC = () => { | |||
|             ))} | ||||
|           </select> | ||||
|         </div> | ||||
| 
 | ||||
|         {/* Model Grid with Cards */} | ||||
|         <div className="grid"> | ||||
|           {selectedAIFunction.map( | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| //#region imports
 | ||||
| import React, { useState, useEffect } from 'react'; | ||||
| import { applyTheme } from './theme'; | ||||
| import { exportSettings, importSettings } from './settingUtils'; // Import utility functions
 | ||||
| import { exportSettings, importSettings, sendToDatabase, importDatabase } from './settingUtils'; // Import utility functions
 | ||||
| import { getAllLocalStorageItems } from '../../backend/GetLocalStorage'; | ||||
| import ColorSetting from './ColorSettings'; | ||||
| import TextSettings from './TextSettings' | ||||
|  | @ -298,6 +298,13 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
|   }; | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const useName = localStorage.getItem("accountName"); | ||||
|     const usePassword = localStorage.getItem("accountPassword"); | ||||
| 
 | ||||
|     if (useName && usePassword) { | ||||
|       importDatabase(useName, usePassword); | ||||
|     } | ||||
| 
 | ||||
|     const savedTheme = localStorage.getItem('selectedTheme'); | ||||
|     if (savedTheme) { | ||||
|       setSelectedTheme(savedTheme); | ||||
|  | @ -714,7 +721,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
| 
 | ||||
|   const handleExport = () => { | ||||
|     const settingsData = exportSettings(); | ||||
| 
 | ||||
|     // Create a blob and download the exported settings
 | ||||
|     const blob = new Blob([settingsData], { type: 'application/json' }); | ||||
|     const url = URL.createObjectURL(blob); | ||||
|  | @ -732,6 +738,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
|     <div className="popup-overlay"> | ||||
|       <div className="settings-content"> | ||||
|         <div className="settings-container"> | ||||
|           {/* Sidebar for desktop */} | ||||
|           <div className="sidebar"> | ||||
|             <ul> | ||||
|               <li onClick={() => setActiveSection('general')}>General</li> | ||||
|  | @ -743,18 +750,32 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
|               <li onClick={() => setActiveSection('im/export')}>Import/Export</li> | ||||
|             </ul> | ||||
|           </div> | ||||
| 
 | ||||
|           <div className="settings-main"> | ||||
|             {/* Dropdown for selections in responsive mode */} | ||||
|             <div className="settings-option dropdown"> | ||||
|               <div className="dropdown-header"><h2>Select a Setting</h2></div> | ||||
|               <select onChange={(e) => setActiveSection(e.target.value)} value={activeSection}> | ||||
|                 <option value="general">General</option> | ||||
|                 <option value="privacy">Privacy</option> | ||||
|                 <option value="theme">Theme</option> | ||||
|                 <option value="foss">FOSS</option> | ||||
|                 <option value="account">Account</option> | ||||
|                 <option value="api">API Keys</option> | ||||
|                 <option value="im/export">Import/Export</option> | ||||
|               </select> | ||||
|             </div> | ||||
|             <h2>Settings for {accountName}</h2> | ||||
|             {renderSettingsContent()} | ||||
|             <button className="close-popup" onClick={closeSettings}>Close</button> | ||||
|             <button className="apply" onClick={async () => { | ||||
|               getAllLocalStorageItems(); | ||||
|               closeSettings(); | ||||
|               await changeSettings(localStorage.getItem('accountName') ?? "hello", localStorage.getItem('accountPassword') ?? "hello", settings) // ????
 | ||||
|               window.location.reload(); | ||||
|               sendToDatabase(); | ||||
|             }}> | ||||
|               Apply | ||||
|             </button> | ||||
| 
 | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | @ -762,4 +783,5 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | |||
|   ); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export default Settings; | ||||
|  | @ -1,4 +1,5 @@ | |||
| // settingsManager.ts
 | ||||
| import { changeSettings, getSettings } from "@/app/backend/database"; | ||||
| 
 | ||||
| // Method to export localStorage to a JSON object
 | ||||
| export function exportSettings(): string { | ||||
|  | @ -37,3 +38,27 @@ export function importSettings(jsonData: string): void { | |||
|         console.error("Invalid JSON data:", error); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export const sendToDatabase = async () => { | ||||
|     let useName = localStorage.getItem("accountName") | ||||
|     let usePassword = localStorage.getItem("accountPassword") | ||||
|     if (useName && usePassword) { | ||||
|         let result = await changeSettings(useName, usePassword, JSON.parse(exportSettings())) | ||||
|         if (result == true) { | ||||
|             alert('Data has been transferred') | ||||
|             window.location.reload(); | ||||
|         } | ||||
|     } | ||||
|     window.location.reload(); | ||||
| }; | ||||
| 
 | ||||
| export const importDatabase = async (useName: string, usePassword: string) => { | ||||
|     const databaseSettings = await getSettings(useName, usePassword); | ||||
| 
 | ||||
|     // Ensure user settings exist before flattening and storing
 | ||||
|     if (typeof databaseSettings == 'object' && databaseSettings) { | ||||
|         importSettings(JSON.stringify(databaseSettings, null, 2)); // Pass only the current user's settings
 | ||||
|     } else { | ||||
|         console.error('Database settings are not in the expected format.'); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| 
 | ||||
| /* Overlay for popup - full screen and centered */ | ||||
| .popup-overlay { | ||||
| .popup-overlay{ | ||||
|     position: fixed; /* Fixed to cover the entire viewport */ | ||||
|     top: 0;          /* Ensure it starts from the top */ | ||||
|     left: 0; | ||||
|  | @ -12,9 +10,7 @@ | |||
|     align-items: center; | ||||
|     z-index: 10000; /* Higher than the header to cover the screen */ | ||||
| } | ||||
| 
 | ||||
| /* Popup content box */ | ||||
| .popup-content { | ||||
| .popup-content{ | ||||
|     background-color: var(--popup-background-color); /* Use variable for background color */ | ||||
|     color: var(--popup-text-color); /* Use variable for text color */ | ||||
|     padding: 30px; | ||||
|  | @ -24,9 +20,7 @@ | |||
|     box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); | ||||
|     position: relative; /* For positioning the close button */ | ||||
| } | ||||
| 
 | ||||
| /* Input styles */ | ||||
| .popup-content input { | ||||
| .popup-content input{ | ||||
|     width: 100%; | ||||
|     padding: 10px; | ||||
|     margin: 10px 0; | ||||
|  | @ -35,14 +29,11 @@ | |||
|     font-size: 16px; | ||||
|     transition: border-color 0.3s; | ||||
| } | ||||
| 
 | ||||
| .popup-content input:focus { | ||||
| .popup-content input:focus{ | ||||
|     border-color: var(--input-button-color); | ||||
|     outline: none; /* Remove default outline */ | ||||
| } | ||||
| 
 | ||||
| /* Close button styles */ | ||||
| .close-popup { | ||||
| .close-popup{ | ||||
|     background: var(--close-button-color); /* Use variable for close button color */ | ||||
|     color: white; /* Use white for text color */ | ||||
|     border: none; | ||||
|  | @ -54,13 +45,10 @@ | |||
|     right: 10px; /* Distance from the right */ | ||||
|     transition: background 0.3s; | ||||
| } | ||||
| 
 | ||||
| .close-popup:hover { | ||||
| .close-popup:hover{ | ||||
|     background: darkred; /* Optional hover effect */ | ||||
| } | ||||
| 
 | ||||
| /* Log In button styles */ | ||||
| .log-into-account { | ||||
| .log-into-account{ | ||||
|     background: green; /* Use variable for login button color */ | ||||
|     color: white; | ||||
|     border: none; | ||||
|  | @ -69,13 +57,10 @@ | |||
|     cursor: pointer; | ||||
|     margin-top: 20px; | ||||
| } | ||||
| 
 | ||||
| /* Footer section for popups */ | ||||
| .popup-footer { | ||||
| .popup-footer{ | ||||
|     margin-top: 15px; | ||||
| } | ||||
| 
 | ||||
| .popup-footer button { | ||||
| .popup-footer button{ | ||||
|     margin-right: 10px; | ||||
|     padding: 8px 15px; | ||||
|     background-color: var(--input-button-color); | ||||
|  | @ -84,22 +69,17 @@ | |||
|     border-radius: 5px; | ||||
|     transition: background-color 0.3s; | ||||
| } | ||||
| 
 | ||||
| .popup-footer button:hover { | ||||
| .popup-footer button:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .popup-footer a { | ||||
| .popup-footer a{ | ||||
|     color: var(--user-message-color); | ||||
|     text-decoration: none; | ||||
| } | ||||
| 
 | ||||
| .popup-footer a:hover { | ||||
| .popup-footer a:hover{ | ||||
|     text-decoration: underline; | ||||
| } | ||||
| 
 | ||||
| /* Paragraph styles within popup */ | ||||
| .popup-content p { | ||||
| .popup-content p{ | ||||
|     color: var(--popup-text-color); /* Use variable for paragraph text color */ | ||||
|     margin: 10px; | ||||
| } | ||||
|  |  | |||
|  | @ -10,15 +10,12 @@ | |||
|     justify-content: center; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .settings-main h2 { | ||||
|     margin-bottom: 1em; | ||||
| } | ||||
| 
 | ||||
| .settings-main p { | ||||
|     padding-bottom: 7px; | ||||
| } | ||||
| 
 | ||||
| /* Main container for the settings */ | ||||
| .settings-container { | ||||
|     display: grid; | ||||
|  | @ -29,7 +26,6 @@ | |||
|     height: 100%; | ||||
|     /* Ensure it takes full height */ | ||||
| } | ||||
| 
 | ||||
| /* Settings content */ | ||||
| .settings-content { | ||||
|     background: var(--history-background-color); | ||||
|  | @ -49,7 +45,6 @@ | |||
|     flex-direction: column; | ||||
|     /* Flexbox for vertical stacking */ | ||||
| } | ||||
| 
 | ||||
| /* Sidebar styles */ | ||||
| .sidebar { | ||||
|     background: var(--settings-background-color); | ||||
|  | @ -66,7 +61,6 @@ | |||
|     height: 100%; | ||||
|     /* Ensures sidebar takes full height */ | ||||
| } | ||||
| 
 | ||||
| /* Sidebar item styles */ | ||||
| .sidebar ul { | ||||
|     list-style-type: none; | ||||
|  | @ -78,7 +72,6 @@ | |||
|     flex-grow: 1; | ||||
|     /* Allows the list to take available space */ | ||||
| } | ||||
| 
 | ||||
| .sidebar li { | ||||
|     margin: 10px 0; | ||||
|     cursor: pointer; | ||||
|  | @ -86,17 +79,14 @@ | |||
|     border-radius: 5px; | ||||
|     transition: background 0.3s; | ||||
| } | ||||
| 
 | ||||
| .sidebar li:hover { | ||||
|     background: var(--input-button-hover-color); | ||||
|     /* Highlight on hover */ | ||||
| } | ||||
| 
 | ||||
| .sidebar li.active { | ||||
|     background: var(--button-hover-background-color); | ||||
|     /* Active section highlight */ | ||||
| } | ||||
| 
 | ||||
| /* Main settings area */ | ||||
| .settings-main { | ||||
|     grid-column: 2; | ||||
|  | @ -110,7 +100,6 @@ | |||
|     flex-direction: column; | ||||
|     /* Stack content vertically */ | ||||
| } | ||||
| 
 | ||||
| /* Close button positioning */ | ||||
| .close-popup { | ||||
|     background: var(--close-button-color); | ||||
|  | @ -129,7 +118,6 @@ | |||
|     /* Distance from the right */ | ||||
|     transition: background 0.3s; | ||||
| } | ||||
| 
 | ||||
| /* Close button positioning */ | ||||
| .apply { | ||||
|     background: var(--apply-button-color); | ||||
|  | @ -148,13 +136,10 @@ | |||
|     /* Distance from the right */ | ||||
|     transition: background 0.3s; | ||||
| } | ||||
| 
 | ||||
| .close-popup:hover { | ||||
|     background: darkred; | ||||
|     /* Optional hover effect */ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Additional styles for inputs and options */ | ||||
| .settings-option { | ||||
|     margin-bottom: 20px; | ||||
|  | @ -164,14 +149,12 @@ | |||
|     border-bottom: 1px solid var(--input-border-color); | ||||
|     /* Optional, creates a separator between options */ | ||||
| } | ||||
| 
 | ||||
| .settings-option:last-child { | ||||
|     margin-bottom: 0; | ||||
|     /* Removes bottom margin from last option */ | ||||
|     border-bottom: none; | ||||
|     /* Removes separator from last option */ | ||||
| } | ||||
| 
 | ||||
| .settings-option input[type="text"], | ||||
| .settings-option input[type="email"], | ||||
| .settings-option input[type="password"], | ||||
|  | @ -188,33 +171,28 @@ | |||
|     margin-bottom: 10px; | ||||
|     /* Adds spacing between inputs */ | ||||
| } | ||||
| 
 | ||||
| /* Optional additional spacing for labels */ | ||||
| .settings-option label { | ||||
|     margin-bottom: 5px; | ||||
|     display: block; | ||||
|     font-weight: bold; | ||||
| } | ||||
| 
 | ||||
| .export-button { | ||||
|     background-color: var(--button-hover-background-color); | ||||
|     padding: 10px; | ||||
|     margin: 10px; | ||||
|     border-radius: 10px; | ||||
| } | ||||
| 
 | ||||
| .import-file { | ||||
|     background-color: var(--button-hover-background-color); | ||||
|     padding: 10px; | ||||
|     margin: 10px; | ||||
| } | ||||
| 
 | ||||
| .slider { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     margin-top: 10px; | ||||
| } | ||||
| 
 | ||||
| .slider-option { | ||||
|     cursor: pointer; | ||||
|     padding: 10px; | ||||
|  | @ -222,22 +200,22 @@ | |||
|     border-radius: 5px; | ||||
|     transition: background-color 0.3s; | ||||
| } | ||||
| 
 | ||||
| .slider-option.active { | ||||
|     background-color: #007bff; | ||||
|     /* Change to your active color */ | ||||
|     color: white; | ||||
|     border-color: #007bff; | ||||
| } | ||||
| 
 | ||||
| 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 */ | ||||
| } | ||||
| .dropdown{ | ||||
|     display: none; | ||||
| } | ||||
|  | @ -5,8 +5,7 @@ | |||
|     height: 90dvh; | ||||
|     padding-top: 1dvh; | ||||
| } | ||||
| 
 | ||||
| .left-panel { | ||||
| .left-panel{ | ||||
|     width: 25vw; /* Adjust as needed */ | ||||
|     transition: width 0.3s ease, opacity 0.3s ease, visibility 0.3s ease; /* Smooth transitions for all properties */ | ||||
|     background-color: var(--left-panel-background-color); /* Use variable for background color */ | ||||
|  | @ -14,23 +13,17 @@ | |||
|     margin-left: 0; | ||||
|     padding-right: 1em; | ||||
| } | ||||
| 
 | ||||
| .left-panel.hidden { | ||||
| .left-panel.hidden{ | ||||
|     opacity: 0; /* Fade out when hidden */ | ||||
|     width: 0; /* Collapse width to 0 */ | ||||
|     visibility: hidden; /* Hide visibility while collapsing */ | ||||
|      | ||||
| } | ||||
| 
 | ||||
| .conversation-container { | ||||
| .conversation-container{ | ||||
|     flex: 1; | ||||
|     transition: margin-left 0.3s ease; /* Smooth margin adjustment */ | ||||
|     background-color: var(--conversation-background-color); /* Use variable for background color */ | ||||
|     border-radius: 1em 0 0 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| .conversation-container.collapsed { | ||||
| .conversation-container.collapsed{ | ||||
|     margin-left: 1vw; /* Space for the left panel */ | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,8 @@ | |||
| /* Styling for the credits container */ | ||||
| .credits-container { | ||||
| .credits-container{ | ||||
|   padding: 2rem; | ||||
|   } | ||||
|    | ||||
|   .credits-section { | ||||
| } | ||||
| .credits-section{ | ||||
|   max-width: 900px; | ||||
|   height: 80dvh; | ||||
|   margin: auto; | ||||
|  | @ -12,30 +11,26 @@ | |||
|   border-radius: 8px; | ||||
|   box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); | ||||
|   overflow-y: scroll; | ||||
|   } | ||||
|    | ||||
|   .title { | ||||
| } | ||||
| .title{ | ||||
|   font-size: calc(var(--font-size)*2); | ||||
|   color: var(--doc-title-color); /* Use variable for title color */ | ||||
|   margin-bottom: 1.5rem; | ||||
|   } | ||||
|    | ||||
|   .subtitle { | ||||
| } | ||||
| .subtitle{ | ||||
|   font-size: calc(var(--font-size)*1.5); | ||||
|   color: var(--doc-subtitle-color); /* Use variable for subtitle color */ | ||||
|   margin-top: 2rem; | ||||
|   margin-bottom: 1rem; | ||||
|   } | ||||
|    | ||||
|   .paragraph { | ||||
| } | ||||
| .paragraph{ | ||||
|   font-size: calc(var(--font-size)); | ||||
|   color: var(--doc-paragraph-color); /* Use variable for paragraph color */ | ||||
|   margin-bottom: 1.5rem; | ||||
|   line-height: 1.6; | ||||
|   } | ||||
|    | ||||
|   /* Styling for the credit buttons */ | ||||
|   .credit-btn { | ||||
| } | ||||
| /* Styling for the credit buttons */ | ||||
| .credit-btn{ | ||||
|   display: inline-block; | ||||
|   padding: 10px 15px; | ||||
|   margin: 10px 5px; | ||||
|  | @ -44,9 +39,7 @@ | |||
|   text-decoration: none; | ||||
|   border-radius: 5px; | ||||
|   transition: background-color 0.3s ease; | ||||
|   } | ||||
|    | ||||
|   .credit-btn:hover { | ||||
| } | ||||
| .credit-btn:hover{ | ||||
|   background-color: var(--button-hover-background-color); /* Button hover */ | ||||
|   } | ||||
|    | ||||
| } | ||||
|  |  | |||
|  | @ -1,11 +1,9 @@ | |||
| /* styles.css */ | ||||
| 
 | ||||
| /* Styling for the documentation container */ | ||||
| .documentation-container { | ||||
| .documentation-container{ | ||||
|   padding: 2rem; | ||||
| } | ||||
| 
 | ||||
| .documentation-section { | ||||
| .documentation-section{ | ||||
|   max-width: 900px; | ||||
|   height: 80dvh; | ||||
|   margin: auto; | ||||
|  | @ -15,28 +13,24 @@ | |||
|   box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); | ||||
|   overflow-y: scroll; | ||||
| } | ||||
| 
 | ||||
| .title { | ||||
| .title{ | ||||
|   font-size: calc(var(--font-size)*2); | ||||
|   color: var(--doc-title-color); /* Use variable for title color */ | ||||
|   margin-bottom: 1.5rem; | ||||
| } | ||||
| 
 | ||||
| .subtitle { | ||||
| .subtitle{ | ||||
|   font-size: calc(var(--font-size)*1.5); | ||||
|   color: var(--doc-subtitle-color); /* Use variable for subtitle color */ | ||||
|   margin-top: 2rem; | ||||
|   margin-bottom: 1rem; | ||||
| } | ||||
| 
 | ||||
| .subsection-title { | ||||
| .subsection-title{ | ||||
|   font-size: calc(var(--font-size)*1.25); | ||||
|   color: var(--doc-subsection-title-color); /* Use variable for subsection title color */ | ||||
|   margin-top: 1.5rem; | ||||
|   margin-bottom: 0.75rem; | ||||
| } | ||||
| 
 | ||||
| .paragraph { | ||||
| .paragraph{ | ||||
|   font-size: calc(var(--font-size)); | ||||
|   color: var(--doc-paragraph-color); /* Use variable for paragraph color */ | ||||
|   margin-bottom: 1.5rem; | ||||
|  |  | |||
|  | @ -1,13 +1,12 @@ | |||
| /* Make sure the parent container of #faq takes up the full viewport height */ | ||||
| .faq-container { | ||||
| .faq-container{ | ||||
|     display: flex; | ||||
|     justify-content: center; /* Center horizontally */ | ||||
|     align-items: center;     /* Center vertically */ | ||||
|     height: 100vh;           /* Full viewport height */ | ||||
|     padding: 0 10px;         /* Optional padding to ensure spacing on small screens */ | ||||
| } | ||||
| 
 | ||||
| #faq { | ||||
| #faq{ | ||||
|     max-width: 800px; | ||||
|     width: 90%; | ||||
|     padding: 20px; | ||||
|  | @ -18,34 +17,29 @@ | |||
|     margin: 2rem auto; | ||||
|     height: 80vh; | ||||
| } | ||||
| 
 | ||||
| #faq h2 { | ||||
| #faq h2{ | ||||
|     text-align: center; | ||||
|     color: var(--faq-heading-color); /* Use variable for heading color */ | ||||
|     font-size: 2em; | ||||
|     margin-bottom: 20px; | ||||
| } | ||||
| 
 | ||||
| .faq-item { | ||||
| .faq-item{ | ||||
|     margin-bottom: 20px; | ||||
|     padding: 10px; | ||||
|     border-radius: 5px; | ||||
|     background-color: var(--faq-item-background-color); /* Use variable for item background */ | ||||
|     transition: background-color 0.3s ease-in-out; | ||||
| } | ||||
| 
 | ||||
| .faq-item h3 { | ||||
| .faq-item h3{ | ||||
|     color: var(--faq-item-heading-color); /* Use variable for item heading color */ | ||||
|     margin-bottom: 10px; | ||||
|     font-size: 1.5em; | ||||
| } | ||||
| 
 | ||||
| .faq-item p { | ||||
| .faq-item p{ | ||||
|     color: var(--faq-item-text-color); /* Use variable for item text color */ | ||||
|     font-size: 1.1em; | ||||
|     line-height: 1.5; | ||||
| } | ||||
| 
 | ||||
| .faq-item:hover { | ||||
| .faq-item:hover{ | ||||
|     background-color: var(--faq-item-hover-background-color); /* Use variable for hover background */ | ||||
| } | ||||
|  |  | |||
|  | @ -1,69 +1,56 @@ | |||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Inconsolata'; | ||||
|     src: url('/fonts/serious/Inconsolata/Inconsolata-VariableFont_wdth,wght.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Merriweather'; | ||||
|     src: url('/fonts/serious/Merriweather/Merriweather-Regular.tff') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Noto Sans'; | ||||
|     src: url('/fonts/serious/Noto_Sans/NotoSans-VariableFont_wdth\,wght.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Noto Serif'; | ||||
|     src: url('/fonts/serious/Noto_Serif/NotoSerif-VariableFont_wdth\,wght.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Playfair Display'; | ||||
|     src: url('/fonts/serious/Playfair_Display/PlayfairDisplay-VariableFont_wght.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Poppins'; | ||||
|     src: url('/fonts/serious/Poppins/Poppins-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Roboto'; | ||||
|     src: url('/fonts/serious/Roboto/Roboto-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Ubuntu'; | ||||
|     src: url('/fonts/serious/Ubuntu/Ubuntu-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Bangers'; | ||||
|     src: url('/fonts/comic-sans-but-better/Bangers/Bangers-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Caveat'; | ||||
|     src: url('/fonts/comic-sans-but-better/Caveat/Caveat-VariableFont_wght.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Frederika the Great'; | ||||
|     src: url('/fonts/comic-sans-but-better/Fredericka_the_Great/FrederickatheGreat-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Rock Salt'; | ||||
|     src: url('/fonts/RockSalt.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Sofadi One'; | ||||
|     src: url('/fonts/comic-sans-but-better/Sofadi_One/SofadiOne-Regular.ttf') format('truetype'); | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
| @font-face{ | ||||
|     font-family: 'Zilla Slab Highlight'; | ||||
|     src: url('/fonts/comic-sans-but-better/Zilla_Slab_Highlight/ZillaSlabHighlight-Regular.ttf') format('truetype'); | ||||
| } | ||||
|  |  | |||
|  | @ -1,79 +1,59 @@ | |||
| body { | ||||
| body{ | ||||
|     height: 100dvh; | ||||
|     overflow: hidden; | ||||
|     position: relative; | ||||
| } | ||||
| 
 | ||||
| /* Chrome, Edge, and Safari */ | ||||
| ::-webkit-scrollbar { | ||||
|     width: 12px; | ||||
|     /* Adjust width for horizontal and vertical scrollbars */ | ||||
| ::-webkit-scrollbar{ | ||||
|     width: 12px; /* Adjust width for horizontal and vertical scrollbars */ | ||||
| } | ||||
| 
 | ||||
| ::-webkit-scrollbar-track { | ||||
|     background: #f0f0f0; | ||||
|     /* Background of the scrollbar track */ | ||||
| ::-webkit-scrollbar-track{ | ||||
|     background: #f0f0f0; /* Background of the scrollbar track */ | ||||
| } | ||||
| 
 | ||||
| ::-webkit-scrollbar-thumb { | ||||
|     background-color: #888; | ||||
|     /* Color of the draggable part (thumb) */ | ||||
|     border-radius: 10px; | ||||
|     /* Rounded corners */ | ||||
|     border: 2px solid #f0f0f0; | ||||
|     /* Space around the thumb */ | ||||
| ::-webkit-scrollbar-thumb{ | ||||
|     background-color: #888; /* Color of the draggable part (thumb) */ | ||||
|     border-radius: 10px; /* Rounded corners */ | ||||
|     border: 2px solid #f0f0f0; /* Space around the thumb */ | ||||
| } | ||||
| 
 | ||||
| ::-webkit-scrollbar-thumb:hover { | ||||
|     background-color: #555; | ||||
|     /* Thumb color on hover */ | ||||
| ::-webkit-scrollbar-thumb:hover{ | ||||
|     background-color: #555; /* Thumb color on hover */ | ||||
| } | ||||
| 
 | ||||
| body { | ||||
| body{ | ||||
|     background-color: var(--background-color); | ||||
|     color: var(--text-color); | ||||
|     font-family: var(--font-family); | ||||
|     font-size: var(--font-size); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| header { | ||||
| header{ | ||||
|     background-color: var(--header-background-color); | ||||
|     color: var(--header-text-color); | ||||
| } | ||||
| 
 | ||||
| button { | ||||
| button{ | ||||
|     background-color: var(--button-background-color); | ||||
|     color: var(--text-color); | ||||
|     border: 1px solid var(--input-border-color); | ||||
|     transition: background-color 0.3s ease; | ||||
| } | ||||
| 
 | ||||
| button:hover { | ||||
| button:hover{ | ||||
|     background-color: var(--button-hover-background-color); | ||||
| } | ||||
| 
 | ||||
| input { | ||||
| input{ | ||||
|     background-color: var(--input-background-color); | ||||
|     border: 1px solid var(--input-border-color); | ||||
|     color: var(--text-color); | ||||
| } | ||||
| 
 | ||||
| input:hover { | ||||
| input:hover{ | ||||
|     border-color: var(--button-hover-background-color); | ||||
| } | ||||
| 
 | ||||
| select{ | ||||
|     background-color: var(--input-background-color); | ||||
| } | ||||
| 
 | ||||
| h1, h2, h3, h4, p{ | ||||
|     color: var(--text-color); | ||||
|     font-family: var(--font-family); | ||||
|     font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| p{ | ||||
|     font-weight: 400; | ||||
|     font-size: var(--font-size) | ||||
|     font-size: var(--font-size); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| header { | ||||
| header{ | ||||
|     position: relative; | ||||
|     padding: 0 20px; | ||||
|     width: 100%; | ||||
|  | @ -9,36 +9,32 @@ header { | |||
|     font-size: 1em; | ||||
|     z-index: 999; | ||||
| } | ||||
| 
 | ||||
| /* Hamburger button styles */ | ||||
| .hamburger { | ||||
| .hamburger{ | ||||
|     position: absolute; | ||||
|     left: 5vw; | ||||
|     display: flex; /* Always show hamburger button */ | ||||
|     flex-direction: column; | ||||
|     cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .hamburger span { | ||||
| .hamburger span{ | ||||
|     width: 25px; | ||||
|     height: 3px; | ||||
|     background-color: white; | ||||
|     margin: 4px; | ||||
|     transition: 0.3s; | ||||
| } | ||||
| 
 | ||||
| .hamburger.open span:nth-child(1) { | ||||
| .hamburger.open span:nth-child(1){ | ||||
|     transform: rotate(45deg) translate(5px, 10px); | ||||
| } | ||||
| .hamburger.open span:nth-child(2) { | ||||
| .hamburger.open span:nth-child(2){ | ||||
|     opacity: 0; | ||||
| } | ||||
| .hamburger.open span:nth-child(3) { | ||||
| .hamburger.open span:nth-child(3){ | ||||
|     transform: rotate(-45deg) translate(5px, -10px); | ||||
| } | ||||
| 
 | ||||
| /* Navigation links (hidden in header, shown in dropdown) */ | ||||
| .nav-links { | ||||
| .nav-links{ | ||||
|     display: none; /* Default hidden */ | ||||
|     position: absolute; | ||||
|     top: 10vh; /* Adjust as needed */ | ||||
|  | @ -51,13 +47,11 @@ header { | |||
|     padding: 10px auto; | ||||
|     margin: auto; | ||||
| } | ||||
| 
 | ||||
| .nav-links.active { | ||||
| .nav-links.active{ | ||||
|     display: flex; /* Show when active */ | ||||
|     height: fit-content; | ||||
| } | ||||
| 
 | ||||
| .nav-btn { | ||||
| .nav-btn{ | ||||
|     background-color: var(--input-button-color); | ||||
|     border: none; | ||||
|     font-size: 0.9em; | ||||
|  | @ -69,13 +63,11 @@ header { | |||
|     text-align: center; /* Center text */ | ||||
|     margin: 4px auto; | ||||
| } | ||||
| 
 | ||||
| .nav-btn:hover { | ||||
| .nav-btn:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| /* Logo styles */ | ||||
| .header-logo { | ||||
| .header-logo{ | ||||
|     width: 250px; | ||||
|     height: 5vh; | ||||
|     background-image: url(../../public/img/logo.png); | ||||
|  | @ -85,9 +77,8 @@ header { | |||
|     background-color: transparent; | ||||
|     border: none; | ||||
| } | ||||
| 
 | ||||
| /* Login button styles */ | ||||
| .login-button-container { | ||||
| .login-button-container{ | ||||
|     position: absolute; | ||||
|     top: 0.1vh; | ||||
|     right: 1vw; | ||||
|  | @ -95,8 +86,7 @@ header { | |||
|     display: flex; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .header-login-button { | ||||
| .header-login-button{ | ||||
|     height: 100%; | ||||
|     width: max-content; | ||||
|     font-size: var(--font-size); | ||||
|  | @ -112,11 +102,9 @@ header { | |||
|     justify-content: center; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .header-login-button:hover { | ||||
| .header-login-button:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .show-hide-btn{ | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| .history-background { | ||||
| .history-background{ | ||||
|     grid-column: 1/2; | ||||
|     grid-row: 1/2; | ||||
|     height: 35dvh; | ||||
|  | @ -9,37 +9,67 @@ | |||
|     margin-right: 0; | ||||
|     border-radius: 1em; | ||||
| } | ||||
| 
 | ||||
| .history { | ||||
| .history{ | ||||
|     height: 100%; | ||||
|     overflow-y: scroll; | ||||
|     padding-right: 10px; | ||||
| } | ||||
| 
 | ||||
| .history ul { | ||||
| .history ul{ | ||||
|     list-style: none; | ||||
| } | ||||
| 
 | ||||
| .history ul li { | ||||
| .history ul li{ | ||||
|     padding: 10px 0; | ||||
|     border-bottom: 1px solid var(--text-color); | ||||
|     width: 100%; | ||||
| } | ||||
| 
 | ||||
| .history ul li a { | ||||
| .history ul li a{ | ||||
|     display: block; | ||||
|     text-decoration: none; | ||||
|     color: var(--text-color); /* Use variable for link text color */ | ||||
|     width: 100%; | ||||
|     padding: 5px; | ||||
| } | ||||
| 
 | ||||
| .history ul li a:hover { | ||||
| .history ul li a:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .history-models{ | ||||
|     position: relative; | ||||
|     height: 86dvh; | ||||
|     /* padding-bottom: 3dvh; */ | ||||
| } | ||||
| .input-container { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     width: 100%; | ||||
| } | ||||
| .chat-input { | ||||
|     border-color: var(--input-border-color); | ||||
|     color: var(--text-color); | ||||
|     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||||
|     padding: 10px; | ||||
|     border-radius: 5px; | ||||
|     width: 80%; | ||||
|     height: 50px; | ||||
|     box-sizing: border-box; | ||||
|     line-height: 30px; | ||||
| } | ||||
| .save-btn, .newChat-btn { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     text-align: center; | ||||
|     width: 20%; | ||||
|     height: 50px; | ||||
|     background-color: var(--input-button-color); | ||||
|     color: var(--text-color); | ||||
|     border: none; | ||||
|     font-size: 0.9em; | ||||
|     border-radius: 5px; | ||||
|     margin-left: 10px; | ||||
| } | ||||
| 
 | ||||
| .newChat-btn{ | ||||
|     margin-left: 0px; | ||||
| } | ||||
|    | ||||
|  |  | |||
|  | @ -1,15 +1,11 @@ | |||
| /* Input Section */ | ||||
| .input { | ||||
| .input{ | ||||
|     border-radius: 8px; | ||||
|     background-color: var(--input-background-color); | ||||
|     padding: 1em; | ||||
|     padding-left: 0.5em; | ||||
|     padding-right: 0; | ||||
|     padding: 1em 0 1em 0.5em; | ||||
|     margin: 0 10px; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     height: auto; | ||||
|     height: 10dvh; | ||||
|     position: absolute; | ||||
|     left: 0.25vw; | ||||
|  | @ -18,8 +14,7 @@ | |||
|     box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.5); | ||||
|     z-index: 600; | ||||
| } | ||||
| 
 | ||||
| .input input { | ||||
| .input input{ | ||||
|     flex-grow: 1; | ||||
|     padding: 5px; | ||||
|     font-size: 1em; | ||||
|  | @ -32,20 +27,16 @@ | |||
|     transition: border-color 0.3s ease-in-out; | ||||
|     height: 7vh; | ||||
| } | ||||
| 
 | ||||
| .textInputField::placeholder { | ||||
| .textInputField::placeholder{ | ||||
|     color: var(--text-color); /* Change to desired placeholder color */ | ||||
|     opacity: 1;  /* Ensures full opacity (optional) */ | ||||
| } | ||||
| 
 | ||||
| .input input:focus { | ||||
| .input input:focus{ | ||||
|     border-color: var(--input-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .input button { | ||||
| .input button{ | ||||
|     padding: 5px; | ||||
|     margin: 5px; | ||||
|     margin-left: 0; | ||||
|     margin: 5px 5px 5px 0; | ||||
|     background-color: var(--input-button-color); | ||||
|     color: var(--user-message-text-color); /* Use variable for button text color */ | ||||
|     border: none; | ||||
|  | @ -61,28 +52,22 @@ | |||
|     position: relative; | ||||
|     box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| .input button img { | ||||
| .input button img{ | ||||
|     height: 20px; | ||||
| } | ||||
| 
 | ||||
| .input button:hover { | ||||
| .input button:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
|     box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| 
 | ||||
| .microphone-button.red{ | ||||
|     background-color: var(--close-button-color); | ||||
| } | ||||
| 
 | ||||
| .microphone-button.green{ | ||||
|     background-color: var(--button-background-color); | ||||
| } | ||||
| 
 | ||||
| .microphone-button.red:hover{ | ||||
|     background-color: var(--close-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .microphone-button.green:hover{ | ||||
|     background-color: var(--input-button-hover-color); | ||||
| } | ||||
|  | @ -13,7 +13,6 @@ | |||
|     border-radius: 1em; | ||||
|     height: 45dvh; | ||||
| } | ||||
| 
 | ||||
| .models { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|  | @ -21,7 +20,6 @@ | |||
|     overflow: hidden; | ||||
|     overflow-y: scroll; | ||||
| } | ||||
| 
 | ||||
| .models .title { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|  | @ -29,24 +27,20 @@ | |||
|     font-size: 1.5em; | ||||
|     margin-bottom: 0; | ||||
| } | ||||
| 
 | ||||
| .model-dropdown { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     margin-bottom: 1em; /* Space between dropdown and models */ | ||||
| } | ||||
| 
 | ||||
| .model-dropdown label { | ||||
|     margin-right: 0.5em; /* Space between label and dropdown */ | ||||
| } | ||||
| 
 | ||||
| .grid { | ||||
|     display: grid; | ||||
|     grid-template-columns: repeat(2, 1fr); | ||||
|     gap: 1.5vh; | ||||
|     width: 100%; /* Ensure grid takes full width */ | ||||
| } | ||||
| 
 | ||||
| .model-box { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|  | @ -59,12 +53,10 @@ | |||
|     width: 18vh; | ||||
|     margin: auto; /* Center each model box in the grid cell */ | ||||
| } | ||||
| 
 | ||||
| .model-box.selected { | ||||
|     box-shadow: 0 0 25px 5px var(--apply-button-hover-color); /* Glowing border */ | ||||
|     border-color: var(--apply-button-hover-color); | ||||
| } | ||||
| 
 | ||||
| .overlay { | ||||
|     position: absolute; | ||||
|     left: 0; | ||||
|  | @ -81,7 +73,6 @@ | |||
|     opacity: 0; | ||||
|     border-radius: 5%; | ||||
| } | ||||
| 
 | ||||
| .overlay img { | ||||
|     align-self: flex-end; | ||||
|     justify-self: end; | ||||
|  | @ -91,18 +82,15 @@ | |||
|     right: 15px; | ||||
|     bottom: 15px; | ||||
| } | ||||
| 
 | ||||
| .model-box:hover .overlay { | ||||
|     opacity: 1; | ||||
| } | ||||
| 
 | ||||
| /* Model background styles */ | ||||
| .code-model { | ||||
|     background-image: url(/img/code.jpg); | ||||
|     background-repeat: no-repeat; | ||||
|     background-size: cover; | ||||
| } | ||||
| 
 | ||||
| .math-model { | ||||
|     background-image: url(/img/math.jpg); | ||||
|     background-color: var(--background-color); | ||||
|  | @ -110,7 +98,6 @@ | |||
|     background-repeat: no-repeat; | ||||
|     background-size: contain; | ||||
| } | ||||
| 
 | ||||
| .language-model { | ||||
|     background-image: url(/img/language.jpg); | ||||
|     background-color: #72cce4; | ||||
|  | @ -118,8 +105,6 @@ | |||
|     background-size: contain; | ||||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .weather-model { | ||||
|     background-image: url(/img/weather.jpg); | ||||
|     background-color: #72cce4; | ||||
|  | @ -127,7 +112,6 @@ | |||
|     background-size: contain; | ||||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| .custom1-model, | ||||
| .custom2-model { | ||||
|     background-image: url(/img/default.jpg); | ||||
|  | @ -135,20 +119,17 @@ | |||
|     background-size: cover; | ||||
|     background-position: center; | ||||
| } | ||||
| 
 | ||||
| .model-dropdown { | ||||
|     display: flex; | ||||
|     flex-direction: column; /* Stack label and dropdown */ | ||||
|     align-items: center; /* Center the content */ | ||||
|     margin-bottom: 1em; /* Space between dropdown and models */ | ||||
| } | ||||
| 
 | ||||
| .model-dropdown label { | ||||
|     margin-bottom: 0.5em; /* Space between label and dropdown */ | ||||
|     font-size: large; /* Increase font size for visibility */ | ||||
|     color: var(--text-color); /* Use variable for text color */ | ||||
| } | ||||
| 
 | ||||
| #model-select { | ||||
|     padding: 0.5em; /* Padding for better touch targets */ | ||||
|     border-radius: 5px; /* Rounded corners */ | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ | |||
|     height: 85dvh; | ||||
|     position: relative; | ||||
| } | ||||
| 
 | ||||
| #conversation { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|  | @ -27,7 +26,6 @@ | |||
|     border-radius: 10px; | ||||
|     scroll-behavior: smooth; | ||||
| } | ||||
| 
 | ||||
| /* Message Bubbles */ | ||||
| .user-message, .ai-message { | ||||
|     padding: 10px; | ||||
|  | @ -37,23 +35,19 @@ | |||
|     word-wrap: break-word; | ||||
|     overflow-wrap: break-word; | ||||
| } | ||||
| 
 | ||||
| .user-message { | ||||
|     background-color: var(--user-message-background-color); | ||||
|     align-self: flex-end; | ||||
|     color: var(--user-message-text-color); | ||||
| } | ||||
| 
 | ||||
| .ai-message { | ||||
|     background-color: var(--ai-message-background-color); | ||||
|     align-self: flex-start; | ||||
|     color: var(--ai-message-text-color); | ||||
| } | ||||
| 
 | ||||
| .ai-message a { | ||||
|     color: var(--text-color); | ||||
| } | ||||
| 
 | ||||
| .ai-message table { | ||||
|     display: block; /* Treat the table as a block element */ | ||||
|     position: relative; | ||||
|  | @ -67,31 +61,24 @@ | |||
|     border-radius: 4px; /* Optional: Add border radius similar to pre/code */ | ||||
|     margin-top: 5px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .ai-message th { | ||||
|     background-color: var(--user-message-background-color); | ||||
|     align-items: center; | ||||
|     padding: 5px; | ||||
| } | ||||
| 
 | ||||
| .ai-message td { | ||||
|     align-items: center; | ||||
|     padding: 5px; | ||||
| } | ||||
| 
 | ||||
| .ai-message img { | ||||
|     max-width: 80%; | ||||
| } | ||||
| 
 | ||||
| .ai-message a:hover { | ||||
|     filter: brightness(70%); | ||||
| } | ||||
| 
 | ||||
| .ai-message li { | ||||
|     margin-left: 1em; | ||||
| } | ||||
| 
 | ||||
| .ai-message code, .ai-message pre { | ||||
|     overflow-x: auto; | ||||
|     white-space: pre; | ||||
|  | @ -101,12 +88,10 @@ | |||
|     background-color: var(--code-background-color); | ||||
|     border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| /* Button Container */ | ||||
| .button-container { | ||||
|     display: flex; | ||||
| } | ||||
| 
 | ||||
| .button-container button { | ||||
|     background: none; | ||||
|     border: none; | ||||
|  | @ -117,18 +102,15 @@ | |||
|     height: 40px; | ||||
|     width: 40px; | ||||
| } | ||||
| 
 | ||||
| .button-container button:hover { | ||||
|     background-color: var(--button-hover-background-color); | ||||
| } | ||||
| 
 | ||||
| .tooltip { | ||||
|     position: relative; | ||||
|     display: inline-block; | ||||
|     cursor: pointer; | ||||
|     z-index: 900; | ||||
| } | ||||
| 
 | ||||
| .tooltip .tooltiptext { | ||||
|     visibility: hidden; | ||||
|     background-color: var(--user-message-background-color); | ||||
|  | @ -137,17 +119,14 @@ | |||
|     padding: 5px; | ||||
|     border-radius: 4px; | ||||
|     font-size: calc(var(--font-size) * 0.8); | ||||
| 
 | ||||
|     position: absolute; | ||||
|     top: 100%; | ||||
|     left: 50%; | ||||
|     transform: translateX(-50%); | ||||
|     white-space: nowrap; | ||||
| 
 | ||||
|     opacity: 0; | ||||
|     transition: all 0.3s; | ||||
| } | ||||
| 
 | ||||
| .tooltip .tooltiptext::after { | ||||
|     content: ""; | ||||
|     position: absolute; | ||||
|  | @ -158,19 +137,16 @@ | |||
|     border-style: solid; | ||||
|     border-color: transparent transparent var(--user-message-background-color) transparent; | ||||
| } | ||||
| 
 | ||||
| .tooltip:hover .tooltiptext { | ||||
|     visibility: visible; | ||||
|     opacity: 1; | ||||
| } | ||||
| 
 | ||||
| #copiedText { | ||||
|     margin-top: 1em; | ||||
|     cursor: default; | ||||
|     pointer-events: none; | ||||
|     user-select: none; | ||||
| } | ||||
| 
 | ||||
| #scrollToBottom { | ||||
|     scroll-behavior: smooth; | ||||
|     visibility: hidden; | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ | |||
|     padding: 0; | ||||
|     border-radius: none; | ||||
|   } | ||||
|    | ||||
|   /* Header styles */ | ||||
|   header { | ||||
|     top: 0; | ||||
|  | @ -14,7 +13,6 @@ | |||
|     padding-top: 0; | ||||
|     width: 100%; | ||||
|   } | ||||
|   | ||||
|   /* Container styles */ | ||||
|   .container { | ||||
|     display: flex; | ||||
|  | @ -24,26 +22,22 @@ | |||
|     margin: 0; | ||||
|     padding: 1dvh 0 0 0; | ||||
|   } | ||||
| 
 | ||||
|   /* Left panel styles */ | ||||
|   .left-panel { | ||||
|     display: hidden; /* Initially hidden */ | ||||
|     min-width: 100%; /* Takes full width when visible */ | ||||
|     margin: 0; | ||||
|   } | ||||
| 
 | ||||
|   .left-panel.visible { | ||||
|     display: block; | ||||
|     height: min-content; | ||||
|   } | ||||
| 
 | ||||
|   /* Conversation container styles */ | ||||
|   .conversation-container { | ||||
|     min-width: 100%; | ||||
|     height: 100%; | ||||
|     border-radius: 0; | ||||
|   } | ||||
| 
 | ||||
|   .conversation-container.collapsed { | ||||
|     width: 0; | ||||
|     padding: 0; | ||||
|  | @ -51,25 +45,21 @@ | |||
|     overflow: hidden; | ||||
|     display: hidden; | ||||
|   } | ||||
| 
 | ||||
|   .conversation-container.expanded { | ||||
|     min-width: 100%; | ||||
|     margin-left: 0; | ||||
|     border-radius: none; | ||||
|     height: 10vh; | ||||
|   } | ||||
| 
 | ||||
|   /* Grid styles */ | ||||
|   .grid { | ||||
|     grid-template-columns: 1fr; /* One item per line */ | ||||
|   } | ||||
| 
 | ||||
|   /* Model box styles */ | ||||
|   .model-box { | ||||
|     max-width: none; /* Remove max-width */ | ||||
|     margin: 0 auto; /* Center each model-box */ | ||||
|   } | ||||
| 
 | ||||
|   /* Input styles */ | ||||
|   .input { | ||||
|     grid-column: 1 / -1; | ||||
|  | @ -82,7 +72,6 @@ | |||
|     left: 2vw; | ||||
|     justify-content: flex-start; | ||||
|   } | ||||
| 
 | ||||
|   .input input { | ||||
|     font-size: 1em; /* Adjust font size */ | ||||
|     max-width: 70%; | ||||
|  | @ -90,7 +79,6 @@ | |||
|     border-color: var(--input-border-color); /* Use variable for input border */ | ||||
|     color: var(--text-color); /* Use variable for text color */ | ||||
|   } | ||||
| 
 | ||||
|   .input button { | ||||
|     height: 100%; /* Adjust button height */ | ||||
|     width: 15%; /* Adjust button width */ | ||||
|  | @ -99,16 +87,13 @@ | |||
|     color: var(--user-message-text-color); /* Use variable for button text color */ | ||||
|     margin: 0; | ||||
|   } | ||||
| 
 | ||||
|   .header-logo { | ||||
|     position: relative; | ||||
|   } | ||||
| 
 | ||||
|   .hamburger.open { | ||||
|     margin-top: 0.5vh; | ||||
|     padding-left: 1vw; | ||||
|   } | ||||
| 
 | ||||
|   .nav-links { | ||||
|     display: none; /* Hidden by default */ | ||||
|     position: absolute; | ||||
|  | @ -121,12 +106,10 @@ | |||
|     padding: 10px; | ||||
|     height: fit-content; | ||||
|   } | ||||
| 
 | ||||
|   .nav-links.active { | ||||
|     display: flex; /* Show when active */ | ||||
|     height: fit-content; | ||||
|   } | ||||
| 
 | ||||
|   .nav-btn { | ||||
|     width: 100%; | ||||
|     text-align: center; | ||||
|  | @ -137,28 +120,43 @@ | |||
|     font-size: 0.9em; | ||||
|     border-radius: 5px; | ||||
|   } | ||||
| 
 | ||||
|   .nav-btn:hover { | ||||
|     background-color: var(--input-button-hover-color); | ||||
|   } | ||||
| 
 | ||||
|   .hamburger { | ||||
|     display: flex; /* Always show hamburger button */ | ||||
|   } | ||||
| 
 | ||||
|   .header-login-button { | ||||
|     right: 5vh; /* Keep login button visible */ | ||||
|   } | ||||
| 
 | ||||
|   .show-hide-btn{ | ||||
|     width: fit-content; | ||||
|     left: 20vw; | ||||
|   } | ||||
| 
 | ||||
|   .header-logo { | ||||
|     background-image: url(../../public/img/logo-small.png); | ||||
|     width: 4em; | ||||
|   } | ||||
|   .sidebar{ | ||||
|     width: 0%; | ||||
|     display: none; | ||||
|   } | ||||
|   .settings-main { | ||||
|     width: 80vw; /* Full width for main content */ | ||||
|     margin: auto; | ||||
|     padding: auto; | ||||
|   } | ||||
|   .dropdown{ | ||||
|     display: flex; | ||||
|     position: relative; | ||||
|     top: 10px; | ||||
|     display: block; | ||||
|   } | ||||
| 
 | ||||
|   .slider-option{ | ||||
|     width: fit-content; | ||||
|     margin: 10px 10px 0 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /* Responsive adjustments for the settings */ | ||||
|  | @ -166,12 +164,4 @@ | |||
|   .settings-content { | ||||
|     flex-direction: column; /* Stack sidebar and main content on smaller screens */ | ||||
|   } | ||||
| 
 | ||||
|   .sidebar { | ||||
|     width: 100%; /* Full width for sidebar */ | ||||
|   } | ||||
| 
 | ||||
|   .settings-main { | ||||
|     width: 100%; /* Full width for main content */ | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -2,16 +2,13 @@ | |||
| .scrollbar { | ||||
|   overflow-y: scroll; | ||||
| } | ||||
| 
 | ||||
| .scrollbar::-webkit-scrollbar { | ||||
|   width: 8px; | ||||
| } | ||||
| 
 | ||||
| .scrollbar::-webkit-scrollbar-thumb { | ||||
|   background-color: var(--input-border-color); /* Use variable for thumb color */ | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .scrollbar::-webkit-scrollbar-track { | ||||
|   background-color: var(--history-background-color); /* Use variable for track color */ | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,6 @@ | |||
|     display: block; | ||||
|     box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| .user-message { | ||||
|     background-color: var(--user-message-background-color); | ||||
|     color: var(--text-color); | ||||
|  | @ -18,7 +17,6 @@ | |||
|     text-align: left; | ||||
|     margin-right: 1.5vw; | ||||
| } | ||||
| 
 | ||||
| .ai-message { | ||||
|     background-color: var(--ai-message-background-color); | ||||
|     color: var(--text-color); | ||||
|  | @ -26,7 +24,6 @@ | |||
|     margin-right: auto; | ||||
|     text-align: left; | ||||
| } | ||||
| 
 | ||||
| .ai-container{ | ||||
|     position: relative; | ||||
|     height: min-content; | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ | |||
|     --apply-button-hover-color:#6b7c2b; | ||||
|     --burger-menu-background-color: #79832e;  /*NEW*/ | ||||
|     --overlay-text-color:white; /*NEW*/   | ||||
|      | ||||
|     /* FAQ Colors */ | ||||
|     --faq-background-color: #474D22; /* Background color for FAQ section */ | ||||
|     --faq-heading-color: #8B9635; /* Heading color for FAQ section */ | ||||
|  | @ -32,7 +31,6 @@ | |||
|     --faq-item-heading-color: #474D22; /* Heading color for FAQ items */ | ||||
|     --faq-item-text-color: #333; /* Text color for FAQ items */ | ||||
|     --faq-item-hover-background-color: #e0e0e0; /* Hover background color for FAQ items */ | ||||
| 
 | ||||
|     --popup-background-color: #8B9635; | ||||
|     --pop-up-text: #000; /* Text color for pop-ups */ | ||||
|     --input-border-color: #8B9635; /* Input border color */ | ||||
|  |  | |||
							
								
								
									
										22
									
								
								deployment_scripts/linux/prepare-free.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								deployment_scripts/linux/prepare-free.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| chmod +x root.sh | ||||
| pkexec ./root.sh | ||||
| npm install | ||||
| npm run build | ||||
| 
 | ||||
| cd py | ||||
| python3 -m venv venv | ||||
| source venv/bin/activate | ||||
| python3 -m pip install -r requirements.txt | ||||
| 
 | ||||
| ollama pull qwen2-math:1.5b | ||||
| ollama pull starcoder2 | ||||
| ollama pull llama3.2 | ||||
| 
 | ||||
| ollama pull wizard-math | ||||
| ollama pull starcoder2:7b | ||||
| ollama pull llama3.1 | ||||
| 
 | ||||
| cd .. | ||||
| chmod +x run.sh | ||||
							
								
								
									
										22
									
								
								deployment_scripts/linux/prepare-nonfree.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								deployment_scripts/linux/prepare-nonfree.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| chmod +x root.sh | ||||
| pkexec ./root.sh | ||||
| npm install | ||||
| npm run build | ||||
| 
 | ||||
| cd py | ||||
| python3 -m venv venv | ||||
| source venv/bin/activate | ||||
| python3 -m pip install -r requirements.txt | ||||
| 
 | ||||
| ollama pull qwen2-math:1.5b | ||||
| ollama pull qwen2.5-coder:1.5b | ||||
| ollama pull phi3.5 | ||||
| 
 | ||||
| ollama pull mathstral | ||||
| ollama pull qwen2.5-coder | ||||
| ollama pull qwen2.5 | ||||
| 
 | ||||
| cd .. | ||||
| chmod +x run.sh | ||||
							
								
								
									
										7
									
								
								deployment_scripts/linux/root.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								deployment_scripts/linux/root.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| apt install npm nodejs python3-full ffmpeg libgtk-3-0 libnotify4 libgconf-2-4 libnss3 libxss1 libasound2 build-essential cmake -y | ||||
| if ! ollama; then | ||||
|     curl -fsSL https://ollama.com/install.sh | sh | ||||
| fi | ||||
| systemctl enable ollama --now | ||||
							
								
								
									
										15
									
								
								deployment_scripts/linux/run.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								deployment_scripts/linux/run.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| cd py | ||||
| source venv/bin/activate | ||||
| python3 api.py & | ||||
| pid_py=$! | ||||
| cd .. | ||||
| 
 | ||||
| npm start & | ||||
| pid_node=$! | ||||
| 
 | ||||
| npx electron . | ||||
| 
 | ||||
| kill $pid_py | ||||
| kill $pid_node | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue