- useContext from parent page for form fields

This commit is contained in:
Shemy Gan committed 2024-12-13 15:59:54 -05:00
1 parent 8292654d27
commit 5045eafb8e
3 files changed
+80 -96

No files matched your search

@@ -5,23 +5,13 @@ import { useTheme } from "@emotion/react";
import TabPanel from "@mui/lab/TabPanel";
import { publicPageGeneralSettingsValidation } from "../../../Validation/validation";
import { buildErrors } from "../../../Validation/error";
import { hasValidationErrors } from "../../../Validation/error";
import Card from "./Card";
import update from "immutability-helper";
import Checkbox from "../../Inputs/Checkbox";
const ContentPanel = () => {
const ContentPanel = ({errors, setErrors}) => {
const theme = useTheme();
const [errors, setErrors] = useState({});
// Local state for form data, errors, and file handling
const [localData, setLocalData] = useState({
monitors: [],
showUptimePercentage: false,
showBarcode: false
});
const [cards, setCards] = useState(localData.monitors);
const [cards, setCards] = useState(form.monitors);
// Clears specific error from errors state
const clearError = (err) => {
@@ -50,7 +40,7 @@ const ContentPanel = () => {
const handleChange = (event) => {
event.preventDefault();
const { value, id } = event.target;
setLocalData((prev) => ({
setForm((prev) => ({
...prev,
[id]: value,
}));
@@ -66,13 +56,6 @@ const ContentPanel = () => {
setCards(update(cards, { $splice: [[idx, 1, x]] }));
} else setCards(update(cards, { $push: [{ id: id, url: value }] }));
}
const handleSubmit = () => {
if (hasValidationErrors(localData, publicPageGeneralSettingsValidation, setErrors)) {
return;
}
};
const handleAddNew = () => {
setCards([...cards, { id: "" + Math.random() }]);
};
@@ -190,34 +173,19 @@ const ContentPanel = () => {
<Checkbox
id="show-barcode"
label={`Show Barcode`}
isChecked={localData.showBarcode}
value={"localData.showBarcode"}
isChecked={form.showBarcode}
onChange={handleChange}
onBlur={handleBlur}
/>
<Checkbox
id="show-uptime-percentage"
label={`Show Uptime Percentage`}
isChecked={localData.showUptimePercentage}
value={"localData.showUptimePercentage"}
isChecked={form.showUptimePercentage}
onChange={handleChange}
onBlur={handleBlur}
/>
</Stack>
</ConfigBox>
<Stack
direction="row"
justifyContent="flex-end"
>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
>
Save
</Button>
</Stack>
</Stack>
</TabPanel>
);
@@ -1,4 +1,4 @@
import { useState, useRef } from "react";
import { useState, useRef, useContext } from "react";
import { Button, Box, Stack, Typography } from "@mui/material";
import { ConfigBox } from "../../../Pages/Settings/styled";
import Checkbox from "../../Inputs/Checkbox";
@@ -18,23 +18,15 @@ import ProgressUpload from "../../ProgressBars";
import ImageIcon from "@mui/icons-material/Image";
import { HttpAdornment } from "../../Inputs/TextInput/Adornments";
import { hasValidationErrors } from "../../../Validation/error";
import { StatusFormContext } from "../../../Pages/Status/TabContext";
const GeneralSettingsPanel = () => {
const theme = useTheme();
const [errors, setErrors] = useState({});
const GeneralSettingsPanel = ({errors, setErrors}) => {
const theme = useTheme();
const [logo, setLogo] = useState();
const { form, setForm } = useContext(StatusFormContext);
const [progress, setProgress] = useState({ value: 0, isLoading: false });
const intervalRef = useRef(null);
// Local state for form data, errors, and file handling
const [localData, setLocalData] = useState({
companyName: "",
url: "",
timezone: "America/Toronto",
color: "#4169E1",
//which fields matching below?
publish: false,
logo: null,
});
// Clears specific error from errors state
const clearError = (err) => {
setErrors((prev) => {
@@ -46,7 +38,7 @@ const GeneralSettingsPanel = () => {
const removeLogo = () => {
errors["logo"] && clearError("logo");
setLogo({});
setLocalData((prev) => ({
setForm((prev) => ({
...prev,
logo: logo?.src,
}));
@@ -58,27 +50,12 @@ const GeneralSettingsPanel = () => {
const handleChange = (event) => {
event.preventDefault();
const { value, id } = event.target;
setLocalData((prev) => ({
setForm((prev) => ({
...prev,
[id]: value,
}));
};
const handleSubmit = () => {
//validate rest of the form
delete localData.logo;
if (hasValidationErrors(localData, publicPageGeneralSettingsValidation, setErrors)) {
return;
}
//validate image field
let error = validateField(
{ type: logo?.type ?? null, size: logo?.size ?? null },
logoImageValidation
);
if (error) return;
localData.logo = { ...logo, size: formatBytes(logo?.size) };
};
const handleBlur = (event) => {
event.preventDefault();
const { value, id } = event.target;
@@ -159,7 +136,7 @@ const GeneralSettingsPanel = () => {
<Checkbox
id="published-to-public"
label={`Published and visible to the public`}
isChecked={localData.publish}
isChecked={form.publish}
onChange={handleChange}
onBlur={handleBlur}
/>
@@ -180,7 +157,7 @@ const GeneralSettingsPanel = () => {
id="companyName"
type="text"
label="Company name"
value={localData.companyName}
value={form.companyName}
onChange={handleChange}
onBlur={handleBlur}
helperText={errors["companyName"]}
@@ -190,7 +167,7 @@ const GeneralSettingsPanel = () => {
id="url"
type="url"
label="SubURL"
value={localData.url}
value={form.url}
startAdornment={<HttpAdornment prefix = {"http://uptimegenie.com/"} https={false} />}
onChange={handleChange}
onBlur={handleBlur}
@@ -212,7 +189,7 @@ const GeneralSettingsPanel = () => {
<Select
id="display-timezone"
label="Display timezone"
value={localData.timezone}
value={form.timezone}
onChange={handleChange}
onBlur={handleBlur}
items={timezones}
@@ -220,7 +197,7 @@ const GeneralSettingsPanel = () => {
/>
<ImageField
id="logo"
src={localData.logo?.src ?? logo?.src}
src={form.logo?.src ?? logo?.src}
loading={progress.isLoading && progress.value !== 100}
onChange={handleLogo}
isRound={false}
@@ -240,25 +217,13 @@ const GeneralSettingsPanel = () => {
<TextInput
id="color"
label="Color"
value={localData.color}
value={form.color}
error={errors["color"]}
onChange={handleChange}
onBlur={handleBlur}
/>
</Stack>
</ConfigBox>
<Stack
direction="row"
justifyContent="flex-end"
>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
>
Save
</Button>
</Stack>
</Stack>
</TabPanel>
);
+61 -10
View File
@@ -1,15 +1,18 @@
import PropTypes from "prop-types";
import { useNavigate } from "react-router";
import { useEffect, useState } from "react";
import { Box, Tab, useTheme } from "@mui/material";
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 {
capitalizeFirstLetter,
toLowerCaseFirstLetter,
} from "../../../Utils/stringUtils";
import ContentPanel from "../../../Components/TabPanels/Status/ContentPanel";
import {
publicPageGeneralSettingsValidation,
} from "../../../Validation/validation";
import { hasValidationErrors } from "../../../Validation/error";
import { StatusFormProvider } from "../TabContext"
/**
* CreateStatus page renders a page with tabs for general settings and contents.
@@ -19,22 +22,47 @@ import ContentPanel from "../../../Components/TabPanels/Status/ContentPanel";
const CreateStatus = ({ open = "general-settings" }) => {
const theme = useTheme();
const navigate = useNavigate();
let tabList = ["General Settings", "Contents"];
const [errors, setErrors] = useState({});
const tab = open
.split("-")
.map((a) => capitalizeFirstLetter(a))
.join(" ");
const [tabIdx, setTabIdx] = useState(tabList.indexOf(tab));
const handleTabChange = (event, newTab) => {
let toNavString = newTab.split(" ").map((a) => toLowerCaseFirstLetter(a));
setTabIdx(tabList.indexOf(newTab));
toNavString = toNavString.join("-");
navigate(`/status/${toNavString}`);
};
const [form, setForm] = useState({
companyName: "",
url: "",
timezone: "America/Toronto",
color: "#4169E1",
//which fields matching below?
publish: false,
logo: null,
monitors: [],
showUptimePercentage: false,
showBarcode: false
});
const handleSubmit = () => {
//validate rest of the form
delete form.logo;
if (hasValidationErrors(form, publicPageGeneralSettingsValidation, setErrors)) {
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) };
};
useEffect(() => {
setTabIdx(tabList.indexOf(tab));
}, [tab]);
@@ -49,7 +77,7 @@ const CreateStatus = ({ open = "general-settings" }) => {
borderRadius={theme.shape.borderRadius}
backgroundColor={theme.palette.background.main}
>
<TabContext value={tab}>
<TabContext value={tabList[tabIdx]}>
<Box
sx={{
borderBottom: 1,
@@ -84,8 +112,31 @@ const CreateStatus = ({ open = "general-settings" }) => {
))}
</TabList>
</Box>
{tabIdx == 0 ? <GeneralSettingsPanel /> : <ContentPanel />}
<StatusFormProvider>
{tabIdx == 0 ? (
<GeneralSettingsPanel
errors={errors}
setErrors={setErrors}/>
) : (
<ContentPanel
ss errors={errors}
setErrors={setErrors}
/>
)}
</StatusFormProvider>
</TabContext>
<Stack
direction="row"
justifyContent="flex-end"
>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
>
Save
</Button>
</Stack>
</Box>
);
};