From 23672cbf34503427a96642a45685c9d307612024 Mon Sep 17 00:00:00 2001 From: Jasneet Singh Date: Sat, 22 Feb 2025 10:15:17 -0500 Subject: [PATCH 01/61] Enhance wallet button layout for better responsiveness and alignment. --- src/Pages/Settings/index.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Pages/Settings/index.jsx b/src/Pages/Settings/index.jsx index 04b8658dc..a8fc3c3c0 100644 --- a/src/Pages/Settings/index.jsx +++ b/src/Pages/Settings/index.jsx @@ -375,9 +375,10 @@ const Settings = () => { - - + + From 591c531192116d1e5e0b0ebfe76ad353e24f0262 Mon Sep 17 00:00:00 2001 From: Jasneet Singh Date: Sat, 22 Feb 2025 16:00:10 -0500 Subject: [PATCH 02/61] updated --- src/Pages/Settings/index.jsx | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Pages/Settings/index.jsx b/src/Pages/Settings/index.jsx index a8fc3c3c0..dbc59073d 100644 --- a/src/Pages/Settings/index.jsx +++ b/src/Pages/Settings/index.jsx @@ -371,15 +371,32 @@ const Settings = () => { monitor to connect to multiple nodes globally. - - - - - + + + )} From 64166d25394df499e46ff540deb55b8410a61f3c Mon Sep 17 00:00:00 2001 From: Jasneet Singh Date: Mon, 24 Feb 2025 18:51:33 -0500 Subject: [PATCH 03/61] updated --- src/Pages/Settings/index.jsx | 46 +++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/Pages/Settings/index.jsx b/src/Pages/Settings/index.jsx index dbc59073d..b7104d71e 100644 --- a/src/Pages/Settings/index.jsx +++ b/src/Pages/Settings/index.jsx @@ -373,28 +373,46 @@ const Settings = () => { From 4b63076acc08699267faad23ce149b38038e2c31 Mon Sep 17 00:00:00 2001 From: Jasneet Singh Date: Fri, 28 Feb 2025 21:13:03 -0500 Subject: [PATCH 04/61] Add responsive styles for wallet components and integrate CSS --- src/Components/WalletProvider/index.css | 41 +++++++++++++++++++ src/Components/WalletProvider/index.jsx | 1 + src/Pages/Settings/index.jsx | 53 +++++-------------------- 3 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 src/Components/WalletProvider/index.css diff --git a/src/Components/WalletProvider/index.css b/src/Components/WalletProvider/index.css new file mode 100644 index 000000000..2ba40c8b3 --- /dev/null +++ b/src/Components/WalletProvider/index.css @@ -0,0 +1,41 @@ +.wallet-adapter-dropdown { + width: 100%; +} + +.wallet-adapter-button { + width: 100%; + justify-content: center; + height: var(--button-height) !important; + font-size: var(--font-size-body) !important; + font-weight: var(--font-weight-medium) !important; + margin: var(--spacing-xs) 0; + white-space: nowrap; +} + +.wallet-adapter-modal-title { + font-size: var(--font-size-h5) !important; +} + +/* Separator styling */ +.wallet-adapter-modal-divider { + background-color: var(--border-color) !important; + margin: var(--spacing-md) 0 !important; +} + +/* Responsive fixes */ +@media (max-width: 1093px) { + .wallet-adapter-button { + padding: var(--spacing-xs) var(--spacing-sm) !important; + font-size: calc(var(--font-size-body) * 0.9) !important; + } +} + +@media (max-width: 910px) { + .wallet-adapter-modal-wrapper { + flex-direction: column !important; + } + + .wallet-adapter-modal-divider { + margin: var(--spacing-sm) 0 !important; + } +} \ No newline at end of file diff --git a/src/Components/WalletProvider/index.jsx b/src/Components/WalletProvider/index.jsx index a24124d93..9491c1d39 100644 --- a/src/Components/WalletProvider/index.jsx +++ b/src/Components/WalletProvider/index.jsx @@ -9,6 +9,7 @@ import { import { WalletModalProvider } from "@solana/wallet-adapter-react-ui"; import { clusterApiUrl } from "@solana/web3.js"; import PropTypes from "prop-types"; +import "./index.css"; // Default styles that can be overridden by your app import "@solana/wallet-adapter-react-ui/styles.css"; diff --git a/src/Pages/Settings/index.jsx b/src/Pages/Settings/index.jsx index b7104d71e..34a82204c 100644 --- a/src/Pages/Settings/index.jsx +++ b/src/Pages/Settings/index.jsx @@ -371,54 +371,19 @@ const Settings = () => { monitor to connect to multiple nodes globally. - - - + + + + + )} + About From b44d1429202f0539c88bc262e0d641a508b9ad7a Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 1 Mar 2025 22:36:07 -0800 Subject: [PATCH 05/61] Implemented notification modal. --- src/Pages/Uptime/Create/index.jsx | 15 +- .../NotificationIntegrationModal.jsx | 413 ++++++++++++++++++ 2 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx diff --git a/src/Pages/Uptime/Create/index.jsx b/src/Pages/Uptime/Create/index.jsx index edad33d20..b9bb7eb8f 100644 --- a/src/Pages/Uptime/Create/index.jsx +++ b/src/Pages/Uptime/Create/index.jsx @@ -23,6 +23,7 @@ import Radio from "../../../Components/Inputs/Radio"; import Checkbox from "../../../Components/Inputs/Checkbox"; import Select from "../../../Components/Inputs/Select"; import ConfigBox from "../../../Components/ConfigBox"; +import NotificationIntegrationModal from "../Details/Components/NotificationIntegrationModal/NotificationIntegrationModal"; const CreateMonitor = () => { const MS_PER_MINUTE = 60000; const SELECT_VALUES = [ @@ -80,6 +81,11 @@ const CreateMonitor = () => { ]; // State + const [isNotificationModalOpen, setIsNotificationModalOpen] = useState(false); + + const handleOpenNotificationModal = () => { + setIsNotificationModalOpen(true); + }; const [errors, setErrors] = useState({}); const [https, setHttps] = useState(true); const [monitor, setMonitor] = useState({ @@ -411,7 +417,7 @@ const CreateMonitor = () => { @@ -512,6 +518,13 @@ const CreateMonitor = () => { + + setIsNotificationModalOpen(false)} + monitor={monitor} + setMonitor={setMonitor} + /> ); }; diff --git a/src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx new file mode 100644 index 000000000..eca6a78d0 --- /dev/null +++ b/src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -0,0 +1,413 @@ +import { useState } from "react"; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Button, + Stack, + Typography, + Box, + Tabs, + Tab, + Divider +} from "@mui/material"; +import { useTheme } from "@emotion/react"; +import TextInput from "../../../../../../src/Components/Inputs/TextInput"; +import Checkbox from "../../../../../../src/Components/Inputs/Checkbox"; + +// Tab Panel component +function TabPanel({ children, value, index, ...other }) { + return ( + + ); +} + +const NotificationIntegrationModal = ({ + open, + onClose, + monitor, + setMonitor +}) => { + const theme = useTheme(); + const [tabValue, setTabValue] = useState(0); + const [integrations, setIntegrations] = useState({ + slack: monitor?.notifications?.some(n => n.type === "slack") || false, + slackWebhook: monitor?.notifications?.find(n => n.type === "slack")?.webhook || "", + discord: monitor?.notifications?.some(n => n.type === "discord") || false, + discordWebhook: monitor?.notifications?.find(n => n.type === "discord")?.webhook || "", + telegram: monitor?.notifications?.some(n => n.type === "telegram") || false, + telegramToken: monitor?.notifications?.find(n => n.type === "telegram")?.token || "", + telegramChatId: monitor?.notifications?.find(n => n.type === "telegram")?.chatId || "", + webhook: monitor?.notifications?.some(n => n.type === "webhook") || false, + webhookUrl: monitor?.notifications?.find(n => n.type === "webhook")?.url || "", + }); + + const testNotificationButtonStyle = { + textDecoration: 'underline', + color: '#344054', + textTransform: 'none', + padding: '0 !important', + margin: 0, + fontSize: '0.9rem', + fontWeight: 'normal', + backgroundColor: 'transparent !important', + '&:hover': { + backgroundColor: 'transparent !important', + textDecoration: 'underline' + }, + '&.Mui-disabled': { + backgroundColor: 'transparent !important' + }, + minWidth: '0 !important', + boxShadow: 'none !important', + border: 'none !important' + }; + + const handleChangeTab = (event, newValue) => { + setTabValue(newValue); + }; + + const handleIntegrationChange = (type, checked) => { + setIntegrations(prev => ({ + ...prev, + [type]: checked + })); + }; + + const handleInputChange = (type, value) => { + setIntegrations(prev => ({ + ...prev, + [type]: value + })); + }; + + const handleTestNotification = (type) => { + console.log(`Testing ${type} notification`); + // Here you would implement the actual test notification functionality + }; + + const handleSave = () => { + // Create notifications array based on selected integrations + const notifications = [...(monitor?.notifications || [])]; + + // Filter out existing integrations that will be updated + const existingTypes = ["slack", "discord", "telegram", "webhook"]; + const filteredNotifications = notifications.filter( + notification => !existingTypes.includes(notification.type) + ); + + // Add selected integrations + if (integrations.slack) { + filteredNotifications.push({ + type: "slack", + webhook: integrations.slackWebhook + }); + } + + if (integrations.discord) { + filteredNotifications.push({ + type: "discord", + webhook: integrations.discordWebhook + }); + } + + if (integrations.telegram) { + filteredNotifications.push({ + type: "telegram", + token: integrations.telegramToken, + chatId: integrations.telegramChatId + }); + } + + if (integrations.webhook) { + filteredNotifications.push({ + type: "webhook", + url: integrations.webhookUrl + }); + } + + // Update monitor with new notifications + setMonitor(prev => ({ + ...prev, + notifications: filteredNotifications + })); + + onClose(); + }; + + return ( + + + + + {/* Left sidebar with tabs */} + + + Add or edit notifications + + + + + + + + + + + {/* Right side content */} + + {/* Slack Tab */} + + Slack + + To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here. + + + + handleIntegrationChange('slack', e.target.checked)} + /> + + + + Webhook URL + handleInputChange('slackWebhook', e.target.value)} + disabled={!integrations.slack} + /> + + + + + + + + {/* Discord Tab */} + + Discord + + To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature. + + + + handleIntegrationChange('discord', e.target.checked)} + /> + + + + Discord Webhook URL + handleInputChange('discordWebhook', e.target.value)} + disabled={!integrations.discord} + /> + + + + + + + + {/* Telegram Tab */} + + Telegram + + To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here. + + + + handleIntegrationChange('telegram', e.target.checked)} + /> + + + + Your bot token + handleInputChange('telegramToken', e.target.value)} + disabled={!integrations.telegram} + /> + + + + Your Chat ID + handleInputChange('telegramChatId', e.target.value)} + disabled={!integrations.telegram} + /> + + + + + + + + {/* Webhooks Tab */} + + Webhooks + + You can set up a custom webhook to receive notifications when incidents occur. + + + + handleIntegrationChange('webhook', e.target.checked)} + /> + + + + Webhook URL + handleInputChange('webhookUrl', e.target.value)} + disabled={!integrations.webhook} + /> + + + + + + + + + + + + + + ); +}; + +export default NotificationIntegrationModal; \ No newline at end of file From 825a2e2bc46dbe72bd7d8ac1f9f06335e45df30e Mon Sep 17 00:00:00 2001 From: Jasneet Singh Date: Tue, 4 Mar 2025 08:36:50 -0500 Subject: [PATCH 06/61] Refactor wallet component styles for improved responsiveness and alignment --- src/Components/WalletProvider/index.css | 34 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Components/WalletProvider/index.css b/src/Components/WalletProvider/index.css index 2ba40c8b3..784c75ace 100644 --- a/src/Components/WalletProvider/index.css +++ b/src/Components/WalletProvider/index.css @@ -1,15 +1,23 @@ .wallet-adapter-dropdown { - width: 100%; + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: var(--env-var-spacing-1); } .wallet-adapter-button { - width: 100%; - justify-content: center; - height: var(--button-height) !important; - font-size: var(--font-size-body) !important; - font-weight: var(--font-weight-medium) !important; - margin: var(--spacing-xs) 0; - white-space: nowrap; + display: flex; + align-items: center; + justify-content: center; + width: auto; + height: var(--env-var-height-2) !important; + font-size: var(--env-var-font-size-medium-plus) !important; + font-weight: 500 !important; + margin: 0; + padding: calc((var(--env-var-height-2) - var(--env-var-font-size-medium-plus) * 1.2) / 2) var(--env-var-spacing-1); + white-space: nowrap; } .wallet-adapter-modal-title { @@ -24,10 +32,12 @@ /* Responsive fixes */ @media (max-width: 1093px) { - .wallet-adapter-button { - padding: var(--spacing-xs) var(--spacing-sm) !important; - font-size: calc(var(--font-size-body) * 0.9) !important; - } + .wallet-adapter-button { + font-size: var(--env-var-font-size-medium) !important; + padding: calc((var(--env-var-height-2) - var(--env-var-font-size-medium) * 1.2) / 2) + var(--env-var-spacing-1-minus) !important; + + } } @media (max-width: 910px) { From a0401ffd2fe76e78df0d69772b61b9ab567b6756 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Wed, 5 Mar 2025 00:32:04 +0530 Subject: [PATCH 07/61] Maitenance start time style fixes. --- src/Utils/Theme/globalTheme.js | 84 ++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 66631edec..f2136b125 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -382,6 +382,90 @@ const baseTheme = (palette) => ({ }), }, }, + + // This code is added for clock in maintenance page + // code starts from here. + MuiClockPicker: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.primary.main, + "& .MuiTypography-root": { + color: theme.palette.primary.lowContrast, + }, + "& .MuiClock-clock": { + backgroundColor: theme.palette.primary.dark, + borderColor: theme.palette.primary.lowContrast, + }, + }), + }, + }, + // The clock pointer ( pointer to number like hour/minute hand) + MuiClockPointer: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.accent.main, + "& .MuiClock-pointer": { + backgroundColor: theme.palette.accent.main, + }, + }), + }, + }, + // This is for numbers in the clock (circular one's) + MuiClockNumber: { + styleOverrides: { + root: ({ theme }) => ({ + color: theme.palette.primary.contrastText, + "&.Mui-selected": { + color: theme.palette.accent.contrastText, + backgroundColor: theme.palette.accent.main, + }, + }), + }, + }, + // This is for 00:00 am and pm (top bar) + MuiTimePickerToolbar: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.secondary.main, + "& .MuiTypography-root": { + color: theme.palette.secondary.contrastText, + }, + }), + }, + }, + // left and right direction style + MuiPickersArrowSwitcher: { + styleOverrides: { + root: ({ theme }) => ({ + "& .MuiIconButton-root": { + color: theme.palette.primary.contrastText, + }, + }), + }, + }, + // cancel and okay actions style + MuiDialogActions: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.primary.main, + "& .MuiButton-root": { + color: theme.palette.primary.contrastText, + }, + }), + }, + }, + // code ends here. + + // For labels of input fields + MuiInputLabel: { + styleOverrides: { + root: ({ theme }) => ({ + "&.Mui-focused": { + color: theme.palette.accent.main, + }, + }), + }, + }, }, shape: { borderRadius: 2, From 1105a3808036461d2138108f7885bbb1321f5c3c Mon Sep 17 00:00:00 2001 From: Skorpios Date: Tue, 4 Mar 2025 15:56:09 -0800 Subject: [PATCH 08/61] Moved component to the regular components dir. --- .../NotificationIntegrationModal.jsx | 28 ++++++++++++------- src/Pages/Uptime/Create/index.jsx | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) rename src/{Pages/Uptime/Details => }/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx (95%) diff --git a/src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx similarity index 95% rename from src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx rename to src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index eca6a78d0..ae6cdc28b 100644 --- a/src/Pages/Uptime/Details/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -13,8 +13,8 @@ import { Divider } from "@mui/material"; import { useTheme } from "@emotion/react"; -import TextInput from "../../../../../../src/Components/Inputs/TextInput"; -import Checkbox from "../../../../../../src/Components/Inputs/Checkbox"; +import TextInput from "../Inputs/TextInput"; +import Checkbox from "../Inputs/Checkbox"; // Tab Panel component function TabPanel({ children, value, index, ...other }) { @@ -96,20 +96,18 @@ const NotificationIntegrationModal = ({ const handleTestNotification = (type) => { console.log(`Testing ${type} notification`); - // Here you would implement the actual test notification functionality + //implement the test notification functionality }; const handleSave = () => { - // Create notifications array based on selected integrations + //notifications array for selected integrations const notifications = [...(monitor?.notifications || [])]; - // Filter out existing integrations that will be updated const existingTypes = ["slack", "discord", "telegram", "webhook"]; const filteredNotifications = notifications.filter( notification => !existingTypes.includes(notification.type) ); - // Add selected integrations if (integrations.slack) { filteredNotifications.push({ type: "slack", @@ -157,13 +155,14 @@ const NotificationIntegrationModal = ({ sx={{ '& .MuiDialog-paper': { backgroundColor: theme.palette.primary.main, - color: '#344054' + color: '#344054', + maxWidth: '775px' } }} > - + {/* Left sidebar with tabs */} - + diff --git a/src/Pages/Uptime/Create/index.jsx b/src/Pages/Uptime/Create/index.jsx index b9bb7eb8f..ebafa3a1f 100644 --- a/src/Pages/Uptime/Create/index.jsx +++ b/src/Pages/Uptime/Create/index.jsx @@ -23,7 +23,7 @@ import Radio from "../../../Components/Inputs/Radio"; import Checkbox from "../../../Components/Inputs/Checkbox"; import Select from "../../../Components/Inputs/Select"; import ConfigBox from "../../../Components/ConfigBox"; -import NotificationIntegrationModal from "../Details/Components/NotificationIntegrationModal/NotificationIntegrationModal"; +import NotificationIntegrationModal from "../../../Components/NotificationIntegrationModal/NotificationIntegrationModal"; const CreateMonitor = () => { const MS_PER_MINUTE = 60000; const SELECT_VALUES = [ From 055799a1356aeadd0426fe25cab249738bbe60c1 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Tue, 4 Mar 2025 15:57:30 -0800 Subject: [PATCH 09/61] Used theme values for consistency instead of hardcoded values for padding. --- .../NotificationIntegrationModal.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index ae6cdc28b..cc326e0dc 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -18,6 +18,8 @@ import Checkbox from "../Inputs/Checkbox"; // Tab Panel component function TabPanel({ children, value, index, ...other }) { + const theme = useTheme(); + return (
{value === index && ( - + {children} )} From 6983b3a5f556667f3314f7a5daf85d480959d31a Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Fri, 7 Mar 2025 01:10:06 +0530 Subject: [PATCH 10/61] have added the accent in order to make sure that the number choosen is identified. --- src/Utils/Theme/globalTheme.js | 38 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index fa0dad9ef..4ffe8e377 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -397,16 +397,28 @@ const baseTheme = (palette) => ({ // This code is added for clock in maintenance page // code starts from here. + MuiClock: { + // Directly target the clock component + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: theme.palette.primary.main, // Alternative target + "& .MuiClock-clock": { + // Inner clock face + backgroundColor: theme.palette.secondary.main, + }, + }), + }, + }, MuiClockPicker: { styleOverrides: { root: ({ theme }) => ({ - backgroundColor: theme.palette.primary.main, - "& .MuiTypography-root": { + backgroundColor: theme.palette.secondary.main, // Outer container background + "& .MuiClock-root": { color: theme.palette.primary.lowContrast, }, "& .MuiClock-clock": { - backgroundColor: theme.palette.primary.dark, - borderColor: theme.palette.primary.lowContrast, + backgroundColor: theme.palette.background.default, // Clock face background + borderColor: theme.palette.secondary.lowContrast, }, }), }, @@ -415,9 +427,10 @@ const baseTheme = (palette) => ({ MuiClockPointer: { styleOverrides: { root: ({ theme }) => ({ + // Main pointer line color backgroundColor: theme.palette.accent.main, - "& .MuiClock-pointer": { - backgroundColor: theme.palette.accent.main, + "& .MuiClockPointer-thumb": { + backgroundColor: theme.palette.grey[500], // Use your desired grey }, }), }, @@ -439,8 +452,19 @@ const baseTheme = (palette) => ({ styleOverrides: { root: ({ theme }) => ({ backgroundColor: theme.palette.secondary.main, + // General text color "& .MuiTypography-root": { - color: theme.palette.secondary.contrastText, + color: theme.palette.secondary.darker, + }, + // Selected time (hour/minute) color + "& .Mui-selected": { + color: `${theme.palette.accent.main} !important`, // Use your accent color + }, + // AM/PM buttons color + "& .MuiButtonBase-root": { + "&.Mui-selected": { + backgroundColor: theme.palette.accent.main, + }, }, }), }, From 5e730acd478b15f059020ebc75708bd34edd05dd Mon Sep 17 00:00:00 2001 From: Skorpios Date: Thu, 6 Mar 2025 17:16:45 -0800 Subject: [PATCH 11/61] Declared variants for the vertical version of tabs in the theme. --- .../NotificationIntegrationModal.jsx | 36 +----- src/Utils/Theme/globalTheme.js | 104 ++++++++++++------ 2 files changed, 74 insertions(+), 66 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index cc326e0dc..1392d6edf 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -182,39 +182,11 @@ const NotificationIntegrationModal = ({ value={tabValue} onChange={handleChangeTab} aria-label="Notification tabs" - sx={{ - backgroundColor: theme.palette.primary.main, - '& .MuiTab-root': { - alignItems: 'flex-start', - px: 2, - fontSize: '0.9rem', - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.primary.main, - border: 'none', - borderBottom: 'none', - borderRight: 'none', - '&.Mui-selected': { - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.tertiary.main, // Match the hover background color - opacity: 1, - border: 'none', - borderBottom: 'none', - borderRight: 'none' - }, - '&:hover': { - backgroundColor: theme.palette.tertiary.main, - border: 'none' - } - }, - '& .MuiTabs-indicator': { - backgroundColor: 'transparent' - } - }} > - - - - + + + + diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 3598af675..7f347d29f 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -328,35 +328,61 @@ const baseTheme = (palette) => ({ }, MuiTab: { styleOverrides: { - root: ({ theme }) => ({ - fontSize: 13, - color: theme.palette.tertiary.contrastText, - backgroundColor: theme.palette.tertiary.main, - textTransform: "none", - minWidth: "fit-content", - paddingY: theme.spacing(6), - fontWeight: 400, - borderBottom: "2px solid transparent", - borderRight: `1px solid ${theme.palette.primary.lowContrast}`, - "&:first-of-type": { borderTopLeftRadius: "8px" }, - "&:last-child": { borderTopRightRadius: "8px", borderRight: 0 }, - "&:focus-visible": { - color: theme.palette.primary.contrastText, - borderColor: theme.palette.tertiary.contrastText, - borderRightColor: theme.palette.primary.lowContrast, - }, - "&.Mui-selected": { - backgroundColor: theme.palette.secondary.main, - color: theme.palette.secondary.contrastText, - borderColor: theme.palette.secondary.contrastText, - borderRightColor: theme.palette.primary.lowContrast, - }, - "&:hover": { - borderColor: theme.palette.primary.lowContrast, - }, - }), + root: ({ theme }) => ({ + fontSize: 13, + color: theme.palette.tertiary.contrastText, + backgroundColor: theme.palette.tertiary.main, + textTransform: "none", + minWidth: "fit-content", + paddingY: theme.spacing(6), + fontWeight: 400, + borderBottom: "2px solid transparent", + borderRight: `1px solid ${theme.palette.primary.lowContrast}`, + "&:first-of-type": { borderTopLeftRadius: "8px" }, + "&:last-child": { borderTopRightRadius: "8px", borderRight: 0 }, + "&:focus-visible": { + color: theme.palette.primary.contrastText, + borderColor: theme.palette.tertiary.contrastText, + borderRightColor: theme.palette.primary.lowContrast, + }, + "&.Mui-selected": { + backgroundColor: theme.palette.secondary.main, + color: theme.palette.secondary.contrastText, + borderColor: theme.palette.secondary.contrastText, + borderRightColor: theme.palette.primary.lowContrast, + }, + "&:hover": { + borderColor: theme.palette.primary.lowContrast, + }, + }), }, - }, + variants: [ + { + props: { orientation: 'vertical' }, + style: ({ theme }) => ({ + alignItems: 'flex-start', + padding: theme.spacing(2), + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.primary.main, + border: 'none', + borderBottom: 'none', + borderRight: 'none', + '&.Mui-selected': { + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.tertiary.main, + opacity: 1, + border: 'none', + borderBottom: 'none', + borderRight: 'none' + }, + '&:hover': { + backgroundColor: theme.palette.tertiary.main, + border: 'none' + } + }), + }, + ], + }, MuiSvgIcon: { styleOverrides: { root: ({ theme }) => ({ @@ -366,13 +392,23 @@ const baseTheme = (palette) => ({ }, MuiTabs: { styleOverrides: { - root: ({ theme }) => ({ - "& .MuiTabs-indicator": { - backgroundColor: theme.palette.tertiary.contrastText, - }, - }), + root: ({ theme }) => ({ + "& .MuiTabs-indicator": { + backgroundColor: theme.palette.tertiary.contrastText, + }, + }), }, - }, + variants: [ + { + props: { orientation: 'vertical' }, + style: { + "& .MuiTabs-indicator": { + display: 'none', + } + }, + }, + ], + }, MuiSwitch: { styleOverrides: { root: ({ theme }) => ({ From 4736f4f301b56a11afd4e7daf4558a74533a22b7 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Thu, 6 Mar 2025 17:46:43 -0800 Subject: [PATCH 12/61] Got rid of button overrides and made a variant for text button. --- .../NotificationIntegrationModal.jsx | 25 ----------------- src/Utils/Theme/globalTheme.js | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 1392d6edf..8716550f5 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -56,27 +56,6 @@ const NotificationIntegrationModal = ({ webhook: monitor?.notifications?.some(n => n.type === "webhook") || false, webhookUrl: monitor?.notifications?.find(n => n.type === "webhook")?.url || "", }); - - const testNotificationButtonStyle = { - textDecoration: 'underline', - color: '#344054', - textTransform: 'none', - padding: '0 !important', - margin: 0, - fontSize: '0.9rem', - fontWeight: 'normal', - backgroundColor: 'transparent !important', - '&:hover': { - backgroundColor: 'transparent !important', - textDecoration: 'underline' - }, - '&.Mui-disabled': { - backgroundColor: 'transparent !important' - }, - minWidth: '0 !important', - boxShadow: 'none !important', - border: 'none !important' - }; const handleChangeTab = (event, newValue) => { setTabValue(newValue); @@ -226,7 +205,6 @@ const NotificationIntegrationModal = ({ color="info" onClick={() => handleTestNotification('slack')} disabled={!integrations.slack || !integrations.slackWebhook} - sx={testNotificationButtonStyle} > Test notification @@ -267,7 +245,6 @@ const NotificationIntegrationModal = ({ color="info" onClick={() => handleTestNotification('discord')} disabled={!integrations.discord || !integrations.discordWebhook} - sx={testNotificationButtonStyle} > Test notification @@ -320,7 +297,6 @@ const NotificationIntegrationModal = ({ color="info" onClick={() => handleTestNotification('telegram')} disabled={!integrations.telegram || !integrations.telegramToken || !integrations.telegramChatId} - sx={testNotificationButtonStyle} > Test notification @@ -361,7 +337,6 @@ const NotificationIntegrationModal = ({ color="info" onClick={() => handleTestNotification('webhook')} disabled={!integrations.webhook || !integrations.webhookUrl} - sx={testNotificationButtonStyle} > Test notification diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 7f347d29f..89ad85c2b 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -117,6 +117,33 @@ const baseTheme = (palette) => ({ color: `${theme.palette.secondary.contrastText} !important`, }, }, + + { + props: { variant: 'text', color: 'info' }, + style: { + textDecoration: 'underline', + color: '#344054', + padding: 0, + margin: 0, + fontSize: '0.9rem', + fontWeight: 'normal', + backgroundColor: 'transparent', + '&:hover': { + backgroundColor: 'transparent', + textDecoration: 'underline' + }, + "&.Mui-disabled": { + backgroundColor: theme.palette.secondary.main, + color: theme.palette.primary.contrastText, + "&.MuiButton-text": { + backgroundColor: 'transparent' + } + }, + minWidth: 0, + boxShadow: 'none', + border: 'none' + }, + }, ], height: 34, fontWeight: 400, From a296a70bcd9cafa403cec6a9ac144dbcecfd5cab Mon Sep 17 00:00:00 2001 From: Skorpios Date: Thu, 6 Mar 2025 17:48:46 -0800 Subject: [PATCH 13/61] adjust padding with theme spacing for consistency. --- .../NotificationIntegrationModal.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 8716550f5..0a70b6448 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -170,7 +170,7 @@ const NotificationIntegrationModal = ({ {/* Right side content */} - + {/* Slack Tab */} Slack From 5fff398a2590ddb0f39333161a101953c1033c36 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Thu, 6 Mar 2025 17:56:30 -0800 Subject: [PATCH 14/61] Got rid of all overridden styles. --- .../NotificationIntegrationModal.jsx | 136 ++++++++++++------ 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 0a70b6448..1015667f9 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -135,13 +135,10 @@ const NotificationIntegrationModal = ({ maxWidth="md" sx={{ '& .MuiDialog-paper': { - backgroundColor: theme.palette.primary.main, - color: '#344054', maxWidth: '775px' } }} > - {/* Left sidebar with tabs */} @@ -149,10 +146,15 @@ const NotificationIntegrationModal = ({ borderRight: 1, borderColor: 'divider', minWidth: '200px', - pr: 20 + pr: theme.spacing(10) }}> - - Add or edit notifications + + Add or edit notifications {/* Right side content */} - + {/* Slack Tab */} - Slack - + Slack + To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here. - - handleIntegrationChange('slack', e.target.checked)} - /> - + + handleIntegrationChange('slack', e.target.checked)} + /> + - - Webhook URL + + Webhook URL - + - Didn't receive the email?{" "} + {t("authCheckEmailDidntReceiveEmail")}{" "} - Click to resend + {t("authCheckEmailClickToResend")} @@ -205,15 +207,15 @@ const CheckEmail = () => { textAlign="center" p={theme.spacing(12)} > - Go back to — + {t("goBackTo")} - Log In + {t("authLoginTitle")} diff --git a/src/Pages/Auth/ForgotPassword.jsx b/src/Pages/Auth/ForgotPassword.jsx index 61234db73..a67f67c14 100644 --- a/src/Pages/Auth/ForgotPassword.jsx +++ b/src/Pages/Auth/ForgotPassword.jsx @@ -11,6 +11,7 @@ import Logo from "../../assets/icons/checkmate-icon.svg?react"; import Key from "../../assets/icons/key.svg?react"; import Background from "../../assets/Images/background-grid.svg?react"; import IconBox from "../../Components/IconBox"; +import { useTranslation } from "react-i18next"; import "./index.css"; const ForgotPassword = () => { @@ -29,6 +30,8 @@ const ForgotPassword = () => { email && setForm({ email: sessionStorage.getItem("email") }); }, []); + const { t } = useTranslation(); + const handleSubmit = async (event) => { event.preventDefault(); @@ -162,7 +165,7 @@ const ForgotPassword = () => { - Forgot password? + {t("authForgotPasswordTitle")} No worries, we'll send you reset instructions. { mt: theme.spacing(15), }} > - Send instructions + {t("continue")} @@ -204,15 +207,15 @@ const ForgotPassword = () => { textAlign="center" p={theme.spacing(12)} > - Go back to — + {t("goBackTo")} - Log In + {t("authLoginTitle")} diff --git a/src/Pages/Auth/NewPasswordConfirmed.jsx b/src/Pages/Auth/NewPasswordConfirmed.jsx index 6258e0fa5..6667b1ace 100644 --- a/src/Pages/Auth/NewPasswordConfirmed.jsx +++ b/src/Pages/Auth/NewPasswordConfirmed.jsx @@ -8,12 +8,14 @@ import Background from "../../assets/Images/background-grid.svg?react"; import ConfirmIcon from "../../assets/icons/check-outlined.svg?react"; import Logo from "../../assets/icons/checkmate-icon.svg?react"; import IconBox from "../../Components/IconBox"; +import { useTranslation } from "react-i18next"; import "./index.css"; const NewPasswordConfirmed = () => { const theme = useTheme(); const navigate = useNavigate(); const dispatch = useDispatch(); + const { t } = useTranslation(); const handleNavigate = () => { dispatch(clearAuthState()); @@ -97,9 +99,9 @@ const NewPasswordConfirmed = () => { - Password reset + {t("passwordreset")} - Your password has been successfully reset. Click below to log in magically. + {t("authNewPasswordConfirmed")} @@ -118,7 +120,7 @@ const NewPasswordConfirmed = () => { textAlign="center" p={theme.spacing(12)} > - Go back to — + {t("goBack-")} { onClick={handleNavigate} sx={{ userSelect: "none" }} > - Log In + {t("authLoginTitle")} diff --git a/src/locales/gb.json b/src/locales/gb.json index cf7711fa8..c3d36d352 100644 --- a/src/locales/gb.json +++ b/src/locales/gb.json @@ -1,5 +1,6 @@ { "dontHaveAccount": "Don't have account", + "aboutus": "About Us", "email": "E-mail", "forgotPassword": "Forgot Password", "password": "password", @@ -16,6 +17,7 @@ "commonBack": "Back", "authForgotPasswordTitle": "Forgot password?", "authForgotPasswordResetPassword": "Reset password", + "passwordreset": "Password Reset", "authRegisterAlreadyHaveAccount": "Already have an account?", "commonAppName": "Checkmate", "authLoginEnterEmail": "Enter your email", @@ -30,9 +32,10 @@ "authForgotPasswordSendInstructions": "Send instructions", "authForgotPasswordBackTo": "Back to", "authCheckEmailTitle": "Check your email", - "authCheckEmailDescription": "We sent a password reset link to {{email}}", + "authCheckEmailDescription": "We sent a password reset link to", "authCheckEmailResendEmail": "Resend email", "authCheckEmailBackTo": "Back to", + "authCheckEmailOpenEmailButton": "Open email app", "goBackTo": "Go back to", "authCheckEmailDidntReceiveEmail": "Didn't receive the email?", "authCheckEmailClickToResend": "Click to resend", @@ -42,6 +45,7 @@ "authSetNewPasswordConfirmPassword": "Confirm password", "confirmPassword": "Confirm your password", "authSetNewPasswordResetPassword": "Reset password", + "authNewPasswordConfirmed": "Your password has been successfully reset. Click below to log in magically.", "authSetNewPasswordBackTo": "Back to", "authPasswordMustBeAtLeast": "Must be at least", "authPasswordCharactersLong": "8 characters long", From 94f4d63e96c407dabaa9e149b5c3cfb833f83f46 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 7 Mar 2025 11:14:40 -0800 Subject: [PATCH 17/61] fix timeSinceLastCheck --- .../Details/Components/StatBoxes/index.jsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Pages/DistributedUptime/Details/Components/StatBoxes/index.jsx b/src/Pages/DistributedUptime/Details/Components/StatBoxes/index.jsx index 0cdd3f01d..97513bb4f 100644 --- a/src/Pages/DistributedUptime/Details/Components/StatBoxes/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/StatBoxes/index.jsx @@ -9,11 +9,6 @@ import PropTypes from "prop-types"; const StatBoxes = ({ monitor, lastUpdateTrigger }) => { const theme = useTheme(); - let timeSinceLastCheck = 0; - - if (monitor?.lastCheckTimestamp) { - timeSinceLastCheck = Date.now() - monitor?.lastCheckTimestamp; - } return ( { heading={"Last check"} subHeading={ } From 57469a2510431e29217ef038875ae7a4bd136b3f Mon Sep 17 00:00:00 2001 From: Aryaman Kumar Sharma Date: Sat, 8 Mar 2025 00:45:08 +0530 Subject: [PATCH 18/61] Feat: Migrate Hardcoded Strings in Auth and About --- src/Pages/Auth/NewPasswordConfirmed.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pages/Auth/NewPasswordConfirmed.jsx b/src/Pages/Auth/NewPasswordConfirmed.jsx index 6667b1ace..9c7734083 100644 --- a/src/Pages/Auth/NewPasswordConfirmed.jsx +++ b/src/Pages/Auth/NewPasswordConfirmed.jsx @@ -120,10 +120,10 @@ const NewPasswordConfirmed = () => { textAlign="center" p={theme.spacing(12)} > - {t("goBack-")} + {t("goBackTo")} Date: Fri, 7 Mar 2025 11:15:19 -0800 Subject: [PATCH 19/61] correct timeSinceLastCheck and uptimePercentage --- .../Details/Components/StatusHeader/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx index dd3263372..316427cec 100644 --- a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx @@ -59,7 +59,7 @@ const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => { backgroundColor={theme.palette.successSecondary.lowContrast} color={theme.palette.success.lowContrast} > - Uptime: {(monitor.totalUptime * 100).toFixed(2)}% + Uptime: {(monitor.uptimePercentage * 100).toFixed(2)}% { Last updated{" "} From f6c1d5bbee475b6c1cf2a17556346e4cca7bd915 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Fri, 7 Mar 2025 16:43:29 -0800 Subject: [PATCH 20/61] Removed DialogTitle, Stack, and Divider as they are not used in the file. --- .../NotificationIntegrationModal.jsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 1015667f9..bb7478b34 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -1,16 +1,13 @@ import { useState } from "react"; import { Dialog, - DialogTitle, DialogContent, DialogActions, Button, - Stack, Typography, Box, Tabs, - Tab, - Divider + Tab } from "@mui/material"; import { useTheme } from "@emotion/react"; import TextInput from "../Inputs/TextInput"; From e6e20d507ed033f092000af36bac3db1c3a6d10f Mon Sep 17 00:00:00 2001 From: Skorpios Date: Fri, 7 Mar 2025 16:56:00 -0800 Subject: [PATCH 21/61] Extracted tab panel component into its own separate file. --- .../NotificationIntegrationModal.jsx | 22 +--------------- .../NotificationIntegrationModal/TabPanel.jsx | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 src/Components/NotificationIntegrationModal/TabPanel.jsx diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index bb7478b34..b34cd5e55 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -12,27 +12,7 @@ import { import { useTheme } from "@emotion/react"; import TextInput from "../Inputs/TextInput"; import Checkbox from "../Inputs/Checkbox"; - -// Tab Panel component -function TabPanel({ children, value, index, ...other }) { - const theme = useTheme(); - - return ( - - ); -} +import TabPanel from "./TabPanel"; const NotificationIntegrationModal = ({ open, diff --git a/src/Components/NotificationIntegrationModal/TabPanel.jsx b/src/Components/NotificationIntegrationModal/TabPanel.jsx new file mode 100644 index 000000000..6299b56e9 --- /dev/null +++ b/src/Components/NotificationIntegrationModal/TabPanel.jsx @@ -0,0 +1,25 @@ +import React from "react"; +import { Box } from "@mui/material"; +import { useTheme } from "@emotion/react"; + +function TabPanel({ children, value, index, ...other }) { + const theme = useTheme(); + + return ( + + ); +} + +export default TabPanel; \ No newline at end of file From 92df32cd82250e4aa19e4c32ecd1591ed82de300 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Fri, 7 Mar 2025 17:25:28 -0800 Subject: [PATCH 22/61] Made tabs configure ready. --- .../NotificationIntegrationModal.jsx | 426 +++++++----------- 1 file changed, 165 insertions(+), 261 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index b34cd5e55..a2c00c882 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -14,25 +14,98 @@ import TextInput from "../Inputs/TextInput"; import Checkbox from "../Inputs/Checkbox"; import TabPanel from "./TabPanel"; +// Configuration for notification tabs +const NOTIFICATION_TYPES = [ + { + id: 'slack', + label: 'Slack', + description: 'To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.', + fields: [ + { + id: 'webhook', + label: 'Webhook URL', + placeholder: 'https://hooks.slack.com/services/...', + type: 'text' + } + ] + }, + { + id: 'discord', + label: 'Discord', + description: 'To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord\'s incoming Webhooks feature.', + fields: [ + { + id: 'webhook', + label: 'Discord Webhook URL', + placeholder: 'https://discord.com/api/webhooks/...', + type: 'text' + } + ] + }, + { + id: 'telegram', + label: 'Telegram', + description: 'To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.', + fields: [ + { + id: 'token', + label: 'Your bot token', + placeholder: '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11', + type: 'text' + }, + { + id: 'chatId', + label: 'Your Chat ID', + placeholder: '-1001234567890', + type: 'text' + } + ] + }, + { + id: 'webhook', + label: 'Webhooks', + description: 'You can set up a custom webhook to receive notifications when incidents occur.', + fields: [ + { + id: 'url', + label: 'Webhook URL', + placeholder: 'https://your-server.com/webhook', + type: 'text' + } + ] + } +]; + const NotificationIntegrationModal = ({ open, onClose, monitor, - setMonitor + setMonitor, + // Optional prop to configure available notification types + notificationTypes = NOTIFICATION_TYPES }) => { const theme = useTheme(); const [tabValue, setTabValue] = useState(0); - const [integrations, setIntegrations] = useState({ - slack: monitor?.notifications?.some(n => n.type === "slack") || false, - slackWebhook: monitor?.notifications?.find(n => n.type === "slack")?.webhook || "", - discord: monitor?.notifications?.some(n => n.type === "discord") || false, - discordWebhook: monitor?.notifications?.find(n => n.type === "discord")?.webhook || "", - telegram: monitor?.notifications?.some(n => n.type === "telegram") || false, - telegramToken: monitor?.notifications?.find(n => n.type === "telegram")?.token || "", - telegramChatId: monitor?.notifications?.find(n => n.type === "telegram")?.chatId || "", - webhook: monitor?.notifications?.some(n => n.type === "webhook") || false, - webhookUrl: monitor?.notifications?.find(n => n.type === "webhook")?.url || "", - }); + + // Initialize integrations state based on available notification types + const initializeIntegrationsState = () => { + const state = {}; + + notificationTypes.forEach(type => { + // Add enabled flag for each notification type + state[type.id] = monitor?.notifications?.some(n => n.type === type.id) || false; + + // Add state for each field in the notification type + type.fields.forEach(field => { + const fieldKey = `${type.id}${field.id.charAt(0).toUpperCase() + field.id.slice(1)}`; + state[fieldKey] = monitor?.notifications?.find(n => n.type === type.id)?.[field.id] || ""; + }); + }); + + return state; + }; + + const [integrations, setIntegrations] = useState(initializeIntegrationsState()); const handleChangeTab = (event, newValue) => { setTabValue(newValue); @@ -61,39 +134,30 @@ const NotificationIntegrationModal = ({ //notifications array for selected integrations const notifications = [...(monitor?.notifications || [])]; - const existingTypes = ["slack", "discord", "telegram", "webhook"]; + // Get all notification types IDs + const existingTypes = notificationTypes.map(type => type.id); + + // Filter out notifications that are configurable in this modal const filteredNotifications = notifications.filter( notification => !existingTypes.includes(notification.type) ); - if (integrations.slack) { - filteredNotifications.push({ - type: "slack", - webhook: integrations.slackWebhook - }); - } - - if (integrations.discord) { - filteredNotifications.push({ - type: "discord", - webhook: integrations.discordWebhook - }); - } - - if (integrations.telegram) { - filteredNotifications.push({ - type: "telegram", - token: integrations.telegramToken, - chatId: integrations.telegramChatId - }); - } - - if (integrations.webhook) { - filteredNotifications.push({ - type: "webhook", - url: integrations.webhookUrl - }); - } + // Add each enabled notification with its configured fields + notificationTypes.forEach(type => { + if (integrations[type.id]) { + const notificationObject = { + type: type.id + }; + + // Add each field value to the notification object + type.fields.forEach(field => { + const fieldKey = `${type.id}${field.id.charAt(0).toUpperCase() + field.id.slice(1)}`; + notificationObject[field.id] = integrations[fieldKey]; + }); + + filteredNotifications.push(notificationObject); + } + }); // Update monitor with new notifications setMonitor(prev => ({ @@ -141,234 +205,74 @@ const NotificationIntegrationModal = ({ onChange={handleChangeTab} aria-label="Notification tabs" > - - - - + {notificationTypes.map((type, index) => ( + + ))} {/* Right side content */} - {/* Slack Tab */} - - Slack - - To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here. - - - - handleIntegrationChange('slack', e.target.checked)} - /> - - - - ( + + Webhook URL - handleInputChange('slackWebhook', e.target.value)} - disabled={!integrations.slack} - /> - - - - - - - - {/* Discord Tab */} - - Discord - - To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature. - - - - handleIntegrationChange('discord', e.target.checked)} - /> - - - + }}>{type.label} Discord Webhook URL - handleInputChange('discordWebhook', e.target.value)} - disabled={!integrations.discord} - /> - - - - - - - - {/* Telegram Tab */} - - Telegram - - To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here. - - - - handleIntegrationChange('telegram', e.target.checked)} - /> - - - - Your bot token - handleInputChange('telegramToken', e.target.value)} - disabled={!integrations.telegram} - /> - - - - Your Chat ID - handleInputChange('telegramChatId', e.target.value)} - disabled={!integrations.telegram} - /> - - - - - - - - {/* Webhooks Tab */} - - Webhooks - - You can set up a custom webhook to receive notifications when incidents occur. - - - - handleIntegrationChange('webhook', e.target.checked)} - /> - - - - Webhook URL - handleInputChange('webhookUrl', e.target.value)} - disabled={!integrations.webhook} - /> - - - - - - + mt: theme.spacing(0.5), + mb: theme.spacing(1.5), + color: theme.palette.primary.contrastTextTertiary + }}> + {type.description} + + + + handleIntegrationChange(type.id, e.target.checked)} + /> + + + {type.fields.map(field => { + const fieldKey = `${type.id}${field.id.charAt(0).toUpperCase() + field.id.slice(1)}`; + + return ( + + {field.label} + handleInputChange(fieldKey, e.target.value)} + disabled={!integrations[type.id]} + /> + + ); + })} + + + + + + ))} From 056e0191b89bc9f8894fa1e45d5f15fa2310882e Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 8 Mar 2025 01:54:38 +0000 Subject: [PATCH 23/61] Update dependency @reduxjs/toolkit to v2.6.1 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89b17b968..5120f576b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@mui/x-charts": "^7.5.1", "@mui/x-data-grid": "7.27.3", "@mui/x-date-pickers": "7.27.3", - "@reduxjs/toolkit": "2.6.0", + "@reduxjs/toolkit": "2.6.1", "@solana/wallet-adapter-base": "0.9.23", "@solana/wallet-adapter-material-ui": "0.16.34", "@solana/wallet-adapter-react": "0.15.35", @@ -4692,9 +4692,9 @@ } }, "node_modules/@reduxjs/toolkit": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.0.tgz", - "integrity": "sha512-mWJCYpewLRyTuuzRSEC/IwIBBkYg2dKtQas8mty5MaV2iXzcmicS3gW554FDeOvLnY3x13NIk8MB1e8wHO7rqQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz", + "integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==", "license": "MIT", "dependencies": { "immer": "^10.0.3", diff --git a/package.json b/package.json index a8fa1128e..5100a0529 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@mui/icons-material": "6.4.7", "@mui/lab": "6.0.0-beta.30", "@mui/material": "6.4.7", - "@reduxjs/toolkit": "2.6.0", + "@reduxjs/toolkit": "2.6.1", "@solana/wallet-adapter-base": "0.9.23", "@solana/wallet-adapter-material-ui": "0.16.34", "@solana/wallet-adapter-react": "0.15.35", From d05821e95e1059f4640a21dc22952478fb818b3f Mon Sep 17 00:00:00 2001 From: Renato Date: Sat, 8 Mar 2025 20:43:29 +0100 Subject: [PATCH 24/61] fix: add on "status pages" table --- .../StatusPages/Components/StatusPagesTable/index.jsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx b/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx index 7c951d420..fd9b27cb1 100644 --- a/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx +++ b/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx @@ -1,7 +1,7 @@ import DataTable from "../../../../../Components/Table"; import { useTheme } from "@emotion/react"; import { useNavigate } from "react-router-dom"; -import { ColoredLabel } from "../../../../../Components/Label"; +import { StatusLabel } from "../../../../../Components/Label"; import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward"; import { Stack, Typography } from "@mui/material"; const StatusPagesTable = ({ data }) => { @@ -66,12 +66,11 @@ const StatusPagesTable = ({ data }) => { id: "status", content: "Status", render: (row) => { + const status = row.isPublished ? "up" : "down"; return ( - ); }, From 3ac56c1ea78e33bb041eee4e1ab61cc87cf9af91 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 13:01:28 -0800 Subject: [PATCH 25/61] Made a separate tab component. --- .../NotificationIntegrationModal.jsx | 68 ++----------- .../TabComponent.jsx | 97 +++++++++++++++++++ 2 files changed, 106 insertions(+), 59 deletions(-) create mode 100644 src/Components/NotificationIntegrationModal/TabComponent.jsx diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index a2c00c882..d8955f18e 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -10,9 +10,8 @@ import { Tab } from "@mui/material"; import { useTheme } from "@emotion/react"; -import TextInput from "../Inputs/TextInput"; -import Checkbox from "../Inputs/Checkbox"; import TabPanel from "./TabPanel"; +import TabComponent from "./TabComponent"; // Configuration for notification tabs const NOTIFICATION_TYPES = [ @@ -205,7 +204,7 @@ const NotificationIntegrationModal = ({ onChange={handleChangeTab} aria-label="Notification tabs" > - {notificationTypes.map((type, index) => ( + {notificationTypes.map((type) => ( ))} @@ -215,62 +214,13 @@ const NotificationIntegrationModal = ({ {notificationTypes.map((type, index) => ( - {type.label} - - {type.description} - - - - handleIntegrationChange(type.id, e.target.checked)} - /> - - - {type.fields.map(field => { - const fieldKey = `${type.id}${field.id.charAt(0).toUpperCase() + field.id.slice(1)}`; - - return ( - - {field.label} - handleInputChange(fieldKey, e.target.value)} - disabled={!integrations[type.id]} - /> - - ); - })} - - - - + ))} diff --git a/src/Components/NotificationIntegrationModal/TabComponent.jsx b/src/Components/NotificationIntegrationModal/TabComponent.jsx new file mode 100644 index 000000000..f9cf6ab53 --- /dev/null +++ b/src/Components/NotificationIntegrationModal/TabComponent.jsx @@ -0,0 +1,97 @@ +import React from "react"; +import { + Typography, + Box, + Button +} from "@mui/material"; +import { useTheme } from "@emotion/react"; +import TextInput from "../../../src/Components/Inputs/TextInput"; +import Checkbox from "../../../src/Components/Inputs/Checkbox"; +const TabComponent = ({ + type, + integrations, + handleIntegrationChange, + handleInputChange, + handleTestNotification +}) => { + const theme = useTheme(); + + // Helper to get the field state key (e.g., slackWebhook, telegramToken) + const getFieldKey = (typeId, fieldId) => { + return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`; + }; + + // Check if all fields have values to enable test button + const areAllFieldsFilled = () => { + return type.fields.every(field => { + const fieldKey = getFieldKey(type.id, field.id); + return integrations[fieldKey]; + }); + }; + + return ( + <> + + {type.label} + + + + {type.description} + + + + handleIntegrationChange(type.id, e.target.checked)} + /> + + + {type.fields.map(field => { + const fieldKey = getFieldKey(type.id, field.id); + + return ( + + + {field.label} + + + handleInputChange(fieldKey, e.target.value)} + disabled={!integrations[type.id]} + /> + + ); + })} + + + + + + ); +}; + +export default TabComponent; \ No newline at end of file From 94045f1164ea3d85d8a41ee34301ac018ff3da93 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 13:56:51 -0800 Subject: [PATCH 26/61] Updated font sizes and colors to match theme values. --- src/Utils/Theme/globalTheme.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 89ad85c2b..dec8c5913 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -122,11 +122,11 @@ const baseTheme = (palette) => ({ props: { variant: 'text', color: 'info' }, style: { textDecoration: 'underline', - color: '#344054', + color: theme.palette.text.primary, padding: 0, margin: 0, - fontSize: '0.9rem', - fontWeight: 'normal', + fontSize: typographyLevels.m, + fontWeight: theme.typography.body2.fontWeight, backgroundColor: 'transparent', '&:hover': { backgroundColor: 'transparent', From 71763f4b6679d0c1c44530a7b2e56af77c26698e Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 14:40:20 -0800 Subject: [PATCH 27/61] Adjusted padding and borders for a more aesthetic look and feel for the vertical tabs. --- src/Utils/Theme/globalTheme.js | 51 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index dec8c5913..1a68cdd70 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -384,31 +384,38 @@ const baseTheme = (palette) => ({ }), }, variants: [ - { - props: { orientation: 'vertical' }, - style: ({ theme }) => ({ - alignItems: 'flex-start', - padding: theme.spacing(2), - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.primary.main, - border: 'none', - borderBottom: 'none', - borderRight: 'none', - '&.Mui-selected': { + { + props: { orientation: 'vertical' }, + style: ({ theme }) => ({ + alignItems: 'flex-start', + padding: `${theme.spacing(1)}px ${theme.spacing(2)}px ${theme.spacing(1)}px ${theme.spacing(6)}px`, + minHeight: theme.spacing(12), color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.tertiary.main, - opacity: 1, + backgroundColor: theme.palette.primary.main, border: 'none', borderBottom: 'none', - borderRight: 'none' - }, - '&:hover': { - backgroundColor: theme.palette.tertiary.main, - border: 'none' - } - }), - }, - ], + borderRight: 'none', + borderRadius: theme.shape.borderRadius * 3, + margin: `${theme.spacing(1)}px ${theme.spacing(2)}px`, + '&.Mui-selected': { + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.tertiary.main, + opacity: 1, + border: 'none', + borderBottom: 'none', + borderRight: 'none', + borderRadius: theme.shape.borderRadius * 3, + minHeight: theme.spacing(14) + }, + '&:hover': { + backgroundColor: theme.palette.tertiary.main, + border: 'none', + borderRadius: theme.shape.borderRadius * 3, + minHeight: theme.spacing(14) + } + }), + }, + ], }, MuiSvgIcon: { styleOverrides: { From 2a54d2ce165cc393a5033b74627e45027651980f Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 14:54:52 -0800 Subject: [PATCH 28/61] Fix spacing, borders, and border radius for style overrides to match theme values. --- src/Utils/Theme/globalTheme.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 1a68cdd70..e3363daab 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -356,17 +356,17 @@ const baseTheme = (palette) => ({ MuiTab: { styleOverrides: { root: ({ theme }) => ({ - fontSize: 13, + fontSize: theme.typography.fontSize - 1, color: theme.palette.tertiary.contrastText, backgroundColor: theme.palette.tertiary.main, textTransform: "none", minWidth: "fit-content", - paddingY: theme.spacing(6), + padding: `${theme.spacing(6)}px ${theme.spacing(4)}px`, fontWeight: 400, - borderBottom: "2px solid transparent", - borderRight: `1px solid ${theme.palette.primary.lowContrast}`, - "&:first-of-type": { borderTopLeftRadius: "8px" }, - "&:last-child": { borderTopRightRadius: "8px", borderRight: 0 }, + borderBottom: `${theme.shape.borderThick}px solid transparent`, + borderRight: `${theme.shape.borderRadius / 2}px solid ${theme.palette.primary.lowContrast}`, + "&:first-of-type": { borderTopLeftRadius: theme.shape.borderRadius * 4 }, + "&:last-child": { borderTopRightRadius: theme.shape.borderRadius * 4, borderRight: 0 }, "&:focus-visible": { color: theme.palette.primary.contrastText, borderColor: theme.palette.tertiary.contrastText, From 25ff7abe7f1ad7542995a0ecefadb29efc518a93 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 16:44:52 -0800 Subject: [PATCH 29/61] refactored all the hardcoded absolute dimension values and made them into relative values that reference the theme. --- .../NotificationIntegrationModal.jsx | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index d8955f18e..2522105a3 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -175,24 +175,30 @@ const NotificationIntegrationModal = ({ maxWidth="md" sx={{ '& .MuiDialog-paper': { - maxWidth: '775px' + width: `calc(90% - ${theme.spacing(40)})`, + maxWidth: theme.breakpoints.values.md } }} > - + {/* Left sidebar with tabs */} Add or edit notifications @@ -205,13 +211,22 @@ const NotificationIntegrationModal = ({ aria-label="Notification tabs" > {notificationTypes.map((type) => ( - + ))} {/* Right side content */} - + {notificationTypes.map((type, index) => ( Save From 99ec5be86545f84a49cb64c7f9360ec0a777a332 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 16:59:53 -0800 Subject: [PATCH 30/61] Added proptypes and jsdocs to the tabpanel. --- .../NotificationIntegrationModal.jsx | 4 ++-- .../NotificationIntegrationModal/TabPanel.jsx | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 2522105a3..16efe77d8 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -175,8 +175,8 @@ const NotificationIntegrationModal = ({ maxWidth="md" sx={{ '& .MuiDialog-paper': { - width: `calc(90% - ${theme.spacing(40)})`, - maxWidth: theme.breakpoints.values.md + width: `calc(80% - ${theme.spacing(40)})`, + maxWidth: `${theme.breakpoints.values.md - 70}px` } }} > diff --git a/src/Components/NotificationIntegrationModal/TabPanel.jsx b/src/Components/NotificationIntegrationModal/TabPanel.jsx index 6299b56e9..a9252e710 100644 --- a/src/Components/NotificationIntegrationModal/TabPanel.jsx +++ b/src/Components/NotificationIntegrationModal/TabPanel.jsx @@ -1,7 +1,19 @@ import React from "react"; +import PropTypes from "prop-types"; import { Box } from "@mui/material"; import { useTheme } from "@emotion/react"; +/** + * TabPanel component that displays content for the selected tab. + * + * @component + * @param {Object} props - The component props. + * @param {React.ReactNode} props.children - The content to be displayed when this tab panel is selected. + * @param {number} props.value - The currently selected tab value. + * @param {number} props.index - The index of this specific tab panel. + * @param {Object} props.other - Any additional props to be spread to the root element. + * @returns {React.ReactElement|null} The rendered tab panel or null if not selected. + */ function TabPanel({ children, value, index, ...other }) { const theme = useTheme(); @@ -22,4 +34,13 @@ function TabPanel({ children, value, index, ...other }) { ); } +TabPanel.propTypes = { + + children: PropTypes.node, + + index: PropTypes.number.isRequired, + + value: PropTypes.number.isRequired +}; + export default TabPanel; \ No newline at end of file From d335cfb4eeabd2478891cbb9fd3f7c7994a216a5 Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 17:13:20 -0800 Subject: [PATCH 31/61] Got rid of unnecessary rerenders by memoizing the integrationstate function. --- .../NotificationIntegrationModal.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 16efe77d8..81f2baec0 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useMemo } from "react"; import { Dialog, DialogContent, @@ -86,8 +86,8 @@ const NotificationIntegrationModal = ({ const theme = useTheme(); const [tabValue, setTabValue] = useState(0); - // Initialize integrations state based on available notification types - const initializeIntegrationsState = () => { + // Memoized function to initialize integrations state + const initialIntegrationsState = useMemo(() => { const state = {}; notificationTypes.forEach(type => { @@ -102,9 +102,9 @@ const NotificationIntegrationModal = ({ }); return state; - }; + }, [monitor, notificationTypes]); // Only recompute when these dependencies change - const [integrations, setIntegrations] = useState(initializeIntegrationsState()); + const [integrations, setIntegrations] = useState(initialIntegrationsState); const handleChangeTab = (event, newValue) => { setTabValue(newValue); From ef954af10655d9138e20984811410e20aa997fc0 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Sun, 9 Mar 2025 07:20:05 +0530 Subject: [PATCH 32/61] Made major ui changes in clock. --- src/Utils/Theme/globalTheme.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 4ffe8e377..98854e160 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -451,14 +451,14 @@ const baseTheme = (palette) => ({ MuiTimePickerToolbar: { styleOverrides: { root: ({ theme }) => ({ - backgroundColor: theme.palette.secondary.main, + backgroundColor: theme.palette.secondary.lowContrast, // General text color "& .MuiTypography-root": { - color: theme.palette.secondary.darker, + color: theme.palette.gradient.color6, }, // Selected time (hour/minute) color "& .Mui-selected": { - color: `${theme.palette.accent.main} !important`, // Use your accent color + color: `${theme.palette.accent.main} !important`, }, // AM/PM buttons color "& .MuiButtonBase-root": { From 5ffc822bd496ff8afa0b07258bc281db28a6bd29 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Sun, 9 Mar 2025 07:21:26 +0530 Subject: [PATCH 33/61] Theme constant changes. --- src/Utils/Theme/constants.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Utils/Theme/constants.js b/src/Utils/Theme/constants.js index 915acedc5..7d20143a5 100644 --- a/src/Utils/Theme/constants.js +++ b/src/Utils/Theme/constants.js @@ -270,6 +270,10 @@ const newSemanticColors = { light: paletteColors.gray50, dark: paletteColors.gray850, }, + color6: { + light: paletteColors.gray300, + dark: paletteColors.gray600, + }, }, map: { From 93462d7ba662c6aea1424decead23f15ded8f45b Mon Sep 17 00:00:00 2001 From: Skorpios Date: Sat, 8 Mar 2025 17:57:27 -0800 Subject: [PATCH 34/61] Changed all user facing strings to use the i18n implementation. --- .../NotificationIntegrationModal.jsx | 37 +++++++++++++++++-- .../TabComponent.jsx | 7 +++- src/locales/gb.json | 35 +++++++++++++++++- 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx index 81f2baec0..cd5a96aa2 100644 --- a/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx +++ b/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx @@ -1,4 +1,5 @@ import { useState, useMemo } from "react"; +import { useTranslation } from "react-i18next"; import { Dialog, DialogContent, @@ -18,12 +19,16 @@ const NOTIFICATION_TYPES = [ { id: 'slack', label: 'Slack', + labelKey: 'notifications.slack.label', description: 'To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.', + descriptionKey: 'notifications.slack.description', fields: [ { id: 'webhook', label: 'Webhook URL', + labelKey: 'notifications.slack.webhookLabel', placeholder: 'https://hooks.slack.com/services/...', + placeholderKey: 'notifications.slack.webhookPlaceholder', type: 'text' } ] @@ -31,12 +36,16 @@ const NOTIFICATION_TYPES = [ { id: 'discord', label: 'Discord', + labelKey: 'notifications.discord.label', description: 'To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord\'s incoming Webhooks feature.', + descriptionKey: 'notifications.discord.description', fields: [ { id: 'webhook', label: 'Discord Webhook URL', + labelKey: 'notifications.discord.webhookLabel', placeholder: 'https://discord.com/api/webhooks/...', + placeholderKey: 'notifications.discord.webhookPlaceholder', type: 'text' } ] @@ -44,18 +53,24 @@ const NOTIFICATION_TYPES = [ { id: 'telegram', label: 'Telegram', + labelKey: 'notifications.telegram.label', description: 'To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.', + descriptionKey: 'notifications.telegram.description', fields: [ { id: 'token', label: 'Your bot token', + labelKey: 'notifications.telegram.tokenLabel', placeholder: '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11', + placeholderKey: 'notifications.telegram.tokenPlaceholder', type: 'text' }, { id: 'chatId', label: 'Your Chat ID', + labelKey: 'notifications.telegram.chatIdLabel', placeholder: '-1001234567890', + placeholderKey: 'notifications.telegram.chatIdPlaceholder', type: 'text' } ] @@ -63,12 +78,16 @@ const NOTIFICATION_TYPES = [ { id: 'webhook', label: 'Webhooks', + labelKey: 'notifications.webhook.label', description: 'You can set up a custom webhook to receive notifications when incidents occur.', + descriptionKey: 'notifications.webhook.description', fields: [ { id: 'url', label: 'Webhook URL', + labelKey: 'notifications.webhook.urlLabel', placeholder: 'https://your-server.com/webhook', + placeholderKey: 'notifications.webhook.urlPlaceholder', type: 'text' } ] @@ -83,6 +102,7 @@ const NotificationIntegrationModal = ({ // Optional prop to configure available notification types notificationTypes = NOTIFICATION_TYPES }) => { + const { t } = useTranslation(); const theme = useTheme(); const [tabValue, setTabValue] = useState(0); @@ -200,7 +220,7 @@ const NotificationIntegrationModal = ({ color: theme.palette.primary.contrastTextSecondary, pl: theme.spacing(4) }}> - Add or edit notifications + {t('notifications.addOrEditNotifications', 'Add or edit notifications')} ( @@ -230,7 +250,16 @@ const NotificationIntegrationModal = ({ {notificationTypes.map((type, index) => ( ({ + ...field, + label: t(field.labelKey, field.label), + placeholder: t(field.placeholderKey, field.placeholder) + })) + }} integrations={integrations} handleIntegrationChange={handleIntegrationChange} handleInputChange={handleInputChange} @@ -258,7 +287,7 @@ const NotificationIntegrationModal = ({ px: theme.spacing(8) }} > - Save + {t('common.save', 'Save')} diff --git a/src/Components/NotificationIntegrationModal/TabComponent.jsx b/src/Components/NotificationIntegrationModal/TabComponent.jsx index f9cf6ab53..89216a8c1 100644 --- a/src/Components/NotificationIntegrationModal/TabComponent.jsx +++ b/src/Components/NotificationIntegrationModal/TabComponent.jsx @@ -4,9 +4,11 @@ import { Box, Button } from "@mui/material"; +import { useTranslation } from "react-i18next"; import { useTheme } from "@emotion/react"; import TextInput from "../../../src/Components/Inputs/TextInput"; import Checkbox from "../../../src/Components/Inputs/Checkbox"; + const TabComponent = ({ type, integrations, @@ -15,6 +17,7 @@ const TabComponent = ({ handleTestNotification }) => { const theme = useTheme(); + const { t } = useTranslation(); // Helper to get the field state key (e.g., slackWebhook, telegramToken) const getFieldKey = (typeId, fieldId) => { @@ -49,7 +52,7 @@ const TabComponent = ({ handleIntegrationChange(type.id, e.target.checked)} /> @@ -87,7 +90,7 @@ const TabComponent = ({ onClick={() => handleTestNotification(type.id)} disabled={!integrations[type.id] || !areAllFieldsFilled()} > - Test notification + {t('notifications.testNotification')} diff --git a/src/locales/gb.json b/src/locales/gb.json index cf7711fa8..9756f8a9d 100644 --- a/src/locales/gb.json +++ b/src/locales/gb.json @@ -107,5 +107,38 @@ "settingsDemoMonitorsAdded": "Successfully added demo monitors", "settingsFailedToAddDemoMonitors": "Failed to add demo monitors", "settingsMonitorsDeleted": "Successfully deleted all monitors", - "settingsFailedToDeleteMonitors": "Failed to delete all monitors" + "settingsFailedToDeleteMonitors": "Failed to delete all monitors", + + "notifications": { + "enableNotifications": "Enable {{platform}} notifications", + "testNotification": "Test notification", + "addOrEditNotifications": "Add or edit notifications", + "slack": { + "label": "Slack", + "description": "To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.", + "webhookLabel": "Webhook URL", + "webhookPlaceholder": "https://hooks.slack.com/services/..." + }, + "discord": { + "label": "Discord", + "description": "To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature.", + "webhookLabel": "Discord Webhook URL", + "webhookPlaceholder": "https://discord.com/api/webhooks/..." + }, + "telegram": { + "label": "Telegram", + "description": "To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.", + "tokenLabel": "Your bot token", + "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", + "chatIdLabel": "Your Chat ID", + "chatIdPlaceholder": "-1001234567890" + }, + "webhook": { + "label": "Webhooks", + "description": "You can set up a custom webhook to receive notifications when incidents occur.", + "urlLabel": "Webhook URL", + "urlPlaceholder": "https://your-server.com/webhook" + } + } + } From d40507ee360ea193358ff9e39382ce830271a766 Mon Sep 17 00:00:00 2001 From: Aryaman Kumar Sharma Date: Sun, 9 Mar 2025 11:36:21 +0530 Subject: [PATCH 35/61] Feat: Migrate Hardcoded Strings in Auth and About --- src/Pages/Auth/Register/Register.jsx | 4 +-- src/Pages/Auth/Register/StepOne/index.jsx | 10 ++++--- src/Pages/DistributedUptime/Create/index.jsx | 22 +++++++------- .../Details/Components/Chatbot/index.jsx | 4 ++- .../Components/ControlsHeader/index.jsx | 9 +++--- .../Details/Components/DeviceTicker/index.jsx | 12 ++++---- .../Helpers/ToolTip.jsx | 7 +++-- .../DistributedUptimeResponseChart/index.jsx | 7 +++-- .../Details/Components/Footer/index.jsx | 9 ++++-- .../Components/MonitorHeader/index.jsx | 4 ++- .../Details/Components/StatusHeader/index.jsx | 6 ++-- src/Pages/DistributedUptime/Details/index.jsx | 8 +++-- .../DistributedUptime/Monitors/index.jsx | 6 ++-- src/locales/gb.json | 30 +++++++++++++++++++ 14 files changed, 97 insertions(+), 41 deletions(-) diff --git a/src/Pages/Auth/Register/Register.jsx b/src/Pages/Auth/Register/Register.jsx index 9f93cc821..b3dfd214b 100644 --- a/src/Pages/Auth/Register/Register.jsx +++ b/src/Pages/Auth/Register/Register.jsx @@ -35,7 +35,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => { textAlign="center" > - Sign Up + {t("signUP")} {isSuperAdmin ? t("authRegisterCreateSuperAdminAccount") @@ -67,7 +67,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => { - {t("authRegisterBySigningUp")} + {t("authRegisterBySigningUp")}{" "} { diff --git a/src/Pages/Auth/Register/StepOne/index.jsx b/src/Pages/Auth/Register/StepOne/index.jsx index 42e547b62..248f57f69 100644 --- a/src/Pages/Auth/Register/StepOne/index.jsx +++ b/src/Pages/Auth/Register/StepOne/index.jsx @@ -4,6 +4,7 @@ import { useTheme } from "@emotion/react"; import { Box, Button, Stack, Typography } from "@mui/material"; import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded"; import TextInput from "../../../../Components/Inputs/TextInput"; +import { useTranslation } from "react-i18next"; StepOne.propTypes = { form: PropTypes.object, @@ -28,6 +29,7 @@ StepOne.propTypes = { function StepOne({ form, errors, onSubmit, onChange, onBack }) { const theme = useTheme(); const inputRef = useRef(null); + const { t } = useTranslation(); useEffect(() => { if (inputRef.current) { @@ -43,8 +45,8 @@ function StepOne({ form, errors, onSubmit, onChange, onBack }) { textAlign="center" > - Sign Up - Enter your personal details + {t("signUp")} + {t("authRegisterStepOnePersonalDetails")} - Back + {t("commonBack")} diff --git a/src/Pages/DistributedUptime/Create/index.jsx b/src/Pages/DistributedUptime/Create/index.jsx index 57160d2ab..458aa011f 100644 --- a/src/Pages/DistributedUptime/Create/index.jsx +++ b/src/Pages/DistributedUptime/Create/index.jsx @@ -19,6 +19,7 @@ import { monitorValidation } from "../../../Validation/validation"; import { useParams } from "react-router-dom"; import { useCreateDistributedUptimeMonitor } from "./Hooks/useCreateDistributedUptimeMonitor"; import { useMonitorFetch } from "./Hooks/useMonitorFetch"; +import { useTranslation } from "react-i18next"; // Constants const MS_PER_MINUTE = 60000; @@ -41,6 +42,7 @@ const parseUrl = (url) => { const CreateDistributedUptime = () => { const { monitorId } = useParams(); const isCreate = typeof monitorId === "undefined"; + const { t } = useTranslation(); let BREADCRUMBS = [ { name: `distributed uptime`, path: "/distributed-uptime" }, @@ -191,14 +193,14 @@ const CreateDistributedUptime = () => { fontSize="inherit" fontWeight="inherit" > - monitor + {t("monitor")} - General settings + {t("settingsGeneralSettings")} - Here you can select the URL of the host, together with the type of monitor. + {t("distributedUptimeCreateSelectURL")} @@ -232,9 +234,9 @@ const CreateDistributedUptime = () => { - Checks to perform + {t("distributedUptimeCreateChecks")} - You can always add or remove checks after adding your site. + {t("distributedUptimeCreateChecksDescription")} @@ -259,14 +261,14 @@ const CreateDistributedUptime = () => { filled={https.toString()} onClick={() => setHttps(true)} > - HTTPS + {t("https")} ) : ( @@ -291,9 +293,9 @@ const CreateDistributedUptime = () => { - Incident notifications + {t("distributedUptimeCreateIncidentNotification")} - When there is an incident, notify users. + {t("distributedUptimeCreateIncidentDescription")} @@ -310,7 +312,7 @@ const CreateDistributedUptime = () => { - Advanced settings + {t("distributedUptimeCreateAdvancedSettings")}