diff --git a/app/backend/GetLocalStorage.ts b/app/backend/GetLocalStorage.ts index 529d444..e838f74 100644 --- a/app/backend/GetLocalStorage.ts +++ b/app/backend/GetLocalStorage.ts @@ -2,7 +2,7 @@ export const getAllLocalStorageItems = (): Record => { const allData: Record = {}; - + if (typeof localStorage !== 'undefined') { for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key) { @@ -10,6 +10,7 @@ export const getAllLocalStorageItems = (): Record => { allData[key] = value; } } + } return allData; }; \ No newline at end of file diff --git a/app/backend/InputOutputHandler.tsx b/app/backend/InputOutputHandler.tsx index c584cb9..64fc4f1 100644 --- a/app/backend/InputOutputHandler.tsx +++ b/app/backend/InputOutputHandler.tsx @@ -20,23 +20,25 @@ const InputOutputBackend: React.FC = () => { const [timeZone, setTimeZone] = useState("GMT"); const [dateFormat, setDateFormat] = useState("DD-MM-YYYY"); const [messages, setMessages] = useState([]); - const [myBoolean, setMyBoolean] = useState(() => localStorage.getItem('myBoolean') === 'true') || false; + const [myBoolean, setMyBoolean] = useState(false); const apiURL = new URL("http://localhost:5000/interstellar_ai/api/ai_create") - apiURL.hostname = window.location.hostname; - - // Fetch local storage values and update state on component mount - useEffect(() => { - setPreferredCurrency(localStorage.getItem("preferredCurrency") || "USD"); - setPreferredLanguage(localStorage.getItem("preferredLanguage") || "english"); - setTimeFormat(localStorage.getItem("timeFormat") || "24-hour"); - setPreferredMeasurement(localStorage.getItem("preferredMeasurement") || "metric"); - setTimeZone(localStorage.getItem("timeZone") || "GMT"); - setDateFormat(localStorage.getItem("dateFormat") || "DD-MM-YYYY"); - setMyBoolean(localStorage.getItem('myBoolean') === 'true'); - }, []); - + if (typeof window !== 'undefined') { + apiURL.hostname = window.location.hostname; + } else { + apiURL.hostname = "localhost" + } + // Update messages when any of the settings change useEffect(() => { + if (typeof localStorage !== 'undefined') { + setPreferredCurrency(localStorage.getItem("preferredCurrency") || "USD"); + setPreferredLanguage(localStorage.getItem("preferredLanguage") || "english"); + setTimeFormat(localStorage.getItem("timeFormat") || "24-hour"); + setPreferredMeasurement(localStorage.getItem("preferredMeasurement") || "metric"); + setTimeZone(localStorage.getItem("timeZone") || "GMT"); + setDateFormat(localStorage.getItem("dateFormat") || "DD-MM-YYYY"); + setMyBoolean(localStorage.getItem('myBoolean') === 'true'); + } const measurementString = (preferredMeasurement == "Metric") ? "All measurements follow the metric system. Refuse to use any other measurement system." : "All measurements follow the imperial system. Refuse to use any other measurement system."; @@ -113,7 +115,12 @@ const InputOutputBackend: React.FC = () => { if (!getWorkerRef.current) { getWorkerRef.current = new Worker(new URL("./threads/GetWorker.ts", import.meta.url)) - const windowname = window.location.hostname + let windowname = "localhost" + if (typeof window !== 'undefined') { + windowname = window.location.hostname + } else { + windowname = "localhost" + } getWorkerRef.current.postMessage({ action: "start", access_token: accessToken, windowname }) @@ -169,12 +176,15 @@ const InputOutputBackend: React.FC = () => { setInputDisabled(true) if (postWorkerRef.current) { addMessage("user", inputValue) - const type = localStorage.getItem('type') + let type:string = "local" let api_key: string = "" - if (type != null && type != 'local') { - const try_key = localStorage.getItem(type) - if (try_key) { - api_key = try_key + if (typeof localStorage !== 'undefined') { + type = localStorage.getItem('type') || "local" + if (type != null && type != 'local') { + const try_key = localStorage.getItem(type) + if (try_key) { + api_key = try_key + } } } setInputMessage("") diff --git a/app/backend/database.ts b/app/backend/database.ts index cb52199..7ef1870 100644 --- a/app/backend/database.ts +++ b/app/backend/database.ts @@ -125,9 +125,11 @@ export const checkCredentials = async (usernameOrEmail: string, password: string }; const sendBack = await sendToDatabase(data); if (sendBack) { - localStorage.setItem("accountEmail", await getEmail(usernameOrEmail, password)) - localStorage.setItem("accountName", await getName(usernameOrEmail, password)) - localStorage.setItem("accountPassword", password) + if (typeof localStorage !== 'undefined') { + localStorage.setItem("accountEmail", await getEmail(usernameOrEmail, password)) + localStorage.setItem("accountName", await getName(usernameOrEmail, password)) + localStorage.setItem("accountPassword", password) + } } return sendBack }; diff --git a/app/backend/voice_backend.ts b/app/backend/voice_backend.ts index 7716f0d..d950380 100644 --- a/app/backend/voice_backend.ts +++ b/app/backend/voice_backend.ts @@ -6,7 +6,11 @@ export const sendToVoiceRecognition = (audio_data: Blob): Promise => { formdata.append("audio", audio_data) const apiURL = new URL("http://localhost:5000/interstellar_ai/api/voice_recognition") - apiURL.hostname = window.location.hostname; + if (typeof window !== 'undefined') { + apiURL.hostname = window.location.hostname; + } else { + apiURL.hostname = "localhost" + } return axios.post(apiURL.href, formdata) .then((response) => { diff --git a/app/components/Login.tsx b/app/components/Login.tsx index f98ffb4..1660f39 100644 --- a/app/components/Login.tsx +++ b/app/components/Login.tsx @@ -23,20 +23,27 @@ const Login: React.FC = () => { // On component mount, check if there are credentials in localStorage useEffect(() => { - const savedAccountName = localStorage.getItem('accountName'); - const savedAccountEmail = localStorage.getItem('accountEmail'); - const savedAccountPassword = localStorage.getItem('accountPassword'); - - // If credentials are found in localStorage, log the user in - if (savedAccountName && savedAccountEmail && savedAccountPassword) { - setAccountName(savedAccountName); - setEmail(savedAccountEmail); - setPassword(savedAccountPassword); - const check = async () => { - const success = await checkCredentials(savedAccountName, savedAccountPassword); - setIsLoggedIn(success); // Automatically log in - }; - check(); + let savedAccountName:string|null; + let savedAccountEmail:string|null; + let savedAccountPassword:string|null; + if (typeof localStorage !== 'undefined') { + savedAccountName = localStorage.getItem('accountName'); + savedAccountEmail = localStorage.getItem('accountEmail'); + savedAccountPassword = localStorage.getItem('accountPassword'); + + // If credentials are found in localStorage, log the user in + if (savedAccountName && savedAccountEmail && savedAccountPassword) { + setAccountName(savedAccountName); + setEmail(savedAccountEmail); + setPassword(savedAccountPassword); + const check = async () => { + if (savedAccountName !== null && savedAccountPassword !== null) { + const success = await checkCredentials(savedAccountName, savedAccountPassword); + setIsLoggedIn(success); // Automatically log in + } + }; + check(); + } } }, []); @@ -57,7 +64,9 @@ const Login: React.FC = () => { setIsLoggedIn(true); // Successful login const data = await getData(accountName, password) if (data) { - localStorage.setItem("dataFromServer", data) + if (typeof localStorage !== 'undefined') { + localStorage.setItem("dataFromServer", data) + } } setShowLoginPopup(false); // Close the login popup } else { diff --git a/app/components/Models.tsx b/app/components/Models.tsx index 5e56519..4e64b33 100644 --- a/app/components/Models.tsx +++ b/app/components/Models.tsx @@ -173,60 +173,72 @@ const ModelSection: React.FC = () => { const [radioSelection, setRadioSelection] = useState("") const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(''); const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState(""); - const [isOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false") + const [isOpenSourceMode, setIsOpenSourceMode] = useState("false") useEffect(() => { - const temp = localStorage.getItem("activeSelectedAIFunction") || "" - setActiveSelectedAIFunction(temp) - if (!localStorage.getItem('selectedModelDropdown')) { - localStorage.setItem("selectedModelDropdown", "Offline Fast") - } - - 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') - } - - const handleStorageChange = () => { + if (typeof localStorage !== 'undefined') { + + setIsOpenSourceMode(localStorage.getItem("openSourceMode")) + const temp = localStorage.getItem("activeSelectedAIFunction") || "" + setActiveSelectedAIFunction(temp) + if (!localStorage.getItem('selectedModelDropdown')) { + localStorage.setItem("selectedModelDropdown", "Offline Fast") + } + + 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') + } + + 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') || ''); - }; - - // Update immediately when localStorage changes - window.addEventListener('storage', handleStorageChange); - - setRadioSelection(localStorage.getItem('radioSelection') || ''); - setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); - // Cleanup listener on component unmount - return () => { - window.removeEventListener('storage', handleStorageChange); - }; + // 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(() => { - const storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || ""; - if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) { - setCurrentSelectedAIFunction(storedActiveSelectedAIFunction); + if (typeof localStorage !== 'undefined') { + const storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || ""; + if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) { + setCurrentSelectedAIFunction(storedActiveSelectedAIFunction); + } } }, [activeSelectedAIFunction]); const handleModelChange = (event: React.ChangeEvent) => { const newModel = event.target.value; setSelectedModelDropdown(newModel); - localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly - const model = localStorage.getItem('activeSelectedAIFunction') || "Code" - modelClicked(model) + if (typeof localStorage !== 'undefined') { + localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly + const model = localStorage.getItem('activeSelectedAIFunction') || "Code" + modelClicked(model) + } }; // Determine the filtered models based on current radioSelection @@ -285,12 +297,14 @@ const ModelSection: React.FC = () => { modelDropdown.offlineNonFoss.includes(model) || modelDropdown.offlineFoss.includes(model); const modelClicked = (model: string) => { - localStorage.setItem('activeSelectedAIFunction', model) - setActiveSelectedAIFunction(model) - const modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast' - const selectedAIFunction = modelDropdown as keyof typeof modelList; - localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]]) - localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]]) + if (typeof localStorage !== 'undefined') { + localStorage.setItem('activeSelectedAIFunction', model) + setActiveSelectedAIFunction(model) + const modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast' + const selectedAIFunction = modelDropdown as keyof typeof modelList; + localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]]) + localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]]) + } } return ( diff --git a/app/components/settings/DropDownTheme.tsx b/app/components/settings/DropDownTheme.tsx index 8609d9b..793a19d 100644 --- a/app/components/settings/DropDownTheme.tsx +++ b/app/components/settings/DropDownTheme.tsx @@ -20,7 +20,7 @@ const ThemeDropdown: React.FC<{ value={selectedTheme} onChange={(e) => { const theme = e.target.value; - if (theme !== 'default') { + if (theme !== 'default' && typeof localStorage !== 'undefined') { setSelectedTheme(theme); localStorage.setItem('selectedTheme', theme); } diff --git a/app/components/settings/Settings.tsx b/app/components/settings/Settings.tsx index 092bdfb..0e3e8b1 100644 --- a/app/components/settings/Settings.tsx +++ b/app/components/settings/Settings.tsx @@ -19,8 +19,12 @@ import ThemeDropdown from './DropDownTheme'; const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ({ closeSettings, accountName }) => { + //#region initialize Variables + let item:string|null; const getItemFromLocalStorage = (key: string) => { - const item = localStorage.getItem(key); + if (typeof localStorage !== 'undefined') { + item = localStorage.getItem(key) + } if (item) { try { @@ -35,32 +39,48 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( }; // Active section - const [activeSection, setActiveSection] = useState(() => localStorage.getItem('activeSection') || 'general'); + const [activeSection, setActiveSection] = useState('general'); // Language setting - const [preferredLanguage, setPreferredLanguage] = useState(() => localStorage.getItem('preferredLanguage') || 'en'); + const [preferredLanguage, setPreferredLanguage] = useState("en"); // Currency setting - const [preferredCurrency, setPreferredCurrency] = useState(() => localStorage.getItem('preferredCurrency') || 'usd'); + const [preferredCurrency, setPreferredCurrency] = useState('usd'); // Date and time format settings - const [dateFormat, setDateFormat] = useState(() => localStorage.getItem('dateFormat') || 'mm/dd/yyyy'); - const [timeFormat, setTimeFormat] = useState(() => localStorage.getItem('timeFormat') || '12-hour'); - const [timeZone, setTimeZone] = useState(() => localStorage.getItem('timeZone') || 'GMT'); + const [dateFormat, setDateFormat] = useState('mm/dd/yyyy'); + const [timeFormat, setTimeFormat] = useState('12-hour'); + const [timeZone, setTimeZone] = useState('GMT'); // Online AI and chat history settings const [selectedOption, setSelectedOption] = useState('Offline'); // Default to 'Offline' - const [disableChatHistory, setDisableChatHistory] = useState(() => getItemFromLocalStorage('disableChatHistory')); - const [disableAIMemory, setDisableAIMemory] = useState(() => getItemFromLocalStorage('disableAIMemory')); - const [openSourceMode, setOpenSourceMode] = useState(() => getItemFromLocalStorage('openSourceMode')); + const [disableChatHistory, setDisableChatHistory] = useState(false); + const [disableAIMemory, setDisableAIMemory] = useState(false); + const [openSourceMode, setOpenSourceMode] = useState(false); // User credentials - const [newName, setNewName] = useState(() => localStorage.getItem('newName') || ''); - const [newEmail, setNewEmail] = useState(() => localStorage.getItem('newEmail') || ''); - const [newPassword, setNewPassword] = useState(() => localStorage.getItem('newPassword') || ''); + const [newName, setNewName] = useState(''); + const [newEmail, setNewEmail] = useState(''); + const [newPassword, setNewPassword] = useState(''); // Measurement setting - const [preferredMeasurement, setPreferredMeasurement] = useState(() => localStorage.getItem('preferredMeasurement') || 'Metric'); + const [preferredMeasurement, setPreferredMeasurement] = useState('Metric'); + + useEffect(() => { + setActiveSection(getItemFromLocalStorage("activeSection") || "general") + setPreferredLanguage(getItemFromLocalStorage("preferredLanguage") || 'en') + setPreferredCurrency(getItemFromLocalStorage("preferredCurrency") || "usd") + setDateFormat(getItemFromLocalStorage("dateFormat") || "mm/dd/yyyy") + setTimeFormat(getItemFromLocalStorage("timeFormat") || "12-hour") + setTimeZone(getItemFromLocalStorage("timeZone") || "GMT") + setDisableChatHistory(getItemFromLocalStorage('disableChatHistory').toLowerCase()==="true") //#TODO Idk if it works + setDisableAIMemory(getItemFromLocalStorage('disableAIMemory').toLowerCase()==="true") + setOpenSourceMode(getItemFromLocalStorage('openSourceMode').toLowerCase() === "true") + setNewName(getItemFromLocalStorage("newName") || "") + setNewEmail(getItemFromLocalStorage("newEmail") || "") + setNewPassword(getItemFromLocalStorage("newPassword") || "") + setPreferredMeasurement(getItemFromLocalStorage("preferredMeasurement") || "Metric") + },[]) // Theme settings const [backgroundColor, setBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--background-color').trim()); @@ -99,22 +119,40 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( const [applyButtonHoverColor, setApplyButtonHoverColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--apply-button-hover-color').trim()); // Per default a purple color gradient - const [primaryColor, setPrimaryColor] = useState(localStorage.getItem("primaryColor") || "#dc8add"); - const [secondaryColor, setSecondaryColor] = useState(localStorage.getItem("secondaryColor") || "#c061cb"); - const [accentColor, setAccentColor] = useState(localStorage.getItem("accentColor") || "#9141ac"); - const [basicBackgroundColor, setBasicBackgroundColor] = useState(localStorage.getItem("basicBackgroundColor") || "#813d9c"); - const [basicTextColor, setBasicTextColor] = useState(localStorage.getItem("basicTextColor") || "#fefefe"); + const [primaryColor, setPrimaryColor] = useState("#dc8add"); + const [secondaryColor, setSecondaryColor] = useState("#c061cb"); + const [accentColor, setAccentColor] = useState("#9141ac"); + const [basicBackgroundColor, setBasicBackgroundColor] = useState("#813d9c"); + const [basicTextColor, setBasicTextColor] = useState("#fefefe"); + + useEffect(() => { + setPrimaryColor(getItemFromLocalStorage("primaryColor")) + setSecondaryColor(getItemFromLocalStorage("secondaryColor")) + setAccentColor(getItemFromLocalStorage("accentColor")) + setBasicBackgroundColor(getItemFromLocalStorage("basicBackgroundColor")) + setBasicTextColor(getItemFromLocalStorage("basicTextColor")) + },[]) // Theme selection const [selectedTheme, setSelectedTheme] = useState(''); // API Keys - const [mistral, setMistral] = useState(localStorage.getItem('mistral') || ""); - const [openai, setOpenai] = useState(localStorage.getItem('openai') || ""); - const [anthropic, setAnthropic] = useState(localStorage.getItem('anthropic') || ""); - const [google, setGoogle] = useState(localStorage.getItem('google') || ""); - const [myBoolean, setMyBoolean] = useState(() => getItemFromLocalStorage('myBoolean')); + const [mistral, setMistral] = useState(""); + const [openai, setOpenai] = useState(""); + const [anthropic, setAnthropic] = useState(""); + const [google, setGoogle] = useState(""); + const [myBoolean, setMyBoolean] = useState(false); + + useEffect(() => { + setMistral(getItemFromLocalStorage("mistral") || "") + setOpenai(getItemFromLocalStorage("openai") || "") + setAnthropic(getItemFromLocalStorage("anthropic") || "") + setGoogle(getItemFromLocalStorage("google") || "") + setMyBoolean(getItemFromLocalStorage("myBoolean").toLowerCase() === "true") + },[]) + + //#region set Settings const settings = { userPreferences: { @@ -287,17 +325,23 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( { value: "'Zilla Slab Highlight', serif", label: 'Zilla Slab Highlight' }, ]; + //#region functions for changing Settings + const handleLogout = () => { - localStorage.clear(); - alert('Successfully logged out!'); - window.location.reload(); + if (typeof window !!== "undefined" && typeof localStorage !== 'undefined') { + localStorage.clear(); + alert('Successfully logged out!'); + window.location.reload(); + } }; useEffect(() => { - const savedTheme = localStorage.getItem('selectedTheme'); - if (savedTheme) { - setSelectedTheme(savedTheme); - applyTheme(savedTheme, primaryColor, secondaryColor, accentColor, basicBackgroundColor, basicTextColor); + if (typeof localStorage !== 'undefined') { + const savedTheme = localStorage.getItem('selectedTheme'); + if (savedTheme) { + setSelectedTheme(savedTheme); + applyTheme(savedTheme, primaryColor, secondaryColor, accentColor, basicBackgroundColor, basicTextColor); + } } }, []); // Runs only once when the component mounts @@ -311,8 +355,10 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( ...settings.generalSettings, }; // Update localStorage for all settings - for (const [key, value] of Object.entries(flattenedSettings)) { - localStorage.setItem(key, typeof value === 'boolean' ? JSON.stringify(value) : value); + if (typeof localStorage !== 'undefined') { + for (const [key, value] of Object.entries(flattenedSettings)) { + localStorage.setItem(key, typeof value === 'boolean' ? JSON.stringify(value) : value); + } } }, [ ...Object.values(settings.userPreferences), @@ -322,41 +368,50 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( ]); useEffect(() => { - const savedOption = localStorage.getItem('radioSelection'); - if (savedOption) { - savedOption.replace(" (FOSS)", ""); - setSelectedOption(savedOption); // Set saved selection + if (typeof localStorage !== 'undefined') { + const savedOption = localStorage.getItem('radioSelection'); + if (savedOption) { + savedOption.replace(" (FOSS)", ""); + setSelectedOption(savedOption); // Set saved selection + } } }, []); const handleRadioChange = (newValue: string) => { - setSelectedOption(newValue); // Update the state with the selected option - localStorage.setItem('radioSelection', newValue); // Save the selection for persistence + if (typeof localStorage !== 'undefined') { + setSelectedOption(newValue); // Update the state with the selected option + localStorage.setItem('radioSelection', newValue); // Save the selection for persistence + } }; // Function to handle updating all credentials const handleUpdateCredentials = async () => { - let useName = localStorage.getItem("accountName") - let useEmail = localStorage.getItem("accountEmail") - let usePassword = localStorage.getItem("accountPassword") - if (useName && useEmail && usePassword) { - await deleteAccount(useName, usePassword) + if (typeof localStorage !== 'undefined') { + + let useName = localStorage.getItem("accountName") + let useEmail = localStorage.getItem("accountEmail") + let usePassword = localStorage.getItem("accountPassword") + if (useName && useEmail && usePassword) { + await deleteAccount(useName, usePassword) - if (newName != "") { - useName = newName - } if (newEmail != "") { - useEmail = newEmail - } if (newPassword != "") { - usePassword = newPassword - } + if (newName != "") { + useName = newName + } if (newEmail != "") { + useEmail = newEmail + } if (newPassword != "") { + usePassword = newPassword + } - if (await createAccount(useName, useEmail, usePassword)) { - if (await changeData(useName, usePassword, settings)) { - localStorage.setItem("currentName", useName) - localStorage.setItem("currentPassword", usePassword) - localStorage.setItem("currentEmail", useEmail) - alert('Account successfully changed!') - window.location.reload() + if (await createAccount(useName, useEmail, usePassword)) { + if (await changeData(useName, usePassword, settings)) { + if (typeof window !== 'undefined') { + localStorage.setItem("currentName", useName) + localStorage.setItem("currentPassword", usePassword) + localStorage.setItem("currentEmail", useEmail) + alert('Account successfully changed!') + window.location.reload() + } + } } } } @@ -364,22 +419,25 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( // Function to handle account deletion const handleDeleteAccount = async () => { - const useName = localStorage.getItem("accountName") - const usePassword = localStorage.getItem("accountPassword") - if (useName && usePassword) { - const success = await deleteAccount(useName, usePassword); - if (success) { - localStorage.clear(); - alert('Account deleted successfully!'); - window.location.reload() - // Optionally, redirect or reset state here - } else { - alert('Account deletion failed. Please check your password.'); + if (typeof localStorage !== 'undefined') { + + const useName = localStorage.getItem("accountName") + const usePassword = localStorage.getItem("accountPassword") + if (useName && usePassword) { + const success = await deleteAccount(useName, usePassword); + if (success && typeof window !== 'undefined' ) { + localStorage.clear(); + alert('Account deleted successfully!'); + window.location.reload() + // Optionally, redirect or reset state here + } else { + alert('Account deletion failed. Please check your password.'); + } } } }; - + //#region rendering // Render settings content based on the active section const renderSettingsContent = () => { switch (activeSection) { @@ -571,6 +629,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( case 'account': + const namePlaceholder = getItemFromLocalStorage("accountName") || "Current Name" + const emailPlaceholder = getItemFromLocalStorage("accountEmail") || "Current Email" return (

Account Settings

@@ -579,14 +639,14 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( value={newName} type='text' setValue={setNewName} - placeholder={localStorage.getItem("accountName") || "Current Name"} // Show current name or a default + placeholder={namePlaceholder} // Show current name or a default /> void; accountName: string }> = ( ); case 'api': + const mistral_APIKey_PlaceHolder = getItemFromLocalStorage("mistral") || "Enter the API key" + const openai_APIKey_PlaceHolder = getItemFromLocalStorage("openai") || "Enter the API key" + const anthropic_APIKey_PlaceHolder = getItemFromLocalStorage("anthropic") || "Enter the API key" + const google_APIKey_PlaceHolder = getItemFromLocalStorage("google") || "Enter the API key" return (
void; accountName: string }> = ( value={mistral} // State variable for the input setValue={setMistral} // State updater function type="text" // Input type - placeholder={localStorage.getItem('mistral') || "Enter the API key"} + placeholder={mistral_APIKey_PlaceHolder} />
@@ -633,7 +697,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( value={openai} // State variable for the input setValue={setOpenai} // State updater function type="text" // Input type - placeholder={localStorage.getItem('openai') || "Enter the API key"} + placeholder={openai_APIKey_PlaceHolder} />
@@ -645,7 +709,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( value={anthropic} // State variable for the input setValue={setAnthropic} // State updater function type="text" // Input type - placeholder={localStorage.getItem('anthropic') || "Enter the API key"} + placeholder={anthropic_APIKey_PlaceHolder} />
@@ -657,7 +721,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( value={google} // State variable for the input setValue={setGoogle} // State updater function type="text" // Input type - placeholder={localStorage.getItem('google') || "Enter the API key"} + placeholder={google_APIKey_PlaceHolder} />
@@ -742,8 +806,12 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( diff --git a/app/components/settings/settingUtils.ts b/app/components/settings/settingUtils.ts index 6ac1148..885ad98 100644 --- a/app/components/settings/settingUtils.ts +++ b/app/components/settings/settingUtils.ts @@ -5,11 +5,13 @@ export function exportSettings(): string { const settings: { [key: string]: string } = {}; // Loop through all keys in localStorage and add them to the settings object - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); - if (key) { - if (key !== "accountName" && key !== "accountPassword" && key !== "accountEmail") { - settings[key] = localStorage.getItem(key) || ""; + if (typeof localStorage !== 'undefined') { + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (key) { + if (key !== "accountName" && key !== "accountPassword" && key !== "accountEmail") { + settings[key] = localStorage.getItem(key) || ""; + } } } } @@ -24,9 +26,11 @@ export function importSettings(jsonData: string): void { const parsedSettings = JSON.parse(jsonData); // Loop through parsed settings and save them in localStorage - Object.keys(parsedSettings).forEach((key) => { - localStorage.setItem(key, parsedSettings[key]); - }); + if (typeof localStorage !== 'undefined') { + Object.keys(parsedSettings).forEach((key) => { + localStorage.setItem(key, parsedSettings[key]); + }); + } console.log("Settings imported successfully!"); } catch (error) { diff --git a/app/components/settings/theme.ts b/app/components/settings/theme.ts index 75c1c40..5c3a948 100644 --- a/app/components/settings/theme.ts +++ b/app/components/settings/theme.ts @@ -114,80 +114,82 @@ export const applyBlackTheme = () => { }; export const applyCustomTheme = () => { - const themeVariables = { - backgroundColor: localStorage.getItem('backgroundColor'), - headerBackground: localStorage.getItem('headerBackground'), - headerTextColor: localStorage.getItem('headerTextColor'), - textColor: localStorage.getItem('textColor'), - inputBackgroundColor: localStorage.getItem('inputBackgroundColor'), - inputButtonColor: localStorage.getItem('inputButtonColor'), - inputButtonHoverColor: localStorage.getItem('inputButtonHoverColor'), - userMessageBackgroundColor: localStorage.getItem('userMessageBackgroundColor'), - userMessageTextColor: localStorage.getItem('userMessageTextColor'), - aiMessageBackgroundColor: localStorage.getItem('aiMessageBackgroundColor'), - aiMessageTextColor: localStorage.getItem('aiMessageTextColor'), - buttonBackgroundColor: localStorage.getItem('buttonBackgroundColor'), - buttonHoverBackgroundColor: localStorage.getItem('buttonHoverBackgroundColor'), - modelsBackgroundColor: localStorage.getItem('modelsBackgroundColor'), - historyBackgroundColor: localStorage.getItem('historyBackgroundColor'), - leftPanelBackgroundColor: localStorage.getItem('leftPanelBackgroundColor'), - conversationBackgroundColor: localStorage.getItem('conversationBackgroundColor'), - docBackgroundColor: localStorage.getItem('docBackgroundColor'), - closeButtonColor: localStorage.getItem('closeButtonColor'), - closeButtonHoverColor: localStorage.getItem('closeButtonHoverColor'), - applyButtonColor: localStorage.getItem('applyButtonColor'), - applyButtonHoverColor: localStorage.getItem('applyButtonHoverColor'), - burgerMenu: localStorage.getItem('burgerMenu'), - overlayTextColor: localStorage.getItem('overlayTextColor'), - faqBackgroundColor: localStorage.getItem('faqBackgroundColor'), - faqHeadingColor: localStorage.getItem('faqHeadingColor'), - faqItemBackgroundColor: localStorage.getItem('faqItemBackgroundColor'), - faqItemHeadingColor: localStorage.getItem('faqItemHeadingColor'), - faqItemTextColor: localStorage.getItem('faqItemTextColor'), - faqItemHoverBackgroundColor: localStorage.getItem('faqItemHoverBackgroundColor'), - popupBackgroundColor: localStorage.getItem('popupBackgroundColor'), - popUpText: localStorage.getItem('popUpText'), - inputBorderColor: localStorage.getItem('inputBorderColor'), - fontFamily: localStorage.getItem('fontFamily'), - fontSize: localStorage.getItem('fontSize'), + if (typeof localStorage !== 'undefined') { + const themeVariables = { + backgroundColor: localStorage.getItem('backgroundColor'), + headerBackground: localStorage.getItem('headerBackground'), + headerTextColor: localStorage.getItem('headerTextColor'), + textColor: localStorage.getItem('textColor'), + inputBackgroundColor: localStorage.getItem('inputBackgroundColor'), + inputButtonColor: localStorage.getItem('inputButtonColor'), + inputButtonHoverColor: localStorage.getItem('inputButtonHoverColor'), + userMessageBackgroundColor: localStorage.getItem('userMessageBackgroundColor'), + userMessageTextColor: localStorage.getItem('userMessageTextColor'), + aiMessageBackgroundColor: localStorage.getItem('aiMessageBackgroundColor'), + aiMessageTextColor: localStorage.getItem('aiMessageTextColor'), + buttonBackgroundColor: localStorage.getItem('buttonBackgroundColor'), + buttonHoverBackgroundColor: localStorage.getItem('buttonHoverBackgroundColor'), + modelsBackgroundColor: localStorage.getItem('modelsBackgroundColor'), + historyBackgroundColor: localStorage.getItem('historyBackgroundColor'), + leftPanelBackgroundColor: localStorage.getItem('leftPanelBackgroundColor'), + conversationBackgroundColor: localStorage.getItem('conversationBackgroundColor'), + docBackgroundColor: localStorage.getItem('docBackgroundColor'), + closeButtonColor: localStorage.getItem('closeButtonColor'), + closeButtonHoverColor: localStorage.getItem('closeButtonHoverColor'), + applyButtonColor: localStorage.getItem('applyButtonColor'), + applyButtonHoverColor: localStorage.getItem('applyButtonHoverColor'), + burgerMenu: localStorage.getItem('burgerMenu'), + overlayTextColor: localStorage.getItem('overlayTextColor'), + faqBackgroundColor: localStorage.getItem('faqBackgroundColor'), + faqHeadingColor: localStorage.getItem('faqHeadingColor'), + faqItemBackgroundColor: localStorage.getItem('faqItemBackgroundColor'), + faqItemHeadingColor: localStorage.getItem('faqItemHeadingColor'), + faqItemTextColor: localStorage.getItem('faqItemTextColor'), + faqItemHoverBackgroundColor: localStorage.getItem('faqItemHoverBackgroundColor'), + popupBackgroundColor: localStorage.getItem('popupBackgroundColor'), + popUpText: localStorage.getItem('popUpText'), + inputBorderColor: localStorage.getItem('inputBorderColor'), + fontFamily: localStorage.getItem('fontFamily'), + fontSize: localStorage.getItem('fontSize'), + }; + + document.documentElement.style.setProperty('--header-background-color', themeVariables.headerBackground || '#7e7e7e'); + document.documentElement.style.setProperty('--header-text-color', themeVariables.headerTextColor || '#ffffff'); + document.documentElement.style.setProperty('--background-color', themeVariables.backgroundColor || '#121212'); + document.documentElement.style.setProperty('--text-color', themeVariables.textColor || '#e0e0e0'); + document.documentElement.style.setProperty('--input-background-color', themeVariables.inputBackgroundColor || '#1e1e1e'); + document.documentElement.style.setProperty('--input-button-color', themeVariables.inputButtonColor || '#3c3c3c'); + document.documentElement.style.setProperty('--input-button-hover-color', themeVariables.inputButtonHoverColor || '#5a5a5a'); + document.documentElement.style.setProperty('--user-message-background-color', themeVariables.userMessageBackgroundColor || '#000000'); + document.documentElement.style.setProperty('--user-message-text-color', themeVariables.userMessageTextColor || '#ffffff'); + document.documentElement.style.setProperty('--ai-message-background-color', themeVariables.aiMessageBackgroundColor || '#202020'); + document.documentElement.style.setProperty('--ai-message-text-color', themeVariables.aiMessageTextColor || '#ffffff'); + document.documentElement.style.setProperty('--button-background-color', themeVariables.buttonBackgroundColor || '#3c3c3c'); + document.documentElement.style.setProperty('--button-hover-background-color', themeVariables.buttonHoverBackgroundColor || '#5a5a5a'); + document.documentElement.style.setProperty('--models-background-color', themeVariables.modelsBackgroundColor || '#1e1e1e'); + document.documentElement.style.setProperty('--history-background-color', themeVariables.historyBackgroundColor || '#1a1a1a'); + document.documentElement.style.setProperty('--left-panel-background-color', themeVariables.leftPanelBackgroundColor || '#1e1e1e'); + document.documentElement.style.setProperty('--conversation-background-color', themeVariables.conversationBackgroundColor || '#2c2c2c'); + document.documentElement.style.setProperty('--doc-background-color', themeVariables.docBackgroundColor || '#000000'); + document.documentElement.style.setProperty('--close-button-color', themeVariables.closeButtonColor || '#f44336'); + document.documentElement.style.setProperty('--close-button-hover-color', themeVariables.closeButtonHoverColor || '#d32f2f'); + document.documentElement.style.setProperty('--apply-button-color', themeVariables.applyButtonColor || '#4caf50'); + document.documentElement.style.setProperty('--apply-button-hover-color', themeVariables.applyButtonHoverColor || '#66bb6a'); + document.documentElement.style.setProperty('--burger-menu-background-color', themeVariables.burgerMenu || '#79832e'); + document.documentElement.style.setProperty('--overlay-text-color', themeVariables.overlayTextColor || '#ffffff'); + document.documentElement.style.setProperty('--faq-background-color', themeVariables.faqBackgroundColor || '#333333'); + document.documentElement.style.setProperty('--faq-heading-color', themeVariables.faqHeadingColor || '#4caf50'); + document.documentElement.style.setProperty('--faq-item-background-color', themeVariables.faqItemBackgroundColor || '#4c4c4c'); + document.documentElement.style.setProperty('--faq-item-heading-color', themeVariables.faqItemHeadingColor || '#ffffff'); + document.documentElement.style.setProperty('--faq-item-text-color', themeVariables.faqItemTextColor || '#e0e0e0'); + document.documentElement.style.setProperty('--faq-item-hover-background-color', themeVariables.faqItemHoverBackgroundColor || '#555555'); + document.documentElement.style.setProperty('--popup-background-color', themeVariables.popupBackgroundColor || '#4caf50'); + document.documentElement.style.setProperty('--pop-up-text', themeVariables.popUpText || '#ffffff'); + document.documentElement.style.setProperty('--input-border-color', themeVariables.inputBorderColor || '#3c3c3c'); + document.documentElement.style.setProperty('--font-family', themeVariables.fontFamily || "'Poppins', 'sans-serif'"); + document.documentElement.style.setProperty('--font-size', themeVariables.fontSize || '16px'); }; - - document.documentElement.style.setProperty('--header-background-color', themeVariables.headerBackground || '#7e7e7e'); - document.documentElement.style.setProperty('--header-text-color', themeVariables.headerTextColor || '#ffffff'); - document.documentElement.style.setProperty('--background-color', themeVariables.backgroundColor || '#121212'); - document.documentElement.style.setProperty('--text-color', themeVariables.textColor || '#e0e0e0'); - document.documentElement.style.setProperty('--input-background-color', themeVariables.inputBackgroundColor || '#1e1e1e'); - document.documentElement.style.setProperty('--input-button-color', themeVariables.inputButtonColor || '#3c3c3c'); - document.documentElement.style.setProperty('--input-button-hover-color', themeVariables.inputButtonHoverColor || '#5a5a5a'); - document.documentElement.style.setProperty('--user-message-background-color', themeVariables.userMessageBackgroundColor || '#000000'); - document.documentElement.style.setProperty('--user-message-text-color', themeVariables.userMessageTextColor || '#ffffff'); - document.documentElement.style.setProperty('--ai-message-background-color', themeVariables.aiMessageBackgroundColor || '#202020'); - document.documentElement.style.setProperty('--ai-message-text-color', themeVariables.aiMessageTextColor || '#ffffff'); - document.documentElement.style.setProperty('--button-background-color', themeVariables.buttonBackgroundColor || '#3c3c3c'); - document.documentElement.style.setProperty('--button-hover-background-color', themeVariables.buttonHoverBackgroundColor || '#5a5a5a'); - document.documentElement.style.setProperty('--models-background-color', themeVariables.modelsBackgroundColor || '#1e1e1e'); - document.documentElement.style.setProperty('--history-background-color', themeVariables.historyBackgroundColor || '#1a1a1a'); - document.documentElement.style.setProperty('--left-panel-background-color', themeVariables.leftPanelBackgroundColor || '#1e1e1e'); - document.documentElement.style.setProperty('--conversation-background-color', themeVariables.conversationBackgroundColor || '#2c2c2c'); - document.documentElement.style.setProperty('--doc-background-color', themeVariables.docBackgroundColor || '#000000'); - document.documentElement.style.setProperty('--close-button-color', themeVariables.closeButtonColor || '#f44336'); - document.documentElement.style.setProperty('--close-button-hover-color', themeVariables.closeButtonHoverColor || '#d32f2f'); - document.documentElement.style.setProperty('--apply-button-color', themeVariables.applyButtonColor || '#4caf50'); - document.documentElement.style.setProperty('--apply-button-hover-color', themeVariables.applyButtonHoverColor || '#66bb6a'); - document.documentElement.style.setProperty('--burger-menu-background-color', themeVariables.burgerMenu || '#79832e'); - document.documentElement.style.setProperty('--overlay-text-color', themeVariables.overlayTextColor || '#ffffff'); - document.documentElement.style.setProperty('--faq-background-color', themeVariables.faqBackgroundColor || '#333333'); - document.documentElement.style.setProperty('--faq-heading-color', themeVariables.faqHeadingColor || '#4caf50'); - document.documentElement.style.setProperty('--faq-item-background-color', themeVariables.faqItemBackgroundColor || '#4c4c4c'); - document.documentElement.style.setProperty('--faq-item-heading-color', themeVariables.faqItemHeadingColor || '#ffffff'); - document.documentElement.style.setProperty('--faq-item-text-color', themeVariables.faqItemTextColor || '#e0e0e0'); - document.documentElement.style.setProperty('--faq-item-hover-background-color', themeVariables.faqItemHoverBackgroundColor || '#555555'); - document.documentElement.style.setProperty('--popup-background-color', themeVariables.popupBackgroundColor || '#4caf50'); - document.documentElement.style.setProperty('--pop-up-text', themeVariables.popUpText || '#ffffff'); - document.documentElement.style.setProperty('--input-border-color', themeVariables.inputBorderColor || '#3c3c3c'); - document.documentElement.style.setProperty('--font-family', themeVariables.fontFamily || "'Poppins', 'sans-serif'"); - document.documentElement.style.setProperty('--font-size', themeVariables.fontSize || '16px'); -}; +} // TypeScript types for color parameters type Color = string; @@ -247,8 +249,10 @@ export const applyBasicCustomTheme = ( document.documentElement.style.setProperty('--popup-background-color', accentColor); document.documentElement.style.setProperty('--pop-up-text', lightenColor(textColor, 80)); document.documentElement.style.setProperty('--input-border-color', primaryColor); - document.documentElement.style.setProperty('--font-family', localStorage.getItem("fontFamily") || "'Poppins', 'sans-serif'"); - document.documentElement.style.setProperty('--font-size', localStorage.getItem("fontSize") || '16px'); + if (typeof localStorage !== 'undefined') { + document.documentElement.style.setProperty('--font-family', localStorage.getItem("fontFamily") || "'Poppins', 'sans-serif'"); + document.documentElement.style.setProperty('--font-size', localStorage.getItem("fontSize") || '16px'); + } }; // Helper function to darken a color (returns a darker version of the provided color) diff --git a/app/page.tsx b/app/page.tsx index fd0c0ce..3c77911 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -15,20 +15,22 @@ const LandingPage: React.FC = () => { const [view, setView] = useState<'AI' | 'FAQ' | 'Documentation' | 'Credits'>('AI'); const conversationRef = useRef(null); - const [primaryColor, setPrimaryColor] = useState(localStorage.getItem("primaryColor") || "#fefefe"); - const [secondaryColor, setSecondaryColor] = useState(localStorage.getItem("secondaryColor") || "#fefefe"); - const [accentColor, setAccentColor] = useState(localStorage.getItem("accentColor") || "#fefefe"); - const [basicBackgroundColor, setBasicBackgroundColor] = useState(localStorage.getItem("basicBackgroundColor") || "#fefefe"); - const [basicTextColor, setBasicTextColor] = useState(localStorage.getItem("basicTextColor") || "#fefefe"); + const [primaryColor, setPrimaryColor] = useState("#fefefe"); + const [secondaryColor, setSecondaryColor] = useState("#fefefe"); + const [accentColor, setAccentColor] = useState("#fefefe"); + const [basicBackgroundColor, setBasicBackgroundColor] = useState("#fefefe"); + const [basicTextColor, setBasicTextColor] = useState("#fefefe"); // Synchronize state with local storage on mount useEffect(() => { - setPrimaryColor(localStorage.getItem("primaryColor") || "#fefefe"); - setSecondaryColor(localStorage.getItem("secondaryColor") || "#fefefe"); - setAccentColor(localStorage.getItem("accentColor") || "#fefefe"); - setBasicBackgroundColor(localStorage.getItem("basicBackgroundColor") || "#fefefe"); - setBasicTextColor(localStorage.getItem("basicTextColor") || "#fefefe"); - }, []); + if (typeof localStorage !== 'undefined') { + setPrimaryColor(localStorage.getItem("primaryColor") || "#fefefe"); + setSecondaryColor(localStorage.getItem("secondaryColor") || "#fefefe"); + setAccentColor(localStorage.getItem("accentColor") || "#fefefe"); + setBasicBackgroundColor(localStorage.getItem("basicBackgroundColor") || "#fefefe"); + setBasicTextColor(localStorage.getItem("basicTextColor") || "#fefefe"); + } + }, [primaryColor, secondaryColor, accentColor, basicBackgroundColor, basicTextColor]); const toggleDivs = () => { setShowDivs(prevState => !prevState); @@ -43,33 +45,35 @@ const LandingPage: React.FC = () => { // Apply theme based on selectedTheme and color settings useEffect(() => { - const savedTheme = localStorage.getItem('selectedTheme'); - if (savedTheme) { - switch (savedTheme) { - case 'IOMARKET': - applyIOMarketTheme(); - break; - case 'WHITE': - applyWhiteTheme(); - break; - case 'BLACK': - applyBlackTheme(); - break; - case 'CUSTOM': - applyCustomTheme(); - break; - case 'BASIC-CUSTOM': - applyBasicCustomTheme( - primaryColor, - secondaryColor, - accentColor, - basicBackgroundColor, - basicTextColor - ); - break; - default: - applyIOMarketTheme(); - break; + if (typeof localStorage !== 'undefined') { + const savedTheme = localStorage.getItem('selectedTheme'); + if (savedTheme) { + switch (savedTheme) { + case 'IOMARKET': + applyIOMarketTheme(); + break; + case 'WHITE': + applyWhiteTheme(); + break; + case 'BLACK': + applyBlackTheme(); + break; + case 'CUSTOM': + applyCustomTheme(); + break; + case 'BASIC-CUSTOM': + applyBasicCustomTheme( + primaryColor, + secondaryColor, + accentColor, + basicBackgroundColor, + basicTextColor + ); + break; + default: + applyIOMarketTheme(); + break; + } } } }, [primaryColor, secondaryColor, accentColor, basicBackgroundColor, basicTextColor]); // Watch color states and apply themes accordingly