From d90d554c65e5736896cf68384eee1d7f996e2b8d Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 21 Apr 2025 00:31:38 +0000 Subject: [PATCH 001/147] feat: translations updated from POEditor --- src/locales/gb.json | 382 ++++++++++++++++++++++++++++++++++++++++++++ src/locales/tr.json | 382 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 764 insertions(+) create mode 100644 src/locales/gb.json create mode 100644 src/locales/tr.json diff --git a/src/locales/gb.json b/src/locales/gb.json new file mode 100644 index 000000000..343386bec --- /dev/null +++ b/src/locales/gb.json @@ -0,0 +1,382 @@ +{ + "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/...", + "webhookRequired": "Slack webhook URL is required" + }, + "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/...", + "webhookRequired": "Discord webhook URL is required" + }, + "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", + "fieldsRequired": "Telegram token and chat ID are required" + }, + "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", + "urlRequired": "Webhook URL is required" + }, + "testNotificationDevelop": "Test notification 2", + "integrationButton": "Notification Integration", + "testSuccess": "Test notification sent successfully!", + "testFailed": "Failed to send test notification", + "unsupportedType": "Unsupported notification type", + "networkError": "Network error occurred" + }, + "testLocale": "testLocale", + "add": "Add", + "monitors": "monitors", + "distributedUptimeStatusCreateStatusPage": "status page", + "distributedUptimeStatusCreateStatusPageAccess": "Access", + "distributedUptimeStatusCreateStatusPageReady": "If your status page is ready, you can mark it as published.", + "distributedUptimeStatusBasicInfoHeader": "Basic Information", + "distributedUptimeStatusBasicInfoDescription": "Define company name and the subdomain that your status page points to.", + "distributedUptimeStatusLogoHeader": "Logo", + "distributedUptimeStatusLogoDescription": "Upload a logo for your status page", + "distributedUptimeStatusLogoUploadButton": "Upload logo", + "distributedUptimeStatusStandardMonitorsHeader": "Standard Monitors", + "distributedUptimeStatusStandardMonitorsDescription": "Attach standard monitors to your status page.", + "distributedUptimeStatusCreateYour": "Create your", + "distributedUptimeStatusEditYour": "Edit your", + "distributedUptimeStatusPublishedLabel": "Published and visible to the public", + "distributedUptimeStatusCompanyNameLabel": "Company name", + "distributedUptimeStatusPageAddressLabel": "Your status page address", + "distributedUptimeStatus30Days": "30 days", + "distributedUptimeStatus60Days": "60 days", + "distributedUptimeStatus90Days": "90 days", + "distributedUptimeStatusPageNotSetUp": "A status page is not set up.", + "distributedUptimeStatusContactAdmin": "Please contact your administrator", + "distributedUptimeStatusPageNotPublic": "This status page is not public.", + "distributedUptimeStatusPageDeleteDialog": "Do you want to delete this status page?", + "distributedUptimeStatusPageDeleteConfirm": "Yes, delete status page", + "distributedUptimeStatusPageDeleteDescription": "Once deleted, your status page cannot be retrieved.", + "distributedUptimeStatusDevices": "Devices", + "distributedUptimeStatusUpt": "UPT", + "distributedUptimeStatusUptBurned": "UPT Burned", + "distributedUptimeStatusUptLogo": "Upt Logo", + "incidentsTableNoIncidents": "No incidents recorded", + "incidentsTablePaginationLabel": "incidents", + "incidentsTableMonitorName": "Monitor Name", + "incidentsTableStatus": "Status", + "incidentsTableDateTime": "Date & Time", + "incidentsTableStatusCode": "Status Code", + "incidentsTableMessage": "Message", + "incidentsOptionsHeader": "Incidents for:", + "incidentsOptionsHeaderFilterBy": "Filter by:", + "incidentsOptionsHeaderFilterAll": "All", + "incidentsOptionsHeaderFilterDown": "Down", + "incidentsOptionsHeaderFilterCannotResolve": "Cannot resolve", + "incidentsOptionsHeaderShow": "Show:", + "incidentsOptionsHeaderLastHour": "Last hour", + "incidentsOptionsHeaderLastDay": "Last day", + "incidentsOptionsHeaderLastWeek": "Last week", + "incidentsOptionsPlaceholderAllServers": "All servers", + "infrastructureCreateYour": "Create your", + "infrastructureCreateGeneralSettingsDescription": "Here you can select the URL of the host, together with the friendly name and authorization secret to connect to the server agent.", + "infrastructureServerRequirement": "The server you are monitoring must be running the", + "infrastructureCustomizeAlerts": "Customize alerts", + "infrastructureAlertNotificationDescription": "Send a notification to user(s) when thresholds exceed a specified percentage.", + "infrastructureCreateMonitor": "Create Infrastructure Monitor", + "infrastructureProtocol": "Protocol", + "infrastructureServerUrlLabel": "Server URL", + "infrastructureDisplayNameLabel": "Display name", + "infrastructureAuthorizationSecretLabel": "Authorization secret", + "gb": "GB", + "mb": "MB", + "mem": "Mem", + "memoryUsage": "Memory usage", + "cpu": "CPU", + "cpuUsage": "CPU usage", + "cpuTemperature": "CPU Temperature", + "diskUsage": "Disk Usage", + "used": "Used", + "total": "Total", + "cores": "Cores", + "frequency": "Frequency", + "status": "Status", + "cpuPhysical": "CPU (Physical)", + "cpuLogical": "CPU (Logical)", + "cpuFrequency": "CPU Frequency", + "avgCpuTemperature": "Average CPU Temperature", + "memory": "Memory", + "disk": "Disk", + "uptime": "Uptime", + "os": "OS", + "host": "Host", + "actions": "Actions", + "integrations": "Integrations", + "integrationsPrism": "Connect Prism to your favorite service.", + "integrationsSlack": "Slack", + "integrationsSlackInfo": "Connect with Slack and see incidents in a channel", + "integrationsDiscord": "Discord", + "integrationsDiscordInfo": "Connect with Discord and view incidents directly in a channel", + "integrationsZapier": "Zapier", + "integrationsZapierInfo": "Send all incidents to Zapier, and then see them everywhere", + "commonSave": "Save", + "createYour": "Create your", + "createMonitor": "Create monitor", + "pause": "Pause", + "resume": "Resume", + "editing": "Editing...", + "url": "URL", + "access": "Access", + "timezone": "Timezone", + "features": "Features", + "administrator": "Administrator?", + "loginHere": "Login here", + "displayName": "Display name", + "urlMonitor": "URL to monitor", + "portToMonitor": "Port to monitor", + "websiteMonitoring": "Website monitoring", + "websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.", + "pingMonitoring": "Ping monitoring", + "pingMonitoringDescription": "Check whether your server is available or not.", + "dockerContainerMonitoring": "Docker container monitoring", + "dockerContainerMonitoringDescription": "Check whether your Docker container is running or not.", + "portMonitoring": "Port monitoring", + "portMonitoringDescription": "Check whether your port is open or not.", + "createMaintenanceWindow": "Create maintenance window", + "createMaintenance": "Create maintenance", + "editMaintenance": "Edit maintenance", + "maintenanceWindowName": "Maintenance Window Name", + "friendlyNameInput": "Friendly name", + "friendlyNamePlaceholder": "Maintenance at __ : __ for ___ minutes", + "maintenanceRepeat": "Maintenance Repeat", + "maintenance": "maintenance", + "duration": "Duration", + "addMonitors": "Add monitors", + "window": "window", + "cancel": "Cancel", + "message": "Message", + "low": "low", + "high": "high", + "statusCode": "Status code", + "date&Time": "Date & Time", + "type": "Type", + "statusPageName": "Status page name", + "publicURL": "Public URL", + "repeat": "Repeat", + "edit": "Edit", + "createA": "Create a", + "remove": "Remove", + "maintenanceWindowDescription": "Your pings won't be sent during this time frame", + "startTime": "Start time", + "timeZoneInfo": "All dates and times are in GMT+0 time zone.", + "monitorsToApply": "Monitors to apply maintenance window to", + "nextWindow": "Next window", + "notFoundButton": "Go to the main dashboard", + "pageSpeedConfigureSettingsDescription": "Here you can select the URL of the host, together with the type of monitor.", + "monitorDisplayName": "Monitor display name", + "whenNewIncident": "When there is a new incident,", + "notifySMS": "Notify via SMS (coming soon)", + "notifyEmails": "Also notify via email to multiple addresses (coming soon)", + "seperateEmails": "You can separate multiple emails with a comma", + "checkFrequency": "Check frequency", + "matchMethod": "Match Method", + "expectedValue": "Expected value", + "deleteDialogTitle": "Do you really want to delete this monitor?", + "deleteDialogDescription": "Once deleted, this monitor cannot be retrieved.", + "pageSpeedMonitor": "PageSpeed monitor", + "shown": "Shown", + "ago": "ago", + "companyName": "Company name", + "pageSpeedDetailsPerformanceReport": "Values are estimated and may vary.", + "pageSpeedDetailsPerformanceReportCalculator": "See calculator", + "checkingEvery": "Checking every", + "statusPageCreateSettings": "If your status page is ready, you can mark it as published.", + "basicInformation": "Basic Information", + "statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.", + "statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.", + "statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.", + "statusPageCreateSettingsCheckboxLabel": "Published and visible to the public", + "statusPageCreateBasicInfoStatusPageAddress": "Your status page address", + "statusPageCreateTabsContent": "Status page servers", + "statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.", + "statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page", + "showCharts": "Show charts", + "showUptimePercentage": "Show uptime percentage", + "removeLogo": "Remove Logo", + "statusPageStatus": "A public status page is not set up.", + "statusPageStatusContactAdmin": "Please contact to your administrator", + "statusPageStatusNotPublic": "This status page is not public.", + "statusPageStatusNoPage": "There's no status page here.", + "statusPageStatusServiceStatus": "Service status", + "deleteStatusPage": "Do you want to delete this status page?", + "deleteStatusPageConfirm": "Yes, delete status page", + "deleteStatusPageDescription": "Once deleted, your status page cannot be retrieved.", + "uptimeCreate": "The expected value is used to match against response result, and the match determines the status.", + "uptimeCreateJsonPath": "This expression will be evaluated against the reponse JSON data and the result will be used to match against the expected value. See", + "uptimeCreateJsonPathQuery": "for query language documentation.", + "maintenanceTableActionMenuDialogTitle": "Do you really want to remove this maintenance window?", + "infrastructureEditYour": "Edit your", + "infrastructureEditMonitor": "Save Infrastructure Monitor", + "infrastructureMonitorCreated": "Infrastructure monitor created successfully!", + "infrastructureMonitorUpdated": "Infrastructure monitor updated successfully!", + "errorInvalidTypeId": "Invalid notification type provided", + "errorInvalidFieldId": "Invalid field ID provided", + "inviteNoTokenFound": "No invite token found", + "pageSpeedWarning": "Warning: You haven't added a Google PageSpeed API key. Without it, the PageSpeed monitor won't function.", + "pageSpeedLearnMoreLink": "Click here to learn", + "pageSpeedAddApiKey": "how to add your API key." +} diff --git a/src/locales/tr.json b/src/locales/tr.json new file mode 100644 index 000000000..1b759a29d --- /dev/null +++ b/src/locales/tr.json @@ -0,0 +1,382 @@ +{ + "dontHaveAccount": "Hesabınız yok mu", + "email": "E-posta", + "forgotPassword": "Parolamı unuttum", + "password": "Parola", + "signUp": "Kayıt Ol", + "submit": "Gönder", + "title": "Başlık", + "continue": "Devam Et", + "enterEmail": "E-posta adresinizi girin", + "authLoginTitle": "Giriş Yap", + "authLoginEnterPassword": "Parolanızı girin", + "commonPassword": "Parola", + "commonBack": "Geri", + "authForgotPasswordTitle": "Parolanızı mı unuttunuz?", + "authForgotPasswordResetPassword": "Parola sıfırla", + "createPassword": "Parolanızı oluşturun", + "createAPassword": "Bir parola oluşturun", + "authRegisterAlreadyHaveAccount": "Zaten hesabınız var mı?", + "commonAppName": "Checkmate", + "authLoginEnterEmail": "E-posta adresinizi girin", + "authRegisterTitle": "Hesap oluştur", + "authRegisterStepOneTitle": "Hesabınızı oluşturun", + "authRegisterStepOneDescription": "Başlamak için bilgilerinizi girin", + "authRegisterStepTwoTitle": "Profilinizi ayarlayın", + "authRegisterStepTwoDescription": "Kendiniz hakkında daha fazla bilgi verin", + "authRegisterStepThreeTitle": "Neredeyse bitti!", + "authRegisterStepThreeDescription": "Bilgilerinizi gözden geçirin", + "authForgotPasswordDescription": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", + "authForgotPasswordSendInstructions": "Talimatları gönder", + "authForgotPasswordBackTo": "Geri dön", + "authCheckEmailTitle": "E-postanızı kontrol edin", + "authCheckEmailDescription": "{{email}} adresine şifre sıfırlama bağlantısı gönderdik", + "authCheckEmailResendEmail": "E-postayı yeniden gönder", + "authCheckEmailBackTo": "Geri dön", + "goBackTo": "Geri dön", + "authCheckEmailDidntReceiveEmail": "E-posta almadınız mı?", + "authCheckEmailClickToResend": "Yeniden göndermek için tıklayın", + "authSetNewPasswordTitle": "Yeni şifre belirle", + "authSetNewPasswordDescription": "Yeni şifreniz daha önce kullanılan şifrelerden farklı olmalıdır.", + "authSetNewPasswordNewPassword": "Yeni şifre", + "authSetNewPasswordConfirmPassword": "Parolayı onayla", + "confirmPassword": "Parolanızı onaylayın", + "authSetNewPasswordResetPassword": "Parola sıfırla", + "authSetNewPasswordBackTo": "Geri dön", + "authPasswordMustBeAtLeast": "En az", + "authPasswordCharactersLong": "8 karakter uzunluğunda olmalı", + "authPasswordMustContainAtLeast": "En az içermeli", + "authPasswordSpecialCharacter": "bir özel karakter", + "authPasswordOneNumber": "bir rakam", + "authPasswordUpperCharacter": "bir büyük harf", + "authPasswordLowerCharacter": "bir küçük harf", + "authPasswordConfirmAndPassword": "Onay şifresi ve şifre", + "authPasswordMustMatch": "eşleşmelidir", + "authRegisterCreateAccount": "Hesap oluşturmak için devam et", + "authRegisterCreateSuperAdminAccount": "Super admin hesabınızı oluşturmak için devam edin", + "authRegisterSignUpWithEmail": "E-posta ile kayıt ol", + "authRegisterBySigningUp": "Kayıt olarak, aşağıdaki şartları kabul ediyorsunuz:", + "distributedStatusHeaderText": "Gerçek zamanlı, Gerçek cihazlar kapsamı", + "distributedStatusSubHeaderText": "Dünya çapında milyonlarca cihaz tarafından desteklenen sistem performansını küresel bölgeye, ülkeye veya şehre göre görüntüleyin", + "settingsGeneralSettings": "Genel ayarlar", + "settingsDisplayTimezone": "Görüntüleme saat dilimi", + "settingsDisplayTimezoneDescription": "Herkese açık olarak görüntülediğiniz kontrol panelinin saat dilimi.", + "settingsAppearance": "Görünüm", + "settingsAppearanceDescription": "Açık ve koyu mod arasında geçiş yapın veya kullanıcı arayüzü dilini değiştirin", + "settingsThemeMode": "Tema", + "settingsLanguage": "Dil", + "settingsDistributedUptime": "Dağıtılmış çalışma süresi", + "settingsDistributedUptimeDescription": "Dağıtılmış çalışma süresi izlemeyi etkinleştirin/devre dışı bırakın.", + "settingsEnabled": "Etkin", + "settingsDisabled": "Devre dışı", + "settingsHistoryAndMonitoring": "Geçmiş ve izleme", + "settingsHistoryAndMonitoringDescription": "Verileri ne kadar süreyle saklamak istediğinizi burada tanımlayın. Ayrıca tüm geçmiş verileri kaldırabilirsiniz.", + "settingsTTLLabel": "İzleme geçmişini saklamak istediğiniz gün sayısı.", + "settingsTTLOptionalLabel": "Sınırsız için 0", + "settingsClearAllStats": "Tüm istatistikleri temizle. Bu geri alınamaz.", + "settingsClearAllStatsButton": "Tüm istatistikleri temizle", + "settingsClearAllStatsDialogTitle": "Tüm istatistikleri temizlemek istiyor musunuz?", + "settingsClearAllStatsDialogDescription": "Silindikten sonra, monitörleriniz geri alınamaz.", + "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", + "settingsDemoMonitors": "Demo monitörler", + "settingsDemoMonitorsDescription": "Burada demo monitörler ekleyebilir ve kaldırabilirsiniz.", + "settingsAddDemoMonitors": "Demo monitörler ekle", + "settingsAddDemoMonitorsButton": "Demo monitörler ekle", + "settingsRemoveAllMonitors": "Tüm monitörleri kaldır", + "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", + "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", + "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri temizle", + "settingsWallet": "Cüzdan", + "settingsWalletDescription": "Cüzdanınızı buradan bağlayın. Bu, Dağıtılmış Çalışma Süresi monitörünün küresel olarak birden çok düğüme bağlanması için gereklidir.", + "settingsAbout": "Hakkında", + "settingsDevelopedBy": "Bluewave Labs tarafından geliştirilmiştir.", + "settingsSave": "Kaydet", + "settingsSuccessSaved": "Ayarlar başarıyla kaydedildi", + "settingsFailedToSave": "Ayarlar kaydedilemedi", + "settingsStatsCleared": "İstatistikler başarıyla temizlendi", + "settingsFailedToClearStats": "İstatistikler temizlenemedi", + "settingsDemoMonitorsAdded": "Demo monitörler başarıyla eklendi", + "settingsFailedToAddDemoMonitors": "Demo monitörler eklenemedi", + "settingsMonitorsDeleted": "Tüm monitörler başarıyla silindi", + "settingsFailedToDeleteMonitors": "Monitörler silinemedi", + "starPromptTitle": "Checkmate yıldızla değerlendirin", + "starPromptDescription": "En son sürümleri görün ve GitHub'daki topluluğun büyümesine yardımcı olun", + "https": "HTTPS", + "http": "HTTP", + "monitor": "monitör", + "aboutus": "Hakkımızda", + "signUP": "Hesap Oluştur", + "now": "Şimdi", + "delete": "Sil", + "configure": "Yapılandır", + "networkError": "Ağ hatası", + "responseTime": "Yanıt süresi:", + "ms": "ms", + "bar": "Çubuk", + "area": "Alan", + "country": "ÜLKE", + "city": "ŞEHİR", + "response": "YANIT", + "checkConnection": "Lütfen bağlantınızı kontrol edin", + "passwordreset": "Parola Sıfırlama", + "authRegisterStepOnePersonalDetails": "Kişisel bilgilerinizi girin", + "authCheckEmailOpenEmailButton": "Eposta uygulamasını aç", + "authNewPasswordConfirmed": "Parolanız başarıyla sıfırlandı. Otomatik olarak giriş yapmak için aşağıya tıklayın.", + "monitorStatusUp": "Monitör {name} ({url}) ayakta ve yanıt veriyor", + "monitorStatusDown": "Monitör {name} ({url}) yanıt vermiyor", + "webhookSendSuccess": "Web kanca bildirimi başarıyla gönderildi", + "webhookSendError": "Web kanca bildirimi bu platforma gönderilemedi: {platform}", + "webhookUnsupportedPlatform": "Desteklenmeyen platform: {platform}", + "distributedRightCategoryTitle": "Monitör", + "distributedStatusServerMonitors": "Sunucu monitörleri", + "distributedStatusServerMonitorsDescription": "İlgili sunucuların monitör durumları", + "distributedUptimeCreateSelectURL": "Burada sunucu adresini (URL) ve monitör türünü girebilirsiniz.", + "distributedUptimeCreateChecks": "Yapılacak kontroller", + "distributedUptimeCreateChecksDescription": "Adresi girdikten sonra kontrol ekleyebilir ya da çıkartabilirsiniz.", + "distributedUptimeCreateIncidentNotification": "Olay bildirimleri", + "distributedUptimeCreateIncidentDescription": "Bir olay olduğunda kullanıcıları bilgilendir.", + "distributedUptimeCreateAdvancedSettings": "Gelişmiş ayarlar", + "distributedUptimeDetailsNoMonitorHistory": "Bu monitör için henüz bir denetim günlüğü oluşturulmadı.", + "distributedUptimeDetailsFooterHeading": "UpRock & Bluewave Labs tarafından geliştirildi", + "distributedUptimeDetailsFooterBuilt": "Altyapı", + "distributedUptimeDetailsFooterSolana": "Solana", + "distributedUptimeDetailsMonitorHeader": "Depin Destekli Dağıtık Kesintisizlik İzleme", + "distributedUptimeDetailsStatusHeaderUptime": "Erişilebilirlik", + "distributedUptimeDetailsStatusHeaderLastUpdate": "Son güncelleme", + "notifications": { + "enableNotifications": "{{platform}} bildirimlerini etkinleştir", + "testNotification": "Bildirimi test et", + "addOrEditNotifications": "Bildirimleri ekle ya da düzenle", + "slack": { + "label": "Slack", + "description": "Slack bildirimlerini etkinleştirmek için bir Slack uygulaması oluşturun ve gelen web kancalarını etkinleştirin. Daha sonra, webhook URL’sini buraya girmeniz yeterlidir.\n\n\n\n\n\n", + "webhookLabel": "Web kanca URL:", + "webhookPlaceholder": "https://hooks.slack.com/services/...", + "webhookRequired": "" + }, + "discord": { + "label": "Discord", + "description": "Checkmate’ten Discord bildirimleri aracılığıyla bir Discord kanalına veri göndermek için Discord’un gelen web kancaları özelliğini kullanabilirsiniz.\n\n\n\n\n\n\n\n", + "webhookLabel": "Discord web kanca URL", + "webhookPlaceholder": "https://discord.com/api/webhooks/...", + "webhookRequired": "" + }, + "telegram": { + "label": "Telegram", + "description": "Telegram bildirimlerini etkinleştirmek için, Telegram botlarını oluşturup yönetmek için kullanılan resmi bot BotFather ile bir Telegram botu oluşturun. Daha sonra, API jetonunu (token) ve sohbet kimliğini (chat ID) alın ve buraya yazın.", + "tokenLabel": "Bot jetonu (token)", + "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", + "chatIdLabel": "Sohbet ID", + "chatIdPlaceholder": "-1001234567890", + "fieldsRequired": "" + }, + "webhook": { + "label": "Web kancaları", + "description": "Olaylar meydana geldiğinde bildirim almak için özel bir web kancası ayarlayabilirsiniz.", + "urlLabel": "Web kanca URL:", + "urlPlaceholder": "https://sunucu-adresiniz.com/webhook", + "urlRequired": "" + }, + "testNotificationDevelop": "Test bildirimi 2", + "integrationButton": "Bildirim Entegrasyonu", + "testSuccess": "", + "testFailed": "", + "unsupportedType": "", + "networkError": "" + }, + "testLocale": "TEST13 UPLOAD", + "add": "Ekle", + "monitors": "Monitörler", + "distributedUptimeStatusCreateStatusPage": "durum sayfası", + "distributedUptimeStatusCreateStatusPageAccess": "Erişim", + "distributedUptimeStatusCreateStatusPageReady": "Durum sayfanız hazırsa yayınlayabilirsiniz.", + "distributedUptimeStatusBasicInfoHeader": "Temel bilgiler", + "distributedUptimeStatusBasicInfoDescription": "", + "distributedUptimeStatusLogoHeader": "Logo", + "distributedUptimeStatusLogoDescription": "Durum sayfanız için bir logo yükleyin", + "distributedUptimeStatusLogoUploadButton": "Logo yükle", + "distributedUptimeStatusStandardMonitorsHeader": "Standart monitörler", + "distributedUptimeStatusStandardMonitorsDescription": "Durum sayfanıza standart monitörleri ekleyin.", + "distributedUptimeStatusCreateYour": "", + "distributedUptimeStatusEditYour": "", + "distributedUptimeStatusPublishedLabel": "Yayında ve herkes tarafından görülebilir", + "distributedUptimeStatusCompanyNameLabel": "Şirket adı", + "distributedUptimeStatusPageAddressLabel": "Durum sayfası adresi", + "distributedUptimeStatus30Days": "30 gün", + "distributedUptimeStatus60Days": "60 gün", + "distributedUptimeStatus90Days": "90 gün", + "distributedUptimeStatusPageNotSetUp": "Henüz bir durum sayfası oluşturulmadı.", + "distributedUptimeStatusContactAdmin": "Lütfen yöneticiniz ile görüşün", + "distributedUptimeStatusPageNotPublic": "Bu durum sayfası herkese açık değil", + "distributedUptimeStatusPageDeleteDialog": "Bu durum sayfasını silmek istiyor musunuz? ", + "distributedUptimeStatusPageDeleteConfirm": "Evet, durum sayfasını sil", + "distributedUptimeStatusPageDeleteDescription": "Silindiği zaman durum sayfalarını geri getiremezsiniz.", + "distributedUptimeStatusDevices": "Cihazlar", + "distributedUptimeStatusUpt": "UPT", + "distributedUptimeStatusUptBurned": "Yakılan UPT", + "distributedUptimeStatusUptLogo": "Upt Logo", + "incidentsTableNoIncidents": "Hiç olay kaydedilmedi", + "incidentsTablePaginationLabel": "olaylar", + "incidentsTableMonitorName": "Monitör adı", + "incidentsTableStatus": "Durum", + "incidentsTableDateTime": "Tarih ve saat", + "incidentsTableStatusCode": "Durum kodu", + "incidentsTableMessage": "Mesaj", + "incidentsOptionsHeader": "Servisler:", + "incidentsOptionsHeaderFilterBy": "Filtrele:", + "incidentsOptionsHeaderFilterAll": "Tümü", + "incidentsOptionsHeaderFilterDown": "Erişilemiyor", + "incidentsOptionsHeaderFilterCannotResolve": "Çözümlenemiyor", + "incidentsOptionsHeaderShow": "Göster:", + "incidentsOptionsHeaderLastHour": "Son saat", + "incidentsOptionsHeaderLastDay": "Son gün", + "incidentsOptionsHeaderLastWeek": "Son hafta", + "incidentsOptionsPlaceholderAllServers": "Tüm sunucular", + "infrastructureCreateYour": "", + "infrastructureCreateGeneralSettingsDescription": "", + "infrastructureServerRequirement": "", + "infrastructureCustomizeAlerts": "Alarmları özelleştir", + "infrastructureAlertNotificationDescription": "", + "infrastructureCreateMonitor": "Altyapı Monitörü oluştur", + "infrastructureProtocol": "Protokol", + "infrastructureServerUrlLabel": "Sunucu adresi", + "infrastructureDisplayNameLabel": "Görünen adı", + "infrastructureAuthorizationSecretLabel": "Kimlik denetimi parolası", + "gb": "GB", + "mb": "MB", + "mem": "Bellek", + "memoryUsage": "Bellek kullanımı", + "cpu": "CPU", + "cpuUsage": "CPU kullanımı", + "cpuTemperature": "CPU sıcaklığı", + "diskUsage": "Disk kullanımı", + "used": "Kullanılan", + "total": "Toplam", + "cores": "Çekirdek", + "frequency": "Frekans", + "status": "Durum", + "cpuPhysical": "CPU (fiziksel)", + "cpuLogical": "CPU (Mantıksal)", + "cpuFrequency": "CPU Frekansı", + "avgCpuTemperature": "Ortalama CPU Isısı", + "memory": "Bellek", + "disk": "Disk", + "uptime": "", + "os": "İşletim sistemi", + "host": "Makine", + "actions": "İşlemler", + "integrations": "Entegrasyonlar", + "integrationsPrism": "Prism'i favori servisinize bağlayın.", + "integrationsSlack": "Slack", + "integrationsSlackInfo": "", + "integrationsDiscord": "Discord", + "integrationsDiscordInfo": "", + "integrationsZapier": "Zapier", + "integrationsZapierInfo": "", + "commonSave": "Kaydet", + "createYour": "", + "createMonitor": "Monitör oluştur", + "pause": "Beklet", + "resume": "Yeniden başlat", + "editing": "Düzenleniyor...", + "url": "URL", + "access": "Erişim", + "timezone": "Zaman dilimi", + "features": "Özellikler", + "administrator": "Yönetici misin?", + "loginHere": "Buradan giriş yap", + "displayName": "Görüntülenecek isim", + "urlMonitor": "Monitör edilecek URL", + "portToMonitor": "Monitör edilecek port", + "websiteMonitoring": "Web sitesi monitörü", + "websiteMonitoringDescription": "", + "pingMonitoring": "Ping monitörü", + "pingMonitoringDescription": "Sitenizin ayakta olup olmadığını denetleyin.", + "dockerContainerMonitoring": "Docker konteyner monitörü", + "dockerContainerMonitoringDescription": "Docker konteynerinizin ayakta olup olmadığını denetleyin.", + "portMonitoring": "Port monitörü", + "portMonitoringDescription": "Portunuzun açık olup olmadığını denetleyin.", + "createMaintenanceWindow": "Bakım aralığı oluşturun", + "createMaintenance": "Bakım oluştur", + "editMaintenance": "Bakımı düzenle", + "maintenanceWindowName": "Bakım aralığı adı", + "friendlyNameInput": "Görünen ad", + "friendlyNamePlaceholder": "__:__ saatinde __ dakika boyunca bakım var", + "maintenanceRepeat": "Bakım Tekrarı", + "maintenance": "bakım", + "duration": "Süre", + "addMonitors": "Monitör ekle", + "window": "pencere", + "cancel": "İptal", + "message": "Mesaj", + "low": "düşük", + "high": "yüksek", + "statusCode": "Durum kodu", + "date&Time": "", + "type": "", + "statusPageName": "", + "publicURL": "", + "repeat": "", + "edit": "", + "createA": "", + "remove": "", + "maintenanceWindowDescription": "", + "startTime": "Başlangıç saati", + "timeZoneInfo": "", + "monitorsToApply": "", + "nextWindow": "Sonraki pencere", + "notFoundButton": "", + "pageSpeedConfigureSettingsDescription": "", + "monitorDisplayName": "", + "whenNewIncident": "Yeni bir olay oluştuğunda,", + "notifySMS": "", + "notifyEmails": "", + "seperateEmails": "", + "checkFrequency": "Frekansı denetle", + "matchMethod": "", + "expectedValue": "Beklenen değer", + "deleteDialogTitle": "Gerçekten bu monitörü silmek istiyor musunuz?", + "deleteDialogDescription": "Bir kez silindiği zaman tekrar getiremezsiniz.", + "pageSpeedMonitor": "Sayfa Hızı Monitörü", + "shown": "", + "ago": "", + "companyName": "Firma adı", + "pageSpeedDetailsPerformanceReport": "", + "pageSpeedDetailsPerformanceReportCalculator": "Hesap makinesini gör", + "checkingEvery": "Denetleme sıklığı", + "statusPageCreateSettings": "Eğer durum sayfanız hazırsa, herkese açık yayınlayabilirsiniz", + "basicInformation": "Temel Bilgiler", + "statusPageCreateBasicInfoDescription": "", + "statusPageCreateSelectTimeZoneDescription": "", + "statusPageCreateAppearanceDescription": "", + "statusPageCreateSettingsCheckboxLabel": "Yayınlandı ve herkese açık", + "statusPageCreateBasicInfoStatusPageAddress": "Durum sayfası adresiniz", + "statusPageCreateTabsContent": "Durum sayfası sunucuları", + "statusPageCreateTabsContentDescription": "", + "statusPageCreateTabsContentFeaturesDescription": "Durum sayfasında daha fazla bilgi göster", + "showCharts": "Çizelgeleri göster", + "showUptimePercentage": "", + "removeLogo": "Logoyu sil", + "statusPageStatus": "Herkese açık bir durum sayfası henüz oluşturulmadı.", + "statusPageStatusContactAdmin": "Lütfen yöneticinizle iletişime geçin.", + "statusPageStatusNotPublic": "Durum sayfası herkese açık değil.", + "statusPageStatusNoPage": "Burada bir durum sayfası bulunmuyor.", + "statusPageStatusServiceStatus": "Servis durumu", + "deleteStatusPage": "Gerçekten bu durum sayfasını silmek istiyor musunuz?", + "deleteStatusPageConfirm": "Evet, durum sayfasını sil", + "deleteStatusPageDescription": "Silindikten sonra durum sayfasını geri getiremezsiniz.", + "uptimeCreate": "", + "uptimeCreateJsonPath": "", + "uptimeCreateJsonPathQuery": "", + "maintenanceTableActionMenuDialogTitle": "Gerçekten bu bakım aralığını silmek istiyor musunuz?", + "infrastructureEditYour": "", + "infrastructureEditMonitor": "", + "infrastructureMonitorCreated": "", + "infrastructureMonitorUpdated": "", + "errorInvalidTypeId": "", + "errorInvalidFieldId": "", + "inviteNoTokenFound": "", + "pageSpeedWarning": "", + "pageSpeedLearnMoreLink": "", + "pageSpeedAddApiKey": "" +} From 91dee2b8ecd7edf0f32fbc6daefd8334c0179a35 Mon Sep 17 00:00:00 2001 From: Aryaman Kumar Sharma Date: Mon, 21 Apr 2025 21:28:02 +0530 Subject: [PATCH 002/147] Fix: Move MD Files from client to main dir --- client/CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md | 0 client/CONTRIBUTING.md => CONTRIBUTING.md | 0 client/LICENSE => LICENSE | 0 client/PULLREQUESTS.md => PULLREQUESTS.md | 0 client/SECURITY.md => SECURITY.md | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename client/CODE_OF_CONDUCT.md => CODE_OF_CONDUCT.md (100%) rename client/CONTRIBUTING.md => CONTRIBUTING.md (100%) rename client/LICENSE => LICENSE (100%) rename client/PULLREQUESTS.md => PULLREQUESTS.md (100%) rename client/SECURITY.md => SECURITY.md (100%) diff --git a/client/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md similarity index 100% rename from client/CODE_OF_CONDUCT.md rename to CODE_OF_CONDUCT.md diff --git a/client/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from client/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/client/LICENSE b/LICENSE similarity index 100% rename from client/LICENSE rename to LICENSE diff --git a/client/PULLREQUESTS.md b/PULLREQUESTS.md similarity index 100% rename from client/PULLREQUESTS.md rename to PULLREQUESTS.md diff --git a/client/SECURITY.md b/SECURITY.md similarity index 100% rename from client/SECURITY.md rename to SECURITY.md From 50452bc93d9c21d9512baea40b864f926d147b0f Mon Sep 17 00:00:00 2001 From: "Gorkem Cetin (BWL)" <167266851+gorkem-bwl@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:51:30 -0400 Subject: [PATCH 003/147] Fix after merge --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index b625890aa..022e04bf1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ![dashboard](https://github.com/user-attachments/assets/252d6047-522b-4576-8f14-233510e464b8) -This repository contains the **frontend** of Checkmate, an open-source, self-hosted monitoring tool for tracking server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. Checkmate regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time. +This repository contains both the frontend and the backend of Checkmate, an open-source, self-hosted monitoring tool for tracking server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. Checkmate regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time. Checkmate also has an agent, called [Capture](https://github.com/bluewave-labs/capture), to retrieve data from remote servers. While Capture is not required to run Checkmate, it provides additional insights about your servers' CPU, RAM, disk, and temperature status. @@ -23,8 +23,6 @@ Checkmate has been stress-tested with 1000+ active monitors without any particul We **love** what we are building here, and we continuously learn a few things about Reactjs, Nodejs, MongoDB, and Docker while building Checkmate. -For backend files, please check [Checkmate backend](https://github.com/bluewave-labs/checkmate-backend) repository. - ## 📦 Demo See [Checkmate](https://checkmate-demo.bluewavelabs.ca/) in action. The username is uptimedemo@demo.com and the password is Demouser1! (just a note that we update the demo server from time to time, so if it doesn't work for you, please ping us on the Discussions channel). From 39a9b96f2b1da585a9841e727be713606a025c55 Mon Sep 17 00:00:00 2001 From: "Gorkem Cetin (BWL)" <167266851+gorkem-bwl@users.noreply.github.com> Date: Tue, 22 Apr 2025 12:10:56 -0400 Subject: [PATCH 004/147] Update README.md --- client/README.md | 144 +---------------------------------------------- 1 file changed, 1 insertion(+), 143 deletions(-) diff --git a/client/README.md b/client/README.md index 1600c9815..ee3ed2de2 100644 --- a/client/README.md +++ b/client/README.md @@ -1,144 +1,2 @@ -

bluewave-labs%2Fcheckmate | Trendshift

- -![](https://img.shields.io/github/license/bluewave-labs/checkmate) -![](https://img.shields.io/github/repo-size/bluewave-labs/checkmate) -![](https://img.shields.io/github/commit-activity/m/bluewave-labs/checkmate) -![](https://img.shields.io/github/last-commit/bluewave-labs/checkmate) -![](https://img.shields.io/github/languages/top/bluewave-labs/checkmate) -![](https://img.shields.io/github/issues/bluewave-labs/checkmate) -![](https://img.shields.io/github/issues-pr/bluewave-labs/checkmate) -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9901/badge)](https://www.bestpractices.dev/projects/9901) -

Checkmate

- -

An open source uptime and infrastructure monitoring application

- -![dashboard](https://github.com/user-attachments/assets/252d6047-522b-4576-8f14-233510e464b8) - -This repository contains the **frontend** of Checkmate, an open-source, self-hosted monitoring tool for tracking server hardware, uptime, response times, and incidents in real-time with beautiful visualizations. Checkmate regularly checks whether a server/website is accessible and performs optimally, providing real-time alerts and reports on the monitored services' availability, downtime, and response time. - -Checkmate also has an agent, called [Capture](https://github.com/bluewave-labs/capture), to retrieve data from remote servers. While Capture is not required to run Checkmate, it provides additional insights about your servers' CPU, RAM, disk, and temperature status. - -Checkmate has been stress-tested with 1000+ active monitors without any particular issues or performance bottlenecks. - -We **love** what we are building here, and we continuously learn a few things about Reactjs, Nodejs, MongoDB, and Docker while building Checkmate. - -For backend files, please check [Checkmate backend](https://github.com/bluewave-labs/checkmate-backend) repository. - -## 📦 Demo - -See [Checkmate](https://checkmate-demo.bluewavelabs.ca/) in action. The username is uptimedemo@demo.com and the password is Demouser1! (just a note that we update the demo server from time to time, so if it doesn't work for you, please ping us on the Discussions channel). - -## 🔗 User's guide - -Usage instructions can be found [here](https://docs.checkmate.so/). It's still WIP and some of the information there might be outdated as we continuously add features weekly. Rest assured, we are doing our best! :) - -## 🛠️ Installation - -See installation instructions in [Checkmate documentation portal](https://docs.checkmate.so/quickstart). Alternatively, you can also use [Coolify](https://coolify.io/) or [Elestio](https://elest.io/open-source/checkmate) for a one-click Docker deployment. If you would like to monitor your server infrastructure, you'll need [Capture agent](https://github.com/bluewave-labs/capture). Capture repository also contains the installation instructions. - -## 🏁 Translations - -If you would like to use Checkmate in your language, please [go to this page](https://poeditor.com/join/project/lRUoGZFCsJ) and register for the language you would like to translate Checkmate to. - -## 🚀 Performance - -Thanks to extensive optimizations, Checkmate operates with an exceptionally small memory footprint, requiring minimal memory and CPU resources. Here’s the memory usage of a Node.js instance running on a server that monitors 323 servers every minute: - -![image](https://github.com/user-attachments/assets/37e04a75-d83a-488f-b25c-025511b492c9) - -You can see the memory footprint of MongoDB and Redis on the same server (398Mb and 15Mb) for the same amount of servers: - -![image](https://github.com/user-attachments/assets/3b469e85-e675-4040-a162-3f24c1afc751) - -## 💚 Questions & Ideas - -If you have any questions, suggestions or comments, please use our [Discord channel](https://discord.gg/NAb6H3UTjK). We've also launched our [Discussions](https://github.com/bluewave-labs/bluewave-uptime/discussions) page! Feel free to ask questions or share your ideas—we'd love to hear from you! - -## 🧩 Features - -- Completely open source, deployable on your servers -- Website monitoring -- Page speed monitoring -- Infrastructure monitoring (memory, disk usage, CPU performance etc) - requires [Capture](https://github.com/bluewave-labs/capture) -- Docker monitoring -- Ping monitoring -- SSL monitoring -- Port monitoring -- Incidents at a glance -- E-mail notifications -- Scheduled maintenance - -**Short term roadmap:** - -- Global (distributed) uptime checking on Solana network (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1593 -- 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 -- 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 -- DNS monitoring - -## 🏗️ Screenshots - -

-server -

-

-uptime -

-

-page speed -

- -## 🏗️ Tech stack - -- [ReactJs](https://react.dev/) -- [MUI (React framework)](https://mui.com/) -- [Node.js](https://nodejs.org/en) -- [MongoDB](https://mongodb.com) -- [Recharts](https://recharts.org) -- Lots of other open source components! - -## A few links - -- If you would like to support us, please consider giving it a ⭐ and click on "watch". -- Have a question or suggestion for the roadmap/featureset? Check our [Discord channel](https://discord.gg/NAb6H3UTjK) or [Discussions](https://github.com/bluewave-labs/checkmate/discussions) forum. -- Need a ping when there's a new release? Use [Newreleases](https://newreleases.io/), a free service to track releases. -- Watch a Checkmate [installation and usage video](https://www.youtube.com/watch?v=GfFOc0xHIwY) - -## 🤝 Contributing - -We are [Alex](http://github.com/ajhollid) (team lead), [Vishnu](http://github.com/vishnusn77), [Mohadeseh](http://github.com/mohicody), [Gorkem](http://github.com/gorkem-bwl/), [Owaise](http://github.com/Owaiseimdad), and [Aryaman](https://github.com/Br0wnHammer) 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! - -Here's how you can contribute: - -0. Star this repo :) -1. Check [Contributor's guideline](https://github.com/bluewave-labs/Checkmate/blob/develop/CONTRIBUTING.md). First timers are encouraged to check `good-first-issue` tag. -2. Optionally, read [project structure](https://docs.checkmate.so/developers-guide/general-project-structure) and [high level overview](https://bluewavelabs.gitbook.io/checkmate/developers-guide/high-level-overview). -3. Open an issue if you believe you've encountered a bug. -4. Check for good-first-issue's if you are a newcomer. -5. Make a pull request to add new features/make quality-of-life improvements/fix bugs. - - - - - -## 💰 Our sponsors - -Thanks to [Gitbook](https://gitbook.io/) for giving us a free tier for their documentation platform, and [Poeditor](https://poeditor.com/) providing us a free account to use their i18n services. If you would like to sponsor Checkmate, please send an email to hello@bluewavelabs.ca - -[![Star History Chart](https://api.star-history.com/svg?repos=bluewave-labs/checkmate&type=Date)](https://star-history.com/#bluewave-labs/bluewave-uptime&Date) - -Also check other developer and contributor-friendly projects of BlueWave: - -- [LangRoute](https://github.com/bluewave-labs/langroute), an LLM proxy and gateway -- [DataRoom](https://github.com/bluewave-labs/bluewave-dataroom), an secure file sharing application, aka dataroom. -- [Headcount](https://github.com/bluewave-labs/bluewave-hrm), a complete Human Resource Management platform. -- [Guidefox](https://github.com/bluewave-labs/guidefox), an application that helps new users learn how to use your product via hints, tours, popups and banners. -- [VerifyWise](https://github.com/bluewave-labs/verifywise), the first open source AI governance platform. +This directory contains the client side (frontend) of Checkmate. From b4b01f4efecb162076f08877631735b8852a8433 Mon Sep 17 00:00:00 2001 From: Aryaman Kumar Sharma Date: Tue, 22 Apr 2025 23:38:40 +0530 Subject: [PATCH 005/147] Fix: Uptime Create Monitor General Settings Text --- client/src/Pages/Uptime/Create/index.jsx | 2 +- client/src/locales/gb.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/Pages/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx index 0a1762887..74facf2ef 100644 --- a/client/src/Pages/Uptime/Create/index.jsx +++ b/client/src/Pages/Uptime/Create/index.jsx @@ -350,7 +350,7 @@ const CreateMonitor = () => { {t("settingsGeneralSettings")} - {t("distributedUptimeCreateSelectURL")} + {t("uptimeCreateSelectURL")} Date: Wed, 23 Apr 2025 01:07:37 +0530 Subject: [PATCH 006/147] FIX for index issue in server. --- server/db/models/Check.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/db/models/Check.js b/server/db/models/Check.js index 2361ea7a6..39c5281d2 100755 --- a/server/db/models/Check.js +++ b/server/db/models/Check.js @@ -77,7 +77,6 @@ CheckSchema.index({ updatedAt: 1 }); CheckSchema.index({ monitorId: 1, updatedAt: 1 }); CheckSchema.index({ monitorId: 1, updatedAt: -1 }); CheckSchema.index({ teamId: 1, updatedAt: -1 }); -CheckSchema.index({ teamId: 1 }); export default mongoose.model("Check", CheckSchema); export { BaseCheckSchema }; From a4a30761aba5714f26b3d0435826e15b3aa2d858 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 22 Apr 2025 15:00:38 -0700 Subject: [PATCH 007/147] init replica set --- docker/staging/docker-compose.yaml | 1 + docker/staging/mongo/init/init_replica_set.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 docker/staging/mongo/init/init_replica_set.js diff --git a/docker/staging/docker-compose.yaml b/docker/staging/docker-compose.yaml index d4dcb7302..128dc1a55 100755 --- a/docker/staging/docker-compose.yaml +++ b/docker/staging/docker-compose.yaml @@ -55,5 +55,6 @@ services: volumes: - ./mongo/data:/data/db - ./mongo/init/create_users.js:/docker-entrypoint-initdb.d/create_users.js + - ./mongo/init/init_replica_set.js:/docker-entrypoint-initdb.d/init_replica_set.js env_file: - mongo.env diff --git a/docker/staging/mongo/init/init_replica_set.js b/docker/staging/mongo/init/init_replica_set.js new file mode 100644 index 000000000..878ce68a6 --- /dev/null +++ b/docker/staging/mongo/init/init_replica_set.js @@ -0,0 +1,15 @@ +try { + const status = rs.status(); + printjson(status); +} catch (e) { + if (e.codeName === "NotYetInitialized") { + print("Replica set not initialized. Initiating..."); + rs.initiate({ + _id: "rs0", + members: [{ _id: 0, host: "mongodb:27017" }], + }); + } else { + print("Unexpected error during rs.status():"); + printjson(e); + } +} From 1b1317949fde1bdf6a708416aa9f0fc8ccae5ce5 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 22 Apr 2025 15:48:28 -0700 Subject: [PATCH 008/147] update paths for POEditor actions --- .github/workflows/poeditor-sync.yml | 8 ++++---- .github/workflows/upload-poeditor.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/poeditor-sync.yml b/.github/workflows/poeditor-sync.yml index 634809252..96f735100 100644 --- a/.github/workflows/poeditor-sync.yml +++ b/.github/workflows/poeditor-sync.yml @@ -88,9 +88,9 @@ jobs: - name: Copy translations to project run: | - mkdir -p src/locales - cp -r temp/* src/locales/ - echo "Translation files copied to src/locales/" + mkdir -p client/src/locales + cp -r temp/* client/src/locales/ + echo "Translation files copied to client/src/locales/" - name: Get current date id: date @@ -113,6 +113,6 @@ jobs: delete-branch: true base: develop add-paths: | - src/locales/*.json + client/src/locales/*.json committer: GitHub Action author: GitHub Action diff --git a/.github/workflows/upload-poeditor.yml b/.github/workflows/upload-poeditor.yml index 0cc0e0f07..f695c8bbc 100644 --- a/.github/workflows/upload-poeditor.yml +++ b/.github/workflows/upload-poeditor.yml @@ -6,7 +6,7 @@ on: branches: - develop paths: - - "src/locales/**" + - "client/src/locales/**" jobs: upload-translations: @@ -58,8 +58,8 @@ jobs: 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') + # Get list of changed files in client/src/locales directory + CHANGED_FILES=$(git diff --name-only $BASE_SHA..$HEAD_SHA -- 'client/src/locales/*.json' || git ls-files 'client/src/locales/*.json') if [ -z "$CHANGED_FILES" ]; then echo "No changes detected in locale files" @@ -81,7 +81,7 @@ jobs: # 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) + # Extract language code from filename (e.g., client/src/locales/en.json -> en) FILENAME=$(basename "$FILE") # Special case: map gb.json to en language code From 82670080a96f5b2e16d6e8b8f1e3ee604e0caa40 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 22 Apr 2025 15:49:37 -0700 Subject: [PATCH 009/147] remove incorrect locales dir --- src/locales/gb.json | 382 -------------------------------------------- src/locales/tr.json | 382 -------------------------------------------- 2 files changed, 764 deletions(-) delete mode 100644 src/locales/gb.json delete mode 100644 src/locales/tr.json diff --git a/src/locales/gb.json b/src/locales/gb.json deleted file mode 100644 index 343386bec..000000000 --- a/src/locales/gb.json +++ /dev/null @@ -1,382 +0,0 @@ -{ - "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/...", - "webhookRequired": "Slack webhook URL is required" - }, - "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/...", - "webhookRequired": "Discord webhook URL is required" - }, - "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", - "fieldsRequired": "Telegram token and chat ID are required" - }, - "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", - "urlRequired": "Webhook URL is required" - }, - "testNotificationDevelop": "Test notification 2", - "integrationButton": "Notification Integration", - "testSuccess": "Test notification sent successfully!", - "testFailed": "Failed to send test notification", - "unsupportedType": "Unsupported notification type", - "networkError": "Network error occurred" - }, - "testLocale": "testLocale", - "add": "Add", - "monitors": "monitors", - "distributedUptimeStatusCreateStatusPage": "status page", - "distributedUptimeStatusCreateStatusPageAccess": "Access", - "distributedUptimeStatusCreateStatusPageReady": "If your status page is ready, you can mark it as published.", - "distributedUptimeStatusBasicInfoHeader": "Basic Information", - "distributedUptimeStatusBasicInfoDescription": "Define company name and the subdomain that your status page points to.", - "distributedUptimeStatusLogoHeader": "Logo", - "distributedUptimeStatusLogoDescription": "Upload a logo for your status page", - "distributedUptimeStatusLogoUploadButton": "Upload logo", - "distributedUptimeStatusStandardMonitorsHeader": "Standard Monitors", - "distributedUptimeStatusStandardMonitorsDescription": "Attach standard monitors to your status page.", - "distributedUptimeStatusCreateYour": "Create your", - "distributedUptimeStatusEditYour": "Edit your", - "distributedUptimeStatusPublishedLabel": "Published and visible to the public", - "distributedUptimeStatusCompanyNameLabel": "Company name", - "distributedUptimeStatusPageAddressLabel": "Your status page address", - "distributedUptimeStatus30Days": "30 days", - "distributedUptimeStatus60Days": "60 days", - "distributedUptimeStatus90Days": "90 days", - "distributedUptimeStatusPageNotSetUp": "A status page is not set up.", - "distributedUptimeStatusContactAdmin": "Please contact your administrator", - "distributedUptimeStatusPageNotPublic": "This status page is not public.", - "distributedUptimeStatusPageDeleteDialog": "Do you want to delete this status page?", - "distributedUptimeStatusPageDeleteConfirm": "Yes, delete status page", - "distributedUptimeStatusPageDeleteDescription": "Once deleted, your status page cannot be retrieved.", - "distributedUptimeStatusDevices": "Devices", - "distributedUptimeStatusUpt": "UPT", - "distributedUptimeStatusUptBurned": "UPT Burned", - "distributedUptimeStatusUptLogo": "Upt Logo", - "incidentsTableNoIncidents": "No incidents recorded", - "incidentsTablePaginationLabel": "incidents", - "incidentsTableMonitorName": "Monitor Name", - "incidentsTableStatus": "Status", - "incidentsTableDateTime": "Date & Time", - "incidentsTableStatusCode": "Status Code", - "incidentsTableMessage": "Message", - "incidentsOptionsHeader": "Incidents for:", - "incidentsOptionsHeaderFilterBy": "Filter by:", - "incidentsOptionsHeaderFilterAll": "All", - "incidentsOptionsHeaderFilterDown": "Down", - "incidentsOptionsHeaderFilterCannotResolve": "Cannot resolve", - "incidentsOptionsHeaderShow": "Show:", - "incidentsOptionsHeaderLastHour": "Last hour", - "incidentsOptionsHeaderLastDay": "Last day", - "incidentsOptionsHeaderLastWeek": "Last week", - "incidentsOptionsPlaceholderAllServers": "All servers", - "infrastructureCreateYour": "Create your", - "infrastructureCreateGeneralSettingsDescription": "Here you can select the URL of the host, together with the friendly name and authorization secret to connect to the server agent.", - "infrastructureServerRequirement": "The server you are monitoring must be running the", - "infrastructureCustomizeAlerts": "Customize alerts", - "infrastructureAlertNotificationDescription": "Send a notification to user(s) when thresholds exceed a specified percentage.", - "infrastructureCreateMonitor": "Create Infrastructure Monitor", - "infrastructureProtocol": "Protocol", - "infrastructureServerUrlLabel": "Server URL", - "infrastructureDisplayNameLabel": "Display name", - "infrastructureAuthorizationSecretLabel": "Authorization secret", - "gb": "GB", - "mb": "MB", - "mem": "Mem", - "memoryUsage": "Memory usage", - "cpu": "CPU", - "cpuUsage": "CPU usage", - "cpuTemperature": "CPU Temperature", - "diskUsage": "Disk Usage", - "used": "Used", - "total": "Total", - "cores": "Cores", - "frequency": "Frequency", - "status": "Status", - "cpuPhysical": "CPU (Physical)", - "cpuLogical": "CPU (Logical)", - "cpuFrequency": "CPU Frequency", - "avgCpuTemperature": "Average CPU Temperature", - "memory": "Memory", - "disk": "Disk", - "uptime": "Uptime", - "os": "OS", - "host": "Host", - "actions": "Actions", - "integrations": "Integrations", - "integrationsPrism": "Connect Prism to your favorite service.", - "integrationsSlack": "Slack", - "integrationsSlackInfo": "Connect with Slack and see incidents in a channel", - "integrationsDiscord": "Discord", - "integrationsDiscordInfo": "Connect with Discord and view incidents directly in a channel", - "integrationsZapier": "Zapier", - "integrationsZapierInfo": "Send all incidents to Zapier, and then see them everywhere", - "commonSave": "Save", - "createYour": "Create your", - "createMonitor": "Create monitor", - "pause": "Pause", - "resume": "Resume", - "editing": "Editing...", - "url": "URL", - "access": "Access", - "timezone": "Timezone", - "features": "Features", - "administrator": "Administrator?", - "loginHere": "Login here", - "displayName": "Display name", - "urlMonitor": "URL to monitor", - "portToMonitor": "Port to monitor", - "websiteMonitoring": "Website monitoring", - "websiteMonitoringDescription": "Use HTTP(s) to monitor your website or API endpoint.", - "pingMonitoring": "Ping monitoring", - "pingMonitoringDescription": "Check whether your server is available or not.", - "dockerContainerMonitoring": "Docker container monitoring", - "dockerContainerMonitoringDescription": "Check whether your Docker container is running or not.", - "portMonitoring": "Port monitoring", - "portMonitoringDescription": "Check whether your port is open or not.", - "createMaintenanceWindow": "Create maintenance window", - "createMaintenance": "Create maintenance", - "editMaintenance": "Edit maintenance", - "maintenanceWindowName": "Maintenance Window Name", - "friendlyNameInput": "Friendly name", - "friendlyNamePlaceholder": "Maintenance at __ : __ for ___ minutes", - "maintenanceRepeat": "Maintenance Repeat", - "maintenance": "maintenance", - "duration": "Duration", - "addMonitors": "Add monitors", - "window": "window", - "cancel": "Cancel", - "message": "Message", - "low": "low", - "high": "high", - "statusCode": "Status code", - "date&Time": "Date & Time", - "type": "Type", - "statusPageName": "Status page name", - "publicURL": "Public URL", - "repeat": "Repeat", - "edit": "Edit", - "createA": "Create a", - "remove": "Remove", - "maintenanceWindowDescription": "Your pings won't be sent during this time frame", - "startTime": "Start time", - "timeZoneInfo": "All dates and times are in GMT+0 time zone.", - "monitorsToApply": "Monitors to apply maintenance window to", - "nextWindow": "Next window", - "notFoundButton": "Go to the main dashboard", - "pageSpeedConfigureSettingsDescription": "Here you can select the URL of the host, together with the type of monitor.", - "monitorDisplayName": "Monitor display name", - "whenNewIncident": "When there is a new incident,", - "notifySMS": "Notify via SMS (coming soon)", - "notifyEmails": "Also notify via email to multiple addresses (coming soon)", - "seperateEmails": "You can separate multiple emails with a comma", - "checkFrequency": "Check frequency", - "matchMethod": "Match Method", - "expectedValue": "Expected value", - "deleteDialogTitle": "Do you really want to delete this monitor?", - "deleteDialogDescription": "Once deleted, this monitor cannot be retrieved.", - "pageSpeedMonitor": "PageSpeed monitor", - "shown": "Shown", - "ago": "ago", - "companyName": "Company name", - "pageSpeedDetailsPerformanceReport": "Values are estimated and may vary.", - "pageSpeedDetailsPerformanceReportCalculator": "See calculator", - "checkingEvery": "Checking every", - "statusPageCreateSettings": "If your status page is ready, you can mark it as published.", - "basicInformation": "Basic Information", - "statusPageCreateBasicInfoDescription": "Define company name and the subdomain that your status page points to.", - "statusPageCreateSelectTimeZoneDescription": "Select the timezone that your status page will be displayed in.", - "statusPageCreateAppearanceDescription": "Define the default look and feel of your public status page.", - "statusPageCreateSettingsCheckboxLabel": "Published and visible to the public", - "statusPageCreateBasicInfoStatusPageAddress": "Your status page address", - "statusPageCreateTabsContent": "Status page servers", - "statusPageCreateTabsContentDescription": "You can add any number of servers that you monitor to your status page. You can also reorder them for the best viewing experience.", - "statusPageCreateTabsContentFeaturesDescription": "Show more details on the status page", - "showCharts": "Show charts", - "showUptimePercentage": "Show uptime percentage", - "removeLogo": "Remove Logo", - "statusPageStatus": "A public status page is not set up.", - "statusPageStatusContactAdmin": "Please contact to your administrator", - "statusPageStatusNotPublic": "This status page is not public.", - "statusPageStatusNoPage": "There's no status page here.", - "statusPageStatusServiceStatus": "Service status", - "deleteStatusPage": "Do you want to delete this status page?", - "deleteStatusPageConfirm": "Yes, delete status page", - "deleteStatusPageDescription": "Once deleted, your status page cannot be retrieved.", - "uptimeCreate": "The expected value is used to match against response result, and the match determines the status.", - "uptimeCreateJsonPath": "This expression will be evaluated against the reponse JSON data and the result will be used to match against the expected value. See", - "uptimeCreateJsonPathQuery": "for query language documentation.", - "maintenanceTableActionMenuDialogTitle": "Do you really want to remove this maintenance window?", - "infrastructureEditYour": "Edit your", - "infrastructureEditMonitor": "Save Infrastructure Monitor", - "infrastructureMonitorCreated": "Infrastructure monitor created successfully!", - "infrastructureMonitorUpdated": "Infrastructure monitor updated successfully!", - "errorInvalidTypeId": "Invalid notification type provided", - "errorInvalidFieldId": "Invalid field ID provided", - "inviteNoTokenFound": "No invite token found", - "pageSpeedWarning": "Warning: You haven't added a Google PageSpeed API key. Without it, the PageSpeed monitor won't function.", - "pageSpeedLearnMoreLink": "Click here to learn", - "pageSpeedAddApiKey": "how to add your API key." -} diff --git a/src/locales/tr.json b/src/locales/tr.json deleted file mode 100644 index 1b759a29d..000000000 --- a/src/locales/tr.json +++ /dev/null @@ -1,382 +0,0 @@ -{ - "dontHaveAccount": "Hesabınız yok mu", - "email": "E-posta", - "forgotPassword": "Parolamı unuttum", - "password": "Parola", - "signUp": "Kayıt Ol", - "submit": "Gönder", - "title": "Başlık", - "continue": "Devam Et", - "enterEmail": "E-posta adresinizi girin", - "authLoginTitle": "Giriş Yap", - "authLoginEnterPassword": "Parolanızı girin", - "commonPassword": "Parola", - "commonBack": "Geri", - "authForgotPasswordTitle": "Parolanızı mı unuttunuz?", - "authForgotPasswordResetPassword": "Parola sıfırla", - "createPassword": "Parolanızı oluşturun", - "createAPassword": "Bir parola oluşturun", - "authRegisterAlreadyHaveAccount": "Zaten hesabınız var mı?", - "commonAppName": "Checkmate", - "authLoginEnterEmail": "E-posta adresinizi girin", - "authRegisterTitle": "Hesap oluştur", - "authRegisterStepOneTitle": "Hesabınızı oluşturun", - "authRegisterStepOneDescription": "Başlamak için bilgilerinizi girin", - "authRegisterStepTwoTitle": "Profilinizi ayarlayın", - "authRegisterStepTwoDescription": "Kendiniz hakkında daha fazla bilgi verin", - "authRegisterStepThreeTitle": "Neredeyse bitti!", - "authRegisterStepThreeDescription": "Bilgilerinizi gözden geçirin", - "authForgotPasswordDescription": "Endişelenmeyin, size sıfırlama talimatlarını göndereceğiz.", - "authForgotPasswordSendInstructions": "Talimatları gönder", - "authForgotPasswordBackTo": "Geri dön", - "authCheckEmailTitle": "E-postanızı kontrol edin", - "authCheckEmailDescription": "{{email}} adresine şifre sıfırlama bağlantısı gönderdik", - "authCheckEmailResendEmail": "E-postayı yeniden gönder", - "authCheckEmailBackTo": "Geri dön", - "goBackTo": "Geri dön", - "authCheckEmailDidntReceiveEmail": "E-posta almadınız mı?", - "authCheckEmailClickToResend": "Yeniden göndermek için tıklayın", - "authSetNewPasswordTitle": "Yeni şifre belirle", - "authSetNewPasswordDescription": "Yeni şifreniz daha önce kullanılan şifrelerden farklı olmalıdır.", - "authSetNewPasswordNewPassword": "Yeni şifre", - "authSetNewPasswordConfirmPassword": "Parolayı onayla", - "confirmPassword": "Parolanızı onaylayın", - "authSetNewPasswordResetPassword": "Parola sıfırla", - "authSetNewPasswordBackTo": "Geri dön", - "authPasswordMustBeAtLeast": "En az", - "authPasswordCharactersLong": "8 karakter uzunluğunda olmalı", - "authPasswordMustContainAtLeast": "En az içermeli", - "authPasswordSpecialCharacter": "bir özel karakter", - "authPasswordOneNumber": "bir rakam", - "authPasswordUpperCharacter": "bir büyük harf", - "authPasswordLowerCharacter": "bir küçük harf", - "authPasswordConfirmAndPassword": "Onay şifresi ve şifre", - "authPasswordMustMatch": "eşleşmelidir", - "authRegisterCreateAccount": "Hesap oluşturmak için devam et", - "authRegisterCreateSuperAdminAccount": "Super admin hesabınızı oluşturmak için devam edin", - "authRegisterSignUpWithEmail": "E-posta ile kayıt ol", - "authRegisterBySigningUp": "Kayıt olarak, aşağıdaki şartları kabul ediyorsunuz:", - "distributedStatusHeaderText": "Gerçek zamanlı, Gerçek cihazlar kapsamı", - "distributedStatusSubHeaderText": "Dünya çapında milyonlarca cihaz tarafından desteklenen sistem performansını küresel bölgeye, ülkeye veya şehre göre görüntüleyin", - "settingsGeneralSettings": "Genel ayarlar", - "settingsDisplayTimezone": "Görüntüleme saat dilimi", - "settingsDisplayTimezoneDescription": "Herkese açık olarak görüntülediğiniz kontrol panelinin saat dilimi.", - "settingsAppearance": "Görünüm", - "settingsAppearanceDescription": "Açık ve koyu mod arasında geçiş yapın veya kullanıcı arayüzü dilini değiştirin", - "settingsThemeMode": "Tema", - "settingsLanguage": "Dil", - "settingsDistributedUptime": "Dağıtılmış çalışma süresi", - "settingsDistributedUptimeDescription": "Dağıtılmış çalışma süresi izlemeyi etkinleştirin/devre dışı bırakın.", - "settingsEnabled": "Etkin", - "settingsDisabled": "Devre dışı", - "settingsHistoryAndMonitoring": "Geçmiş ve izleme", - "settingsHistoryAndMonitoringDescription": "Verileri ne kadar süreyle saklamak istediğinizi burada tanımlayın. Ayrıca tüm geçmiş verileri kaldırabilirsiniz.", - "settingsTTLLabel": "İzleme geçmişini saklamak istediğiniz gün sayısı.", - "settingsTTLOptionalLabel": "Sınırsız için 0", - "settingsClearAllStats": "Tüm istatistikleri temizle. Bu geri alınamaz.", - "settingsClearAllStatsButton": "Tüm istatistikleri temizle", - "settingsClearAllStatsDialogTitle": "Tüm istatistikleri temizlemek istiyor musunuz?", - "settingsClearAllStatsDialogDescription": "Silindikten sonra, monitörleriniz geri alınamaz.", - "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", - "settingsDemoMonitors": "Demo monitörler", - "settingsDemoMonitorsDescription": "Burada demo monitörler ekleyebilir ve kaldırabilirsiniz.", - "settingsAddDemoMonitors": "Demo monitörler ekle", - "settingsAddDemoMonitorsButton": "Demo monitörler ekle", - "settingsRemoveAllMonitors": "Tüm monitörleri kaldır", - "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", - "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", - "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri temizle", - "settingsWallet": "Cüzdan", - "settingsWalletDescription": "Cüzdanınızı buradan bağlayın. Bu, Dağıtılmış Çalışma Süresi monitörünün küresel olarak birden çok düğüme bağlanması için gereklidir.", - "settingsAbout": "Hakkında", - "settingsDevelopedBy": "Bluewave Labs tarafından geliştirilmiştir.", - "settingsSave": "Kaydet", - "settingsSuccessSaved": "Ayarlar başarıyla kaydedildi", - "settingsFailedToSave": "Ayarlar kaydedilemedi", - "settingsStatsCleared": "İstatistikler başarıyla temizlendi", - "settingsFailedToClearStats": "İstatistikler temizlenemedi", - "settingsDemoMonitorsAdded": "Demo monitörler başarıyla eklendi", - "settingsFailedToAddDemoMonitors": "Demo monitörler eklenemedi", - "settingsMonitorsDeleted": "Tüm monitörler başarıyla silindi", - "settingsFailedToDeleteMonitors": "Monitörler silinemedi", - "starPromptTitle": "Checkmate yıldızla değerlendirin", - "starPromptDescription": "En son sürümleri görün ve GitHub'daki topluluğun büyümesine yardımcı olun", - "https": "HTTPS", - "http": "HTTP", - "monitor": "monitör", - "aboutus": "Hakkımızda", - "signUP": "Hesap Oluştur", - "now": "Şimdi", - "delete": "Sil", - "configure": "Yapılandır", - "networkError": "Ağ hatası", - "responseTime": "Yanıt süresi:", - "ms": "ms", - "bar": "Çubuk", - "area": "Alan", - "country": "ÜLKE", - "city": "ŞEHİR", - "response": "YANIT", - "checkConnection": "Lütfen bağlantınızı kontrol edin", - "passwordreset": "Parola Sıfırlama", - "authRegisterStepOnePersonalDetails": "Kişisel bilgilerinizi girin", - "authCheckEmailOpenEmailButton": "Eposta uygulamasını aç", - "authNewPasswordConfirmed": "Parolanız başarıyla sıfırlandı. Otomatik olarak giriş yapmak için aşağıya tıklayın.", - "monitorStatusUp": "Monitör {name} ({url}) ayakta ve yanıt veriyor", - "monitorStatusDown": "Monitör {name} ({url}) yanıt vermiyor", - "webhookSendSuccess": "Web kanca bildirimi başarıyla gönderildi", - "webhookSendError": "Web kanca bildirimi bu platforma gönderilemedi: {platform}", - "webhookUnsupportedPlatform": "Desteklenmeyen platform: {platform}", - "distributedRightCategoryTitle": "Monitör", - "distributedStatusServerMonitors": "Sunucu monitörleri", - "distributedStatusServerMonitorsDescription": "İlgili sunucuların monitör durumları", - "distributedUptimeCreateSelectURL": "Burada sunucu adresini (URL) ve monitör türünü girebilirsiniz.", - "distributedUptimeCreateChecks": "Yapılacak kontroller", - "distributedUptimeCreateChecksDescription": "Adresi girdikten sonra kontrol ekleyebilir ya da çıkartabilirsiniz.", - "distributedUptimeCreateIncidentNotification": "Olay bildirimleri", - "distributedUptimeCreateIncidentDescription": "Bir olay olduğunda kullanıcıları bilgilendir.", - "distributedUptimeCreateAdvancedSettings": "Gelişmiş ayarlar", - "distributedUptimeDetailsNoMonitorHistory": "Bu monitör için henüz bir denetim günlüğü oluşturulmadı.", - "distributedUptimeDetailsFooterHeading": "UpRock & Bluewave Labs tarafından geliştirildi", - "distributedUptimeDetailsFooterBuilt": "Altyapı", - "distributedUptimeDetailsFooterSolana": "Solana", - "distributedUptimeDetailsMonitorHeader": "Depin Destekli Dağıtık Kesintisizlik İzleme", - "distributedUptimeDetailsStatusHeaderUptime": "Erişilebilirlik", - "distributedUptimeDetailsStatusHeaderLastUpdate": "Son güncelleme", - "notifications": { - "enableNotifications": "{{platform}} bildirimlerini etkinleştir", - "testNotification": "Bildirimi test et", - "addOrEditNotifications": "Bildirimleri ekle ya da düzenle", - "slack": { - "label": "Slack", - "description": "Slack bildirimlerini etkinleştirmek için bir Slack uygulaması oluşturun ve gelen web kancalarını etkinleştirin. Daha sonra, webhook URL’sini buraya girmeniz yeterlidir.\n\n\n\n\n\n", - "webhookLabel": "Web kanca URL:", - "webhookPlaceholder": "https://hooks.slack.com/services/...", - "webhookRequired": "" - }, - "discord": { - "label": "Discord", - "description": "Checkmate’ten Discord bildirimleri aracılığıyla bir Discord kanalına veri göndermek için Discord’un gelen web kancaları özelliğini kullanabilirsiniz.\n\n\n\n\n\n\n\n", - "webhookLabel": "Discord web kanca URL", - "webhookPlaceholder": "https://discord.com/api/webhooks/...", - "webhookRequired": "" - }, - "telegram": { - "label": "Telegram", - "description": "Telegram bildirimlerini etkinleştirmek için, Telegram botlarını oluşturup yönetmek için kullanılan resmi bot BotFather ile bir Telegram botu oluşturun. Daha sonra, API jetonunu (token) ve sohbet kimliğini (chat ID) alın ve buraya yazın.", - "tokenLabel": "Bot jetonu (token)", - "tokenPlaceholder": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11", - "chatIdLabel": "Sohbet ID", - "chatIdPlaceholder": "-1001234567890", - "fieldsRequired": "" - }, - "webhook": { - "label": "Web kancaları", - "description": "Olaylar meydana geldiğinde bildirim almak için özel bir web kancası ayarlayabilirsiniz.", - "urlLabel": "Web kanca URL:", - "urlPlaceholder": "https://sunucu-adresiniz.com/webhook", - "urlRequired": "" - }, - "testNotificationDevelop": "Test bildirimi 2", - "integrationButton": "Bildirim Entegrasyonu", - "testSuccess": "", - "testFailed": "", - "unsupportedType": "", - "networkError": "" - }, - "testLocale": "TEST13 UPLOAD", - "add": "Ekle", - "monitors": "Monitörler", - "distributedUptimeStatusCreateStatusPage": "durum sayfası", - "distributedUptimeStatusCreateStatusPageAccess": "Erişim", - "distributedUptimeStatusCreateStatusPageReady": "Durum sayfanız hazırsa yayınlayabilirsiniz.", - "distributedUptimeStatusBasicInfoHeader": "Temel bilgiler", - "distributedUptimeStatusBasicInfoDescription": "", - "distributedUptimeStatusLogoHeader": "Logo", - "distributedUptimeStatusLogoDescription": "Durum sayfanız için bir logo yükleyin", - "distributedUptimeStatusLogoUploadButton": "Logo yükle", - "distributedUptimeStatusStandardMonitorsHeader": "Standart monitörler", - "distributedUptimeStatusStandardMonitorsDescription": "Durum sayfanıza standart monitörleri ekleyin.", - "distributedUptimeStatusCreateYour": "", - "distributedUptimeStatusEditYour": "", - "distributedUptimeStatusPublishedLabel": "Yayında ve herkes tarafından görülebilir", - "distributedUptimeStatusCompanyNameLabel": "Şirket adı", - "distributedUptimeStatusPageAddressLabel": "Durum sayfası adresi", - "distributedUptimeStatus30Days": "30 gün", - "distributedUptimeStatus60Days": "60 gün", - "distributedUptimeStatus90Days": "90 gün", - "distributedUptimeStatusPageNotSetUp": "Henüz bir durum sayfası oluşturulmadı.", - "distributedUptimeStatusContactAdmin": "Lütfen yöneticiniz ile görüşün", - "distributedUptimeStatusPageNotPublic": "Bu durum sayfası herkese açık değil", - "distributedUptimeStatusPageDeleteDialog": "Bu durum sayfasını silmek istiyor musunuz? ", - "distributedUptimeStatusPageDeleteConfirm": "Evet, durum sayfasını sil", - "distributedUptimeStatusPageDeleteDescription": "Silindiği zaman durum sayfalarını geri getiremezsiniz.", - "distributedUptimeStatusDevices": "Cihazlar", - "distributedUptimeStatusUpt": "UPT", - "distributedUptimeStatusUptBurned": "Yakılan UPT", - "distributedUptimeStatusUptLogo": "Upt Logo", - "incidentsTableNoIncidents": "Hiç olay kaydedilmedi", - "incidentsTablePaginationLabel": "olaylar", - "incidentsTableMonitorName": "Monitör adı", - "incidentsTableStatus": "Durum", - "incidentsTableDateTime": "Tarih ve saat", - "incidentsTableStatusCode": "Durum kodu", - "incidentsTableMessage": "Mesaj", - "incidentsOptionsHeader": "Servisler:", - "incidentsOptionsHeaderFilterBy": "Filtrele:", - "incidentsOptionsHeaderFilterAll": "Tümü", - "incidentsOptionsHeaderFilterDown": "Erişilemiyor", - "incidentsOptionsHeaderFilterCannotResolve": "Çözümlenemiyor", - "incidentsOptionsHeaderShow": "Göster:", - "incidentsOptionsHeaderLastHour": "Son saat", - "incidentsOptionsHeaderLastDay": "Son gün", - "incidentsOptionsHeaderLastWeek": "Son hafta", - "incidentsOptionsPlaceholderAllServers": "Tüm sunucular", - "infrastructureCreateYour": "", - "infrastructureCreateGeneralSettingsDescription": "", - "infrastructureServerRequirement": "", - "infrastructureCustomizeAlerts": "Alarmları özelleştir", - "infrastructureAlertNotificationDescription": "", - "infrastructureCreateMonitor": "Altyapı Monitörü oluştur", - "infrastructureProtocol": "Protokol", - "infrastructureServerUrlLabel": "Sunucu adresi", - "infrastructureDisplayNameLabel": "Görünen adı", - "infrastructureAuthorizationSecretLabel": "Kimlik denetimi parolası", - "gb": "GB", - "mb": "MB", - "mem": "Bellek", - "memoryUsage": "Bellek kullanımı", - "cpu": "CPU", - "cpuUsage": "CPU kullanımı", - "cpuTemperature": "CPU sıcaklığı", - "diskUsage": "Disk kullanımı", - "used": "Kullanılan", - "total": "Toplam", - "cores": "Çekirdek", - "frequency": "Frekans", - "status": "Durum", - "cpuPhysical": "CPU (fiziksel)", - "cpuLogical": "CPU (Mantıksal)", - "cpuFrequency": "CPU Frekansı", - "avgCpuTemperature": "Ortalama CPU Isısı", - "memory": "Bellek", - "disk": "Disk", - "uptime": "", - "os": "İşletim sistemi", - "host": "Makine", - "actions": "İşlemler", - "integrations": "Entegrasyonlar", - "integrationsPrism": "Prism'i favori servisinize bağlayın.", - "integrationsSlack": "Slack", - "integrationsSlackInfo": "", - "integrationsDiscord": "Discord", - "integrationsDiscordInfo": "", - "integrationsZapier": "Zapier", - "integrationsZapierInfo": "", - "commonSave": "Kaydet", - "createYour": "", - "createMonitor": "Monitör oluştur", - "pause": "Beklet", - "resume": "Yeniden başlat", - "editing": "Düzenleniyor...", - "url": "URL", - "access": "Erişim", - "timezone": "Zaman dilimi", - "features": "Özellikler", - "administrator": "Yönetici misin?", - "loginHere": "Buradan giriş yap", - "displayName": "Görüntülenecek isim", - "urlMonitor": "Monitör edilecek URL", - "portToMonitor": "Monitör edilecek port", - "websiteMonitoring": "Web sitesi monitörü", - "websiteMonitoringDescription": "", - "pingMonitoring": "Ping monitörü", - "pingMonitoringDescription": "Sitenizin ayakta olup olmadığını denetleyin.", - "dockerContainerMonitoring": "Docker konteyner monitörü", - "dockerContainerMonitoringDescription": "Docker konteynerinizin ayakta olup olmadığını denetleyin.", - "portMonitoring": "Port monitörü", - "portMonitoringDescription": "Portunuzun açık olup olmadığını denetleyin.", - "createMaintenanceWindow": "Bakım aralığı oluşturun", - "createMaintenance": "Bakım oluştur", - "editMaintenance": "Bakımı düzenle", - "maintenanceWindowName": "Bakım aralığı adı", - "friendlyNameInput": "Görünen ad", - "friendlyNamePlaceholder": "__:__ saatinde __ dakika boyunca bakım var", - "maintenanceRepeat": "Bakım Tekrarı", - "maintenance": "bakım", - "duration": "Süre", - "addMonitors": "Monitör ekle", - "window": "pencere", - "cancel": "İptal", - "message": "Mesaj", - "low": "düşük", - "high": "yüksek", - "statusCode": "Durum kodu", - "date&Time": "", - "type": "", - "statusPageName": "", - "publicURL": "", - "repeat": "", - "edit": "", - "createA": "", - "remove": "", - "maintenanceWindowDescription": "", - "startTime": "Başlangıç saati", - "timeZoneInfo": "", - "monitorsToApply": "", - "nextWindow": "Sonraki pencere", - "notFoundButton": "", - "pageSpeedConfigureSettingsDescription": "", - "monitorDisplayName": "", - "whenNewIncident": "Yeni bir olay oluştuğunda,", - "notifySMS": "", - "notifyEmails": "", - "seperateEmails": "", - "checkFrequency": "Frekansı denetle", - "matchMethod": "", - "expectedValue": "Beklenen değer", - "deleteDialogTitle": "Gerçekten bu monitörü silmek istiyor musunuz?", - "deleteDialogDescription": "Bir kez silindiği zaman tekrar getiremezsiniz.", - "pageSpeedMonitor": "Sayfa Hızı Monitörü", - "shown": "", - "ago": "", - "companyName": "Firma adı", - "pageSpeedDetailsPerformanceReport": "", - "pageSpeedDetailsPerformanceReportCalculator": "Hesap makinesini gör", - "checkingEvery": "Denetleme sıklığı", - "statusPageCreateSettings": "Eğer durum sayfanız hazırsa, herkese açık yayınlayabilirsiniz", - "basicInformation": "Temel Bilgiler", - "statusPageCreateBasicInfoDescription": "", - "statusPageCreateSelectTimeZoneDescription": "", - "statusPageCreateAppearanceDescription": "", - "statusPageCreateSettingsCheckboxLabel": "Yayınlandı ve herkese açık", - "statusPageCreateBasicInfoStatusPageAddress": "Durum sayfası adresiniz", - "statusPageCreateTabsContent": "Durum sayfası sunucuları", - "statusPageCreateTabsContentDescription": "", - "statusPageCreateTabsContentFeaturesDescription": "Durum sayfasında daha fazla bilgi göster", - "showCharts": "Çizelgeleri göster", - "showUptimePercentage": "", - "removeLogo": "Logoyu sil", - "statusPageStatus": "Herkese açık bir durum sayfası henüz oluşturulmadı.", - "statusPageStatusContactAdmin": "Lütfen yöneticinizle iletişime geçin.", - "statusPageStatusNotPublic": "Durum sayfası herkese açık değil.", - "statusPageStatusNoPage": "Burada bir durum sayfası bulunmuyor.", - "statusPageStatusServiceStatus": "Servis durumu", - "deleteStatusPage": "Gerçekten bu durum sayfasını silmek istiyor musunuz?", - "deleteStatusPageConfirm": "Evet, durum sayfasını sil", - "deleteStatusPageDescription": "Silindikten sonra durum sayfasını geri getiremezsiniz.", - "uptimeCreate": "", - "uptimeCreateJsonPath": "", - "uptimeCreateJsonPathQuery": "", - "maintenanceTableActionMenuDialogTitle": "Gerçekten bu bakım aralığını silmek istiyor musunuz?", - "infrastructureEditYour": "", - "infrastructureEditMonitor": "", - "infrastructureMonitorCreated": "", - "infrastructureMonitorUpdated": "", - "errorInvalidTypeId": "", - "errorInvalidFieldId": "", - "inviteNoTokenFound": "", - "pageSpeedWarning": "", - "pageSpeedLearnMoreLink": "", - "pageSpeedAddApiKey": "" -} From 389eb00d5d1b6655287d75d6d0aa45f688a4d3e3 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 22 Apr 2025 22:59:00 +0000 Subject: [PATCH 010/147] feat: translations updated from POEditor --- client/src/locales/gb.json | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index f3eec29fd..343386bec 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -131,7 +131,6 @@ "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.", - "uptimeCreateSelectURL": "Here you can select the host address/container ID, together with the display name.", "distributedUptimeCreateChecks": "Checks to perform", "distributedUptimeCreateChecksDescription": "You can always add or remove checks after adding your site.", "distributedUptimeCreateIncidentNotification": "Incident notifications", From 4f5a855083d44fcd3875431a33f52b1e45955ce5 Mon Sep 17 00:00:00 2001 From: Vishnu Sreekumaran Nair <200557136@student.georgianc.on.ca> Date: Tue, 22 Apr 2025 19:33:15 -0400 Subject: [PATCH 011/147] create new imgupload folder and copy code --- .../Components/Inputs/ImageUpload/index.jsx | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 client/src/Components/Inputs/ImageUpload/index.jsx diff --git a/client/src/Components/Inputs/ImageUpload/index.jsx b/client/src/Components/Inputs/ImageUpload/index.jsx new file mode 100644 index 000000000..a49dc4860 --- /dev/null +++ b/client/src/Components/Inputs/ImageUpload/index.jsx @@ -0,0 +1,243 @@ +// Components +import { Box, Stack, Typography } from "@mui/material"; +import CloudUploadIcon from "@mui/icons-material/CloudUpload"; +import Image from "../../../Components/Image"; +import TextField from "@mui/material/TextField"; +import IconButton from "@mui/material/IconButton"; +import ProgressUpload from "../../ProgressBars"; +import ImageIcon from "@mui/icons-material/Image"; + +// Utils +import PropTypes from "prop-types"; +import { useCallback, useState, useRef, useEffect } from "react"; +import { useTheme } from "@emotion/react"; +import { useTranslation } from "react-i18next"; + +/** + * ImageUpload component allows users to upload images with drag-and-drop functionality. + * It supports file size and format validation. + * + * @component + * @param {Object} props - Component props + * @param {boolean} [props.previewIsRound=false] - Determines if the image preview should be round + * @param {string} [props.src] - Source URL of the image to display + * @param {function} props.onChange - Callback function to handle file change, takes a file as an argument + * @param {number} [props.maxSize=3145728] - Maximum file size allowed in bytes (default is 3MB) + * @param {Array} [props.accept=['jpg', 'jpeg', 'png']] - Array of accepted file formats + * @param {Object} [props.errors] - Object containing error messages + * @returns {JSX.Element} The rendered component + */ +const ImageUpload = ({ + previewIsRound = false, + src, + onChange, + maxSize = 3 * 1024 * 1024, + accept = ["jpg", "jpeg", "png"], + error, +}) => { + const theme = useTheme(); + const { t } = useTranslation(); + const [uploadComplete, setUploadComplete] = useState(false); + const [completedFile, setCompletedFile] = useState(null); + const [file, setFile] = useState(null); + const [progress, setProgress] = useState({ value: 0, isLoading: false }); + const intervalRef = useRef(null); + const [localError, setLocalError] = useState(null); + const [isDragging, setIsDragging] = useState(false); + + const roundStyle = previewIsRound ? { borderRadius: "50%" } : {}; + + const handleImageChange = useCallback( + (file) => { + if (!file) return; + + const isValidType = accept.some((type) => + file.type.includes(type) + ); + const isValidSize = file.size <= maxSize; + + if (!isValidType) { + setLocalError(t('invalidFileFormat')); + return; + } + if (!isValidSize) { + setLocalError(t('invalidFileSize')); + return; + } + + setLocalError(null); + + const previewFile = { + src: URL.createObjectURL(file), + name: file.name, + file, + }; + + setFile(previewFile); + setProgress({ value: 0, isLoading: true }); + + intervalRef.current = setInterval(() => { + setProgress((prev) => { + const buffer = 12; + if (prev.value + buffer >= 100) { + clearInterval(intervalRef.current); + setUploadComplete(true); + setCompletedFile(previewFile); + return { value: 100, isLoading: false }; + } + return { value: prev.value + buffer, isLoading: true }; + }); + }, 120); + }, + [maxSize, accept] + ); + + useEffect(() => { + if (uploadComplete && completedFile) { + onChange?.(completedFile); + setUploadComplete(false); + setCompletedFile(null); + } + }, [uploadComplete, completedFile, onChange]); + + + return ( + <> + {src ? ( + + Uploaded preview + + ) : ( + <> + setIsDragging(true)} + onDragLeave={() => setIsDragging(false)} + onDrop={() => setIsDragging(false)} + sx={{ + position: "relative", + height: "fit-content", + border: "dashed", + borderRadius: theme.shape.borderRadius, + borderColor: isDragging + ? theme.palette.primary.main + : theme.palette.primary.lowContrast, + backgroundColor: isDragging + ? "hsl(215, 87%, 51%, 0.05)" + : "transparent", + borderWidth: "2px", + transition: "0.2s", + "&:hover": { + borderColor: theme.palette.primary.main, + backgroundColor: "hsl(215, 87%, 51%, 0.05)", + }, + }} + > + handleImageChange(e?.target?.files?.[0])} + sx={{ + width: "100%", + "& .MuiInputBase-input[type='file']": { + opacity: 0, + cursor: "pointer", + maxWidth: "500px", + minHeight: "175px", + zIndex: 1, + }, + "& fieldset": { + padding: 0, + border: "none", + }, + }} + /> + + + + + + + {t('ClickUpload')} + {" "} + or {t('DragandDrop')} + + ({t('MaxSize')}: {Math.round(maxSize / 1024 / 1024)}MB) + + + + {(localError || progress.isLoading || progress.value !== 0) && ( + } + label={file?.name || "Upload failed"} + size={file?.size} + progress={progress.value} + onClick={() => { + clearInterval(intervalRef.current); + setFile(null); + setProgress({ value: 0, isLoading: false }); + setLocalError(null); + onChange(undefined); + }} + error={localError || error} + /> + )} + + {t('SupportedFormats')}: {accept.join(", ").toUpperCase()} + + + )} + + ); +}; + +ImageUpload.propTypes = { + previewIsRound: PropTypes.bool, + src: PropTypes.string, + onChange: PropTypes.func, + maxSize: PropTypes.number, + accept: PropTypes.array, + error: PropTypes.string, +}; + +export default ImageUpload; \ No newline at end of file From 6be71e43372d2146b4c24ceb9d20403184a5ab7f Mon Sep 17 00:00:00 2001 From: Vishnu Sreekumaran Nair <200557136@student.georgianc.on.ca> Date: Tue, 22 Apr 2025 19:34:17 -0400 Subject: [PATCH 012/147] update profilepanel to use imageupload component --- .../TabPanels/Account/ProfilePanel.jsx | 176 +++++++----------- 1 file changed, 67 insertions(+), 109 deletions(-) diff --git a/client/src/Components/TabPanels/Account/ProfilePanel.jsx b/client/src/Components/TabPanels/Account/ProfilePanel.jsx index 7cf123667..aa6c11f3c 100644 --- a/client/src/Components/TabPanels/Account/ProfilePanel.jsx +++ b/client/src/Components/TabPanels/Account/ProfilePanel.jsx @@ -1,21 +1,19 @@ import { useTheme } from "@emotion/react"; -import { useRef, useState } from "react"; +import { useState } from "react"; import TabPanel from "@mui/lab/TabPanel"; import { Box, Button, Divider, Stack, Typography } from "@mui/material"; import Avatar from "../../Avatar"; import TextInput from "../../Inputs/TextInput"; -import ImageField from "../../Inputs/Image"; -import { credentials, imageValidation } from "../../../Validation/validation"; +import ImageUpload from "../../Inputs/ImageUpload"; +import { credentials } from "../../../Validation/validation"; import { useDispatch, useSelector } from "react-redux"; import { clearAuthState, deleteUser, update } from "../../../Features/Auth/authSlice"; -import ImageIcon from "@mui/icons-material/Image"; -import ProgressUpload from "../../ProgressBars"; -import { formatBytes } from "../../../Utils/fileUtils"; import { clearUptimeMonitorState } from "../../../Features/UptimeMonitors/uptimeMonitorsSlice"; import { createToast } from "../../../Utils/toastUtils"; import { logger } from "../../../Utils/Logger"; import { GenericDialog } from "../../Dialog/genericDialog"; import Dialog from "../../Dialog"; +import { useTranslation } from "react-i18next"; /** * ProfilePanel component displays a form for editing user profile information @@ -28,7 +26,7 @@ import Dialog from "../../Dialog"; const ProfilePanel = () => { const theme = useTheme(); const dispatch = useDispatch(); - + const { t } = useTranslation(); const SPACING_GAP = theme.spacing(12); //redux state @@ -49,8 +47,6 @@ const ProfilePanel = () => { }); const [errors, setErrors] = useState({}); const [file, setFile] = useState(); - const intervalRef = useRef(null); - const [progress, setProgress] = useState({ value: 0, isLoading: false }); // Handles input field changes and performs validation const handleChange = (event) => { @@ -65,33 +61,6 @@ const ProfilePanel = () => { validateField({ [name]: value }, credentials, name); }; - // Handles image file - const handlePicture = (event) => { - const pic = event.target.files[0]; - let error = validateField({ type: pic.type, size: pic.size }, imageValidation); - if (error) return; - - setProgress((prev) => ({ ...prev, isLoading: true })); - setFile({ - src: URL.createObjectURL(pic), - name: pic.name, - size: formatBytes(pic.size), - delete: false, - }); - - //TODO - potentitally remove, will revisit in the future - intervalRef.current = setInterval(() => { - const buffer = 12; - setProgress((prev) => { - if (prev.value + buffer >= 100) { - clearInterval(intervalRef.current); - return { value: 100, isLoading: false }; - } - return { ...prev, value: prev.value + buffer }; - }); - }, 120); - }; - // Validates input against provided schema and updates error state const validateField = (toValidate, schema, name = "picture") => { const { error } = schema.validate(toValidate, { abortEarly: false }); @@ -116,52 +85,55 @@ const ProfilePanel = () => { // Resets picture-related states and clears interval const removePicture = () => { errors["picture"] && clearError("picture"); - setFile({ delete: true }); - clearInterval(intervalRef.current); // interrupt interval if image upload is canceled prior to completing the process - setProgress({ value: 0, isLoading: false }); - }; + setFile(undefined); + setLocalData((prev) => ({ + ...prev, + file: undefined, + deleteProfileImage: true, + })); + }; // Opens the picture update modal const openPictureModal = () => { setIsOpen("picture"); - setFile({ delete: localData.deleteProfileImage }); + setFile(undefined); }; // Closes the picture update modal and resets related states const closePictureModal = () => { - errors["picture"] && clearError("picture"); - setFile(); //reset file - clearInterval(intervalRef.current); // interrupt interval if image upload is canceled prior to completing the process - setProgress({ value: 0, isLoading: false }); - setIsOpen(""); - }; + if (errors["picture"]) clearError("picture"); + setFile(undefined); + setIsOpen(""); + }; // Updates profile image displayed on UI const handleUpdatePicture = () => { - setProgress({ value: 0, isLoading: false }); setLocalData((prev) => ({ ...prev, - file: file.src, + file: file?.src, deleteProfileImage: false, })); setIsOpen(""); - errors["unchanged"] && clearError("unchanged"); + if (errors["unchanged"]) clearError("unchanged"); }; - + // Handles form submission to update user profile const handleSaveProfile = async (event) => { event.preventDefault(); - if ( - localData.firstName === user.firstName && - localData.lastName === user.lastName && - localData.deleteProfileImage === undefined && - localData.file === undefined - ) { - createToast({ - body: "Unable to update profile — no changes detected.", - }); - setErrors({ unchanged: "unable to update profile" }); - return; + const nameChanged = + localData.firstName !== user.firstName || + localData.lastName !== user.lastName; + + const avatarChanged = + localData.deleteProfileImage === true || + (localData.file && localData.file !== `data:image/png;base64,${user.avatarImage}`); + + if (!nameChanged && !avatarChanged) { + createToast({ + body: "Unable to update profile — no changes detected.", + }); + setErrors({ unchanged: "unable to update profile" }); + return; } const action = await dispatch(update({ localData })); @@ -182,6 +154,7 @@ const ProfilePanel = () => { ...prev, deleteProfileImage: true, })); + setFile(undefined); errors["unchanged"] && clearError("unchanged"); }; @@ -232,7 +205,7 @@ const ProfilePanel = () => { > {/* This 0.9 is a bit magic numbering, refactor */} - First name + {t('FirstName')} { gap={SPACING_GAP} > - Last name + {t('LastName')} { gap={SPACING_GAP} > - Email + {t('email')} - This is your current email address — it cannot be changed. + {t('EmailDescriptionText')} { gap={SPACING_GAP} > - Your photo + {t('YourPhoto')} - This photo will be displayed in your profile page. + {t('PhotoDescriptionText')} { color="error" onClick={handleDeletePicture} > - Delete + {t('delete')} @@ -352,7 +325,7 @@ const ProfilePanel = () => { disabled={Object.keys(errors).length !== 0 && !errors?.picture && true} sx={{ px: theme.spacing(12) }} > - Save + {t('save')} @@ -371,13 +344,12 @@ const ProfilePanel = () => { spellCheck="false" > - Delete account + {t('DeleteAccount')} - Note that deleting your account will remove all data from the server. This - is permanent and non-recoverable. + {t('DeleteDescriptionText')} )} setIsOpen("")} - confirmationButtonLabel={"Delete account"} + confirmationButtonLabel={t('DeleteAccount')} onConfirm={handleDeleteAccount} isLoading={isLoading} /> @@ -408,34 +378,27 @@ const ProfilePanel = () => { onClose={closePictureModal} theme={theme} > - { + if (newFile) { + setFile(newFile); + clearError("unchanged"); + } + }} + previewIsRound + maxSize={3 * 1024 * 1024} /> - {progress.isLoading || progress.value !== 0 || errors["picture"] ? ( - } - label={file?.name} - size={file?.size} - progress={progress.value} - onClick={removePicture} - error={errors["picture"]} - /> - ) : ( - "" - )} { color="info" onClick={removePicture} > - Remove + {t('remove')} From 5058dd35ac09bd9a7ca92c804d64265d20e595be Mon Sep 17 00:00:00 2001 From: Vishnu Sreekumaran Nair <200557136@student.georgianc.on.ca> Date: Tue, 22 Apr 2025 19:35:55 -0400 Subject: [PATCH 013/147] update status page create to use new component --- .../Pages/StatusPage/Create/Components/Tabs/Settings.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx index 4d197ad56..e3d0a0bc6 100644 --- a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx +++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx @@ -5,7 +5,7 @@ import ConfigBox from "../../../../../Components/ConfigBox"; import Checkbox from "../../../../../Components/Inputs/Checkbox"; import TextInput from "../../../../../Components/Inputs/TextInput"; import Select from "../../../../../Components/Inputs/Select"; -import ImageField from "../../../../../Components/Inputs/Image"; +import ImageUpload from "../../../../../Components/Inputs/ImageUpload"; import ColorPicker from "../../../../../Components/Inputs/ColorPicker"; import Progress from "../Progress"; @@ -106,11 +106,10 @@ const TabSettings = ({ - - {isAdmin && ( + {/* {isAdmin && ( {t("settingsDistributedUptime")} @@ -276,8 +276,8 @@ const Settings = () => { : t("settingsDisabled")} - )} - {isAdmin && ( + )} */} + {/* {isAdmin && ( {t("settingsWallet")} @@ -302,7 +302,7 @@ const Settings = () => { - )} + )} */} {isAdmin && ( diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx index 79c214b2c..f5a1adcae 100644 --- a/client/src/Routes/index.jsx +++ b/client/src/Routes/index.jsx @@ -96,16 +96,16 @@ const Routes = () => { path="/uptime/configure/:monitorId/" element={} /> - {" "} } - /> + /> */} - @@ -120,15 +120,15 @@ const Routes = () => { } - /> - */} + {/* } - /> + /> */} { path="infrastructure/create" element={} /> - } + } /> { element={} /> - } - /> + /> */} } /> - } - /> + /> */} } /> - } - /> + /> */} { path="/status/uptime/public/:url" element={} /> - } - /> + /> */} response, (error) => { + if (error.code === "ERR_NETWORK") { + // Do error handling here + } if (error.response && error.response.status === 401) { dispatch(clearAuthState()); dispatch(clearUptimeMonitorState()); From 1afde4e16d55d3531e40a16bb99a2fe27f00a667 Mon Sep 17 00:00:00 2001 From: "Gorkem Cetin (BWL)" <167266851+gorkem-bwl@users.noreply.github.com> Date: Fri, 2 May 2025 21:56:04 -0400 Subject: [PATCH 096/147] Remove distributed uptime from the release for now --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c0491c44a..a04971a83 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,10 @@ If you have any questions, suggestions or comments, please use our [Discord chan **Short term roadmap:** -- Global (distributed) uptime checking on Solana network (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1593 - 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 -- JSON query monitoring https://github.com/bluewave-labs/Checkmate/issues/1573 +- JSON query monitoring (**in progress**) https://github.com/bluewave-labs/Checkmate/issues/1573 - Tagging/grouping monitors https://github.com/bluewave-labs/Checkmate/issues/1546 - More configuration options - DNS monitoring From 712fd0a56f792cfcba397e279577f914e7e01057 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Sun, 4 May 2025 00:16:08 +0530 Subject: [PATCH 097/147] Fixed the strict evaluation and text of the button. --- client/src/Components/Fallback/index.jsx | 5 ++--- client/src/locales/gb.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/Components/Fallback/index.jsx b/client/src/Components/Fallback/index.jsx index 0ae639ef5..18fecd3dd 100644 --- a/client/src/Components/Fallback/index.jsx +++ b/client/src/Components/Fallback/index.jsx @@ -118,16 +118,15 @@ const Fallback = ({ title, checks, link = "/", isAdmin, vowelStart = false, show > Let's create your first {title} - {/* Bulk create of uptime monitors */} - {title == "uptime monitor" && ( + {title === "uptime monitor" && ( )} diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index 266fbdaad..920d1307b 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -409,6 +409,6 @@ "uploadSuccess": "Monitors created successfully!", "validationFailed": "Validation failed", "noFileSelected": "No file selected", - "fallbackPage": "Click here for bulk" + "fallbackPage": "Import a file to upload a list of servers in bulk" } } From 914e1d68290338d9fae3194696ea605f1f9a5536 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Sun, 4 May 2025 01:39:29 +0530 Subject: [PATCH 098/147] Added notification in configure page as well. Used useEffect to retrive the information if once added. --- .../NotificationIntegrationModal.jsx | 106 +++++++++++++----- client/src/Pages/Uptime/Configure/index.jsx | 29 +++++ 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx index 16ebd130c..67502d9a0 100644 --- a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx +++ b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx @@ -1,4 +1,4 @@ -import { useState, useMemo } from "react"; +import { useState, useMemo, useEffect, useCallback} from "react"; import { useTranslation } from "react-i18next"; import PropTypes from "prop-types"; @@ -11,6 +11,7 @@ import { Box, Tabs, Tab, + Stack, } from "@mui/material"; import { useTheme } from "@emotion/react"; import TabPanel from "./TabPanel"; @@ -48,7 +49,7 @@ const NotificationIntegrationModal = ({ const [loading, _, sendTestNotification] = useNotifications(); // Helper to get the field state key with error handling - const getFieldKey = (typeId, fieldId) => { + const getFieldKey = useCallback((typeId, fieldId) => { if (typeof typeId !== 'string' || typeId === '') { throw new Error(t('errorInvalidTypeId')); } @@ -58,7 +59,7 @@ const NotificationIntegrationModal = ({ } return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`; - }; + }); // Define notification types const DEFAULT_NOTIFICATION_TYPES = [ @@ -128,23 +129,79 @@ const NotificationIntegrationModal = ({ // Memoized function to initialize integrations state const initialIntegrationsState = useMemo(() => { const state = {}; + + activeNotificationTypes.forEach((type) => { + // Add enabled flag for each notification type + state[type.id] = false; + + // Add state for each field in the notification type + type.fields.forEach((field) => { + const fieldKey = getFieldKey(type.id, field.id); + state[fieldKey] = ""; + }); + }); - activeNotificationTypes.forEach(type => { - // Add enabled flag for each notification type - state[type.id] = monitor?.notifications?.some(n => n.type === type.id) || false; - - // Add state for each field in the notification type - type.fields.forEach(field => { - const fieldKey = getFieldKey(type.id, field.id); - state[fieldKey] = monitor?.notifications?.find(n => n.type === type.id)?.[field.id] || ""; - }); - }); - - return state; - }, [monitor, activeNotificationTypes]); // Only recompute when these dependencies change + return state; + }, [activeNotificationTypes, getFieldKey]); // Only recompute when these dependencies change const [integrations, setIntegrations] = useState(initialIntegrationsState); + useEffect(() => { + if (open) { + const extractNotificationValues = () => { + const values = {}; + + if (!monitor?.notifications || !Array.isArray(monitor.notifications)) { + return values; + } + + monitor.notifications.forEach((notification) => { + // Handle notification based on its structure + if (notification.type === "webhook" && notification.platform) { + if (typeof notification.config === "undefined") return; + const platform = notification.platform; + values[platform] = true; // Set platform as enabled + + // Extract configuration based on platform + switch (platform) { + case NOTIFICATION_TYPES.SLACK: + case NOTIFICATION_TYPES.DISCORD: + if (notification.config.webhookUrl) { + values[getFieldKey(platform, FIELD_IDS.WEBHOOK)] = + notification.config.webhookUrl; + } + break; + case NOTIFICATION_TYPES.TELEGRAM: + if (notification.config.botToken) { + values[getFieldKey(platform, FIELD_IDS.TOKEN)] = + notification.config.botToken; + } + if (notification.config.chatId) { + values[getFieldKey(platform, FIELD_IDS.CHAT_ID)] = + notification.config.chatId; + } + break; + case NOTIFICATION_TYPES.WEBHOOK: + if (notification.config.webhookUrl) { + values[getFieldKey(platform, FIELD_IDS.URL)] = + notification.config.webhookUrl; + } + break; + } + } + }); + + return values; + }; + + const extractedValues = extractNotificationValues(); + setIntegrations((prev) => ({ + ...prev, + ...extractedValues, + })); + } + }, [open, monitor, getFieldKey]); + const handleChangeTab = (event, newValue) => { setTabValue(newValue); }; @@ -256,9 +313,10 @@ const handleSave = () => { }} > - {/* Left sidebar with tabs */} { maxWidth: theme.spacing(120), pr: theme.spacing(10) }}> - + {t('notifications.addOrEditNotifications')} @@ -315,7 +367,7 @@ const handleSave = () => { ))} - + { const parsedUrl = parseUrl(monitor?.url); const protocol = parsedUrl?.protocol?.replace(":", "") || ""; + // Notification modal state + const [isNotificationModalOpen, setIsNotificationModalOpen] = useState(false); + + const handleOpenNotificationModal = () => { + setIsNotificationModalOpen(true); + }; + + const handleClosenNotificationModal = () => { + setIsNotificationModalOpen(false); + }; + + const statusColor = { true: theme.palette.success.main, false: theme.palette.error.main, @@ -424,6 +437,15 @@ const Configure = () => { value={user?.email} onChange={(event) => handleChange(event)} /> + + + {/* { onConfirm={handleRemove} isLoading={isLoading} /> + + ); }; From 3df19fc51691d71ebfae3d1df9605a9650baa48f Mon Sep 17 00:00:00 2001 From: Pezhman Parsaee Date: Sun, 4 May 2025 01:21:53 +0200 Subject: [PATCH 099/147] hide certificate expiry box for non-http uptimes --- .../Components/UptimeStatusBoxes/index.jsx | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx index 66c021aa2..ddc7e223b 100644 --- a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx +++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx @@ -61,18 +61,20 @@ const UptimeStatusBoxes = ({ } /> - - {certificateExpiry} - - } - /> + {monitor?.type === "http" && ( + + {certificateExpiry} + + } + /> + )} ); }; From ac2b55f1e0dfdc9655dc142952c809842296f74a Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 4 May 2025 00:34:11 +0000 Subject: [PATCH 100/147] feat: translations updated from POEditor --- client/src/locales/tr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index 568e1fe51..b9990f733 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -408,6 +408,7 @@ "parsingFailed": "", "uploadSuccess": "", "validationFailed": "", - "noFileSelected": "" + "noFileSelected": "", + "fallbackPage": "" } } From f78430f0d7897b1029d1996d9d3c37199ef13300 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Sun, 4 May 2025 12:51:36 +0530 Subject: [PATCH 101/147] Added flex end instead of space between as mentioned in #2178 --- client/src/Components/MonitorTimeFrameHeader/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Components/MonitorTimeFrameHeader/index.jsx b/client/src/Components/MonitorTimeFrameHeader/index.jsx index 97f113897..1b93f3447 100644 --- a/client/src/Components/MonitorTimeFrameHeader/index.jsx +++ b/client/src/Components/MonitorTimeFrameHeader/index.jsx @@ -55,7 +55,7 @@ const MonitorTimeFrameHeader = ({ return ( Date: Sun, 4 May 2025 11:34:36 +0200 Subject: [PATCH 102/147] defined a constant for the type of monitors --- .../Uptime/Details/Components/UptimeStatusBoxes/index.jsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx index ddc7e223b..80e1d2072 100644 --- a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx +++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx @@ -7,6 +7,13 @@ import { useTheme } from "@mui/material/styles"; import { Typography } from "@mui/material"; import useUtils from "../../../Monitors/Hooks/useUtils"; +const MONITOR_TYPES = { + WEB: ["http", "https"], + PING: ["ping"], + DOCKER: ["docker"], + PORT: ["port"], +}; + const UptimeStatusBoxes = ({ isLoading = false, monitor, From d68c8e523d80b69af203d4f7c7fc740c2c041858 Mon Sep 17 00:00:00 2001 From: Pezhman Parsaee Date: Sun, 4 May 2025 11:35:48 +0200 Subject: [PATCH 103/147] changed conditional rendering to hide certificate expiry box for non http uptimes --- .../Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx index 80e1d2072..9391256c5 100644 --- a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx +++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx @@ -68,7 +68,7 @@ const UptimeStatusBoxes = ({ } /> - {monitor?.type === "http" && ( + {MONITOR_TYPES.WEB.includes(monitor?.type) && ( Date: Sun, 4 May 2025 20:23:59 -0700 Subject: [PATCH 104/147] Added Public Link Button on Status Page if published --- .../Components/ControlsHeader/index.jsx | 26 +++++++++++++++++++ client/src/Pages/StatusPage/Status/index.jsx | 1 + client/src/locales/gb.json | 3 ++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx index a9872e99f..d45c977a1 100644 --- a/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx +++ b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx @@ -3,6 +3,7 @@ import { Box, Stack, Typography, Button } from "@mui/material"; import Image from "../../../../../Components/Image"; import SettingsIcon from "../../../../../assets/icons/settings-bold.svg?react"; import ThemeSwitch from "../../../../../Components/ThemeSwitch"; +import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward"; //Utils import { useTheme } from "@mui/material/styles"; import { useNavigate } from "react-router-dom"; @@ -86,6 +87,11 @@ const ControlsHeader = ({ type = "uptime", }) => { const theme = useTheme(); + const { t } = useTranslation(); + const publicUrl = + type === "uptime" + ? `/status/uptime/public/${url}` + : `/status/distributed/public/${url}`; return ( {statusPage?.companyName} + {statusPage?.isPublished && !isPublic && ( + { + window.open(publicUrl, "_blank", "noopener,noreferrer"); + }} + sx={{ + display: "inline-flex", + ":hover": { + cursor: "pointer", + borderBottom: 1, + }, + }} + > + {t("publicLink")} + + + )} { isDeleteOpen={isDeleteOpen} setIsDeleteOpen={setIsDeleteOpen} url={url} + isPublic={isPublic} /> {t("statusPageStatusServiceStatus")} diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index 9deaa9e48..930804cfa 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -410,5 +410,6 @@ "validationFailed": "Validation failed", "noFileSelected": "No file selected", "fallbackPage": "Import a file to upload a list of servers in bulk" - } + }, + "publicLink": "Public Link" } From 33b07fe3692fc53a3c7e748fc6866063acf72548 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Mon, 5 May 2025 09:27:03 +0530 Subject: [PATCH 105/147] Aligned the text in middle of the buttons and also removed the bottom margin. --- client/src/Components/MonitorTimeFrameHeader/index.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/Components/MonitorTimeFrameHeader/index.jsx b/client/src/Components/MonitorTimeFrameHeader/index.jsx index 1b93f3447..3958d507c 100644 --- a/client/src/Components/MonitorTimeFrameHeader/index.jsx +++ b/client/src/Components/MonitorTimeFrameHeader/index.jsx @@ -56,9 +56,8 @@ const MonitorTimeFrameHeader = ({ Showing statistics for past{" "} From c9fe0ced3774c6936c4322a602cb09c6eda16812 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Sun, 4 May 2025 22:26:06 -0700 Subject: [PATCH 106/147] fix missing dependency array --- .../NotificationIntegrationModal.jsx | 624 +++++++++--------- 1 file changed, 319 insertions(+), 305 deletions(-) diff --git a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx index 67502d9a0..dc94ee731 100644 --- a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx +++ b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx @@ -1,17 +1,17 @@ -import { useState, useMemo, useEffect, useCallback} from "react"; +import { useState, useMemo, useEffect, useCallback } from "react"; import { useTranslation } from "react-i18next"; import PropTypes from "prop-types"; -import { - Dialog, - DialogContent, - DialogActions, - Button, - Typography, - Box, - Tabs, - Tab, - Stack, +import { + Dialog, + DialogContent, + DialogActions, + Button, + Typography, + Box, + Tabs, + Tab, + Stack, } from "@mui/material"; import { useTheme } from "@emotion/react"; import TabPanel from "./TabPanel"; @@ -20,115 +20,118 @@ import useNotifications from "../Hooks/useNotification"; // Define constants for notification types to avoid magic values const NOTIFICATION_TYPES = { - SLACK: 'slack', - DISCORD: 'discord', - TELEGRAM: 'telegram', - WEBHOOK: 'webhook' + SLACK: "slack", + DISCORD: "discord", + TELEGRAM: "telegram", + WEBHOOK: "webhook", }; // Define constants for field IDs const FIELD_IDS = { - WEBHOOK: 'webhook', - TOKEN: 'token', - CHAT_ID: 'chatId', - URL: 'url' + WEBHOOK: "webhook", + TOKEN: "token", + CHAT_ID: "chatId", + URL: "url", }; -const NotificationIntegrationModal = ({ - open, - onClose, - monitor, - setMonitor, - // Optional prop to configure available notification types - notificationTypes = null +const NotificationIntegrationModal = ({ + open, + onClose, + monitor, + setMonitor, + // Optional prop to configure available notification types + notificationTypes = null, }) => { - const { t } = useTranslation(); - const theme = useTheme(); - const [tabValue, setTabValue] = useState(0); - - const [loading, _, sendTestNotification] = useNotifications(); - - // Helper to get the field state key with error handling - const getFieldKey = useCallback((typeId, fieldId) => { - if (typeof typeId !== 'string' || typeId === '') { - throw new Error(t('errorInvalidTypeId')); - } - - if (typeof fieldId !== 'string' || fieldId === '') { - throw new Error(t('errorInvalidFieldId')); - } - - return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`; - }); - - // Define notification types - const DEFAULT_NOTIFICATION_TYPES = [ - { - id: NOTIFICATION_TYPES.SLACK, - label: t('notifications.slack.label'), - description: t('notifications.slack.description'), - fields: [ - { - id: FIELD_IDS.WEBHOOK, - label: t('notifications.slack.webhookLabel'), - placeholder: t('notifications.slack.webhookPlaceholder'), - type: 'text' - } - ] - }, - { - id: NOTIFICATION_TYPES.DISCORD, - label: t('notifications.discord.label'), - description: t('notifications.discord.description'), - fields: [ - { - id: FIELD_IDS.WEBHOOK, - label: t('notifications.discord.webhookLabel'), - placeholder: t('notifications.discord.webhookPlaceholder'), - type: 'text' - } - ] - }, - { - id: NOTIFICATION_TYPES.TELEGRAM, - label: t('notifications.telegram.label'), - description: t('notifications.telegram.description'), - fields: [ - { - id: FIELD_IDS.TOKEN, - label: t('notifications.telegram.tokenLabel'), - placeholder: t('notifications.telegram.tokenPlaceholder'), - type: 'text' - }, - { - id: FIELD_IDS.CHAT_ID, - label: t('notifications.telegram.chatIdLabel'), - placeholder: t('notifications.telegram.chatIdPlaceholder'), - type: 'text' - } - ] - }, - { - id: NOTIFICATION_TYPES.WEBHOOK, - label: t('notifications.webhook.label'), - description: t('notifications.webhook.description'), - fields: [ - { - id: FIELD_IDS.URL, - label: t('notifications.webhook.urlLabel'), - placeholder: t('notifications.webhook.urlPlaceholder'), - type: 'text' - } - ] - } - ]; + const { t } = useTranslation(); + const theme = useTheme(); + const [tabValue, setTabValue] = useState(0); - // Use provided notification types or default to our translated ones - const activeNotificationTypes = notificationTypes || DEFAULT_NOTIFICATION_TYPES; - - // Memoized function to initialize integrations state - const initialIntegrationsState = useMemo(() => { - const state = {}; + const [loading, _, sendTestNotification] = useNotifications(); + + // Helper to get the field state key with error handling + const getFieldKey = useCallback( + (typeId, fieldId) => { + if (typeof typeId !== "string" || typeId === "") { + throw new Error(t("errorInvalidTypeId")); + } + + if (typeof fieldId !== "string" || fieldId === "") { + throw new Error(t("errorInvalidFieldId")); + } + + return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`; + }, + [t] + ); + + // Define notification types + const DEFAULT_NOTIFICATION_TYPES = [ + { + id: NOTIFICATION_TYPES.SLACK, + label: t("notifications.slack.label"), + description: t("notifications.slack.description"), + fields: [ + { + id: FIELD_IDS.WEBHOOK, + label: t("notifications.slack.webhookLabel"), + placeholder: t("notifications.slack.webhookPlaceholder"), + type: "text", + }, + ], + }, + { + id: NOTIFICATION_TYPES.DISCORD, + label: t("notifications.discord.label"), + description: t("notifications.discord.description"), + fields: [ + { + id: FIELD_IDS.WEBHOOK, + label: t("notifications.discord.webhookLabel"), + placeholder: t("notifications.discord.webhookPlaceholder"), + type: "text", + }, + ], + }, + { + id: NOTIFICATION_TYPES.TELEGRAM, + label: t("notifications.telegram.label"), + description: t("notifications.telegram.description"), + fields: [ + { + id: FIELD_IDS.TOKEN, + label: t("notifications.telegram.tokenLabel"), + placeholder: t("notifications.telegram.tokenPlaceholder"), + type: "text", + }, + { + id: FIELD_IDS.CHAT_ID, + label: t("notifications.telegram.chatIdLabel"), + placeholder: t("notifications.telegram.chatIdPlaceholder"), + type: "text", + }, + ], + }, + { + id: NOTIFICATION_TYPES.WEBHOOK, + label: t("notifications.webhook.label"), + description: t("notifications.webhook.description"), + fields: [ + { + id: FIELD_IDS.URL, + label: t("notifications.webhook.urlLabel"), + placeholder: t("notifications.webhook.urlPlaceholder"), + type: "text", + }, + ], + }, + ]; + + // Use provided notification types or default to our translated ones + const activeNotificationTypes = notificationTypes || DEFAULT_NOTIFICATION_TYPES; + + // Memoized function to initialize integrations state + const initialIntegrationsState = useMemo(() => { + const state = {}; activeNotificationTypes.forEach((type) => { // Add enabled flag for each notification type @@ -140,13 +143,13 @@ const NotificationIntegrationModal = ({ state[fieldKey] = ""; }); }); - - return state; - }, [activeNotificationTypes, getFieldKey]); // Only recompute when these dependencies change - - const [integrations, setIntegrations] = useState(initialIntegrationsState); - useEffect(() => { + return state; + }, [activeNotificationTypes, getFieldKey]); // Only recompute when these dependencies change + + const [integrations, setIntegrations] = useState(initialIntegrationsState); + + useEffect(() => { if (open) { const extractNotificationValues = () => { const values = {}; @@ -202,204 +205,215 @@ const NotificationIntegrationModal = ({ } }, [open, monitor, getFieldKey]); - const handleChangeTab = (event, newValue) => { - setTabValue(newValue); - }; + const handleChangeTab = (event, newValue) => { + setTabValue(newValue); + }; - const handleIntegrationChange = (type, checked) => { - setIntegrations(prev => ({ - ...prev, - [type]: checked - })); - }; + const handleIntegrationChange = (type, checked) => { + setIntegrations((prev) => ({ + ...prev, + [type]: checked, + })); + }; - const handleInputChange = (type, value) => { - setIntegrations(prev => ({ - ...prev, - [type]: value - })); - }; + const handleInputChange = (type, value) => { + setIntegrations((prev) => ({ + ...prev, + [type]: value, + })); + }; - const handleTestNotification = async (type) => { - // Get the notification type details - const notificationType = activeNotificationTypes.find(t => t.id === type); - - if (typeof notificationType === "undefined") { - return; - } - - // Prepare config object based on notification type - const config = {}; - - // Add each field value to the config object - notificationType.fields.forEach(field => { - const fieldKey = getFieldKey(type, field.id); - config[field.id] = integrations[fieldKey]; - }); - - await sendTestNotification(type, config); - }; - - // In NotificationIntegrationModal.jsx, update the handleSave function: + const handleTestNotification = async (type) => { + // Get the notification type details + const notificationType = activeNotificationTypes.find((t) => t.id === type); -const handleSave = () => { - // Get existing notifications - const notifications = [...(monitor?.notifications || [])]; - - // Get all notification types IDs - const existingTypes = activeNotificationTypes.map(type => type.id); - - // Filter out notifications that are configurable in this modal - const filteredNotifications = notifications.filter( - notification => { - - if (notification.platform) { - return !existingTypes.includes(notification.platform); - } - - return !existingTypes.includes(notification.type); - } - ); + if (typeof notificationType === "undefined") { + return; + } - // Add each enabled notification with its configured fields - activeNotificationTypes.forEach(type => { - if (integrations[type.id]) { + // Prepare config object based on notification type + const config = {}; - let notificationObject = { - type: "webhook", - platform: type.id, // Set platform to identify the specific service - config: {} - }; - - // Configure based on notification type - switch(type.id) { - case "slack": - case "discord": - notificationObject.config.webhookUrl = integrations[getFieldKey(type.id, 'webhook')]; - break; - case "telegram": - notificationObject.config.botToken = integrations[getFieldKey(type.id, 'token')]; - notificationObject.config.chatId = integrations[getFieldKey(type.id, 'chatId')]; - break; - case "webhook": - notificationObject.config.webhookUrl = integrations[getFieldKey(type.id, 'url')]; - break; - } - - filteredNotifications.push(notificationObject); - } - }); + // Add each field value to the config object + notificationType.fields.forEach((field) => { + const fieldKey = getFieldKey(type, field.id); + config[field.id] = integrations[fieldKey]; + }); - // Update monitor with new notifications - setMonitor(prev => ({ - ...prev, - notifications: filteredNotifications - })); - - onClose(); -}; + await sendTestNotification(type, config); + }; - return ( - - - - {/* Left sidebar with tabs */} - - - {t('notifications.addOrEditNotifications')} - - - - {activeNotificationTypes.map((type) => ( - - ))} - - + // In NotificationIntegrationModal.jsx, update the handleSave function: - {/* Right side content */} - - {activeNotificationTypes.map((type, index) => ( - - - - ))} - - - - - - - - ); + const handleSave = () => { + // Get existing notifications + const notifications = [...(monitor?.notifications || [])]; + + // Get all notification types IDs + const existingTypes = activeNotificationTypes.map((type) => type.id); + + // Filter out notifications that are configurable in this modal + const filteredNotifications = notifications.filter((notification) => { + if (notification.platform) { + return !existingTypes.includes(notification.platform); + } + + return !existingTypes.includes(notification.type); + }); + + // Add each enabled notification with its configured fields + activeNotificationTypes.forEach((type) => { + if (integrations[type.id]) { + let notificationObject = { + type: "webhook", + platform: type.id, // Set platform to identify the specific service + config: {}, + }; + + // Configure based on notification type + switch (type.id) { + case "slack": + case "discord": + notificationObject.config.webhookUrl = + integrations[getFieldKey(type.id, "webhook")]; + break; + case "telegram": + notificationObject.config.botToken = + integrations[getFieldKey(type.id, "token")]; + notificationObject.config.chatId = + integrations[getFieldKey(type.id, "chatId")]; + break; + case "webhook": + notificationObject.config.webhookUrl = + integrations[getFieldKey(type.id, "url")]; + break; + } + + filteredNotifications.push(notificationObject); + } + }); + + // Update monitor with new notifications + setMonitor((prev) => ({ + ...prev, + notifications: filteredNotifications, + })); + + onClose(); + }; + + return ( + + + + {/* Left sidebar with tabs */} + + + {t("notifications.addOrEditNotifications")} + + + + {activeNotificationTypes.map((type) => ( + + ))} + + + + {/* Right side content */} + + {activeNotificationTypes.map((type, index) => ( + + + + ))} + + + + + + + + ); }; NotificationIntegrationModal.propTypes = { - open: PropTypes.bool.isRequired, - onClose: PropTypes.func.isRequired, - monitor: PropTypes.object.isRequired, - setMonitor: PropTypes.func.isRequired, - notificationTypes: PropTypes.array + open: PropTypes.bool.isRequired, + onClose: PropTypes.func.isRequired, + monitor: PropTypes.object.isRequired, + setMonitor: PropTypes.func.isRequired, + notificationTypes: PropTypes.array, }; -export default NotificationIntegrationModal; \ No newline at end of file +export default NotificationIntegrationModal; From 911d9e4ca1a14efd41248f92ff8209d5ca5849b5 Mon Sep 17 00:00:00 2001 From: "Gorkem Cetin (BWL)" <167266851+gorkem-bwl@users.noreply.github.com> Date: Mon, 5 May 2025 01:53:29 -0400 Subject: [PATCH 107/147] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a04971a83..1217bf02d 100644 --- a/README.md +++ b/README.md @@ -135,8 +135,6 @@ Thanks to [Gitbook](https://gitbook.io/) for giving us a free tier for their doc Also check other developer and contributor-friendly projects of BlueWave: -- [LangRoute](https://github.com/bluewave-labs/langroute), an LLM proxy and gateway -- [DataRoom](https://github.com/bluewave-labs/bluewave-dataroom), an secure file sharing application, aka dataroom. -- [Headcount](https://github.com/bluewave-labs/bluewave-hrm), a complete Human Resource Management platform. -- [Guidefox](https://github.com/bluewave-labs/guidefox), an application that helps new users learn how to use your product via hints, tours, popups and banners. - [VerifyWise](https://github.com/bluewave-labs/verifywise), the first open source AI governance platform. +- [DataRoom](https://github.com/bluewave-labs/bluewave-dataroom), an secure file sharing application, aka dataroom. +- [Guidefox](https://github.com/bluewave-labs/guidefox), an application that helps new users learn how to use your product via hints, tours, popups and banners. From 7bb1245e52a5eb6c659c6a6d1c0061526462860e Mon Sep 17 00:00:00 2001 From: Br0wnHammer Date: Mon, 5 May 2025 14:41:32 +0530 Subject: [PATCH 108/147] Fix: Re-render of unrelated UI Components --- client/src/Pages/Uptime/Monitors/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Pages/Uptime/Monitors/index.jsx b/client/src/Pages/Uptime/Monitors/index.jsx index 74883c909..e3e5718c3 100644 --- a/client/src/Pages/Uptime/Monitors/index.jsx +++ b/client/src/Pages/Uptime/Monitors/index.jsx @@ -146,7 +146,7 @@ const UptimeMonitors = () => { monitorUpdateTrigger, }); - const isLoading = monitorsWithSummaryIsLoading || monitorsWithChecksIsLoading; + const isLoading = monitorsWithSummaryIsLoading; if (networkError) { return ( From 4df043209a6fff5bd73c7d33bac3d0f2b3b6be95 Mon Sep 17 00:00:00 2001 From: Br0wnHammer Date: Mon, 5 May 2025 15:16:14 +0530 Subject: [PATCH 109/147] Fix: Infra Page Actions Button Disabled for Members --- .../Monitors/Components/MonitorsTableMenu/index.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx index d8bb05151..bce3020a6 100644 --- a/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx +++ b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx @@ -75,6 +75,7 @@ const InfrastructureMenu = ({ monitor, isAdmin, updateCallback }) => { Date: Mon, 5 May 2025 10:23:02 -0700 Subject: [PATCH 110/147] Changed publicUrl to constant uptime type and changed "Public link" text --- .../StatusPage/Status/Components/ControlsHeader/index.jsx | 5 +---- client/src/locales/gb.json | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx index d45c977a1..7546e8725 100644 --- a/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx +++ b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx @@ -88,10 +88,7 @@ const ControlsHeader = ({ }) => { const theme = useTheme(); const { t } = useTranslation(); - const publicUrl = - type === "uptime" - ? `/status/uptime/public/${url}` - : `/status/distributed/public/${url}`; + const publicUrl = `/status/uptime/public/${url}`; return ( Date: Mon, 5 May 2025 20:36:43 +0200 Subject: [PATCH 111/147] removed newly created constant for monitor types --- .../Uptime/Details/Components/UptimeStatusBoxes/index.jsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx index 9391256c5..f3ea2dfa6 100644 --- a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx +++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx @@ -7,13 +7,6 @@ import { useTheme } from "@mui/material/styles"; import { Typography } from "@mui/material"; import useUtils from "../../../Monitors/Hooks/useUtils"; -const MONITOR_TYPES = { - WEB: ["http", "https"], - PING: ["ping"], - DOCKER: ["docker"], - PORT: ["port"], -}; - const UptimeStatusBoxes = ({ isLoading = false, monitor, From 73e3aaf017febe0cf4313f680bf1926f6587d2df Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:08:11 +0530 Subject: [PATCH 112/147] Initial push for the test email --- server/controllers/monitorController.js | 43 ++++++++++++++++++++++++- server/index.js | 3 +- server/routes/monitorRoute.js | 6 ++++ server/service/emailService.js | 1 + server/templates/testEmailTemplate.mjml | 17 ++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 server/templates/testEmailTemplate.mjml diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 06c2d583f..3b673a93f 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -27,11 +27,12 @@ const SERVICE_NAME = "monitorController"; import pkg from "papaparse"; class MonitorController { - constructor(db, settingsService, jobQueue, stringService) { + constructor(db, settingsService, jobQueue, stringService, emailService) { this.db = db; this.settingsService = settingsService; this.jobQueue = jobQueue; this.stringService = stringService; + this.emailService = emailService; } /** @@ -636,6 +637,46 @@ class MonitorController { } }; + /** + * Sends a test email to verify email delivery functionality. + * @async + * @param {Object} req - The Express request object. + * @property {Object} req.body - The body of the request. + * @property {string} req.body.to - The email address to send the test email to. + * @param {Object} res - The Express response object. + * @param {function} next - The next middleware function. + * @returns {Object} The response object with a success status and the email delivery message ID. + * @throws {Error} If there is an error while sending the test email. + */ + sendTestEmail = async (req, res, next) => { + try { + const { to } = req.body; + + if (!to || typeof to !== "string") { + return res + .status(400) + .json({ error: "A valid recipient email address is required." }); + } + + const subject = "Test Email from Monitoring System"; + const context = { testName: "Monitoring System" }; + + const messageId = await this.emailService.buildAndSendEmail( + "testEmailTemplate", + context, + to, + subject + ); + + return res.success({ + msg: "Test email sent successfully.", + data: { messageId }, + }); + } catch (error) { + next(handleError(error, SERVICE_NAME, "sendTestEmail")); + } + }; + getMonitorsByTeamId = async (req, res, next) => { try { await getMonitorsByTeamIdParamValidation.validateAsync(req.params); diff --git a/server/index.js b/server/index.js index 520e5cab2..153660de1 100755 --- a/server/index.js +++ b/server/index.js @@ -231,7 +231,8 @@ const startApp = async () => { ServiceRegistry.get(MongoDB.SERVICE_NAME), ServiceRegistry.get(SettingsService.SERVICE_NAME), ServiceRegistry.get(JobQueue.SERVICE_NAME), - ServiceRegistry.get(StringService.SERVICE_NAME) + ServiceRegistry.get(StringService.SERVICE_NAME), + ServiceRegistry.get(EmailService.SERVICE_NAME), ); const settingsController = new SettingsController( diff --git a/server/routes/monitorRoute.js b/server/routes/monitorRoute.js index 4b4331d5b..f9ef460c6 100755 --- a/server/routes/monitorRoute.js +++ b/server/routes/monitorRoute.js @@ -99,6 +99,12 @@ class MonitorRoutes { ); this.router.post("/seed", isAllowed(["superadmin"]), this.monitorController.seedDb); + + this.router.post( + "/test-email", + isAllowed(["admin", "superadmin"]), + this.monitorController.sendTestEmail + ); } getRouter() { diff --git a/server/service/emailService.js b/server/service/emailService.js index ac2e077c0..c9e34eeda 100755 --- a/server/service/emailService.js +++ b/server/service/emailService.js @@ -67,6 +67,7 @@ class EmailService { serverIsUpTemplate: this.loadTemplate("serverIsUp"), passwordResetTemplate: this.loadTemplate("passwordReset"), hardwareIncidentTemplate: this.loadTemplate("hardwareIncident"), + testEmailTemplate: this.loadTemplate("testEmailTemplate") }; /** diff --git a/server/templates/testEmailTemplate.mjml b/server/templates/testEmailTemplate.mjml new file mode 100644 index 000000000..e9fd3221e --- /dev/null +++ b/server/templates/testEmailTemplate.mjml @@ -0,0 +1,17 @@ + + + + + + Hello! + + + This is a test email from the Monitoring System. + + + If you're receiving this, your email configuration is working correctly. + + + + + From 9b216cd059b8814da70cada808983de4fcc8025e Mon Sep 17 00:00:00 2001 From: Pezhman Parsaee Date: Mon, 5 May 2025 20:38:19 +0200 Subject: [PATCH 113/147] changed the condition to show the certificate expiry box for http monitor type --- .../Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx index f3ea2dfa6..ddc7e223b 100644 --- a/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx +++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx @@ -61,7 +61,7 @@ const UptimeStatusBoxes = ({ } /> - {MONITOR_TYPES.WEB.includes(monitor?.type) && ( + {monitor?.type === "http" && ( Date: Tue, 6 May 2025 00:22:26 +0530 Subject: [PATCH 114/147] Added returing of error message if the mail fails. --- server/controllers/monitorController.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 3b673a93f..1a37f2b24 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -668,6 +668,12 @@ class MonitorController { subject ); + if (!messageId) { + return res.error({ + msg: "Failed to send test email.", + }); + } + return res.success({ msg: "Test email sent successfully.", data: { messageId }, From 6d4b3f5174e08269e44afb871624bf5a4f3ac4e4 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:25:02 +0530 Subject: [PATCH 115/147] Returing only internal error spaces. --- server/controllers/monitorController.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 1a37f2b24..6343f2b28 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -653,9 +653,7 @@ class MonitorController { const { to } = req.body; if (!to || typeof to !== "string") { - return res - .status(400) - .json({ error: "A valid recipient email address is required." }); + return res.error({ error: "A valid recipient email address is required." }); } const subject = "Test Email from Monitoring System"; From 6268917abe32af74bd1c75803c763536813d2a15 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:27:27 +0530 Subject: [PATCH 116/147] Use string service for success. --- server/controllers/monitorController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 6343f2b28..733b20ed0 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -673,7 +673,7 @@ class MonitorController { } return res.success({ - msg: "Test email sent successfully.", + msg: this.stringService.sendTestEmail, data: { messageId }, }); } catch (error) { From f8233aef08cd693ec49cb311fbce2c2637d63e0f Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:28:54 +0530 Subject: [PATCH 117/147] local en addition. --- server/locales/en.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/locales/en.json b/server/locales/en.json index 449ab5a8e..b53c6d406 100755 --- a/server/locales/en.json +++ b/server/locales/en.json @@ -158,5 +158,6 @@ "platformRequired": "Platform is required", "testNotificationFailed": "Failed to send test notification", "monitorUpAlert": "Uptime Alert: One of your monitors is back online.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: UP\n📟 Status Code: {code}\n\u200B\n", - "monitorDownAlert": "Downtime Alert: One of your monitors went offline.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: DOWN\n📟 Status Code: {code}\n\u200B\n" + "monitorDownAlert": "Downtime Alert: One of your monitors went offline.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: DOWN\n📟 Status Code: {code}\n\u200B\n", + "sendTestEmail": "Test email sent successfully" } From 87573945f2b98fff0c96fdaa83fddfc0506a06fe Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:33:31 +0530 Subject: [PATCH 118/147] returing msg instead of error. --- server/controllers/monitorController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 733b20ed0..c917d1269 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -653,7 +653,7 @@ class MonitorController { const { to } = req.body; if (!to || typeof to !== "string") { - return res.error({ error: "A valid recipient email address is required." }); + return res.error({ msg: "A valid recipient email address is required." }); } const subject = "Test Email from Monitoring System"; From c2eeed81217bc81f4f2057fd81ad0666f4265e6b Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:37:01 +0530 Subject: [PATCH 119/147] Finall touch on string msgs. --- server/controllers/monitorController.js | 2 +- server/locales/en.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index c917d1269..5d6a4665e 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -653,7 +653,7 @@ class MonitorController { const { to } = req.body; if (!to || typeof to !== "string") { - return res.error({ msg: "A valid recipient email address is required." }); + return res.error({ msg: this.stringService.errorForValidEmailAddress }); } const subject = "Test Email from Monitoring System"; diff --git a/server/locales/en.json b/server/locales/en.json index b53c6d406..5496b0e74 100755 --- a/server/locales/en.json +++ b/server/locales/en.json @@ -159,5 +159,6 @@ "testNotificationFailed": "Failed to send test notification", "monitorUpAlert": "Uptime Alert: One of your monitors is back online.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: UP\n📟 Status Code: {code}\n\u200B\n", "monitorDownAlert": "Downtime Alert: One of your monitors went offline.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: DOWN\n📟 Status Code: {code}\n\u200B\n", - "sendTestEmail": "Test email sent successfully" + "sendTestEmail": "Test email sent successfully", + "errorForValidEmailAddress": "A valid recipient email address is required." } From bd236480790e0573ea49205104aca771200b6af3 Mon Sep 17 00:00:00 2001 From: Owaise Imdad Date: Tue, 6 May 2025 00:38:38 +0530 Subject: [PATCH 120/147] string service for subject. --- server/controllers/monitorController.js | 2 +- server/locales/en.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/controllers/monitorController.js b/server/controllers/monitorController.js index 5d6a4665e..6295a9aba 100755 --- a/server/controllers/monitorController.js +++ b/server/controllers/monitorController.js @@ -656,7 +656,7 @@ class MonitorController { return res.error({ msg: this.stringService.errorForValidEmailAddress }); } - const subject = "Test Email from Monitoring System"; + const subject = this.stringService.testEmailSubject; const context = { testName: "Monitoring System" }; const messageId = await this.emailService.buildAndSendEmail( diff --git a/server/locales/en.json b/server/locales/en.json index 5496b0e74..6cd956c37 100755 --- a/server/locales/en.json +++ b/server/locales/en.json @@ -160,5 +160,6 @@ "monitorUpAlert": "Uptime Alert: One of your monitors is back online.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: UP\n📟 Status Code: {code}\n\u200B\n", "monitorDownAlert": "Downtime Alert: One of your monitors went offline.\n📌 Monitor: {monitorName}\n📅 Time: {time}\n⚠️ Status: DOWN\n📟 Status Code: {code}\n\u200B\n", "sendTestEmail": "Test email sent successfully", - "errorForValidEmailAddress": "A valid recipient email address is required." + "errorForValidEmailAddress": "A valid recipient email address is required.", + "testEmailSubject": "Test Email from Monitoring System" } From 673022120f867245c5fca5059bfb8c28c0f4c671 Mon Sep 17 00:00:00 2001 From: Br0wnHammer Date: Tue, 6 May 2025 00:41:40 +0530 Subject: [PATCH 121/147] Fix: Re-render of unrelated UI Components --- client/src/Components/MonitorCreateHeader/index.jsx | 8 ++++---- client/src/Pages/Uptime/Monitors/index.jsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/Components/MonitorCreateHeader/index.jsx b/client/src/Components/MonitorCreateHeader/index.jsx index 382345379..05a9b7f9b 100644 --- a/client/src/Components/MonitorCreateHeader/index.jsx +++ b/client/src/Components/MonitorCreateHeader/index.jsx @@ -1,14 +1,13 @@ import { Stack, Button } from "@mui/material"; import { useNavigate } from "react-router-dom"; import PropTypes from "prop-types"; -import SkeletonLayout from "./skeleton"; import { useTranslation } from "react-i18next"; import { useTheme } from "@emotion/react"; const CreateMonitorHeader = ({ isAdmin, label = "Create new", - shouldRender = true, + isLoading = true, path, bulkPath, }) => { @@ -17,7 +16,6 @@ const CreateMonitorHeader = ({ const theme = useTheme(); if (!isAdmin) return null; - if (!shouldRender) return ; return ( {bulkPath && ( )} @@ -367,7 +367,7 @@ const ProfilePanel = () => { title={t('DeleteWarningTitle')} description={t('DeleteAccountWarning')} onCancel={() => setIsOpen("")} - confirmationButtonLabel={t('DeleteAccount')} + confirmationButtonLabel={t('DeleteAccountButton')} onConfirm={handleDeleteAccount} isLoading={isLoading} /> diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index b78e4116b..ce82f8dff 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -393,7 +393,8 @@ "YourPhoto": "Profile photo", "PhotoDescriptionText": "This photo will be displayed in your profile page.", "save": "Save", - "DeleteAccount": "Remove account", + "DeleteAccountTitle": "Remove account", + "DeleteAccountButton": "Remove account", "DeleteDescriptionText": "This will remove the account and all associated data from the server. This isn't reversible.", "DeleteAccountWarning": "Removing your account means you won't be able to sign in again and all your data will be removed. This isn't reversible.", "DeleteWarningTitle": "Really remove this account?", diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index 001e96c56..e694394b7 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -105,7 +105,8 @@ "YourPhoto": "Фото профиля", "PhotoDescriptionText": "Это фото будет отображаться на странице вашего профиля.", "EmailDescriptionText": "Ваш текущий email—его нельзя изменить.", - "DeleteAccount": "Удалить аккаунт", + "DeleteAccountTitle": "Удалить аккаунт", + "DeleteAccountButton": "Удалить аккаунт", "DeleteDescriptionText": "Это удалит аккаунт и все связанные данные с сервера. Это необратимо.", "DeleteAccountWarning": "Удаление аккаунта означает, что вы не сможете снова войти в систему, и все ваши данные будут удалены. Это необратимо.", "DeleteWarningTitle": "Действительно удалить этот аккаунт?", diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index e2b163986..f4a5c4b01 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -393,7 +393,8 @@ "YourPhoto": "Profil fotoğrafı", "PhotoDescriptionText": "Bu fotoğraf profil sayfanızda görüntülenecektir.", "save": "", - "DeleteAccount": "Hesabı kaldır", + "DeleteAccountTitle": "Hesabı kaldır", + "DeleteAccountButton": "Hesabı kaldır", "DeleteDescriptionText": "Bu, hesabı ve tüm ilişkili verileri sunucudan kaldıracaktır. Bu geri alınamaz.", "DeleteAccountWarning": "Hesabınızı kaldırmak, tekrar oturum açamayacağınız ve tüm verilerinizin kaldırılacağı anlamına gelir. Bu geri alınamaz.", "DeleteWarningTitle": "Bu hesabı gerçekten kaldırmak istiyor musunuz?", From aafdff3b0aad1469faae2e5150607788a34a7e53 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 6 May 2025 18:46:35 -0700 Subject: [PATCH 140/147] add client-host --- docker/dist/docker-compose.yaml | 1 + docker/prod/docker-compose.yaml | 2 +- docker/staging/docker-compose.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docker/dist/docker-compose.yaml b/docker/dist/docker-compose.yaml index 230623c8d..ca8e24061 100755 --- a/docker/dist/docker-compose.yaml +++ b/docker/dist/docker-compose.yaml @@ -4,6 +4,7 @@ services: restart: always environment: UPTIME_APP_API_BASE_URL: "http://localhost:5000/api/v1" + UPTIME_APP_CLIENT_HOST: "http://localhost" ports: - "80:80" - "443:443" diff --git a/docker/prod/docker-compose.yaml b/docker/prod/docker-compose.yaml index 770aaad9c..bc720862f 100755 --- a/docker/prod/docker-compose.yaml +++ b/docker/prod/docker-compose.yaml @@ -4,7 +4,7 @@ services: restart: always environment: UPTIME_APP_API_BASE_URL: "https://checkmate-demo.bluewavelabs.ca/api/v1" - UPTIME_STATUS_PAGE_SUBDOMAIN_PREFIX: "http://uptimegenie.com/" + UPTIME_APP_CLIENT_HOST: "https://checkmate-demo.bluewavelabs.ca" ports: - "80:80" - "443:443" diff --git a/docker/staging/docker-compose.yaml b/docker/staging/docker-compose.yaml index 8117dc01b..d491a729e 100755 --- a/docker/staging/docker-compose.yaml +++ b/docker/staging/docker-compose.yaml @@ -4,7 +4,7 @@ services: restart: always environment: UPTIME_APP_API_BASE_URL: "https://checkmate-test.bluewavelabs.ca/api/v1" - UPTIME_STATUS_PAGE_SUBDOMAIN_PREFIX: "http://uptimegenie.com/" + UPTIME_APP_CLIENT_HOST: "https://checkmate-test.bluewavelabs.ca" ports: - "80:80" - "443:443" From 038b7a150c0d70cc137163badd972ccae19e94f0 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 6 May 2025 19:01:23 -0700 Subject: [PATCH 141/147] fix env var name --- client/src/Hooks/inviteHooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Hooks/inviteHooks.js b/client/src/Hooks/inviteHooks.js index f8b44f0fd..705906efa 100644 --- a/client/src/Hooks/inviteHooks.js +++ b/client/src/Hooks/inviteHooks.js @@ -2,7 +2,7 @@ import { useState } from "react"; import { networkService } from "../main"; import { useTranslation } from "react-i18next"; -const CLIENT_HOST = import.meta.env.VITE_CLIENT_HOST; +const CLIENT_HOST = import.meta.env.VITE_APP_CLIENT_HOST; const useGetInviteToken = () => { const { t } = useTranslation(); From 74b1d3e245303b209746f16f457ae88b9b1858bd Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Tue, 6 May 2025 22:08:36 -0400 Subject: [PATCH 142/147] Low quality of English text --- .../TabPanels/Account/PasswordPanel.jsx | 4 ++- .../Pages/Auth/Login/Components/EmailStep.jsx | 2 +- client/src/Pages/Auth/Login/Login.jsx | 16 ++++++---- client/src/locales/gb.json | 30 +++++++++++-------- client/src/locales/ru.json | 30 +++++++++++-------- client/src/locales/tr.json | 28 +++++++++-------- 6 files changed, 65 insertions(+), 45 deletions(-) diff --git a/client/src/Components/TabPanels/Account/PasswordPanel.jsx b/client/src/Components/TabPanels/Account/PasswordPanel.jsx index 6f2775cf1..474058e66 100644 --- a/client/src/Components/TabPanels/Account/PasswordPanel.jsx +++ b/client/src/Components/TabPanels/Account/PasswordPanel.jsx @@ -10,6 +10,7 @@ import { update } from "../../../Features/Auth/authSlice"; import { useDispatch, useSelector } from "react-redux"; import { createToast } from "../../../Utils/toastUtils"; import { getTouchedFieldErrors } from "../../../Validation/error"; +import { useTranslation } from "react-i18next"; const defaultPasswordsState = { password: "", @@ -26,6 +27,7 @@ const defaultPasswordsState = { const PasswordPanel = () => { const theme = useTheme(); const dispatch = useDispatch(); + const { t } = useTranslation(); const SPACING_GAP = theme.spacing(12); @@ -203,7 +205,7 @@ const PasswordPanel = () => { { onInput={(e) => (e.target.value = e.target.value.toLowerCase())} onChange={onChange} error={errors.email ? true : false} - helperText={errors.email} + helperText={errors.email ? t(errors.email) : ""} ref={inputRef} /> { - const dispatch = useDispatch(); - const navigate = useNavigate(); const theme = useTheme(); + const dispatch = useDispatch(); + const { t } = useTranslation(); + const navigate = useNavigate(); const authState = useSelector((state) => state.auth); const { authToken } = authState; @@ -88,8 +90,10 @@ const Login = () => { { abortEarly: false } ); if (error) { - setErrors((prev) => ({ ...prev, email: error.details[0].message })); - createToast({ body: error.details[0].message }); + const errorMessage = error.details[0].message; + const translatedMessage = errorMessage.startsWith('auth') ? t(errorMessage) : errorMessage; + setErrors((prev) => ({ ...prev, email: translatedMessage })); + createToast({ body: translatedMessage }); } else { setStep(1); } @@ -106,8 +110,8 @@ const Login = () => { createToast({ body: error.details && error.details.length > 0 - ? error.details[0].message - : "Error validating data.", + ? (error.details[0].message.startsWith('auth') ? t(error.details[0].message) : error.details[0].message) + : t("Error validating data."), }); } else { const action = await dispatch(login(form)); diff --git a/client/src/locales/gb.json b/client/src/locales/gb.json index ce82f8dff..3f6e82cbc 100644 --- a/client/src/locales/gb.json +++ b/client/src/locales/gb.json @@ -2,7 +2,7 @@ "dontHaveAccount": "Don't have account", "email": "E-mail", "forgotPassword": "Forgot Password", - "password": "password", + "password": "Password", "signUp": "Sign Up", "submit": "Submit", "title": "Title", @@ -15,7 +15,7 @@ "authForgotPasswordTitle": "Forgot password?", "authForgotPasswordResetPassword": "Reset password", "createPassword": "Create your password", - "createAPassword": "Create a password", + "createAPassword": "Password", "authRegisterAlreadyHaveAccount": "Already have an account?", "authRegisterLoginLink": "Log In", "commonAppName": "Checkmate", @@ -41,7 +41,7 @@ "authSetNewPasswordDescription": "Your new password must be different from previously used passwords.", "authSetNewPasswordNewPassword": "New password", "authSetNewPasswordConfirmPassword": "Confirm password", - "confirmPassword": "Confirm your password", + "confirmPassword": "Re-enter password to confirm", "authSetNewPasswordResetPassword": "Reset password", "authSetNewPasswordBackTo": "Back to", "authPasswordMustBeAtLeast": "Must be at least", @@ -52,7 +52,10 @@ "authPasswordUpperCharacter": "one upper character", "authPasswordLowerCharacter": "one lower character", "authPasswordConfirmAndPassword": "Confirm password and password", - "authPasswordMustMatch": "must match", + "authPasswordMustMatch": "Passwords must match", + "validationNameRequired": "Please enter your name", + "validationNameTooLong": "Name should be less than 50 characters", + "validationNameInvalidCharacters": "Please use only letters, spaces, apostrophes, or hyphens", "authRegisterCreateAccount": "Create your account to get started", "authRegisterCreateSuperAdminAccount": "Create your super admin account to get started", "authRegisterSignUpWithEmail": "Create super admin account", @@ -61,7 +64,7 @@ "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.", + "settingsDisplayTimezoneDescription": "Select the timezone used to display dates and times throughout the application.", "settingsAppearance": "Appearance", "settingsAppearanceDescription": "Switch between light and dark mode, or change user interface language", "settingsThemeMode": "Theme Mode", @@ -70,20 +73,22 @@ "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.", + "settingsHistoryAndMonitoring": "History of monitoring", + "settingsHistoryAndMonitoringDescription": "Define how long you want to retain historical data. You can also clear all existing 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.", + "settingsClearAllStatsDialogDescription": "Once removed, the monitoring history and stats cannot be retrieved.", "settingsClearAllStatsDialogConfirm": "Yes, clear all stats", "settingsDemoMonitors": "Demo monitors", - "settingsDemoMonitorsDescription": "Here you can add and remove demo monitors.", - "settingsAddDemoMonitors": "Add demo monitors", + "settingsDemoMonitorsDescription": "Add sample monitors for demonstration purposes.", + "settingsAddDemoMonitors": "Adding demo monitors", "settingsAddDemoMonitorsButton": "Add demo monitors", - "settingsRemoveAllMonitors": "Remove all monitors", + "settingsSystemReset": "System reset", + "settingsSystemResetDescription": "Remove all monitors from your system.", + "settingsRemoveAllMonitors": "Removing all monitors", "settingsRemoveAllMonitorsButton": "Remove all monitors", "settingsRemoveAllMonitorsDialogTitle": "Do you want to remove all monitors?", "settingsRemoveAllMonitorsDialogConfirm": "Yes, remove all monitors", @@ -401,7 +406,8 @@ "authRegisterFirstName": "Name", "authRegisterLastName": "Surname", "authRegisterEmail": "Email", - "authRegisterEmailRequired": "Email is required", + "authRegisterEmailRequired": "To continue, please enter your email address", + "authRegisterEmailInvalid": "Please enter a valid email address", "bulkImport": { "title": "Bulk Import", "selectFileTips": "Select CSV file to upload", diff --git a/client/src/locales/ru.json b/client/src/locales/ru.json index e694394b7..ac098629b 100644 --- a/client/src/locales/ru.json +++ b/client/src/locales/ru.json @@ -2,7 +2,7 @@ "dontHaveAccount": "Нет аккаунта", "email": "Почта", "forgotPassword": "Забыли пароль", - "password": "пароль", + "password": "Пароль", "signUp": "Зарегистрироваться", "submit": "Подтвердить", "title": "Название", @@ -15,7 +15,7 @@ "authForgotPasswordTitle": "Забыли пароль?", "authForgotPasswordResetPassword": "Сбросить пароль", "createPassword": "Создайте свой пароль", - "createAPassword": "Создайте пароль", + "createAPassword": "Пароль", "authRegisterAlreadyHaveAccount": "Уже есть аккаунт?", "authRegisterLoginLink": "Войти", "commonAppName": "Checkmate", @@ -41,7 +41,8 @@ "authSetNewPasswordDescription": "Ваш новый пароль должен отличаться от ранее использованных паролей.", "authSetNewPasswordNewPassword": "Новый пароль", "authSetNewPasswordConfirmPassword": "Подтвердите пароль", - "confirmPassword": "Подтвердите ваш пароль", + "confirmPassword": "Введите пароль еще раз для подтверждения", + "confirmNewPasswordPlaceholder": "Подтвердите ваш новый пароль", "authSetNewPasswordResetPassword": "Сбросить пароль", "authSetNewPasswordBackTo": "Назад к", "authPasswordMustBeAtLeast": "Должно быть как минимум", @@ -52,7 +53,7 @@ "authPasswordUpperCharacter": "один верхний символ", "authPasswordLowerCharacter": "один нижний символ", "authPasswordConfirmAndPassword": "Подтвердите пароль и пароль", - "authPasswordMustMatch": "должен совпадать", + "authPasswordMustMatch": "Пароли должны совпадать", "authRegisterCreateAccount": "Создайте свою учетную запись, чтобы начать", "authRegisterCreateSuperAdminAccount": "Создайте учетную запись суперадминистратора, чтобы начать работу", "authRegisterSignUpWithEmail": "Создать учетную запись суперадминистратора", @@ -60,12 +61,13 @@ "authRegisterFirstName": "Имя", "authRegisterLastName": "Фамилия", "authRegisterEmail": "Эл. почта", - "authRegisterEmailRequired": "Эл. почта обязательна", + "authRegisterEmailRequired": "Чтобы продолжить, пожалуйста, введите ваш адрес электронной почты", + "authRegisterEmailInvalid": "Пожалуйста, введите корректный адрес электронной почты", "distributedStatusHeaderText": "Охват реального времени и реального устройства", "distributedStatusSubHeaderText": "Работает на миллионах устройств по всему миру, просматривайте производительность системы по глобальному региону, стране или городу", "settingsGeneralSettings": "Общие настройки", "settingsDisplayTimezone": "Отображать часовой пояс", - "settingsDisplayTimezoneDescription": "Часовой пояс панели мониторинга, которую вы публично отображаете.", + "settingsDisplayTimezoneDescription": "Выберите часовой пояс, используемый для отображения дат и времени в приложении.", "settingsAppearance": "Внешний вид", "settingsAppearanceDescription": "Переключение между светлым и темным режимом или изменение языка пользовательского интерфейса", "settingsThemeMode": "Тема", @@ -74,21 +76,23 @@ "settingsDistributedUptimeDescription": "Включить/выключить distributed uptime monitoring.", "settingsEnabled": "Включено", "settingsDisabled": "Выключено", - "settingsHistoryAndMonitoring": "История и мониторинг", - "settingsHistoryAndMonitoringDescription": "Определите здесь, как долго вы хотите хранить данные. Вы также можете удалить все прошлые данные.", + "settingsHistoryAndMonitoring": "История мониторинга", + "settingsHistoryAndMonitoringDescription": "Определите, как долго вы хотите хранить исторические данные. Вы также можете очистить все существующие данные.", "settingsTTLLabel": "Дни, за которыми вы хотите следить.", "settingsTTLOptionalLabel": "0 для бесконечности", "settingsClearAllStats": "Очистить всю статистику. Это необратимо.", "settingsClearAllStatsButton": "Очистить всю статистику", "settingsClearAllStatsDialogTitle": "Хотите очистить всю статистику?", - "settingsClearAllStatsDialogDescription": "После удаления ваши мониторы не могут быть восстановлены.", + "settingsClearAllStatsDialogDescription": "После удаления история мониторинга и статистика не могут быть восстановлены.", "settingsClearAllStatsDialogConfirm": "Да, очистить всю статистику", "settingsDemoMonitors": "Демо мониторы", - "settingsDemoMonitorsDescription": "Здесь вы можете добавлять и удалять демонстрационные мониторы.", - "settingsAddDemoMonitors": "Добавьте демонстрационные мониторы", + "settingsDemoMonitorsDescription": "Добавьте примеры мониторов для демонстрации.", + "settingsAddDemoMonitors": "Добавление демонстрационных мониторов", "settingsAddDemoMonitorsButton": "Добавьте демонстрационные мониторы", - "settingsRemoveAllMonitors": "Удалить все демонстрационные мониторы", - "settingsRemoveAllMonitorsButton": "Удалить все демонстрационные мониторы", + "settingsSystemReset": "Сброс системы", + "settingsSystemResetDescription": "Удалить все мониторы из вашей системы.", + "settingsRemoveAllMonitors": "Удаление всех мониторов", + "settingsRemoveAllMonitorsButton": "Удалить все мониторы", "settingsRemoveAllMonitorsDialogTitle": "Хотите удалить все мониторы?", "settingsRemoveAllMonitorsDialogConfirm": "Да, удалить все мониторы", "settingsWallet": "Кошелёк", diff --git a/client/src/locales/tr.json b/client/src/locales/tr.json index f4a5c4b01..fe902cbd8 100644 --- a/client/src/locales/tr.json +++ b/client/src/locales/tr.json @@ -15,7 +15,7 @@ "authForgotPasswordTitle": "Parolanızı mı unuttunuz?", "authForgotPasswordResetPassword": "Parola sıfırla", "createPassword": "Parolanızı oluşturun", - "createAPassword": "Bir parola oluşturun", + "createAPassword": "Parola", "authRegisterAlreadyHaveAccount": "Zaten hesabınız var mı?", "authRegisterLoginLink": "Giriş Yap", "commonAppName": "Checkmate", @@ -41,7 +41,8 @@ "authSetNewPasswordDescription": "Yeni şifreniz daha önce kullanılan şifrelerden farklı olmalıdır.", "authSetNewPasswordNewPassword": "Yeni şifre", "authSetNewPasswordConfirmPassword": "Parolayı onayla", - "confirmPassword": "Parolanızı onaylayın", + "confirmPassword": "Onaylamak için parolayı tekrar girin", + "confirmNewPasswordPlaceholder": "Yeni parolanızı onaylayın", "authSetNewPasswordResetPassword": "Parola sıfırla", "authSetNewPasswordBackTo": "Geri dön", "authPasswordMustBeAtLeast": "En az", @@ -52,7 +53,7 @@ "authPasswordUpperCharacter": "bir büyük harf", "authPasswordLowerCharacter": "bir küçük harf", "authPasswordConfirmAndPassword": "Onay şifresi ve şifre", - "authPasswordMustMatch": "eşleşmelidir", + "authPasswordMustMatch": "Parolalar eşleşmelidir", "authRegisterCreateAccount": "Hesap oluşturmak için devam et", "authRegisterCreateSuperAdminAccount": "Super admin hesabınızı oluşturmak için devam edin", "authRegisterSignUpWithEmail": "E-posta ile kayıt ol", @@ -61,7 +62,7 @@ "distributedStatusSubHeaderText": "Dünya çapında milyonlarca cihaz tarafından desteklenen sistem performansını küresel bölgeye, ülkeye veya şehre göre görüntüleyin", "settingsGeneralSettings": "Genel ayarlar", "settingsDisplayTimezone": "Görüntüleme saat dilimi", - "settingsDisplayTimezoneDescription": "Herkese açık olarak görüntülediğiniz kontrol panelinin saat dilimi.", + "settingsDisplayTimezoneDescription": "Uygulama genelinde tarih ve saatlerin görüntülenmesi için kullanılacak saat dilimini seçin.", "settingsAppearance": "Görünüm", "settingsAppearanceDescription": "Açık ve koyu mod arasında geçiş yapın veya kullanıcı arayüzü dilini değiştirin", "settingsThemeMode": "Tema", @@ -70,20 +71,22 @@ "settingsDistributedUptimeDescription": "Dağıtılmış çalışma süresi izlemeyi etkinleştirin/devre dışı bırakın.", "settingsEnabled": "Etkin", "settingsDisabled": "Devre dışı", - "settingsHistoryAndMonitoring": "Geçmiş ve izleme", - "settingsHistoryAndMonitoringDescription": "Verileri ne kadar süreyle saklamak istediğinizi burada tanımlayın. Ayrıca tüm geçmiş verileri kaldırabilirsiniz.", + "settingsHistoryAndMonitoring": "İzleme geçmişi", + "settingsHistoryAndMonitoringDescription": "Geçmiş verileri ne kadar süre saklamak istediğinizi tanımlayın. Ayrıca mevcut tüm verileri temizleyebilirsiniz.", "settingsTTLLabel": "İzleme geçmişini saklamak istediğiniz gün sayısı.", "settingsTTLOptionalLabel": "Sınırsız için 0", "settingsClearAllStats": "Tüm istatistikleri temizle. Bu geri alınamaz.", "settingsClearAllStatsButton": "Tüm istatistikleri temizle", "settingsClearAllStatsDialogTitle": "Tüm istatistikleri temizlemek istiyor musunuz?", - "settingsClearAllStatsDialogDescription": "Silindikten sonra, monitörleriniz geri alınamaz.", + "settingsClearAllStatsDialogDescription": "Kaldırıldıktan sonra, izleme geçmişi ve istatistikleri geri alınamaz.", "settingsClearAllStatsDialogConfirm": "Evet, tüm istatistikleri temizle", "settingsDemoMonitors": "Demo monitörler", - "settingsDemoMonitorsDescription": "Burada demo monitörler ekleyebilir ve kaldırabilirsiniz.", - "settingsAddDemoMonitors": "Demo monitörler ekle", + "settingsDemoMonitorsDescription": "Gösterim amaçlı örnek monitörler ekleyin.", + "settingsAddDemoMonitors": "Demo monitörler ekleniyor", "settingsAddDemoMonitorsButton": "Demo monitörler ekle", - "settingsRemoveAllMonitors": "Tüm monitörleri kaldır", + "settingsSystemReset": "Sistem sıfırlama", + "settingsSystemResetDescription": "Sisteminizden tüm monitörleri kaldırın.", + "settingsRemoveAllMonitors": "Tüm monitörler kaldırılıyor", "settingsRemoveAllMonitorsButton": "Tüm monitörleri kaldır", "settingsRemoveAllMonitorsDialogTitle": "Tüm monitörleri kaldırmak istiyor musunuz?", "settingsRemoveAllMonitorsDialogConfirm": "Evet, tüm monitörleri kaldır", @@ -400,8 +403,9 @@ "DeleteWarningTitle": "Bu hesabı gerçekten kaldırmak istiyor musunuz?", "authRegisterFirstName": "Ad", "authRegisterLastName": "Soyad", - "authRegisterEmail": "", - "authRegisterEmailRequired": "", + "authRegisterEmail": "E-posta", + "authRegisterEmailRequired": "Devam etmek için lütfen e-posta adresinizi girin", + "authRegisterEmailInvalid": "Lütfen geçerli bir e-posta adresi girin", "bulkImport": { "title": "", "selectFileTips": "", From 9a5de71158f68be93976a6954df548d21e1f7981 Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Tue, 6 May 2025 22:15:27 -0400 Subject: [PATCH 143/147] Fix --- .../src/Pages/Auth/Register/StepTwo/index.jsx | 2 +- client/src/Pages/Settings/index.jsx | 49 ++++++++++++------- client/src/Validation/validation.js | 12 +++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/client/src/Pages/Auth/Register/StepTwo/index.jsx b/client/src/Pages/Auth/Register/StepTwo/index.jsx index d40ff161f..fbd7e70c1 100644 --- a/client/src/Pages/Auth/Register/StepTwo/index.jsx +++ b/client/src/Pages/Auth/Register/StepTwo/index.jsx @@ -68,7 +68,7 @@ function StepTwo({ form, errors, onSubmit, onChange, onBack }) { onInput={(e) => (e.target.value = e.target.value.toLowerCase())} onChange={onChange} error={errors.email ? true : false} - helperText={errors.email && t("authRegisterEmailRequired")} + helperText={errors.email && (errors.email === "Email is required" ? t("authRegisterEmailRequired") : errors.email === "Must be a valid email address" ? t("authRegisterEmailInvalid") : errors.email)} ref={inputRef} /> { )} {isAdmin && ( - - - {t("settingsDemoMonitors")} - - {t("settingsDemoMonitorsDescription")} - - - + <> + {/* Demo Monitors Section */} + + + {t("settingsDemoMonitors")} + + {t("settingsDemoMonitorsDescription")} + + {t("settingsAddDemoMonitors")} + + + {/* System Reset Section */} + + + {t("settingsSystemReset")} + + {t("settingsSystemResetDescription")} + + {t("settingsRemoveAllMonitors")} - - setIsOpen(deleteStatsMonitorsInitState)} - confirmationButtonLabel={t("settingsRemoveAllMonitorsDialogConfirm")} - onConfirm={handleDeleteAllMonitors} - isLoading={isLoading || authIsLoading || checksIsLoading} - /> - + setIsOpen(deleteStatsMonitorsInitState)} + confirmationButtonLabel={t("settingsRemoveAllMonitorsDialogConfirm")} + onConfirm={handleDeleteAllMonitors} + isLoading={isLoading || authIsLoading || checksIsLoading} + /> + + )} diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 38092c9e6..23e14b84b 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -10,8 +10,8 @@ const nameSchema = joi .pattern(/^[\p{L}\p{M}''\- ]+$/u) .messages({ "string.empty": "Name is required", - "string.max": "Name must be less than 50 characters", - "string.pattern.base": "Name must contain only letters, spaces, apostrophes, or hyphens" + "string.max": "Name should be less than 50 characters", + "string.pattern.base": "Please use only letters, spaces, apostrophes, or hyphens" }); const passwordSchema = joi @@ -66,8 +66,8 @@ const credentials = joi.object({ return lowercasedValue; }) .messages({ - "string.empty": "Email is required", - "string.email": "Must be a valid email address", + "string.empty": "authRegisterEmailRequired", + "string.email": "authRegisterEmailInvalid", }), password: passwordSchema, newPassword: passwordSchema, @@ -253,7 +253,9 @@ const statusPageValidation = joi.object({ }); const settingsValidation = joi.object({ ttl: joi.number().required().messages({ - "string.empty": "TTL is required", + "string.empty": "Please enter a value", + "number.base": "Please enter a valid number", + "any.required": "Please enter a value" }), }); From f928322ec7ecac35a829b888d6d52fcb82106f61 Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Tue, 6 May 2025 22:19:50 -0400 Subject: [PATCH 144/147] . --- client/src/Validation/validation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 23e14b84b..01a2fd48c 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -10,8 +10,8 @@ const nameSchema = joi .pattern(/^[\p{L}\p{M}''\- ]+$/u) .messages({ "string.empty": "Name is required", - "string.max": "Name should be less than 50 characters", - "string.pattern.base": "Please use only letters, spaces, apostrophes, or hyphens" + "string.max": "Name must be less than 50 characters", + "string.pattern.base": "Name must contain only letters, spaces, apostrophes, or hyphens" }); const passwordSchema = joi From 4df4dc72e16f4ddc0ebd31068b84d52d0a05c09e Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Tue, 6 May 2025 22:37:35 -0400 Subject: [PATCH 145/147] improve email validation error handling with partial string matching --- client/src/Pages/Auth/Register/StepTwo/index.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/Pages/Auth/Register/StepTwo/index.jsx b/client/src/Pages/Auth/Register/StepTwo/index.jsx index fbd7e70c1..5f563b303 100644 --- a/client/src/Pages/Auth/Register/StepTwo/index.jsx +++ b/client/src/Pages/Auth/Register/StepTwo/index.jsx @@ -68,7 +68,11 @@ function StepTwo({ form, errors, onSubmit, onChange, onBack }) { onInput={(e) => (e.target.value = e.target.value.toLowerCase())} onChange={onChange} error={errors.email ? true : false} - helperText={errors.email && (errors.email === "Email is required" ? t("authRegisterEmailRequired") : errors.email === "Must be a valid email address" ? t("authRegisterEmailInvalid") : errors.email)} + helperText={errors.email && ( + errors.email.includes("required") ? t("authRegisterEmailRequired") : + errors.email.includes("valid email") ? t("authRegisterEmailInvalid") : + errors.email + )} ref={inputRef} /> Date: Wed, 7 May 2025 11:31:37 +0530 Subject: [PATCH 146/147] Fix: Status Page Create Monitor Button Loading --- client/src/Pages/StatusPage/StatusPages/index.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/Pages/StatusPage/StatusPages/index.jsx b/client/src/Pages/StatusPage/StatusPages/index.jsx index 6654be38c..095023d76 100644 --- a/client/src/Pages/StatusPage/StatusPages/index.jsx +++ b/client/src/Pages/StatusPage/StatusPages/index.jsx @@ -61,6 +61,7 @@ const StatusPages = () => { label="Create status page" isAdmin={isAdmin} path="/status/uptime/create" + isLoading={isLoading} /> From 6033d1545ef63f146285babe6db86b1bb02b8c82 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 7 May 2025 10:21:41 -0700 Subject: [PATCH 147/147] update .env.produciton, update dev docker build --- docker/dev/build_images.sh | 2 +- docker/dev/client.Dockerfile | 11 +++++---- docker/dev/docker-compose.yaml | 19 +++++++++++---- docker/dev/nginx/conf.d/default.conf | 35 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 9 deletions(-) create mode 100755 docker/dev/nginx/conf.d/default.conf diff --git a/docker/dev/build_images.sh b/docker/dev/build_images.sh index 4baf442b8..e94be9fa5 100755 --- a/docker/dev/build_images.sh +++ b/docker/dev/build_images.sh @@ -5,7 +5,7 @@ cd "$(dirname "$0")" cd ../.. # Define service names and their corresponding Dockerfiles in parallel arrays -services=("uptime_client" "uptime_database_mongo" "uptime_redis" "uptime_server") +services=("uptime_client" "uptime_mongo" "uptime_redis" "uptime_server") dockerfiles=( "./docker/dev/client.Dockerfile" "./docker/dev/mongoDB.Dockerfile" diff --git a/docker/dev/client.Dockerfile b/docker/dev/client.Dockerfile index fd60f47a2..aa4d228fc 100755 --- a/docker/dev/client.Dockerfile +++ b/docker/dev/client.Dockerfile @@ -18,10 +18,13 @@ COPY ./client/package*.json ./ RUN npm install -COPY ./client . +COPY ./client ./ -RUN npm run build-dev +RUN npm run build -RUN npm install -g serve +FROM nginx:1.27.1-alpine -CMD ["serve","-s", "dist", "-l", "5173"] +COPY --from=build /app/dist /usr/share/nginx/html +COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh +RUN chmod +x /docker-entrypoint.d/env.sh +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/docker/dev/docker-compose.yaml b/docker/dev/docker-compose.yaml index f8b2c6936..73904da37 100755 --- a/docker/dev/docker-compose.yaml +++ b/docker/dev/docker-compose.yaml @@ -3,8 +3,12 @@ services: image: uptime_client:latest restart: always ports: - - "5173:5173" - + - "80:80" + environment: + UPTIME_APP_API_BASE_URL: "http://localhost:5000/api/v1" + UPTIME_APP_CLIENT_HOST: "http://localhost" + volumes: + - ./nginx/conf.d:/etc/nginx/conf.d/ depends_on: - server server: @@ -31,10 +35,17 @@ services: retries: 5 start_period: 5s mongodb: - image: uptime_database_mongo:latest + image: uptime_mongo:latest restart: always - command: ["mongod", "--quiet"] + command: ["mongod", "--quiet", "--replSet", "rs0", "--bind_ip_all"] ports: - "27017:27017" volumes: - ./mongo/data:/data/db + healthcheck: + test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'mongodb:27017'}]}) }" | mongosh --port 27017 --quiet + interval: 5s + timeout: 30s + start_period: 0s + start_interval: 1s + retries: 30 diff --git a/docker/dev/nginx/conf.d/default.conf b/docker/dev/nginx/conf.d/default.conf new file mode 100755 index 000000000..9a7690aa5 --- /dev/null +++ b/docker/dev/nginx/conf.d/default.conf @@ -0,0 +1,35 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + + server_name localhost; # Set server name to localhost + server_tokens off; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + # location /api/ { + # proxy_pass http://server:5000/api/; + # proxy_http_version 1.1; + # proxy_set_header Host $host; + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + # proxy_set_header Connection ''; + # chunked_transfer_encoding off; + # proxy_buffering off; + # proxy_cache off; + # } + + location /api-docs/ { + proxy_pass http://server:5000/api-docs/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} \ No newline at end of file