diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 22252c301..b267220e8 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -13,7 +13,11 @@ Mention the issue number(s) this PR addresses (e.g., #123).
- [ ] (Do not skip this or your PR will be closed) I deployed the application locally.
- [ ] (Do not skip this or your PR will be closed) I have performed a self-review and testing of my code.
- [ ] I have included the issue # in the PR.
-- [ ] I have labelled the PR correctly.
+- [ ] I have added i18n support to visible strings (instead of `
Add
`, use):
+```Javascript
+const { t } = useTranslation();
+{t('add')}
+```
- [ ] The issue I am working on is assigned to me.
- [ ] I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
- [ ] I made sure font sizes, color choices etc are all referenced from the theme. I have no hardcoded dimensions.
diff --git a/.github/scripts/download-translations.js b/.github/scripts/download-translations.js
index 62f63a6a0..918be97d3 100644
--- a/.github/scripts/download-translations.js
+++ b/.github/scripts/download-translations.js
@@ -57,11 +57,12 @@ async function downloadTranslations() {
});
}
- // Save file
- const outputPath = path.join(process.cwd(), 'temp', `${language}.json`);
+ // Determine the output filename based on language
+ const filename = language === 'en' ? 'gb.json' : `${language}.json`;
+ const outputPath = path.join(process.cwd(), 'temp', filename);
await fs.writeJson(outputPath, formattedTranslations, { spaces: 2 });
- console.log(`Translations for ${language} language successfully downloaded and saved: ${outputPath}`);
+ console.log(`Translations for ${language} language successfully downloaded and saved as: ${filename}`);
}
console.log('All translations successfully downloaded!');
diff --git a/.github/workflows/poeditor-sync.yml b/.github/workflows/poeditor-sync.yml
index 1f1194e3e..711d9825d 100644
--- a/.github/workflows/poeditor-sync.yml
+++ b/.github/workflows/poeditor-sync.yml
@@ -17,15 +17,24 @@ on:
schedule:
- cron: "0 0 * * *"
+permissions:
+ contents: write
+ pull-requests: write
+
jobs:
sync-translations:
runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v3
@@ -83,10 +92,27 @@ jobs:
cp -r temp/* src/locales/
echo "Translation files copied to src/locales/"
- - name: Commit changes
- run: |
- git config --local user.email "github-actions[bot]@users.noreply.github.com"
- git config --local user.name "github-actions[bot]"
- git add src/locales/*.json
- git diff --staged --quiet || git commit -m "Translations updated from POEditor"
- git push
+ - name: Get current date
+ id: date
+ run: echo "date=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v7
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ commit-message: "feat: translations updated from POEditor"
+ title: "🌐 Updated Translations from POEditor"
+ body: |
+ This PR contains the latest translations from POEditor.
+
+ 📅 Update Date: ${{ steps.date.outputs.date }}
+ 🔄 Updated Languages: ${{ github.event.inputs.languages || 'tr,en' }}
+
+ ⚠️ Please review the translations and approve the PR if everything looks correct.
+ branch: translation-update-${{ github.run_number }}
+ delete-branch: true
+ base: develop
+ add-paths: |
+ src/locales/*.json
+ committer: GitHub Action
+ author: GitHub Action
diff --git a/.github/workflows/upload-poeditor.yml b/.github/workflows/upload-poeditor.yml
index bdd2b8fbf..988463d4b 100644
--- a/.github/workflows/upload-poeditor.yml
+++ b/.github/workflows/upload-poeditor.yml
@@ -51,14 +51,26 @@ jobs:
id: changed-files
if: github.event_name == 'pull_request'
run: |
- # Get list of changed files in src/locales directory
- CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} -- src/locales/*.json)
- echo "Changed files: $CHANGED_FILES"
+ # Get base and head commits
+ BASE_SHA=${{ github.event.pull_request.base.sha }}
+ HEAD_SHA=${{ github.event.pull_request.head.sha }}
- # Create a JSON array of changed files with language codes
- echo "CHANGED_FILES<> $GITHUB_ENV
- echo "$CHANGED_FILES" >> $GITHUB_ENV
- echo "EOF" >> $GITHUB_ENV
+ echo "Base SHA: $BASE_SHA"
+ echo "Head SHA: $HEAD_SHA"
+
+ # Get list of changed files in src/locales directory
+ CHANGED_FILES=$(git diff --name-only $BASE_SHA..$HEAD_SHA -- 'src/locales/*.json' || git ls-files 'src/locales/*.json')
+
+ if [ -z "$CHANGED_FILES" ]; then
+ echo "No changes detected in locale files"
+ echo "CHANGED_FILES=" >> $GITHUB_ENV
+ else
+ echo "Changed files:"
+ echo "$CHANGED_FILES"
+ echo "CHANGED_FILES<> $GITHUB_ENV
+ echo "$CHANGED_FILES" >> $GITHUB_ENV
+ echo "EOF" >> $GITHUB_ENV
+ fi
- name: Upload changed translations to POEditor
if: env.CHANGED_FILES != ''
diff --git a/README.md b/README.md
index 5505f72fe..6d197cc08 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,6 @@ If you have any questions, suggestions or comments, please use our [Discord chan
- Status pages (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1131
- Translations (i18n) (**in progress**)
- Better notification options (Webhooks, Discord, Telegram, Slack) (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1545
-- Command line interface (CLI) (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1558
- JSON query monitoring https://github.com/bluewave-labs/Checkmate/issues/1573
- Tagging/grouping monitors https://github.com/bluewave-labs/Checkmate/issues/1546
- More configuration options
@@ -107,7 +106,9 @@ If you have any questions, suggestions or comments, please use our [Discord chan
## 🤝 Contributing
-We pride ourselves on building strong connections with contributors at every level. Despite being a young project, Checkmate has already earned 4.4K+ stars and attracted 50+ contributors from around the globe.
+We are [@ajhollid](http://github.com/ajhollid) (team lead), [@vishnusn77](http://github.com/vishnusn77), [@mohicody](http://github.com/mohicody), [@gorkem-bwl](http://github.com/gorkem-bwl/) and [@Owaiseimdad](http://github.com/Owaiseimdad), helping individuals and businesses monitor their infra and servers.
+
+We pride ourselves on building strong connections with contributors at every level. Despite being a young project, Checkmate has already earned 4.6K+ stars and attracted 60 contributors from around the globe.
Our repo is starred by employees from **Google, Microsoft, Intel, Cisco, Tencent, Electronic Arts, ByteDance, JP Morgan Chase, Deloitte, Accenture, Foxconn, Broadcom, China Telecom, Barclays, Capgemini, Wipro, Cloudflare, Dassault Systèmes and NEC**, so don’t hold back — jump in, contribute and learn with us!
diff --git a/package-lock.json b/package-lock.json
index 5120f576b..b918b9b04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1973,9 +1973,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.26.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz",
- "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
+ "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -9189,9 +9189,9 @@
}
},
"node_modules/axios": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.2.tgz",
- "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==",
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz",
+ "integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -12525,9 +12525,9 @@
}
},
"node_modules/i18next": {
- "version": "24.2.2",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.2.tgz",
- "integrity": "sha512-NE6i86lBCKRYZa5TaUDkU5S4HFgLIEJRLr3Whf2psgaxBleQ2LC1YW1Vc+SCgkAW7VEzndT6al6+CzegSUHcTQ==",
+ "version": "24.2.3",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.3.tgz",
+ "integrity": "sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==",
"funding": [
{
"type": "individual",
@@ -12542,8 +12542,9 @@
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
+ "license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.23.2"
+ "@babel/runtime": "^7.26.10"
},
"peerDependencies": {
"typescript": "^5"
diff --git a/src/Components/Charts/BarChart/index.jsx b/src/Components/Charts/BarChart/index.jsx
index 101afe648..375773b94 100644
--- a/src/Components/Charts/BarChart/index.jsx
+++ b/src/Components/Charts/BarChart/index.jsx
@@ -58,7 +58,7 @@ const BarChart = ({ checks = [] }) => {
<>
{formatDateWithTz(
- check.createdAt,
+ check.updatedAt,
"ddd, MMMM D, YYYY, HH:mm A",
uiTimezone
)}
diff --git a/src/Components/Table/TablePagination/index.jsx b/src/Components/Table/TablePagination/index.jsx
index 8427f4270..44b127d45 100644
--- a/src/Components/Table/TablePagination/index.jsx
+++ b/src/Components/Table/TablePagination/index.jsx
@@ -15,6 +15,14 @@ Pagination.propTypes = {
const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25];
+// Determine whether pagination buttons should be shown
+const shouldShowPaginationButtons = (itemCount, rowsPerPage) => {
+ return Math.ceil(itemCount / rowsPerPage) > 1;
+};
+
+// Empty action component for pagination (no-op component)
+const EmptyPaginationActions = () =>
;
+
/**
* Pagination component for table navigation with customized styling and behavior.
*
@@ -41,6 +49,8 @@ function Pagination({
const end = Math.min(page * rowsPerPage + rowsPerPage, itemCount);
const range = `${start} - ${end}`;
+ const showPaginationButtons = shouldShowPaginationButtons(itemCount, rowsPerPage);
+
return (
`Page ${page + 1} of ${Math.max(0, Math.ceil(count / rowsPerPage))}`
diff --git a/src/Pages/DistributedUptimeStatus/Status/Hooks/useDUStatusPageFetchByUrl.jsx b/src/Hooks/useFetchDepinStatusPage.js
similarity index 80%
rename from src/Pages/DistributedUptimeStatus/Status/Hooks/useDUStatusPageFetchByUrl.jsx
rename to src/Hooks/useFetchDepinStatusPage.js
index b1b0542a4..cb436d6d6 100644
--- a/src/Pages/DistributedUptimeStatus/Status/Hooks/useDUStatusPageFetchByUrl.jsx
+++ b/src/Hooks/useFetchDepinStatusPage.js
@@ -1,11 +1,11 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../../../main";
-import { createToast } from "../../../../Utils/toastUtils";
+import { networkService } from "../main";
+import { createToast } from "../Utils/toastUtils";
import { useSelector } from "react-redux";
import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../../Hooks/useMonitorUtils";
+import { useMonitorUtils } from "./useMonitorUtils";
-const useDUStatusPageFetchByUrl = ({ url, timeFrame, isCreate = false }) => {
+const useFetchDepinStatusPage = ({ url, timeFrame, isCreate = false }) => {
const [isLoading, setIsLoading] = useState(true);
const [networkError, setNetworkError] = useState(false);
const [statusPage, setStatusPage] = useState(undefined);
@@ -50,9 +50,9 @@ const useDUStatusPageFetchByUrl = ({ url, timeFrame, isCreate = false }) => {
}
};
fetchStatusPageByUrl();
- }, [authToken, url, getMonitorWithPercentage, theme, timeFrame]);
+ }, [authToken, url, getMonitorWithPercentage, theme, timeFrame, isCreate]);
return [isLoading, networkError, statusPage, monitorId, isPublished];
};
-export { useDUStatusPageFetchByUrl };
+export { useFetchDepinStatusPage };
diff --git a/src/Hooks/useFetchMonitorsWithChecks.js b/src/Hooks/useFetchMonitorsWithChecks.js
new file mode 100644
index 000000000..f318c4b69
--- /dev/null
+++ b/src/Hooks/useFetchMonitorsWithChecks.js
@@ -0,0 +1,70 @@
+import { useEffect, useState } from "react";
+import { networkService } from "../main";
+import { createToast } from "../Utils/toastUtils";
+import { useTheme } from "@emotion/react";
+import { useMonitorUtils } from "./useMonitorUtils";
+
+export const useFetchMonitorsWithChecks = ({
+ teamId,
+ types,
+ limit,
+ page,
+ rowsPerPage,
+ filter,
+ field,
+ order,
+}) => {
+ const [isLoading, setIsLoading] = useState(false);
+ const [count, setCount] = useState(undefined);
+ const [monitors, setMonitors] = useState(undefined);
+ const [networkError, setNetworkError] = useState(false);
+
+ const theme = useTheme();
+ const { getMonitorWithPercentage } = useMonitorUtils();
+ useEffect(() => {
+ const fetchMonitors = async () => {
+ try {
+ setIsLoading(true);
+ const res = await networkService.getMonitorsWithChecksByTeamId({
+ teamId,
+ limit,
+ types,
+ page,
+ rowsPerPage,
+ filter,
+ field,
+ order,
+ });
+ const { count, monitors } = res?.data?.data ?? {};
+ const mappedMonitors = monitors.map((monitor) =>
+ getMonitorWithPercentage(monitor, theme)
+ );
+ setMonitors(mappedMonitors);
+ setCount(count?.monitorsCount ?? 0);
+ } catch (error) {
+ console.error(error);
+ setNetworkError(true);
+ createToast({
+ body: error.message,
+ });
+ } finally {
+ setIsLoading(false);
+ }
+ };
+ fetchMonitors();
+ }, [
+ field,
+ filter,
+ getMonitorWithPercentage,
+ limit,
+ order,
+ page,
+ rowsPerPage,
+ teamId,
+ theme,
+ types,
+ ]);
+ return [monitors, count, isLoading, networkError];
+};
+
+export default useFetchMonitorsWithChecks;
diff --git a/src/Hooks/useFetchMonitorsWithSummary.js b/src/Hooks/useFetchMonitorsWithSummary.js
new file mode 100644
index 000000000..7d1b6ec78
--- /dev/null
+++ b/src/Hooks/useFetchMonitorsWithSummary.js
@@ -0,0 +1,37 @@
+import { useEffect, useState } from "react";
+import { networkService } from "../main";
+import { createToast } from "../Utils/toastUtils";
+
+export const useFetchMonitorsWithSummary = ({ teamId, types }) => {
+ const [isLoading, setIsLoading] = useState(false);
+ const [monitors, setMonitors] = useState(undefined);
+ const [monitorsSummary, setMonitorsSummary] = useState(undefined);
+ const [networkError, setNetworkError] = useState(false);
+
+ useEffect(() => {
+ const fetchMonitors = async () => {
+ try {
+ setIsLoading(true);
+ const res = await networkService.getMonitorsWithSummaryByTeamId({
+ teamId,
+ types,
+ });
+ const { monitors, summary } = res?.data?.data ?? {};
+ setMonitors(monitors);
+ setMonitorsSummary(summary);
+ } catch (error) {
+ console.error(error);
+ setNetworkError(true);
+ createToast({
+ body: error.message,
+ });
+ } finally {
+ setIsLoading(false);
+ }
+ };
+ fetchMonitors();
+ }, [teamId, types]);
+ return [monitors, monitorsSummary, isLoading, networkError];
+};
+
+export default useFetchMonitorsWithSummary;
diff --git a/src/Pages/DistributedUptime/Details/Hooks/useSubscribeToDetails.jsx b/src/Hooks/useSubscribeToDepinDetails.js
similarity index 90%
rename from src/Pages/DistributedUptime/Details/Hooks/useSubscribeToDetails.jsx
rename to src/Hooks/useSubscribeToDepinDetails.js
index e8a49e886..67b7c898f 100644
--- a/src/Pages/DistributedUptime/Details/Hooks/useSubscribeToDetails.jsx
+++ b/src/Hooks/useSubscribeToDepinDetails.js
@@ -1,8 +1,8 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../../../main";
-import { createToast } from "../../../../Utils/toastUtils";
+import { networkService } from "../main";
+import { createToast } from "../Utils/toastUtils";
-const useSubscribeToDetails = ({ monitorId, isPublic, isPublished, dateRange }) => {
+const useSubscribeToDepinDetails = ({ monitorId, isPublic, isPublished, dateRange }) => {
const [isLoading, setIsLoading] = useState(true);
const [connectionStatus, setConnectionStatus] = useState(undefined);
const [retryCount, setRetryCount] = useState(0);
@@ -92,4 +92,4 @@ const useSubscribeToDetails = ({ monitorId, isPublic, isPublished, dateRange })
return [isLoading, networkError, connectionStatus, monitor, lastUpdateTrigger];
};
-export { useSubscribeToDetails };
+export { useSubscribeToDepinDetails };
diff --git a/src/Pages/DistributedUptime/Monitors/Hooks/useSubscribeToMonitors.jsx b/src/Hooks/useSubscribeToDepinMonitors.js
similarity index 65%
rename from src/Pages/DistributedUptime/Monitors/Hooks/useSubscribeToMonitors.jsx
rename to src/Hooks/useSubscribeToDepinMonitors.js
index 3b6c262ba..3bc098afa 100644
--- a/src/Pages/DistributedUptime/Monitors/Hooks/useSubscribeToMonitors.jsx
+++ b/src/Hooks/useSubscribeToDepinMonitors.js
@@ -1,20 +1,19 @@
import { useEffect, useState } from "react";
-import { networkService } from "../../../../main";
+import { networkService } from "../main";
import { useSelector } from "react-redux";
import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../../Hooks/useMonitorUtils";
-import { createToast } from "../../../../Utils/toastUtils";
+import { useMonitorUtils } from "./useMonitorUtils";
+import { createToast } from "../Utils/toastUtils";
-const useSubscribeToMonitors = (page, rowsPerPage) => {
+const useSubscribeToDepinMonitors = (page, rowsPerPage) => {
// Redux
const { user } = useSelector((state) => state.auth);
// Local state
const [isLoading, setIsLoading] = useState(true);
const [networkError, setNetworkError] = useState(false);
+ const [count, setCount] = useState(undefined);
const [monitors, setMonitors] = useState(undefined);
- const [monitorsSummary, setMonitorsSummary] = useState(undefined);
- const [filteredMonitors, setFilteredMonitors] = useState(undefined);
const theme = useTheme();
const { getMonitorWithPercentage } = useMonitorUtils();
@@ -29,18 +28,17 @@ const useSubscribeToMonitors = (page, rowsPerPage) => {
page,
rowsPerPage,
});
+
+ const { count, monitors } = initialDataRes?.data?.data ?? {};
const responseData = initialDataRes?.data?.data;
if (typeof responseData === "undefined") throw new Error("No data");
- const { monitors, filteredMonitors, summary } = responseData;
-
- const mappedMonitors = filteredMonitors?.map((monitor) =>
+ const mappedMonitors = monitors?.map((monitor) =>
getMonitorWithPercentage(monitor, theme)
);
- setMonitors(monitors);
- setMonitorsSummary(summary);
- setFilteredMonitors(mappedMonitors);
+ setMonitors(mappedMonitors);
+ setCount(count?.monitorsCount ?? 0);
} catch (error) {
setNetworkError(true);
createToast({
@@ -71,15 +69,12 @@ const useSubscribeToMonitors = (page, rowsPerPage) => {
if (isLoading === true) {
setIsLoading(false);
}
-
- const res = data.monitors;
- const { monitors, filteredMonitors, summary } = res;
- const mappedMonitors = filteredMonitors.map((monitor) =>
+ const { count, monitors } = data;
+ const mappedMonitors = monitors.map((monitor) =>
getMonitorWithPercentage(monitor, theme)
);
- setMonitors(monitors);
- setMonitorsSummary(summary);
- setFilteredMonitors(mappedMonitors);
+ setMonitors(mappedMonitors);
+ setCount(count?.monitorsCount ?? 0);
},
onError: () => {
setIsLoading(false);
@@ -94,6 +89,6 @@ const useSubscribeToMonitors = (page, rowsPerPage) => {
setNetworkError(true);
}
}, [user, getMonitorWithPercentage, theme, isLoading, page, rowsPerPage]);
- return [isLoading, networkError, monitors, monitorsSummary, filteredMonitors];
+ return [monitors, count, isLoading, networkError];
};
-export { useSubscribeToMonitors };
+export { useSubscribeToDepinMonitors };
diff --git a/src/Pages/Auth/Login/Login.jsx b/src/Pages/Auth/Login/Login.jsx
index 60aaed6ba..c13218018 100644
--- a/src/Pages/Auth/Login/Login.jsx
+++ b/src/Pages/Auth/Login/Login.jsx
@@ -142,7 +142,7 @@ const Login = () => {
overflow="hidden"
sx={{
"& h1": {
- color: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
fontWeight: 600,
fontSize: 28,
},
diff --git a/src/Pages/Auth/Register/Register.jsx b/src/Pages/Auth/Register/Register.jsx
index 021cda18a..afb05435c 100644
--- a/src/Pages/Auth/Register/Register.jsx
+++ b/src/Pages/Auth/Register/Register.jsx
@@ -35,7 +35,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
textAlign="center"
>
- {t("signUP")}
+ {t("signUp")}
{isSuperAdmin
? t("authRegisterCreateSuperAdminAccount")
@@ -83,9 +83,9 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
},
}}
>
- Terms of Service
+ {t("authRegisterTerms")}
{" "}
- and{" "}
+ {t("and")}{" "}
{
@@ -101,7 +101,7 @@ const LandingPage = ({ isSuperAdmin, onSignup }) => {
},
}}
>
- Privacy Policy.
+ {t("authRegisterPrivacy")}
@@ -283,7 +283,7 @@ const Register = ({ isSuperAdmin }) => {
overflow="hidden"
sx={{
"& h1": {
- color: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
fontWeight: 600,
fontSize: 28,
},
@@ -370,7 +370,7 @@ const Register = ({ isSuperAdmin }) => {
p={theme.spacing(12)}
>
- {t("authRegisterAlreadyHaveAccount")} -
+ {t("authRegisterAlreadyHaveAccount")}
{
onClick={() => {
navigate("/login");
}}
- sx={{ userSelect: "none", color: theme.palette.primary.main }}
+ sx={{ userSelect: "none", color: theme.palette.accent.main }}
>
{t("authLoginTitle")}
diff --git a/src/Pages/DistributedUptime/Details/Hooks/useDeleteMonitor.jsx b/src/Pages/DistributedUptime/Details/Hooks/useDeleteMonitor.jsx
index 8d73e55a9..a26de2a5e 100644
--- a/src/Pages/DistributedUptime/Details/Hooks/useDeleteMonitor.jsx
+++ b/src/Pages/DistributedUptime/Details/Hooks/useDeleteMonitor.jsx
@@ -1,4 +1,3 @@
-import { useSelector } from "react-redux";
import { useState } from "react";
import { networkService } from "../../../../main";
import { createToast } from "../../../../Utils/toastUtils";
diff --git a/src/Pages/DistributedUptime/Details/index.jsx b/src/Pages/DistributedUptime/Details/index.jsx
index d2011709e..27b39b600 100644
--- a/src/Pages/DistributedUptime/Details/index.jsx
+++ b/src/Pages/DistributedUptime/Details/index.jsx
@@ -19,7 +19,7 @@ import { useTheme } from "@mui/material/styles";
import { useState } from "react";
import { useParams } from "react-router-dom";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
-import { useSubscribeToDetails } from "./Hooks/useSubscribeToDetails";
+import { useSubscribeToDepinDetails } from "../../../Hooks/useSubscribeToDepinDetails";
import { useDeleteMonitor } from "./Hooks/useDeleteMonitor";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
@@ -36,7 +36,7 @@ const DistributedUptimeDetails = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const [isLoading, networkError, connectionStatus, monitor, lastUpdateTrigger] =
- useSubscribeToDetails({ monitorId, dateRange });
+ useSubscribeToDepinDetails({ monitorId, dateRange });
const [deleteMonitor, isDeleting] = useDeleteMonitor({ monitorId });
// Constants
diff --git a/src/Pages/DistributedUptime/Monitors/index.jsx b/src/Pages/DistributedUptime/Monitors/index.jsx
index 097f0128c..d2cea7432 100644
--- a/src/Pages/DistributedUptime/Monitors/index.jsx
+++ b/src/Pages/DistributedUptime/Monitors/index.jsx
@@ -11,7 +11,7 @@ import GenericFallback from "../../../Components/GenericFallback";
import { useState } from "react";
import { useTheme } from "@mui/material/styles";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
-import { useSubscribeToMonitors } from "./Hooks/useSubscribeToMonitors";
+import { useSubscribeToDepinMonitors } from "../../../Hooks/useSubscribeToDepinMonitors";
import SkeletonLayout from "./Components/Skeleton";
import { useTranslation } from "react-i18next";
// Constants
@@ -26,8 +26,10 @@ const DistributedUptimeMonitors = () => {
const theme = useTheme();
const isAdmin = useIsAdmin();
const { t } = useTranslation();
- const [isLoading, networkError, monitors, monitorsSummary, filteredMonitors] =
- useSubscribeToMonitors(page, rowsPerPage);
+ const [monitors, count, isLoading, networkError] = useSubscribeToDepinMonitors(
+ page,
+ rowsPerPage
+ );
// Handlers
const handleChangePage = (event, newPage) => {
setPage(newPage);
@@ -57,7 +59,7 @@ const DistributedUptimeMonitors = () => {
);
}
- if (typeof monitorsSummary === "undefined" || monitorsSummary.totalMonitors === 0) {
+ if (count === 0) {
return (
{
/>
{
const theme = useTheme();
const { monitorId, url } = useParams();
const navigate = useNavigate();
+ const { t } = useTranslation();
const isCreate = typeof url === "undefined";
const [createStatusPage, isLoading, networkError] = useCreateStatusPage(isCreate);
const [statusPageIsLoading, statusPageNetworkError, statusPage, _, isPublished] =
- useDUStatusPageFetchByUrl({
+ useFetchDepinStatusPage({
url,
timeFrame: 30,
isCreate,
@@ -176,7 +177,9 @@ const CreateStatus = () => {
component="span"
fontSize="inherit"
>
- {isCreate ? "Create your" : "Edit your"}{" "}
+ {isCreate
+ ? t("distributedUptimeStatusCreateYour")
+ : t("distributedUptimeStatusEditYour")}{" "}
{
fontSize="inherit"
fontWeight="inherit"
>
- status page
+ {t("distributedUptimeStatusCreateStatusPage")}
- Access
+
+ {t("distributedUptimeStatusCreateStatusPageAccess")}
+
- If your status page is ready, you can mark it as published.
+ {t("distributedUptimeStatusCreateStatusPageReady")}
@@ -206,9 +211,11 @@ const CreateStatus = () => {
- Basic Information
+
+ {t("distributedUptimeStatusBasicInfoHeader")}
+
- Define company name and the subdomain that your status page points to.
+ {t("distributedUptimeStatusBasicInfoDescription")}
@@ -216,7 +223,7 @@ const CreateStatus = () => {
id="companyName"
name="companyName"
type="text"
- label="Company name"
+ label={t("distributedUptimeStatusCompanyNameLabel")}
placeholder="Company name"
value={form.companyName}
onChange={handleFormChange}
@@ -227,7 +234,7 @@ const CreateStatus = () => {
id="url"
name="url"
type="url"
- label="Your status page address"
+ label={t("distributedUptimeStatusPageAddressLabel")}
disabled={!isCreate}
value={form.url}
onChange={handleFormChange}
@@ -238,8 +245,10 @@ const CreateStatus = () => {
- Logo
- Upload a logo for your status page
+ {t("distributedUptimeStatusLogoHeader")}
+
+ {t("distributedUptimeStatusLogoDescription")}{" "}
+
{
color="accent"
tabIndex={-1}
>
- Upload logo
+ {t("distributedUptimeStatusLogoUploadButton")}
@@ -270,9 +279,11 @@ const CreateStatus = () => {
- Standard Monitors
+
+ {t("distributedUptimeStatusStandardMonitorsHeader")}
+
- Attach standard monitors to your status page.
+ {t("distributedUptimeStatusStandardMonitorsDescription")}
@@ -301,7 +312,7 @@ const CreateStatus = () => {
color="accent"
onClick={handleSubmit}
>
- Save
+ {t("settingsSave")}
diff --git a/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx b/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx
index 5ec509376..7ee4ff292 100644
--- a/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx
+++ b/src/Pages/DistributedUptimeStatus/Status/Components/TimeframeHeader/index.jsx
@@ -1,8 +1,10 @@
import { Stack, Button, ButtonGroup } from "@mui/material";
import { useTheme } from "@emotion/react";
+import { useTranslation } from "react-i18next";
const TimeFrameHeader = ({ timeFrame, setTimeFrame, sx, ...props }) => {
const theme = useTheme();
+ const { t } = useTranslation();
return (
{
filled={(timeFrame === 30).toString()}
onClick={() => setTimeFrame(30)}
>
- 30 days
+ {t("distributedUptimeStatus30Days")}
setTimeFrame(60)}
>
- 60 days
+ {t("distributedUptimeStatus60Days")}
setTimeFrame(90)}
>
- 90 days
+ {t("distributedUptimeStatus90Days")}
diff --git a/src/Pages/DistributedUptimeStatus/Status/index.jsx b/src/Pages/DistributedUptimeStatus/Status/index.jsx
index 515bd9be5..117a297e5 100644
--- a/src/Pages/DistributedUptimeStatus/Status/index.jsx
+++ b/src/Pages/DistributedUptimeStatus/Status/index.jsx
@@ -23,8 +23,8 @@ import { RowContainer } from "../../../Components/StandardContainer";
import { useTheme } from "@mui/material/styles";
import { useState, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
-import { useSubscribeToDetails } from "../../DistributedUptime/Details/Hooks/useSubscribeToDetails";
-import { useDUStatusPageFetchByUrl } from "./Hooks/useDUStatusPageFetchByUrl";
+import { useFetchDepinStatusPage } from "../../../Hooks/useFetchDepinStatusPage";
+import { useSubscribeToDepinDetails } from "../../../Hooks/useSubscribeToDepinDetails";
import { useStatusPageDelete } from "../../StatusPage/Status/Hooks/useStatusPageDelete";
import TimeFrameHeader from "./Components/TimeframeHeader";
import SubHeader from "../../../Components/Subheader";
@@ -64,13 +64,13 @@ const DistributedUptimeStatus = () => {
statusPage,
monitorId,
isPublished,
- ] = useDUStatusPageFetchByUrl({
+ ] = useFetchDepinStatusPage({
url,
timeFrame,
});
const [isLoading, networkError, connectionStatus, monitor, lastUpdateTrigger] =
- useSubscribeToDetails({ monitorId, dateRange, isPublic, isPublished });
+ useSubscribeToDepinDetails({ monitorId, dateRange, isPublic, isPublished });
const [deleteStatusPage, isDeleting] = useStatusPageDelete(() => {
navigate("/distributed-uptime");
@@ -124,9 +124,9 @@ const DistributedUptimeStatus = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
- A status page is not set up.
+ {t("distributedUptimeStatusPageNotSetUp")}
- Please contact your administrator
+ {t("distributedUptimeStatusContactAdmin")}
);
@@ -137,7 +137,7 @@ const DistributedUptimeStatus = () => {
return (
- This status page is not public.
+ {t("distributedUptimeStatusPageNotPublic")}
);
@@ -155,9 +155,9 @@ const DistributedUptimeStatus = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
- Network error
+ {t("networkError")}
- Please check your connection
+ {t("checkConnection")}
);
}
@@ -171,7 +171,7 @@ const DistributedUptimeStatus = () => {
- There is no check history for this monitor yet.
+ {t("distributedUptimeDetailsNoMonitorHistory")}
);
@@ -246,17 +246,21 @@ const DistributedUptimeStatus = () => {
gap={theme.spacing(8)}
>
@@ -295,7 +299,7 @@ const DistributedUptimeStatus = () => {
{
deleteStatusPage();
setIsDeleteOpen(false);
@@ -304,8 +308,8 @@ const DistributedUptimeStatus = () => {
setIsDeleteOpen(false);
}}
open={isDeleteOpen}
- confirmationButtonLabel="Yes, delete status page"
- description="Once deleted, your status page cannot be retrieved."
+ confirmationButtonLabel={t("distributedUptimeStatusPageDeleteConfirm")}
+ description={t("distributedUptimeStatusPageDeleteDescription")}
isLoading={isDeleting || isLoading}
/>
diff --git a/src/Pages/Incidents/Components/IncidentTable/index.jsx b/src/Pages/Incidents/Components/IncidentTable/index.jsx
index 16adcee16..cc2d212f0 100644
--- a/src/Pages/Incidents/Components/IncidentTable/index.jsx
+++ b/src/Pages/Incidents/Components/IncidentTable/index.jsx
@@ -13,6 +13,7 @@ import { useSelector } from "react-redux";
import { useState } from "react";
import useChecksFetch from "../../Hooks/useChecksFetch";
import PropTypes from "prop-types";
+import { useTranslation } from "react-i18next";
const IncidentTable = ({
shouldRender,
@@ -38,6 +39,8 @@ const IncidentTable = ({
rowsPerPage,
});
+ const { t } = useTranslation();
+
//Handlers
const handleChangePage = (_, newPage) => {
setPage(newPage);
@@ -50,12 +53,12 @@ const IncidentTable = ({
const headers = [
{
id: "monitorName",
- content: "Monitor Name",
+ content: t("incidentsTableMonitorName"),
render: (row) => monitors[row.monitorId]?.name ?? "N/A",
},
{
id: "status",
- content: "Status",
+ content: t("incidentsTableStatus"),
render: (row) => {
const status = row.status === true ? "up" : "down";
return (
@@ -69,7 +72,7 @@ const IncidentTable = ({
},
{
id: "dateTime",
- content: "Date & Time",
+ content: t("incidentsTableDateTime"),
render: (row) => {
const formattedDate = formatDateWithTz(
row.createdAt,
@@ -81,10 +84,10 @@ const IncidentTable = ({
},
{
id: "statusCode",
- content: "Status Code",
+ content: t("incidentsTableStatusCode"),
render: (row) => ,
},
- { id: "message", content: "Message", render: (row) => row.message },
+ { id: "message", content: t("incidentsTableMessage"), render: (row) => row.message },
];
if (!shouldRender || isLoading) return ;
@@ -98,7 +101,7 @@ const IncidentTable = ({
}
if (!isLoading && typeof checksCount === "undefined") {
- return No incidents recorded ;
+ return {t("incidentsTableNoIncidents")} ;
}
return (
@@ -108,7 +111,7 @@ const IncidentTable = ({
data={checks}
/>
{
const theme = useTheme();
+ const { t } = useTranslation();
const monitorNames = typeof monitors !== "undefined" ? Object.values(monitors) : [];
// The stacks below which are three in number have the same style so
@@ -40,11 +42,11 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
- Incidents for:
+ {t("incidentsOptionsHeader")}
setSelectedMonitor(e.target.value)}
items={monitorNames}
@@ -61,7 +63,7 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
- Filter by:
+ {t("incidentsOptionsHeaderFilterBy")}
setFilter("all")}
>
- All
+ {t("incidentsOptionsHeaderFilterAll")}
setFilter("down")}
>
- Down
+ {t("incidentsOptionsHeaderFilterDown")}
setFilter("resolve")}
>
- Cannot resolve
+ {t("incidentsOptionsHeaderFilterCannotResolve")}
@@ -93,7 +95,7 @@ const OptionsHeader = ({
component="h1"
color={theme.palette.primary.contrastTextSecondary}
>
- Show:
+ {t("incidentsOptionsHeaderShow")}
setDateRange("hour")}
>
- Last hour
+ {t("incidentsOptionsHeaderLastHour")}
setDateRange("day")}
>
- Last day
+ {t("incidentsOptionsHeaderLastDay")}
setDateRange("week")}
>
- Last week
+ {t("incidentsOptionsHeaderLastWeek")}
setDateRange("all")}
>
- All
+ {t("incidentsOptionsHeaderFilterAll")}
diff --git a/src/Pages/Infrastructure/Create/index.jsx b/src/Pages/Infrastructure/Create/index.jsx
index 06c97195b..2c2a5505f 100644
--- a/src/Pages/Infrastructure/Create/index.jsx
+++ b/src/Pages/Infrastructure/Create/index.jsx
@@ -8,6 +8,7 @@ import { useSelector, useDispatch } from "react-redux";
import { infrastructureMonitorValidation } from "../../../Validation/validation";
import { createInfrastructureMonitor } from "../../../Features/InfrastructureMonitors/infrastructureMonitorsSlice";
import { capitalizeFirstLetter } from "../../../Utils/stringUtils";
+import { useTranslation } from "react-i18next";
// MUI
import { Box, Stack, Typography, Button, ButtonGroup } from "@mui/material";
@@ -52,6 +53,7 @@ const CreateInfrastructureMonitor = () => {
const monitorState = useSelector((state) => state.infrastructureMonitor);
const dispatch = useDispatch();
const navigate = useNavigate();
+ const { t } = useTranslation();
// State
const [errors, setErrors] = useState({});
@@ -233,7 +235,7 @@ const CreateInfrastructureMonitor = () => {
component="span"
fontSize="inherit"
>
- Create your{" "}
+ {t("infrastructureCreateYour")}{" "}
{
fontSize="inherit"
fontWeight="inherit"
>
- monitor
+ {t("monitor")}
- General settings
+ {t("settingsGeneralSettings")}
- Here you can select the URL of the host, together with the friendly name and
- authorization secret to connect to the server agent.
+ {t("infrastructureCreateGeneralSettingsDescription")}
- The server you are monitoring must be running the{" "}
+ {t("infrastructureServerRequirement")}{" "}
{
name="url"
startAdornment={ }
placeholder={"localhost:59232/api/v1/metrics"}
- label="Server URL"
+ label={t("infrastructureServerUrlLabel")}
https={https}
value={infrastructureMonitor.url}
onChange={handleChange}
@@ -275,21 +276,21 @@ const CreateInfrastructureMonitor = () => {
helperText={errors["url"]}
/>
- Protocol
+ {t("infrastructureProtocol")}
setHttps(true)}
>
- HTTPS
+ {t("https")}
setHttps(false)}
>
- HTTP
+ {t("http")}
@@ -297,7 +298,7 @@ const CreateInfrastructureMonitor = () => {
type="text"
id="name"
name="name"
- label="Display name"
+ label={t("infrastructureDisplayNameLabel")}
placeholder="Google"
isOptional={true}
value={infrastructureMonitor.name}
@@ -308,7 +309,7 @@ const CreateInfrastructureMonitor = () => {
type="text"
id="secret"
name="secret"
- label="Authorization secret"
+ label={t("infrastructureAuthorizationSecretLabel")}
value={infrastructureMonitor.secret}
onChange={handleChange}
error={errors["secret"] ? true : false}
@@ -318,9 +319,9 @@ const CreateInfrastructureMonitor = () => {
- Incident notifications
+ {t("distributedUptimeCreateIncidentNotification")}
- When there is an incident, notify users.
+ {t("distributedUptimeCreateIncidentDescription")}
@@ -337,10 +338,9 @@ const CreateInfrastructureMonitor = () => {
- Customize alerts
+ {t("infrastructureCustomizeAlerts")}
- Send a notification to user(s) when thresholds exceed a specified
- percentage.
+ {t("infrastructureAlertNotificationDescription")}
@@ -385,7 +385,7 @@ const CreateInfrastructureMonitor = () => {
- Advanced settings
+ {t("distributedUptimeCreateAdvancedSettings")}
{
onClick={handleCreateInfrastructureMonitor}
loading={monitorState?.isLoading}
>
- Create infrastructure monitor
+ {t("infrastructureCreateMonitor")}
diff --git a/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx b/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
index 4052b11b5..0eb3aa36d 100644
--- a/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
+++ b/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
@@ -12,8 +12,10 @@ import {
} from "../../../../../Components/Charts/Utils/chartUtils";
import { useTheme } from "@emotion/react";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
+import { useTranslation } from "react-i18next";
const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
const theme = useTheme();
+ const { t } = useTranslation();
const { buildTemps } = useHardwareUtils();
if (!shouldRender) {
@@ -31,10 +33,10 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
type: "memory",
data: checks,
dataKeys: ["avgMemoryUsage"],
- heading: "Memory usage",
+ heading: t("memoryUsage"),
strokeColor: theme.palette.accent.main, // CAIO_REVIEW
gradientStartColor: theme.palette.accent.main, // CAIO_REVIEW
- yLabel: "Memory usage",
+ yLabel: t("memoryUsage"),
yDomain: [0, 1],
yTick: ,
xTick: ,
@@ -51,10 +53,10 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
type: "cpu",
data: checks,
dataKeys: ["avgCpuUsage"],
- heading: "CPU usage",
+ heading: t("cpuUsage"),
strokeColor: theme.palette.success.main,
gradientStartColor: theme.palette.success.main,
- yLabel: "CPU usage",
+ yLabel: t("cpuUsage"),
yDomain: [0, 1],
yTick: ,
xTick: ,
@@ -73,7 +75,7 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
dataKeys: tempKeys,
strokeColor: theme.palette.error.main,
gradientStartColor: theme.palette.error.main,
- heading: "CPU Temperature",
+ heading: t("cpuTemperature"),
yLabel: "Temperature",
xTick: ,
yDomain: [
@@ -96,7 +98,7 @@ const AreaChartBoxes = ({ shouldRender, monitor, dateRange }) => {
heading: `Disk${idx} usage`,
strokeColor: theme.palette.warning.main,
gradientStartColor: theme.palette.warning.main,
- yLabel: "Disk Usage",
+ yLabel: t("diskUsage"),
yDomain: [0, 1],
yTick: ,
xTick: ,
diff --git a/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx b/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx
index 1d2e044ce..4dd978018 100644
--- a/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx
+++ b/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx
@@ -6,10 +6,12 @@ import SkeletonLayout from "./skeleton";
// Utils
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
import { useTheme } from "@emotion/react";
+import { useTranslation } from "react-i18next";
const Gauges = ({ shouldRender, monitor }) => {
const { decimalToPercentage, formatBytes } = useHardwareUtils();
const theme = useTheme();
+ const { t } = useTranslation();
if (!shouldRender) {
return ;
@@ -28,19 +30,19 @@ const Gauges = ({ shouldRender, monitor }) => {
{
type: "memory",
value: decimalToPercentage(memoryUsagePercent),
- heading: "Memory usage",
- metricOne: "Used",
+ heading: t("memoryUsage"),
+ metricOne: t("used"),
valueOne: formatBytes(memoryUsedBytes, true),
- metricTwo: "Total",
+ metricTwo: t("total"),
valueTwo: formatBytes(memoryTotalBytes, true),
},
{
type: "cpu",
value: decimalToPercentage(cpuUsagePercent),
- heading: "CPU usage",
- metricOne: "Cores",
+ heading: t("cpuUsage"),
+ metricOne: t("cores"),
valueOne: cpuPhysicalCores ?? 0,
- metricTwo: "Frequency",
+ metricTwo: t("frequency"),
valueTwo: `${(cpuFrequency / 1000).toFixed(2)} Ghz`,
},
...(latestCheck?.disk ?? []).map((disk, idx) => ({
@@ -48,9 +50,9 @@ const Gauges = ({ shouldRender, monitor }) => {
diskIndex: idx,
value: decimalToPercentage(disk.usage_percent),
heading: `Disk${idx} usage`,
- metricOne: "Used",
+ metricOne: t("used"),
valueOne: formatBytes(disk.total_bytes - disk.free_bytes, true),
- metricTwo: "Total",
+ metricTwo: t("total"),
valueTwo: formatBytes(disk.total_bytes, true),
})),
];
diff --git a/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx b/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
index aa7ab97ae..8dfe19a7b 100644
--- a/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
+++ b/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
@@ -6,11 +6,13 @@ import StatBox from "../../../../../Components/StatBox";
//Utils
import useUtils from "../../../../../Pages/Uptime/Monitors/Hooks/useUtils";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils";
+import { useTranslation } from "react-i18next";
const InfraStatBoxes = ({ shouldRender, monitor }) => {
// Utils
const { formatBytes } = useHardwareUtils();
const { statusStyles, determineState } = useUtils();
+ const { t } = useTranslation();
const { stats, uptimePercentage } = monitor ?? {};
const latestCheck = stats?.aggregateData?.latestCheck;
@@ -40,11 +42,11 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
>
{physicalCores}
@@ -54,7 +56,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
/>
{logicalCores}
@@ -63,7 +65,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
{(cpuFrequency / 1000).toFixed(2)}
@@ -72,7 +74,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
{cpuTemperature.toFixed(2)}
@@ -81,15 +83,15 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
}
/>
{(uptimePercentage * 100).toFixed(2)}
@@ -99,7 +101,7 @@ const InfraStatBoxes = ({ shouldRender, monitor }) => {
/>
diff --git a/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx b/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx
index 1752533d0..a2e4c5153 100644
--- a/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx
+++ b/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx
@@ -1,5 +1,6 @@
import { Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
+import { useTranslation } from "react-i18next";
// Constants
const BASE_BOX_PADDING_VERTICAL = 4;
@@ -9,6 +10,7 @@ const CHART_CONTAINER_HEIGHT = 300;
const useHardwareUtils = () => {
const theme = useTheme();
+ const { t } = useTranslation();
const getDimensions = () => {
const totalTypographyPadding = parseInt(theme.spacing(TYPOGRAPHY_PADDING), 10) * 2;
@@ -29,7 +31,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
- GB
+ {t("gb")}
>
);
if (typeof bytes !== "number")
@@ -37,7 +39,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
- GB
+ {t("gb")}
>
);
if (bytes === 0)
@@ -45,7 +47,7 @@ const useHardwareUtils = () => {
<>
{0}
{space ? " " : ""}
- GB
+ {t("gb")}
>
);
@@ -57,7 +59,7 @@ const useHardwareUtils = () => {
<>
{Number(GB.toFixed(0))}
{space ? " " : ""}
- GB
+ {t("gb")}
>
);
} else {
@@ -65,7 +67,7 @@ const useHardwareUtils = () => {
<>
{Number(MB.toFixed(0))}
{space ? " " : ""}
- MB
+ {t("mb")}
>
);
}
diff --git a/src/Pages/Infrastructure/Details/index.jsx b/src/Pages/Infrastructure/Details/index.jsx
index 00705d2e1..0006caf4e 100644
--- a/src/Pages/Infrastructure/Details/index.jsx
+++ b/src/Pages/Infrastructure/Details/index.jsx
@@ -13,6 +13,7 @@ import { useTheme } from "@emotion/react";
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
import { useHardwareMonitorsFetch } from "./Hooks/useHardwareMonitorsFetch";
import { useState } from "react";
+import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
// Constants
@@ -29,6 +30,7 @@ const InfrastructureDetails = () => {
// Utils
const theme = useTheme();
const { monitorId } = useParams();
+ const { t } = useTranslation();
const { isLoading, networkError, monitor } = useHardwareMonitorsFetch({
monitorId,
@@ -43,9 +45,9 @@ const InfrastructureDetails = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
- Network error
+ {t("networkError")}
- Please check your connection
+ {t("checkConnection")}
);
}
@@ -61,7 +63,7 @@ const InfrastructureDetails = () => {
monitor={monitor}
/>
- No check history for this monitor yet.
+ {t("distributedUptimeDetailsNoMonitorHistory")}
);
diff --git a/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx b/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
index 3f1832889..450aee424 100644
--- a/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
+++ b/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
@@ -13,10 +13,12 @@ import { useTheme } from "@emotion/react";
import useUtils from "../../../../Uptime/Monitors/Hooks/useUtils";
import { useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
+import { useTranslation } from "react-i18next";
const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete }) => {
// Utils
const theme = useTheme();
+ const { t } = useTranslation();
const { determineState } = useUtils();
const navigate = useNavigate();
@@ -27,7 +29,7 @@ const MonitorsTable = ({ shouldRender, monitors, isAdmin, handleActionMenuDelete
const headers = [
{
id: "host",
- content: "Host",
+ content: t("host"),
render: (row) => (
(
(
),
},
- { id: "cpu", content: "CPU", render: (row) => },
- { id: "mem", content: "Mem", render: (row) => },
- { id: "disk", content: "Disk", render: (row) => },
+ { id: "cpu", content: t("cpu"), render: (row) => },
+ { id: "mem", content: t("mem"), render: (row) => },
+ { id: "disk", content: t("disk"), render: (row) => },
{
id: "actions",
- content: "Actions",
+ content: t("actions"),
render: (row) => (
{
// Utils
const theme = useTheme();
const isAdmin = useIsAdmin();
+ const { t } = useTranslation();
// Handlers
const handleActionMenuDelete = () => {
@@ -52,9 +54,9 @@ const InfrastructureMonitors = () => {
marginY={theme.spacing(4)}
color={theme.palette.primary.contrastTextTertiary}
>
- Network error
+ {t("networkError")}
- Please check your connection
+ {t("checkConnection")}
);
}
@@ -96,7 +98,7 @@ const InfrastructureMonitors = () => {
/>
{
const theme = useTheme();
+ const { t } = useTranslation();
return (
{
sx={{ alignSelf: "center" }}
disabled={true}
>
- Add
+ {t("add")}
@@ -81,6 +83,7 @@ IntegrationsComponent.propTypes = {
const Integrations = () => {
const theme = useTheme();
+ const { t } = useTranslation();
const integrations = [
{
@@ -90,8 +93,8 @@ const Integrations = () => {
style={{ width: "45px", height: "45px", alignSelf: "center" }}
/>
),
- header: "Slack",
- info: "Connect with Slack and see incidents in a channel",
+ header: t("integrationsSlack"),
+ info: t("integrationsSlackInfo"),
onClick: () => {},
},
{
@@ -101,8 +104,8 @@ const Integrations = () => {
style={{ width: "42px", height: "42px", alignSelf: "center" }}
/>
),
- header: "Discord",
- info: "Connect with Discord and view incidents directly in a channel",
+ header: t("integrationsDiscord"),
+ info: t("integrationsDiscordInfo"),
onClick: () => {},
},
{
@@ -112,8 +115,8 @@ const Integrations = () => {
style={{ width: "42px", height: "42px", alignSelf: "center" }}
/>
),
- header: "Zapier",
- info: "Send all incidents to Zapier, and then see them everywhere",
+ header: t("integrationsZapier"),
+ info: t("integrationsZapierInfo"),
onClick: () => {},
},
// Add more integrations as needed
@@ -130,9 +133,9 @@ const Integrations = () => {
},
}}
>
- Integrations
+ {t("integrations")}
- Connect Prism to your favorite service.
+ {t("integrationsPrism")}
{
// Utils
const navigate = useNavigate();
@@ -89,23 +96,32 @@ const UptimeMonitors = () => {
}, []);
const teamId = user.teamId;
- const {
- monitorsAreLoading,
- monitors,
- filteredMonitors,
- monitorsSummary,
- networkError,
- } = useMonitorsFetch({
+
+ const [monitors, monitorsSummary, monitorsWithSummaryIsLoading, networkError] =
+ useFetchMonitorsWithSummary({
+ teamId,
+ types: TYPES,
+ });
+
+ const [
+ monitorsWithChecks,
+ monitorsWithChecksCount,
+ monitorsWithChecksIsLoading,
+ monitorsWithChecksNetworkError,
+ ] = useFetchMonitorsWithChecks({
teamId,
+ types: TYPES,
limit: 25,
page: page,
rowsPerPage: rowsPerPage,
filter: search,
field: sort?.field,
order: sort?.order,
- triggerUpdate: monitorUpdateTrigger,
+ triggerUpdate,
});
- const totalMonitors = monitorsSummary?.totalMonitors;
+
+ const isLoading = monitorsWithSummaryIsLoading || monitorsWithChecksIsLoading;
+
if (networkError) {
return (
@@ -121,8 +137,9 @@ const UptimeMonitors = () => {
);
}
if (
- !monitorsAreLoading &&
- (totalMonitors === 0 || typeof totalMonitors === "undefined")
+ !isLoading &&
+ (monitorsSummary?.totalMonitors === 0 ||
+ typeof monitorsSummary?.totalMonitors === "undefined")
) {
return (
{
0 && !monitorsAreLoading}
- monitorCount={totalMonitors}
+ shouldRender={monitors?.length > 0 && !monitorsWithSummaryIsLoading}
+ monitorCount={monitorsSummary?.totalMonitors}
heading={"Uptime monitors"}
>
{
{
+ params.append("type", type);
+ });
+ }
+
+ return this.axiosInstance.get(
+ `/monitors/summary/team/${teamId}?${params.toString()}`,
+ {
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ }
+
+ // ************************************
+ // Fetch monitors with checks by TeamID
+ // ************************************
+ async getMonitorsWithChecksByTeamId(config) {
+ const { teamId, limit, types, page, rowsPerPage, filter, field, order } = config;
+ const params = new URLSearchParams();
+
+ if (limit) params.append("limit", limit);
+ if (types) {
+ types.forEach((type) => {
+ params.append("type", type);
+ });
+ }
+ if (page) params.append("page", page);
+ if (rowsPerPage) params.append("rowsPerPage", rowsPerPage);
+ if (filter) params.append("filter", filter);
+ if (field) params.append("field", field);
+ if (order) params.append("order", order);
+
+ return this.axiosInstance.get(
+ `/monitors/team/${teamId}/with-checks?${params.toString()}`,
+ {
+ headers: {
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ }
}
export default NetworkService;
diff --git a/src/locales/gb.json b/src/locales/gb.json
index 2ba0d8c2f..662478270 100644
--- a/src/locales/gb.json
+++ b/src/locales/gb.json
@@ -1,178 +1,179 @@
{
- "dontHaveAccount": "Don't have account",
- "https": "HTTPS",
- "http": "HTTP",
- "monitor": "monitor",
- "aboutus": "About Us",
- "email": "E-mail",
- "forgotPassword": "Forgot Password",
- "password": "password",
- "signUp": "Sign up",
- "signUP": "Sign Up",
- "submit": "Submit",
- "title": "Title",
- "continue": "Continue",
- "now": "Now",
- "delete": "Delete",
- "configure": "Configure",
- "networkError": "Network error",
- "responseTime": "Response time:",
- "ms": "ms",
- "bar": "Bar",
- "area": "Area",
- "country": "COUNTRY",
- "city": "CITY",
- "response": "RESPONSE",
- "checkConnection": "Please check your connection",
- "enterEmail": "Enter your email",
- "authLoginTitle": "Log In",
- "authLoginEnterPassword": "Enter your password",
- "commonPassword": "Password",
- "createPassword": "Create your password",
- "createAPassword": "Create a password",
- "commonBack": "Back",
- "authForgotPasswordTitle": "Forgot password?",
- "authForgotPasswordResetPassword": "Reset password",
- "passwordreset": "Password Reset",
- "authRegisterAlreadyHaveAccount": "Already have an account?",
- "commonAppName": "Checkmate",
- "authLoginEnterEmail": "Enter your email",
- "authRegisterTitle": "Create an account",
- "authRegisterStepOneTitle": "Create your account",
- "authRegisterStepOnePersonalDetails": "Enter your personal details",
- "authRegisterStepOneDescription": "Enter your details to get started",
- "authRegisterStepTwoTitle": "Set up your profile",
- "authRegisterStepTwoDescription": "Tell us more about yourself",
- "authRegisterStepThreeTitle": "Almost done!",
- "authRegisterStepThreeDescription": "Review your information",
- "authForgotPasswordDescription": "No worries, we'll send you reset instructions.",
- "authForgotPasswordSendInstructions": "Send instructions",
- "authForgotPasswordBackTo": "Back to",
- "authCheckEmailTitle": "Check your email",
- "authCheckEmailDescription": "We sent a password reset link to",
- "authCheckEmailResendEmail": "Resend email",
- "authCheckEmailBackTo": "Back to",
- "authCheckEmailOpenEmailButton": "Open email app",
- "goBackTo": "Go back to",
- "authCheckEmailDidntReceiveEmail": "Didn't receive the email?",
- "authCheckEmailClickToResend": "Click to resend",
- "authSetNewPasswordTitle": "Set new password",
- "authSetNewPasswordDescription": "Your new password must be different from previously used passwords.",
- "authSetNewPasswordNewPassword": "New password",
- "authSetNewPasswordConfirmPassword": "Confirm password",
- "confirmPassword": "Confirm your password",
- "authSetNewPasswordResetPassword": "Reset password",
- "authNewPasswordConfirmed": "Your password has been successfully reset. Click below to log in magically.",
- "authSetNewPasswordBackTo": "Back to",
- "authPasswordMustBeAtLeast": "Must be at least",
- "authPasswordCharactersLong": "8 characters long",
- "authPasswordMustContainAtLeast": "Must contain at least",
- "authPasswordSpecialCharacter": "one special character",
- "authPasswordOneNumber": "one number",
- "authPasswordUpperCharacter": "one upper character",
- "authPasswordLowerCharacter": "one lower character",
- "authPasswordConfirmAndPassword": "Confirm password and password",
- "authPasswordMustMatch": "must match",
- "authRegisterCreateAccount": "Create your account to get started",
- "authRegisterCreateSuperAdminAccount": "Create your Super admin account to get started",
- "authRegisterSignUpWithEmail": "Sign up with Email",
- "authRegisterBySigningUp": "By signing up, you agree to our",
- "monitorStatusUp": "Monitor {name} ({url}) is now UP and responding",
- "monitorStatusDown": "Monitor {name} ({url}) is DOWN and not responding",
- "webhookSendSuccess": "Webhook notification sent successfully",
- "webhookSendError": "Error sending webhook notification to {platform}",
- "webhookUnsupportedPlatform": "Unsupported platform: {platform}",
- "distributedStatusHeaderText": "Real-time, real-device coverage",
- "distributedStatusSubHeaderText": "Powered by millions devices worldwide, view a system performance by global region, country or city",
- "distributedRightCategoryTitle": "Monitor",
- "distributedStatusServerMonitors": "Server Monitors",
- "distributedStatusServerMonitorsDescription": "Monitor status of related servers",
- "distributedUptimeCreateSelectURL": "Here you can select the URL of the host, together with the type of monitor.",
- "distributedUptimeCreateChecks": "Checks to perform",
- "distributedUptimeCreateChecksDescription": "You can always add or remove checks after adding your site.",
- "distributedUptimeCreateIncidentNotification": "Incident notifications",
- "distributedUptimeCreateIncidentDescription": "When there is an incident, notify users.",
- "distributedUptimeCreateAdvancedSettings": "Advanced settings",
- "distributedUptimeDetailsNoMonitorHistory": "There is no check history for this monitor yet.",
- "distributedUptimeDetailsFooterHeading": "Made with ❤️ by UpRock & Bluewave Labs",
- "distributedUptimeDetailsFooterBuilt": "Built on",
- "distributedUptimeDetailsFooterSolana": "Solana",
- "distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN",
- "distributedUptimeDetailsStatusHeaderUptime": "Uptime:",
- "distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated",
-
- "settingsGeneralSettings": "General settings",
- "settingsDisplayTimezone": "Display timezone",
- "settingsDisplayTimezoneDescription": "The timezone of the dashboard you publicly display.",
- "settingsAppearance": "Appearance",
- "settingsAppearanceDescription": "Switch between light and dark mode, or change user interface language",
- "settingsThemeMode": "Theme Mode",
- "settingsLanguage": "Language",
- "settingsDistributedUptime": "Distributed uptime",
- "settingsDistributedUptimeDescription": "Enable/disable distributed uptime monitoring.",
- "settingsEnabled": "Enabled",
- "settingsDisabled": "Disabled",
- "settingsHistoryAndMonitoring": "History and monitoring",
- "settingsHistoryAndMonitoringDescription": "Define here for how long you want to keep the data. You can also remove all past data.",
- "settingsTTLLabel": "The days you want to keep monitoring history.",
- "settingsTTLOptionalLabel": "0 for infinite",
- "settingsClearAllStats": "Clear all stats. This is irreversible.",
- "settingsClearAllStatsButton": "Clear all stats",
- "settingsClearAllStatsDialogTitle": "Do you want to clear all stats?",
- "settingsClearAllStatsDialogDescription": "Once deleted, your monitors cannot be retrieved.",
- "settingsClearAllStatsDialogConfirm": "Yes, clear all stats",
- "settingsDemoMonitors": "Demo monitors",
- "settingsDemoMonitorsDescription": "Here you can add and remove demo monitors.",
- "settingsAddDemoMonitors": "Add demo monitors",
- "settingsAddDemoMonitorsButton": "Add demo monitors",
- "settingsRemoveAllMonitors": "Remove all monitors",
- "settingsRemoveAllMonitorsButton": "Remove all monitors",
- "settingsRemoveAllMonitorsDialogTitle": "Do you want to remove all monitors?",
- "settingsRemoveAllMonitorsDialogConfirm": "Yes, clear all monitors",
- "settingsWallet": "Wallet",
- "settingsWalletDescription": "Connect your wallet here. This is required for the Distributed Uptime monitor to connect to multiple nodes globally.",
- "settingsAbout": "About",
- "settingsDevelopedBy": "Developed by Bluewave Labs.",
- "settingsSave": "Save",
- "settingsSuccessSaved": "Settings saved successfully",
- "settingsFailedToSave": "Failed to save settings",
- "settingsStatsCleared": "Stats cleared successfully",
- "settingsFailedToClearStats": "Failed to clear stats",
- "settingsDemoMonitorsAdded": "Successfully added demo monitors",
- "settingsFailedToAddDemoMonitors": "Failed to add demo monitors",
- "settingsMonitorsDeleted": "Successfully deleted all monitors",
- "settingsFailedToDeleteMonitors": "Failed to delete all monitors",
- "starPromptTitle": "Star Checkmate",
- "starPromptDescription": "See the latest releases and help grow the community on GitHub",
- "notifications": {
- "enableNotifications": "Enable {{platform}} notifications",
- "testNotification": "Test notification",
- "addOrEditNotifications": "Add or edit notifications",
- "slack": {
- "label": "Slack",
- "description": "To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.",
- "webhookLabel": "Webhook URL",
- "webhookPlaceholder": "https://hooks.slack.com/services/..."
- },
- "discord": {
- "label": "Discord",
- "description": "To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature.",
- "webhookLabel": "Discord Webhook URL",
- "webhookPlaceholder": "https://discord.com/api/webhooks/..."
- },
- "telegram": {
- "label": "Telegram",
- "description": "To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.",
- "tokenLabel": "Your bot token",
- "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
- "chatIdLabel": "Your Chat ID",
- "chatIdPlaceholder": "-1001234567890"
- },
- "webhook": {
- "label": "Webhooks",
- "description": "You can set up a custom webhook to receive notifications when incidents occur.",
- "urlLabel": "Webhook URL",
- "urlPlaceholder": "https://your-server.com/webhook"
- }
- }
+ "dontHaveAccount": "Don't have account",
+ "email": "E-mail",
+ "forgotPassword": "Forgot Password",
+ "password": "password",
+ "signUp": "Sign up",
+ "submit": "Submit",
+ "title": "Title",
+ "continue": "Continue",
+ "enterEmail": "Enter your email",
+ "authLoginTitle": "Log In",
+ "authLoginEnterPassword": "Enter your password",
+ "commonPassword": "Password",
+ "commonBack": "Back",
+ "authForgotPasswordTitle": "Forgot password?",
+ "authForgotPasswordResetPassword": "Reset password",
+ "createPassword": "Create your password",
+ "createAPassword": "Create a password",
+ "authRegisterAlreadyHaveAccount": "Already have an account?",
+ "commonAppName": "Checkmate",
+ "authLoginEnterEmail": "Enter your email",
+ "authRegisterTitle": "Create an account",
+ "authRegisterStepOneTitle": "Create your account",
+ "authRegisterStepOneDescription": "Enter your details to get started",
+ "authRegisterStepTwoTitle": "Set up your profile",
+ "authRegisterStepTwoDescription": "Tell us more about yourself",
+ "authRegisterStepThreeTitle": "Almost done!",
+ "authRegisterStepThreeDescription": "Review your information",
+ "authForgotPasswordDescription": "No worries, we'll send you reset instructions.",
+ "authForgotPasswordSendInstructions": "Send instructions",
+ "authForgotPasswordBackTo": "Back to",
+ "authCheckEmailTitle": "Check your email",
+ "authCheckEmailDescription": "We sent a password reset link to",
+ "authCheckEmailResendEmail": "Resend email",
+ "authCheckEmailBackTo": "Back to",
+ "goBackTo": "Go back to",
+ "authCheckEmailDidntReceiveEmail": "Didn't receive the email?",
+ "authCheckEmailClickToResend": "Click to resend",
+ "authSetNewPasswordTitle": "Set new password",
+ "authSetNewPasswordDescription": "Your new password must be different from previously used passwords.",
+ "authSetNewPasswordNewPassword": "New password",
+ "authSetNewPasswordConfirmPassword": "Confirm password",
+ "confirmPassword": "Confirm your password",
+ "authSetNewPasswordResetPassword": "Reset password",
+ "authSetNewPasswordBackTo": "Back to",
+ "authPasswordMustBeAtLeast": "Must be at least",
+ "authPasswordCharactersLong": "8 characters long",
+ "authPasswordMustContainAtLeast": "Must contain at least",
+ "authPasswordSpecialCharacter": "one special character",
+ "authPasswordOneNumber": "one number",
+ "authPasswordUpperCharacter": "one upper character",
+ "authPasswordLowerCharacter": "one lower character",
+ "authPasswordConfirmAndPassword": "Confirm password and password",
+ "authPasswordMustMatch": "must match",
+ "authRegisterCreateAccount": "Create your account to get started",
+ "authRegisterCreateSuperAdminAccount": "Create your Super admin account to get started",
+ "authRegisterSignUpWithEmail": "Sign up with Email",
+ "authRegisterBySigningUp": "By signing up, you agree to our",
+ "distributedStatusHeaderText": "Real-time, real-device coverage",
+ "distributedStatusSubHeaderText": "Powered by millions devices worldwide, view a system performance by global region, country or city",
+ "settingsGeneralSettings": "General settings",
+ "settingsDisplayTimezone": "Display timezone",
+ "settingsDisplayTimezoneDescription": "The timezone of the dashboard you publicly display.",
+ "settingsAppearance": "Appearance",
+ "settingsAppearanceDescription": "Switch between light and dark mode, or change user interface language",
+ "settingsThemeMode": "Theme Mode",
+ "settingsLanguage": "Language",
+ "settingsDistributedUptime": "Distributed uptime",
+ "settingsDistributedUptimeDescription": "Enable/disable distributed uptime monitoring.",
+ "settingsEnabled": "Enabled",
+ "settingsDisabled": "Disabled",
+ "settingsHistoryAndMonitoring": "History and monitoring",
+ "settingsHistoryAndMonitoringDescription": "Define here for how long you want to keep the data. You can also remove all past data.",
+ "settingsTTLLabel": "The days you want to keep monitoring history.",
+ "settingsTTLOptionalLabel": "0 for infinite",
+ "settingsClearAllStats": "Clear all stats. This is irreversible.",
+ "settingsClearAllStatsButton": "Clear all stats",
+ "settingsClearAllStatsDialogTitle": "Do you want to clear all stats?",
+ "settingsClearAllStatsDialogDescription": "Once deleted, your monitors cannot be retrieved.",
+ "settingsClearAllStatsDialogConfirm": "Yes, clear all stats",
+ "settingsDemoMonitors": "Demo monitors",
+ "settingsDemoMonitorsDescription": "Here you can add and remove demo monitors.",
+ "settingsAddDemoMonitors": "Add demo monitors",
+ "settingsAddDemoMonitorsButton": "Add demo monitors",
+ "settingsRemoveAllMonitors": "Remove all monitors",
+ "settingsRemoveAllMonitorsButton": "Remove all monitors",
+ "settingsRemoveAllMonitorsDialogTitle": "Do you want to remove all monitors?",
+ "settingsRemoveAllMonitorsDialogConfirm": "Yes, clear all monitors",
+ "settingsWallet": "Wallet",
+ "settingsWalletDescription": "Connect your wallet here. This is required for the Distributed Uptime monitor to connect to multiple nodes globally.",
+ "settingsAbout": "About",
+ "settingsDevelopedBy": "Developed by Bluewave Labs.",
+ "settingsSave": "Save",
+ "settingsSuccessSaved": "Settings saved successfully",
+ "settingsFailedToSave": "Failed to save settings",
+ "settingsStatsCleared": "Stats cleared successfully",
+ "settingsFailedToClearStats": "Failed to clear stats",
+ "settingsDemoMonitorsAdded": "Successfully added demo monitors",
+ "settingsFailedToAddDemoMonitors": "Failed to add demo monitors",
+ "settingsMonitorsDeleted": "Successfully deleted all monitors",
+ "settingsFailedToDeleteMonitors": "Failed to delete all monitors",
+ "starPromptTitle": "Star Checkmate",
+ "starPromptDescription": "See the latest releases and help grow the community on GitHub",
+ "https": "HTTPS",
+ "http": "HTTP",
+ "monitor": "monitor",
+ "aboutus": "About Us",
+ "signUP": "Sign Up",
+ "now": "Now",
+ "delete": "Delete",
+ "configure": "Configure",
+ "networkError": "Network error",
+ "responseTime": "Response time:",
+ "ms": "ms",
+ "bar": "Bar",
+ "area": "Area",
+ "country": "COUNTRY",
+ "city": "CITY",
+ "response": "RESPONSE",
+ "checkConnection": "Please check your connection",
+ "passwordreset": "Password Reset",
+ "authRegisterStepOnePersonalDetails": "Enter your personal details",
+ "authCheckEmailOpenEmailButton": "Open email app",
+ "authNewPasswordConfirmed": "Your password has been successfully reset. Click below to log in magically.",
+ "monitorStatusUp": "Monitor {name} ({url}) is now UP and responding",
+ "monitorStatusDown": "Monitor {name} ({url}) is DOWN and not responding",
+ "webhookSendSuccess": "Webhook notification sent successfully",
+ "webhookSendError": "Error sending webhook notification to {platform}",
+ "webhookUnsupportedPlatform": "Unsupported platform: {platform}",
+ "distributedRightCategoryTitle": "Monitor",
+ "distributedStatusServerMonitors": "Server Monitors",
+ "distributedStatusServerMonitorsDescription": "Monitor status of related servers",
+ "distributedUptimeCreateSelectURL": "Here you can select the URL of the host, together with the type of monitor.",
+ "distributedUptimeCreateChecks": "Checks to perform",
+ "distributedUptimeCreateChecksDescription": "You can always add or remove checks after adding your site.",
+ "distributedUptimeCreateIncidentNotification": "Incident notifications",
+ "distributedUptimeCreateIncidentDescription": "When there is an incident, notify users.",
+ "distributedUptimeCreateAdvancedSettings": "Advanced settings",
+ "distributedUptimeDetailsNoMonitorHistory": "There is no check history for this monitor yet.",
+ "distributedUptimeDetailsFooterHeading": "Made with ❤️ by UpRock & Bluewave Labs",
+ "distributedUptimeDetailsFooterBuilt": "Built on",
+ "distributedUptimeDetailsFooterSolana": "Solana",
+ "distributedUptimeDetailsMonitorHeader": "Distributed Uptime Monitoring powered by DePIN",
+ "distributedUptimeDetailsStatusHeaderUptime": "Uptime:",
+ "distributedUptimeDetailsStatusHeaderLastUpdate": "Last updated",
+ "notifications": {
+ "enableNotifications": "Enable {{platform}} notifications",
+ "testNotification": "Test notification",
+ "addOrEditNotifications": "Add or edit notifications",
+ "slack": {
+ "label": "Slack",
+ "description": "To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.",
+ "webhookLabel": "Webhook URL",
+ "webhookPlaceholder": "https://hooks.slack.com/services/..."
+ },
+ "discord": {
+ "label": "Discord",
+ "description": "To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord's incoming Webhooks feature.",
+ "webhookLabel": "Discord Webhook URL",
+ "webhookPlaceholder": "https://discord.com/api/webhooks/..."
+ },
+ "telegram": {
+ "label": "Telegram",
+ "description": "To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.",
+ "tokenLabel": "Your bot token",
+ "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
+ "chatIdLabel": "Your Chat ID",
+ "chatIdPlaceholder": "-1001234567890"
+ },
+ "webhook": {
+ "label": "Webhooks",
+ "description": "You can set up a custom webhook to receive notifications when incidents occur.",
+ "urlLabel": "Webhook URL",
+ "urlPlaceholder": "https://your-server.com/webhook"
+ },
+ "testNotificationDevelop": "Test notification 2"
+ },
+ "testLocale": ""
}
diff --git a/src/locales/tr.json b/src/locales/tr.json
index f008db6fa..b4332a548 100644
--- a/src/locales/tr.json
+++ b/src/locales/tr.json
@@ -175,5 +175,5 @@
},
"testNotificationDevelop": ""
},
- "testLocale": "TEST4 UPLOAD"
+ "testLocale": "TEST11 UPLOAD"
}
\ No newline at end of file