Files
Checkmate/Client/src/Pages/Status/CreateStatus/index.jsx
T
Shemy Gan 23d97f8e56 - Replace Doc icon with Reorder icon
- Replace Text input with Search component
- Extend Search component to accept start and end adorment
2024-12-27 20:59:03 -05:00

176 lines
5.0 KiB
React

import PropTypes from "prop-types";
import { useState } from "react";
import { Box, Tab, useTheme, Stack, Button } from "@mui/material";
import TabContext from "@mui/lab/TabContext";
import TabList from "@mui/lab/TabList";
import GeneralSettingsPanel from "../../../Components/TabPanels/Status/GeneralSettingsPanel";
import ContentPanel from "../../../Components/TabPanels/Status/ContentPanel";
import { publicPageGeneralSettingsValidation } from "../../../Validation/validation";
import { hasValidationErrors } from "../../../Validation/error";
import { StatusFormProvider } from "../CreateStatusContext";
import { formatBytes } from "../../../Utils/fileUtils";
import { useSelector } from "react-redux";
import { createToast } from "../../../Utils/toastUtils";
import { networkService } from "../../../main";
/**
* CreateStatus page renders a page with tabs for general settings and contents.
* @param {object} [props.initForm] - Specifies the initial form value if the status page exists
* @returns {JSX.Element}
*/
const CreateStatus = ({ initForm }) => {
const theme = useTheme();
const mode = useSelector((state) => state.ui.mode);
const { authToken } = useSelector((state) => state.auth);
const {apiBaseUrl} = useSelector((state) => state.settings);
const [tabIdx, setTabIdx] = useState(0);
const [errors, setErrors] = useState({});
const error_tab_maping = [["companyName","url","timezone","color","publish","logo"],["monitors",
"showUptimePercentage", "showBarcode"]]
const tabList = ["General Settings", "Contents"];
const hasInitForm = initForm && Object.keys(initForm).length > 0;
const [form, setForm] = useState(
hasInitForm
? initForm
: {
companyName: "",
url: "",
timezone: "America/Toronto",
color: "#4169E1",
//which fields matching below?
//publish: false,
logo: null,
monitors: [],
// showUptimePercentage: false,
// showBarcode: false,
}
);
const setActiveTabOnErrors = () => {
let newIdx = -1;
Object.keys(errors).map((id) => {
if (newIdx !== -1) return;
error_tab_maping.map((val, idx) => {
let anyMatch = val.some((vl) => vl == id);
if (anyMatch) {
newIdx = idx;
return;
}
});
});
if (newIdx !== -1) setTabIdx(newIdx);
};
const handleTabChange = (_, newTab) => {
setTabIdx(tabList.indexOf(newTab));
};
const handleSubmit = async (e) => {
e.preventDefault();
//validate rest of the form
delete form.logo;
//let localData = {...form, monitors: form.monitors.map(m=>m.url)}
let localData = {...form, monitors: form.monitors, theme: mode}
if (hasValidationErrors(localData, publicPageGeneralSettingsValidation, setErrors)) {
setActiveTabOnErrors();
return;
}
// //validate image field, double check if it is required
// let error = validateField(
// { type: logo?.type ?? null, size: logo?.size ?? null },
// logoImageValidation
// );
// if (error) return;
//form.logo = { ...logo, size: formatBytes(logo?.size) };
localData = {...form, monitors: form.monitors.map(m=>m.url),theme: mode}
let config = { authToken: authToken, url: "status-page", data: localData };
try{
const res = await networkService.createStatusPage(config)
if (!res.status === 200) {
throw new Error("Failed to create status page");
}
createToast({ body: "Status page created successfully!" });
}
catch(e){
createToast({ body: e.message || "Error creating status page" });
}
};
return (
<Box
className="status"
px={theme.spacing(20)}
py={theme.spacing(12)}
border={1}
borderColor={theme.palette.border.light}
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
>
<TabContext value={tabList[tabIdx]}>
<Box
sx={{
borderBottom: 1,
borderColor: theme.palette.border.light,
"& .MuiTabs-root": { height: "fit-content", minHeight: "0" },
}}
>
<TabList
onChange={handleTabChange}
aria-label="status tabs"
>
{tabList.map((label, index) => (
<Tab
label={label}
key={index}
value={label}
sx={{
fontSize: 13,
color: theme.palette.text.tertiary,
textTransform: "none",
minWidth: "fit-content",
minHeight: 0,
paddingLeft: 0,
paddingY: theme.spacing(4),
fontWeight: 400,
marginRight: theme.spacing(8),
"&:focus": {
outline: "none",
},
}}
/>
))}
</TabList>
</Box>
<StatusFormProvider
form={hasInitForm ? initForm : form}
setForm={setForm}
errors={errors}
setErrors={setErrors}
>
{tabIdx == 0 ? <GeneralSettingsPanel /> : <ContentPanel />}
</StatusFormProvider>
</TabContext>
<Stack
direction="row"
justifyContent="flex-end"
>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
>
Save
</Button>
</Stack>
</Box>
);
};
CreateStatus.propTypes = {
initForm: PropTypes.object
};
export default CreateStatus;