import { useTheme } from "@emotion/react"; import { Box, Stack, Typography } from "@mui/material"; import Field from "../../Components/Inputs/Field"; import Link from "../../Components/Link"; import Select from "../../Components/Inputs/Select"; import { logger } from "../../Utils/Logger"; import "./index.css"; import { useDispatch, useSelector } from "react-redux"; import { createToast } from "../../Utils/toastUtils"; import { deleteMonitorChecksByTeamId, addDemoMonitors, deleteAllMonitors, } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; import { update } from "../../Features/Auth/authSlice"; import PropTypes from "prop-types"; import LoadingButton from "@mui/lab/LoadingButton"; import { setTimezone } from "../../Features/UI/uiSlice"; import timezones from "../../Utils/timezones.json"; import { useState } from "react"; import { ConfigBox } from "./styled"; import { networkService } from "../../main"; import { settingsValidation } from "../../Validation/validation"; const SECONDS_PER_DAY = 86400; const Settings = ({ isAdmin }) => { const theme = useTheme(); const { user, authToken } = useSelector((state) => state.auth); const { checkTTL } = user; const { isLoading } = useSelector((state) => state.uptimeMonitors); const { isLoading: authIsLoading } = useSelector((state) => state.auth); const { timezone } = useSelector((state) => state.ui); const [checksIsLoading, setChecksIsLoading] = useState(false); const [form, setForm] = useState({ ttl: checkTTL ? (checkTTL / SECONDS_PER_DAY).toString() : 0, }); const [errors, setErrors] = useState({}); const dispatch = useDispatch(); const handleChange = (event) => { const { value, id } = event.target; const { error } = settingsValidation.validate( { [id]: value }, { abortEarly: false, } ); if (!error || error.details.length === 0) { setErrors({}); } else { const newErrors = {}; error.details.forEach((err) => { newErrors[err.path[0]] = err.message; }); setErrors(newErrors); console.log(newErrors); logger.error("Validation errors:", error.details); } let inputValue = value; id === "ttl" && (inputValue = value.replace(/[^0-9]/g, "")); setForm((prev) => ({ ...prev, [id]: inputValue, })); }; // TODO Handle saving const handleSave = async () => { try { setChecksIsLoading(true); await networkService.updateChecksTTL({ authToken: authToken, ttl: form.ttl, }); const updatedUser = { ...user, checkTTL: form.ttl }; const action = await dispatch( update({ authToken, localData: updatedUser }) ); if (action.payload.success) { createToast({ body: "Settings saved successfully", }); } else { if (action.payload) { // dispatch errors createToast({ body: action.payload.msg, }); } else { // unknown errors createToast({ body: "Unknown error.", }); } } } catch (error) { console.log(error); createToast({ body: "Failed to save settings" }); } finally { setChecksIsLoading(false); } }; const handleClearStats = async () => { try { const action = await dispatch( deleteMonitorChecksByTeamId({ teamId: user.teamId, authToken }) ); if (deleteMonitorChecksByTeamId.fulfilled.match(action)) { createToast({ body: "Stats cleared successfully" }); } else { createToast({ body: "Failed to clear stats" }); } } catch (error) { logger.error(error); createToast({ body: "Failed to clear stats" }); } }; const handleInsertDemoMonitors = async () => { try { const action = await dispatch(addDemoMonitors({ authToken })); if (addDemoMonitors.fulfilled.match(action)) { createToast({ body: "Successfully added demo monitors" }); } else { createToast({ body: "Failed to add demo monitors" }); } } catch (error) { logger.error(error); createToast({ Body: "Failed to add demo monitors" }); } }; const handleDeleteAllMonitors = async () => { try { const action = await dispatch(deleteAllMonitors({ authToken })); if (deleteAllMonitors.fulfilled.match(action)) { createToast({ body: "Successfully deleted all monitors" }); } else { createToast({ body: "Failed to add demo monitors" }); } } catch (error) { logger.error(error); createToast({ Body: "Failed to delete all monitors" }); } }; return ( General Settings Display timezone- The timezone of the dashboard you publicly display.