diff --git a/app/backend/InputOutputHandler.tsx b/app/backend/InputOutputHandler.tsx index 07806d7..0445d66 100644 --- a/app/backend/InputOutputHandler.tsx +++ b/app/backend/InputOutputHandler.tsx @@ -5,7 +5,7 @@ import InputFrontend from "../components/InputFrontend"; import { sendToVoiceRecognition } from "./voice_backend" import { AudioRecorder } from "./AudioRecorder"; import axios from "axios"; -import { resolve } from "path"; +import { resolve } from "path"; import { FFmpeg } from "@ffmpeg/ffmpeg"; import { fetchFile, toBlobURL } from "@ffmpeg/util" diff --git a/app/components/settings/ButtonSettings.tsx b/app/components/settings/ButtonSettings.tsx new file mode 100644 index 0000000..3352fbf --- /dev/null +++ b/app/components/settings/ButtonSettings.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +interface ButtonSettingProps { + label: string; // The label to display on the button + onClick: () => void; // The function to call when the button is clicked + className?: string; // Optional additional classes for styling +} + +const ButtonSetting: React.FC = ({ label, onClick, className }) => { + return ( +
+ +
+ ); +}; + +export default ButtonSetting; diff --git a/app/components/settings/CheckBox.tsx b/app/components/settings/CheckBox.tsx new file mode 100644 index 0000000..1b1ece5 --- /dev/null +++ b/app/components/settings/CheckBox.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +interface CheckboxSettingProps { + label: string; // The label to display + checked: boolean; // The checked state of the checkbox + setChecked: (value: boolean) => void; // Method to update the state +} + +const CheckboxSetting: React.FC = ({ label, checked, setChecked }) => { + const handleCheckboxChange = () => { + setChecked(!checked); + }; + + return ( +
+ +
+ ); +}; + +export default CheckboxSetting; diff --git a/app/components/settings/ColorSettings.tsx b/app/components/settings/ColorSettings.tsx index 42b69f8..4ada123 100644 --- a/app/components/settings/ColorSettings.tsx +++ b/app/components/settings/ColorSettings.tsx @@ -1,29 +1,29 @@ -import React from 'react'; + import React from 'react'; -interface ColorSettingProps { - name: string; // The name to display in the

tag - value: string; // The current color value - setValue: (newColor: string) => void; // The method to update the state - cssVariable: string; // The CSS variable name to set -} + interface ColorSettingProps { + name: string; // The name to display in the

tag + value: string; // The current color value + setValue: (newColor: string) => void; // The method to update the state + cssVariable: string; // The CSS variable name to set + } -const ColorSetting: React.FC = ({ name, value, setValue, cssVariable }) => { - const handleColorChange = (e: React.ChangeEvent) => { - const newColor = e.target.value; - setValue(newColor); - document.documentElement.style.setProperty(cssVariable, newColor); - }; + const ColorSetting: React.FC = ({ name, value, setValue, cssVariable }) => { + const handleColorChange = (e: React.ChangeEvent) => { + const newColor = e.target.value; + setValue(newColor); + document.documentElement.style.setProperty(cssVariable, newColor); + }; - return ( -

-

{name}

- -
- ); -}; + return ( +
+

{name}

+ +
+ ); + }; -export default ColorSetting; + export default ColorSetting; diff --git a/app/components/settings/DropDown.tsx b/app/components/settings/DropDown.tsx new file mode 100644 index 0000000..9b0f79d --- /dev/null +++ b/app/components/settings/DropDown.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +interface Option { + value: string; // The actual value to be used + label: string; // The label to display for the option +} + +interface DropdownSettingProps { + label: string; // The label to display + value: string; // The current selected value + setValue: (newValue: string) => void; // The method to update the state + options: Option[]; // List of options for the dropdown +} + +const DropdownSetting: React.FC = ({ label, value, setValue, options }) => { + const handleSelectChange = (e: React.ChangeEvent) => { + const newValue = e.target.value; + setValue(newValue); + }; + + return ( +
+ + +
+ ); +}; + +export default DropdownSetting; diff --git a/app/components/settings/DropDownTheme.tsx b/app/components/settings/DropDownTheme.tsx new file mode 100644 index 0000000..955158f --- /dev/null +++ b/app/components/settings/DropDownTheme.tsx @@ -0,0 +1,41 @@ +// ThemeDropdown.tsx +import React from 'react'; +import { applyTheme, applyCustomTheme } from './theme'; + +const ThemeDropdown: React.FC<{ + selectedTheme: string; + setSelectedTheme: (theme: string) => void; +}> = ({ selectedTheme, setSelectedTheme }) => { + const themeOptions = [ + { value: 'IOMARKET', label: 'IOMARKET' }, + { value: 'WHITE', label: 'WHITE' }, + { value: 'BLACK', label: 'BLACK' }, + { value: 'CUSTOM', label: 'CUSTOM' }, + ]; + + return ( +
+

