Merge branch 'develop' into enhancement/check-if-url-resolves

This commit is contained in:
om-3004 committed 2024-10-18 11:39:07 +05:30
commit 34a13530b3
202 files changed
+33101 -32065

No files matched your search

+43 -43
View File
@@ -3,54 +3,54 @@ const LOG_LEVEL = import.meta.env.VITE_APP_LOG_LEVEL || "debug";
const NO_OP = () => {};
class Logger {
constructor() {
let logLevel = LOG_LEVEL;
this.unsubscribe = store.subscribe(() => {
const state = store.getState();
logLevel = state.settings.logLevel || "debug";
this.updateLogLevel(logLevel);
});
}
constructor() {
let logLevel = LOG_LEVEL;
this.unsubscribe = store.subscribe(() => {
const state = store.getState();
logLevel = state.settings.logLevel || "debug";
this.updateLogLevel(logLevel);
});
}
updateLogLevel(logLevel) {
if (logLevel === "none") {
this.info = NO_OP;
this.error = NO_OP;
this.warn = NO_OP;
this.log = NO_OP;
return;
}
updateLogLevel(logLevel) {
if (logLevel === "none") {
this.info = NO_OP;
this.error = NO_OP;
this.warn = NO_OP;
this.log = NO_OP;
return;
}
if (logLevel === "error") {
this.error = console.error.bind(console);
this.info = NO_OP;
this.warn = NO_OP;
this.log = NO_OP;
return;
}
if (logLevel === "error") {
this.error = console.error.bind(console);
this.info = NO_OP;
this.warn = NO_OP;
this.log = NO_OP;
return;
}
if (logLevel === "warn") {
this.error = console.error.bind(console);
this.warn = console.warn.bind(console);
this.info = NO_OP;
this.log = NO_OP;
return;
}
if (logLevel === "warn") {
this.error = console.error.bind(console);
this.warn = console.warn.bind(console);
this.info = NO_OP;
this.log = NO_OP;
return;
}
if (logLevel === "info") {
this.error = console.error.bind(console);
this.warn = console.warn.bind(console);
this.info = console.info.bind(console);
this.log = NO_OP;
return;
}
}
if (logLevel === "info") {
this.error = console.error.bind(console);
this.warn = console.warn.bind(console);
this.info = console.info.bind(console);
this.log = NO_OP;
return;
}
}
cleanup() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
cleanup() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
}
export const logger = new Logger();
File diff suppressed because it is too large. Load diff
+5 -5
View File
@@ -5,11 +5,11 @@ import NetworkService from "./NetworkService";
import { store } from "../store";
const NetworkServiceProvider = ({ children }) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const networkService = new NetworkService(store, dispatch, navigate);
setNetworkService(networkService);
return children;
const dispatch = useDispatch();
const navigate = useNavigate();
const networkService = new NetworkService(store, dispatch, navigate);
setNetworkService(networkService);
return children;
};
export default NetworkServiceProvider;
+1 -1
View File
@@ -1 +1 @@
#Utils folder
#Utils folder
+240 -241
View File
@@ -1,256 +1,255 @@
import { createTheme } from "@mui/material";
const text = {
primary: "#fafafa",
secondary: "#e6e6e6",
tertiary: "#a1a1aa",
accent: "#8e8e8f",
disabled: "rgba(172, 172, 172, 0.3)",
primary: "#fafafa",
secondary: "#e6e6e6",
tertiary: "#a1a1aa",
accent: "#8e8e8f",
disabled: "rgba(172, 172, 172, 0.3)",
};
const background = {
main: "#151518",
alt: "#09090b",
fill: "#2D2D33",
accent: "#18181a",
main: "#151518",
alt: "#09090b",
fill: "#2D2D33",
accent: "#18181a",
};
const border = { light: "#27272a", dark: "#36363e" };
const fontFamilyDefault =
'"Inter","system-ui", "Avenir", "Helvetica", "Arial", sans-serif';
'"Inter","system-ui", "Avenir", "Helvetica", "Arial", sans-serif';
const shadow =
"0px 4px 24px -4px rgba(255, 255, 255, 0.03), 0px 3px 3px -3px rgba(255, 255, 255, 0.01)";
"0px 4px 24px -4px rgba(255, 255, 255, 0.03), 0px 3px 3px -3px rgba(255, 255, 255, 0.01)";
const darkTheme = createTheme({
typography: {
fontFamily: fontFamilyDefault,
fontSize: 13,
h1: { fontSize: 22, color: text.primary, fontWeight: 500 },
h2: { fontSize: 14.5, color: text.secondary, fontWeight: 400 },
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
},
palette: {
mode: "dark",
primary: { main: "#1570ef" },
secondary: { main: "#2D2D33" },
text: text,
background: background,
border: border,
info: {
text: text.primary,
main: text.secondary,
bg: background.main,
light: background.main,
border: border.light,
},
success: {
text: "#079455",
main: "#45bb7a",
light: "#1c4428",
bg: "#12261e",
},
error: {
text: "#f04438",
main: "#d32f2f",
light: "#542426",
bg: "#301a1f",
dark: "#932020",
border: "#f04438",
},
warning: {
text: "#e88c30",
main: "#FF9F00",
light: "#624711",
bg: "#262115",
border: "#e88c30",
},
percentage: {
uptimePoor: "#d32f2f",
uptimeFair: "#e88c30",
uptimeGood: "#ffd600",
uptimeExcellent: "#079455",
},
unresolved: { main: "#664eff", light: "#3a1bff", bg: "#f2f4f7" },
divider: border.light,
other: {
icon: "#e6e6e6",
line: "#27272a",
fill: "#18181a",
grid: "#454546",
autofill: "#2d2d33",
},
},
spacing: 2,
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
backgroundImage:
"radial-gradient(circle, #09090b, #0c0c0e, #0f0f11, #111113, #131315, #131315, #131315, #131315, #111113, #0f0f11, #0c0c0e, #09090b)",
lineHeight: "inherit",
paddingLeft: "calc(100vw - 100%)",
},
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: (props) => props.variant === "group",
style: {
color: theme.palette.secondary.contrastText,
backgroundColor: theme.palette.background.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
{
props: (props) =>
props.variant === "group" && props.filled === "true",
style: {
backgroundColor: theme.palette.secondary.main,
},
},
{
props: (props) =>
props.variant === "contained" && props.color === "secondary",
style: {
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.dark,
},
},
],
fontWeight: 400,
borderRadius: 4,
boxShadow: "none",
textTransform: "none",
"&:focus": {
outline: "none",
},
"&:hover": {
boxShadow: "none",
},
}),
},
},
MuiIconButton: {
styleOverrides: {
root: {
padding: 4,
transition: "none",
"&:hover": {
backgroundColor: border.light,
},
},
},
},
MuiPaper: {
styleOverrides: {
root: {
marginTop: 4,
padding: 0,
border: 1,
borderStyle: "solid",
borderColor: border.light,
borderRadius: 4,
boxShadow: shadow,
backgroundColor: background.main,
backgroundImage: "none",
},
},
},
MuiList: {
styleOverrides: {
root: {
padding: 0,
},
},
},
MuiListItemButton: {
styleOverrides: {
root: {
transition: "none",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
borderRadius: 4,
backgroundColor: "inherit",
padding: "4px 6px",
color: text.secondary,
fontSize: 13,
margin: 2,
minWidth: 100,
"&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected.Mui-focusVisible":
{
backgroundColor: background.fill,
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottomColor: border.light,
},
},
},
MuiTableHead: {
styleOverrides: {
root: {
backgroundColor: background.accent,
},
},
},
MuiPagination: {
styleOverrides: {
root: {
backgroundColor: background.main,
border: 1,
borderStyle: "solid",
borderColor: border.light,
"& button": {
color: text.tertiary,
borderRadius: 4,
},
"& li:first-of-type button, & li:last-of-type button": {
border: 1,
borderStyle: "solid",
borderColor: border.light,
},
},
},
},
MuiPaginationItem: {
styleOverrides: {
root: {
"&:not(.MuiPaginationItem-ellipsis):hover, &.Mui-selected": {
backgroundColor: background.fill,
},
},
},
},
MuiSkeleton: {
styleOverrides: {
root: {
backgroundColor: "#151518",
},
},
},
},
shape: {
borderRadius: 2,
borderThick: 2,
boxShadow: shadow,
},
typography: {
fontFamily: fontFamilyDefault,
fontSize: 13,
h1: { fontSize: 22, color: text.primary, fontWeight: 500 },
h2: { fontSize: 14.5, color: text.secondary, fontWeight: 400 },
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
},
palette: {
mode: "dark",
primary: { main: "#1570ef" },
secondary: { main: "#2D2D33" },
text: text,
background: background,
border: border,
info: {
text: text.primary,
main: text.secondary,
bg: background.main,
light: background.main,
border: border.light,
},
success: {
text: "#079455",
main: "#45bb7a",
light: "#1c4428",
bg: "#12261e",
},
error: {
text: "#f04438",
main: "#d32f2f",
light: "#542426",
bg: "#301a1f",
dark: "#932020",
border: "#f04438",
},
warning: {
text: "#e88c30",
main: "#FF9F00",
light: "#624711",
bg: "#262115",
border: "#e88c30",
},
percentage: {
uptimePoor: "#d32f2f",
uptimeFair: "#e88c30",
uptimeGood: "#ffd600",
uptimeExcellent: "#079455",
},
unresolved: { main: "#664eff", light: "#3a1bff", bg: "#f2f4f7" },
divider: border.light,
other: {
icon: "#e6e6e6",
line: "#27272a",
fill: "#18181a",
grid: "#454546",
autofill: "#2d2d33",
},
},
spacing: 2,
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
backgroundImage:
"radial-gradient(circle, #09090b, #0c0c0e, #0f0f11, #111113, #131315, #131315, #131315, #131315, #111113, #0f0f11, #0c0c0e, #09090b)",
lineHeight: "inherit",
paddingLeft: "calc(100vw - 100%)",
},
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: (props) => props.variant === "group",
style: {
color: theme.palette.secondary.contrastText,
backgroundColor: theme.palette.background.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
{
props: (props) => props.variant === "group" && props.filled === "true",
style: {
backgroundColor: theme.palette.secondary.main,
},
},
{
props: (props) =>
props.variant === "contained" && props.color === "secondary",
style: {
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.dark,
},
},
],
fontWeight: 400,
borderRadius: 4,
boxShadow: "none",
textTransform: "none",
"&:focus": {
outline: "none",
},
"&:hover": {
boxShadow: "none",
},
}),
},
},
MuiIconButton: {
styleOverrides: {
root: {
padding: 4,
transition: "none",
"&:hover": {
backgroundColor: border.light,
},
},
},
},
MuiPaper: {
styleOverrides: {
root: {
marginTop: 4,
padding: 0,
border: 1,
borderStyle: "solid",
borderColor: border.light,
borderRadius: 4,
boxShadow: shadow,
backgroundColor: background.main,
backgroundImage: "none",
},
},
},
MuiList: {
styleOverrides: {
root: {
padding: 0,
},
},
},
MuiListItemButton: {
styleOverrides: {
root: {
transition: "none",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
borderRadius: 4,
backgroundColor: "inherit",
padding: "4px 6px",
color: text.secondary,
fontSize: 13,
margin: 2,
minWidth: 100,
"&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected.Mui-focusVisible":
{
backgroundColor: background.fill,
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottomColor: border.light,
},
},
},
MuiTableHead: {
styleOverrides: {
root: {
backgroundColor: background.accent,
},
},
},
MuiPagination: {
styleOverrides: {
root: {
backgroundColor: background.main,
border: 1,
borderStyle: "solid",
borderColor: border.light,
"& button": {
color: text.tertiary,
borderRadius: 4,
},
"& li:first-of-type button, & li:last-of-type button": {
border: 1,
borderStyle: "solid",
borderColor: border.light,
},
},
},
},
MuiPaginationItem: {
styleOverrides: {
root: {
"&:not(.MuiPaginationItem-ellipsis):hover, &.Mui-selected": {
backgroundColor: background.fill,
},
},
},
},
MuiSkeleton: {
styleOverrides: {
root: {
backgroundColor: "#151518",
},
},
},
},
shape: {
borderRadius: 2,
borderThick: 2,
boxShadow: shadow,
},
});
export default darkTheme;
+237 -238
View File
@@ -1,253 +1,252 @@
import { createTheme } from "@mui/material";
const text = {
primary: "#1c2130",
secondary: "#344054",
tertiary: "#475467",
accent: "#838c99",
primary: "#1c2130",
secondary: "#344054",
tertiary: "#475467",
accent: "#838c99",
};
const background = {
main: "#FFFFFF",
alt: "#FCFCFD",
fill: "#F4F4F4",
accent: "#f9fafb",
main: "#FFFFFF",
alt: "#FCFCFD",
fill: "#F4F4F4",
accent: "#f9fafb",
};
const border = { light: "#eaecf0", dark: "#d0d5dd" };
const fontFamilyDefault =
'"Inter","system-ui", "Avenir", "Helvetica", "Arial", sans-serif';
'"Inter","system-ui", "Avenir", "Helvetica", "Arial", sans-serif';
const shadow =
"0px 4px 24px -4px rgba(16, 24, 40, 0.08), 0px 3px 3px -3px rgba(16, 24, 40, 0.03)";
"0px 4px 24px -4px rgba(16, 24, 40, 0.08), 0px 3px 3px -3px rgba(16, 24, 40, 0.03)";
const lightTheme = createTheme({
typography: {
fontFamily: fontFamilyDefault,
fontSize: 13,
h1: { fontSize: 22, color: text.primary, fontWeight: 500 },
h2: { fontSize: 14.5, color: text.secondary, fontWeight: 400 },
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
},
palette: {
primary: { main: "#1570EF" },
secondary: { main: "#F4F4F4", dark: "#e3e3e3", contrastText: "#475467" },
text: text,
background: background,
border: border,
info: {
text: text.primary,
main: text.tertiary,
bg: background.main,
light: background.main,
border: border.dark,
},
success: {
text: "#079455",
main: "#17b26a",
light: "#d4f4e1",
bg: "#ecfdf3",
},
error: {
text: "#f04438",
main: "#d32f2f",
light: "#fbd1d1",
bg: "#f9eced",
border: "#f04438",
},
warning: {
text: "#DC6803",
main: "#fdb022",
light: "#ffecbc",
bg: "#fef8ea",
border: "#fec84b",
},
percentage: {
uptimePoor: "#d32f2f",
uptimeFair: "#ec8013",
uptimeGood: "#ffb800",
uptimeExcellent: "#079455",
},
unresolved: { main: "#4e5ba6", light: "#e2eaf7", bg: "#f2f4f7" },
divider: border.light,
other: {
icon: "#667085",
line: "#d6d9dd",
fill: "#e3e3e3",
grid: "#a2a3a3",
autofill: "#e8f0fe",
},
},
spacing: 2,
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
backgroundImage:
"radial-gradient(circle, #fcfcfd, #fdfcfd, #fdfdfd, #fefdfe, #fefefe, #fefefe, #fefefe, #fefefe, #fefdfe, #fdfdfd, #fdfcfd, #fcfcfd)",
lineHeight: "inherit",
paddingLeft: "calc(100vw - 100%)",
},
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: (props) => props.variant === "group",
style: {
color: theme.palette.secondary.contrastText,
backgroundColor: theme.palette.background.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
{
props: (props) =>
props.variant === "group" && props.filled === "true",
style: {
backgroundColor: theme.palette.secondary.main,
},
},
{
props: (props) =>
props.variant === "contained" && props.color === "secondary",
style: {
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
],
fontWeight: 400,
borderRadius: 4,
boxShadow: "none",
textTransform: "none",
"&:focus": {
outline: "none",
},
"&:hover": {
boxShadow: "none",
},
}),
},
},
MuiIconButton: {
styleOverrides: {
root: {
padding: 4,
transition: "none",
"&:hover": {
backgroundColor: background.fill,
},
},
},
},
MuiPaper: {
styleOverrides: {
root: {
marginTop: 4,
padding: 0,
border: 1,
borderStyle: "solid",
borderColor: border.light,
borderRadius: 4,
boxShadow: shadow,
backgroundColor: background.main,
backgroundImage: "none",
},
},
},
MuiList: {
styleOverrides: {
root: {
padding: 0,
},
},
},
MuiListItemButton: {
styleOverrides: {
root: {
transition: "none",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
borderRadius: 4,
backgroundColor: "inherit",
padding: "4px 6px",
color: text.secondary,
fontSize: 13,
margin: 2,
minWidth: 100,
"&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected.Mui-focusVisible":
{
backgroundColor: background.fill,
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottomColor: border.light,
},
},
},
MuiTableHead: {
styleOverrides: {
root: {
backgroundColor: background.accent,
},
},
},
MuiPagination: {
styleOverrides: {
root: {
backgroundColor: background.main,
border: 1,
borderStyle: "solid",
borderColor: border.light,
"& button": {
color: text.tertiary,
borderRadius: 4,
},
"& li:first-of-type button, & li:last-of-type button": {
border: 1,
borderStyle: "solid",
borderColor: border.light,
},
},
},
},
MuiPaginationItem: {
styleOverrides: {
root: {
"&:not(.MuiPaginationItem-ellipsis):hover, &.Mui-selected": {
backgroundColor: background.fill,
},
},
},
},
MuiSkeleton: {
styleOverrides: {
root: {
backgroundColor: "#f2f4f7",
},
},
},
},
shape: {
borderRadius: 2,
borderThick: 2,
boxShadow: shadow,
},
typography: {
fontFamily: fontFamilyDefault,
fontSize: 13,
h1: { fontSize: 22, color: text.primary, fontWeight: 500 },
h2: { fontSize: 14.5, color: text.secondary, fontWeight: 400 },
body1: { fontSize: 13, color: text.tertiary, fontWeight: 400 },
body2: { fontSize: 12, color: text.tertiary, fontWeight: 400 },
},
palette: {
primary: { main: "#1570EF" },
secondary: { main: "#F4F4F4", dark: "#e3e3e3", contrastText: "#475467" },
text: text,
background: background,
border: border,
info: {
text: text.primary,
main: text.tertiary,
bg: background.main,
light: background.main,
border: border.dark,
},
success: {
text: "#079455",
main: "#17b26a",
light: "#d4f4e1",
bg: "#ecfdf3",
},
error: {
text: "#f04438",
main: "#d32f2f",
light: "#fbd1d1",
bg: "#f9eced",
border: "#f04438",
},
warning: {
text: "#DC6803",
main: "#fdb022",
light: "#ffecbc",
bg: "#fef8ea",
border: "#fec84b",
},
percentage: {
uptimePoor: "#d32f2f",
uptimeFair: "#ec8013",
uptimeGood: "#ffb800",
uptimeExcellent: "#079455",
},
unresolved: { main: "#4e5ba6", light: "#e2eaf7", bg: "#f2f4f7" },
divider: border.light,
other: {
icon: "#667085",
line: "#d6d9dd",
fill: "#e3e3e3",
grid: "#a2a3a3",
autofill: "#e8f0fe",
},
},
spacing: 2,
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
backgroundImage:
"radial-gradient(circle, #fcfcfd, #fdfcfd, #fdfdfd, #fefdfe, #fefefe, #fefefe, #fefefe, #fefefe, #fefdfe, #fdfdfd, #fdfcfd, #fcfcfd)",
lineHeight: "inherit",
paddingLeft: "calc(100vw - 100%)",
},
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
root: ({ theme }) => ({
variants: [
{
props: (props) => props.variant === "group",
style: {
color: theme.palette.secondary.contrastText,
backgroundColor: theme.palette.background.main,
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
{
props: (props) => props.variant === "group" && props.filled === "true",
style: {
backgroundColor: theme.palette.secondary.main,
},
},
{
props: (props) =>
props.variant === "contained" && props.color === "secondary",
style: {
border: 1,
borderStyle: "solid",
borderColor: theme.palette.border.light,
},
},
],
fontWeight: 400,
borderRadius: 4,
boxShadow: "none",
textTransform: "none",
"&:focus": {
outline: "none",
},
"&:hover": {
boxShadow: "none",
},
}),
},
},
MuiIconButton: {
styleOverrides: {
root: {
padding: 4,
transition: "none",
"&:hover": {
backgroundColor: background.fill,
},
},
},
},
MuiPaper: {
styleOverrides: {
root: {
marginTop: 4,
padding: 0,
border: 1,
borderStyle: "solid",
borderColor: border.light,
borderRadius: 4,
boxShadow: shadow,
backgroundColor: background.main,
backgroundImage: "none",
},
},
},
MuiList: {
styleOverrides: {
root: {
padding: 0,
},
},
},
MuiListItemButton: {
styleOverrides: {
root: {
transition: "none",
},
},
},
MuiMenuItem: {
styleOverrides: {
root: {
borderRadius: 4,
backgroundColor: "inherit",
padding: "4px 6px",
color: text.secondary,
fontSize: 13,
margin: 2,
minWidth: 100,
"&:hover, &.Mui-selected, &.Mui-selected:hover, &.Mui-selected.Mui-focusVisible":
{
backgroundColor: background.fill,
},
},
},
},
MuiTableCell: {
styleOverrides: {
root: {
borderBottomColor: border.light,
},
},
},
MuiTableHead: {
styleOverrides: {
root: {
backgroundColor: background.accent,
},
},
},
MuiPagination: {
styleOverrides: {
root: {
backgroundColor: background.main,
border: 1,
borderStyle: "solid",
borderColor: border.light,
"& button": {
color: text.tertiary,
borderRadius: 4,
},
"& li:first-of-type button, & li:last-of-type button": {
border: 1,
borderStyle: "solid",
borderColor: border.light,
},
},
},
},
MuiPaginationItem: {
styleOverrides: {
root: {
"&:not(.MuiPaginationItem-ellipsis):hover, &.Mui-selected": {
backgroundColor: background.fill,
},
},
},
},
MuiSkeleton: {
styleOverrides: {
root: {
backgroundColor: "#f2f4f7",
},
},
},
},
shape: {
borderRadius: 2,
borderThick: 2,
boxShadow: shadow,
},
});
export default lightTheme;
+10 -10
View File
@@ -1,18 +1,18 @@
import { useState, useEffect } from "react";
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value);
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
};
export default useDebounce;
+7 -7
View File
@@ -1,11 +1,11 @@
export const formatBytes = (bytes) => {
if (bytes === 0) return "0 Bytes";
const megabytes = bytes / (1024 * 1024);
return megabytes.toFixed(2) + " MB";
if (bytes === 0) return "0 Bytes";
const megabytes = bytes / (1024 * 1024);
return megabytes.toFixed(2) + " MB";
};
export const checkImage = (url) => {
const img = new Image();
img.src = url;
return img.naturalWidth !== 0;
};
const img = new Image();
img.src = url;
return img.naturalWidth !== 0;
};
+149 -138
View File
@@ -6,115 +6,115 @@ import { useEffect } from "react";
import { setGreeting } from "../Features/UI/uiSlice";
const early = [
{
prepend: "Rise and shine",
append: "If you’re up this early, you might as well be a legend!",
emoji: "☕",
},
{
prepend: "Good morning",
append: "The world’s still asleep, but you’re already awesome!",
emoji: "🦉",
},
{
prepend: "Good morning",
append: "Are you a wizard? Only magical people are up at this hour!",
emoji: "🌄",
},
{
prepend: "Up before the roosters",
append: "Ready to tackle the day before it even starts?",
emoji: "🐓",
},
{
prepend: "Early bird special",
append: "Let’s get things done while everyone else is snoozing!",
emoji: "🌟",
},
{
prepend: "Rise and shine",
append: "If you’re up this early, you might as well be a legend!",
emoji: "☕",
},
{
prepend: "Good morning",
append: "The world’s still asleep, but you’re already awesome!",
emoji: "🦉",
},
{
prepend: "Good morning",
append: "Are you a wizard? Only magical people are up at this hour!",
emoji: "🌄",
},
{
prepend: "Up before the roosters",
append: "Ready to tackle the day before it even starts?",
emoji: "🐓",
},
{
prepend: "Early bird special",
append: "Let’s get things done while everyone else is snoozing!",
emoji: "🌟",
},
];
const morning = [
{
prepend: "Good morning",
append: "Is it coffee o’clock yet, or should we start with high fives?",
emoji: "☕",
},
{
prepend: "Morning",
append: "The sun is up, and so are you—time to be amazing!",
emoji: "🌞",
},
{
prepend: "Good morning",
append: "Time to make today the best thing since sliced bread!",
emoji: "🥐",
},
{
prepend: "Morning",
append: "Let’s kick off the day with more energy than a double espresso!",
emoji: "🚀",
},
{
prepend: "Rise and shine",
append: "You’re about to make today so great, even Monday will be jealous!",
emoji: "🌟",
},
{
prepend: "Good morning",
append: "Is it coffee o’clock yet, or should we start with high fives?",
emoji: "☕",
},
{
prepend: "Morning",
append: "The sun is up, and so are you—time to be amazing!",
emoji: "🌞",
},
{
prepend: "Good morning",
append: "Time to make today the best thing since sliced bread!",
emoji: "🥐",
},
{
prepend: "Morning",
append: "Let’s kick off the day with more energy than a double espresso!",
emoji: "🚀",
},
{
prepend: "Rise and shine",
append: "You’re about to make today so great, even Monday will be jealous!",
emoji: "🌟",
},
];
const afternoon = [
{
prepend: "Good afternoon",
append: "How about a break to celebrate how awesome you’re doing?",
emoji: "🥪",
},
{
prepend: "Afternoon",
append: "If you’re still going strong, you’re officially a rockstar!",
emoji: "🌞",
},
{
prepend: "Hey there",
append: "The afternoon is your playground—let’s make it epic!",
emoji: "🍕",
},
{
prepend: "Good afternoon",
append: "Time to crush the rest of the day like a pro!",
emoji: "🏆",
},
{
prepend: "Afternoon",
append: "Time to turn those afternoon slumps into afternoon triumphs!",
emoji: "🎉",
},
{
prepend: "Good afternoon",
append: "How about a break to celebrate how awesome you’re doing?",
emoji: "🥪",
},
{
prepend: "Afternoon",
append: "If you’re still going strong, you’re officially a rockstar!",
emoji: "🌞",
},
{
prepend: "Hey there",
append: "The afternoon is your playground—let’s make it epic!",
emoji: "🍕",
},
{
prepend: "Good afternoon",
append: "Time to crush the rest of the day like a pro!",
emoji: "🏆",
},
{
prepend: "Afternoon",
append: "Time to turn those afternoon slumps into afternoon triumphs!",
emoji: "🎉",
},
];
const evening = [
{
prepend: "Good evening",
append: "Time to wind down and think about how you crushed today!",
emoji: "🌇",
},
{
prepend: "Evening",
append: "You’ve earned a break—let’s make the most of these evening vibes!",
emoji: "🍹",
},
{
prepend: "Hey there",
append: "Time to relax and bask in the glow of your day’s awesomeness!",
emoji: "🌙",
},
{
prepend: "Good evening",
append: "Ready to trade productivity for chill mode?",
emoji: "🛋️ ",
},
{
prepend: "Evening",
append: "Let’s call it a day and toast to your success!",
emoji: "🕶️",
},
{
prepend: "Good evening",
append: "Time to wind down and think about how you crushed today!",
emoji: "🌇",
},
{
prepend: "Evening",
append: "You’ve earned a break—let’s make the most of these evening vibes!",
emoji: "🍹",
},
{
prepend: "Hey there",
append: "Time to relax and bask in the glow of your day’s awesomeness!",
emoji: "🌙",
},
{
prepend: "Good evening",
append: "Ready to trade productivity for chill mode?",
emoji: "🛋️ ",
},
{
prepend: "Evening",
append: "Let’s call it a day and toast to your success!",
emoji: "🕶️",
},
];
/**
@@ -131,52 +131,63 @@ const evening = [
*/
const Greeting = ({ type = "" }) => {
const theme = useTheme();
const dispatch = useDispatch();
const { firstName } = useSelector((state) => state.auth.user);
const index = useSelector((state) => state.ui.greeting.index);
const lastUpdate = useSelector((state) => state.ui.greeting.lastUpdate);
const theme = useTheme();
const dispatch = useDispatch();
const { firstName } = useSelector((state) => state.auth.user);
const index = useSelector((state) => state.ui.greeting.index);
const lastUpdate = useSelector((state) => state.ui.greeting.lastUpdate);
const now = new Date();
const hour = now.getHours();
const now = new Date();
const hour = now.getHours();
useEffect(() => {
const hourDiff = lastUpdate ? hour - lastUpdate : null;
useEffect(() => {
const hourDiff = lastUpdate ? hour - lastUpdate : null;
if (!lastUpdate || hourDiff >= 1) {
let random = Math.floor(Math.random() * 5);
dispatch(setGreeting({ index: random, lastUpdate: hour }));
}
}, [dispatch, hour]);
if (!lastUpdate || hourDiff >= 1) {
let random = Math.floor(Math.random() * 5);
dispatch(setGreeting({ index: random, lastUpdate: hour }));
}
}, [dispatch, hour]);
let greetingArray =
hour < 6 ? early : hour < 12 ? morning : hour < 18 ? afternoon : evening;
const { prepend, append, emoji } = greetingArray[index];
let greetingArray =
hour < 6 ? early : hour < 12 ? morning : hour < 18 ? afternoon : evening;
const { prepend, append, emoji } = greetingArray[index];
return (
<Box>
<Typography component="h1" variant="h1" mb={theme.spacing(1)}>
<Typography component="span" fontSize="inherit">
{prepend},{" "}
</Typography>
<Typography
component="span"
fontSize="inherit"
fontWeight="inherit"
color={theme.palette.text.secondary}
>
{firstName} {emoji}
</Typography>
</Typography>
<Typography variant="h2" lineHeight={1} color={theme.palette.text.accent}>
{append} — Here’s an overview of your {type} monitors.
</Typography>
</Box>
);
return (
<Box>
<Typography
component="h1"
variant="h1"
mb={theme.spacing(1)}
>
<Typography
component="span"
fontSize="inherit"
>
{prepend},{" "}
</Typography>
<Typography
component="span"
fontSize="inherit"
fontWeight="inherit"
color={theme.palette.text.secondary}
>
{firstName} {emoji}
</Typography>
</Typography>
<Typography
variant="h2"
lineHeight={1}
color={theme.palette.text.accent}
>
{append} — Here’s an overview of your {type} monitors.
</Typography>
</Box>
);
};
Greeting.propTypes = {
type: PropTypes.string,
type: PropTypes.string,
};
export default Greeting;
+8 -8
View File
@@ -5,13 +5,13 @@
* @returns {number} Timestamp of the most recent check.
*/
export const getLastChecked = (checks, duration = true) => {
if (!checks || checks.length === 0) {
return 0; // Handle case when no checks are available
}
if (!checks || checks.length === 0) {
return 0; // Handle case when no checks are available
}
// Data is sorted newest -> oldest, so newest check is the most recent
if (!duration) {
return new Date(checks[0].createdAt);
}
return new Date() - new Date(checks[0].createdAt);
// Data is sorted newest -> oldest, so newest check is the most recent
if (!duration) {
return new Date(checks[0].createdAt);
}
return new Date() - new Date(checks[0].createdAt);
};
+61 -61
View File
@@ -11,85 +11,85 @@ export const MS_PER_DAY = 24 * MS_PER_HOUR;
export const MS_PER_WEEK = MS_PER_DAY * 7;
export const formatDuration = (ms) => {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
let dateStr = "";
let dateStr = "";
days && (dateStr += `${days}d `);
hours && (dateStr += `${hours % 24}h `);
minutes && (dateStr += `${minutes % 60}m `);
seconds && (dateStr += `${seconds % 60}s `);
days && (dateStr += `${days}d `);
hours && (dateStr += `${hours % 24}h `);
minutes && (dateStr += `${minutes % 60}m `);
seconds && (dateStr += `${seconds % 60}s `);
dateStr === "" && (dateStr = "0s");
dateStr === "" && (dateStr = "0s");
return dateStr;
return dateStr;
};
export const formatDurationRounded = (ms) => {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
let time = "";
if (days > 0) {
time += `${days} day${days !== 1 ? "s" : ""}`;
return time;
}
if (hours > 0) {
time += `${hours} hour${hours !== 1 ? "s" : ""}`;
return time;
}
if (minutes > 0) {
time += `${minutes} minute${minutes !== 1 ? "s" : ""}`;
return time;
}
if (seconds > 0) {
time += `${seconds} second${seconds !== 1 ? "s" : ""}`;
return time;
}
let time = "";
if (days > 0) {
time += `${days} day${days !== 1 ? "s" : ""}`;
return time;
}
if (hours > 0) {
time += `${hours} hour${hours !== 1 ? "s" : ""}`;
return time;
}
if (minutes > 0) {
time += `${minutes} minute${minutes !== 1 ? "s" : ""}`;
return time;
}
if (seconds > 0) {
time += `${seconds} second${seconds !== 1 ? "s" : ""}`;
return time;
}
return time;
return time;
};
export const formatDurationSplit = (ms) => {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
return days > 0
? { time: days, format: days === 1 ? "day" : "days" }
: hours > 0
? { time: hours, format: hours === 1 ? "hour" : "hours" }
: minutes > 0
? { time: minutes, format: minutes === 1 ? "minute" : "minutes" }
: seconds > 0
? { time: seconds, format: seconds === 1 ? "second" : "seconds" }
: { time: 0, format: "seconds" };
return days > 0
? { time: days, format: days === 1 ? "day" : "days" }
: hours > 0
? { time: hours, format: hours === 1 ? "hour" : "hours" }
: minutes > 0
? { time: minutes, format: minutes === 1 ? "minute" : "minutes" }
: seconds > 0
? { time: seconds, format: seconds === 1 ? "second" : "seconds" }
: { time: 0, format: "seconds" };
};
export const formatDate = (date, customOptions) => {
const options = {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: true,
...customOptions,
};
const options = {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: true,
...customOptions,
};
// Return the date using the specified options
return date
.toLocaleString("en-US", options)
.replace(/\b(AM|PM)\b/g, (match) => match.toLowerCase());
// Return the date using the specified options
return date
.toLocaleString("en-US", options)
.replace(/\b(AM|PM)\b/g, (match) => match.toLowerCase());
};
export const formatDateWithTz = (timestamp, format, timezone) => {
const formattedDate = dayjs(timestamp, timezone).tz(timezone).format(format);
return formattedDate;
const formattedDate = dayjs(timestamp, timezone).tz(timezone).format(format);
return formattedDate;
};
File diff suppressed because it is too large. Load diff
+31 -31
View File
@@ -12,40 +12,40 @@ import Alert from "../Components/Alert";
*/
export const createToast = ({
variant = "info",
title,
body,
hasIcon = false,
config = {},
variant = "info",
title,
body,
hasIcon = false,
config = {},
}) => {
const toastConfig = {
position: "top-right",
autoClose: 3000,
hideProgressBar: true,
closeButton: false,
transition: Slide,
...config,
};
const toastConfig = {
position: "top-right",
autoClose: 3000,
hideProgressBar: true,
closeButton: false,
transition: Slide,
...config,
};
toast(
({ closeToast }) => (
<Alert
variant={variant}
title={title}
body={body}
isToast={true}
hasIcon={hasIcon}
onClick={closeToast}
/>
),
toastConfig
);
toast(
({ closeToast }) => (
<Alert
variant={variant}
title={title}
body={body}
isToast={true}
hasIcon={hasIcon}
onClick={closeToast}
/>
),
toastConfig
);
};
createToast.propTypes = {
variant: PropTypes.oneOf(["info", "error", "warning"]),
title: PropTypes.string,
body: PropTypes.string.isRequired,
hasIcon: PropTypes.bool,
config: PropTypes.object,
variant: PropTypes.oneOf(["info", "error", "warning"]),
title: PropTypes.string,
body: PropTypes.string.isRequired,
hasIcon: PropTypes.bool,
config: PropTypes.object,
};