mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:21:10 +02:00
feat(calendar): localize all toast messages with i18n
Replace ~20 hardcoded German toast strings in events, shares, and external-calendars stores with svelte-i18n keys (5 languages). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5b77369547
commit
d7cef38379
8 changed files with 144 additions and 29 deletions
|
|
@ -94,6 +94,26 @@
|
|||
"password": "Passwort",
|
||||
"forgotPassword": "Passwort vergessen?"
|
||||
},
|
||||
"toast": {
|
||||
"eventLoadError": "Termine konnten nicht geladen werden",
|
||||
"eventUpdateError": "Termin konnte nicht aktualisiert werden",
|
||||
"eventDeleteError": "Termin konnte nicht gelöscht werden",
|
||||
"eventDeleted": "Termin gelöscht",
|
||||
"error": "Fehler",
|
||||
"calendarShared": "Kalender mit {email} geteilt",
|
||||
"shareLinkCreated": "Freigabe-Link erstellt",
|
||||
"inviteAccepted": "Einladung angenommen",
|
||||
"shareRemoved": "Freigabe entfernt",
|
||||
"shareError": "Freigabe fehlgeschlagen",
|
||||
"updateError": "Aktualisierung fehlgeschlagen",
|
||||
"removeError": "Entfernen fehlgeschlagen",
|
||||
"declineError": "Ablehnung fehlgeschlagen",
|
||||
"calendarConnected": "{name} verbunden",
|
||||
"calendarDisconnected": "{name} getrennt",
|
||||
"syncCompleted": "Synchronisation abgeschlossen",
|
||||
"connectionError": "Verbindung fehlgeschlagen",
|
||||
"syncError": "Sync fehlgeschlagen"
|
||||
},
|
||||
"common": {
|
||||
"save": "Speichern",
|
||||
"cancel": "Abbrechen",
|
||||
|
|
@ -103,7 +123,8 @@
|
|||
"close": "Schließen",
|
||||
"search": "Suchen",
|
||||
"error": "Fehler",
|
||||
"success": "Erfolgreich"
|
||||
"success": "Erfolgreich",
|
||||
"calendar": "Kalender"
|
||||
},
|
||||
"errors": {
|
||||
"loadEvents": "Termine konnten nicht geladen werden",
|
||||
|
|
|
|||
|
|
@ -94,6 +94,26 @@
|
|||
"password": "Password",
|
||||
"forgotPassword": "Forgot password?"
|
||||
},
|
||||
"toast": {
|
||||
"eventLoadError": "Failed to load events",
|
||||
"eventUpdateError": "Failed to update event",
|
||||
"eventDeleteError": "Failed to delete event",
|
||||
"eventDeleted": "Event deleted",
|
||||
"error": "Error",
|
||||
"calendarShared": "Calendar shared with {email}",
|
||||
"shareLinkCreated": "Share link created",
|
||||
"inviteAccepted": "Invitation accepted",
|
||||
"shareRemoved": "Share removed",
|
||||
"shareError": "Sharing failed",
|
||||
"updateError": "Update failed",
|
||||
"removeError": "Remove failed",
|
||||
"declineError": "Decline failed",
|
||||
"calendarConnected": "{name} connected",
|
||||
"calendarDisconnected": "{name} disconnected",
|
||||
"syncCompleted": "Sync completed",
|
||||
"connectionError": "Connection failed",
|
||||
"syncError": "Sync failed"
|
||||
},
|
||||
"common": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
|
|
@ -103,7 +123,8 @@
|
|||
"close": "Close",
|
||||
"search": "Search",
|
||||
"error": "Error",
|
||||
"success": "Success"
|
||||
"success": "Success",
|
||||
"calendar": "Calendar"
|
||||
},
|
||||
"errors": {
|
||||
"loadEvents": "Failed to load events",
|
||||
|
|
|
|||
|
|
@ -87,6 +87,26 @@
|
|||
"password": "Contraseña",
|
||||
"forgotPassword": "¿Olvidaste tu contraseña?"
|
||||
},
|
||||
"toast": {
|
||||
"eventLoadError": "No se pudieron cargar los eventos",
|
||||
"eventUpdateError": "No se pudo actualizar el evento",
|
||||
"eventDeleteError": "No se pudo eliminar el evento",
|
||||
"eventDeleted": "Evento eliminado",
|
||||
"error": "Error",
|
||||
"calendarShared": "Calendario compartido con {email}",
|
||||
"shareLinkCreated": "Enlace de compartir creado",
|
||||
"inviteAccepted": "Invitación aceptada",
|
||||
"shareRemoved": "Compartir eliminado",
|
||||
"shareError": "Error al compartir",
|
||||
"updateError": "Error al actualizar",
|
||||
"removeError": "Error al eliminar",
|
||||
"declineError": "Error al rechazar",
|
||||
"calendarConnected": "{name} conectado",
|
||||
"calendarDisconnected": "{name} desconectado",
|
||||
"syncCompleted": "Sincronización completada",
|
||||
"connectionError": "Error de conexión",
|
||||
"syncError": "Error de sincronización"
|
||||
},
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar",
|
||||
|
|
@ -96,7 +116,8 @@
|
|||
"close": "Cerrar",
|
||||
"search": "Buscar",
|
||||
"error": "Error",
|
||||
"success": "Éxito"
|
||||
"success": "Éxito",
|
||||
"calendar": "Calendario"
|
||||
},
|
||||
"error": {
|
||||
"notFound": "Página no encontrada",
|
||||
|
|
|
|||
|
|
@ -87,6 +87,26 @@
|
|||
"password": "Mot de passe",
|
||||
"forgotPassword": "Mot de passe oublié?"
|
||||
},
|
||||
"toast": {
|
||||
"eventLoadError": "Impossible de charger les événements",
|
||||
"eventUpdateError": "Impossible de mettre à jour l'événement",
|
||||
"eventDeleteError": "Impossible de supprimer l'événement",
|
||||
"eventDeleted": "Événement supprimé",
|
||||
"error": "Erreur",
|
||||
"calendarShared": "Calendrier partagé avec {email}",
|
||||
"shareLinkCreated": "Lien de partage créé",
|
||||
"inviteAccepted": "Invitation acceptée",
|
||||
"shareRemoved": "Partage supprimé",
|
||||
"shareError": "Échec du partage",
|
||||
"updateError": "Échec de la mise à jour",
|
||||
"removeError": "Échec de la suppression",
|
||||
"declineError": "Échec du refus",
|
||||
"calendarConnected": "{name} connecté",
|
||||
"calendarDisconnected": "{name} déconnecté",
|
||||
"syncCompleted": "Synchronisation terminée",
|
||||
"connectionError": "Échec de la connexion",
|
||||
"syncError": "Échec de la synchronisation"
|
||||
},
|
||||
"common": {
|
||||
"save": "Enregistrer",
|
||||
"cancel": "Annuler",
|
||||
|
|
@ -96,7 +116,8 @@
|
|||
"close": "Fermer",
|
||||
"search": "Rechercher",
|
||||
"error": "Erreur",
|
||||
"success": "Succès"
|
||||
"success": "Succès",
|
||||
"calendar": "Calendrier"
|
||||
},
|
||||
"error": {
|
||||
"notFound": "Page non trouvée",
|
||||
|
|
|
|||
|
|
@ -87,6 +87,26 @@
|
|||
"password": "Password",
|
||||
"forgotPassword": "Password dimenticata?"
|
||||
},
|
||||
"toast": {
|
||||
"eventLoadError": "Impossibile caricare gli eventi",
|
||||
"eventUpdateError": "Impossibile aggiornare l'evento",
|
||||
"eventDeleteError": "Impossibile eliminare l'evento",
|
||||
"eventDeleted": "Evento eliminato",
|
||||
"error": "Errore",
|
||||
"calendarShared": "Calendario condiviso con {email}",
|
||||
"shareLinkCreated": "Link di condivisione creato",
|
||||
"inviteAccepted": "Invito accettato",
|
||||
"shareRemoved": "Condivisione rimossa",
|
||||
"shareError": "Condivisione fallita",
|
||||
"updateError": "Aggiornamento fallito",
|
||||
"removeError": "Rimozione fallita",
|
||||
"declineError": "Rifiuto fallito",
|
||||
"calendarConnected": "{name} connesso",
|
||||
"calendarDisconnected": "{name} disconnesso",
|
||||
"syncCompleted": "Sincronizzazione completata",
|
||||
"connectionError": "Connessione fallita",
|
||||
"syncError": "Sincronizzazione fallita"
|
||||
},
|
||||
"common": {
|
||||
"save": "Salva",
|
||||
"cancel": "Annulla",
|
||||
|
|
@ -96,7 +116,8 @@
|
|||
"close": "Chiudi",
|
||||
"search": "Cerca",
|
||||
"error": "Errore",
|
||||
"success": "Successo"
|
||||
"success": "Successo",
|
||||
"calendar": "Calendario"
|
||||
},
|
||||
"error": {
|
||||
"notFound": "Pagina non trovata",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import { format, isWithinInterval, isSameDay, differenceInMilliseconds } from 'd
|
|||
import { toDate } from '$lib/utils/eventDateHelpers';
|
||||
import { toastStore } from '@manacore/shared-ui';
|
||||
import { CalendarEvents } from '@manacore/shared-utils/analytics';
|
||||
import { get } from 'svelte/store';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
// State
|
||||
let events = $state<CalendarEvent[]>([]);
|
||||
|
|
@ -96,7 +98,7 @@ export const eventsStore = {
|
|||
|
||||
if (result.error) {
|
||||
error = result.error.message;
|
||||
toastStore.error(`Termine konnten nicht geladen werden: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.eventLoadError') + ': ' + result.error.message);
|
||||
} else {
|
||||
// API returns events array directly (already extracted in api/events.ts)
|
||||
const eventsData = result.data as CalendarEvent[] | null;
|
||||
|
|
@ -182,7 +184,7 @@ export const eventsStore = {
|
|||
const result = await api.updateEvent(id, data);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Termin konnte nicht aktualisiert werden: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.eventUpdateError') + ': ' + result.error.message);
|
||||
} else if (result.data) {
|
||||
events = events.map((e) => (e.id === id ? result.data! : e));
|
||||
CalendarEvents.eventUpdated();
|
||||
|
|
@ -206,10 +208,10 @@ export const eventsStore = {
|
|||
if (eventToDelete) {
|
||||
events = [...events, eventToDelete];
|
||||
}
|
||||
toastStore.error(`Termin konnte nicht gelöscht werden: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.eventDeleteError') + ': ' + result.error.message);
|
||||
} else {
|
||||
CalendarEvents.eventDeleted();
|
||||
toastStore.success('Termin gelöscht');
|
||||
toastStore.success(get(_)('toast.eventDeleted'));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -330,13 +332,13 @@ export const eventsStore = {
|
|||
});
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Fehler: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.error') + ': ' + result.error.message);
|
||||
// Refetch to restore state
|
||||
if (loadedRange) {
|
||||
this.fetchEvents(loadedRange.start, loadedRange.end);
|
||||
}
|
||||
} else {
|
||||
toastStore.success('Termin gelöscht');
|
||||
toastStore.success(get(_)('toast.eventDeleted'));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -358,7 +360,7 @@ export const eventsStore = {
|
|||
const result = await api.updateEvent(parentId, data);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Fehler: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.error') + ': ' + result.error.message);
|
||||
} else {
|
||||
// Refetch to regenerate occurrences
|
||||
if (loadedRange) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
import type { ExternalCalendar, ConnectExternalCalendarInput } from '@calendar/shared';
|
||||
import * as api from '$lib/api/sync';
|
||||
import { toastStore } from '@manacore/shared-ui';
|
||||
import { get } from 'svelte/store';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
// State
|
||||
let externalCalendars = $state<ExternalCalendar[]>([]);
|
||||
|
|
@ -53,10 +55,10 @@ export const externalCalendarsStore = {
|
|||
const result = await api.connectExternalCalendar(data);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Verbindung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.connectionError') + ': ' + result.error.message);
|
||||
} else if (result.data) {
|
||||
externalCalendars = [...externalCalendars, result.data];
|
||||
toastStore.success(`${data.name} verbunden`);
|
||||
toastStore.success(get(_)('toast.calendarConnected', { values: { name: data.name } }));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -66,7 +68,7 @@ export const externalCalendarsStore = {
|
|||
const result = await api.updateExternalCalendar(id, data);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Aktualisierung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.updateError') + ': ' + result.error.message);
|
||||
} else if (result.data) {
|
||||
externalCalendars = getArray().map((c) => (c.id === id ? result.data! : c));
|
||||
}
|
||||
|
|
@ -79,10 +81,14 @@ export const externalCalendarsStore = {
|
|||
const result = await api.disconnectExternalCalendar(id);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Trennung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.connectionError') + ': ' + result.error.message);
|
||||
} else {
|
||||
externalCalendars = getArray().filter((c) => c.id !== id);
|
||||
toastStore.success(`${cal?.name || 'Kalender'} getrennt`);
|
||||
toastStore.success(
|
||||
get(_)('toast.calendarDisconnected', {
|
||||
values: { name: cal?.name || get(_)('common.calendar') },
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -94,13 +100,13 @@ export const externalCalendarsStore = {
|
|||
const result = await api.triggerSync(id);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Sync fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.syncError') + ': ' + result.error.message);
|
||||
// Update last sync error in local state
|
||||
externalCalendars = getArray().map((c) =>
|
||||
c.id === id ? { ...c, lastSyncError: result.error!.message } : c
|
||||
);
|
||||
} else {
|
||||
toastStore.success('Synchronisation abgeschlossen');
|
||||
toastStore.success(get(_)('toast.syncCompleted'));
|
||||
// Update local state with new sync time
|
||||
externalCalendars = getArray().map((c) =>
|
||||
c.id === id ? { ...c, lastSyncAt: new Date().toISOString(), lastSyncError: null } : c
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
import type { CalendarShare, CalendarShareWithDetails } from '@calendar/shared';
|
||||
import * as api from '$lib/api/shares';
|
||||
import { toastStore } from '@manacore/shared-ui';
|
||||
import { get } from 'svelte/store';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
// State
|
||||
let shares = $state<Map<string, CalendarShare[]>>(new Map());
|
||||
|
|
@ -56,9 +58,9 @@ export const sharesStore = {
|
|||
const result = await api.createShare(calendarId, { calendarId, email, permission });
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Freigabe fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.shareError') + ': ' + result.error.message);
|
||||
} else {
|
||||
toastStore.success(`Kalender mit ${email} geteilt`);
|
||||
toastStore.success(get(_)('toast.calendarShared', { values: { email } }));
|
||||
await this.fetchSharesForCalendar(calendarId);
|
||||
}
|
||||
|
||||
|
|
@ -73,9 +75,9 @@ export const sharesStore = {
|
|||
});
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Link-Erstellung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.shareError') + ': ' + result.error.message);
|
||||
} else {
|
||||
toastStore.success('Freigabe-Link erstellt');
|
||||
toastStore.success(get(_)('toast.shareLinkCreated'));
|
||||
await this.fetchSharesForCalendar(calendarId);
|
||||
}
|
||||
|
||||
|
|
@ -86,9 +88,9 @@ export const sharesStore = {
|
|||
const result = await api.acceptShare(shareId);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Annahme fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.shareError') + ': ' + result.error.message);
|
||||
} else {
|
||||
toastStore.success('Einladung angenommen');
|
||||
toastStore.success(get(_)('toast.inviteAccepted'));
|
||||
invitations = invitations.filter((i) => i.id !== shareId);
|
||||
await this.fetchSharedWithMe();
|
||||
}
|
||||
|
|
@ -100,7 +102,7 @@ export const sharesStore = {
|
|||
const result = await api.declineShare(shareId);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Ablehnung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.declineError') + ': ' + result.error.message);
|
||||
} else {
|
||||
invitations = invitations.filter((i) => i.id !== shareId);
|
||||
}
|
||||
|
|
@ -112,9 +114,9 @@ export const sharesStore = {
|
|||
const result = await api.deleteShare(calendarId, shareId);
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Entfernen fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.removeError') + ': ' + result.error.message);
|
||||
} else {
|
||||
toastStore.success('Freigabe entfernt');
|
||||
toastStore.success(get(_)('toast.shareRemoved'));
|
||||
const current = shares.get(calendarId) || [];
|
||||
shares = new Map(shares).set(
|
||||
calendarId,
|
||||
|
|
@ -129,7 +131,7 @@ export const sharesStore = {
|
|||
const result = await api.updateShare(shareId, { permission });
|
||||
|
||||
if (result.error) {
|
||||
toastStore.error(`Aktualisierung fehlgeschlagen: ${result.error.message}`);
|
||||
toastStore.error(get(_)('toast.updateError') + ': ' + result.error.message);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue