diff --git a/frontend/src/components/Modals/Settings/Appearance/index.jsx b/frontend/src/components/Modals/Settings/Appearance/index.jsx index 8108e74e6..92f210d59 100644 --- a/frontend/src/components/Modals/Settings/Appearance/index.jsx +++ b/frontend/src/components/Modals/Settings/Appearance/index.jsx @@ -5,13 +5,12 @@ import System from "../../../../models/system"; import EditingChatBubble from "../../../EditingChatBubble"; import AnythingLLMLight from "../../../../media/logo/anything-llm-light.png"; import AnythingLLMDark from "../../../../media/logo/anything-llm-dark.png"; +import showToast from "../../../../utils/toast"; export default function Appearance() { const { logo: _initLogo } = useLogo(); const prefersDarkMode = usePrefersDarkMode(); const [logo, setLogo] = useState(""); - const [errorMsg, setErrorMsg] = useState(""); - const [successMsg, setSuccessMsg] = useState(""); const [hasChanges, setHasChanges] = useState(false); const [messages, setMessages] = useState([]); @@ -30,20 +29,6 @@ export default function Appearance() { setInitLogo(); }, [_initLogo]); - useEffect(() => { - if (!!successMsg) { - setTimeout(() => { - setSuccessMsg(""); - }, 3_500); - } - - if (!!errorMsg) { - setTimeout(() => { - setErrorMsg(""); - }, 3_500); - } - }, [successMsg, errorMsg]); - const handleFileUpload = async (event) => { const file = event.target.files[0]; if (!file) return false; @@ -53,30 +38,26 @@ export default function Appearance() { const { success, error } = await System.uploadLogo(formData); if (!success) { console.error("Failed to upload logo:", error); - setErrorMsg(error); - setSuccessMsg(""); + showToast(`Failed to upload logo: ${error}`, "error"); return; } const logoURL = await System.fetchLogo(); setLogo(logoURL); - setSuccessMsg("Image uploaded successfully"); - setErrorMsg(""); + showToast("Image uploaded successfully.", "success"); }; const handleRemoveLogo = async () => { const { success, error } = await System.removeCustomLogo(); if (!success) { console.error("Failed to remove logo:", error); - setErrorMsg(error); - setSuccessMsg(""); + showToast(`Failed to remove logo: ${error}`, "error"); return; } const logoURL = await System.fetchLogo(); setLogo(logoURL); - setSuccessMsg("Image successfully removed"); - setErrorMsg(""); + showToast("Image successfully removed.", "success"); }; const addMessage = (type) => { @@ -108,10 +89,10 @@ export default function Appearance() { const handleMessageSave = async () => { const { success, error } = await System.setWelcomeMessages(messages); if (!success) { - setErrorMsg(error); + showToast(`Failed to update welcome messages: ${error}`, "error"); return; } - setSuccessMsg("Successfully updated welcome messages."); + showToast("Successfully updated welcome messages.", "success"); setHasChanges(false); }; @@ -227,16 +208,6 @@ export default function Appearance() { </div> )} </div> - {errorMsg && ( - <div className="mt-4 text-sm text-red-600 dark:text-red-400 text-center"> - {errorMsg} - </div> - )} - {successMsg && ( - <div className="mt-4 text-sm text-green-600 dark:text-green-400 text-center"> - {successMsg} - </div> - )} </div> </div> </div> diff --git a/frontend/src/components/Modals/Settings/LLMSelection/index.jsx b/frontend/src/components/Modals/Settings/LLMSelection/index.jsx index 2cf014352..bc40db3eb 100644 --- a/frontend/src/components/Modals/Settings/LLMSelection/index.jsx +++ b/frontend/src/components/Modals/Settings/LLMSelection/index.jsx @@ -3,6 +3,7 @@ import System from "../../../../models/system"; import OpenAiLogo from "../../../../media/llmprovider/openai.png"; import AzureOpenAiLogo from "../../../../media/llmprovider/azure.png"; import AnthropicLogo from "../../../../media/llmprovider/anthropic.png"; +import showToast from "../../../../utils/toast"; const noop = () => false; export default function LLMSelection({ @@ -13,7 +14,6 @@ export default function LLMSelection({ const [hasChanges, setHasChanges] = useState(false); const [llmChoice, setLLMChoice] = useState(settings?.LLMProvider || "openai"); const [saving, setSaving] = useState(false); - const [error, setError] = useState(null); const canDebug = settings.MultiUserMode ? settings?.CanDebug && user?.role === "admin" : settings?.CanDebug; @@ -27,12 +27,15 @@ export default function LLMSelection({ const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); - setError(null); const data = {}; const form = new FormData(e.target); for (var [key, value] of form.entries()) data[key] = value; const { error } = await System.updateSystem(data); - setError(error); + if (error) { + showToast(`Failed to save LLM settings: ${error}`, "error"); + } else { + showToast("LLM settings saved successfully.", "success"); + } setSaving(false); setHasChanges(!!error ? true : false); }; @@ -47,12 +50,6 @@ export default function LLMSelection({ </p> </div> - {!!error && ( - <div className="mb-8 bg-red-700 dark:bg-orange-800 bg-opacity-30 border border-red-800 dark:border-orange-600 p-4 rounded-lg w-[90%] flex mx-auto"> - <p className="text-red-800 dark:text-orange-300 text-sm">{error}</p> - </div> - )} - <form onSubmit={handleSubmit} onChange={() => setHasChanges(true)}> <div className="px-6 space-y-6 flex h-full w-full"> <div className="w-full flex flex-col gap-y-4"> diff --git a/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx b/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx index 5e6269121..3b1a92dce 100644 --- a/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx +++ b/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx @@ -1,6 +1,7 @@ import React, { useState } from "react"; import System from "../../../../models/system"; import { AUTH_TOKEN, AUTH_USER } from "../../../../utils/constants"; +import showToast from "../../../../utils/toast"; const noop = () => false; export default function PasswordProtection({ @@ -8,15 +9,11 @@ export default function PasswordProtection({ settings = {}, }) { const [saving, setSaving] = useState(false); - const [success, setSuccess] = useState(false); - const [error, setError] = useState(null); const [usePassword, setUsePassword] = useState(settings?.RequiresAuth); const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); - setSuccess(false); - setError(null); const form = new FormData(e.target); const data = { @@ -26,17 +23,18 @@ export default function PasswordProtection({ const { success, error } = await System.updateSystemPassword(data); if (success) { - setSuccess(true); + showToast("Your page will refresh in a few seconds.", "success"); setSaving(false); setTimeout(() => { window.localStorage.removeItem(AUTH_USER); window.localStorage.removeItem(AUTH_TOKEN); window.location.reload(); - }, 2_000); + }, 3_000); return; + } else { + showToast(`Failed to update password: ${error}`, "error"); } - setError(error); setSaving(false); }; @@ -49,20 +47,6 @@ export default function PasswordProtection({ this there is no recovery method so ensure you save this password. </p> </div> - {(error || success) && ( - <div className="w-full flex px-6"> - {error && ( - <div className="w-full bg-red-300 text-red-800 font-semibold px-4 py-2 rounded-lg"> - {error} - </div> - )} - {success && ( - <div className="w-full bg-green-300 text-green-800 font-semibold px-4 py-2 rounded-lg"> - Your page will refresh in a few seconds. - </div> - )} - </div> - )} <div className="p-6 space-y-6 flex h-full w-full"> <div className="w-full flex flex-col gap-y-4"> <form onSubmit={handleSubmit}> diff --git a/frontend/src/pages/Admin/Appearance/index.jsx b/frontend/src/pages/Admin/Appearance/index.jsx index e96319631..08e61f67c 100644 --- a/frontend/src/pages/Admin/Appearance/index.jsx +++ b/frontend/src/pages/Admin/Appearance/index.jsx @@ -8,13 +8,12 @@ import usePrefersDarkMode from "../../../hooks/usePrefersDarkMode"; import useLogo from "../../../hooks/useLogo"; import System from "../../../models/system"; import EditingChatBubble from "../../../components/EditingChatBubble"; +import showToast from "../../../utils/toast"; export default function Appearance() { const { logo: _initLogo } = useLogo(); const [logo, setLogo] = useState(""); const prefersDarkMode = usePrefersDarkMode(); - const [errorMsg, setErrorMsg] = useState(""); - const [successMsg, setSuccessMsg] = useState(""); const [hasChanges, setHasChanges] = useState(false); const [messages, setMessages] = useState([]); @@ -25,20 +24,6 @@ export default function Appearance() { setInitLogo(); }, [_initLogo]); - useEffect(() => { - if (!!errorMsg) { - setTimeout(() => { - setErrorMsg(""); - }, 3_500); - } - - if (!!successMsg) { - setTimeout(() => { - setSuccessMsg(""); - }, 3_500); - } - }, [errorMsg, successMsg]); - useEffect(() => { async function fetchMessages() { const messages = await System.getWelcomeMessages(); @@ -55,29 +40,26 @@ export default function Appearance() { formData.append("logo", file); const { success, error } = await Admin.uploadLogo(formData); if (!success) { - setErrorMsg(error); + showToast(`Failed to upload logo: ${error}`, "error"); return; } const logoURL = await System.fetchLogo(); setLogo(logoURL); - setErrorMsg(""); - window.location.reload(); + showToast("Image uploaded successfully.", "success"); }; const handleRemoveLogo = async () => { const { success, error } = await Admin.removeCustomLogo(); if (!success) { console.error("Failed to remove logo:", error); - setErrorMsg(error); + showToast(`Failed to remove logo: ${error}`, "error"); return; } const logoURL = await System.fetchLogo(); setLogo(logoURL); - setErrorMsg(""); - - window.location.reload(); + showToast("Image successfully removed.", "success"); }; const addMessage = (type) => { @@ -109,10 +91,10 @@ export default function Appearance() { const handleMessageSave = async () => { const { success, error } = await Admin.setWelcomeMessages(messages); if (!success) { - setErrorMsg(error); + showToast(`Failed to update welcome messages: ${error}`, "error"); return; } - setSuccessMsg("Successfully updated welcome messages."); + showToast("Successfully updated welcome messages.", "success"); setHasChanges(false); }; @@ -235,16 +217,6 @@ export default function Appearance() { </div> )} </div> - {errorMsg && ( - <div className="mt-4 text-sm text-red-600 dark:text-red-400 text-center"> - {errorMsg} - </div> - )} - {successMsg && ( - <div className="mt-4 text-sm text-green-600 dark:text-green-400 text-center"> - {successMsg} - </div> - )} </div> </div> </div> diff --git a/frontend/src/pages/Admin/System/index.jsx b/frontend/src/pages/Admin/System/index.jsx index 58874b90b..b16a17c26 100644 --- a/frontend/src/pages/Admin/System/index.jsx +++ b/frontend/src/pages/Admin/System/index.jsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import Sidebar, { SidebarMobileHeader } from "../../../components/AdminSidebar"; import { isMobile } from "react-device-detect"; import Admin from "../../../models/admin"; +import showToast from "../../../utils/toast"; export default function AdminSystem() { const [saving, setSaving] = useState(false); @@ -21,6 +22,7 @@ export default function AdminSystem() { }); setSaving(false); setHasChanges(false); + showToast("System preferences updated successfully.", "success"); }; useEffect(() => {