Select Theme

+ +
+ ); +}; + +export default ThemeDropdown; diff --git a/app/components/settings/FontSize.tsx b/app/components/settings/FontSize.tsx new file mode 100644 index 0000000..d126ca5 --- /dev/null +++ b/app/components/settings/FontSize.tsx @@ -0,0 +1,31 @@ +// FontSizeSetting.tsx +import React from 'react'; + +interface FontSizeSettingProps { + fontSize: string; // The current font size + setFontSize: (newSize: string) => void; // Function to update the font size +} + +const FontSizeSetting: React.FC = ({ fontSize, setFontSize }) => { + const handleFontSizeChange = (e: React.ChangeEvent) => { + const newSize = `${e.target.value}px`; + setFontSize(newSize); + document.documentElement.style.setProperty('--font-size', newSize); + }; + + return ( +
+

Font Size

+ + {fontSize} +
+ ); +}; + +export default FontSizeSetting; diff --git a/app/components/settings/OpenSourceToggle.tsx b/app/components/settings/OpenSourceToggle.tsx new file mode 100644 index 0000000..9e60415 --- /dev/null +++ b/app/components/settings/OpenSourceToggle.tsx @@ -0,0 +1,41 @@ +// OpenSourceModeToggle.tsx +import React from 'react'; + +interface OpenSourceModeToggleProps { + openSourceMode: boolean; // Current state of open source mode + setOpenSourceMode: (value: boolean) => void; // Function to update open source mode + setSelectedOption: (value: string) => void; // Function to update the selected option +} + +const OpenSourceModeToggle: React.FC = ({ + openSourceMode, + setOpenSourceMode, + setSelectedOption +}) => { + const handleToggleChange = () => { + const newValue = !openSourceMode; + setOpenSourceMode(newValue); + + // Update radio selection based on the new openSourceMode value + if (newValue) { + setSelectedOption('FOSS'); // Set to FOSS if enabling open source mode + } else { + setSelectedOption('None'); // Or any other default value when disabling + } + }; + + return ( +
+ +
+ ); +}; + +export default OpenSourceModeToggle; diff --git a/app/components/settings/PrivacySettings.tsx b/app/components/settings/PrivacySettings.tsx new file mode 100644 index 0000000..d7ff28e --- /dev/null +++ b/app/components/settings/PrivacySettings.tsx @@ -0,0 +1,50 @@ +// PrivacySettings.tsx +import React from 'react'; + +interface PrivacySettingsProps { + selectedOption: string; // The currently selected option + handleRadioChange: (option: string) => void; // Function to handle option changes + openSourceMode: boolean; // Boolean to check if the mode is open source +} + +const PrivacySettings: React.FC = ({ selectedOption, handleRadioChange, openSourceMode }) => { + return ( + <> + {/* AI Mode Radio Options */} +
+

Disable Options:

+
+ {/* Offline */} +
handleRadioChange('Offline')} // Allow selection only if not in open-source mode + > + Offline tools{openSourceMode ? ' (FOSS)' : ''} +
+ + {/* Online */} +
handleRadioChange('Online')} + > + Online tools{openSourceMode ? ' (FOSS)' : ''} +
+ + {/* None */} +
handleRadioChange('None')} + > + None{openSourceMode ? ' (FOSS)' : ''} +
+
+
+

+ After changing the preferred settings, please reload the website so it can update itself properly. +

