diff --git a/client/src/common/components/Header/HeaderComponent.jsx b/client/src/common/components/Header/HeaderComponent.jsx index 8feb84f0..76cc9005 100644 --- a/client/src/common/components/Header/HeaderComponent.jsx +++ b/client/src/common/components/Header/HeaderComponent.jsx @@ -10,7 +10,7 @@ import { } from "@fortawesome/free-solid-svg-icons"; import { useContext, useEffect, useState } from "react"; import DropdownComponent from "../Dropdown/DropdownComponent"; -import { InputDialogContext } from "@/common/contexts/InputDialog"; +import { useAlert } from "@/common/contexts/Alert"; import { StatusContext } from "@/common/contexts/Status"; import { SpeedtestContext } from "@/common/contexts/Speedtests"; import { jsonRequest, postRequest } from "@/common/utils/RequestUtil"; @@ -23,6 +23,7 @@ import { Trans } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import Pagination from "./components/Pagination"; import AboutDialog from "@/common/components/AboutDialog"; +import Tooltip from "@/common/components/Tooltip"; const HeaderComponent = () => { const findNode = useContext(NodeContext)[4]; @@ -30,7 +31,7 @@ const HeaderComponent = () => { const navigate = useNavigate(); const location = useLocation(); - const [setDialog] = useContext(InputDialogContext); + const alert = useAlert(); const [icon, setIcon] = useState(faGear); const [status, updateStatus, setRunning] = useContext(StatusContext); const {updateTests} = useContext(SpeedtestContext); @@ -44,35 +45,38 @@ const HeaderComponent = () => { setIcon(isDropdownOpen ? faGear : faClose); } - const showDemoDialog = () => setDialog({ - title: t("preview.title"), - description: }}>preview.description, - buttonText: t("dialog.okay") - }); + const showDemoDialog = () => alert.openAlert( + t("preview.title"), + }}>preview.description, + { buttonText: t("dialog.okay") } + ); - const showPasswordDialog = () => setDialog({ - title: t("header.admin_login"), - placeholder: t("dialog.password.placeholder"), - description: localStorage.getItem("password") ? {t("dialog.password.wrong")} : "", - type: "password", - buttonText: t("dialog.login"), - onSuccess: (value) => { - localStorage.setItem("password", value); + const showPasswordDialog = async () => { + const result = await alert.openInput(t("header.admin_login"), { + placeholder: t("dialog.password.placeholder"), + description: localStorage.getItem("password") ? {t("dialog.password.wrong")} : "", + inputType: "password", + buttonText: t("dialog.login") + }); + + if (result) { + localStorage.setItem("password", result); reloadConfig(); - checkConfig().then((config) => config?.viewMode ? showPasswordDialog() : false).catch(() => showPasswordDialog()); - }, - onClose: () => { + const newConfig = await checkConfig().catch(() => null); + if (newConfig?.viewMode) { + showPasswordDialog(); + } + } else { localStorage.removeItem("password"); } - }); + }; const startSpeedtest = async () => { await updateStatus(); - if (status.paused) return setDialog({ - title: t("failed"), - description: t("header.paused"), - buttonText: t("dialog.okay") - }); + if (status.paused) { + alert.openAlert(t("failed"), t("header.paused"), { buttonText: t("dialog.okay") }); + return; + } if (status.running) return; @@ -101,7 +105,7 @@ const HeaderComponent = () => { return ( - {showAboutDialog && setShowAboutDialog(false)}/>} + setShowAboutDialog(false)}/> {config.viewMode && {t("header.title")}} @@ -115,38 +119,43 @@ const HeaderComponent = () => { {updateAvailable ? setDialog({ - title: t("header.new_update"), - buttonText: t("dialog.okay"), - description: updateInfo(updateAvailable) - })} /> : <>>} + onClick={() => alert.openAlert( + t("header.new_update"), + updateInfo(updateAvailable), + { buttonText: t("dialog.okay") } + )} /> : <>>} - {!(status.paused || config.viewMode) ? - - {t("header." + (status.running ? "running_tooltip" : "start_tooltip"))} - : <>>} + {!(status.paused || config.viewMode) ? + + + + : <>>} - {(config.viewMode ? - - {t("header.admin_login")} - : <>>)} + {config.viewMode ? + + + + : <>>} - {(config.previewMode ? - - {t("header.download")} - : <>>)} + {config.previewMode ? + + + + : <>>} - {!config.viewMode && - navigate("/nodes")} /> - {t("header.servers")} - } + {!config.viewMode && + + navigate("/nodes")} /> + + } - - - {t("dropdown.settings")} - + + + + + diff --git a/client/src/common/components/Header/styles.sass b/client/src/common/components/Header/styles.sass index 69902c3b..fe8ab1a9 100644 --- a/client/src/common/components/Header/styles.sass +++ b/client/src/common/components/Header/styles.sass @@ -15,9 +15,7 @@ header .header-right display: flex justify-content: flex-end - -.header-right svg - margin-left: 15px + gap: 15px .header-main * font-size: 24pt diff --git a/client/src/common/components/OptimalValuesDialog/OptimalValuesDialog.jsx b/client/src/common/components/OptimalValuesDialog/OptimalValuesDialog.jsx index f5abf997..a9c5d078 100644 --- a/client/src/common/components/OptimalValuesDialog/OptimalValuesDialog.jsx +++ b/client/src/common/components/OptimalValuesDialog/OptimalValuesDialog.jsx @@ -1,28 +1,27 @@ -import {DialogContext, DialogProvider} from "@/common/contexts/Dialog"; +import {Dialog, DialogHeader, DialogBody, DialogFooter} from "@/common/contexts/Dialog"; import {t} from "i18next"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {faArrowDown, faArrowUp, faCheck, faClose, faExclamationTriangle, faTableTennis, faWandMagicSparkles} from "@fortawesome/free-solid-svg-icons"; +import {faArrowDown, faArrowUp, faCheck, faExclamationTriangle, faTableTennis, faWandMagicSparkles} from "@fortawesome/free-solid-svg-icons"; import "./styles.sass"; import React, {useContext, useEffect, useState} from "react"; import {jsonRequest, patchRequest} from "@/common/utils/RequestUtil"; import {ConfigContext} from "@/common/contexts/Config"; import {ToastNotificationContext} from "@/common/contexts/ToastNotification"; -export const Dialog = () => { - const close = useContext(DialogContext); +export const OptimalValuesDialog = ({open, onClose}) => { const [config, reloadConfig] = useContext(ConfigContext); const updateToast = useContext(ToastNotificationContext); - const [ping, setPing] = useState(config.ping || ""); const [download, setDownload] = useState(config.download || ""); const [upload, setUpload] = useState(config.upload || ""); const [recommendations, setRecommendations] = useState(null); useEffect(() => { + if (!open) return; jsonRequest("/recommendations").then((result) => { if (!result.message) setRecommendations(result); }).catch(() => {}); - }, []); + }, [open]); const applyRecommendations = () => { if (recommendations) { @@ -32,17 +31,15 @@ export const Dialog = () => { } }; - const update = async () => { + const update = async (close) => { if ((ping && /[^0-9.]/.test(ping)) || (download && /[^0-9.]/.test(download)) || (upload && /[^0-9.]/.test(upload))) { updateToast(t("dropdown.invalid"), "red", faExclamationTriangle); return; } - try { if (ping !== config.ping) await patchRequest("/config/ping", {value: ping}); if (download !== config.download) await patchRequest("/config/download", {value: download}); if (upload !== config.upload) await patchRequest("/config/upload", {value: upload}); - reloadConfig(); updateToast(t("dropdown.changes_applied"), "green", faCheck); close(); @@ -52,65 +49,60 @@ export const Dialog = () => { }; return ( - <> - - {t("optimal_values.title")} - close()}/> - - - - - - - - {t("latest.ping")} - {t("welcome.ms")} + + {({close}) => ( + <> + {t("optimal_values.title")} + + + + + + + + {t("latest.ping")} + {t("welcome.ms")} + + + setPing(e.target.value)}/> + + + + + + {t("latest.down")} + {t("welcome.mbps")} + + + setDownload(e.target.value)}/> + + + + + + {t("latest.up")} + {t("welcome.mbps")} + + + setUpload(e.target.value)}/> + - setPing(e.target.value)}/> - - - - - - {t("latest.down")} - {t("welcome.mbps")} - - - setDownload(e.target.value)}/> - - - - - - {t("latest.up")} - {t("welcome.mbps")} - - - setUpload(e.target.value)}/> - - - - - {recommendations && ( - - - {t("optimal_values.use_recommended")} - - )} - {t("dialog.update")} - - > - ); -}; - -export const OptimalValuesDialog = (props) => { - return ( - - - + + + {recommendations && ( + + + {t("optimal_values.use_recommended")} + + )} + update(close)}>{t("dialog.update")} + + > + )} + ); };
{t("welcome.ms")}
{t("welcome.mbps")}