diff --git a/package.json b/package.json index 8d9033f..1d985b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.23.1", + "version": "1.24.0", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index 51f7118..88a7a7d 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -321,6 +321,84 @@ const translations: Record = { weekdayCaseNormal: "Normal (monday)", weekdayCaseCapitalize: "Capitalize (Monday)", weekdayCaseUppercase: "Uppercase (MONDAY)", + styling: "Styling", + motivation: "Motivation", + about: "About", + weekStartLabel: "Start week on", + startViewLabel: "Start view on", + monday: "Monday", + sunday: "Sunday", + today: "Today", + yesterday: "Yesterday", + accountId: "Account ID", + accountIdDesc: "Your unique account identifier", + accountNumberLabel: "Account Number", + accountNumberDesc: "Your account number for identification when changing email", + connectOutlook: "Connect Outlook", + syncTasks: "Sync Tasks", + syncTasksDesc: "Sync tasks with Google Tasks or Microsoft To-Do.", + fetchingLists: "(fetching lists...)", + listHeader: "List", + syncHeader: "Sync", + noTaskListsFound: "No task lists found.", + connectProviderAbove: "Connect a provider above to sync task lists.", + noCalendarsFound: "No calendars found or permission denied.", + noCalendarsApple: "No calendars loaded. Please disconnect and reconnect Apple Calendar.", + noCalendarsSynology: "No calendars loaded. Please disconnect and reconnect Synology.", + selectionAfterConnect: "Selection available after connect.", + sharedCalendar: "Shared calendar", + primaryCalendar: "(Primary)", + fontCustomization: "Font Customization", + dateLayoutRight: "Date Right of Weekday", + dateLayoutLeft: "Date Left of Weekday", + dateLayoutAbove: "Date Above Weekday", + dateLayoutBelow: "Date Below Weekday", + dateLayoutHidden: "Date Hidden", + dateLayoutMobile: "Date Layout (Mobile)", + dayWeekdayGap: "Day / Weekday Gap", + weekdayFont: "Weekday Font", + dateFont: "Date Font", + taskFont: "Task Font", + eventFont: "Event Font", + goalFont: "Goal / Quote Font", + cwFont: "Calendar Week Font", + yearFont: "Year Font", + fontPlaceholder: "e.g. Poppins, Bebas Neue...", + fontSizePlaceholder: "Font size (e.g. 1.25rem)", + weightLight: "Light", + weightNormal: "Normal", + weightMedium: "Medium", + weightSemi: "Semi", + weightBold: "Bold", + weightBlack: "Black", + hourLabelFormat: "Hour Label Format", + hourLabelShort: "Short (8, 9, 10)", + hourLabelFull: "Full (8:00, 9:00, 10:00)", + showSubhourLabels: "Show Sub-hour Labels (:15, :30, :45)", + showScheduleCalendar: "Show Schedule / Calendar", + showDoThisNow: 'Show "Do This Now" instead of Motto', + focusTimer: "Focus Timer (min)", + focusBreak: "Focus Break (min)", + goalScopeTitle: "Goal Time Period", + goalFallbackTitle: "Goal Fallback", + motivationalQuote: "Motivational Quote / Holiday Hint", + nextTodo: "Next To-Do", + defaultText: "Default Text", + apiDataSources: "API Data Sources (URLs)", + addSource: "Add Source", + urlFormatHelp: "URL returning JSON quotes", + quoteLanguages: "Quote Languages", + quoteLanguagesDesc: "Choose which languages your quotes appear in. At least one must be selected.", + quoteFallbackDesc: "If no external source responds, curated local quotes in your language are used as fallback.", + defaultGoalPlaceholder: "Enter your goal here...", + saturdayColor: "Saturday", + sundayColor: "Sunday", + todayHighlight: "Today Highlight", + pastDayColor: "Past Day Color", + deleteProjectConfirm: "Delete project", + importConfirmReplace: "This will delete ALL existing tasks, lists, and projects. Continue?", + importSuccess: "Import complete", + importInvalidJson: "Invalid JSON file", }, de: { settings: "Einstellungen", @@ -425,6 +503,84 @@ const translations: Record = { weekdayCaseNormal: "Klein (montag)", weekdayCaseCapitalize: "Großbuchstabe (Montag)", weekdayCaseUppercase: "Großbuchstaben (MONTAG)", + styling: "Design", + motivation: "Motivation", + about: "Über", + weekStartLabel: "Woche beginnt am", + startViewLabel: "Ansicht beginnt mit", + monday: "Montag", + sunday: "Sonntag", + today: "Heute", + yesterday: "Gestern", + accountId: "Konto-ID", + accountIdDesc: "Ihre eindeutige Konto-Kennung", + accountNumberLabel: "Kontonummer", + accountNumberDesc: "Ihre Kontonummer zur Identifikation", + connectOutlook: "Outlook verbinden", + syncTasks: "Aufgaben synchronisieren", + syncTasksDesc: "Aufgaben mit Google Tasks oder Microsoft To-Do synchronisieren.", + fetchingLists: "(Listen werden geladen...)", + listHeader: "Liste", + syncHeader: "Sync", + noTaskListsFound: "Keine Aufgabenlisten gefunden.", + connectProviderAbove: "Verbinden Sie einen Anbieter oben, um Aufgabenlisten zu synchronisieren.", + noCalendarsFound: "Keine Kalender gefunden oder Zugriff verweigert.", + noCalendarsApple: "Keine Kalender geladen. Bitte trennen und erneut verbinden.", + noCalendarsSynology: "Keine Kalender geladen. Bitte trennen und erneut verbinden.", + selectionAfterConnect: "Auswahl nach Verbindung verfügbar.", + sharedCalendar: "Geteilter Kalender", + primaryCalendar: "(Primär)", + fontCustomization: "Schriftart-Anpassung", + dateLayoutRight: "Datum rechts vom Wochentag", + dateLayoutLeft: "Datum links vom Wochentag", + dateLayoutAbove: "Datum über Wochentag", + dateLayoutBelow: "Datum unter Wochentag", + dateLayoutHidden: "Datum ausgeblendet", + dateLayoutMobile: "Datum-Layout (Mobil)", + dayWeekdayGap: "Tag / Wochentag Abstand", + weekdayFont: "Wochentag-Schrift", + dateFont: "Datum-Schrift", + taskFont: "Aufgaben-Schrift", + eventFont: "Termin-Schrift", + goalFont: "Ziel / Zitat-Schrift", + cwFont: "Kalenderwoche-Schrift", + yearFont: "Jahr-Schrift", + fontPlaceholder: "z.B. Poppins, Bebas Neue...", + fontSizePlaceholder: "Schriftgröße (z.B. 1.25rem)", + weightLight: "Leicht", + weightNormal: "Normal", + weightMedium: "Mittel", + weightSemi: "Halb-fett", + weightBold: "Fett", + weightBlack: "Schwarz", + hourLabelFormat: "Stundenformat", + hourLabelShort: "Kurz (8, 9, 10)", + hourLabelFull: "Voll (8:00, 9:00, 10:00)", + showSubhourLabels: "Viertelstunden anzeigen (:15, :30, :45)", + showScheduleCalendar: "Zeitplan / Kalender anzeigen", + showDoThisNow: '"Jetzt erledigen" statt Motto anzeigen', + focusTimer: "Fokus-Timer (Min)", + focusBreak: "Fokus-Pause (Min)", + goalScopeTitle: "Ziel-Zeitraum", + goalFallbackTitle: "Ziel-Fallback", + motivationalQuote: "Motivationszitat / Feiertags-Hinweis", + nextTodo: "Nächstes To-Do", + defaultText: "Standardtext", + apiDataSources: "API-Datenquellen (URLs)", + addSource: "Quelle hinzufügen", + urlFormatHelp: "URL die JSON-Zitate liefert", + quoteLanguages: "Zitatsprachen", + quoteLanguagesDesc: "Wählen Sie die Sprachen für Ihre Zitate. Mindestens eine muss ausgewählt sein.", + quoteFallbackDesc: "Wenn keine externe Quelle antwortet, werden lokale kuratierte Zitate in Ihrer Sprache verwendet.", + defaultGoalPlaceholder: "Ihr Ziel hier eingeben...", + saturdayColor: "Samstag", + sundayColor: "Sonntag", + todayHighlight: "Heute-Hervorhebung", + pastDayColor: "Vergangene Tage", + deleteProjectConfirm: "Projekt löschen", + importConfirmReplace: "Dies löscht ALLE bestehenden Aufgaben, Listen und Projekte. Fortfahren?", + importSuccess: "Import abgeschlossen", + importInvalidJson: "Ungültige JSON-Datei", }, fr: { settings: "Paramètres", @@ -528,6 +684,84 @@ const translations: Record = { weekdayCaseNormal: "Normal (lundi)", weekdayCaseCapitalize: "Majuscule (Lundi)", weekdayCaseUppercase: "Majuscules (LUNDI)", + styling: "Style", + motivation: "Motivation", + about: "À propos", + weekStartLabel: "La semaine commence le", + startViewLabel: "Vue commence par", + monday: "Lundi", + sunday: "Dimanche", + today: "Aujourd'hui", + yesterday: "Hier", + accountId: "ID du compte", + accountIdDesc: "Votre identifiant de compte unique", + accountNumberLabel: "Numéro de compte", + accountNumberDesc: "Votre numéro de compte pour identification", + connectOutlook: "Connecter Outlook", + syncTasks: "Synchroniser les tâches", + syncTasksDesc: "Synchronisez les tâches avec Google Tasks ou Microsoft To-Do.", + fetchingLists: "(chargement des listes...)", + listHeader: "Liste", + syncHeader: "Sync", + noTaskListsFound: "Aucune liste de tâches trouvée.", + connectProviderAbove: "Connectez un fournisseur ci-dessus pour synchroniser les listes.", + noCalendarsFound: "Aucun calendrier trouvé ou accès refusé.", + noCalendarsApple: "Aucun calendrier chargé. Veuillez déconnecter et reconnecter.", + noCalendarsSynology: "Aucun calendrier chargé. Veuillez déconnecter et reconnecter.", + selectionAfterConnect: "Sélection disponible après connexion.", + sharedCalendar: "Calendrier partagé", + primaryCalendar: "(Principal)", + fontCustomization: "Personnalisation des polices", + dateLayoutRight: "Date à droite du jour", + dateLayoutLeft: "Date à gauche du jour", + dateLayoutAbove: "Date au-dessus du jour", + dateLayoutBelow: "Date en dessous du jour", + dateLayoutHidden: "Date masquée", + dateLayoutMobile: "Disposition date (mobile)", + dayWeekdayGap: "Espacement jour / semaine", + weekdayFont: "Police du jour", + dateFont: "Police de la date", + taskFont: "Police des tâches", + eventFont: "Police des événements", + goalFont: "Police objectif / citation", + cwFont: "Police semaine calendaire", + yearFont: "Police de l'année", + fontPlaceholder: "ex. Poppins, Bebas Neue...", + fontSizePlaceholder: "Taille (ex. 1.25rem)", + weightLight: "Léger", + weightNormal: "Normal", + weightMedium: "Moyen", + weightSemi: "Semi-gras", + weightBold: "Gras", + weightBlack: "Noir", + hourLabelFormat: "Format des heures", + hourLabelShort: "Court (8, 9, 10)", + hourLabelFull: "Complet (8:00, 9:00, 10:00)", + showSubhourLabels: "Afficher les quarts d'heure (:15, :30, :45)", + showScheduleCalendar: "Afficher le calendrier", + showDoThisNow: '"Faire maintenant" au lieu de la devise', + focusTimer: "Minuteur Focus (min)", + focusBreak: "Pause Focus (min)", + goalScopeTitle: "Période de l'objectif", + goalFallbackTitle: "Fallback objectif", + motivationalQuote: "Citation motivante / info jour férié", + nextTodo: "Prochaine tâche", + defaultText: "Texte par défaut", + apiDataSources: "Sources de données API (URLs)", + addSource: "Ajouter une source", + urlFormatHelp: "URL retournant des citations JSON", + quoteLanguages: "Langues des citations", + quoteLanguagesDesc: "Choisissez les langues de vos citations. Au moins une doit être sélectionnée.", + quoteFallbackDesc: "Si aucune source externe ne répond, des citations locales dans votre langue sont utilisées.", + defaultGoalPlaceholder: "Entrez votre objectif ici...", + saturdayColor: "Samedi", + sundayColor: "Dimanche", + todayHighlight: "Surbrillance aujourd'hui", + pastDayColor: "Jours passés", + deleteProjectConfirm: "Supprimer le projet", + importConfirmReplace: "Cela supprimera TOUTES les tâches, listes et projets existants. Continuer ?", + importSuccess: "Import terminé", + importInvalidJson: "Fichier JSON invalide", }, es: { settings: "Ajustes", @@ -631,6 +865,84 @@ const translations: Record = { weekdayCaseNormal: "Normal (lunes)", weekdayCaseCapitalize: "Mayúscula inicial (Lunes)", weekdayCaseUppercase: "Mayúsculas (LUNES)", + styling: "Estilo", + motivation: "Motivación", + about: "Acerca de", + weekStartLabel: "La semana empieza el", + startViewLabel: "Vista empieza con", + monday: "Lunes", + sunday: "Domingo", + today: "Hoy", + yesterday: "Ayer", + accountId: "ID de cuenta", + accountIdDesc: "Tu identificador único de cuenta", + accountNumberLabel: "Número de cuenta", + accountNumberDesc: "Tu número de cuenta para identificación", + connectOutlook: "Conectar Outlook", + syncTasks: "Sincronizar tareas", + syncTasksDesc: "Sincroniza tareas con Google Tasks o Microsoft To-Do.", + fetchingLists: "(cargando listas...)", + listHeader: "Lista", + syncHeader: "Sync", + noTaskListsFound: "No se encontraron listas de tareas.", + connectProviderAbove: "Conecta un proveedor arriba para sincronizar listas.", + noCalendarsFound: "No se encontraron calendarios o acceso denegado.", + noCalendarsApple: "No hay calendarios cargados. Desconecta y reconecta.", + noCalendarsSynology: "No hay calendarios cargados. Desconecta y reconecta.", + selectionAfterConnect: "Selección disponible tras conectar.", + sharedCalendar: "Calendario compartido", + primaryCalendar: "(Principal)", + fontCustomization: "Personalización de fuentes", + dateLayoutRight: "Fecha a la derecha del día", + dateLayoutLeft: "Fecha a la izquierda del día", + dateLayoutAbove: "Fecha encima del día", + dateLayoutBelow: "Fecha debajo del día", + dateLayoutHidden: "Fecha oculta", + dateLayoutMobile: "Disposición fecha (móvil)", + dayWeekdayGap: "Espacio día / semana", + weekdayFont: "Fuente del día", + dateFont: "Fuente de la fecha", + taskFont: "Fuente de tareas", + eventFont: "Fuente de eventos", + goalFont: "Fuente objetivo / cita", + cwFont: "Fuente semana calendario", + yearFont: "Fuente del año", + fontPlaceholder: "ej. Poppins, Bebas Neue...", + fontSizePlaceholder: "Tamaño (ej. 1.25rem)", + weightLight: "Ligero", + weightNormal: "Normal", + weightMedium: "Medio", + weightSemi: "Semi-negrita", + weightBold: "Negrita", + weightBlack: "Negro", + hourLabelFormat: "Formato de horas", + hourLabelShort: "Corto (8, 9, 10)", + hourLabelFull: "Completo (8:00, 9:00, 10:00)", + showSubhourLabels: "Mostrar cuartos de hora (:15, :30, :45)", + showScheduleCalendar: "Mostrar calendario", + showDoThisNow: '"Hacer ahora" en vez de lema', + focusTimer: "Temporizador Focus (min)", + focusBreak: "Pausa Focus (min)", + goalScopeTitle: "Periodo del objetivo", + goalFallbackTitle: "Fallback del objetivo", + motivationalQuote: "Cita motivacional / festivo", + nextTodo: "Siguiente tarea", + defaultText: "Texto predeterminado", + apiDataSources: "Fuentes de datos API (URLs)", + addSource: "Añadir fuente", + urlFormatHelp: "URL que devuelve citas JSON", + quoteLanguages: "Idiomas de citas", + quoteLanguagesDesc: "Elige los idiomas de tus citas. Al menos uno debe estar seleccionado.", + quoteFallbackDesc: "Si ninguna fuente externa responde, se usan citas locales en tu idioma.", + defaultGoalPlaceholder: "Ingresa tu objetivo aquí...", + saturdayColor: "Sábado", + sundayColor: "Domingo", + todayHighlight: "Resaltado de hoy", + pastDayColor: "Días pasados", + deleteProjectConfirm: "Eliminar proyecto", + importConfirmReplace: "Esto eliminará TODAS las tareas, listas y proyectos existentes. ¿Continuar?", + importSuccess: "Importación completada", + importInvalidJson: "Archivo JSON inválido", }, it: { settings: "Impostazioni", @@ -734,6 +1046,84 @@ const translations: Record = { weekdayCaseNormal: "Normale (lunedì)", weekdayCaseCapitalize: "Iniziale maiuscola (Lunedì)", weekdayCaseUppercase: "Maiuscolo (LUNEDÌ)", + styling: "Stile", + motivation: "Motivazione", + about: "Info", + weekStartLabel: "La settimana inizia il", + startViewLabel: "Vista inizia con", + monday: "Lunedì", + sunday: "Domenica", + today: "Oggi", + yesterday: "Ieri", + accountId: "ID account", + accountIdDesc: "Il tuo identificatore account unico", + accountNumberLabel: "Numero account", + accountNumberDesc: "Il tuo numero account per identificazione", + connectOutlook: "Connetti Outlook", + syncTasks: "Sincronizza attività", + syncTasksDesc: "Sincronizza le attività con Google Tasks o Microsoft To-Do.", + fetchingLists: "(caricamento liste...)", + listHeader: "Lista", + syncHeader: "Sync", + noTaskListsFound: "Nessuna lista di attività trovata.", + connectProviderAbove: "Connetti un provider sopra per sincronizzare le liste.", + noCalendarsFound: "Nessun calendario trovato o accesso negato.", + noCalendarsApple: "Nessun calendario caricato. Disconnetti e riconnetti.", + noCalendarsSynology: "Nessun calendario caricato. Disconnetti e riconnetti.", + selectionAfterConnect: "Selezione disponibile dopo la connessione.", + sharedCalendar: "Calendario condiviso", + primaryCalendar: "(Principale)", + fontCustomization: "Personalizzazione caratteri", + dateLayoutRight: "Data a destra del giorno", + dateLayoutLeft: "Data a sinistra del giorno", + dateLayoutAbove: "Data sopra il giorno", + dateLayoutBelow: "Data sotto il giorno", + dateLayoutHidden: "Data nascosta", + dateLayoutMobile: "Layout data (mobile)", + dayWeekdayGap: "Spazio giorno / settimana", + weekdayFont: "Carattere giorno", + dateFont: "Carattere data", + taskFont: "Carattere attività", + eventFont: "Carattere eventi", + goalFont: "Carattere obiettivo / citazione", + cwFont: "Carattere settimana calendario", + yearFont: "Carattere anno", + fontPlaceholder: "es. Poppins, Bebas Neue...", + fontSizePlaceholder: "Dimensione (es. 1.25rem)", + weightLight: "Leggero", + weightNormal: "Normale", + weightMedium: "Medio", + weightSemi: "Semi-grassetto", + weightBold: "Grassetto", + weightBlack: "Nero", + hourLabelFormat: "Formato delle ore", + hourLabelShort: "Breve (8, 9, 10)", + hourLabelFull: "Completo (8:00, 9:00, 10:00)", + showSubhourLabels: "Mostra quarti d'ora (:15, :30, :45)", + showScheduleCalendar: "Mostra calendario", + showDoThisNow: '"Fai ora" invece del motto', + focusTimer: "Timer Focus (min)", + focusBreak: "Pausa Focus (min)", + goalScopeTitle: "Periodo dell'obiettivo", + goalFallbackTitle: "Fallback obiettivo", + motivationalQuote: "Citazione motivazionale / festività", + nextTodo: "Prossima attività", + defaultText: "Testo predefinito", + apiDataSources: "Fonti dati API (URL)", + addSource: "Aggiungi fonte", + urlFormatHelp: "URL che restituisce citazioni JSON", + quoteLanguages: "Lingue delle citazioni", + quoteLanguagesDesc: "Scegli le lingue delle citazioni. Almeno una deve essere selezionata.", + quoteFallbackDesc: "Se nessuna fonte esterna risponde, vengono usate citazioni locali nella tua lingua.", + defaultGoalPlaceholder: "Inserisci il tuo obiettivo qui...", + saturdayColor: "Sabato", + sundayColor: "Domenica", + todayHighlight: "Evidenziazione oggi", + pastDayColor: "Giorni passati", + deleteProjectConfirm: "Elimina progetto", + importConfirmReplace: "Questo eliminerà TUTTE le attività, liste e progetti esistenti. Continuare?", + importSuccess: "Importazione completata", + importInvalidJson: "File JSON non valido", }, }; @@ -8563,7 +8953,7 @@ function SettingsSidebar({ showTimeGrid: showTimeGrid, cellDuration: cellDuration, viewStyle: viewStyle, - language: profile.language || "en", + language: profile.language || "de", dateFormat: profile.dateFormat || "MM/dd/yyyy", timeFormat: profile.timeFormat || "12h", startHour: profile.startHour || 8, @@ -8925,7 +9315,7 @@ function SettingsSidebar({ showTimeGrid: showTimeGrid, cellDuration: cellDuration, viewStyle: viewStyle, - language: profile.language || "en", + language: profile.language || "de", dateFormat: profile.dateFormat || "MM/dd/yyyy", timeFormat: profile.timeFormat || "12h", startHour: profile.startHour || 8, @@ -9022,11 +9412,7 @@ function SettingsSidebar({ if (!importFile) return; if (importMode === "replace") { - const confirmed = confirm( - profile.language === "de" - ? "Sind Sie sicher? Alle bestehenden Aufgaben, Listen und Projekte werden gelöscht und durch die importierten Daten ersetzt." - : "Are you sure? All existing tasks, lists, and projects will be deleted and replaced with the imported data." - ); + const confirmed = confirm(t.importConfirmReplace); if (!confirmed) return; } @@ -9122,9 +9508,9 @@ function SettingsSidebar({ { key: "localisation", icon: , label: t.localisation }, { key: "calendar", icon: , label: t.calendar }, { key: "account", icon: , label: t.account }, - { key: "styling", icon: , label: "Styling" }, - { key: "motivation", icon: , label: "Motivation" }, - { key: "about", icon: , label: "About" }, + { key: "styling", icon: , label: t.styling }, + { key: "motivation", icon: , label: t.motivation }, + { key: "about", icon: , label: t.about }, ] as const).map((tab) => ( @@ -9755,7 +10141,7 @@ function SettingsSidebar({ marginBottom: "4px", }} > - {profile.language === "de" ? "Ansicht beginnt mit" : "Start view on"} + {t.startViewLabel}
@@ -9875,9 +10261,9 @@ function SettingsSidebar({ {t.language} @@ -10260,12 +10646,12 @@ function SettingsSidebar({ }} > {conn.provider === "google" - ? "No calendars found or permission denied." + ? t.noCalendarsFound : conn.provider === "apple" - ? "No calendars loaded. Please disconnect and reconnect Apple Calendar to load your calendars." + ? t.noCalendarsApple : conn.provider === "synology" - ? "No calendars loaded. Please disconnect and reconnect Synology to load your calendars." - : "Selection available after connect."} + ? t.noCalendarsSynology + : t.selectionAfterConnect} )} @@ -10300,7 +10686,7 @@ function SettingsSidebar({ onClick={handleOutlookConnect} className="calendar-connect-btn" > - Connect Outlook + {t.connectOutlook} @@ -11663,7 +12048,7 @@ function SettingsSidebar({ color: "var(--weekly-settings-title)", }} > - Ziel der Woche Fallback + {t.goalFallbackTitle}
{(!profile.goalFallbackType || profile.goalFallbackType === "quote") && ( @@ -11711,7 +12096,7 @@ function SettingsSidebar({ color: "var(--weekly-settings-label)", }} > - API-Datenquellen (URLs) + {t.apiDataSources}
{(profile.quoteSourceUrls || [profile.quoteSourceUrl || ""]).map((url: string, idx: number) => ( @@ -11775,22 +12160,14 @@ function SettingsSidebar({ gap: "4px" }} > - Add Source + {t.addSource}

- URL that returns a JSON list or object of quotes (e.g. {'[{"quote":"...","author":"..."}]'} or {'{"quote":"..."}'}). + {t.urlFormatHelp}

- {profile.language === "de" - ? "Wenn keine externe Quelle antwortet, werden lokale kuratierte Zitate in Ihrer Sprache verwendet." - : profile.language === "fr" - ? "Si aucune source externe ne répond, des citations locales dans votre langue sont utilisées." - : profile.language === "es" - ? "Si ninguna fuente externa responde, se usan citas locales en tu idioma." - : profile.language === "it" - ? "Se nessuna fonte esterna risponde, vengono usate citazioni locali nella tua lingua." - : "If no external source responds, curated local quotes in your language are used as fallback."} + {t.quoteFallbackDesc}

{[ @@ -11849,15 +12226,7 @@ function SettingsSidebar({ })}

- {profile.language === "de" - ? "Wählen Sie die Sprachen für Ihre Zitate. Mindestens eine muss ausgewählt sein." - : profile.language === "fr" - ? "Choisissez les langues de vos citations. Au moins une doit être sélectionnée." - : profile.language === "es" - ? "Elige los idiomas de tus citas. Al menos uno debe estar seleccionado." - : profile.language === "it" - ? "Scegli le lingue delle citazioni. Almeno una deve essere selezionata." - : "Choose which languages your quotes appear in. At least one must be selected."} + {t.quoteLanguagesDesc}

@@ -11872,7 +12241,7 @@ function SettingsSidebar({ color: "var(--weekly-settings-label)", }} > - Standardtext + {t.defaultText} )} @@ -12032,7 +12401,7 @@ function SettingsSidebar({ marginBottom: "4px", }} > - {profile.language === "de" ? "Konto-ID" : "Account ID"} + {t.accountId} - {profile.language === "de" - ? "Ihre eindeutige Konto-Kennung" - : "Your unique account identifier"} + {t.accountIdDesc} )} @@ -12069,7 +12436,7 @@ function SettingsSidebar({ marginBottom: "4px", }} > - {profile.language === "de" ? "Kontonummer" : "Account Number"} + {t.accountNumberLabel} - {profile.language === "de" - ? "Ihre Kontonummer zur Identifikation bei E-Mail-Änderungen" - : "Your account number for identification when changing email"} + {t.accountNumberDesc} )} diff --git a/src/lib/synology-calendar.ts b/src/lib/synology-calendar.ts index a053ab1..aed4651 100644 --- a/src/lib/synology-calendar.ts +++ b/src/lib/synology-calendar.ts @@ -232,7 +232,14 @@ export const getUpcomingEvents = async ( return parsedEvents; } catch (error: any) { - console.error(`[SYNOLOGY CALENDAR] Error fetching events for ${calendarUrl}:`, error); + const msg = error?.message || ''; + const status = error?.response?.status || error?.status; + // Silently handle expected failures (stale/deleted calendars, permission issues) + if (status === 405 || status === 404 || msg.includes('405') || msg.includes('Not Allowed') || msg.includes('not found')) { + console.warn(`[SYNOLOGY CALENDAR] Calendar unavailable (${status || msg.slice(0, 60)}): ${calendarUrl}`); + } else { + console.error(`[SYNOLOGY CALENDAR] Error fetching events for ${calendarUrl}:`, error); + } return []; } };