+
+ + ); +}; + +export default PrivacySettings; diff --git a/app/components/settings/Settings.tsx b/app/components/settings/Settings.tsx index feb5558..a35131f 100644 --- a/app/components/settings/Settings.tsx +++ b/app/components/settings/Settings.tsx @@ -3,11 +3,19 @@ import { applyTheme, applyCustomTheme } from './theme'; import { exportSettings, importSettings } from './settingUtils'; // Import utility functions import { getAllLocalStorageItems } from '../../backend/GetLocalStorage'; import ColorSetting from './ColorSettings'; +import TextSettings from './TextSettings' +import ButtonSetting from './ButtonSettings'; +import DropdownSetting from './DropDown'; +import CheckboxSetting from './CheckBox'; +import PrivacySettings from './PrivacySettings'; +import FontSizeSetting from './FontSize'; +import OpenSourceModeToggle from './OpenSourceToggle'; import { changePassword, changeData, deleteAccount, } from '../../backend/database'; +import ThemeDropdown from './DropDownTheme'; const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ({ closeSettings, accountName }) => { @@ -64,6 +72,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( // Theme settings const [backgroundColor, setBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--background-color').trim()); + const [headerBackground, setHeaderBackground] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--header-background-color').trim()); const [textColor, setTextColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim()); const [inputBackgroundColor, setInputBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--input-background-color').trim()); const [inputButtonColor, setInputButtonColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--input-button-color').trim()); @@ -97,8 +106,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( const [selectedTheme, setSelectedTheme] = useState(''); // API Keys - const [mistral, setmistral] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-la-plateforme').trim()); - const [openai, setopenai] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-openai').trim()); + const [mistral, setMistral] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-la-plateforme').trim()); + const [openai, setOpenai] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-openai').trim()); const [anthropic, setAnthropic] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-anthropic').trim()); const [google, setGoogle] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-google').trim()); @@ -123,6 +132,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( }, theme: { backgroundColor, + headerBackground, textColor, inputBackgroundColor, inputButtonColor, @@ -166,6 +176,109 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( }, }; + const colorSettings = [ + { name: "Background Color", value: headerBackground, setValue: setBackgroundColor, cssVariable: "--background-color" }, + { name: "Header Background Color", value: backgroundColor, setValue: setHeaderBackground, cssVariable: "--background-color" }, + { name: "Text Color", value: textColor, setValue: setTextColor, cssVariable: "--text-color" }, + { name: "Input Background Color", value: inputBackgroundColor, setValue: setInputBackgroundColor, cssVariable: "--input-background-color" }, + { name: "Input Button Color", value: inputButtonColor, setValue: setInputButtonColor, cssVariable: "--input-button-color" }, + { name: "Input Button Hover Color", value: inputButtonHoverColor, setValue: setInputButtonHoverColor, cssVariable: "--input-button-hover-color" }, + { name: "User Message Background Color", value: userMessageBackgroundColor, setValue: setUserMessageBackgroundColor, cssVariable: "--user-message-background-color" }, + { name: "User Message Text Color", value: userMessageTextColor, setValue: setUserMessageTextColor, cssVariable: "--user-message-text-color" }, + { name: "AI Message Background Color", value: aiMessageBackgroundColor, setValue: setAiMessageBackgroundColor, cssVariable: "--ai-message-background-color" }, + { name: "AI Message Text Color", value: aiMessageTextColor, setValue: setAiMessageTextColor, cssVariable: "--ai-message-text-color" }, + { name: "Button Background Color", value: buttonBackgroundColor, setValue: setButtonBackgroundColor, cssVariable: "--button-background-color" }, + { name: "Button Hover Background Color", value: buttonHoverBackgroundColor, setValue: setButtonHoverBackgroundColor, cssVariable: "--button-hover-background-color" }, + { name: "Models Background Color", value: modelsBackgroundColor, setValue: setModelsBackgroundColor, cssVariable: "--models-background-color" }, + { name: "History Background Color", value: historyBackgroundColor, setValue: setHistoryBackgroundColor, cssVariable: "--history-background-color" }, + { name: "Left Panel Background Color", value: leftPanelBackgroundColor, setValue: setLeftPanelBackgroundColor, cssVariable: "--left-panel-background-color" }, + { name: "Conversation Background Color", value: conversationBackgroundColor, setValue: setConversationBackgroundColor, cssVariable: "--conversation-background-color" }, + { name: "Pop-up Text Color", value: popUpTextColor, setValue: setPopUpTextColor, cssVariable: "--pop-up-text" }, + { name: "Input Border Color", value: inputBorderColor, setValue: setInputBorderColor, cssVariable: "--input-border-color" }, + { name: "FAQ Background Color", value: faqBackgroundColor, setValue: setFaqBackgroundColor, cssVariable: "--faq-background-color" }, + { name: "FAQ Heading Color", value: faqHeadingColor, setValue: setFaqHeadingColor, cssVariable: "--faq-heading-color" }, + { name: "FAQ Item Background Color", value: faqItemBackgroundColor, setValue: setFaqItemBackgroundColor, cssVariable: "--faq-item-background-color" }, + { name: "FAQ Item Heading Color", value: faqItemHeadingColor, setValue: setFaqItemHeadingColor, cssVariable: "--faq-item-heading-color" }, + { name: "FAQ Item Text Color", value: faqItemTextColor, setValue: setFaqItemTextColor, cssVariable: "--faq-item-text-color" }, + { name: "FAQ Item Hover Background Color", value: faqItemHoverBackgroundColor, setValue: setFaqItemHoverBackgroundColor, cssVariable: "--faq-item-hover-background-color" }, + { name: "Popup Background Color", value: popupBackgroundColor, setValue: setPopupBackgroundColor, cssVariable: "--popup-background-color" }, + { name: "Overlay Text Color", value: overlayTextColor, setValue: setOverlayTextColor, cssVariable: "--overlay-text-color" }, + ]; + + const timeZoneOptions = [ + { value: 'GMT', label: 'GMT' }, + { value: 'EST', label: 'EST' }, + { value: 'CST', label: 'CST' }, + { value: 'MST', label: 'MST' }, + { value: 'PST', label: 'PST' }, + { value: 'UTC', label: 'UTC' }, + { value: 'BST', label: 'BST' }, + { value: 'IST', label: 'IST' }, + { value: 'CET', label: 'CET' }, + { value: 'JST', label: 'JST' }, + ]; + + + const languageOptions = [ + { code: 'en', name: 'English' }, + { code: 'es', name: 'Spanish' }, + { code: 'fr', name: 'French' }, + { code: 'de', name: 'German' }, + { code: 'it', name: 'Italian' }, + { code: 'pt', name: 'Portuguese' }, + { code: 'zh', name: 'Chinese' }, + { code: 'ja', name: 'Japanese' }, + { code: 'ru', name: 'Russian' }, + { code: 'ar', name: 'Arabic' }, + ]; + + const currencyOptions = [ + { code: 'usd', name: 'USD' }, + { code: 'eur', name: 'EUR' }, + { code: 'gbp', name: 'GBP' }, + { code: 'jpy', name: 'JPY' }, + { code: 'cad', name: 'CAD' }, + { code: 'aud', name: 'AUD' }, + { code: 'chf', name: 'CHF' }, + { code: 'cny', name: 'CNY' }, + { code: 'inr', name: 'INR' }, + ]; + + const dateFormatOptions = [ + { value: 'mm/dd/yyyy', label: 'MM/DD/YYYY' }, + { value: 'dd/mm/yyyy', label: 'DD/MM/YYYY' }, + { value: 'yyyy-mm-dd', label: 'YYYY-MM-DD' }, + { value: 'mm-dd-yyyy', label: 'MM-DD-YYYY' }, + { value: 'dd-mm-yyyy', label: 'DD-MM-YYYY' }, + ]; + + const timeFormatOptions = [ + { value: '12-hour', label: '12 Hour' }, + { value: '24-hour', label: '24 Hour' }, + ]; + + const measurementOptions = [ + { value: 'Metric', label: 'Metric' }, + { value: 'Imperial', label: 'Imperial' }, + ]; + + const fontOptions = [ + { value: "'Poppins', sans-serif", label: 'Poppins' }, + { value: "'Inconsolata', monospace", label: 'Inconsolata' }, + { value: "'Merriweather', serif", label: 'Merriweather' }, + { value: "'Noto Sans', sans-serif", label: 'Noto Sans' }, + { value: "'Noto Serif', serif", label: 'Noto Serif' }, + { value: "'Playfair Display', serif", label: 'Playfair Display' }, + { value: "'Roboto', sans-serif", label: 'Roboto' }, + { value: "'Ubuntu', sans-serif", label: 'Ubuntu' }, + { value: "'Bangers', cursive", label: 'Bangers' }, + { value: "'Caveat', cursive", label: 'Caveat' }, + { value: "'Frederika the Great', cursive", label: 'Frederika the Great' }, + { value: "'Rock Salt', cursive", label: 'Rock Salt' }, + { value: "'Sofadi One', sans-serif", label: 'Sofadi One' }, + { value: "'Zilla Slab Highlight', serif", label: 'Zilla Slab Highlight' }, + ]; + const handleLogout = () => { setIsLoggedIn(false); localStorage.removeItem('accountName'); @@ -265,98 +378,47 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (

