diff --git a/Client/src/Components/Skeletons/FullPage/index.jsx b/Client/src/Components/Skeletons/FullPage/index.jsx
new file mode 100644
index 000000000..233fc3c06
--- /dev/null
+++ b/Client/src/Components/Skeletons/FullPage/index.jsx
@@ -0,0 +1,14 @@
+import { Stack, Skeleton } from "@mui/material";
+
+export const SkeletonLayout = () => {
+ return (
+
+
+
+ );
+};
+
+export default SkeletonLayout;
diff --git a/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
index 9bdce5887..ea8a1d7a3 100644
--- a/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
+++ b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
@@ -34,7 +34,6 @@ const MaintenanceTable = ({
updateCallback,
}) => {
const { rowsPerPage } = useSelector((state) => state.ui.maintenance);
- console.log(rowsPerPage);
const dispatch = useDispatch();
const handleChangePage = (event, newPage) => {
@@ -175,8 +174,6 @@ const MaintenanceTable = ({
setSort({ field, order });
};
- console.log(handleChangePage);
-
return (
<>
{
if (typeof error === "undefined") {
const success = await createStatusPage({ form });
if (success) {
- createToast({ body: "Status page created successfully" });
+ createToast({
+ body: isCreate
+ ? "Status page created successfully"
+ : "Status page updated successfully",
+ });
navigate(`/status/uptime/${form.url}`);
}
return;
diff --git a/Client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx b/Client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
index 2c96db054..e8ea104b8 100644
--- a/Client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
+++ b/Client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
@@ -43,11 +43,7 @@ const Controls = ({ isDeleteOpen, setIsDeleteOpen, isDeleting, url, type }) => {
variant="contained"
color="secondary"
onClick={() => {
- if (type === "uptime") {
- navigate(`/status/uptime/configure/${url}`);
- } else {
- navigate(`/status/distributed/configure/${url}`);
- }
+ navigate(`/status/`);
}}
sx={{
px: theme.spacing(5),
diff --git a/Client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx b/Client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx
new file mode 100644
index 000000000..746d10f42
--- /dev/null
+++ b/Client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx
@@ -0,0 +1,85 @@
+import DataTable from "../../../../../Components/Table";
+import { useTheme } from "@emotion/react";
+import { useNavigate } from "react-router-dom";
+import { ColoredLabel } from "../../../../../Components/Label";
+import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
+import { Stack, Typography } from "@mui/material";
+const StatusPagesTable = ({ data }) => {
+ const theme = useTheme();
+ const navigate = useNavigate();
+ const headers = [
+ {
+ id: "name",
+ content: "Status page name",
+ render: (row) => {
+ return row.companyName;
+ },
+ },
+ {
+ id: "url",
+ content: "URL",
+ render: (row) => {
+ return (
+
+ {`/${row.url}`}
+
+
+ );
+ },
+ },
+ {
+ id: "type",
+ content: "Type",
+ render: (row) => {
+ return row.type;
+ },
+ },
+ {
+ id: "status",
+ content: "Status",
+ render: (row) => {
+ return (
+
+ );
+ },
+ },
+ ];
+
+ const handleRowClick = (statusPage) => {
+ if (statusPage.type === "distributed") {
+ navigate(`/status/distributed/${statusPage.url}`);
+ } else if (statusPage.type === "uptime") {
+ navigate(`/status/uptime/${statusPage.url}`);
+ }
+ };
+
+ return (
+ {
+ handleRowClick(row);
+ },
+ }}
+ headers={headers}
+ data={data}
+ />
+ );
+};
+
+export default StatusPagesTable;
diff --git a/Client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx b/Client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
index 7565f129a..26eec8104 100644
--- a/Client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
+++ b/Client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
@@ -20,7 +20,9 @@ const useStatusPagesFetch = () => {
setStatusPages(res?.data?.data);
} catch (error) {
setNetworkError(true);
- createToast(error.message, "error");
+ createToast({
+ body: error.message,
+ });
} finally {
setIsLoading(false);
}
diff --git a/Client/src/Pages/StatusPage/StatusPages/index.jsx b/Client/src/Pages/StatusPage/StatusPages/index.jsx
index cf5b83289..9027467a4 100644
--- a/Client/src/Pages/StatusPage/StatusPages/index.jsx
+++ b/Client/src/Pages/StatusPage/StatusPages/index.jsx
@@ -4,11 +4,12 @@ import Breadcrumbs from "../../../Components/Breadcrumbs";
import Fallback from "../../../Components/Fallback";
import MonitorCreateHeader from "../../../Components/MonitorCreateHeader";
import GenericFallback from "../../../Components/GenericFallback";
+import StatusPagesTable from "./Components/StatusPagesTable";
+import SkeletonLayout from "../../../Components/Skeletons/FullPage";
// Utils
import { useTheme } from "@emotion/react";
import { useStatusPagesFetch } from "./Hooks/useStatusPagesFetch";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
-import { useNavigate } from "react-router";
const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
const StatusPages = () => {
@@ -16,29 +17,9 @@ const StatusPages = () => {
const theme = useTheme();
const isAdmin = useIsAdmin();
const [isLoading, networkError, statusPages] = useStatusPagesFetch();
- const navigate = useNavigate();
- // Handlers
- const handleStatusPageClick = (statusPage) => {
- if (statusPage.type === "distributed") {
- navigate(`/status/distributed/${statusPage.url}`);
- } else if (statusPage.type === "uptime") {
- navigate(`/status/uptime/${statusPage.url}`);
- }
- };
-
- if (!isLoading && typeof statusPages === "undefined") {
- return (
-
- );
+ if (isLoading) {
+ return ;
}
if (networkError === true) {
@@ -55,6 +36,21 @@ const StatusPages = () => {
);
}
+
+ if (!isLoading && typeof statusPages !== "undefined" && statusPages.length === 0) {
+ return (
+
+ );
+ }
return (
@@ -63,19 +59,7 @@ const StatusPages = () => {
isAdmin={isAdmin}
path="/status/uptime/create"
/>
- {statusPages?.map((statusPage) => {
- return (
- handleStatusPageClick(statusPage)}
- sx={{ cursor: "pointer" }}
- >
- Company Name: {statusPage.companyName}
- Status page URL: {statusPage.url}
- Type: {statusPage.type}
-
- );
- })}
+
);
};
diff --git a/Client/src/Utils/NetworkService.js b/Client/src/Utils/NetworkService.js
index ebb726a2c..515ae5930 100644
--- a/Client/src/Utils/NetworkService.js
+++ b/Client/src/Utils/NetworkService.js
@@ -1015,11 +1015,12 @@ class NetworkService {
async createStatusPage(config) {
const { authToken, user, form, isCreate } = config;
+
const fd = new FormData();
fd.append("teamId", user.teamId);
fd.append("userId", user._id);
fd.append("type", form.type);
- form.isPublished && fd.append("isPublished", form.isPublished);
+ form.isPublished !== undefined && fd.append("isPublished", form.isPublished);
form.companyName && fd.append("companyName", form.companyName);
form.url && fd.append("url", form.url);
form.timezone && fd.append("timezone", form.timezone);
diff --git a/Server/controllers/statusPageController.js b/Server/controllers/statusPageController.js
index 1a69c92ec..7d75fc7d3 100644
--- a/Server/controllers/statusPageController.js
+++ b/Server/controllers/statusPageController.js
@@ -95,6 +95,7 @@ class StatusPageController {
try {
const teamId = req.params.teamId;
const statusPages = await this.db.getStatusPagesByTeamId(teamId);
+
return res.success({
msg: successMessages.STATUS_PAGE_BY_TEAM_ID,
data: statusPages,
diff --git a/Server/db/mongo/modules/statusPageModule.js b/Server/db/mongo/modules/statusPageModule.js
index 8687f06ed..a0a1b5af6 100644
--- a/Server/db/mongo/modules/statusPageModule.js
+++ b/Server/db/mongo/modules/statusPageModule.js
@@ -69,11 +69,6 @@ const getStatusPageByUrl = async (url, type) => {
const getStatusPagesByTeamId = async (teamId) => {
try {
const statusPages = await StatusPage.find({ teamId });
- if (statusPages.length === 0) {
- const error = new Error(errorMessages.STATUS_PAGE_NOT_FOUND);
- error.status = 404;
- throw error;
- }
return statusPages;
} catch (error) {
error.service = SERVICE_NAME;
diff --git a/Server/locales/en.json.bak b/Server/locales/en.json.bak
new file mode 100644
index 000000000..eaef58eef
--- /dev/null
+++ b/Server/locales/en.json.bak
@@ -0,0 +1,147 @@
+{
+ "dontHaveAccount": "Don't have account",
+ "email": "E-mail",
+ "forgotPassword": "Forgot Password",
+ "password": "password",
+ "signUp": "Sign up",
+ "submit": "Submit",
+ "title": "Title",
+ "continue": "Continue",
+ "enterEmail": "Enter your email",
+ "authLoginTitle": "Log In",
+ "authLoginEnterPassword": "Enter your password",
+ "commonPassword": "Password",
+ "commonBack": "Back",
+ "authForgotPasswordTitle": "Forgot password?",
+ "authForgotPasswordResetPassword": "Reset password",
+ "createPassword": "Create your password",
+ "createAPassword": "Create a password",
+ "authRegisterAlreadyHaveAccount": "Already have an account?",
+ "commonAppName": "BlueWave Uptime",
+ "authLoginEnterEmail": "Enter your email",
+ "authRegisterTitle": "Create an account",
+ "authRegisterStepOneTitle": "Create your account",
+ "authRegisterStepOneDescription": "Enter your details to get started",
+ "authRegisterStepTwoTitle": "Set up your profile",
+ "authRegisterStepTwoDescription": "Tell us more about yourself",
+ "authRegisterStepThreeTitle": "Almost done!",
+ "authRegisterStepThreeDescription": "Review your information",
+ "authForgotPasswordDescription": "No worries, we'll send you reset instructions.",
+ "authForgotPasswordSendInstructions": "Send instructions",
+ "authForgotPasswordBackTo": "Back to",
+ "authCheckEmailTitle": "Check your email",
+ "authCheckEmailDescription": "We sent a password reset link to {{email}}",
+ "authCheckEmailResendEmail": "Resend email",
+ "authCheckEmailBackTo": "Back to",
+ "goBackTo": "Go back to",
+ "authCheckEmailDidntReceiveEmail": "Didn't receive the email?",
+ "authCheckEmailClickToResend": "Click to resend",
+ "authSetNewPasswordTitle": "Set new password",
+ "authSetNewPasswordDescription": "Your new password must be different from previously used passwords.",
+ "authSetNewPasswordNewPassword": "New password",
+ "authSetNewPasswordConfirmPassword": "Confirm password",
+ "confirmPassword": "Confirm your password",
+ "authSetNewPasswordResetPassword": "Reset password",
+ "authSetNewPasswordBackTo": "Back to",
+ "authPasswordMustBeAtLeast": "Must be at least",
+ "authPasswordCharactersLong": "8 characters long",
+ "authPasswordMustContainAtLeast": "Must contain at least",
+ "authPasswordSpecialCharacter": "one special character",
+ "authPasswordOneNumber": "one number",
+ "authPasswordUpperCharacter": "one upper character",
+ "authPasswordLowerCharacter": "one lower character",
+ "authPasswordConfirmAndPassword": "Confirm password and password",
+ "authPasswordMustMatch": "must match",
+ "friendlyError": "Something went wrong...",
+ "unknownError": "An unknown error occurred",
+ "unauthorized": "Unauthorized access",
+ "authAdminExists": "Admin already exists",
+ "authInviteNotFound": "Invite not found",
+ "unknownService": "Unknown service",
+ "noAuthToken": "No auth token provided",
+ "invalidAuthToken": "Invalid auth token",
+ "expiredAuthToken": "Token expired",
+ "noRefreshToken": "No refresh token provided",
+ "invalidRefreshToken": "Invalid refresh token",
+ "expiredRefreshToken": "Refresh token expired",
+ "requestNewAccessToken": "Request new access token",
+ "invalidPayload": "Invalid payload",
+ "verifyOwnerNotFound": "Document not found",
+ "verifyOwnerUnauthorized": "Unauthorized access",
+ "insufficientPermissions": "Insufficient permissions",
+ "dbUserExists": "User already exists",
+ "dbUserNotFound": "User not found",
+ "dbTokenNotFound": "Token not found",
+ "dbResetPasswordBadMatch": "New password must be different from old password",
+ "dbFindMonitorById": "Monitor with id ${monitorId} not found",
+ "dbDeleteChecks": "No checks found for monitor with id ${monitorId}",
+ "authIncorrectPassword": "Incorrect password",
+ "authUnauthorized": "Unauthorized access",
+ "monitorGetById": "Monitor not found",
+ "monitorGetByUserId": "No monitors found for user",
+ "jobQueueWorkerClose": "Error closing worker",
+ "jobQueueDeleteJob": "Job not found in queue",
+ "jobQueueObliterate": "Error obliterating queue",
+ "pingCannotResolve": "No response",
+ "statusPageNotFound": "Status page not found",
+ "statusPageUrlNotUnique": "Status page url must be unique",
+ "dockerFail": "Failed to fetch Docker container information",
+ "dockerNotFound": "Docker container not found",
+ "portFail": "Failed to connect to port",
+ "alertCreate": "Alert created successfully",
+ "alertGetByUser": "Got alerts successfully",
+ "alertGetByMonitor": "Got alerts by Monitor successfully",
+ "alertGetById": "Got alert by Id successfully",
+ "alertEdit": "Alert edited successfully",
+ "alertDelete": "Alert deleted successfully",
+ "authCreateUser": "User created successfully",
+ "authLoginUser": "User logged in successfully",
+ "authLogoutUser": "User logged out successfully",
+ "authUpdateUser": "User updated successfully",
+ "authCreateRecoveryToken": "Recovery token created successfully",
+ "authVerifyRecoveryToken": "Recovery token verified successfully",
+ "authResetPassword": "Password reset successfully",
+ "authAdminCheck": "Admin check completed successfully",
+ "authDeleteUser": "User deleted successfully",
+ "authTokenRefreshed": "Auth token is refreshed",
+ "authGetAllUsers": "Got all users successfully",
+ "inviteIssued": "Invite sent successfully",
+ "inviteVerified": "Invite verified successfully",
+ "checkCreate": "Check created successfully",
+ "checkGet": "Got checks successfully",
+ "checkDelete": "Checks deleted successfully",
+ "checkUpdateTtl": "Checks TTL updated successfully",
+ "monitorGetAll": "Got all monitors successfully",
+ "monitorStatsById": "Got monitor stats by Id successfully",
+ "monitorGetByIdSuccess": "Got monitor by Id successfully",
+ "monitorGetByTeamId": "Got monitors by Team Id successfully",
+ "monitorGetByUserIdSuccess": "Got monitor for ${userId} successfully",
+ "monitorCreate": "Monitor created successfully",
+ "monitorDelete": "Monitor deleted successfully",
+ "monitorEdit": "Monitor edited successfully",
+ "monitorCertificate": "Got monitor certificate successfully",
+ "monitorDemoAdded": "Successfully added demo monitors",
+ "queueGetMetrics": "Got metrics successfully",
+ "queueAddJob": "Job added successfully",
+ "queueObliterate": "Queue obliterated",
+ "jobQueueDeleteJobSuccess": "Job removed successfully",
+ "jobQueuePauseJob": "Job paused successfully",
+ "jobQueueResumeJob": "Job resumed successfully",
+ "maintenanceWindowGetById": "Got Maintenance Window by Id successfully",
+ "maintenanceWindowCreate": "Maintenance Window created successfully",
+ "maintenanceWindowGetByTeam": "Got Maintenance Windows by Team successfully",
+ "maintenanceWindowDelete": "Maintenance Window deleted successfully",
+ "maintenanceWindowEdit": "Maintenance Window edited successfully",
+ "pingSuccess": "Success",
+ "getAppSettings": "Got app settings successfully",
+ "updateAppSettings": "Updated app settings successfully",
+ "statusPageByUrl": "Got status page by url successfully",
+ "statusPageCreate": "Status page created successfully",
+ "newTermsAdded": "New terms added to POEditor",
+ "dockerSuccess": "Docker container status fetched successfully",
+ "portSuccess": "Port connected successfully",
+ "monitorPause": "Monitor paused successfully",
+ "monitorResume": "Monitor resumed successfully",
+ "statusPageDelete": "Status page deleted successfully",
+ "statusPageUpdate": "Status page updated successfully"
+}