diff --git a/client/README.md b/client/README.md index ee3ed2de2..55bc1efe2 100644 --- a/client/README.md +++ b/client/README.md @@ -1,2 +1 @@ - This directory contains the client side (frontend) of Checkmate. diff --git a/client/index.html b/client/index.html index a667d1ecf..0b0f675b4 100644 --- a/client/index.html +++ b/client/index.html @@ -1,17 +1,24 @@ + + + + - - - - + Checkmate + - Checkmate - - - -
- - - - \ No newline at end of file + +
+ + + diff --git a/client/package.json b/client/package.json index 483f660d1..238ced4ac 100644 --- a/client/package.json +++ b/client/package.json @@ -8,7 +8,9 @@ "build": "vite build", "build-dev": "vite build --mode development", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "preview": "vite preview", + "format": "prettier --write .", + "format-check": "prettier --check ." }, "dependencies": { "@emotion/react": "^11.13.3", diff --git a/client/renovate.json b/client/renovate.json index adfd80a40..67bfd7514 100644 --- a/client/renovate.json +++ b/client/renovate.json @@ -1,7 +1,5 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "labels": ["dependencies"] + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "labels": ["dependencies"] } diff --git a/client/src/Components/Buttons/RoundGradientButton.jsx b/client/src/Components/Buttons/RoundGradientButton.jsx index f9e14735c..ff22be955 100644 --- a/client/src/Components/Buttons/RoundGradientButton.jsx +++ b/client/src/Components/Buttons/RoundGradientButton.jsx @@ -3,28 +3,28 @@ import Button from "@mui/material/Button"; import { styled } from "@mui/material/styles"; const RoundGradientButton = styled(Button)(({ theme }) => ({ - position: "relative", - border: "5px solid transparent", - backgroundClip: "padding-box", - borderRadius: 30, - fontSize: "1.2rem", - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.background.main, + position: "relative", + border: "5px solid transparent", + backgroundClip: "padding-box", + borderRadius: 30, + fontSize: "1.2rem", + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.background.main, - "&:after": { - position: "absolute", - top: -3, - left: -3, - right: -3, - bottom: -3, - background: - theme.palette.mode === "dark" - ? "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)" - : "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)", - content: '""', - zIndex: -1, - borderRadius: 30, - }, + "&:after": { + position: "absolute", + top: -3, + left: -3, + right: -3, + bottom: -3, + background: + theme.palette.mode === "dark" + ? "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)" + : "linear-gradient(90deg, #842bd2, #ff5451, #8c52ff)", + content: '""', + zIndex: -1, + borderRadius: 30, + }, })); export default RoundGradientButton; diff --git a/client/src/Components/Charts/ChartBox/EmptyView.jsx b/client/src/Components/Charts/ChartBox/EmptyView.jsx index 94b1af7b0..296197a8c 100644 --- a/client/src/Components/Charts/ChartBox/EmptyView.jsx +++ b/client/src/Components/Charts/ChartBox/EmptyView.jsx @@ -31,78 +31,76 @@ import IconBox from "../../IconBox"; */ const EmptyView = ({ - icon, - header, - message = "No Data", - headingLevel = "h2", - justifyContent = "flex-start", - height = "100%" + icon, + header, + message = "No Data", + headingLevel = "h2", + justifyContent = "flex-start", + height = "100%", }) => { - const theme = useTheme(); - return ( - - + - - {icon && {icon}} - {header && {header}} - - - - {message} - - - - - ); + "& tspan, & text": { + fill: theme.palette.primary.contrastTextTertiary, + }, + }} + > + + {icon && {icon}} + {header && {header}} + + + {message} + + + + ); }; EmptyView.propTypes = { - message: PropTypes.string, - icon: PropTypes.node, - header: PropTypes.string, - headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3']), - justifyContent: PropTypes.string, - height: PropTypes.string + message: PropTypes.string, + icon: PropTypes.node, + header: PropTypes.string, + headingLevel: PropTypes.oneOf(["h1", "h2", "h3"]), + justifyContent: PropTypes.string, + height: PropTypes.string, }; export default EmptyView; diff --git a/client/src/Components/Charts/ChartBox/index.jsx b/client/src/Components/Charts/ChartBox/index.jsx index 4b72fe16a..6b74ace68 100644 --- a/client/src/Components/Charts/ChartBox/index.jsx +++ b/client/src/Components/Charts/ChartBox/index.jsx @@ -18,7 +18,13 @@ const ChartBox = ({ }) => { const theme = useTheme(); if (isEmpty) { - return ; + return ( + + ); } return ( - {'Copyright © '} - - UpRock - -   - {new Date().getFullYear()} - - ); + return ( + + {"Copyright © "} + + UpRock + +   + {new Date().getFullYear()} + + ); } export default function Footer() { - return ( - - - -
- - Privacy Policy - - -  •  - - - Terms of Service - - -
- - - - - - - - - - - - - - - - + return ( + + +
+ + Privacy Policy + + +  •  + + + Terms of Service + + +
+ + + + + + + + + + + + + + + + + +
-
-
- - - - Made with ❤️ by  - - UpRock  - - &  - - Bluewave Labs - - - - - Built on  - - -
- ); + + + + + + + + + + + + + + + + + + +  Solana + + + + + ); } diff --git a/client/src/Components/ConfigBox/index.jsx b/client/src/Components/ConfigBox/index.jsx index 9b64712fc..44ae38472 100644 --- a/client/src/Components/ConfigBox/index.jsx +++ b/client/src/Components/ConfigBox/index.jsx @@ -29,7 +29,7 @@ const ConfigBox = styled(Stack)(({ theme }) => ({ }, "& h1, & h2": { color: theme.palette.primary.contrastTextSecondary, - } + }, })); export default ConfigBox; diff --git a/client/src/Components/ConfigRow/index.jsx b/client/src/Components/ConfigRow/index.jsx index c19d9ac5a..217085b6d 100644 --- a/client/src/Components/ConfigRow/index.jsx +++ b/client/src/Components/ConfigRow/index.jsx @@ -7,7 +7,7 @@ import ConfigBox from "../ConfigBox"; * ConfigRow is a styled container used to layout content in a row format with specific padding, border, and spacing. * It serves as the wrapper for ConfigBox, with the left section displaying the title and description, * and the right section displaying the children. - * + * * @component * @example * return ( @@ -19,31 +19,40 @@ import ConfigBox from "../ConfigBox"; */ const ConfigRow = ({ title, description, children }) => { - const theme = useTheme(); + const theme = useTheme(); - return ( - - - - {title} - - {description && ( - - {description} - - )} - - - {children} - - - ); + return ( + + + + {title} + + {description && ( + + {description} + + )} + + + {children} + + + ); }; ConfigRow.propTypes = { - title: PropTypes.string.isRequired, - description: PropTypes.string, - children: PropTypes.node, + title: PropTypes.string.isRequired, + description: PropTypes.string, + children: PropTypes.node, }; export default ConfigRow; diff --git a/client/src/Components/FilterHeader/index.jsx b/client/src/Components/FilterHeader/index.jsx index de438da96..36dd04081 100644 --- a/client/src/Components/FilterHeader/index.jsx +++ b/client/src/Components/FilterHeader/index.jsx @@ -42,10 +42,14 @@ const FilterHeader = ({ header, options, value, onChange, multiple = true }) => return header; } - return header + " | " + selected - .map((value) => options.find((option) => option.value === value)?.label) - .filter(Boolean) - .join(", "); + return ( + header + + " | " + + selected + .map((value) => options.find((option) => option.value === value)?.label) + .filter(Boolean) + .join(", ") + ); }} MenuProps={{ anchorOrigin: { diff --git a/client/src/Components/Inputs/ImageUpload/index.jsx b/client/src/Components/Inputs/ImageUpload/index.jsx index a49dc4860..a81c89393 100644 --- a/client/src/Components/Inputs/ImageUpload/index.jsx +++ b/client/src/Components/Inputs/ImageUpload/index.jsx @@ -36,199 +36,198 @@ const ImageUpload = ({ error, }) => { const theme = useTheme(); - const { t } = useTranslation(); - const [uploadComplete, setUploadComplete] = useState(false); - const [completedFile, setCompletedFile] = useState(null); - const [file, setFile] = useState(null); - const [progress, setProgress] = useState({ value: 0, isLoading: false }); - const intervalRef = useRef(null); - const [localError, setLocalError] = useState(null); - const [isDragging, setIsDragging] = useState(false); + const { t } = useTranslation(); + const [uploadComplete, setUploadComplete] = useState(false); + const [completedFile, setCompletedFile] = useState(null); + const [file, setFile] = useState(null); + const [progress, setProgress] = useState({ value: 0, isLoading: false }); + const intervalRef = useRef(null); + const [localError, setLocalError] = useState(null); + const [isDragging, setIsDragging] = useState(false); const roundStyle = previewIsRound ? { borderRadius: "50%" } : {}; const handleImageChange = useCallback( - (file) => { - if (!file) return; + (file) => { + if (!file) return; - const isValidType = accept.some((type) => - file.type.includes(type) - ); - const isValidSize = file.size <= maxSize; - - if (!isValidType) { - setLocalError(t('invalidFileFormat')); - return; - } - if (!isValidSize) { - setLocalError(t('invalidFileSize')); - return; - } - - setLocalError(null); - - const previewFile = { - src: URL.createObjectURL(file), - name: file.name, - file, - }; - - setFile(previewFile); - setProgress({ value: 0, isLoading: true }); - - intervalRef.current = setInterval(() => { - setProgress((prev) => { - const buffer = 12; - if (prev.value + buffer >= 100) { - clearInterval(intervalRef.current); - setUploadComplete(true); - setCompletedFile(previewFile); - return { value: 100, isLoading: false }; - } - return { value: prev.value + buffer, isLoading: true }; - }); - }, 120); - }, - [maxSize, accept] - ); + const isValidType = accept.some((type) => file.type.includes(type)); + const isValidSize = file.size <= maxSize; - useEffect(() => { - if (uploadComplete && completedFile) { - onChange?.(completedFile); - setUploadComplete(false); - setCompletedFile(null); - } - }, [uploadComplete, completedFile, onChange]); + if (!isValidType) { + setLocalError(t("invalidFileFormat")); + return; + } + if (!isValidSize) { + setLocalError(t("invalidFileSize")); + return; + } + setLocalError(null); + + const previewFile = { + src: URL.createObjectURL(file), + name: file.name, + file, + }; + + setFile(previewFile); + setProgress({ value: 0, isLoading: true }); + + intervalRef.current = setInterval(() => { + setProgress((prev) => { + const buffer = 12; + if (prev.value + buffer >= 100) { + clearInterval(intervalRef.current); + setUploadComplete(true); + setCompletedFile(previewFile); + return { value: 100, isLoading: false }; + } + return { value: prev.value + buffer, isLoading: true }; + }); + }, 120); + }, + [maxSize, accept] + ); + + useEffect(() => { + if (uploadComplete && completedFile) { + onChange?.(completedFile); + setUploadComplete(false); + setCompletedFile(null); + } + }, [uploadComplete, completedFile, onChange]); return ( - <> - {src ? ( - - Uploaded preview - - ) : ( - <> - setIsDragging(true)} - onDragLeave={() => setIsDragging(false)} - onDrop={() => setIsDragging(false)} - sx={{ - position: "relative", - height: "fit-content", - border: "dashed", - borderRadius: theme.shape.borderRadius, - borderColor: isDragging - ? theme.palette.primary.main - : theme.palette.primary.lowContrast, - backgroundColor: isDragging - ? "hsl(215, 87%, 51%, 0.05)" - : "transparent", - borderWidth: "2px", - transition: "0.2s", - "&:hover": { - borderColor: theme.palette.primary.main, - backgroundColor: "hsl(215, 87%, 51%, 0.05)", - }, - }} - > - handleImageChange(e?.target?.files?.[0])} - sx={{ - width: "100%", - "& .MuiInputBase-input[type='file']": { - opacity: 0, - cursor: "pointer", - maxWidth: "500px", - minHeight: "175px", - zIndex: 1, - }, - "& fieldset": { - padding: 0, - border: "none", - }, - }} - /> - - - - - - - {t('ClickUpload')} - {" "} - or {t('DragandDrop')} - - ({t('MaxSize')}: {Math.round(maxSize / 1024 / 1024)}MB) - - - - {(localError || progress.isLoading || progress.value !== 0) && ( - } - label={file?.name || "Upload failed"} - size={file?.size} - progress={progress.value} - onClick={() => { - clearInterval(intervalRef.current); - setFile(null); - setProgress({ value: 0, isLoading: false }); - setLocalError(null); - onChange(undefined); - }} - error={localError || error} - /> - )} - - {t('SupportedFormats')}: {accept.join(", ").toUpperCase()} - - - )} - - ); + <> + {src ? ( + + Uploaded preview + + ) : ( + <> + setIsDragging(true)} + onDragLeave={() => setIsDragging(false)} + onDrop={() => setIsDragging(false)} + sx={{ + position: "relative", + height: "fit-content", + border: "dashed", + borderRadius: theme.shape.borderRadius, + borderColor: isDragging + ? theme.palette.primary.main + : theme.palette.primary.lowContrast, + backgroundColor: isDragging ? "hsl(215, 87%, 51%, 0.05)" : "transparent", + borderWidth: "2px", + transition: "0.2s", + "&:hover": { + borderColor: theme.palette.primary.main, + backgroundColor: "hsl(215, 87%, 51%, 0.05)", + }, + }} + > + handleImageChange(e?.target?.files?.[0])} + sx={{ + width: "100%", + "& .MuiInputBase-input[type='file']": { + opacity: 0, + cursor: "pointer", + maxWidth: "500px", + minHeight: "175px", + zIndex: 1, + }, + "& fieldset": { + padding: 0, + border: "none", + }, + }} + /> + + + + + + + {t("ClickUpload")} + {" "} + or {t("DragandDrop")} + + + ({t("MaxSize")}: {Math.round(maxSize / 1024 / 1024)}MB) + + + + {(localError || progress.isLoading || progress.value !== 0) && ( + } + label={file?.name || "Upload failed"} + size={file?.size} + progress={progress.value} + onClick={() => { + clearInterval(intervalRef.current); + setFile(null); + setProgress({ value: 0, isLoading: false }); + setLocalError(null); + onChange(undefined); + }} + error={localError || error} + /> + )} + + {t("SupportedFormats")}: {accept.join(", ").toUpperCase()} + + + )} + + ); }; ImageUpload.propTypes = { @@ -240,4 +239,4 @@ ImageUpload.propTypes = { error: PropTypes.string, }; -export default ImageUpload; \ No newline at end of file +export default ImageUpload; diff --git a/client/src/Components/Label/index.jsx b/client/src/Components/Label/index.jsx index 6ba55e81c..8c4278fed 100644 --- a/client/src/Components/Label/index.jsx +++ b/client/src/Components/Label/index.jsx @@ -158,7 +158,15 @@ const StatusLabel = ({ status, text, customStyles }) => { }; StatusLabel.propTypes = { - status: PropTypes.oneOf(["up", "down", "paused", "pending", "cannot resolve", "published", "unpublished"]), + status: PropTypes.oneOf([ + "up", + "down", + "paused", + "pending", + "cannot resolve", + "published", + "unpublished", + ]), text: PropTypes.string, customStyles: PropTypes.object, }; diff --git a/client/src/Components/Layouts/HomeLayout/index.css b/client/src/Components/Layouts/HomeLayout/index.css index 28ac340f8..2db147f41 100644 --- a/client/src/Components/Layouts/HomeLayout/index.css +++ b/client/src/Components/Layouts/HomeLayout/index.css @@ -30,4 +30,4 @@ max-width: 1400px; margin: 0 auto; flex: 1; -} \ No newline at end of file +} diff --git a/client/src/Components/MonitorCreateHeader/index.jsx b/client/src/Components/MonitorCreateHeader/index.jsx index 15d6d5c0f..b630cb259 100644 --- a/client/src/Components/MonitorCreateHeader/index.jsx +++ b/client/src/Components/MonitorCreateHeader/index.jsx @@ -4,17 +4,11 @@ import PropTypes from "prop-types"; import { useTranslation } from "react-i18next"; import { useTheme } from "@emotion/react"; -const CreateMonitorHeader = ({ - isAdmin, - label, - isLoading = true, - path, - bulkPath, -}) => { +const CreateMonitorHeader = ({ isAdmin, label, isLoading = true, path, bulkPath }) => { const navigate = useNavigate(); const { t } = useTranslation(); const theme = useTheme(); - + // Use the provided label or fall back to the translated default if (!isAdmin) return null; diff --git a/client/src/Components/MonitorStatusHeader/index.jsx b/client/src/Components/MonitorStatusHeader/index.jsx index a3cb5edfe..edadfb8df 100644 --- a/client/src/Components/MonitorStatusHeader/index.jsx +++ b/client/src/Components/MonitorStatusHeader/index.jsx @@ -28,8 +28,9 @@ const MonitorStatusHeader = ({ path, isLoading = false, isAdmin, monitor }) => { gap={theme.spacing(4)} > - {monitor?.url?.replace(/^https?:\/\//, "") || "..."} diff --git a/client/src/Components/NotificationIntegrationModal/Components/TabComponent.jsx b/client/src/Components/NotificationIntegrationModal/Components/TabComponent.jsx index e46a8cdd5..571379c7e 100644 --- a/client/src/Components/NotificationIntegrationModal/Components/TabComponent.jsx +++ b/client/src/Components/NotificationIntegrationModal/Components/TabComponent.jsx @@ -1,109 +1,115 @@ import React from "react"; -import { - Typography, - Box, - Button, - CircularProgress -} from "@mui/material"; +import { Typography, Box, Button, CircularProgress } from "@mui/material"; import { useTranslation } from "react-i18next"; import { useTheme } from "@emotion/react"; import TextInput from "../../../Components/Inputs/TextInput"; import Checkbox from "../../../Components/Inputs/Checkbox"; -const TabComponent = ({ - type, - integrations, - handleIntegrationChange, - handleInputChange, - handleTestNotification, - isLoading +const TabComponent = ({ + type, + integrations, + handleIntegrationChange, + handleInputChange, + handleTestNotification, + isLoading, }) => { - const theme = useTheme(); - const { t } = useTranslation(); - - // 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)} - disabled={isLoading} - /> - - - {type.fields.map(field => { - const fieldKey = getFieldKey(type.id, field.id); - - return ( - - - {field.label} - - - handleInputChange(fieldKey, e.target.value)} - disabled={!integrations[type.id] || isLoading} - /> - - ); - })} - - - - - - ); + const theme = useTheme(); + const { t } = useTranslation(); + + // 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)} + disabled={isLoading} + /> + + + {type.fields.map((field) => { + const fieldKey = getFieldKey(type.id, field.id); + + return ( + + + {field.label} + + + handleInputChange(fieldKey, e.target.value)} + disabled={!integrations[type.id] || isLoading} + /> + + ); + })} + + + + + + ); }; -export default TabComponent; \ No newline at end of file +export default TabComponent; diff --git a/client/src/Components/NotificationIntegrationModal/Components/TabPanel.jsx b/client/src/Components/NotificationIntegrationModal/Components/TabPanel.jsx index a9252e710..93546e7bc 100644 --- a/client/src/Components/NotificationIntegrationModal/Components/TabPanel.jsx +++ b/client/src/Components/NotificationIntegrationModal/Components/TabPanel.jsx @@ -5,7 +5,7 @@ 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. @@ -15,32 +15,27 @@ import { useTheme } from "@emotion/react"; * @returns {React.ReactElement|null} The rendered tab panel or null if not selected. */ function TabPanel({ children, value, index, ...other }) { - const theme = useTheme(); - - return ( - - ); + const theme = useTheme(); + + return ( + + ); } TabPanel.propTypes = { + children: PropTypes.node, - children: PropTypes.node, - - index: PropTypes.number.isRequired, - - value: PropTypes.number.isRequired + index: PropTypes.number.isRequired, + + value: PropTypes.number.isRequired, }; -export default TabPanel; \ No newline at end of file +export default TabPanel; diff --git a/client/src/Components/NotificationIntegrationModal/Hooks/useNotification.js b/client/src/Components/NotificationIntegrationModal/Hooks/useNotification.js index 3547873e8..cdbc11598 100644 --- a/client/src/Components/NotificationIntegrationModal/Hooks/useNotification.js +++ b/client/src/Components/NotificationIntegrationModal/Hooks/useNotification.js @@ -1,128 +1,129 @@ -import { useState } from 'react'; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import { networkService } from '../../../Utils/NetworkService'; -import { createToast } from '../../../Utils/toastUtils'; +import { networkService } from "../../../Utils/NetworkService"; +import { createToast } from "../../../Utils/toastUtils"; // Define constants for notification types to avoid magic values const NOTIFICATION_TYPES = { - SLACK: 'slack', - DISCORD: 'discord', - TELEGRAM: 'telegram', - WEBHOOK: 'webhook' + SLACK: "slack", + DISCORD: "discord", + TELEGRAM: "telegram", + WEBHOOK: "webhook", }; // Define constants for field IDs const FIELD_IDS = { - WEBHOOK: 'webhook', - TOKEN: 'token', - CHAT_ID: 'chatId', - URL: 'url' + WEBHOOK: "webhook", + TOKEN: "token", + CHAT_ID: "chatId", + URL: "url", }; /** * Custom hook for notification-related operations */ const useNotifications = () => { - const [loading, setLoading] = useState(false); - const [error, setError] = useState(undefined); - const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(undefined); + const { t } = useTranslation(); - /** - * Send a test notification - * @param {string} type - The notification type (slack, discord, telegram, webhook) - * @param {object} config - Configuration object with necessary params - */ - const sendTestNotification = async (type, config) => { - setLoading(true); - setError(undefined); - - // Validation based on notification type - let payload = { platform: type }; - let isValid = true; - let errorMessage = ''; - - switch(type) { - case NOTIFICATION_TYPES.SLACK: - payload.webhookUrl = config.webhook; - if (typeof payload.webhookUrl === 'undefined' || payload.webhookUrl === '') { - isValid = false; - errorMessage = t('notifications.slack.webhookRequired'); - } - break; - - case NOTIFICATION_TYPES.DISCORD: - payload.webhookUrl = config.webhook; - if (typeof payload.webhookUrl === 'undefined' || payload.webhookUrl === '') { - isValid = false; - errorMessage = t('notifications.discord.webhookRequired'); - } - break; - - case NOTIFICATION_TYPES.TELEGRAM: - payload.botToken = config.token; - payload.chatId = config.chatId; - if (typeof payload.botToken === 'undefined' || payload.botToken === '' || - typeof payload.chatId === 'undefined' || payload.chatId === '') { - isValid = false; - errorMessage = t('notifications.telegram.fieldsRequired'); - } - break; - - case NOTIFICATION_TYPES.WEBHOOK: - payload.webhookUrl = config.url; - payload.platform = NOTIFICATION_TYPES.SLACK; - if (typeof payload.webhookUrl === 'undefined' || payload.webhookUrl === '') { - isValid = false; - errorMessage = t('notifications.webhook.urlRequired'); - } - break; - - default: - isValid = false; - errorMessage = t('notifications.unsupportedType'); - } + /** + * Send a test notification + * @param {string} type - The notification type (slack, discord, telegram, webhook) + * @param {object} config - Configuration object with necessary params + */ + const sendTestNotification = async (type, config) => { + setLoading(true); + setError(undefined); - // If validation fails, show error and return - if (isValid === false) { - createToast({ - body: errorMessage, - variant: "error" - }); - setLoading(false); - return; - } + // Validation based on notification type + let payload = { platform: type }; + let isValid = true; + let errorMessage = ""; - try { - const response = await networkService.testNotification({ - platform: type, - payload: payload - }); - - if (response.data.success === true) { - createToast({ - body: t('notifications.testSuccess'), - variant: "info" - }); - } else { - throw new Error(response.data.msg || t('notifications.testFailed')); - } - } catch (error) { - const errorMsg = error.response?.data?.msg || error.message || t('notifications.networkError'); - createToast({ - body: `${t('notifications.testFailed')}: ${errorMsg}`, - variant: "error" - }); - setError(errorMsg); - } finally { - setLoading(false); - } - }; + switch (type) { + case NOTIFICATION_TYPES.SLACK: + payload.webhookUrl = config.webhook; + if (typeof payload.webhookUrl === "undefined" || payload.webhookUrl === "") { + isValid = false; + errorMessage = t("notifications.slack.webhookRequired"); + } + break; - return [ - loading, - error, - sendTestNotification - ]; + case NOTIFICATION_TYPES.DISCORD: + payload.webhookUrl = config.webhook; + if (typeof payload.webhookUrl === "undefined" || payload.webhookUrl === "") { + isValid = false; + errorMessage = t("notifications.discord.webhookRequired"); + } + break; + + case NOTIFICATION_TYPES.TELEGRAM: + payload.botToken = config.token; + payload.chatId = config.chatId; + if ( + typeof payload.botToken === "undefined" || + payload.botToken === "" || + typeof payload.chatId === "undefined" || + payload.chatId === "" + ) { + isValid = false; + errorMessage = t("notifications.telegram.fieldsRequired"); + } + break; + + case NOTIFICATION_TYPES.WEBHOOK: + payload.webhookUrl = config.url; + payload.platform = NOTIFICATION_TYPES.SLACK; + if (typeof payload.webhookUrl === "undefined" || payload.webhookUrl === "") { + isValid = false; + errorMessage = t("notifications.webhook.urlRequired"); + } + break; + + default: + isValid = false; + errorMessage = t("notifications.unsupportedType"); + } + + // If validation fails, show error and return + if (isValid === false) { + createToast({ + body: errorMessage, + variant: "error", + }); + setLoading(false); + return; + } + + try { + const response = await networkService.testNotification({ + platform: type, + payload: payload, + }); + + if (response.data.success === true) { + createToast({ + body: t("notifications.testSuccess"), + variant: "info", + }); + } else { + throw new Error(response.data.msg || t("notifications.testFailed")); + } + } catch (error) { + const errorMsg = + error.response?.data?.msg || error.message || t("notifications.networkError"); + createToast({ + body: `${t("notifications.testFailed")}: ${errorMsg}`, + variant: "error", + }); + setError(errorMsg); + } finally { + setLoading(false); + } + }; + + return [loading, error, sendTestNotification]; }; -export default useNotifications; \ No newline at end of file +export default useNotifications; diff --git a/client/src/Components/ProgressBars/index.jsx b/client/src/Components/ProgressBars/index.jsx index 4f5515d3a..ad7ceb3dc 100644 --- a/client/src/Components/ProgressBars/index.jsx +++ b/client/src/Components/ProgressBars/index.jsx @@ -93,7 +93,7 @@ const ProgressUpload = ({ icon, label, size, progress = 0, onClick, error }) => {error ? error : label} diff --git a/client/src/Components/Sidebar/index.jsx b/client/src/Components/Sidebar/index.jsx index b0f99cd2f..f78ac62f0 100644 --- a/client/src/Components/Sidebar/index.jsx +++ b/client/src/Components/Sidebar/index.jsx @@ -121,7 +121,7 @@ function Sidebar() { const dispatch = useDispatch(); const { t } = useTranslation(); const authState = useSelector((state) => state.auth); - + const menu = getMenu(t); const otherMenuItems = getOtherMenuItems(t); const accountMenuItems = getAccountMenuItems(t); @@ -147,7 +147,7 @@ function Sidebar() { } else { setSidebarReady(false); } - }, [collapsed]); + }, [collapsed]); const renderAccountMenuItems = () => { let filteredAccountMenuItems = [...accountMenuItems]; @@ -170,8 +170,8 @@ function Sidebar() { { - closePopup() - navigate(item.path) + closePopup(); + navigate(item.path); }} sx={{ gap: theme.spacing(2), @@ -231,7 +231,7 @@ function Sidebar() { */ sx={{ position: "relative", - borderRight: `1px solid ${theme.palette.primary.lowContrast}`, + borderRight: `1px solid ${theme.palette.primary.lowContrast}`, borderColor: theme.palette.primary.lowContrast, borderRadius: 0, backgroundColor: theme.palette.primary.main, @@ -732,11 +732,15 @@ function Sidebar() { {authState.user?.firstName} {authState.user?.lastName} - {authState.user?.role?.includes("superadmin") ? t("roles.superAdmin") : - authState.user?.role?.includes("admin") ? t("roles.admin") : - authState.user?.role?.includes("user") ? t("roles.teamMember") : - authState.user?.role?.includes("demo") ? t("roles.demoUser") : - authState.user?.role} + {authState.user?.role?.includes("superadmin") + ? t("roles.superAdmin") + : authState.user?.role?.includes("admin") + ? t("roles.admin") + : authState.user?.role?.includes("user") + ? t("roles.teamMember") + : authState.user?.role?.includes("demo") + ? t("roles.demoUser") + : authState.user?.role} { - const theme = useTheme(); - const dispatch = useDispatch(); - const { t } = useTranslation(); - const isOpen = useSelector((state) => state.ui?.starPromptOpen ?? true); - const mode = useSelector((state) => state.ui.mode); +const StarPrompt = ({ repoUrl = "https://github.com/bluewave-labs/checkmate" }) => { + const theme = useTheme(); + const dispatch = useDispatch(); + const { t } = useTranslation(); + const isOpen = useSelector((state) => state.ui?.starPromptOpen ?? true); + const mode = useSelector((state) => state.ui.mode); - const handleClose = () => { - dispatch(setStarPromptOpen(false)); - }; + const handleClose = () => { + dispatch(setStarPromptOpen(false)); + }; - const handleStarClick = () => { - window.open(repoUrl, '_blank'); - }; + const handleStarClick = () => { + window.open(repoUrl, "_blank"); + }; - if (!isOpen) return null; + if (!isOpen) return null; - return ( - - - - {t('starPromptTitle')} - - - - - + return ( + + + + {t("starPromptTitle")} + + + + + - - {t('starPromptDescription')} - + + {t("starPromptDescription")} + - - - ); + + + ); }; export default StarPrompt; diff --git a/client/src/Components/StatBox/index.jsx b/client/src/Components/StatBox/index.jsx index ed0b6694a..673736ea9 100644 --- a/client/src/Components/StatBox/index.jsx +++ b/client/src/Components/StatBox/index.jsx @@ -80,7 +80,7 @@ const StatBox = ({ }; const responsiveWidths = { - default: `calc(25% - (3 * ${theme.spacing(8)} / 4))`, + default: `calc(25% - (3 * ${theme.spacing(8)} / 4))`, md: `calc(50% - (1 * ${theme.spacing(8)} / 2))`, }; diff --git a/client/src/Components/Tab/index.jsx b/client/src/Components/Tab/index.jsx index 97bb25c7f..72709cc00 100644 --- a/client/src/Components/Tab/index.jsx +++ b/client/src/Components/Tab/index.jsx @@ -20,7 +20,11 @@ const CustomTabList = ({ value, onChange, children, ...props }) => { "& .MuiTabs-root": { height: "fit-content", minHeight: "0" }, }} > - + {children} diff --git a/client/src/Components/TabPanels/Account/PasswordPanel.jsx b/client/src/Components/TabPanels/Account/PasswordPanel.jsx index 94991ab09..88604c72b 100644 --- a/client/src/Components/TabPanels/Account/PasswordPanel.jsx +++ b/client/src/Components/TabPanels/Account/PasswordPanel.jsx @@ -94,7 +94,10 @@ const PasswordPanel = () => { const action = await dispatch(update({ localData })); if (action.payload.success) { createToast({ - body: t("passwordPanel.passwordChangedSuccess", "Your password was changed successfully."), + body: t( + "passwordPanel.passwordChangedSuccess", + "Your password was changed successfully." + ), }); setLocalData({ password: "", @@ -104,7 +107,10 @@ const PasswordPanel = () => { } else { // TODO: Check for other errors? createToast({ - body: t("passwordPanel.passwordInputIncorrect", "Your password input was incorrect."), + body: t( + "passwordPanel.passwordInputIncorrect", + "Your password input was incorrect." + ), }); setErrors({ password: "*" + action.payload.msg + "." }); } @@ -153,7 +159,10 @@ const PasswordPanel = () => { { )} diff --git a/client/src/Components/TabPanels/Account/ProfilePanel.jsx b/client/src/Components/TabPanels/Account/ProfilePanel.jsx index bdf52de3a..53a8a8d77 100644 --- a/client/src/Components/TabPanels/Account/ProfilePanel.jsx +++ b/client/src/Components/TabPanels/Account/ProfilePanel.jsx @@ -85,13 +85,13 @@ const ProfilePanel = () => { // Resets picture-related states and clears interval const removePicture = () => { errors["picture"] && clearError("picture"); - setFile(undefined); + setFile(undefined); setLocalData((prev) => ({ ...prev, file: undefined, - deleteProfileImage: true, + deleteProfileImage: true, })); - }; + }; // Opens the picture update modal const openPictureModal = () => { @@ -102,9 +102,9 @@ const ProfilePanel = () => { // Closes the picture update modal and resets related states const closePictureModal = () => { if (errors["picture"]) clearError("picture"); - setFile(undefined); - setIsOpen(""); - }; + setFile(undefined); + setIsOpen(""); + }; // Updates profile image displayed on UI const handleUpdatePicture = () => { @@ -116,24 +116,23 @@ const ProfilePanel = () => { setIsOpen(""); if (errors["unchanged"]) clearError("unchanged"); }; - + // Handles form submission to update user profile const handleSaveProfile = async (event) => { event.preventDefault(); const nameChanged = - localData.firstName !== user.firstName || - localData.lastName !== user.lastName; + localData.firstName !== user.firstName || localData.lastName !== user.lastName; const avatarChanged = - localData.deleteProfileImage === true || - (localData.file && localData.file !== `data:image/png;base64,${user.avatarImage}`); + localData.deleteProfileImage === true || + (localData.file && localData.file !== `data:image/png;base64,${user.avatarImage}`); if (!nameChanged && !avatarChanged) { - createToast({ - body: "Unable to update profile — no changes detected.", - }); - setErrors({ unchanged: "unable to update profile" }); - return; + createToast({ + body: "Unable to update profile — no changes detected.", + }); + setErrors({ unchanged: "unable to update profile" }); + return; } const action = await dispatch(update({ localData })); @@ -205,7 +204,7 @@ const ProfilePanel = () => { > {/* This 0.9 is a bit magic numbering, refactor */} - {t('FirstName')} + {t("FirstName")} { gap={SPACING_GAP} > - {t('LastName')} + {t("LastName")} { gap={SPACING_GAP} > - {t('email')} + {t("email")} - {t('EmailDescriptionText')} + {t("EmailDescriptionText")} { gap={SPACING_GAP} > - {t('YourPhoto')} + {t("YourPhoto")} - {t('PhotoDescriptionText')} + {t("PhotoDescriptionText")} { color="error" onClick={handleDeletePicture} > - {t('delete')} + {t("delete")} @@ -325,7 +324,7 @@ const ProfilePanel = () => { disabled={Object.keys(errors).length !== 0 && !errors?.picture && true} sx={{ px: theme.spacing(12) }} > - {t('save')} + {t("save")}
@@ -344,12 +343,12 @@ const ProfilePanel = () => { spellCheck="false" > - {t('DeleteAccountTitle')} + {t("DeleteAccountTitle")} - {t('DeleteDescriptionText')} + {t("DeleteDescriptionText")} )} setIsOpen("")} - confirmationButtonLabel={t('DeleteAccountButton')} + confirmationButtonLabel={t("DeleteAccountButton")} onConfirm={handleDeleteAccount} isLoading={isLoading} /> @@ -389,13 +388,13 @@ const ProfilePanel = () => { : user?.avatarImage ? `data:image/png;base64,${user.avatarImage}` : "" - } + } onChange={(newFile) => { if (newFile) { setFile(newFile); clearError("unchanged"); } - }} + }} previewIsRound maxSize={3 * 1024 * 1024} /> @@ -410,7 +409,7 @@ const ProfilePanel = () => { color="info" onClick={removePicture} > - {t('remove')} + {t("remove")} diff --git a/client/src/Components/TabPanels/Account/TeamPanel.jsx b/client/src/Components/TabPanels/Account/TeamPanel.jsx index fe4b201dd..c29762233 100644 --- a/client/src/Components/TabPanels/Account/TeamPanel.jsx +++ b/client/src/Components/TabPanels/Account/TeamPanel.jsx @@ -48,7 +48,8 @@ const TeamPanel = () => { {row.firstName + " " + row.lastName} - {t("teamPanel.table.created")} {new Date(row.createdAt).toLocaleDateString()} + {t("teamPanel.table.created")}{" "} + {new Date(row.createdAt).toLocaleDateString()} ); diff --git a/client/src/Components/WalletProvider/index.css b/client/src/Components/WalletProvider/index.css index 15fb9d816..f3da31efc 100644 --- a/client/src/Components/WalletProvider/index.css +++ b/client/src/Components/WalletProvider/index.css @@ -1,10 +1,10 @@ .wallet-adapter-dropdown { width: 100%; display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - gap: var(--env-var-spacing-1); + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: var(--env-var-spacing-1); } .wallet-adapter-button { @@ -15,37 +15,39 @@ 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); + 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 { - font-size: var(--font-size-h5) !important; + 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; + background-color: var(--border-color) !important; + margin: var(--spacing-md) 0 !important; } /* Responsive fixes */ -@media (max-width: 1200px) { +@media (max-width: 1200px) { .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: 900px) { - .wallet-adapter-modal-wrapper { - flex-direction: column !important; - } - - .wallet-adapter-modal-divider { - margin: var(--spacing-sm) 0 !important; - } -} \ No newline at end of file +@media (max-width: 900px) { + .wallet-adapter-modal-wrapper { + flex-direction: column !important; + } + + .wallet-adapter-modal-divider { + margin: var(--spacing-sm) 0 !important; + } +} diff --git a/client/src/Hooks/useBulkMonitors.js b/client/src/Hooks/useBulkMonitors.js index 0caa58b41..a834f0140 100644 --- a/client/src/Hooks/useBulkMonitors.js +++ b/client/src/Hooks/useBulkMonitors.js @@ -2,26 +2,26 @@ import { useState } from "react"; import { networkService } from "../main"; export const useBulkMonitors = () => { - const [isLoading, setIsLoading] = useState(false); + const [isLoading, setIsLoading] = useState(false); - const createBulkMonitors = async (file, user) => { - setIsLoading(true); + const createBulkMonitors = async (file, user) => { + setIsLoading(true); - const formData = new FormData(); - formData.append("csvFile", file); - formData.append("userId", user._id); - formData.append("teamId", user.teamId); + const formData = new FormData(); + formData.append("csvFile", file); + formData.append("userId", user._id); + formData.append("teamId", user.teamId); - try { - const response = await networkService.createBulkMonitors(formData); - return [true, response.data, null]; // [success, data, error] - } catch (err) { - const errorMessage = err?.response?.data?.msg || err.message; - return [false, null, errorMessage]; - } finally { - setIsLoading(false); - } - }; + try { + const response = await networkService.createBulkMonitors(formData); + return [true, response.data, null]; // [success, data, error] + } catch (err) { + const errorMessage = err?.response?.data?.msg || err.message; + return [false, null, errorMessage]; + } finally { + setIsLoading(false); + } + }; - return [createBulkMonitors, isLoading]; + return [createBulkMonitors, isLoading]; }; diff --git a/client/src/Hooks/useMonitorUtils.js b/client/src/Hooks/useMonitorUtils.js index f187f7250..424112a81 100644 --- a/client/src/Hooks/useMonitorUtils.js +++ b/client/src/Hooks/useMonitorUtils.js @@ -2,7 +2,6 @@ import { useCallback } from "react"; import { useTheme } from "@mui/material"; const useMonitorUtils = () => { - const getMonitorWithPercentage = useCallback((monitor, theme) => { let uptimePercentage = ""; let percentageColor = ""; diff --git a/client/src/Hooks/useSendTestEmail.js b/client/src/Hooks/useSendTestEmail.js index d186fd748..e280b1f99 100644 --- a/client/src/Hooks/useSendTestEmail.js +++ b/client/src/Hooks/useSendTestEmail.js @@ -20,18 +20,20 @@ const useSendTestEmail = () => { setError(null); // Send the test email with or without configuration - const response = await networkService.sendTestEmail({ + const response = await networkService.sendTestEmail({ to: user.email, - emailConfig + emailConfig, }); - + if (typeof response?.data?.data?.messageId !== "undefined") { createToast({ body: t("settingsTestEmailSuccess", "Test email sent successfully"), }); } else { - throw new Error(response?.data?.error || t("settingsTestEmailFailed", "Failed to send test email")); - + throw new Error( + response?.data?.error || + t("settingsTestEmailFailed", "Failed to send test email") + ); } } catch (error) { createToast({ @@ -39,10 +41,14 @@ const useSendTestEmail = () => { }); setError(error); createToast({ - body: t("settingsTestEmailFailedWithReason", "Failed to send test email: {{reason}}", { - reason: error.message || t("settingsTestEmailUnknownError", "Unknown error") - }), - variant: "error" + body: t( + "settingsTestEmailFailedWithReason", + "Failed to send test email: {{reason}}", + { + reason: error.message || t("settingsTestEmailUnknownError", "Unknown error"), + } + ), + variant: "error", }); } finally { setIsSending(false); diff --git a/client/src/Pages/About/index.jsx b/client/src/Pages/About/index.jsx index dcb9d3f43..97040b2e3 100644 --- a/client/src/Pages/About/index.jsx +++ b/client/src/Pages/About/index.jsx @@ -1,6 +1,6 @@ -import React from 'react'; -import AppBar from '../../Components/Common/AppBar'; -import Footer from '../../Components/Common/Footer'; +import React from "react"; +import AppBar from "../../Components/Common/AppBar"; +import Footer from "../../Components/Common/Footer"; import { useTranslation } from "react-i18next"; const AboutUs = () => { diff --git a/client/src/Pages/Account/index.jsx b/client/src/Pages/Account/index.jsx index 0f17d2d01..9ba57eb06 100644 --- a/client/src/Pages/Account/index.jsx +++ b/client/src/Pages/Account/index.jsx @@ -31,21 +31,19 @@ const Account = ({ open = "profile" }) => { let tabList = [ { name: t("menu.profile"), value: "profile" }, { name: t("menu.password"), value: "password" }, - { name: t("menu.team"), value: "team" } + { name: t("menu.team"), value: "team" }, ]; const hideTeams = !requiredRoles.some((role) => user.role.includes(role)); if (hideTeams) { tabList = [ { name: t("menu.profile"), value: "profile" }, - { name: t("menu.password"), value: "password" } + { name: t("menu.password"), value: "password" }, ]; } // Remove password for demo if (user.role.includes("demo")) { - tabList = [ - { name: t("menu.profile"), value: "profile" } - ]; + tabList = [{ name: t("menu.profile"), value: "profile" }]; } const handleKeyDown = (event) => { @@ -70,7 +68,11 @@ const Account = ({ open = "profile" }) => { py={theme.spacing(12)} > - + {tabList.map((item, index) => ( { width: "30%", px: theme.spacing(6), borderRadius: `${theme.shape.borderRadius}px !important`, - '&.MuiButtonBase-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButtonBase-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, - '&.MuiButton-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButton-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, "&.Mui-focusVisible": { outline: `2px solid ${theme.palette.primary.main}`, diff --git a/client/src/Pages/Auth/Login/Components/PasswordStep.jsx b/client/src/Pages/Auth/Login/Components/PasswordStep.jsx index a57246e23..1fbdf93f0 100644 --- a/client/src/Pages/Auth/Login/Components/PasswordStep.jsx +++ b/client/src/Pages/Auth/Login/Components/PasswordStep.jsx @@ -79,11 +79,11 @@ const PasswordStep = ({ form, errors, onSubmit, onChange, onBack }) => { sx={{ px: theme.spacing(5), borderRadius: `${theme.shape.borderRadius}px !important`, - '&.MuiButtonBase-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButtonBase-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, - '&.MuiButton-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButton-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, "& svg.MuiSvgIcon-root": { mr: theme.spacing(3), @@ -108,11 +108,11 @@ const PasswordStep = ({ form, errors, onSubmit, onChange, onBack }) => { width: "30%", px: theme.spacing(4), borderRadius: `${theme.shape.borderRadius}px !important`, - '&.MuiButtonBase-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButtonBase-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, - '&.MuiButton-root': { - borderRadius: `${theme.shape.borderRadius}px !important` + "&.MuiButton-root": { + borderRadius: `${theme.shape.borderRadius}px !important`, }, "&.Mui-focusVisible": { outline: `2px solid ${theme.palette.primary.main}`, diff --git a/client/src/Pages/Auth/Login/Login.jsx b/client/src/Pages/Auth/Login/Login.jsx index 8ac831a40..5df2ed011 100644 --- a/client/src/Pages/Auth/Login/Login.jsx +++ b/client/src/Pages/Auth/Login/Login.jsx @@ -43,8 +43,6 @@ const Login = () => { const [errors, setErrors] = useState({}); const [step, setStep] = useState(0); - - useEffect(() => { if (authToken) { navigate("/uptime"); @@ -84,7 +82,9 @@ const Login = () => { ); if (error) { const errorMessage = error.details[0].message; - const translatedMessage = errorMessage.startsWith('auth') ? t(errorMessage) : errorMessage; + const translatedMessage = errorMessage.startsWith("auth") + ? t(errorMessage) + : errorMessage; setErrors((prev) => ({ ...prev, email: translatedMessage })); createToast({ body: translatedMessage }); } else { @@ -103,7 +103,9 @@ const Login = () => { createToast({ body: error.details && error.details.length > 0 - ? (error.details[0].message.startsWith('auth') ? t(error.details[0].message) : error.details[0].message) + ? error.details[0].message.startsWith("auth") + ? t(error.details[0].message) + : error.details[0].message : t("Error validating data."), }); } else { @@ -227,9 +229,9 @@ const Login = () => { email={form.email} errorEmail={errors.email} /> - + {/* Registration link */} - + { component="span" color={theme.palette.accent.main} ml={theme.spacing(2)} - sx={{ - cursor: 'pointer', - '&:hover': { - color: theme.palette.accent.darker - } + sx={{ + cursor: "pointer", + "&:hover": { + color: theme.palette.accent.darker, + }, }} onClick={() => navigate("/register")} > diff --git a/client/src/Pages/Auth/NewPasswordConfirmed.jsx b/client/src/Pages/Auth/NewPasswordConfirmed.jsx index 9c7734083..57a4aaf25 100644 --- a/client/src/Pages/Auth/NewPasswordConfirmed.jsx +++ b/client/src/Pages/Auth/NewPasswordConfirmed.jsx @@ -100,9 +100,7 @@ const NewPasswordConfirmed = () => { {t("passwordreset")} - - {t("authNewPasswordConfirmed")} - + {t("authNewPasswordConfirmed")} diff --git a/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx b/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx index d374d1960..70d36bd00 100644 --- a/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx +++ b/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx @@ -16,8 +16,8 @@ const Gauge = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo }) => mb: theme.spacing(2), mt: theme.spacing(2), pr: theme.spacing(2), - textAlign: 'right' - } + textAlign: "right", + }; return ( @@ -32,14 +32,19 @@ const Gauge = ({ value, heading, metricOne, valueOne, metricTwo, valueTwo }) => flexDirection: "column", alignItems: "center", width: "100%", - backgroundColor: theme.palette.gradient.color1 + backgroundColor: theme.palette.gradient.color1, }} > - {heading} + + {heading} + { - // Abort early if creating monitor - if (!monitorId) { - return { monitor: undefined, isLoading: false, networkError: undefined }; - } + if (!monitorId) { + return { monitor: undefined, isLoading: false, networkError: undefined }; + } const [isLoading, setIsLoading] = useState(true); const [networkError, setNetworkError] = useState(false); const [monitor, setMonitor] = useState(undefined); diff --git a/client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx index a2d82613c..3c2511c2f 100644 --- a/client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx +++ b/client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx @@ -53,10 +53,10 @@ const Filter = ({ return ( { ); } - if (!isLoading && typeof summary?.totalMonitors === "undefined" ) { + if (!isLoading && typeof summary?.totalMonitors === "undefined") { return ( { }} > {t("integrations")} - - {t("integrationsPrism")} - + {t("integrationsPrism")} { - {t("settingsGeneralSettings")} + + {t("settingsGeneralSettings")} + {t("pageSpeedConfigureSettingsDescription")} @@ -349,7 +354,12 @@ const PageSpeedConfigure = () => { - {t("distributedUptimeCreateIncidentNotification")} + + {t("distributedUptimeCreateIncidentNotification")} + {t("distributedUptimeCreateIncidentDescription")} @@ -394,9 +404,7 @@ const PageSpeedConfigure = () => { value="" onChange={() => logger.warn("disabled")} /> - - {t("seperateEmails")} - + {t("seperateEmails")} ) : ( "" @@ -405,7 +413,12 @@ const PageSpeedConfigure = () => { - {t("distributedUptimeCreateAdvancedSettings")} + + {t("distributedUptimeCreateAdvancedSettings")} + { const theme = useTheme(); const { t } = useTranslation(); - + if (!shouldRender) { return ; } diff --git a/client/src/Pages/ServerUnreachable.jsx b/client/src/Pages/ServerUnreachable.jsx index aaa61cbc4..e7d81926e 100644 --- a/client/src/Pages/ServerUnreachable.jsx +++ b/client/src/Pages/ServerUnreachable.jsx @@ -12,150 +12,158 @@ import ThemeSwitch from "../Components/ThemeSwitch"; import LanguageSelector from "../Components/LanguageSelector"; const ServerUnreachable = () => { - const theme = useTheme(); - const navigate = useNavigate(); - const { t } = useTranslation(); - - // State for tracking connection check status - const [isCheckingConnection, setIsCheckingConnection] = useState(false); + const theme = useTheme(); + const navigate = useNavigate(); + const { t } = useTranslation(); - const handleRetry = React.useCallback(async () => { - setIsCheckingConnection(true); - try { - // Try to connect to the backend with a simple API call - // We'll use any lightweight endpoint that doesn't require authentication - await networkService.axiosInstance.get('/health', { timeout: 5000 }); - - // If successful, show toast and navigate to login page - createToast({ - body: t("backendReconnected", "Connection to server restored"), - }); - navigate("/login"); - } catch (error) { - // If still unreachable, stay on this page and show toast - createToast({ - body: t("backendStillUnreachable", "Server is still unreachable"), - }); - } finally { - setIsCheckingConnection(false); - } - }, [navigate, t]); + // State for tracking connection check status + const [isCheckingConnection, setIsCheckingConnection] = useState(false); - return ( - - - - - - {/* Header with logo */} - - - - Checkmate - - - - - - - .MuiStack-root": { - border: 1, - borderRadius: theme.spacing(5), - borderColor: theme.palette.primary.lowContrast, - backgroundColor: theme.palette.primary.main, - padding: { - xs: theme.spacing(12), - sm: theme.spacing(20), - }, - }, - }} - > - - - - - - - {t("backendUnreachableMessage", "The Checkmate server is not responding. Please check your deployment configuration or try again later.")} - - - - - - - - - ); + const handleRetry = React.useCallback(async () => { + setIsCheckingConnection(true); + try { + // Try to connect to the backend with a simple API call + // We'll use any lightweight endpoint that doesn't require authentication + await networkService.axiosInstance.get("/health", { timeout: 5000 }); + + // If successful, show toast and navigate to login page + createToast({ + body: t("backendReconnected", "Connection to server restored"), + }); + navigate("/login"); + } catch (error) { + // If still unreachable, stay on this page and show toast + createToast({ + body: t("backendStillUnreachable", "Server is still unreachable"), + }); + } finally { + setIsCheckingConnection(false); + } + }, [navigate, t]); + + return ( + + + + + + {/* Header with logo */} + + + + Checkmate + + + + + + + .MuiStack-root": { + border: 1, + borderRadius: theme.spacing(5), + borderColor: theme.palette.primary.lowContrast, + backgroundColor: theme.palette.primary.main, + padding: { + xs: theme.spacing(12), + sm: theme.spacing(20), + }, + }, + }} + > + + + + + + + {t( + "backendUnreachableMessage", + "The Checkmate server is not responding. Please check your deployment configuration or try again later." + )} + + + + + + + + + ); }; export default ServerUnreachable; diff --git a/client/src/Pages/Settings/SettingsAbout.jsx b/client/src/Pages/Settings/SettingsAbout.jsx index 91a3c5e58..121b732f8 100644 --- a/client/src/Pages/Settings/SettingsAbout.jsx +++ b/client/src/Pages/Settings/SettingsAbout.jsx @@ -12,7 +12,12 @@ const SettingsAbout = () => { return ( - {t("settingsAbout")} + + {t("settingsAbout")} + Checkmate {2.1} diff --git a/client/src/Pages/Settings/SettingsDemoMonitors.jsx b/client/src/Pages/Settings/SettingsDemoMonitors.jsx index c685038de..fbcbc66ab 100644 --- a/client/src/Pages/Settings/SettingsDemoMonitors.jsx +++ b/client/src/Pages/Settings/SettingsDemoMonitors.jsx @@ -23,7 +23,12 @@ const SettingsDemoMonitors = ({ isAdmin, HEADER_SX, handleChange, isLoading }) = <> - {t("settingsDemoMonitors")} + + {t("settingsDemoMonitors")} + {t("settingsDemoMonitorsDescription")} @@ -48,7 +53,12 @@ const SettingsDemoMonitors = ({ isAdmin, HEADER_SX, handleChange, isLoading }) = - {t("settingsSystemReset")} + + {t("settingsSystemReset")} + {t("settingsSystemResetDescription")} diff --git a/client/src/Pages/Settings/SettingsEmail.jsx b/client/src/Pages/Settings/SettingsEmail.jsx index bc69db106..88f8f98c1 100644 --- a/client/src/Pages/Settings/SettingsEmail.jsx +++ b/client/src/Pages/Settings/SettingsEmail.jsx @@ -52,18 +52,18 @@ const SettingsEmail = ({ systemEmailUser: settingsData?.settings?.systemEmailUser, systemEmailAddress: settingsData?.settings?.systemEmailAddress, systemEmailPassword: password || settingsData?.settings?.systemEmailPassword, - systemEmailConnectionHost: settingsData?.settings?.systemEmailConnectionHost + systemEmailConnectionHost: settingsData?.settings?.systemEmailConnectionHost, }; - + // Basic validation if (!emailConfig.systemEmailHost || !emailConfig.systemEmailPort) { createToast({ body: t("settingsEmailRequiredFields", "Email host and port are required"), - variant: "error" + variant: "error", }); return; } - + // Send test email with current form values sendTestEmail(emailConfig); }; @@ -75,7 +75,12 @@ const SettingsEmail = ({ return ( - {t("settingsEmail")} + + {t("settingsEmail")} + {t("settingsEmailDescription")} diff --git a/client/src/Pages/Settings/SettingsPagespeed.jsx b/client/src/Pages/Settings/SettingsPagespeed.jsx index ea45d66ed..c7007b5bd 100644 --- a/client/src/Pages/Settings/SettingsPagespeed.jsx +++ b/client/src/Pages/Settings/SettingsPagespeed.jsx @@ -41,7 +41,12 @@ const SettingsPagespeed = ({ return ( - {t("pageSpeedApiKeyFieldTitle")} + + {t("pageSpeedApiKeyFieldTitle")} + {t("pageSpeedApiKeyFieldDescription")} diff --git a/client/src/Pages/Settings/SettingsTimeZone.jsx b/client/src/Pages/Settings/SettingsTimeZone.jsx index fccd19466..86fc72992 100644 --- a/client/src/Pages/Settings/SettingsTimeZone.jsx +++ b/client/src/Pages/Settings/SettingsTimeZone.jsx @@ -15,7 +15,12 @@ const SettingsTimeZone = ({ HEADING_SX, handleChange, timezone }) => { return ( - {t("settingsGeneralSettings")} + + {t("settingsGeneralSettings")} + {t("settingsDisplayTimezone")}-{" "} {t("settingsDisplayTimezoneDescription")} diff --git a/client/src/Pages/Settings/SettingsUI.jsx b/client/src/Pages/Settings/SettingsUI.jsx index e15b5e657..a6dc6c9e4 100644 --- a/client/src/Pages/Settings/SettingsUI.jsx +++ b/client/src/Pages/Settings/SettingsUI.jsx @@ -16,7 +16,12 @@ const SettingsUI = ({ HEADING_SX, handleChange, mode, language }) => { return ( - {t("settingsAppearance")} + + {t("settingsAppearance")} + {t("settingsAppearanceDescription")} diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx index adc622eed..e313f0e85 100644 --- a/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx +++ b/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx @@ -9,7 +9,12 @@ const ConfigStack = ({ title, description, children }) => { return ( - {title} + + {title} + {description} {children} diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx index bb43959d9..4242f931c 100644 --- a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx +++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx @@ -34,10 +34,13 @@ const TabSettings = ({ - {t("access")} - - {t("statusPageCreateSettings")} + + {t("access")} + {t("statusPageCreateSettings")} - {t("basicInformation")} + + {t("basicInformation")} + {t("statusPageCreateBasicInfoDescription")} @@ -82,7 +90,12 @@ const TabSettings = ({ - {t("timezone")} + + {t("timezone")} + {t("statusPageCreateSelectTimeZoneDescription")} @@ -100,7 +113,12 @@ const TabSettings = ({ - {t("settingsAppearance")} + + {t("settingsAppearance")} + {t("statusPageCreateAppearanceDescription")} diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx index 5f5433bb6..936a22130 100644 --- a/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx +++ b/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx @@ -23,7 +23,6 @@ const Tabs = ({ setTab, TAB_LIST, }) => { - const theme = useTheme(); return ( @@ -63,7 +62,6 @@ const Tabs = ({ setSelectedMonitors={setSelectedMonitors} /> )} - ); }; diff --git a/client/src/Pages/StatusPage/Create/index.jsx b/client/src/Pages/StatusPage/Create/index.jsx index 5f56418fa..d1bb8d196 100644 --- a/client/src/Pages/StatusPage/Create/index.jsx +++ b/client/src/Pages/StatusPage/Create/index.jsx @@ -194,7 +194,7 @@ const CreateStatusPage = () => { color: statusPage?.color, logo: newLogo, showCharts: statusPage?.showCharts ?? true, - showUptimePercentage: statusPage?.showUptimePercentage ?? true + showUptimePercentage: statusPage?.showUptimePercentage ?? true, }; }); setSelectedMonitors(statusPageMonitors); diff --git a/client/src/Pages/StatusPage/Status/index.jsx b/client/src/Pages/StatusPage/Status/index.jsx index bc81bb23c..341c6d731 100644 --- a/client/src/Pages/StatusPage/Status/index.jsx +++ b/client/src/Pages/StatusPage/Status/index.jsx @@ -34,7 +34,7 @@ const PublicStatus = () => { const [statusPage, monitors, isLoading, networkError, fetchStatusPage] = useStatusPageFetch(false, url); const [deleteStatusPage, isDeleting] = useStatusPageDelete(fetchStatusPage, url); - + // Breadcrumbs const crumbs = [ { name: t("statusBreadCrumbsStatusPages"), path: "/status" }, diff --git a/client/src/Pages/Uptime/BulkImport/Upload.jsx b/client/src/Pages/Uptime/BulkImport/Upload.jsx index 9f49b54bc..261dcffe6 100644 --- a/client/src/Pages/Uptime/BulkImport/Upload.jsx +++ b/client/src/Pages/Uptime/BulkImport/Upload.jsx @@ -4,7 +4,8 @@ import { Button, Typography } from "@mui/material"; import { useTranslation } from "react-i18next"; import PropTypes from "prop-types"; -const UploadFile = ({ onFileSelect }) => { // Changed prop to onFileSelect +const UploadFile = ({ onFileSelect }) => { + // Changed prop to onFileSelect const theme = useTheme(); const [file, setFile] = useState(); const [error, setError] = useState(""); @@ -18,17 +19,17 @@ const UploadFile = ({ onFileSelect }) => { // Changed prop to onFileSelect const handleFileChange = (e) => { setError(""); const selectedFile = e.target.files[0]; - + // Basic file validation if (!selectedFile) return; - - if (!selectedFile.name.endsWith('.csv')) { + + if (!selectedFile.name.endsWith(".csv")) { setError(t("bulkImport.invalidFileType")); return; } - + setFile(selectedFile); - onFileSelect(selectedFile); // Pass the file directly to parent + onFileSelect(selectedFile); // Pass the file directly to parent }; return ( @@ -63,11 +64,10 @@ const UploadFile = ({ onFileSelect }) => { // Changed prop to onFileSelect ); -} - +}; UploadFile.prototype = { onFileSelect: PropTypes.func.isRequired, }; -export default UploadFile; \ No newline at end of file +export default UploadFile; diff --git a/client/src/Pages/Uptime/BulkImport/index.jsx b/client/src/Pages/Uptime/BulkImport/index.jsx index b3a825740..99a6d51d8 100644 --- a/client/src/Pages/Uptime/BulkImport/index.jsx +++ b/client/src/Pages/Uptime/BulkImport/index.jsx @@ -61,7 +61,12 @@ const BulkImport = () => { - {t("bulkImport.selectFileTips")} + + {t("bulkImport.selectFileTips")} + { - {t("settingsGeneralSettings")} + + {t("settingsGeneralSettings")} + {t("distributedUptimeCreateSelectURL")} @@ -389,7 +394,10 @@ const Configure = () => { - + {t("distributedUptimeCreateIncidentNotification")} @@ -457,7 +465,12 @@ const Configure = () => { - {t("ignoreTLSError")} + + {t("ignoreTLSError")} + {t("ignoreTLSErrorDescription")} @@ -477,7 +490,10 @@ const Configure = () => { - + {t("distributedUptimeCreateAdvancedSettings")} diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx index f35a09d9c..65a025b83 100644 --- a/client/src/Pages/Uptime/Create/index.jsx +++ b/client/src/Pages/Uptime/Create/index.jsx @@ -261,7 +261,12 @@ const CreateMonitor = () => { - {t("distributedUptimeCreateChecks")} + + {t("distributedUptimeCreateChecks")} + {t("distributedUptimeCreateChecksDescription")} @@ -342,7 +347,12 @@ const CreateMonitor = () => { - {t("settingsGeneralSettings")} + + {t("settingsGeneralSettings")} + {t("uptimeCreateSelectURL")} @@ -386,7 +396,10 @@ const CreateMonitor = () => { - + {t("distributedUptimeCreateIncidentNotification")} @@ -417,7 +430,12 @@ const CreateMonitor = () => { - {t("ignoreTLSError")} + + {t("ignoreTLSError")} + {t("ignoreTLSErrorDescription")} @@ -437,7 +455,10 @@ const CreateMonitor = () => { - + {t("distributedUptimeCreateAdvancedSettings")} diff --git a/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx b/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx index a6ef105b6..ba4a139e3 100644 --- a/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx +++ b/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx @@ -150,7 +150,10 @@ const UptimeDataTable = ({ id: "responseTime", content: t("responseTime"), render: (row) => ( - + ), diff --git a/client/src/Utils/NetworkService.js b/client/src/Utils/NetworkService.js index 767d36934..86c5bfa6f 100644 --- a/client/src/Utils/NetworkService.js +++ b/client/src/Utils/NetworkService.js @@ -1162,21 +1162,25 @@ class NetworkService { async sendTestEmail(config) { // Extract recipient and email configuration const { to, emailConfig } = config; - + // If emailConfig is provided, use the new endpoint with direct parameters if (emailConfig) { - return this.axiosInstance.post(`/settings/test-email`, { + return this.axiosInstance.post(`/settings/test-email`, { to, systemEmailHost: emailConfig.systemEmailHost, systemEmailPort: emailConfig.systemEmailPort, systemEmailAddress: emailConfig.systemEmailAddress, systemEmailPassword: emailConfig.systemEmailPassword, // Only include these if they are present - ...(emailConfig.systemEmailConnectionHost && { systemEmailConnectionHost: emailConfig.systemEmailConnectionHost }), - ...(emailConfig.systemEmailUser && { systemEmailUser: emailConfig.systemEmailUser }) + ...(emailConfig.systemEmailConnectionHost && { + systemEmailConnectionHost: emailConfig.systemEmailConnectionHost, + }), + ...(emailConfig.systemEmailUser && { + systemEmailUser: emailConfig.systemEmailUser, + }), }); } - + // Fallback to original behavior for backward compatibility return this.axiosInstance.post(`/settings/test-email`, { to }); } diff --git a/client/src/Utils/greeting.jsx b/client/src/Utils/greeting.jsx index 269d4c73b..d2b7fa033 100644 --- a/client/src/Utils/greeting.jsx +++ b/client/src/Utils/greeting.jsx @@ -167,7 +167,7 @@ const Greeting = ({ type = "" }) => { fontSize="inherit" color={theme.palette.primary.contrastTextTertiary} > - {t("greeting.prepend", { defaultValue: prepend })}, {" "} + {t("greeting.prepend", { defaultValue: prepend })},{" "} { lineHeight={1} color={theme.palette.primary.contrastTextTertiary} > - {t("greeting.append", { defaultValue: append })} — {t("greeting.overview", { type: t(`menu.${type}`) })} + {t("greeting.append", { defaultValue: append })} —{" "} + {t("greeting.overview", { type: t(`menu.${type}`) })} ); diff --git a/client/src/Validation/error.js b/client/src/Validation/error.js index 8f043f997..5738edf40 100644 --- a/client/src/Validation/error.js +++ b/client/src/Validation/error.js @@ -1,13 +1,12 @@ /** * Update errors if passed id matches the error.details[0].path, otherwise remove * the error for the id - * @param {*} prev Previous errors * + * @param {*} prev Previous errors * * @param {*} id ID of the field whose error is to be either updated or removed - * @param {*} error the error object + * @param {*} error the error object * @returns the Update Errors with the specific field with id being either removed or updated */ - const buildErrors = (prev, id, error) => { const updatedErrors = { ...prev }; if (error && id == error.details[0].path) { @@ -43,7 +42,7 @@ const getTouchedFieldErrors = (validation, touchedErrors) => { return newErrors; }; /** - * + * * @param {*} form The form object of the submitted form data * @param {*} validation The Joi validation rules * @param {*} setErrors The function used to set the local errors @@ -69,7 +68,7 @@ const hasValidationErrors = (form, validation, setErrors) => { "_id", "__v", "createdAt", - "updatedAt" + "updatedAt", ].includes(err.path[0]) ) { newErrors[err.path[0]] = err.message ?? "Validation error"; diff --git a/client/src/index.css b/client/src/index.css index 173551ba6..f83cdc461 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -52,8 +52,8 @@ html { --env-var-default-1: 24px; --env-var-default-2: 40px; - --env-var-shadow-1: 0px 4px 24px -4px rgba(16, 24, 40, 0.08), - 0px 3px 3px -3px rgba(16, 24, 40, 0.03); + --env-var-shadow-1: + 0px 4px 24px -4px rgba(16, 24, 40, 0.08), 0px 3px 3px -3px rgba(16, 24, 40, 0.03); } .MuiInputBase-root.Mui-disabled input { diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index 4b73daa54..4bd71e9c6 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -549,7 +549,7 @@ "sendTestEmail": "Send test email", "emailSent": "Email sent successfully", "failedToSendEmail": "Failed to send email", - "statusMsg" : { + "statusMsg": { "paused": "Monitoring is paused.", "up": "Your site is up.", "down": "Your site is down.", diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index d18d5f007..c2321f4ab 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -1,503 +1,503 @@ { - "dontHaveAccount": "Нет аккаунта", - "doNotHaveAccount": "У вас нет учетной записи?", - "registerHere": "Зарегистрироваться здесь", - "email": "Почта", - "forgotPassword": "Забыли пароль", - "password": "Пароль", - "signUp": "Зарегистрироваться", - "submit": "Подтвердить", - "title": "Название", - "continue": "Продолжить", - "enterEmail": "Введите свой email", - "authLoginTitle": "Войти", - "authLoginEnterPassword": "Введите свой пароль", - "commonPassword": "Пароль", - "commonBack": "Назад", - "authForgotPasswordTitle": "Забыли пароль?", - "authForgotPasswordResetPassword": "Сбросить пароль", - "authForgotPasswordInstructions": "Не волнуйтесь, мы отправим вам инструкции по сбросу.", - "createPassword": "Создайте свой пароль", - "createAPassword": "Пароль", - "authRegisterAlreadyHaveAccount": "Уже есть аккаунт?", - "authRegisterLoginLink": "Войти", - "commonAppName": "Checkmate", - "welcomeBack": "Добро пожаловать обратно! Вы успешно вошли в систему.", - "authLoginEnterEmail": "Введите свой email", - "authRegisterTitle": "Создать аккаунт", - "authRegisterStepOneTitle": "Создайте свой аккаут", - "authRegisterStepOneDescription": "Введите свои данные, чтобы начать", - "authRegisterStepTwoTitle": "Настройте свой профиль", - "authRegisterStepTwoDescription": "Расскажите нам о себе", - "authRegisterStepThreeTitle": "Почти готово!", - "authRegisterStepThreeDescription": "Проверьте свою информацию", - "authForgotPasswordDescription": "Не волнуйтесь, мы вышлем вам инструкции по сбросу настроек.", - "authForgotPasswordSendInstructions": "Отправить инструкции", - "authForgotPasswordBackTo": "Назад к", - "authCheckEmailTitle": "Проверьте свою почту", - "authCheckEmailDescription": "Мы отправили ссылку для сброса пароля", - "authCheckEmailResendEmail": "Отправить письмо повторно", - "authCheckEmailBackTo": "Назад к", - "goBackTo": "Назад к", - "authCheckEmailDidntReceiveEmail": "Не получили письмо?", - "authCheckEmailClickToResend": "Нажмите, чтобы отправить повторно", - "authSetNewPasswordTitle": "Установите новый пароль", - "authSetNewPasswordDescription": "Ваш новый пароль должен отличаться от ранее использованных паролей.", - "authSetNewPasswordNewPassword": "Новый пароль", - "authSetNewPasswordConfirmPassword": "Подтвердите пароль", - "confirmPassword": "Введите пароль еще раз для подтверждения", - "confirmNewPasswordPlaceholder": "Подтвердите ваш новый пароль", - "authSetNewPasswordResetPassword": "Сбросить пароль", - "authSetNewPasswordBackTo": "Назад к", - "authPasswordMustBeAtLeast": "Должно быть как минимум", - "authPasswordCharactersLong": "длиной 8 символов", - "authPasswordMustContainAtLeast": "Должен содержать как минимум", - "authPasswordSpecialCharacter": "один специальный символ", - "authPasswordOneNumber": "одно число", - "authPasswordUpperCharacter": "один верхний символ", - "authPasswordLowerCharacter": "один нижний символ", - "authPasswordConfirmAndPassword": "Подтвердите пароль и пароль", - "authPasswordMustMatch": "Пароли должны совпадать", - "authRegisterCreateAccount": "Создайте свою учетную запись, чтобы начать", - "authRegisterCreateSuperAdminAccount": "Создайте учетную запись суперадминистратора, чтобы начать работу", - "authRegisterSignUpWithEmail": "Создать учетную запись суперадминистратора", - "authRegisterBySigningUp": "Создавая учетную запись, вы соглашаетесь с нашими Условиями использования и Политикой конфиденциальности.", - "authRegisterFirstName": "Имя", - "authRegisterLastName": "Фамилия", - "authRegisterEmail": "Эл. почта", - "authRegisterEmailRequired": "Чтобы продолжить, пожалуйста, введите ваш адрес электронной почты", - "authRegisterEmailInvalid": "Пожалуйста, введите действительный адрес электронной почты", - "bulkImport": { - "title": "Массовый импорт", - "selectFileTips": "Выберите CSV-файл для загрузки", - "selectFileDescription": "Вы можете скачать наш или пример", - "selectFile": "Выбрать файл", - "parsingFailed": "Ошибка анализа", - "uploadSuccess": "Мониторы успешно созданы!", - "validationFailed": "Ошибка проверки", - "noFileSelected": "Файл не выбран", - "fallbackPage": "Импортируйте файл для загрузки списка серверов" - }, - "distributedStatusHeaderText": "Охват реального времени и реального устройства", - "distributedStatusSubHeaderText": "Работает на миллионах устройств по всему миру, просматривайте производительность системы по глобальному региону, стране или городу", - "settingsGeneralSettings": "Общие настройки", - "settingsDisplayTimezone": "Отображать часовой пояс", - "settingsDisplayTimezoneDescription": "Выберите часовой пояс, используемый для отображения дат и времени в приложении.", - "settingsAppearance": "Внешний вид", - "settingsAppearanceDescription": "Переключение между светлым и темным режимом или изменение языка пользовательского интерфейса", - "settingsThemeMode": "Тема", - "settingsThemeModeLight": "Светлая", - "settingsThemeModeDark": "Тёмная", - "settingsLanguage": "Язык", - "settingsURLTitle": "Отображать IP/URL на странице статуса", - "settingsURLDescription": "Отображать IP-адрес или URL-адрес монитора на общедоступной странице статуса. Если отключено, будет отображаться только имя монитора для защиты конфиденциальной информации.", - "settingsURLSelectTitle": "Показать IP/URL на странице статуса", - "settingsURLEnabled": "Включено", - "settingURLDisabled": "Отключено", - "settingsDistributedUptime": "Distributed uptime", - "settingsDistributedUptimeDescription": "Включить/выключить distributed uptime monitoring.", - "settingsEnabled": "Включено", - "settingsDisabled": "Выключено", - "settingsHistoryAndMonitoring": "История мониторинга", - "settingsHistoryAndMonitoringDescription": "Определите, как долго вы хотите хранить исторические данные. Вы также можете очистить все существующие данные.", - "settingsTTLLabel": "Дни, за которыми вы хотите следить.", - "settingsTTLOptionalLabel": "0 для бесконечности", - "settingsClearAllStats": "Очистить всю статистику. Это необратимо.", - "settingsClearAllStatsButton": "Очистить всю статистику", - "settingsClearAllStatsDialogTitle": "Хотите очистить всю статистику?", - "settingsClearAllStatsDialogDescription": "После удаления история мониторинга и статистика не могут быть восстановлены.", - "settingsClearAllStatsDialogConfirm": "Да, очистить всю статистику", - "settingsClearAllStatsDialogCancel": "Отмена", - "settingsDemoMonitors": "Демо мониторы", - "settingsDemoMonitorsDescription": "Добавьте примеры мониторов для демонстрации.", - "settingsAddDemoMonitors": "Добавление демонстрационных мониторов", - "settingsAddDemoMonitorsButton": "Добавьте демонстрационные мониторы", - "settingsSystemReset": "Сброс системы", - "settingsSystemResetDescription": "Удалить все мониторы из вашей системы.", - "settingsRemoveAllMonitors": "Удаление всех мониторов", - "settingsRemoveAllMonitorsButton": "Удалить все мониторы", - "settingsRemoveAllMonitorsDialogTitle": "Хотите удалить все мониторы?", - "settingsRemoveAllMonitorsDialogConfirm": "Да, удалить все мониторы", - "settingsWallet": "Кошелёк", - "settingsWalletDescription": "Подключите свой кошелек здесь. Это необходимо для того, чтобы монитор Distributed Uptime мог подключиться к нескольким узлам по всему миру.", - "settingsEmail": "Настройки электронной почты", - "settingsEmailDescription": "Настройте параметры электронной почты", - "settingsEmailHost": "Хост электронной почты - имя хоста или IP-адрес SMTP-сервера", - "settingsEmailPort": "Порт электронной почты - порт для подключения", - "settingsEmailAddress": "Адрес электронной почты - используется для аутентификации", - "settingsEmailPassword": "Пароль электронной почты - пароль для аутентификации", - "settingsEmailUser": "Пользователь электронной почты - имя пользователя для аутентификации, переопределяет адрес электронной почты, если указан", - "settingsEmailFieldResetLabel": "Пароль установлен. Нажмите «Сбросить», чтобы изменить его.", - "settingsEmailConnectionHost": "Хост подключения электронной почты - имя хоста, используемое в приветствии HELO/EHLO", - "settingsTestEmail": "Отправить тестовое письмо", - "settingsTestEmailSuccess": "Тестовое письмо успешно отправлено", - "settingsTestEmailFailed": "Не удалось отправить тестовое письмо", - "settingsTestEmailFailedWithReason": "Не удалось отправить тестовое письмо: {{reason}}", - "settingsTestEmailUnknownError": "Неизвестная ошибка", - "settingsEmailRequiredFields": "Требуются хост и порт электронной почты", - "settingsAbout": "О", - "settingsDevelopedBy": "Developed by Bluewave Labs.", - "settingsSave": "Сохранить", - "commonSave": "Сохранить", - "commonSaving": "Сохранение...", - "settingsSuccessSaved": "Настройки успешно сохранены", - "settingsFailedToSave": "Не удалось сохранить настройки", - "settingsStatsCleared": "Статистика успешно очищена", - "settingsFailedToClearStats": "Не удалось очистить статистику", - "FirstName": "Имя", - "LastName": "Фамилия", - "YourPhoto": "Фото профиля", - "PhotoDescriptionText": "Это фото будет отображаться на странице вашего профиля.", - "EmailDescriptionText": "Ваш текущий email—его нельзя изменить.", - "DeleteAccountTitle": "Удалить аккаунт", - "DeleteAccountButton": "Удалить аккаунт", - "DeleteDescriptionText": "Это удалит аккаунт и все связанные данные с сервера. Это необратимо.", - "DeleteAccountWarning": "Удаление аккаунта означает, что вы не сможете снова войти в систему, и все ваши данные будут удалены. Это необратимо.", - "DeleteWarningTitle": "Действительно удалить этот аккаунт?", - "settingsDemoMonitorsAdded": "Успешно добавлены демонстрационные мониторы", - "settingsFailedToAddDemoMonitors": "Не удалось добавить демонстрационные мониторы", - "settingsMonitorsDeleted": "Успешно удалены все мониторы", - "settingsFailedToDeleteMonitors": "Не удалось удалить все мониторы", - "backendUnreachable": "Ошибка подключения к серверу", - "backendUnreachableMessage": "Мы не можем подключиться к серверу. Пожалуйста, проверьте ваше интернет-соединение или проверьте конфигурацию развертывания, если проблема не устраняется.", - "backendUnreachableError": "Невозможно подключиться к серверу. Пожалуйста, повторите попытку позже.", - "retryConnection": "Повторить подключение", - "retryingConnection": "Подключение...", - "backendReconnected": "Успешно восстановлено подключение к серверу.", - "backendStillUnreachable": "Сервер по-прежнему недоступен. Пожалуйста, повторите попытку позже.", - "backendConnectionError": "Ошибка подключения к серверу. Пожалуйста, проверьте ваше сетевое подключение.", - "starPromptTitle": "Star Checkmate", - "starPromptDescription": "Ознакомьтесь с последними релизами и помогите развить сообщество на GitHub", - "https": "HTTPS", - "http": "HTTP", - "monitor": "монитор", - "aboutus": "О Нас", - "now": "Сейчас", - "delete": "Удалить", - "configure": "Настроить", - "networkError": "Ошибка сети", - "responseTime": "Время ответа", - "ms": "мс", - "bar": "Bar", - "area": "Area", - "country": "СТРАНА", - "city": "ГОРОД", - "response": "ОТВЕТ", - "checkConnection": "Пожалуйста, проверьте ваше соединение", - "passwordreset": "Сброс пароля", - "authRegisterStepOnePersonalDetails": "Введите свои личные данные", - "authCheckEmailOpenEmailButton": "Откройте приложение почты", - "authNewPasswordConfirmed": "Ваш пароль успешно сброшен. Нажмите ниже, чтобы войти в систему магическим образом.", - "monitorStatusUp": "Монитор {name} ({url}) теперь включен и отвечает", - "monitorStatusDown": "Монитор {name} ({url}) ОТКЛЮЧЕН и не отвечает", - "webhookSendSuccess": "Уведомление Webhook успешно отправлено", - "webhookSendError": "Ошибка отправки уведомления webhook на {platform}", - "webhookUnsupportedPlatform": "Неподдерживаемая платформа: {platform}", - "distributedRightCategoryTitle": "Монитор", - "distributedStatusServerMonitors": "Серверные мониторы", - "distributedStatusServerMonitorsDescription": "Мониторинг состояния связанных серверов", - "distributedUptimeCreateSelectURL": "Здесь вы можете выбрать URL-адрес хоста, а также тип монитора.", - "distributedUptimeCreateChecks": "Проверки, которые необходимо выполнить", - "distributedUptimeCreateChecksDescription": "Вы всегда можете добавить или удалить проверки после добавления своего сайта.", - "distributedUptimeCreateIncidentNotification": "Уведомления об инцидентах", - "distributedUptimeCreateIncidentDescription": "В случае возникновения инцидента сообщите об этом пользователям.", - "distributedUptimeCreateAdvancedSettings": "Расширенные настройки", - "distributedUptimeDetailsNoMonitorHistory": "Для этого монитора пока нет истории проверок.", - "distributedUptimeDetailsFooterHeading": "Made with ❤️ by UpRock & Bluewave Labs", - "distributedUptimeDetailsFooterBuilt": "Built on", - "distributedUptimeDetailsFooterSolana": "Solana", - "distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN", - "distributedUptimeDetailsStatusHeaderUptime": "Аптайм:", - "distributedUptimeDetailsStatusHeaderLastUpdate": "Последнее обновление", - "notifications": { - "enableNotifications": "Включить уведомления {{platform}}", - "testNotification": "Тестовое уведомление", - "addOrEditNotifications": "Добавить или изменить уведомления", - "slack": { - "label": "Slack", - "description": "Чтобы включить уведомления Slack, создайте приложение Slack и включите входящие вебхуки. После этого просто укажите URL вебхука здесь.", - "webhookLabel": "URL вебхука", - "webhookPlaceholder": "https://hooks.slack.com/services/..." - }, - "discord": { - "label": "Discord", - "description": "Чтобы отправить данные на канал Discord из Checkmate через уведомления Discord с использованием веб-хуков, вы можете использовать функцию входящих веб-хуков Discord.", - "webhookLabel": "Discord Webhook URL", - "webhookPlaceholder": "https://discord.com/api/webhooks/..." - }, - "telegram": { - "label": "Telegram", - "description": "Чтобы включить уведомления Telegram, создайте бота Telegram с помощью BotFather, официального бота для создания и управления ботами Telegram. Затем получите токен API и идентификатор чата и запишите их здесь.", - "tokenLabel": "Ваш токен бота", - "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", - "chatIdLabel": "ID Вашего Чата", - "chatIdPlaceholder": "-1001234567890" - }, - "webhook": { - "label": "Вебхуки", - "description": "Вы можете настроить пользовательский вебхук для получения уведомлений о возникновении инцидентов.", - "urlLabel": "URL вебхука", - "urlPlaceholder": "https://your-server.com/webhook" - }, - "testNotificationDevelop": "Тестовое уведомление 2", - "integrationButton": "" - }, - "testLocale": "testLocale", - "add": "Добавить", - "monitors": "мониторы", - "distributedUptimeStatusCreateStatusPage": "страница статуса", - "distributedUptimeStatusCreateStatusPageAccess": "Доступ", - "distributedUptimeStatusCreateStatusPageReady": "Если ваша страница статуса готова, вы можете отметить ее как опубликованную.", - "distributedUptimeStatusBasicInfoHeader": "Основная информация", - "distributedUptimeStatusBasicInfoDescription": "Определите название компании и поддомен, на который ссылается ваша страница статуса.", - "distributedUptimeStatusLogoHeader": "Логотип", - "distributedUptimeStatusLogoDescription": "Загрузите логотип для своей страницы статуса", - "distributedUptimeStatusLogoUploadButton": "Загрузить логотип", - "distributedUptimeStatusStandardMonitorsHeader": "Стандартные Мониторы", - "distributedUptimeStatusStandardMonitorsDescription": "Прикрепите стандартные мониторы к своей странице статуса.", - "distributedUptimeStatusCreateYour": "Создайте свой", - "distributedUptimeStatusEditYour": "Отредактируйте свой", - "distributedUptimeStatusPublishedLabel": "Опубликовано и доступно для общественности", - "distributedUptimeStatusCompanyNameLabel": "Название компании", - "distributedUptimeStatusPageAddressLabel": "Адрес вашей страницы статуса", - "distributedUptimeStatus30Days": "30 дней", - "distributedUptimeStatus60Days": "60 дней", - "distributedUptimeStatus90Days": "90 дней", - "distributedUptimeStatusPageNotSetUp": "Страница статуса не настроена.", - "distributedUptimeStatusContactAdmin": "Пожалуйста, свяжитесь с вашим администратором", - "distributedUptimeStatusPageNotPublic": "Эта страница статуса не является публичной.", - "distributedUptimeStatusPageDeleteDialog": "Вы хотите удалить эту страницу статуса?", - "distributedUptimeStatusPageDeleteConfirm": "Да, удалить страницу статуса", - "distributedUptimeStatusPageDeleteDescription": "После удаления ваша страница статуса не может быть восстановлена.", - "distributedUptimeStatusDevices": "Устройства", - "distributedUptimeStatusUpt": "UPT", - "distributedUptimeStatusUptBurned": "UPT Burned", - "distributedUptimeStatusUptLogo": "Upt Logo", - "incidentsTableNoIncidents": "Инцидентов не зафиксировано", - "incidentsTablePaginationLabel": "инциденты", - "incidentsTableMonitorName": "Имя Монитора", - "incidentsTableStatus": "Статус", - "incidentsTableDateTime": "Дата и Время", - "incidentsTableStatusCode": "Код Статуса", - "incidentsTableMessage": "Сообщение", - "incidentsOptionsHeader": "Инцидент для:", - "incidentsOptionsHeaderFilterBy": "Фильтровать по:", - "incidentsOptionsHeaderFilterAll": "Все", - "incidentsOptionsHeaderFilterDown": "Недоступно", - "incidentsOptionsHeaderFilterCannotResolve": "Невозможно решить", - "incidentsOptionsHeaderShow": "Показать:", - "incidentsOptionsHeaderLastHour": "Последний час", - "incidentsOptionsHeaderLastDay": "Последний день", - "incidentsOptionsHeaderLastWeek": "Последняя неделя", - "incidentsOptionsPlaceholderAllServers": "Все сервера", - "infrastructureCreateYour": "Создайте свой", - "infrastructureCreateGeneralSettingsDescription": "Здесь вы можете выбрать URL-адрес хоста, а также понятное имя и секретный ключ авторизации для подключения к агенту сервера.", - "infrastructureServerRequirement": "Сервер, который вы отслеживаете, должен быть запущен", - "infrastructureCustomizeAlerts": "Настройте оповещения", - "infrastructureAlertNotificationDescription": "Отправлять уведомления пользователям, когда пороговые значения превышают указанный процент.", - "infrastructureCreateMonitor": "Создать Монитор Инфраструктуры", - "infrastructureProtocol": "Протокол", - "infrastructureServerUrlLabel": "URL Сервера", - "infrastructureDisplayNameLabel": "Отображаемое имя", - "infrastructureAuthorizationSecretLabel": "Секрет авторизации", - "gb": "ГБ", - "mb": "МБ", - "mem": "Mem", - "memoryUsage": "Использование памяти", - "cpu": "CPU", - "cpuUsage": "Использование CPU", - "cpuTemperature": "Температура CPU", - "diskUsage": "Использование диска", - "used": "Использовал", - "total": "Всего", - "cores": "Ядра", - "frequency": "Частота", - "status": "Статус", - "cpuPhysical": "CPU (физический)", - "cpuLogical": "CPU (логический)", - "cpuFrequency": "Частота CPU", - "avgCpuTemperature": "Средняя температура CPU", - "memory": "Память", - "disk": "Диск", - "uptime": "Аптайм", - "os": "ОС", - "host": "Хост", - "actions": "Действия", - "integrations": "Интеграции", - "integrationsPrism": "Подключите Prism к вашему любимому сервису.", - "integrationsSlack": "Slack", - "integrationsSlackInfo": "Подключитесь к Slack и просматривайте инциденты в канале", - "integrationsDiscord": "Discord", - "integrationsDiscordInfo": "Подключитесь к Discord и просматривайте инциденты прямо в канале", - "integrationsZapier": "Zapier", - "integrationsZapierInfo": "Отправляйте все инциденты в Zapier, и тогда вы сможете видеть их везде", - "createYour": "", - "createMonitor": "", - "pause": "", - "resume": "", - "editing": "", - "url": "", - "access": "", - "timezone": "", - "features": "", - "administrator": "", - "loginHere": "", - "displayName": "", - "urlMonitor": "", - "portToMonitor": "", - "websiteMonitoring": "", - "websiteMonitoringDescription": "", - "pingMonitoring": "", - "pingMonitoringDescription": "", - "dockerContainerMonitoring": "", - "window": "", - "cancel": "", - "message": "", - "low": "", - "high": "", - "statusCode": "", - "date&Time": "", - "type": "", - "statusPageName": "", - "publicURL": "", - "repeat": "", - "edit": "", - "createA": "", - "remove": "", - "maintenanceWindowDescription": "", - "startTime": "", - "timeZoneInfo": "", - "monitorsToApply": "", - "nextWindow": "", - "notFoundButton": "", - "pageSpeedConfigureSettingsDescription": "", - "monitorDisplayName": "", - "whenNewIncident": "", - "notifySMS": "", - "notifyEmails": "", - "seperateEmails": "", - "checkFrequency": "", - "matchMethod": "", - "expectedValue": "", - "deleteDialogTitle": "", - "deleteDialogDescription": "", - "pageSpeedMonitor": "", - "shown": "", - "ago": "", - "companyName": "", - "pageSpeedDetailsPerformanceReport": "", - "pageSpeedDetailsPerformanceReportCalculator": "", - "checkingEvery": "", - "statusPageCreateSettings": "", - "basicInformation": "", - "statusPageCreateBasicInfoDescription": "", - "statusPageCreateSelectTimeZoneDescription": "", - "statusPageCreateAppearanceDescription": "", - "statusPageCreateSettingsCheckboxLabel": "", - "statusPageCreateBasicInfoStatusPageAddress": "", - "statusPageCreateTabsContent": "", - "statusPageCreateTabsContentDescription": "", - "statusPageCreateTabsContentFeaturesDescription": "", - "showCharts": "", - "showUptimePercentage": "", - "removeLogo": "", - "statusPageStatus": "", - "statusPageStatusContactAdmin": "", - "statusPageStatusNotPublic": "", - "statusPageStatusNoPage": "", - "statusPageStatusServiceStatus": "", - "deleteStatusPage": "", - "deleteStatusPageConfirm": "", - "deleteStatusPageDescription": "", - "uptimeCreate": "", - "uptimeCreateJsonPath": "", - "uptimeCreateJsonPathQuery": "", - "maintenanceTableActionMenuDialogTitle": "", - "incidentsPageTitle": "Инциденты", - "passwordPanel": { - "passwordChangedSuccess": "Ваш пароль был успешно изменен.", - "passwordInputIncorrect": "Ваш пароль введен неверно.", - "currentPassword": "Текущий пароль", - "enterCurrentPassword": "Введите ваш текущий пароль", - "newPassword": "Новый пароль", - "enterNewPassword": "Введите ваш новый пароль", - "confirmNewPassword": "Подтвердите новый пароль", - "passwordRequirements": "Новый пароль должен содержать не менее 8 символов и должен иметь как минимум одну заглавную букву, одну строчную букву, одну цифру и один специальный символ.", - "saving": "Сохранение..." - }, - "pageSpeedWarning": "Предупреждение: Вы не добавили ключ API Google PageSpeed. Без него монитор PageSpeed не будет работать.", - "pageSpeedLearnMoreLink": "Нажмите здесь, чтобы узнать", - "pageSpeedAddApiKey": "как добавить ваш ключ API.", - "pageSpeedApiKeyFieldTitle": "Ключ Google PageSpeed API", - "pageSpeedApiKeyFieldLabel": "Ключ PageSpeed API", - "pageSpeedApiKeyFieldDescription": "Введите свой ключ Google PageSpeed API, чтобы включить мониторинг скорости страниц. Нажмите «Сбросить», чтобы обновить ключ.", - "pageSpeedApiKeyFieldResetLabel": "Ключ API установлен. Нажмите «Сбросить», чтобы изменить его.", - "createNew": "Создать новый", - "greeting": { - "prepend": "Привет", - "append": "День прекрасен для новых достижений!", - "overview": "Вот обзор ваших мониторов {{type}}." - }, - "monitorStatus": { - "up": "работает", - "down": "не работает", - "paused": "приостановлен" - }, - "roles": { - "superAdmin": "Суперадминистратор", - "admin": "Администратор", - "teamMember": "Член команды", - "demoUser": "Демо-пользователь" - }, - "teamPanel": { - "teamMembers": "Члены команды", - "filter": { - "all": "Все", - "member": "Член" - }, - "inviteTeamMember": "Пригласить члена команды", - "inviteNewTeamMember": "Пригласить нового члена команды", - "inviteDescription": "Когда вы добавляете нового члена команды, он получит доступ ко всем мониторам.", - "email": "Эл. почта", - "selectRole": "Выберите роль", - "inviteLink": "Ссылка для приглашения", - "cancel": "Отмена", - "noMembers": "Нет членов команды с этой ролью", - "getToken": "Получить токен", - "emailToken": "Отправить токен по эл. почте", - "table": { - "name": "Имя", - "email": "Эл. почта", - "role": "Роль", - "created": "Создан" - } - }, - "monitorState": { - "paused": "приостановлен", - "resumed": "возобновлен", - "active": "активный" - }, - "menu": { - "uptime": "Аптайм", - "pagespeed": "Скорость страницы", - "infrastructure": "Инфраструктура", - "distributedUptime": "Распределенный Аптайм", - "incidents": "Инциденты", - "statusPages": "Страницы статуса", - "maintenance": "Обслуживание", - "integrations": "Интеграции", - "settings": "Настройки", - "support": "Поддержка", - "profile": "Профиль", - "password": "Пароль", - "team": "Команда", - "logOut": "Выйти", - "discussions": "Обсуждения", - "docs": "Документация", - "changelog": "История изменений" - }, - "navControls": "Управление", - "statusBreadCrumbsStatusPages": "Страницы статуса", - "statusBreadCrumbsDetails": "Подробности", - "uptimeCreateSelectURL": "Введите URL или IP для мониторинга (например, https://example.com/ или 192.168.1.100) и добавьте понятное отображаемое имя, которое будет показано на панели управления." -} \ No newline at end of file + "dontHaveAccount": "Нет аккаунта", + "doNotHaveAccount": "У вас нет учетной записи?", + "registerHere": "Зарегистрироваться здесь", + "email": "Почта", + "forgotPassword": "Забыли пароль", + "password": "Пароль", + "signUp": "Зарегистрироваться", + "submit": "Подтвердить", + "title": "Название", + "continue": "Продолжить", + "enterEmail": "Введите свой email", + "authLoginTitle": "Войти", + "authLoginEnterPassword": "Введите свой пароль", + "commonPassword": "Пароль", + "commonBack": "Назад", + "authForgotPasswordTitle": "Забыли пароль?", + "authForgotPasswordResetPassword": "Сбросить пароль", + "authForgotPasswordInstructions": "Не волнуйтесь, мы отправим вам инструкции по сбросу.", + "createPassword": "Создайте свой пароль", + "createAPassword": "Пароль", + "authRegisterAlreadyHaveAccount": "Уже есть аккаунт?", + "authRegisterLoginLink": "Войти", + "commonAppName": "Checkmate", + "welcomeBack": "Добро пожаловать обратно! Вы успешно вошли в систему.", + "authLoginEnterEmail": "Введите свой email", + "authRegisterTitle": "Создать аккаунт", + "authRegisterStepOneTitle": "Создайте свой аккаут", + "authRegisterStepOneDescription": "Введите свои данные, чтобы начать", + "authRegisterStepTwoTitle": "Настройте свой профиль", + "authRegisterStepTwoDescription": "Расскажите нам о себе", + "authRegisterStepThreeTitle": "Почти готово!", + "authRegisterStepThreeDescription": "Проверьте свою информацию", + "authForgotPasswordDescription": "Не волнуйтесь, мы вышлем вам инструкции по сбросу настроек.", + "authForgotPasswordSendInstructions": "Отправить инструкции", + "authForgotPasswordBackTo": "Назад к", + "authCheckEmailTitle": "Проверьте свою почту", + "authCheckEmailDescription": "Мы отправили ссылку для сброса пароля", + "authCheckEmailResendEmail": "Отправить письмо повторно", + "authCheckEmailBackTo": "Назад к", + "goBackTo": "Назад к", + "authCheckEmailDidntReceiveEmail": "Не получили письмо?", + "authCheckEmailClickToResend": "Нажмите, чтобы отправить повторно", + "authSetNewPasswordTitle": "Установите новый пароль", + "authSetNewPasswordDescription": "Ваш новый пароль должен отличаться от ранее использованных паролей.", + "authSetNewPasswordNewPassword": "Новый пароль", + "authSetNewPasswordConfirmPassword": "Подтвердите пароль", + "confirmPassword": "Введите пароль еще раз для подтверждения", + "confirmNewPasswordPlaceholder": "Подтвердите ваш новый пароль", + "authSetNewPasswordResetPassword": "Сбросить пароль", + "authSetNewPasswordBackTo": "Назад к", + "authPasswordMustBeAtLeast": "Должно быть как минимум", + "authPasswordCharactersLong": "длиной 8 символов", + "authPasswordMustContainAtLeast": "Должен содержать как минимум", + "authPasswordSpecialCharacter": "один специальный символ", + "authPasswordOneNumber": "одно число", + "authPasswordUpperCharacter": "один верхний символ", + "authPasswordLowerCharacter": "один нижний символ", + "authPasswordConfirmAndPassword": "Подтвердите пароль и пароль", + "authPasswordMustMatch": "Пароли должны совпадать", + "authRegisterCreateAccount": "Создайте свою учетную запись, чтобы начать", + "authRegisterCreateSuperAdminAccount": "Создайте учетную запись суперадминистратора, чтобы начать работу", + "authRegisterSignUpWithEmail": "Создать учетную запись суперадминистратора", + "authRegisterBySigningUp": "Создавая учетную запись, вы соглашаетесь с нашими Условиями использования и Политикой конфиденциальности.", + "authRegisterFirstName": "Имя", + "authRegisterLastName": "Фамилия", + "authRegisterEmail": "Эл. почта", + "authRegisterEmailRequired": "Чтобы продолжить, пожалуйста, введите ваш адрес электронной почты", + "authRegisterEmailInvalid": "Пожалуйста, введите действительный адрес электронной почты", + "bulkImport": { + "title": "Массовый импорт", + "selectFileTips": "Выберите CSV-файл для загрузки", + "selectFileDescription": "Вы можете скачать наш или пример", + "selectFile": "Выбрать файл", + "parsingFailed": "Ошибка анализа", + "uploadSuccess": "Мониторы успешно созданы!", + "validationFailed": "Ошибка проверки", + "noFileSelected": "Файл не выбран", + "fallbackPage": "Импортируйте файл для загрузки списка серверов" + }, + "distributedStatusHeaderText": "Охват реального времени и реального устройства", + "distributedStatusSubHeaderText": "Работает на миллионах устройств по всему миру, просматривайте производительность системы по глобальному региону, стране или городу", + "settingsGeneralSettings": "Общие настройки", + "settingsDisplayTimezone": "Отображать часовой пояс", + "settingsDisplayTimezoneDescription": "Выберите часовой пояс, используемый для отображения дат и времени в приложении.", + "settingsAppearance": "Внешний вид", + "settingsAppearanceDescription": "Переключение между светлым и темным режимом или изменение языка пользовательского интерфейса", + "settingsThemeMode": "Тема", + "settingsThemeModeLight": "Светлая", + "settingsThemeModeDark": "Тёмная", + "settingsLanguage": "Язык", + "settingsURLTitle": "Отображать IP/URL на странице статуса", + "settingsURLDescription": "Отображать IP-адрес или URL-адрес монитора на общедоступной странице статуса. Если отключено, будет отображаться только имя монитора для защиты конфиденциальной информации.", + "settingsURLSelectTitle": "Показать IP/URL на странице статуса", + "settingsURLEnabled": "Включено", + "settingURLDisabled": "Отключено", + "settingsDistributedUptime": "Distributed uptime", + "settingsDistributedUptimeDescription": "Включить/выключить distributed uptime monitoring.", + "settingsEnabled": "Включено", + "settingsDisabled": "Выключено", + "settingsHistoryAndMonitoring": "История мониторинга", + "settingsHistoryAndMonitoringDescription": "Определите, как долго вы хотите хранить исторические данные. Вы также можете очистить все существующие данные.", + "settingsTTLLabel": "Дни, за которыми вы хотите следить.", + "settingsTTLOptionalLabel": "0 для бесконечности", + "settingsClearAllStats": "Очистить всю статистику. Это необратимо.", + "settingsClearAllStatsButton": "Очистить всю статистику", + "settingsClearAllStatsDialogTitle": "Хотите очистить всю статистику?", + "settingsClearAllStatsDialogDescription": "После удаления история мониторинга и статистика не могут быть восстановлены.", + "settingsClearAllStatsDialogConfirm": "Да, очистить всю статистику", + "settingsClearAllStatsDialogCancel": "Отмена", + "settingsDemoMonitors": "Демо мониторы", + "settingsDemoMonitorsDescription": "Добавьте примеры мониторов для демонстрации.", + "settingsAddDemoMonitors": "Добавление демонстрационных мониторов", + "settingsAddDemoMonitorsButton": "Добавьте демонстрационные мониторы", + "settingsSystemReset": "Сброс системы", + "settingsSystemResetDescription": "Удалить все мониторы из вашей системы.", + "settingsRemoveAllMonitors": "Удаление всех мониторов", + "settingsRemoveAllMonitorsButton": "Удалить все мониторы", + "settingsRemoveAllMonitorsDialogTitle": "Хотите удалить все мониторы?", + "settingsRemoveAllMonitorsDialogConfirm": "Да, удалить все мониторы", + "settingsWallet": "Кошелёк", + "settingsWalletDescription": "Подключите свой кошелек здесь. Это необходимо для того, чтобы монитор Distributed Uptime мог подключиться к нескольким узлам по всему миру.", + "settingsEmail": "Настройки электронной почты", + "settingsEmailDescription": "Настройте параметры электронной почты", + "settingsEmailHost": "Хост электронной почты - имя хоста или IP-адрес SMTP-сервера", + "settingsEmailPort": "Порт электронной почты - порт для подключения", + "settingsEmailAddress": "Адрес электронной почты - используется для аутентификации", + "settingsEmailPassword": "Пароль электронной почты - пароль для аутентификации", + "settingsEmailUser": "Пользователь электронной почты - имя пользователя для аутентификации, переопределяет адрес электронной почты, если указан", + "settingsEmailFieldResetLabel": "Пароль установлен. Нажмите «Сбросить», чтобы изменить его.", + "settingsEmailConnectionHost": "Хост подключения электронной почты - имя хоста, используемое в приветствии HELO/EHLO", + "settingsTestEmail": "Отправить тестовое письмо", + "settingsTestEmailSuccess": "Тестовое письмо успешно отправлено", + "settingsTestEmailFailed": "Не удалось отправить тестовое письмо", + "settingsTestEmailFailedWithReason": "Не удалось отправить тестовое письмо: {{reason}}", + "settingsTestEmailUnknownError": "Неизвестная ошибка", + "settingsEmailRequiredFields": "Требуются хост и порт электронной почты", + "settingsAbout": "О", + "settingsDevelopedBy": "Developed by Bluewave Labs.", + "settingsSave": "Сохранить", + "commonSave": "Сохранить", + "commonSaving": "Сохранение...", + "settingsSuccessSaved": "Настройки успешно сохранены", + "settingsFailedToSave": "Не удалось сохранить настройки", + "settingsStatsCleared": "Статистика успешно очищена", + "settingsFailedToClearStats": "Не удалось очистить статистику", + "FirstName": "Имя", + "LastName": "Фамилия", + "YourPhoto": "Фото профиля", + "PhotoDescriptionText": "Это фото будет отображаться на странице вашего профиля.", + "EmailDescriptionText": "Ваш текущий email—его нельзя изменить.", + "DeleteAccountTitle": "Удалить аккаунт", + "DeleteAccountButton": "Удалить аккаунт", + "DeleteDescriptionText": "Это удалит аккаунт и все связанные данные с сервера. Это необратимо.", + "DeleteAccountWarning": "Удаление аккаунта означает, что вы не сможете снова войти в систему, и все ваши данные будут удалены. Это необратимо.", + "DeleteWarningTitle": "Действительно удалить этот аккаунт?", + "settingsDemoMonitorsAdded": "Успешно добавлены демонстрационные мониторы", + "settingsFailedToAddDemoMonitors": "Не удалось добавить демонстрационные мониторы", + "settingsMonitorsDeleted": "Успешно удалены все мониторы", + "settingsFailedToDeleteMonitors": "Не удалось удалить все мониторы", + "backendUnreachable": "Ошибка подключения к серверу", + "backendUnreachableMessage": "Мы не можем подключиться к серверу. Пожалуйста, проверьте ваше интернет-соединение или проверьте конфигурацию развертывания, если проблема не устраняется.", + "backendUnreachableError": "Невозможно подключиться к серверу. Пожалуйста, повторите попытку позже.", + "retryConnection": "Повторить подключение", + "retryingConnection": "Подключение...", + "backendReconnected": "Успешно восстановлено подключение к серверу.", + "backendStillUnreachable": "Сервер по-прежнему недоступен. Пожалуйста, повторите попытку позже.", + "backendConnectionError": "Ошибка подключения к серверу. Пожалуйста, проверьте ваше сетевое подключение.", + "starPromptTitle": "Star Checkmate", + "starPromptDescription": "Ознакомьтесь с последними релизами и помогите развить сообщество на GitHub", + "https": "HTTPS", + "http": "HTTP", + "monitor": "монитор", + "aboutus": "О Нас", + "now": "Сейчас", + "delete": "Удалить", + "configure": "Настроить", + "networkError": "Ошибка сети", + "responseTime": "Время ответа", + "ms": "мс", + "bar": "Bar", + "area": "Area", + "country": "СТРАНА", + "city": "ГОРОД", + "response": "ОТВЕТ", + "checkConnection": "Пожалуйста, проверьте ваше соединение", + "passwordreset": "Сброс пароля", + "authRegisterStepOnePersonalDetails": "Введите свои личные данные", + "authCheckEmailOpenEmailButton": "Откройте приложение почты", + "authNewPasswordConfirmed": "Ваш пароль успешно сброшен. Нажмите ниже, чтобы войти в систему магическим образом.", + "monitorStatusUp": "Монитор {name} ({url}) теперь включен и отвечает", + "monitorStatusDown": "Монитор {name} ({url}) ОТКЛЮЧЕН и не отвечает", + "webhookSendSuccess": "Уведомление Webhook успешно отправлено", + "webhookSendError": "Ошибка отправки уведомления webhook на {platform}", + "webhookUnsupportedPlatform": "Неподдерживаемая платформа: {platform}", + "distributedRightCategoryTitle": "Монитор", + "distributedStatusServerMonitors": "Серверные мониторы", + "distributedStatusServerMonitorsDescription": "Мониторинг состояния связанных серверов", + "distributedUptimeCreateSelectURL": "Здесь вы можете выбрать URL-адрес хоста, а также тип монитора.", + "distributedUptimeCreateChecks": "Проверки, которые необходимо выполнить", + "distributedUptimeCreateChecksDescription": "Вы всегда можете добавить или удалить проверки после добавления своего сайта.", + "distributedUptimeCreateIncidentNotification": "Уведомления об инцидентах", + "distributedUptimeCreateIncidentDescription": "В случае возникновения инцидента сообщите об этом пользователям.", + "distributedUptimeCreateAdvancedSettings": "Расширенные настройки", + "distributedUptimeDetailsNoMonitorHistory": "Для этого монитора пока нет истории проверок.", + "distributedUptimeDetailsFooterHeading": "Made with ❤️ by UpRock & Bluewave Labs", + "distributedUptimeDetailsFooterBuilt": "Built on", + "distributedUptimeDetailsFooterSolana": "Solana", + "distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN", + "distributedUptimeDetailsStatusHeaderUptime": "Аптайм:", + "distributedUptimeDetailsStatusHeaderLastUpdate": "Последнее обновление", + "notifications": { + "enableNotifications": "Включить уведомления {{platform}}", + "testNotification": "Тестовое уведомление", + "addOrEditNotifications": "Добавить или изменить уведомления", + "slack": { + "label": "Slack", + "description": "Чтобы включить уведомления Slack, создайте приложение Slack и включите входящие вебхуки. После этого просто укажите URL вебхука здесь.", + "webhookLabel": "URL вебхука", + "webhookPlaceholder": "https://hooks.slack.com/services/..." + }, + "discord": { + "label": "Discord", + "description": "Чтобы отправить данные на канал Discord из Checkmate через уведомления Discord с использованием веб-хуков, вы можете использовать функцию входящих веб-хуков Discord.", + "webhookLabel": "Discord Webhook URL", + "webhookPlaceholder": "https://discord.com/api/webhooks/..." + }, + "telegram": { + "label": "Telegram", + "description": "Чтобы включить уведомления Telegram, создайте бота Telegram с помощью BotFather, официального бота для создания и управления ботами Telegram. Затем получите токен API и идентификатор чата и запишите их здесь.", + "tokenLabel": "Ваш токен бота", + "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", + "chatIdLabel": "ID Вашего Чата", + "chatIdPlaceholder": "-1001234567890" + }, + "webhook": { + "label": "Вебхуки", + "description": "Вы можете настроить пользовательский вебхук для получения уведомлений о возникновении инцидентов.", + "urlLabel": "URL вебхука", + "urlPlaceholder": "https://your-server.com/webhook" + }, + "testNotificationDevelop": "Тестовое уведомление 2", + "integrationButton": "" + }, + "testLocale": "testLocale", + "add": "Добавить", + "monitors": "мониторы", + "distributedUptimeStatusCreateStatusPage": "страница статуса", + "distributedUptimeStatusCreateStatusPageAccess": "Доступ", + "distributedUptimeStatusCreateStatusPageReady": "Если ваша страница статуса готова, вы можете отметить ее как опубликованную.", + "distributedUptimeStatusBasicInfoHeader": "Основная информация", + "distributedUptimeStatusBasicInfoDescription": "Определите название компании и поддомен, на который ссылается ваша страница статуса.", + "distributedUptimeStatusLogoHeader": "Логотип", + "distributedUptimeStatusLogoDescription": "Загрузите логотип для своей страницы статуса", + "distributedUptimeStatusLogoUploadButton": "Загрузить логотип", + "distributedUptimeStatusStandardMonitorsHeader": "Стандартные Мониторы", + "distributedUptimeStatusStandardMonitorsDescription": "Прикрепите стандартные мониторы к своей странице статуса.", + "distributedUptimeStatusCreateYour": "Создайте свой", + "distributedUptimeStatusEditYour": "Отредактируйте свой", + "distributedUptimeStatusPublishedLabel": "Опубликовано и доступно для общественности", + "distributedUptimeStatusCompanyNameLabel": "Название компании", + "distributedUptimeStatusPageAddressLabel": "Адрес вашей страницы статуса", + "distributedUptimeStatus30Days": "30 дней", + "distributedUptimeStatus60Days": "60 дней", + "distributedUptimeStatus90Days": "90 дней", + "distributedUptimeStatusPageNotSetUp": "Страница статуса не настроена.", + "distributedUptimeStatusContactAdmin": "Пожалуйста, свяжитесь с вашим администратором", + "distributedUptimeStatusPageNotPublic": "Эта страница статуса не является публичной.", + "distributedUptimeStatusPageDeleteDialog": "Вы хотите удалить эту страницу статуса?", + "distributedUptimeStatusPageDeleteConfirm": "Да, удалить страницу статуса", + "distributedUptimeStatusPageDeleteDescription": "После удаления ваша страница статуса не может быть восстановлена.", + "distributedUptimeStatusDevices": "Устройства", + "distributedUptimeStatusUpt": "UPT", + "distributedUptimeStatusUptBurned": "UPT Burned", + "distributedUptimeStatusUptLogo": "Upt Logo", + "incidentsTableNoIncidents": "Инцидентов не зафиксировано", + "incidentsTablePaginationLabel": "инциденты", + "incidentsTableMonitorName": "Имя Монитора", + "incidentsTableStatus": "Статус", + "incidentsTableDateTime": "Дата и Время", + "incidentsTableStatusCode": "Код Статуса", + "incidentsTableMessage": "Сообщение", + "incidentsOptionsHeader": "Инцидент для:", + "incidentsOptionsHeaderFilterBy": "Фильтровать по:", + "incidentsOptionsHeaderFilterAll": "Все", + "incidentsOptionsHeaderFilterDown": "Недоступно", + "incidentsOptionsHeaderFilterCannotResolve": "Невозможно решить", + "incidentsOptionsHeaderShow": "Показать:", + "incidentsOptionsHeaderLastHour": "Последний час", + "incidentsOptionsHeaderLastDay": "Последний день", + "incidentsOptionsHeaderLastWeek": "Последняя неделя", + "incidentsOptionsPlaceholderAllServers": "Все сервера", + "infrastructureCreateYour": "Создайте свой", + "infrastructureCreateGeneralSettingsDescription": "Здесь вы можете выбрать URL-адрес хоста, а также понятное имя и секретный ключ авторизации для подключения к агенту сервера.", + "infrastructureServerRequirement": "Сервер, который вы отслеживаете, должен быть запущен", + "infrastructureCustomizeAlerts": "Настройте оповещения", + "infrastructureAlertNotificationDescription": "Отправлять уведомления пользователям, когда пороговые значения превышают указанный процент.", + "infrastructureCreateMonitor": "Создать Монитор Инфраструктуры", + "infrastructureProtocol": "Протокол", + "infrastructureServerUrlLabel": "URL Сервера", + "infrastructureDisplayNameLabel": "Отображаемое имя", + "infrastructureAuthorizationSecretLabel": "Секрет авторизации", + "gb": "ГБ", + "mb": "МБ", + "mem": "Mem", + "memoryUsage": "Использование памяти", + "cpu": "CPU", + "cpuUsage": "Использование CPU", + "cpuTemperature": "Температура CPU", + "diskUsage": "Использование диска", + "used": "Использовал", + "total": "Всего", + "cores": "Ядра", + "frequency": "Частота", + "status": "Статус", + "cpuPhysical": "CPU (физический)", + "cpuLogical": "CPU (логический)", + "cpuFrequency": "Частота CPU", + "avgCpuTemperature": "Средняя температура CPU", + "memory": "Память", + "disk": "Диск", + "uptime": "Аптайм", + "os": "ОС", + "host": "Хост", + "actions": "Действия", + "integrations": "Интеграции", + "integrationsPrism": "Подключите Prism к вашему любимому сервису.", + "integrationsSlack": "Slack", + "integrationsSlackInfo": "Подключитесь к Slack и просматривайте инциденты в канале", + "integrationsDiscord": "Discord", + "integrationsDiscordInfo": "Подключитесь к Discord и просматривайте инциденты прямо в канале", + "integrationsZapier": "Zapier", + "integrationsZapierInfo": "Отправляйте все инциденты в Zapier, и тогда вы сможете видеть их везде", + "createYour": "", + "createMonitor": "", + "pause": "", + "resume": "", + "editing": "", + "url": "", + "access": "", + "timezone": "", + "features": "", + "administrator": "", + "loginHere": "", + "displayName": "", + "urlMonitor": "", + "portToMonitor": "", + "websiteMonitoring": "", + "websiteMonitoringDescription": "", + "pingMonitoring": "", + "pingMonitoringDescription": "", + "dockerContainerMonitoring": "", + "window": "", + "cancel": "", + "message": "", + "low": "", + "high": "", + "statusCode": "", + "date&Time": "", + "type": "", + "statusPageName": "", + "publicURL": "", + "repeat": "", + "edit": "", + "createA": "", + "remove": "", + "maintenanceWindowDescription": "", + "startTime": "", + "timeZoneInfo": "", + "monitorsToApply": "", + "nextWindow": "", + "notFoundButton": "", + "pageSpeedConfigureSettingsDescription": "", + "monitorDisplayName": "", + "whenNewIncident": "", + "notifySMS": "", + "notifyEmails": "", + "seperateEmails": "", + "checkFrequency": "", + "matchMethod": "", + "expectedValue": "", + "deleteDialogTitle": "", + "deleteDialogDescription": "", + "pageSpeedMonitor": "", + "shown": "", + "ago": "", + "companyName": "", + "pageSpeedDetailsPerformanceReport": "", + "pageSpeedDetailsPerformanceReportCalculator": "", + "checkingEvery": "", + "statusPageCreateSettings": "", + "basicInformation": "", + "statusPageCreateBasicInfoDescription": "", + "statusPageCreateSelectTimeZoneDescription": "", + "statusPageCreateAppearanceDescription": "", + "statusPageCreateSettingsCheckboxLabel": "", + "statusPageCreateBasicInfoStatusPageAddress": "", + "statusPageCreateTabsContent": "", + "statusPageCreateTabsContentDescription": "", + "statusPageCreateTabsContentFeaturesDescription": "", + "showCharts": "", + "showUptimePercentage": "", + "removeLogo": "", + "statusPageStatus": "", + "statusPageStatusContactAdmin": "", + "statusPageStatusNotPublic": "", + "statusPageStatusNoPage": "", + "statusPageStatusServiceStatus": "", + "deleteStatusPage": "", + "deleteStatusPageConfirm": "", + "deleteStatusPageDescription": "", + "uptimeCreate": "", + "uptimeCreateJsonPath": "", + "uptimeCreateJsonPathQuery": "", + "maintenanceTableActionMenuDialogTitle": "", + "incidentsPageTitle": "Инциденты", + "passwordPanel": { + "passwordChangedSuccess": "Ваш пароль был успешно изменен.", + "passwordInputIncorrect": "Ваш пароль введен неверно.", + "currentPassword": "Текущий пароль", + "enterCurrentPassword": "Введите ваш текущий пароль", + "newPassword": "Новый пароль", + "enterNewPassword": "Введите ваш новый пароль", + "confirmNewPassword": "Подтвердите новый пароль", + "passwordRequirements": "Новый пароль должен содержать не менее 8 символов и должен иметь как минимум одну заглавную букву, одну строчную букву, одну цифру и один специальный символ.", + "saving": "Сохранение..." + }, + "pageSpeedWarning": "Предупреждение: Вы не добавили ключ API Google PageSpeed. Без него монитор PageSpeed не будет работать.", + "pageSpeedLearnMoreLink": "Нажмите здесь, чтобы узнать", + "pageSpeedAddApiKey": "как добавить ваш ключ API.", + "pageSpeedApiKeyFieldTitle": "Ключ Google PageSpeed API", + "pageSpeedApiKeyFieldLabel": "Ключ PageSpeed API", + "pageSpeedApiKeyFieldDescription": "Введите свой ключ Google PageSpeed API, чтобы включить мониторинг скорости страниц. Нажмите «Сбросить», чтобы обновить ключ.", + "pageSpeedApiKeyFieldResetLabel": "Ключ API установлен. Нажмите «Сбросить», чтобы изменить его.", + "createNew": "Создать новый", + "greeting": { + "prepend": "Привет", + "append": "День прекрасен для новых достижений!", + "overview": "Вот обзор ваших мониторов {{type}}." + }, + "monitorStatus": { + "up": "работает", + "down": "не работает", + "paused": "приостановлен" + }, + "roles": { + "superAdmin": "Суперадминистратор", + "admin": "Администратор", + "teamMember": "Член команды", + "demoUser": "Демо-пользователь" + }, + "teamPanel": { + "teamMembers": "Члены команды", + "filter": { + "all": "Все", + "member": "Член" + }, + "inviteTeamMember": "Пригласить члена команды", + "inviteNewTeamMember": "Пригласить нового члена команды", + "inviteDescription": "Когда вы добавляете нового члена команды, он получит доступ ко всем мониторам.", + "email": "Эл. почта", + "selectRole": "Выберите роль", + "inviteLink": "Ссылка для приглашения", + "cancel": "Отмена", + "noMembers": "Нет членов команды с этой ролью", + "getToken": "Получить токен", + "emailToken": "Отправить токен по эл. почте", + "table": { + "name": "Имя", + "email": "Эл. почта", + "role": "Роль", + "created": "Создан" + } + }, + "monitorState": { + "paused": "приостановлен", + "resumed": "возобновлен", + "active": "активный" + }, + "menu": { + "uptime": "Аптайм", + "pagespeed": "Скорость страницы", + "infrastructure": "Инфраструктура", + "distributedUptime": "Распределенный Аптайм", + "incidents": "Инциденты", + "statusPages": "Страницы статуса", + "maintenance": "Обслуживание", + "integrations": "Интеграции", + "settings": "Настройки", + "support": "Поддержка", + "profile": "Профиль", + "password": "Пароль", + "team": "Команда", + "logOut": "Выйти", + "discussions": "Обсуждения", + "docs": "Документация", + "changelog": "История изменений" + }, + "navControls": "Управление", + "statusBreadCrumbsStatusPages": "Страницы статуса", + "statusBreadCrumbsDetails": "Подробности", + "uptimeCreateSelectURL": "Введите URL или IP для мониторинга (например, https://example.com/ или 192.168.1.100) и добавьте понятное отображаемое имя, которое будет показано на панели управления." +} diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index 6fc650ad3..e411b7e4a 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -1,536 +1,536 @@ { - "dontHaveAccount": "Hesabınız yok mu", - "doNotHaveAccount": "Hesabınız yok mu?", - "registerHere": "Buradan kayıt olun", - "email": "E-posta", - "forgotPassword": "Parolamı unuttum", - "password": "Parola", - "signUp": "Kayıt Ol", - "submit": "Gönder", - "title": "Başlık", - "continue": "Devam Et", - "enterEmail": "E-posta adresinizi girin", - "authLoginTitle": "Giriş Yap", - "authLoginEnterPassword": "Parolanızı girin", - "commonPassword": "Parola", - "commonBack": "Geri", - "authForgotPasswordTitle": "Parolanızı mı unuttunuz?", - "authForgotPasswordResetPassword": "Parola sıfırla", - "authForgotPasswordInstructions": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", - "createPassword": "Parolanızı oluşturun", - "createAPassword": "Parola", - "authRegisterAlreadyHaveAccount": "Zaten hesabınız var mı?", - "authRegisterLoginLink": "Giriş Yap", - "commonAppName": "Checkmate", - "welcomeBack": "Tekrar hoş geldiniz! Başarıyla giriş yaptınız.", - "authLoginEnterEmail": "E-posta adresinizi girin", - "authRegisterTitle": "Hesap oluştur", - "authRegisterStepOneTitle": "Hesabınızı oluşturun", - "authRegisterStepOneDescription": "Başlamak için bilgilerinizi girin", - "authRegisterStepTwoTitle": "Profilinizi ayarlayın", - "authRegisterStepTwoDescription": "Kendiniz hakkında daha fazla bilgi verin", - "authRegisterStepThreeTitle": "Neredeyse bitti!", - "authRegisterStepThreeDescription": "Bilgilerinizi gözden geçirin", - "authForgotPasswordDescription": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", - "authForgotPasswordSendInstructions": "Talimatları gönder", - "authForgotPasswordBackTo": "Geri dön", - "authCheckEmailTitle": "E-postanızı kontrol edin", - "authCheckEmailDescription": "{{email}} adresine şifre sıfırlama bağlantısı gönderdik", - "authCheckEmailResendEmail": "E-postayı yeniden gönder", - "authCheckEmailBackTo": "Geri dön", - "goBackTo": "Geri dön", - "authCheckEmailDidntReceiveEmail": "E-posta almadınız mı?", - "authCheckEmailClickToResend": "Yeniden göndermek için tıklayın", - "authSetNewPasswordTitle": "Yeni şifre belirle", - "authSetNewPasswordDescription": "Yeni şifreniz daha önce kullanılan şifrelerden farklı olmalıdır.", - "authSetNewPasswordNewPassword": "Yeni şifre", - "authSetNewPasswordConfirmPassword": "Parolayı onayla", - "confirmPassword": "Onaylamak için parolayı tekrar girin", - "confirmNewPasswordPlaceholder": "Yeni parolanızı onaylayın", - "authSetNewPasswordResetPassword": "Parola sıfırla", - "authSetNewPasswordBackTo": "Geri dön", - "authPasswordMustBeAtLeast": "En az", - "authPasswordCharactersLong": "8 karakter uzunluğunda olmalı", - "authPasswordMustContainAtLeast": "En az içermeli", - "authPasswordSpecialCharacter": "bir özel karakter", - "authPasswordOneNumber": "bir rakam", - "authPasswordUpperCharacter": "bir büyük harf", - "authPasswordLowerCharacter": "bir küçük harf", - "authPasswordConfirmAndPassword": "Onay şifresi ve şifre", - "authPasswordMustMatch": "Parolalar eşleşmelidir", - "authRegisterCreateAccount": "Hesap oluşturmak için devam et", - "authRegisterCreateSuperAdminAccount": "Super admin hesabınızı oluşturmak için devam edin", - "authRegisterSignUpWithEmail": "E-posta ile kayıt ol", - "authRegisterBySigningUp": "Kayıt olarak, aşağıdaki şartları kabul ediyorsunuz:", - "distributedStatusHeaderText": "Gerçek zamanlı, Gerçek cihazlar kapsamı", - "distributedStatusSubHeaderText": "Dünya çapında milyonlarca cihaz tarafından desteklenen sistem performansını küresel bölgeye, ülkeye veya şehre göre görüntüleyin", - "settingsGeneralSettings": "Genel ayarlar", - "settingsDisplayTimezone": "Görüntüleme saat dilimi", - "settingsDisplayTimezoneDescription": "Uygulama genelinde tarih ve saatlerin görüntülenmesi için kullanılacak saat dilimini seçin.", - "settingsAppearance": "Görünüm", - "settingsAppearanceDescription": "Açık ve koyu mod arasında geçiş yapın veya kullanıcı arayüzü dilini değiştirin", - "settingsThemeMode": "Tema", - "settingsThemeModeLight": "Açık", - "settingsThemeModeDark": "Koyu", - "settingsLanguage": "Dil", - "settingsURLTitle": "Durum Sayfasında IP/URL'yi Göster", - "settingsURLDescription": "Monitörün IP adresini veya URL'sini genel Durum sayfasında göster. Devre dışı bırakıldığında, hassas bilgileri korumak için yalnızca monitör adı gösterilecektir.", - "settingsURLSelectTitle": "Durum sayfasında IP/URL'yi göster", - "settingsURLEnabled": "Etkin", - "settingURLDisabled": "Devre Dışı", - "settingsDistributedUptime": "Dağıtılmış çalışma süresi", - "settingsDistributedUptimeDescription": "Dağıtılmış çalışma süresi izlemeyi etkinleştirin/devre dışı bırakın.", - "settingsEnabled": "Etkin", - "settingsDisabled": "Devre dışı", - "settingsHistoryAndMonitoring": "İzleme geçmişi", - "settingsHistoryAndMonitoringDescription": "Geçmiş verileri ne kadar süre saklamak istediğinizi tanımlayın. Ayrıca mevcut tüm verileri temizleyebilirsiniz.", - "settingsTTLLabel": "İzleme geçmişini saklamak istediğiniz gün sayısı.", - "settingsTTLOptionalLabel": "Sınırsız için 0", - "settingsClearAllStats": "Tüm istatistikleri temizle. Bu geri alınamaz.", - "settingsClearAllStatsButton": "Tüm istatistikleri temizle", - "settingsClearAllStatsDialogTitle": "Tüm istatistikleri temizlemek istiyor musunuz?", - "settingsClearAllStatsDialogDescription": "Kaldırıldıktan sonra, izleme geçmişi ve istatistikleri geri alınamaz.", - "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", - "settingsClearAllStatsDialogCancel": "İptal", - "settingsDemoMonitors": "Demo monitörler", - "settingsDemoMonitorsDescription": "Gösterim amaçlı örnek monitörler ekleyin.", - "settingsAddDemoMonitors": "Demo monitörler ekleniyor", - "settingsAddDemoMonitorsButton": "Demo monitörler ekle", - "settingsSystemReset": "Sistem sıfırlama", - "settingsSystemResetDescription": "Sisteminizden tüm monitörleri kaldırın.", - "settingsRemoveAllMonitors": "Tüm monitörler kaldırılıyor", - "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", - "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", - "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri kaldır", - "settingsWallet": "Cüzdan", - "settingsWalletDescription": "Cüzdanınızı buradan bağlayın. Bu, Dağıtılmış Çalışma Süresi monitörünün küresel olarak birden çok düğüme bağlanması için gereklidir.", - "settingsTestEmail": "Test e-postası gönder", - "settingsTestEmailSuccess": "Test e-postası başarıyla gönderildi", - "settingsTestEmailFailed": "Test e-postası gönderilemedi", - "settingsTestEmailFailedWithReason": "Test e-postası gönderilemedi: {{reason}}", - "settingsTestEmailUnknownError": "Bilinmeyen hata", - "settingsEmail": "E-posta", - "settingsEmailDescription": "Sisteminiz için e-posta ayarlarını yapılandırın. Bu, bildirim ve uyarıları göndermek için kullanılır.", - "settingsEmailHost": "E-posta sunucusu - SMTP sunucusunun ana bilgisayar adı veya IP adresi", - "settingsEmailPort": "E-posta portu - Bağlanılacak port", - "settingsEmailUser": "E-posta kullanıcısı - Kimlik doğrulama için kullanıcı adı, belirtilirse e-posta adresini geçersiz kılar", - "settingsEmailAddress": "E-posta adresi - Kimlik doğrulama için kullanılır", - "settingsEmailPassword": "E-posta şifresi - Kimlik doğrulama için şifre", - "settingsEmailConnectionHost": "E-posta bağlantı sunucusu - HELO/EHLO selamlamasında kullanılacak ana bilgisayar adı", - "settingsEmailRequiredFields": "E-posta sunucusu ve port gereklidir", - "settingsAbout": "Hakkında", - "settingsDevelopedBy": "Bluewave Labs tarafından geliştirilmiştir.", - "settingsSave": "Kaydet", - "settingsSuccessSaved": "Ayarlar başarıyla kaydedildi", - "settingsFailedToSave": "Ayarlar kaydedilemedi", - "settingsStatsCleared": "İstatistikler başarıyla temizlendi", - "settingsFailedToClearStats": "İstatistikler temizlenemedi", - "settingsDemoMonitorsAdded": "Demo monitörler başarıyla eklendi", - "settingsFailedToAddDemoMonitors": "Demo monitörler eklenemedi", - "settingsMonitorsDeleted": "Tüm monitörler başarıyla silindi", - "settingsFailedToDeleteMonitors": "Monitörler silinemedi", - "backendUnreachable": "Sunucu Bağlantı Hatası", - "backendUnreachableMessage": "Sunucuya bağlanamıyoruz. Lütfen internet bağlantınızı kontrol edin veya sorun devam ederse dağıtım yapılandırmanızı doğrulayın.", - "backendUnreachableError": "Sunucuya bağlanılamıyor. Lütfen daha sonra tekrar deneyin.", - "retryConnection": "Bağlantıyı Yeniden Dene", - "retryingConnection": "Bağlanıyor...", - "backendReconnected": "Sunucuya başarıyla yeniden bağlandı.", - "backendStillUnreachable": "Sunucu hala erişilemez durumda. Lütfen daha sonra tekrar deneyin.", - "backendConnectionError": "Sunucuya bağlanırken hata oluştu. Lütfen ağ bağlantınızı kontrol edin.", - "starPromptTitle": "Checkmate yıldızla değerlendirin", - "starPromptDescription": "En son sürümleri görün ve GitHub'daki topluluğun büyümesine yardımcı olun", - "https": "HTTPS", - "http": "HTTP", - "monitor": "monitör", - "aboutus": "Hakkımızda", - "now": "Şimdi", - "delete": "Sil", - "configure": "Yapılandır", - "networkError": "Ağ hatası", - "responseTime": "Yanıt süresi", - "ms": "ms", - "bar": "Çubuk", - "area": "Alan", - "country": "ÜLKE", - "city": "ŞEHİR", - "response": "YANIT", - "checkConnection": "Lütfen bağlantınızı kontrol edin", - "passwordreset": "Parola Sıfırlama", - "authRegisterStepOnePersonalDetails": "Kişisel bilgilerinizi girin", - "authCheckEmailOpenEmailButton": "Eposta uygulamasını aç", - "authNewPasswordConfirmed": "Parolanız başarıyla sıfırlandı. Otomatik olarak giriş yapmak için aşağıya tıklayın.", - "monitorStatusUp": "Monitör {name} ({url}) ayakta ve yanıt veriyor", - "monitorStatusDown": "Monitör {name} ({url}) yanıt vermiyor", - "webhookSendSuccess": "Web kanca bildirimi başarıyla gönderildi", - "webhookSendError": "Web kanca bildirimi bu platforma gönderilemedi: {platform}", - "webhookUnsupportedPlatform": "Desteklenmeyen platform: {platform}", - "distributedRightCategoryTitle": "Monitör", - "distributedStatusServerMonitors": "Sunucu monitörleri", - "distributedStatusServerMonitorsDescription": "İlgili sunucuların monitör durumları", - "distributedUptimeCreateSelectURL": "Burada sunucu adresini (URL) ve monitör türünü girebilirsiniz.", - "distributedUptimeCreateChecks": "Yapılacak kontroller", - "distributedUptimeCreateChecksDescription": "Adresi girdikten sonra kontrol ekleyebilir ya da çıkartabilirsiniz.", - "distributedUptimeCreateIncidentNotification": "Olay bildirimleri", - "distributedUptimeCreateIncidentDescription": "Bir olay olduğunda kullanıcıları bilgilendir.", - "distributedUptimeCreateAdvancedSettings": "Gelişmiş ayarlar", - "distributedUptimeDetailsNoMonitorHistory": "Bu monitör için henüz bir denetim günlüğü oluşturulmadı.", - "distributedUptimeDetailsFooterHeading": "UpRock & Bluewave Labs tarafından geliştirildi", - "distributedUptimeDetailsFooterBuilt": "Altyapı", - "distributedUptimeDetailsFooterSolana": "Solana", - "distributedUptimeDetailsMonitorHeader": "Depin Destekli Dağıtık Kesintisizlik İzleme", - "distributedUptimeDetailsStatusHeaderUptime": "Erişilebilirlik", - "distributedUptimeDetailsStatusHeaderLastUpdate": "Son güncelleme", - "notifications": { - "enableNotifications": "{{platform}} bildirimlerini etkinleştir", - "testNotification": "Bildirimi test et", - "addOrEditNotifications": "Bildirimleri ekle ya da düzenle", - "slack": { - "label": "Slack", - "description": "Slack bildirimlerini etkinleştirmek için bir Slack uygulaması oluşturun ve gelen web kancalarını etkinleştirin. Daha sonra, webhook URL’sini buraya girmeniz yeterlidir.\n\n\n\n\n\n", - "webhookLabel": "Web kanca URL:", - "webhookPlaceholder": "https://hooks.slack.com/services/...", - "webhookRequired": "" - }, - "discord": { - "label": "Discord", - "description": "Checkmate’ten Discord bildirimleri aracılığıyla bir Discord kanalına veri göndermek için Discord’un gelen web kancaları özelliğini kullanabilirsiniz.\n\n\n\n\n\n\n\n", - "webhookLabel": "Discord web kanca URL", - "webhookPlaceholder": "https://discord.com/api/webhooks/...", - "webhookRequired": "" - }, - "telegram": { - "label": "Telegram", - "description": "Telegram bildirimlerini etkinleştirmek için, Telegram botlarını oluşturup yönetmek için kullanılan resmi bot BotFather ile bir Telegram botu oluşturun. Daha sonra, API jetonunu (token) ve sohbet kimliğini (chat ID) alın ve buraya yazın.", - "tokenLabel": "Bot jetonu (token)", - "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", - "chatIdLabel": "Sohbet ID", - "chatIdPlaceholder": "-1001234567890", - "fieldsRequired": "" - }, - "webhook": { - "label": "Web kancaları", - "description": "Olaylar meydana geldiğinde bildirim almak için özel bir web kancası ayarlayabilirsiniz.", - "urlLabel": "Web kanca URL:", - "urlPlaceholder": "https://sunucu-adresiniz.com/webhook", - "urlRequired": "" - }, - "testNotificationDevelop": "Test bildirimi 2", - "integrationButton": "Bildirim Entegrasyonu", - "testSuccess": "", - "testFailed": "", - "unsupportedType": "", - "networkError": "" - }, - "testLocale": "TEST13 UPLOAD", - "add": "Ekle", - "monitors": "Monitörler", - "distributedUptimeStatusCreateStatusPage": "durum sayfası", - "distributedUptimeStatusCreateStatusPageAccess": "Erişim", - "distributedUptimeStatusCreateStatusPageReady": "Durum sayfanız hazırsa yayınlayabilirsiniz.", - "distributedUptimeStatusBasicInfoHeader": "Temel bilgiler", - "distributedUptimeStatusBasicInfoDescription": "", - "distributedUptimeStatusLogoHeader": "Logo", - "distributedUptimeStatusLogoDescription": "Durum sayfanız için bir logo yükleyin", - "distributedUptimeStatusLogoUploadButton": "Logo yükle", - "distributedUptimeStatusStandardMonitorsHeader": "Standart monitörler", - "distributedUptimeStatusStandardMonitorsDescription": "Durum sayfanıza standart monitörleri ekleyin.", - "distributedUptimeStatusCreateYour": "", - "distributedUptimeStatusEditYour": "", - "distributedUptimeStatusPublishedLabel": "Yayında ve herkes tarafından görülebilir", - "distributedUptimeStatusCompanyNameLabel": "Şirket adı", - "distributedUptimeStatusPageAddressLabel": "Durum sayfası adresi", - "distributedUptimeStatus30Days": "30 gün", - "distributedUptimeStatus60Days": "60 gün", - "distributedUptimeStatus90Days": "90 gün", - "distributedUptimeStatusPageNotSetUp": "Henüz bir durum sayfası oluşturulmadı.", - "distributedUptimeStatusContactAdmin": "Lütfen yöneticiniz ile görüşün", - "distributedUptimeStatusPageNotPublic": "Bu durum sayfası herkese açık değil", - "distributedUptimeStatusPageDeleteDialog": "Bu durum sayfasını silmek istiyor musunuz? ", - "distributedUptimeStatusPageDeleteConfirm": "Evet, durum sayfasını sil", - "distributedUptimeStatusPageDeleteDescription": "Silindiği zaman durum sayfalarını geri getiremezsiniz.", - "distributedUptimeStatusDevices": "Cihazlar", - "distributedUptimeStatusUpt": "UPT", - "distributedUptimeStatusUptBurned": "Yakılan UPT", - "distributedUptimeStatusUptLogo": "Upt Logo", - "incidentsTableNoIncidents": "Hiç olay kaydedilmedi", - "incidentsTablePaginationLabel": "olaylar", - "incidentsTableMonitorName": "Monitör adı", - "incidentsTableStatus": "Durum", - "incidentsTableDateTime": "Tarih ve saat", - "incidentsTableStatusCode": "Durum kodu", - "incidentsTableMessage": "Mesaj", - "incidentsOptionsHeader": "Servisler:", - "incidentsOptionsHeaderFilterBy": "Filtrele:", - "incidentsOptionsHeaderFilterAll": "Tümü", - "incidentsOptionsHeaderFilterDown": "Erişilemiyor", - "incidentsOptionsHeaderFilterCannotResolve": "Çözümlenemiyor", - "incidentsOptionsHeaderShow": "Göster:", - "incidentsOptionsHeaderLastHour": "Son saat", - "incidentsOptionsHeaderLastDay": "Son gün", - "incidentsOptionsHeaderLastWeek": "Son hafta", - "incidentsOptionsPlaceholderAllServers": "Tüm sunucular", - "infrastructureCreateYour": "", - "infrastructureCreateGeneralSettingsDescription": "", - "infrastructureServerRequirement": "", - "infrastructureCustomizeAlerts": "Alarmları özelleştir", - "infrastructureAlertNotificationDescription": "", - "infrastructureCreateMonitor": "Altyapı Monitörü oluştur", - "infrastructureProtocol": "Protokol", - "infrastructureServerUrlLabel": "Sunucu adresi", - "infrastructureDisplayNameLabel": "Görünen adı", - "infrastructureAuthorizationSecretLabel": "Kimlik denetimi parolası", - "gb": "GB", - "mb": "MB", - "mem": "Bellek", - "memoryUsage": "Bellek kullanımı", - "cpu": "CPU", - "cpuUsage": "CPU kullanımı", - "cpuTemperature": "CPU sıcaklığı", - "diskUsage": "Disk kullanımı", - "used": "Kullanılan", - "total": "Toplam", - "cores": "Çekirdek", - "frequency": "Frekans", - "status": "Durum", - "cpuPhysical": "CPU (fiziksel)", - "cpuLogical": "CPU (Mantıksal)", - "cpuFrequency": "CPU Frekansı", - "avgCpuTemperature": "Ortalama CPU Isısı", - "memory": "Bellek", - "disk": "Disk", - "uptime": "", - "os": "İşletim sistemi", - "host": "Makine", - "actions": "İşlemler", - "integrations": "Entegrasyonlar", - "integrationsPrism": "Prism'i favori servisinize bağlayın.", - "integrationsSlack": "Slack", - "integrationsSlackInfo": "", - "integrationsDiscord": "Discord", - "integrationsDiscordInfo": "", - "integrationsZapier": "Zapier", - "integrationsZapierInfo": "", - "commonSave": "Kaydet", - "commonSaving": "Kaydediliyor...", - "createYour": "", - "createMonitor": "Monitör oluştur", - "pause": "Beklet", - "resume": "Yeniden başlat", - "editing": "Düzenleniyor...", - "url": "URL", - "access": "Erişim", - "timezone": "Zaman dilimi", - "features": "Özellikler", - "administrator": "Yönetici misin?", - "loginHere": "Buradan giriş yap", - "displayName": "Görüntülenecek isim", - "urlMonitor": "Monitör edilecek URL", - "portToMonitor": "Monitör edilecek port", - "websiteMonitoring": "Web sitesi monitörü", - "websiteMonitoringDescription": "", - "pingMonitoring": "Ping monitörü", - "pingMonitoringDescription": "Sitenizin ayakta olup olmadığını denetleyin.", - "dockerContainerMonitoring": "Docker konteyner monitörü", - "dockerContainerMonitoringDescription": "Docker konteynerinizin ayakta olup olmadığını denetleyin.", - "portMonitoring": "Port monitörü", - "portMonitoringDescription": "Portunuzun açık olup olmadığını denetleyin.", - "createMaintenanceWindow": "Bakım aralığı oluşturun", - "createMaintenance": "Bakım oluştur", - "editMaintenance": "Bakımı düzenle", - "maintenanceWindowName": "Bakım aralığı adı", - "friendlyNameInput": "Görünen ad", - "friendlyNamePlaceholder": "__:__ saatinde __ dakika boyunca bakım var", - "maintenanceRepeat": "Bakım Tekrarı", - "maintenance": "bakım", - "duration": "Süre", - "addMonitors": "Monitör ekle", - "window": "pencere", - "cancel": "İptal", - "message": "Mesaj", - "low": "düşük", - "high": "yüksek", - "statusCode": "Durum kodu", - "date&Time": "", - "type": "", - "statusPageName": "", - "publicURL": "", - "repeat": "", - "edit": "", - "createA": "", - "remove": "", - "maintenanceWindowDescription": "", - "startTime": "Başlangıç saati", - "timeZoneInfo": "", - "monitorsToApply": "", - "nextWindow": "Sonraki pencere", - "notFoundButton": "", - "pageSpeedConfigureSettingsDescription": "", - "monitorDisplayName": "", - "whenNewIncident": "Yeni bir olay oluştuğunda,", - "notifySMS": "", - "notifyEmails": "", - "seperateEmails": "", - "checkFrequency": "Frekansı denetle", - "matchMethod": "", - "expectedValue": "Beklenen değer", - "deleteDialogTitle": "Gerçekten bu monitörü silmek istiyor musunuz?", - "deleteDialogDescription": "Bir kez silindiği zaman tekrar getiremezsiniz.", - "pageSpeedMonitor": "Sayfa Hızı Monitörü", - "shown": "", - "ago": "", - "companyName": "Firma adı", - "pageSpeedDetailsPerformanceReport": "", - "pageSpeedDetailsPerformanceReportCalculator": "Hesap makinesini gör", - "checkingEvery": "Denetleme sıklığı", - "statusPageCreateSettings": "Eğer durum sayfanız hazırsa, herkese açık yayınlayabilirsiniz", - "basicInformation": "Temel Bilgiler", - "statusPageCreateBasicInfoDescription": "", - "statusPageCreateSelectTimeZoneDescription": "", - "statusPageCreateAppearanceDescription": "", - "statusPageCreateSettingsCheckboxLabel": "Yayınlandı ve herkese açık", - "statusPageCreateBasicInfoStatusPageAddress": "Durum sayfası adresiniz", - "statusPageCreateTabsContent": "Durum sayfası sunucuları", - "statusPageCreateTabsContentDescription": "", - "statusPageCreateTabsContentFeaturesDescription": "Durum sayfasında daha fazla bilgi göster", - "showCharts": "Çizelgeleri göster", - "showUptimePercentage": "", - "removeLogo": "Logoyu sil", - "statusPageStatus": "Herkese açık bir durum sayfası henüz oluşturulmadı.", - "statusPageStatusContactAdmin": "Lütfen yöneticinizle iletişime geçin.", - "statusPageStatusNotPublic": "Durum sayfası herkese açık değil.", - "statusPageStatusNoPage": "Burada bir durum sayfası bulunmuyor.", - "statusPageStatusServiceStatus": "Servis durumu", - "deleteStatusPage": "Gerçekten bu durum sayfasını silmek istiyor musunuz?", - "deleteStatusPageConfirm": "Evet, durum sayfasını sil", - "deleteStatusPageDescription": "Silindikten sonra durum sayfasını geri getiremezsiniz.", - "uptimeCreate": "", - "uptimeCreateJsonPath": "", - "uptimeCreateJsonPathQuery": "", - "maintenanceTableActionMenuDialogTitle": "Gerçekten bu bakım aralığını silmek istiyor musunuz?", - "infrastructureEditYour": "", - "infrastructureEditMonitor": "", - "infrastructureMonitorCreated": "", - "infrastructureMonitorUpdated": "", - "errorInvalidTypeId": "", - "pageSpeedWarning": "Uyarı: Google PageSpeed API anahtarı eklemediniz. Bu olmadan, PageSpeed monitörü çalışmayacaktır.", - "pageSpeedLearnMoreLink": "Daha fazla bilgi için tıklayın", - "pageSpeedAddApiKey": "API anahtarınızı nasıl ekleyeceğinizi öğrenin.", - "pageSpeedApiKeyFieldTitle": "Google PageSpeed API anahtarı", - "pageSpeedApiKeyFieldLabel": "PageSpeed API anahtarı", - "pageSpeedApiKeyFieldDescription": "PageSpeed izlemeyi etkinleştirmek için Google PageSpeed API anahtarınızı girin. Anahtarı güncellemek için Sıfırla'ya tıklayın.", - "pageSpeedApiKeyFieldResetLabel": "API anahtarı ayarlandı. Değiştirmek için Sıfırla'ya tıklayın.", - "reset": "Sıfırla", - "invalidFileFormat": "", - "invalidFileSize": "", - "ClickUpload": "", - "DragandDrop": "", - "MaxSize": "", - "SupportedFormats": "", - "FirstName": "Ad", - "LastName": "Soyad", - "EmailDescriptionText": "Mevcut e-postanız—değiştirilemez.", - "YourPhoto": "Profil fotoğrafı", - "PhotoDescriptionText": "Bu fotoğraf profil sayfanızda görüntülenecektir.", - "save": "", - "DeleteAccountTitle": "Hesabı kaldır", - "DeleteAccountButton": "Hesabı kaldır", - "DeleteDescriptionText": "Bu, hesabı ve tüm ilişkili verileri sunucudan kaldıracaktır. Bu geri alınamaz.", - "DeleteAccountWarning": "Hesabınızı kaldırmak, tekrar oturum açamayacağınız ve tüm verilerinizin kaldırılacağı anlamına gelir. Bu geri alınamaz.", - "DeleteWarningTitle": "Bu hesabı gerçekten kaldırmak istiyor musunuz?", - "authRegisterFirstName": "Ad", - "authRegisterLastName": "Soyad", - "authRegisterEmail": "E-posta", - "authRegisterEmailRequired": "Devam etmek için lütfen e-posta adresinizi girin", - "authRegisterEmailInvalid": "Lütfen geçerli bir e-posta adresi girin", - "bulkImport": { - "title": "Toplu İçe Aktar", - "selectFileTips": "Yüklemek için CSV dosyası seçin", - "selectFileDescription": " veya örneğimizi indirebilirsiniz", - "selectFile": "Dosya Seç", - "parsingFailed": "Ayrıştırma başarısız oldu", - "uploadSuccess": "Monitörler başarıyla oluşturuldu!", - "validationFailed": "Doğrulama başarısız oldu", - "noFileSelected": "Dosya seçilmedi", - "fallbackPage": "Sunucuların listesini toplu olarak yüklemek için bir dosya içe aktarın" - }, - "createNew": "Yeni oluştur", - "greeting": { - "prepend": "Merhaba", - "append": "Öğleden sonra senin oyun alanın—hadi onu muhteşem yapalım!", - "overview": "İşte {{type}} monitörlerinizin genel görünümü." - }, - "monitorStatus": { - "up": "aktif", - "down": "devre dışı", - "paused": "duraklatıldı" - }, - "roles": { - "superAdmin": "Süper yönetici", - "admin": "Yönetici", - "teamMember": "Takım üyesi", - "demoUser": "Demo kullanıcı" - }, - "teamPanel": { - "teamMembers": "Takım üyeleri", - "filter": { - "all": "Tümü", - "member": "Üye" - }, - "inviteTeamMember": "Takım üyesi davet et", - "inviteNewTeamMember": "Yeni takım üyesi davet et", - "inviteDescription": "Yeni bir takım üyesi eklediğinizde, tüm monitörlere erişim hakkı alacaktır.", - "email": "E-posta", - "selectRole": "Rol seçin", - "inviteLink": "Davet bağlantısı", - "cancel": "İptal", - "noMembers": "Bu role sahip takım üyesi bulunmamaktadır", - "getToken": "Token al", - "emailToken": "Token e-posta ile gönder", - "table": { - "name": "Ad", - "email": "E-posta", - "role": "Rol", - "created": "Oluşturuldu" - } - }, - "monitorState": { - "paused": "duraklatıldı", - "resumed": "devam ettirildi", - "active": "aktif" - }, - "menu": { - "uptime": "Çalışma Süresi", - "pagespeed": "Sayfa Hızı", - "infrastructure": "Altyapı", - "distributedUptime": "Dağıtılmış Çalışma Süresi", - "incidents": "Olaylar", - "statusPages": "Durum Sayfaları", - "maintenance": "Bakım", - "integrations": "Entegrasyonlar", - "settings": "Ayarlar", - "support": "Destek", - "discussions": "Tartışmalar", - "docs": "Belgeler", - "changelog": "Değişiklik Günlüğü", - "profile": "Profil", - "password": "Şifre", - "team": "Takım", - "logOut": "Çıkış" - }, - "navControls": "Kontroller", - "statusBreadCrumbsStatusPages": "Durum Sayfaları", - "statusBreadCrumbsDetails": "Detaylar", - "incidentsPageTitle": "Olaylar", - "passwordPanel": { - "passwordChangedSuccess": "Şifreniz başarıyla değiştirildi.", - "passwordInputIncorrect": "Şifre girişiniz yanlış.", - "currentPassword": "Mevcut şifre", - "enterCurrentPassword": "Mevcut şifrenizi girin", - "newPassword": "Yeni şifre", - "enterNewPassword": "Yeni şifrenizi girin", - "confirmNewPassword": "Yeni şifreyi onaylayın", - "passwordRequirements": "Yeni şifre en az 8 karakter içermeli ve en az bir büyük harf, bir küçük harf, bir rakam ve bir özel karakter içermelidir.", - "saving": "Kaydediliyor..." - }, - "uptimeCreateSelectURL": "İzlenecek URL veya IP adresini girin (örn. https://example.com/ veya 192.168.1.100) ve kontrol panelinde görünecek net bir görüntü adı ekleyin." -} \ No newline at end of file + "dontHaveAccount": "Hesabınız yok mu", + "doNotHaveAccount": "Hesabınız yok mu?", + "registerHere": "Buradan kayıt olun", + "email": "E-posta", + "forgotPassword": "Parolamı unuttum", + "password": "Parola", + "signUp": "Kayıt Ol", + "submit": "Gönder", + "title": "Başlık", + "continue": "Devam Et", + "enterEmail": "E-posta adresinizi girin", + "authLoginTitle": "Giriş Yap", + "authLoginEnterPassword": "Parolanızı girin", + "commonPassword": "Parola", + "commonBack": "Geri", + "authForgotPasswordTitle": "Parolanızı mı unuttunuz?", + "authForgotPasswordResetPassword": "Parola sıfırla", + "authForgotPasswordInstructions": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", + "createPassword": "Parolanızı oluşturun", + "createAPassword": "Parola", + "authRegisterAlreadyHaveAccount": "Zaten hesabınız var mı?", + "authRegisterLoginLink": "Giriş Yap", + "commonAppName": "Checkmate", + "welcomeBack": "Tekrar hoş geldiniz! Başarıyla giriş yaptınız.", + "authLoginEnterEmail": "E-posta adresinizi girin", + "authRegisterTitle": "Hesap oluştur", + "authRegisterStepOneTitle": "Hesabınızı oluşturun", + "authRegisterStepOneDescription": "Başlamak için bilgilerinizi girin", + "authRegisterStepTwoTitle": "Profilinizi ayarlayın", + "authRegisterStepTwoDescription": "Kendiniz hakkında daha fazla bilgi verin", + "authRegisterStepThreeTitle": "Neredeyse bitti!", + "authRegisterStepThreeDescription": "Bilgilerinizi gözden geçirin", + "authForgotPasswordDescription": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", + "authForgotPasswordSendInstructions": "Talimatları gönder", + "authForgotPasswordBackTo": "Geri dön", + "authCheckEmailTitle": "E-postanızı kontrol edin", + "authCheckEmailDescription": "{{email}} adresine şifre sıfırlama bağlantısı gönderdik", + "authCheckEmailResendEmail": "E-postayı yeniden gönder", + "authCheckEmailBackTo": "Geri dön", + "goBackTo": "Geri dön", + "authCheckEmailDidntReceiveEmail": "E-posta almadınız mı?", + "authCheckEmailClickToResend": "Yeniden göndermek için tıklayın", + "authSetNewPasswordTitle": "Yeni şifre belirle", + "authSetNewPasswordDescription": "Yeni şifreniz daha önce kullanılan şifrelerden farklı olmalıdır.", + "authSetNewPasswordNewPassword": "Yeni şifre", + "authSetNewPasswordConfirmPassword": "Parolayı onayla", + "confirmPassword": "Onaylamak için parolayı tekrar girin", + "confirmNewPasswordPlaceholder": "Yeni parolanızı onaylayın", + "authSetNewPasswordResetPassword": "Parola sıfırla", + "authSetNewPasswordBackTo": "Geri dön", + "authPasswordMustBeAtLeast": "En az", + "authPasswordCharactersLong": "8 karakter uzunluğunda olmalı", + "authPasswordMustContainAtLeast": "En az içermeli", + "authPasswordSpecialCharacter": "bir özel karakter", + "authPasswordOneNumber": "bir rakam", + "authPasswordUpperCharacter": "bir büyük harf", + "authPasswordLowerCharacter": "bir küçük harf", + "authPasswordConfirmAndPassword": "Onay şifresi ve şifre", + "authPasswordMustMatch": "Parolalar eşleşmelidir", + "authRegisterCreateAccount": "Hesap oluşturmak için devam et", + "authRegisterCreateSuperAdminAccount": "Super admin hesabınızı oluşturmak için devam edin", + "authRegisterSignUpWithEmail": "E-posta ile kayıt ol", + "authRegisterBySigningUp": "Kayıt olarak, aşağıdaki şartları kabul ediyorsunuz:", + "distributedStatusHeaderText": "Gerçek zamanlı, Gerçek cihazlar kapsamı", + "distributedStatusSubHeaderText": "Dünya çapında milyonlarca cihaz tarafından desteklenen sistem performansını küresel bölgeye, ülkeye veya şehre göre görüntüleyin", + "settingsGeneralSettings": "Genel ayarlar", + "settingsDisplayTimezone": "Görüntüleme saat dilimi", + "settingsDisplayTimezoneDescription": "Uygulama genelinde tarih ve saatlerin görüntülenmesi için kullanılacak saat dilimini seçin.", + "settingsAppearance": "Görünüm", + "settingsAppearanceDescription": "Açık ve koyu mod arasında geçiş yapın veya kullanıcı arayüzü dilini değiştirin", + "settingsThemeMode": "Tema", + "settingsThemeModeLight": "Açık", + "settingsThemeModeDark": "Koyu", + "settingsLanguage": "Dil", + "settingsURLTitle": "Durum Sayfasında IP/URL'yi Göster", + "settingsURLDescription": "Monitörün IP adresini veya URL'sini genel Durum sayfasında göster. Devre dışı bırakıldığında, hassas bilgileri korumak için yalnızca monitör adı gösterilecektir.", + "settingsURLSelectTitle": "Durum sayfasında IP/URL'yi göster", + "settingsURLEnabled": "Etkin", + "settingURLDisabled": "Devre Dışı", + "settingsDistributedUptime": "Dağıtılmış çalışma süresi", + "settingsDistributedUptimeDescription": "Dağıtılmış çalışma süresi izlemeyi etkinleştirin/devre dışı bırakın.", + "settingsEnabled": "Etkin", + "settingsDisabled": "Devre dışı", + "settingsHistoryAndMonitoring": "İzleme geçmişi", + "settingsHistoryAndMonitoringDescription": "Geçmiş verileri ne kadar süre saklamak istediğinizi tanımlayın. Ayrıca mevcut tüm verileri temizleyebilirsiniz.", + "settingsTTLLabel": "İzleme geçmişini saklamak istediğiniz gün sayısı.", + "settingsTTLOptionalLabel": "Sınırsız için 0", + "settingsClearAllStats": "Tüm istatistikleri temizle. Bu geri alınamaz.", + "settingsClearAllStatsButton": "Tüm istatistikleri temizle", + "settingsClearAllStatsDialogTitle": "Tüm istatistikleri temizlemek istiyor musunuz?", + "settingsClearAllStatsDialogDescription": "Kaldırıldıktan sonra, izleme geçmişi ve istatistikleri geri alınamaz.", + "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", + "settingsClearAllStatsDialogCancel": "İptal", + "settingsDemoMonitors": "Demo monitörler", + "settingsDemoMonitorsDescription": "Gösterim amaçlı örnek monitörler ekleyin.", + "settingsAddDemoMonitors": "Demo monitörler ekleniyor", + "settingsAddDemoMonitorsButton": "Demo monitörler ekle", + "settingsSystemReset": "Sistem sıfırlama", + "settingsSystemResetDescription": "Sisteminizden tüm monitörleri kaldırın.", + "settingsRemoveAllMonitors": "Tüm monitörler kaldırılıyor", + "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", + "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", + "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri kaldır", + "settingsWallet": "Cüzdan", + "settingsWalletDescription": "Cüzdanınızı buradan bağlayın. Bu, Dağıtılmış Çalışma Süresi monitörünün küresel olarak birden çok düğüme bağlanması için gereklidir.", + "settingsTestEmail": "Test e-postası gönder", + "settingsTestEmailSuccess": "Test e-postası başarıyla gönderildi", + "settingsTestEmailFailed": "Test e-postası gönderilemedi", + "settingsTestEmailFailedWithReason": "Test e-postası gönderilemedi: {{reason}}", + "settingsTestEmailUnknownError": "Bilinmeyen hata", + "settingsEmail": "E-posta", + "settingsEmailDescription": "Sisteminiz için e-posta ayarlarını yapılandırın. Bu, bildirim ve uyarıları göndermek için kullanılır.", + "settingsEmailHost": "E-posta sunucusu - SMTP sunucusunun ana bilgisayar adı veya IP adresi", + "settingsEmailPort": "E-posta portu - Bağlanılacak port", + "settingsEmailUser": "E-posta kullanıcısı - Kimlik doğrulama için kullanıcı adı, belirtilirse e-posta adresini geçersiz kılar", + "settingsEmailAddress": "E-posta adresi - Kimlik doğrulama için kullanılır", + "settingsEmailPassword": "E-posta şifresi - Kimlik doğrulama için şifre", + "settingsEmailConnectionHost": "E-posta bağlantı sunucusu - HELO/EHLO selamlamasında kullanılacak ana bilgisayar adı", + "settingsEmailRequiredFields": "E-posta sunucusu ve port gereklidir", + "settingsAbout": "Hakkında", + "settingsDevelopedBy": "Bluewave Labs tarafından geliştirilmiştir.", + "settingsSave": "Kaydet", + "settingsSuccessSaved": "Ayarlar başarıyla kaydedildi", + "settingsFailedToSave": "Ayarlar kaydedilemedi", + "settingsStatsCleared": "İstatistikler başarıyla temizlendi", + "settingsFailedToClearStats": "İstatistikler temizlenemedi", + "settingsDemoMonitorsAdded": "Demo monitörler başarıyla eklendi", + "settingsFailedToAddDemoMonitors": "Demo monitörler eklenemedi", + "settingsMonitorsDeleted": "Tüm monitörler başarıyla silindi", + "settingsFailedToDeleteMonitors": "Monitörler silinemedi", + "backendUnreachable": "Sunucu Bağlantı Hatası", + "backendUnreachableMessage": "Sunucuya bağlanamıyoruz. Lütfen internet bağlantınızı kontrol edin veya sorun devam ederse dağıtım yapılandırmanızı doğrulayın.", + "backendUnreachableError": "Sunucuya bağlanılamıyor. Lütfen daha sonra tekrar deneyin.", + "retryConnection": "Bağlantıyı Yeniden Dene", + "retryingConnection": "Bağlanıyor...", + "backendReconnected": "Sunucuya başarıyla yeniden bağlandı.", + "backendStillUnreachable": "Sunucu hala erişilemez durumda. Lütfen daha sonra tekrar deneyin.", + "backendConnectionError": "Sunucuya bağlanırken hata oluştu. Lütfen ağ bağlantınızı kontrol edin.", + "starPromptTitle": "Checkmate yıldızla değerlendirin", + "starPromptDescription": "En son sürümleri görün ve GitHub'daki topluluğun büyümesine yardımcı olun", + "https": "HTTPS", + "http": "HTTP", + "monitor": "monitör", + "aboutus": "Hakkımızda", + "now": "Şimdi", + "delete": "Sil", + "configure": "Yapılandır", + "networkError": "Ağ hatası", + "responseTime": "Yanıt süresi", + "ms": "ms", + "bar": "Çubuk", + "area": "Alan", + "country": "ÜLKE", + "city": "ŞEHİR", + "response": "YANIT", + "checkConnection": "Lütfen bağlantınızı kontrol edin", + "passwordreset": "Parola Sıfırlama", + "authRegisterStepOnePersonalDetails": "Kişisel bilgilerinizi girin", + "authCheckEmailOpenEmailButton": "Eposta uygulamasını aç", + "authNewPasswordConfirmed": "Parolanız başarıyla sıfırlandı. Otomatik olarak giriş yapmak için aşağıya tıklayın.", + "monitorStatusUp": "Monitör {name} ({url}) ayakta ve yanıt veriyor", + "monitorStatusDown": "Monitör {name} ({url}) yanıt vermiyor", + "webhookSendSuccess": "Web kanca bildirimi başarıyla gönderildi", + "webhookSendError": "Web kanca bildirimi bu platforma gönderilemedi: {platform}", + "webhookUnsupportedPlatform": "Desteklenmeyen platform: {platform}", + "distributedRightCategoryTitle": "Monitör", + "distributedStatusServerMonitors": "Sunucu monitörleri", + "distributedStatusServerMonitorsDescription": "İlgili sunucuların monitör durumları", + "distributedUptimeCreateSelectURL": "Burada sunucu adresini (URL) ve monitör türünü girebilirsiniz.", + "distributedUptimeCreateChecks": "Yapılacak kontroller", + "distributedUptimeCreateChecksDescription": "Adresi girdikten sonra kontrol ekleyebilir ya da çıkartabilirsiniz.", + "distributedUptimeCreateIncidentNotification": "Olay bildirimleri", + "distributedUptimeCreateIncidentDescription": "Bir olay olduğunda kullanıcıları bilgilendir.", + "distributedUptimeCreateAdvancedSettings": "Gelişmiş ayarlar", + "distributedUptimeDetailsNoMonitorHistory": "Bu monitör için henüz bir denetim günlüğü oluşturulmadı.", + "distributedUptimeDetailsFooterHeading": "UpRock & Bluewave Labs tarafından geliştirildi", + "distributedUptimeDetailsFooterBuilt": "Altyapı", + "distributedUptimeDetailsFooterSolana": "Solana", + "distributedUptimeDetailsMonitorHeader": "Depin Destekli Dağıtık Kesintisizlik İzleme", + "distributedUptimeDetailsStatusHeaderUptime": "Erişilebilirlik", + "distributedUptimeDetailsStatusHeaderLastUpdate": "Son güncelleme", + "notifications": { + "enableNotifications": "{{platform}} bildirimlerini etkinleştir", + "testNotification": "Bildirimi test et", + "addOrEditNotifications": "Bildirimleri ekle ya da düzenle", + "slack": { + "label": "Slack", + "description": "Slack bildirimlerini etkinleştirmek için bir Slack uygulaması oluşturun ve gelen web kancalarını etkinleştirin. Daha sonra, webhook URL’sini buraya girmeniz yeterlidir.\n\n\n\n\n\n", + "webhookLabel": "Web kanca URL:", + "webhookPlaceholder": "https://hooks.slack.com/services/...", + "webhookRequired": "" + }, + "discord": { + "label": "Discord", + "description": "Checkmate’ten Discord bildirimleri aracılığıyla bir Discord kanalına veri göndermek için Discord’un gelen web kancaları özelliğini kullanabilirsiniz.\n\n\n\n\n\n\n\n", + "webhookLabel": "Discord web kanca URL", + "webhookPlaceholder": "https://discord.com/api/webhooks/...", + "webhookRequired": "" + }, + "telegram": { + "label": "Telegram", + "description": "Telegram bildirimlerini etkinleştirmek için, Telegram botlarını oluşturup yönetmek için kullanılan resmi bot BotFather ile bir Telegram botu oluşturun. Daha sonra, API jetonunu (token) ve sohbet kimliğini (chat ID) alın ve buraya yazın.", + "tokenLabel": "Bot jetonu (token)", + "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", + "chatIdLabel": "Sohbet ID", + "chatIdPlaceholder": "-1001234567890", + "fieldsRequired": "" + }, + "webhook": { + "label": "Web kancaları", + "description": "Olaylar meydana geldiğinde bildirim almak için özel bir web kancası ayarlayabilirsiniz.", + "urlLabel": "Web kanca URL:", + "urlPlaceholder": "https://sunucu-adresiniz.com/webhook", + "urlRequired": "" + }, + "testNotificationDevelop": "Test bildirimi 2", + "integrationButton": "Bildirim Entegrasyonu", + "testSuccess": "", + "testFailed": "", + "unsupportedType": "", + "networkError": "" + }, + "testLocale": "TEST13 UPLOAD", + "add": "Ekle", + "monitors": "Monitörler", + "distributedUptimeStatusCreateStatusPage": "durum sayfası", + "distributedUptimeStatusCreateStatusPageAccess": "Erişim", + "distributedUptimeStatusCreateStatusPageReady": "Durum sayfanız hazırsa yayınlayabilirsiniz.", + "distributedUptimeStatusBasicInfoHeader": "Temel bilgiler", + "distributedUptimeStatusBasicInfoDescription": "", + "distributedUptimeStatusLogoHeader": "Logo", + "distributedUptimeStatusLogoDescription": "Durum sayfanız için bir logo yükleyin", + "distributedUptimeStatusLogoUploadButton": "Logo yükle", + "distributedUptimeStatusStandardMonitorsHeader": "Standart monitörler", + "distributedUptimeStatusStandardMonitorsDescription": "Durum sayfanıza standart monitörleri ekleyin.", + "distributedUptimeStatusCreateYour": "", + "distributedUptimeStatusEditYour": "", + "distributedUptimeStatusPublishedLabel": "Yayında ve herkes tarafından görülebilir", + "distributedUptimeStatusCompanyNameLabel": "Şirket adı", + "distributedUptimeStatusPageAddressLabel": "Durum sayfası adresi", + "distributedUptimeStatus30Days": "30 gün", + "distributedUptimeStatus60Days": "60 gün", + "distributedUptimeStatus90Days": "90 gün", + "distributedUptimeStatusPageNotSetUp": "Henüz bir durum sayfası oluşturulmadı.", + "distributedUptimeStatusContactAdmin": "Lütfen yöneticiniz ile görüşün", + "distributedUptimeStatusPageNotPublic": "Bu durum sayfası herkese açık değil", + "distributedUptimeStatusPageDeleteDialog": "Bu durum sayfasını silmek istiyor musunuz? ", + "distributedUptimeStatusPageDeleteConfirm": "Evet, durum sayfasını sil", + "distributedUptimeStatusPageDeleteDescription": "Silindiği zaman durum sayfalarını geri getiremezsiniz.", + "distributedUptimeStatusDevices": "Cihazlar", + "distributedUptimeStatusUpt": "UPT", + "distributedUptimeStatusUptBurned": "Yakılan UPT", + "distributedUptimeStatusUptLogo": "Upt Logo", + "incidentsTableNoIncidents": "Hiç olay kaydedilmedi", + "incidentsTablePaginationLabel": "olaylar", + "incidentsTableMonitorName": "Monitör adı", + "incidentsTableStatus": "Durum", + "incidentsTableDateTime": "Tarih ve saat", + "incidentsTableStatusCode": "Durum kodu", + "incidentsTableMessage": "Mesaj", + "incidentsOptionsHeader": "Servisler:", + "incidentsOptionsHeaderFilterBy": "Filtrele:", + "incidentsOptionsHeaderFilterAll": "Tümü", + "incidentsOptionsHeaderFilterDown": "Erişilemiyor", + "incidentsOptionsHeaderFilterCannotResolve": "Çözümlenemiyor", + "incidentsOptionsHeaderShow": "Göster:", + "incidentsOptionsHeaderLastHour": "Son saat", + "incidentsOptionsHeaderLastDay": "Son gün", + "incidentsOptionsHeaderLastWeek": "Son hafta", + "incidentsOptionsPlaceholderAllServers": "Tüm sunucular", + "infrastructureCreateYour": "", + "infrastructureCreateGeneralSettingsDescription": "", + "infrastructureServerRequirement": "", + "infrastructureCustomizeAlerts": "Alarmları özelleştir", + "infrastructureAlertNotificationDescription": "", + "infrastructureCreateMonitor": "Altyapı Monitörü oluştur", + "infrastructureProtocol": "Protokol", + "infrastructureServerUrlLabel": "Sunucu adresi", + "infrastructureDisplayNameLabel": "Görünen adı", + "infrastructureAuthorizationSecretLabel": "Kimlik denetimi parolası", + "gb": "GB", + "mb": "MB", + "mem": "Bellek", + "memoryUsage": "Bellek kullanımı", + "cpu": "CPU", + "cpuUsage": "CPU kullanımı", + "cpuTemperature": "CPU sıcaklığı", + "diskUsage": "Disk kullanımı", + "used": "Kullanılan", + "total": "Toplam", + "cores": "Çekirdek", + "frequency": "Frekans", + "status": "Durum", + "cpuPhysical": "CPU (fiziksel)", + "cpuLogical": "CPU (Mantıksal)", + "cpuFrequency": "CPU Frekansı", + "avgCpuTemperature": "Ortalama CPU Isısı", + "memory": "Bellek", + "disk": "Disk", + "uptime": "", + "os": "İşletim sistemi", + "host": "Makine", + "actions": "İşlemler", + "integrations": "Entegrasyonlar", + "integrationsPrism": "Prism'i favori servisinize bağlayın.", + "integrationsSlack": "Slack", + "integrationsSlackInfo": "", + "integrationsDiscord": "Discord", + "integrationsDiscordInfo": "", + "integrationsZapier": "Zapier", + "integrationsZapierInfo": "", + "commonSave": "Kaydet", + "commonSaving": "Kaydediliyor...", + "createYour": "", + "createMonitor": "Monitör oluştur", + "pause": "Beklet", + "resume": "Yeniden başlat", + "editing": "Düzenleniyor...", + "url": "URL", + "access": "Erişim", + "timezone": "Zaman dilimi", + "features": "Özellikler", + "administrator": "Yönetici misin?", + "loginHere": "Buradan giriş yap", + "displayName": "Görüntülenecek isim", + "urlMonitor": "Monitör edilecek URL", + "portToMonitor": "Monitör edilecek port", + "websiteMonitoring": "Web sitesi monitörü", + "websiteMonitoringDescription": "", + "pingMonitoring": "Ping monitörü", + "pingMonitoringDescription": "Sitenizin ayakta olup olmadığını denetleyin.", + "dockerContainerMonitoring": "Docker konteyner monitörü", + "dockerContainerMonitoringDescription": "Docker konteynerinizin ayakta olup olmadığını denetleyin.", + "portMonitoring": "Port monitörü", + "portMonitoringDescription": "Portunuzun açık olup olmadığını denetleyin.", + "createMaintenanceWindow": "Bakım aralığı oluşturun", + "createMaintenance": "Bakım oluştur", + "editMaintenance": "Bakımı düzenle", + "maintenanceWindowName": "Bakım aralığı adı", + "friendlyNameInput": "Görünen ad", + "friendlyNamePlaceholder": "__:__ saatinde __ dakika boyunca bakım var", + "maintenanceRepeat": "Bakım Tekrarı", + "maintenance": "bakım", + "duration": "Süre", + "addMonitors": "Monitör ekle", + "window": "pencere", + "cancel": "İptal", + "message": "Mesaj", + "low": "düşük", + "high": "yüksek", + "statusCode": "Durum kodu", + "date&Time": "", + "type": "", + "statusPageName": "", + "publicURL": "", + "repeat": "", + "edit": "", + "createA": "", + "remove": "", + "maintenanceWindowDescription": "", + "startTime": "Başlangıç saati", + "timeZoneInfo": "", + "monitorsToApply": "", + "nextWindow": "Sonraki pencere", + "notFoundButton": "", + "pageSpeedConfigureSettingsDescription": "", + "monitorDisplayName": "", + "whenNewIncident": "Yeni bir olay oluştuğunda,", + "notifySMS": "", + "notifyEmails": "", + "seperateEmails": "", + "checkFrequency": "Frekansı denetle", + "matchMethod": "", + "expectedValue": "Beklenen değer", + "deleteDialogTitle": "Gerçekten bu monitörü silmek istiyor musunuz?", + "deleteDialogDescription": "Bir kez silindiği zaman tekrar getiremezsiniz.", + "pageSpeedMonitor": "Sayfa Hızı Monitörü", + "shown": "", + "ago": "", + "companyName": "Firma adı", + "pageSpeedDetailsPerformanceReport": "", + "pageSpeedDetailsPerformanceReportCalculator": "Hesap makinesini gör", + "checkingEvery": "Denetleme sıklığı", + "statusPageCreateSettings": "Eğer durum sayfanız hazırsa, herkese açık yayınlayabilirsiniz", + "basicInformation": "Temel Bilgiler", + "statusPageCreateBasicInfoDescription": "", + "statusPageCreateSelectTimeZoneDescription": "", + "statusPageCreateAppearanceDescription": "", + "statusPageCreateSettingsCheckboxLabel": "Yayınlandı ve herkese açık", + "statusPageCreateBasicInfoStatusPageAddress": "Durum sayfası adresiniz", + "statusPageCreateTabsContent": "Durum sayfası sunucuları", + "statusPageCreateTabsContentDescription": "", + "statusPageCreateTabsContentFeaturesDescription": "Durum sayfasında daha fazla bilgi göster", + "showCharts": "Çizelgeleri göster", + "showUptimePercentage": "", + "removeLogo": "Logoyu sil", + "statusPageStatus": "Herkese açık bir durum sayfası henüz oluşturulmadı.", + "statusPageStatusContactAdmin": "Lütfen yöneticinizle iletişime geçin.", + "statusPageStatusNotPublic": "Durum sayfası herkese açık değil.", + "statusPageStatusNoPage": "Burada bir durum sayfası bulunmuyor.", + "statusPageStatusServiceStatus": "Servis durumu", + "deleteStatusPage": "Gerçekten bu durum sayfasını silmek istiyor musunuz?", + "deleteStatusPageConfirm": "Evet, durum sayfasını sil", + "deleteStatusPageDescription": "Silindikten sonra durum sayfasını geri getiremezsiniz.", + "uptimeCreate": "", + "uptimeCreateJsonPath": "", + "uptimeCreateJsonPathQuery": "", + "maintenanceTableActionMenuDialogTitle": "Gerçekten bu bakım aralığını silmek istiyor musunuz?", + "infrastructureEditYour": "", + "infrastructureEditMonitor": "", + "infrastructureMonitorCreated": "", + "infrastructureMonitorUpdated": "", + "errorInvalidTypeId": "", + "pageSpeedWarning": "Uyarı: Google PageSpeed API anahtarı eklemediniz. Bu olmadan, PageSpeed monitörü çalışmayacaktır.", + "pageSpeedLearnMoreLink": "Daha fazla bilgi için tıklayın", + "pageSpeedAddApiKey": "API anahtarınızı nasıl ekleyeceğinizi öğrenin.", + "pageSpeedApiKeyFieldTitle": "Google PageSpeed API anahtarı", + "pageSpeedApiKeyFieldLabel": "PageSpeed API anahtarı", + "pageSpeedApiKeyFieldDescription": "PageSpeed izlemeyi etkinleştirmek için Google PageSpeed API anahtarınızı girin. Anahtarı güncellemek için Sıfırla'ya tıklayın.", + "pageSpeedApiKeyFieldResetLabel": "API anahtarı ayarlandı. Değiştirmek için Sıfırla'ya tıklayın.", + "reset": "Sıfırla", + "invalidFileFormat": "", + "invalidFileSize": "", + "ClickUpload": "", + "DragandDrop": "", + "MaxSize": "", + "SupportedFormats": "", + "FirstName": "Ad", + "LastName": "Soyad", + "EmailDescriptionText": "Mevcut e-postanız—değiştirilemez.", + "YourPhoto": "Profil fotoğrafı", + "PhotoDescriptionText": "Bu fotoğraf profil sayfanızda görüntülenecektir.", + "save": "", + "DeleteAccountTitle": "Hesabı kaldır", + "DeleteAccountButton": "Hesabı kaldır", + "DeleteDescriptionText": "Bu, hesabı ve tüm ilişkili verileri sunucudan kaldıracaktır. Bu geri alınamaz.", + "DeleteAccountWarning": "Hesabınızı kaldırmak, tekrar oturum açamayacağınız ve tüm verilerinizin kaldırılacağı anlamına gelir. Bu geri alınamaz.", + "DeleteWarningTitle": "Bu hesabı gerçekten kaldırmak istiyor musunuz?", + "authRegisterFirstName": "Ad", + "authRegisterLastName": "Soyad", + "authRegisterEmail": "E-posta", + "authRegisterEmailRequired": "Devam etmek için lütfen e-posta adresinizi girin", + "authRegisterEmailInvalid": "Lütfen geçerli bir e-posta adresi girin", + "bulkImport": { + "title": "Toplu İçe Aktar", + "selectFileTips": "Yüklemek için CSV dosyası seçin", + "selectFileDescription": " veya örneğimizi indirebilirsiniz", + "selectFile": "Dosya Seç", + "parsingFailed": "Ayrıştırma başarısız oldu", + "uploadSuccess": "Monitörler başarıyla oluşturuldu!", + "validationFailed": "Doğrulama başarısız oldu", + "noFileSelected": "Dosya seçilmedi", + "fallbackPage": "Sunucuların listesini toplu olarak yüklemek için bir dosya içe aktarın" + }, + "createNew": "Yeni oluştur", + "greeting": { + "prepend": "Merhaba", + "append": "Öğleden sonra senin oyun alanın—hadi onu muhteşem yapalım!", + "overview": "İşte {{type}} monitörlerinizin genel görünümü." + }, + "monitorStatus": { + "up": "aktif", + "down": "devre dışı", + "paused": "duraklatıldı" + }, + "roles": { + "superAdmin": "Süper yönetici", + "admin": "Yönetici", + "teamMember": "Takım üyesi", + "demoUser": "Demo kullanıcı" + }, + "teamPanel": { + "teamMembers": "Takım üyeleri", + "filter": { + "all": "Tümü", + "member": "Üye" + }, + "inviteTeamMember": "Takım üyesi davet et", + "inviteNewTeamMember": "Yeni takım üyesi davet et", + "inviteDescription": "Yeni bir takım üyesi eklediğinizde, tüm monitörlere erişim hakkı alacaktır.", + "email": "E-posta", + "selectRole": "Rol seçin", + "inviteLink": "Davet bağlantısı", + "cancel": "İptal", + "noMembers": "Bu role sahip takım üyesi bulunmamaktadır", + "getToken": "Token al", + "emailToken": "Token e-posta ile gönder", + "table": { + "name": "Ad", + "email": "E-posta", + "role": "Rol", + "created": "Oluşturuldu" + } + }, + "monitorState": { + "paused": "duraklatıldı", + "resumed": "devam ettirildi", + "active": "aktif" + }, + "menu": { + "uptime": "Çalışma Süresi", + "pagespeed": "Sayfa Hızı", + "infrastructure": "Altyapı", + "distributedUptime": "Dağıtılmış Çalışma Süresi", + "incidents": "Olaylar", + "statusPages": "Durum Sayfaları", + "maintenance": "Bakım", + "integrations": "Entegrasyonlar", + "settings": "Ayarlar", + "support": "Destek", + "discussions": "Tartışmalar", + "docs": "Belgeler", + "changelog": "Değişiklik Günlüğü", + "profile": "Profil", + "password": "Şifre", + "team": "Takım", + "logOut": "Çıkış" + }, + "navControls": "Kontroller", + "statusBreadCrumbsStatusPages": "Durum Sayfaları", + "statusBreadCrumbsDetails": "Detaylar", + "incidentsPageTitle": "Olaylar", + "passwordPanel": { + "passwordChangedSuccess": "Şifreniz başarıyla değiştirildi.", + "passwordInputIncorrect": "Şifre girişiniz yanlış.", + "currentPassword": "Mevcut şifre", + "enterCurrentPassword": "Mevcut şifrenizi girin", + "newPassword": "Yeni şifre", + "enterNewPassword": "Yeni şifrenizi girin", + "confirmNewPassword": "Yeni şifreyi onaylayın", + "passwordRequirements": "Yeni şifre en az 8 karakter içermeli ve en az bir büyük harf, bir küçük harf, bir rakam ve bir özel karakter içermelidir.", + "saving": "Kaydediliyor..." + }, + "uptimeCreateSelectURL": "İzlenecek URL veya IP adresini girin (örn. https://example.com/ veya 192.168.1.100) ve kontrol panelinde görünecek net bir görüntü adı ekleyin." +}