General Settings

-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- - {/* New Preferred Measurement Option */} -
- - -
+ ({ value: lang.code, label: lang.name }))} // Convert to Option format + /> + + ({ value: currency.code, label: currency.name }))} // Convert to Option format + /> + + + + + + + +
); @@ -364,63 +426,23 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( return (

Privacy Settings

- {/* AI Mode Radio Options */} -
-

Disable Options:

-
- {/* Offline */} -
handleRadioChange('Offline')} // Allow selection only if not in open-source mode - > - Offline tools{openSourceMode ? ' (FOSS)' : ''} -
- {/* Online */} -
handleRadioChange('Online')} - > - Online tools{openSourceMode ? ' (FOSS)' : ''} -
+ - {/* None */} -
handleRadioChange('None')} - > - None{openSourceMode ? ' (FOSS)' : ''} -
-
-
-

- After changing the preferred settings, please reload the website so it can update itself properly. -

-
- - {/* Disable Chat History Checkbox */} -
- -
- - {/* Disable AI Memory Checkbox */} -
- -
+ +
); @@ -430,234 +452,38 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (

Theme Settings

- {/* Dropdown to select theme */} -
-

Select Theme

- -
- {/* Conditionally render theme settings only if "CUSTOM" is selected */} + + {selectedTheme === 'CUSTOM' && ( <> {/* Font Size */} -
-

Font Size

- { - const newSize = `${e.target.value}px`; - setFontSize(newSize); - document.documentElement.style.setProperty('--font-size', newSize); - }} + + + {colorSettings.map((setting) => ( + - {fontSize} -
+ ))} - { + setFontFamily(newFont); + document.documentElement.style.setProperty('--font-family', newFont); + }} + options={fontOptions} /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Font Family

- -
)}
@@ -668,25 +494,11 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( return (

Open Source Settings

-
- -
+
); @@ -695,100 +507,75 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( return (

Account Settings

-
- - setNewName(e.target.value)} + -
-
- - setNewEmail(e.target.value)} + setValue={setNewEmail} + type="email" // Input type is email /> -
-
- - setNewPassword(e.target.value)} + setValue={setNewPassword} + type="password" // Input type is password /> -
-
- - setCurrentPassword(e.target.value)} + setValue={setCurrentPassword} + type="password" // Input type is password + /> + + +
-
- -
-
- -
-
- -
-
); case 'api': return (
-
- - setmistral(e.target.value)} + -
-
- - setopenai(e.target.value)} + -
-
- - setAnthropic(e.target.value)} + -
-
- - setGoogle(e.target.value)} + -
); @@ -804,7 +591,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (

Import the settings

- + ); default: @@ -820,8 +607,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( } }; - // Gather all settings into an object - // Gather current settings into an object const currentSettings = { ...settings.userPreferences, ...settings.theme, diff --git a/app/components/settings/TextSettings.tsx b/app/components/settings/TextSettings.tsx new file mode 100644 index 0000000..ef8aafc --- /dev/null +++ b/app/components/settings/TextSettings.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +interface TextSettingProps { + label: string; // The label to display + value: string; // The current text value + setValue: (newText: string) => void; // The method to update the state + type: 'text' | 'email' | 'password'; // The type of input field +} + +const TextSetting: React.FC = ({ label, value, setValue, type }) => { + const handleTextChange = (e: React.ChangeEvent) => { + const newText = e.target.value; // Get the new value from the input + setValue(newText); // Update the state in the parent component + }; + + return ( +
+ + +
+ ); +}; + +export default TextSetting;