diff --git a/.github/scripts/download-translations.js b/.github/scripts/download-translations.js new file mode 100644 index 000000000..62f63a6a0 --- /dev/null +++ b/.github/scripts/download-translations.js @@ -0,0 +1,89 @@ +import axios from 'axios'; +import fs from 'fs-extra'; +import path from 'path'; +import { URLSearchParams } from 'url'; + +// POEditor API information +const API_TOKEN = process.env.POEDITOR_API; +const PROJECT_ID = process.env.POEDITOR_PROJECT_ID; +const LANGUAGES = (process.env.LANGUAGES || 'tr,en').split(','); +const EXPORT_FORMAT = process.env.EXPORT_FORMAT || 'key_value_json'; + +// POEditor API endpoint +const API_URL = 'https://api.poeditor.com/v2'; + +// Function to download translations +async function downloadTranslations() { + try { + console.log('Downloading translations from POEditor...'); + console.log(`Using export format: ${EXPORT_FORMAT}`); + + for (const language of LANGUAGES) { + console.log(`Downloading translations for ${language} language...`); + + // Get export URL from POEditor + const exportResponse = await axios.post(`${API_URL}/projects/export`, + new URLSearchParams({ + api_token: API_TOKEN, + id: PROJECT_ID, + language: language, + type: EXPORT_FORMAT + }) + ); + + if (exportResponse.data.response.status !== 'success') { + throw new Error(`Failed to get export URL for ${language} language: ${JSON.stringify(exportResponse.data)}`); + } + + const fileUrl = exportResponse.data.result.url; + console.log(`Export URL obtained for ${language}`); + + // Download translation file + const downloadResponse = await axios.get(fileUrl, { responseType: 'json' }); + const translations = downloadResponse.data; + console.log(`Downloaded translations for ${language}`); + + // Check the format of data returned from POEditor and convert if necessary + let formattedTranslations = translations; + + // If data is in array format, convert it to key-value format + if (Array.isArray(translations)) { + console.log(`Converting array format to key-value format for ${language}`); + formattedTranslations = {}; + translations.forEach(item => { + if (item.term && item.definition) { + formattedTranslations[item.term] = item.definition; + } + }); + } + + // Save file + const outputPath = path.join(process.cwd(), 'temp', `${language}.json`); + await fs.writeJson(outputPath, formattedTranslations, { spaces: 2 }); + + console.log(`Translations for ${language} language successfully downloaded and saved: ${outputPath}`); + } + + console.log('All translations successfully downloaded!'); + } catch (error) { + console.error('An error occurred while downloading translations:', error); + process.exit(1); + } +} + +// Main function +async function main() { + try { + // Clean temp folder + await fs.emptyDir(path.join(process.cwd(), 'temp')); + + // Download translations + await downloadTranslations(); + } catch (error) { + console.error('An error occurred during the process:', error); + process.exit(1); + } +} + +// Run script +main(); \ No newline at end of file diff --git a/.github/scripts/upload-translations.js b/.github/scripts/upload-translations.js new file mode 100644 index 000000000..aa23cf35f --- /dev/null +++ b/.github/scripts/upload-translations.js @@ -0,0 +1,64 @@ +import axios from "axios"; +import FormData from "form-data"; +import fs from "fs-extra"; + +// POEditor API information +const API_TOKEN = process.env.POEDITOR_API; +const PROJECT_ID = process.env.POEDITOR_PROJECT_ID; +const FILE_PATH = process.env.FILE_PATH; +const LANGUAGE = process.env.LANGUAGE; + +// POEditor API endpoint +const API_URL = 'https://api.poeditor.com/v2'; + +// Function to upload translations +async function uploadTranslations() { + try { + console.log(`Uploading translations for ${LANGUAGE} language from ${FILE_PATH}... test1`); + + // Check if file exists + if (!await fs.pathExists(FILE_PATH)) { + throw new Error(`File not found: ${FILE_PATH}`); + } + + // Read file content + const fileContent = await fs.readFile(FILE_PATH, 'utf8'); + + // Validate JSON format + try { + JSON.parse(fileContent); + } catch (error) { + throw new Error(`Invalid JSON format in ${FILE_PATH}: ${error.message}`); + } + + // Create form data for upload + const formData = new FormData(); + formData.append('api_token', API_TOKEN); + formData.append('id', PROJECT_ID); + formData.append('language', LANGUAGE); + formData.append('updating', 'terms_translations'); + formData.append('file', fs.createReadStream(FILE_PATH)); + formData.append('overwrite', '1'); + formData.append('sync_terms', '1'); + + // Upload to POEditor + const response = await axios.post(`${API_URL}/projects/upload`, formData, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + } + }); + + if (response.data.response.status !== 'success') { + throw new Error(`Failed to upload translations: ${JSON.stringify(response.data)}`); + } + + console.log(`Successfully uploaded translations for ${LANGUAGE} language.`); + console.log(`Statistics: ${JSON.stringify(response.data.result)}`); + } catch (error) { + console.error('An error occurred while uploading translations:', error); + process.exit(1); + } +} + +// Run script +uploadTranslations(); diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..774a816b3 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,69 @@ +# POEditor Translation Synchronization + +This GitHub Actions workflow automatically downloads translation files from POEditor and integrates them into the project. + +## How It Works + +The workflow can be triggered in two ways: + +1. **Manual Trigger**: You can manually run the "POEditor Translation Synchronization" workflow from the "Actions" tab in the GitHub interface. +2. **Automatic Trigger**: The workflow runs automatically every day at midnight (UTC). + +## Required Settings + +For this workflow to function, you need to define the following secrets in your GitHub repository: + +1. `POEDITOR_API_TOKEN`: Your POEditor API token +2. `POEDITOR_PROJECT_ID`: Your POEditor project ID + +You can add these secrets in the "Settings > Secrets and variables > Actions" section of your GitHub repository. + +## Manual Execution + +When running the workflow manually, you can specify which languages to download. Languages should be entered as comma-separated values (e.g., `tr,gb,es`). + +If you don't specify any languages, the default languages `tr` and `en` will be downloaded. + +## Output + +When the workflow completes successfully: + +1. Translation files for the specified languages are downloaded from POEditor +2. These files are copied to the `src/locales/` directory +3. Changes are automatically committed and pushed to the main branch + +## Troubleshooting + +If the workflow fails: + +1. Check the GitHub Actions logs +2. Make sure your POEditor API token and project ID are correct +3. Ensure that the languages you specified exist in your POEditor project + +# POEditor Upload Workflow + +## Summary of Implemented Translation Workflow + +We have successfully created a GitHub Actions workflow that automatically uploads translation files to POEditor when changes are merged to the develop branch. Here's a summary of what we've implemented: +### Created Files + +1. .github/scripts/upload-translations.js + +- A Node.js script that handles the upload of translation files to POEditor +- Uses the POEditor API to upload JSON translation files +- Validates file existence and JSON format before uploading +- Provides detailed logging of the upload process + +2. .github/workflows/poeditor-upload-on-merge.yml - A GitHub Actions workflow that triggers when PRs are merged to the develop branch - Only runs when changes are made to files in the src/locales directory - Detects which translation files were changed in the PR - Extracts language codes from filenames (e.g., tr.json → "tr") - Calls the upload script for each changed file + ### Workflow Process +1. When a PR is merged to the develop branch, the workflow checks if any files in src/locales were modified. + +1. If translation files were changed, the workflow: + +- Sets up the necessary Node.js environment +- Installs required dependencies +- Identifies which specific translation files were changed +- For each changed file, extracts the language code and uploads to POEditor +- Provides status notifications about the upload process + +This automated workflow ensures that your translations are always in sync between your codebase and POEditor, eliminating the need for manual uploads and reducing the risk of translation inconsistencies. diff --git a/.github/workflows/poeditor-sync.yml b/.github/workflows/poeditor-sync.yml new file mode 100644 index 000000000..1f1194e3e --- /dev/null +++ b/.github/workflows/poeditor-sync.yml @@ -0,0 +1,92 @@ +name: POEditor Translation Synchronization + +on: + # For manual triggering + workflow_dispatch: + inputs: + languages: + description: "Languages to synchronize (comma separated, e.g.: tr,en,es)" + required: false + default: "tr,en" + format: + description: "Export format (key_value_json or json)" + required: false + default: "key_value_json" + + # For automatic execution at a specific time (every day at midnight) + schedule: + - cron: "0 0 * * *" + +jobs: + sync-translations: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + + - name: Create package.json for scripts + run: | + mkdir -p .github/scripts + cat > .github/scripts/package.json << EOF + { + "name": "poeditor-scripts", + "version": "1.0.0", + "private": true, + "type": "module", + "dependencies": { + "axios": "^1.6.0", + "fs-extra": "^11.1.1" + } + } + EOF + + - name: Install dependencies + run: | + cd .github/scripts + npm install + + - name: Download translations from POEditor + env: + POEDITOR_API: ${{ secrets.POEDITOR_API }} + POEDITOR_PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} + LANGUAGES: ${{ github.event.inputs.languages || 'tr,en' }} + EXPORT_FORMAT: ${{ github.event.inputs.format || 'key_value_json' }} + run: | + mkdir -p temp + node .github/scripts/download-translations.js + + - name: Verify translation files + run: | + echo "Verifying translation files..." + for file in temp/*.json; do + echo "Checking $file" + if [ ! -s "$file" ]; then + echo "Error: $file is empty or does not exist" + exit 1 + fi + # Validate JSON format + cat "$file" | jq . > /dev/null || { echo "Error: $file is not valid JSON"; exit 1; } + done + echo "All translation files are valid" + + - name: Copy translations to project + run: | + mkdir -p src/locales + 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 diff --git a/.github/workflows/upload-poeditor.yml b/.github/workflows/upload-poeditor.yml new file mode 100644 index 000000000..bdd2b8fbf --- /dev/null +++ b/.github/workflows/upload-poeditor.yml @@ -0,0 +1,101 @@ +name: Upload Translations to POEditor on PR Merge + +on: + pull_request: + types: [closed] + branches: + - develop + paths: + - "src/locales/**" + +jobs: + upload-translations: + # Only run if the PR was merged (not just closed) or manually triggered + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Fetch all history to get changed files + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + + - name: Create package.json for scripts + run: | + mkdir -p .github/scripts + cat > .github/scripts/package.json << EOF + { + "name": "poeditor-scripts", + "version": "1.0.0", + "private": true, + "type": "module", + "dependencies": { + "axios": "^1.6.0", + "fs-extra": "^11.1.1", + "form-data": "^4.0.0" + } + } + EOF + + - name: Install dependencies + run: | + cd .github/scripts + npm install + + - name: Get changed locale files + 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" + + # Create a JSON array of changed files with language codes + echo "CHANGED_FILES<> $GITHUB_ENV + echo "$CHANGED_FILES" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Upload changed translations to POEditor + if: env.CHANGED_FILES != '' + env: + POEDITOR_API: ${{ secrets.POEDITOR_API }} + POEDITOR_PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }} + run: | + # Process each changed file + for FILE in $CHANGED_FILES; do + if [[ -f "$FILE" ]]; then + # Extract language code from filename (e.g., src/locales/en.json -> en) + FILENAME=$(basename "$FILE") + + # Special case: map gb.json to en language code + if [ "$FILENAME" == "gb.json" ]; then + LANG="en" + echo "Found gb.json, mapping to language code 'en'" + else + LANG=$(basename "$FILE" .json) + fi + + echo "Processing $FILE for language $LANG" + + # Upload to POEditor + LANGUAGE=$LANG FILE_PATH=$FILE node .github/scripts/upload-translations.js + fi + done + + - name: Notify on success + if: success() && env.CHANGED_FILES != '' + run: | + echo "Successfully uploaded translation files to POEditor." + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "Manual trigger comment: ${{ github.event.inputs.comment }}" + fi + + - name: Notify on no changes + if: env.CHANGED_FILES == '' + run: | + echo "No translation files were found to upload." diff --git a/src/Components/Inputs/Search/index.jsx b/src/Components/Inputs/Search/index.jsx index 662ade695..647af874a 100644 --- a/src/Components/Inputs/Search/index.jsx +++ b/src/Components/Inputs/Search/index.jsx @@ -128,7 +128,7 @@ const Search = ({ { const theme = useTheme(); const levelConfig = { - primary: {}, + primary: { + color: theme.palette.primary.contrastTextTertiary, + sx: { + ":hover": { + color: theme.palette.primary.contrastTextSecondary, + }, + }, + }, secondary: { color: theme.palette.primary.contrastTextSecondary, sx: { diff --git a/src/Components/Sidebar/index.jsx b/src/Components/Sidebar/index.jsx index c82f2e5be..4fbc12538 100644 --- a/src/Components/Sidebar/index.jsx +++ b/src/Components/Sidebar/index.jsx @@ -17,6 +17,7 @@ import { } from "@mui/material"; import ThemeSwitch from "../ThemeSwitch"; import Avatar from "../Avatar"; +import StarPrompt from "../StarPrompt"; import LockSvg from "../../assets/icons/lock.svg?react"; import UserSvg from "../../assets/icons/user.svg?react"; import TeamSvg from "../../assets/icons/user-two.svg?react"; @@ -608,6 +609,8 @@ function Sidebar() { + {!collapsed && } + { + 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 handleStarClick = () => { + window.open(repoUrl, '_blank'); + }; + + if (!isOpen) return null; + + return ( + + + + {t('starPromptTitle')} + + + + + + + + {t('starPromptDescription')} + + + + + ); +}; + +export default StarPrompt; diff --git a/src/Components/WalletProvider/index.css b/src/Components/WalletProvider/index.css new file mode 100644 index 000000000..15fb9d816 --- /dev/null +++ b/src/Components/WalletProvider/index.css @@ -0,0 +1,51 @@ +.wallet-adapter-dropdown { + width: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: var(--env-var-spacing-1); +} + +.wallet-adapter-button { + display: flex; + align-items: center; + justify-content: center; + width: auto; + height: var(--env-var-height-2) !important; + font-size: var(--env-var-font-size-medium-plus) !important; + font-weight: 500 !important; + margin: 0; + padding: calc((var(--env-var-height-2) - var(--env-var-font-size-medium-plus) * 1.2) / 2) var(--env-var-spacing-1); + white-space: nowrap; +} + +.wallet-adapter-modal-title { + font-size: var(--font-size-h5) !important; +} + +/* Separator styling */ +.wallet-adapter-modal-divider { + background-color: var(--border-color) !important; + margin: var(--spacing-md) 0 !important; +} + +/* Responsive fixes */ +@media (max-width: 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 diff --git a/src/Components/WalletProvider/index.jsx b/src/Components/WalletProvider/index.jsx index a24124d93..9491c1d39 100644 --- a/src/Components/WalletProvider/index.jsx +++ b/src/Components/WalletProvider/index.jsx @@ -9,6 +9,7 @@ import { import { WalletModalProvider } from "@solana/wallet-adapter-react-ui"; import { clusterApiUrl } from "@solana/web3.js"; import PropTypes from "prop-types"; +import "./index.css"; // Default styles that can be overridden by your app import "@solana/wallet-adapter-react-ui/styles.css"; diff --git a/src/Features/UI/uiSlice.js b/src/Features/UI/uiSlice.js index ebafdbbf6..f20115b92 100644 --- a/src/Features/UI/uiSlice.js +++ b/src/Features/UI/uiSlice.js @@ -24,6 +24,7 @@ const initialState = { timezone: "America/Toronto", distributedUptimeEnabled: false, language: "gb", + starPromptOpen: true, }; const uiSlice = createSlice({ @@ -55,6 +56,9 @@ const uiSlice = createSlice({ setLanguage(state, action) { state.language = action.payload; }, + setStarPromptOpen: (state, action) => { + state.starPromptOpen = action.payload; + }, }, }); @@ -67,4 +71,5 @@ export const { setTimezone, setDistributedUptimeEnabled, setLanguage, + setStarPromptOpen, } = uiSlice.actions; diff --git a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx index 8f188c970..22a56bd7e 100644 --- a/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx +++ b/src/Pages/DistributedUptime/Details/Components/StatusHeader/index.jsx @@ -30,7 +30,6 @@ const StatusHeader = ({ monitor, connectionStatus, elementToCapture }) => { }; let bgColor = COLOR_MAP[connectionStatus]; - return ( { backgroundColor={theme.palette.successSecondary.lowContrast} color={theme.palette.success.lowContrast} > - {t("distributedUptimeDetailsStatusHeaderUptime")} {(monitor.totalUptime * 100).toFixed(2)}% + {t("distributedUptimeDetailsStatusHeaderUptime")}{" "} + {(monitor.uptimePercentage * 100).toFixed(2)}% { {t("settingsWalletDescription")} - + { )} + {t("settingsAbout")} diff --git a/src/Pages/StatusPage/Status/index.jsx b/src/Pages/StatusPage/Status/index.jsx index ac5877815..a47e9d33e 100644 --- a/src/Pages/StatusPage/Status/index.jsx +++ b/src/Pages/StatusPage/Status/index.jsx @@ -24,7 +24,6 @@ const PublicStatus = () => { const [isDeleteOpen, setIsDeleteOpen] = useState(false); // Utils const theme = useTheme(); - const isAdmin = useIsAdmin(); const location = useLocation(); const navigate = useNavigate(); @@ -33,7 +32,6 @@ const PublicStatus = () => { const [deleteStatusPage, isDeleting] = useStatusPageDelete(fetchStatusPage, url); // Setup - const currentPath = location.pathname; let sx = { paddingLeft: theme.spacing(20), paddingRight: theme.spacing(20) }; let link = undefined; const isPublic = location.pathname.startsWith("/status/uptime/public"); diff --git a/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx b/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx index 7bee4be8f..6772dcdb7 100644 --- a/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx +++ b/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx @@ -25,7 +25,7 @@ const StatusPagesTable = ({ data }) => { row.type === "distributed" ? `/status/distributed/public/${row.url}` : `/status/uptime/public/${row.url}`; - navigate(url); + window.open(url, "_blank", "noopener,noreferrer") } }, render: (row) => { diff --git a/src/Pages/Uptime/Details/Hooks/useChecksFetch.jsx b/src/Pages/Uptime/Details/Hooks/useChecksFetch.jsx index 51da1a20b..23c66b084 100644 --- a/src/Pages/Uptime/Details/Hooks/useChecksFetch.jsx +++ b/src/Pages/Uptime/Details/Hooks/useChecksFetch.jsx @@ -2,18 +2,30 @@ import { useState } from "react"; import { useEffect } from "react"; import { networkService } from "../../../../main"; import { createToast } from "../../../../Utils/toastUtils"; -export const useChecksFetch = ({ monitorId, dateRange, page, rowsPerPage }) => { +export const useChecksFetch = ({ + monitorId, + monitorType, + dateRange, + page, + rowsPerPage, +}) => { const [checks, setChecks] = useState(undefined); const [checksCount, setChecksCount] = useState(undefined); const [isLoading, setIsLoading] = useState(false); const [networkError, setNetworkError] = useState(false); useEffect(() => { + if (!monitorType) { + console.warn("Monitor Type is not provided. Fetching checks will not proceed."); + return; + } + const fetchChecks = async () => { try { setIsLoading(true); const res = await networkService.getChecksByMonitor({ monitorId: monitorId, + type: monitorType, sortOrder: "desc", limit: null, dateRange: dateRange, @@ -31,7 +43,7 @@ export const useChecksFetch = ({ monitorId, dateRange, page, rowsPerPage }) => { } }; fetchChecks(); - }, [monitorId, dateRange, page, rowsPerPage]); + }, [monitorId, monitorType, dateRange, page, rowsPerPage]); return [checks, checksCount, isLoading, networkError]; }; diff --git a/src/Pages/Uptime/Details/index.jsx b/src/Pages/Uptime/Details/index.jsx index d170f7b18..672640d67 100644 --- a/src/Pages/Uptime/Details/index.jsx +++ b/src/Pages/Uptime/Details/index.jsx @@ -59,8 +59,11 @@ const UptimeDetails = () => { uiTimezone, }); + const monitorType = monitor?.type; + const [checks, checksCount, checksAreLoading, checksNetworkError] = useChecksFetch({ monitorId, + monitorType, dateRange, page, rowsPerPage, diff --git a/src/Utils/Theme/globalTheme.js b/src/Utils/Theme/globalTheme.js index 6e05fa592..490a5baea 100644 --- a/src/Utils/Theme/globalTheme.js +++ b/src/Utils/Theme/globalTheme.js @@ -332,13 +332,13 @@ const baseTheme = (palette) => ({ color: palette.error.main, opacity: 0.8, fontSize: "var(--env-var-font-size-medium)", - marginLeft: 0, }, "& .MuiFormHelperText-root.Mui-error": { opacity: 0.8, fontSize: "var(--env-var-font-size-medium)", color: palette.error.main, + whiteSpace: 'nowrap', }, }), }, diff --git a/src/locales/gb.json b/src/locales/gb.json index 60d0899cb..2ba0d8c2f 100644 --- a/src/locales/gb.json +++ b/src/locales/gb.json @@ -100,7 +100,7 @@ "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.", @@ -142,37 +142,37 @@ "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/..." + "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/..." + "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" + "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" + "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" } } - } diff --git a/src/locales/tr.json b/src/locales/tr.json index abd358548..68dedbfa5 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -60,7 +60,6 @@ "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", "distributedRightCatagoryTitle": "Monitör", "distributedRightCatagoryDescription": "Mainnet Beta Kümesi", - "settingsGeneralSettings": "Genel ayarlar", "settingsDisplayTimezone": "Görüntüleme saat dilimi", "settingsDisplayTimezoneDescription": "Herkese açık olarak görüntülediğiniz kontrol panelinin saat dilimi.", @@ -101,5 +100,8 @@ "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" -} + "settingsFailedToDeleteMonitors": "Monitörler silinemedi", + "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", + "testLocale": "TEST1311 UPLOAD" +} \ No newline at end of file