Merge branch 'main' of github.com:rafaelfoster/oikos

This commit is contained in:
Rafael Foster
2026-04-29 08:13:48 -03:00
19 changed files with 548 additions and 386 deletions
+11
View File
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.32.2] - 2026-04-29
### Changed
- Bottom navigation restructured: Dashboard, Tasks, Calendar as first three primary slots; Search promoted to a dedicated fourth bottom-nav button (no longer buried in the More sheet)
- Sidebar tooltips added for the collapsed mode (10241439 px) — hovering an icon now shows a label tooltip so module names remain discoverable without expanding the sidebar
## [0.32.1] - 2026-04-29
### Fixed
- i18n: complete documents and tasks translations for all 15 locales — gridView, listView, viewToggle, file labels, action labels, toast messages, status labels, and the five new tasks keys (statusArchived, archiveButton, archivedToast, kanbanArchived, reminderNeedsDueDate) were untranslated in all non-English locales (#103)
## [0.32.0] - 2026-04-29
### Added
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "oikos",
"version": "0.32.0",
"version": "0.32.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "oikos",
"version": "0.32.0",
"version": "0.32.2",
"license": "MIT",
"dependencies": {
"bcrypt": "^6.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "oikos",
"version": "0.32.0",
"version": "0.32.2",
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
"main": "server/index.js",
"type": "module",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "الأولوية",
"filterGroupStatus": "الحالة",
"swipedDoneToast": "تم وضع علامة مكتمل.",
"swipedOpenToast": "تم وضع علامة مفتوح."
"swipedOpenToast": "تم وضع علامة مفتوح.",
"statusArchived": "مؤرشف",
"archiveButton": "أرشفة المهمة",
"archivedToast": "تم أرشفة المهمة.",
"kanbanArchived": "مؤرشف",
"reminderNeedsDueDate": "حدّد تاريخ استحقاق لتفعيل تذكيرات المهمة."
},
"shopping": {
"title": "التسوق",
@@ -903,38 +908,38 @@
"title": "المستندات",
"addButton": "إضافة مستند",
"searchPlaceholder": "البحث في المستندات...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "عرض شبكي",
"listView": "عرض قائمة",
"viewToggle": "عرض المستندات",
"allCategories": "كل الفئات",
"emptyTitle": "لا توجد مستندات بعد",
"emptyDescription": "ارفع مستندات العائلة وتحكم في من يمكنه رؤية كل ملف.",
"newTitle": "مستند جديد",
"editTitle": "إعدادات المستند",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "الاسم",
"descriptionLabel": "الوصف",
"categoryLabel": "الفئة",
"fileLabel": "الملف",
"fileHint": "ملفات PDF والصور والنصوص وملفات Office حتى 5 ميغابايت.",
"visibilityLabel": "مستوى الرؤية",
"statusLabel": "الحالة",
"allowedMembersLabel": "الأعضاء المسموح لهم",
"uploadAction": "رفع",
"downloadAction": "تحميل",
"editAction": "إعدادات",
"archiveAction": "أرشفة",
"restoreAction": "استعادة",
"savedToast": "تم حفظ المستند.",
"uploadedToast": "تم رفع المستند.",
"archivedToast": "تم أرشفة المستند.",
"restoredToast": "تم استعادة المستند.",
"deletedToast": "تم حذف المستند.",
"deleteConfirm": "حذف المستند \"{{name}}\"؟",
"fileRequired": "يرجى اختيار ملف للرفع.",
"fileTooLarge": "يجب ألا يتجاوز حجم الملف 5 ميغابايت.",
"fileReadError": "تعذّر قراءة الملف.",
"statusActive": "نشط",
"statusArchived": "مؤرشف",
"visibility": {
"family": "كل العائلة",
"restricted": "أعضاء محددون",
+31 -26
View File
@@ -187,7 +187,12 @@
"filterGroupPriority": "Priorität",
"filterGroupPerson": "Person",
"filterClearAll": "Alle Filter zurücksetzen",
"navLabelOverdue": "Aufgaben, {{count}} überfällig"
"navLabelOverdue": "Aufgaben, {{count}} überfällig",
"statusArchived": "Archiviert",
"archiveButton": "Aufgabe archivieren",
"archivedToast": "Aufgabe archiviert.",
"kanbanArchived": "Archiviert",
"reminderNeedsDueDate": "Lege ein Fälligkeitsdatum fest, um Aufgabenerinnerungen zu aktivieren."
},
"shopping": {
"title": "Einkauf",
@@ -941,38 +946,38 @@
"title": "Dokumente",
"addButton": "Dokument hinzufügen",
"searchPlaceholder": "Dokumente suchen...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Rasteransicht",
"listView": "Listenansicht",
"viewToggle": "Dokumentansicht",
"allCategories": "Alle Kategorien",
"emptyTitle": "Noch keine Dokumente",
"emptyDescription": "Lade Familiendokumente hoch und steuere, wer jede Datei sehen darf.",
"newTitle": "Neues Dokument",
"editTitle": "Dokumenteinstellungen",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"descriptionLabel": "Beschreibung",
"categoryLabel": "Kategorie",
"fileLabel": "Datei",
"fileHint": "PDF, Bilder, Text und Office-Dateien bis zu 5 MB.",
"visibilityLabel": "Sichtbarkeit",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"allowedMembersLabel": "Erlaubte Mitglieder",
"uploadAction": "Hochladen",
"downloadAction": "Herunterladen",
"editAction": "Einstellungen",
"archiveAction": "Archivieren",
"restoreAction": "Wiederherstellen",
"savedToast": "Dokument gespeichert.",
"uploadedToast": "Dokument hochgeladen.",
"archivedToast": "Dokument archiviert.",
"restoredToast": "Dokument wiederhergestellt.",
"deletedToast": "Dokument gelöscht.",
"deleteConfirm": "Dokument \"{{name}}\" löschen?",
"fileRequired": "Bitte wähle eine Datei aus.",
"fileTooLarge": "Die Datei darf höchstens 5 MB groß sein.",
"fileReadError": "Die Datei konnte nicht gelesen werden.",
"statusActive": "Aktiv",
"statusArchived": "Archiviert",
"visibility": {
"family": "Ganze Familie",
"restricted": "Ausgewählte Mitglieder",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Προτεραιότητα",
"filterGroupStatus": "Κατάσταση",
"swipedDoneToast": "Επισημάνθηκε ως ολοκληρωμένο.",
"swipedOpenToast": "Επισημάνθηκε ως ανοιχτό."
"swipedOpenToast": "Επισημάνθηκε ως ανοιχτό.",
"statusArchived": "Αρχειοθετημένο",
"archiveButton": "Αρχειοθέτηση εργασίας",
"archivedToast": "Η εργασία αρχειοθετήθηκε.",
"kanbanArchived": "Αρχειοθετημένο",
"reminderNeedsDueDate": "Ορίστε ημερομηνία λήξης για να ενεργοποιήσετε τις υπενθυμίσεις."
},
"shopping": {
"title": "Αγορές",
@@ -903,38 +908,38 @@
"title": "Έγγραφα",
"addButton": "Προσθήκη εγγράφου",
"searchPlaceholder": "Αναζήτηση εγγράφων...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Προβολή πλέγματος",
"listView": "Προβολή λίστας",
"viewToggle": "Προβολή εγγράφων",
"allCategories": "Όλες οι κατηγορίες",
"emptyTitle": "Δεν υπάρχουν έγγραφα ακόμα",
"emptyDescription": "Ανεβάστε οικογενειακά έγγραφα και ελέγξτε ποιος μπορεί να βλέπει κάθε αρχείο.",
"newTitle": "Νέο έγγραφο",
"editTitle": "Ρυθμίσεις εγγράφου",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "Όνομα",
"descriptionLabel": "Περιγραφή",
"categoryLabel": "Κατηγορία",
"fileLabel": "Αρχείο",
"fileHint": "PDF, εικόνες, κείμενο και αρχεία Office έως 5 MB.",
"visibilityLabel": "Ορατότητα",
"statusLabel": "Κατάσταση",
"allowedMembersLabel": "Επιτρεπόμενα μέλη",
"uploadAction": "Μεταφόρτωση",
"downloadAction": "Λήψη",
"editAction": "Ρυθμίσεις",
"archiveAction": "Αρχειοθέτηση",
"restoreAction": "Επαναφορά",
"savedToast": "Το έγγραφο αποθηκεύτηκε.",
"uploadedToast": "Το έγγραφο ανέβηκε.",
"archivedToast": "Το έγγραφο αρχειοθετήθηκε.",
"restoredToast": "Το έγγραφο επαναφέρθηκε.",
"deletedToast": "Το έγγραφο διαγράφηκε.",
"deleteConfirm": "Διαγραφή εγγράφου \"{{name}}\";",
"fileRequired": "Επιλέξτε ένα αρχείο για μεταφόρτωση.",
"fileTooLarge": "Το αρχείο μπορεί να είναι έως 5 MB.",
"fileReadError": "Δεν ήταν δυνατή η ανάγνωση του αρχείου.",
"statusActive": "Ενεργό",
"statusArchived": "Αρχειοθετημένο",
"visibility": {
"family": "Όλη η οικογένεια",
"restricted": "Επιλεγμένα μέλη",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Prioridad",
"filterGroupStatus": "Estado",
"swipedDoneToast": "Marcado como hecho.",
"swipedOpenToast": "Marcado como abierto."
"swipedOpenToast": "Marcado como abierto.",
"statusArchived": "Archivado",
"archiveButton": "Archivar tarea",
"archivedToast": "Tarea archivada.",
"kanbanArchived": "Archivado",
"reminderNeedsDueDate": "Establece una fecha de vencimiento para activar los recordatorios de tareas."
},
"shopping": {
"title": "Compras",
@@ -903,38 +908,38 @@
"title": "Documentos",
"addButton": "Agregar documento",
"searchPlaceholder": "Buscar documentos...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Vista de cuadrícula",
"listView": "Vista de lista",
"viewToggle": "Vista de documentos",
"allCategories": "Todas las categorías",
"emptyTitle": "Aún no hay documentos",
"emptyDescription": "Sube documentos familiares y controla quién puede ver cada archivo.",
"newTitle": "Nuevo documento",
"editTitle": "Configuración del documento",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "Nombre",
"descriptionLabel": "Descripción",
"categoryLabel": "Categoría",
"fileLabel": "Archivo",
"fileHint": "PDF, imágenes, texto y archivos Office de hasta 5 MB.",
"visibilityLabel": "Visibilidad",
"statusLabel": "Estado",
"allowedMembersLabel": "Miembros permitidos",
"uploadAction": "Subir",
"downloadAction": "Descargar",
"editAction": "Configuración",
"archiveAction": "Archivar",
"restoreAction": "Restaurar",
"savedToast": "Documento guardado.",
"uploadedToast": "Documento subido.",
"archivedToast": "Documento archivado.",
"restoredToast": "Documento restaurado.",
"deletedToast": "Documento eliminado.",
"deleteConfirm": "¿Eliminar documento \"{{name}}\"?",
"fileRequired": "Selecciona un archivo para subir.",
"fileTooLarge": "El archivo puede tener como máximo 5 MB.",
"fileReadError": "No se pudo leer el archivo.",
"statusActive": "Activo",
"statusArchived": "Archivado",
"visibility": {
"family": "Toda la familia",
"restricted": "Miembros seleccionados",
+32 -27
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Priorité",
"filterGroupStatus": "Statut",
"swipedDoneToast": "Marqué comme terminé.",
"swipedOpenToast": "Marqué comme ouvert."
"swipedOpenToast": "Marqué comme ouvert.",
"statusArchived": "Archivé",
"archiveButton": "Archiver la tâche",
"archivedToast": "Tâche archivée.",
"kanbanArchived": "Archivé",
"reminderNeedsDueDate": "Définissez une date d'échéance pour activer les rappels de tâche."
},
"shopping": {
"title": "Courses",
@@ -903,38 +908,38 @@
"title": "Documents",
"addButton": "Ajouter un document",
"searchPlaceholder": "Rechercher des documents...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Vue en grille",
"listView": "Vue en liste",
"viewToggle": "Vue des documents",
"allCategories": "Toutes les catégories",
"emptyTitle": "Aucun document pour le moment",
"emptyDescription": "Ajoutez des documents familiaux et contrôlez qui peut voir chaque fichier.",
"newTitle": "Nouveau document",
"editTitle": "Paramètres du document",
"nameLabel": "Name",
"nameLabel": "Nom",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"categoryLabel": "Catégorie",
"fileLabel": "Fichier",
"fileHint": "PDF, images, texte et fichiers Office jusqu'à 5 Mo.",
"visibilityLabel": "Visibilité",
"statusLabel": "Statut",
"allowedMembersLabel": "Membres autorisés",
"uploadAction": "Téléverser",
"downloadAction": "Télécharger",
"editAction": "Paramètres",
"archiveAction": "Archiver",
"restoreAction": "Restaurer",
"savedToast": "Document enregistré.",
"uploadedToast": "Document téléversé.",
"archivedToast": "Document archivé.",
"restoredToast": "Document restauré.",
"deletedToast": "Document supprimé.",
"deleteConfirm": "Supprimer le document \"{{name}}\" ?",
"fileRequired": "Sélectionnez un fichier à téléverser.",
"fileTooLarge": "Le fichier ne peut pas dépasser 5 Mo.",
"fileReadError": "Impossible de lire le fichier.",
"statusActive": "Actif",
"statusArchived": "Archivé",
"visibility": {
"family": "Toute la famille",
"restricted": "Membres sélectionnés",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "प्राथमिकता",
"filterGroupStatus": "स्थिति",
"swipedDoneToast": "पूर्ण के रूप में चिह्नित।",
"swipedOpenToast": "खुले के रूप में चिह्नित।"
"swipedOpenToast": "खुले के रूप में चिह्नित।",
"statusArchived": "संग्रहित",
"archiveButton": "कार्य संग्रहित करें",
"archivedToast": "कार्य संग्रहित किया गया।",
"kanbanArchived": "संग्रहित",
"reminderNeedsDueDate": "कार्य अनुस्मारक सक्षम करने के लिए एक नियत तारीख निर्धारित करें।"
},
"shopping": {
"title": "खरीदारी",
@@ -903,38 +908,38 @@
"title": "दस्तावेज़",
"addButton": "दस्तावेज़ जोड़ें",
"searchPlaceholder": "दस्तावेज़ खोजें...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "ग्रिड व्यू",
"listView": "सूची व्यू",
"viewToggle": "दस्तावेज़ व्यू",
"allCategories": "सभी श्रेणियाँ",
"emptyTitle": "अभी कोई दस्तावेज़ नहीं",
"emptyDescription": "परिवार के दस्तावेज़ अपलोड करें और तय करें कि हर फ़ाइल कौन देख सकता है।",
"newTitle": "नया दस्तावेज़",
"editTitle": "दस्तावेज़ सेटिंग्स",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "नाम",
"descriptionLabel": "विवरण",
"categoryLabel": "श्रेणी",
"fileLabel": "फ़ाइल",
"fileHint": "PDF, चित्र, टेक्स्ट और Office फ़ाइलें 5 MB तक।",
"visibilityLabel": "दृश्यता",
"statusLabel": "स्थिति",
"allowedMembersLabel": "अनुमत सदस्य",
"uploadAction": "अपलोड करें",
"downloadAction": "डाउनलोड करें",
"editAction": "सेटिंग्स",
"archiveAction": "संग्रहित करें",
"restoreAction": "पुनर्स्थापित करें",
"savedToast": "दस्तावेज़ सहेजा गया।",
"uploadedToast": "दस्तावेज़ अपलोड किया गया।",
"archivedToast": "दस्तावेज़ संग्रहित किया गया।",
"restoredToast": "दस्तावेज़ पुनर्स्थापित किया गया।",
"deletedToast": "दस्तावेज़ हटाया गया।",
"deleteConfirm": "दस्तावेज़ \"{{name}}\" हटाएं?",
"fileRequired": "अपलोड करने के लिए एक फ़ाइल चुनें।",
"fileTooLarge": "फ़ाइल अधिकतम 5 MB हो सकती है।",
"fileReadError": "फ़ाइल पढ़ी नहीं जा सकी।",
"statusActive": "सक्रिय",
"statusArchived": "संग्रहित",
"visibility": {
"family": "पूरा परिवार",
"restricted": "चुने हुए सदस्य",
+32 -27
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Priorità",
"filterGroupStatus": "Stato",
"swipedDoneToast": "Contrassegnato come fatto.",
"swipedOpenToast": "Contrassegnato come aperto."
"swipedOpenToast": "Contrassegnato come aperto.",
"statusArchived": "Archiviato",
"archiveButton": "Archivia attività",
"archivedToast": "Attività archiviata.",
"kanbanArchived": "Archiviato",
"reminderNeedsDueDate": "Imposta una data di scadenza per abilitare i promemoria delle attività."
},
"shopping": {
"title": "Spesa",
@@ -903,38 +908,38 @@
"title": "Documenti",
"addButton": "Aggiungi documento",
"searchPlaceholder": "Cerca documenti...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Vista griglia",
"listView": "Vista elenco",
"viewToggle": "Vista documenti",
"allCategories": "Tutte le categorie",
"emptyTitle": "Nessun documento",
"emptyDescription": "Carica documenti di famiglia e controlla chi può vedere ogni file.",
"newTitle": "Nuovo documento",
"editTitle": "Impostazioni documento",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"nameLabel": "Nome",
"descriptionLabel": "Descrizione",
"categoryLabel": "Categoria",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"fileHint": "PDF, immagini, testo e file Office fino a 5 MB.",
"visibilityLabel": "Visibilità",
"statusLabel": "Stato",
"allowedMembersLabel": "Membri autorizzati",
"uploadAction": "Carica",
"downloadAction": "Scarica",
"editAction": "Impostazioni",
"archiveAction": "Archivia",
"restoreAction": "Ripristina",
"savedToast": "Documento salvato.",
"uploadedToast": "Documento caricato.",
"archivedToast": "Documento archiviato.",
"restoredToast": "Documento ripristinato.",
"deletedToast": "Documento eliminato.",
"deleteConfirm": "Eliminare il documento \"{{name}}\"?",
"fileRequired": "Seleziona un file da caricare.",
"fileTooLarge": "Il file può essere al massimo 5 MB.",
"fileReadError": "Impossibile leggere il file.",
"statusActive": "Attivo",
"statusArchived": "Archiviato",
"visibility": {
"family": "Tutta la famiglia",
"restricted": "Membri selezionati",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "優先度",
"filterGroupStatus": "ステータス",
"swipedDoneToast": "完了としてマーク。",
"swipedOpenToast": "未完了としてマーク。"
"swipedOpenToast": "未完了としてマーク。",
"statusArchived": "アーカイブ済み",
"archiveButton": "タスクをアーカイブ",
"archivedToast": "タスクをアーカイブしました。",
"kanbanArchived": "アーカイブ済み",
"reminderNeedsDueDate": "タスクのリマインダーを有効にするには期日を設定してください。"
},
"shopping": {
"title": "買い物",
@@ -903,38 +908,38 @@
"title": "書類",
"addButton": "書類を追加",
"searchPlaceholder": "書類を検索...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "グリッド表示",
"listView": "リスト表示",
"viewToggle": "ドキュメント表示",
"allCategories": "すべてのカテゴリ",
"emptyTitle": "書類はまだありません",
"emptyDescription": "家族の書類をアップロードし、各ファイルを見られるメンバーを管理できます。",
"newTitle": "新しい書類",
"editTitle": "書類設定",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "名前",
"descriptionLabel": "説明",
"categoryLabel": "カテゴリ",
"fileLabel": "ファイル",
"fileHint": "PDF、画像、テキスト、Officeファイル(5MBまで)。",
"visibilityLabel": "公開範囲",
"statusLabel": "ステータス",
"allowedMembersLabel": "許可メンバー",
"uploadAction": "アップロード",
"downloadAction": "ダウンロード",
"editAction": "設定",
"archiveAction": "アーカイブ",
"restoreAction": "復元",
"savedToast": "ドキュメントを保存しました。",
"uploadedToast": "ドキュメントをアップロードしました。",
"archivedToast": "ドキュメントをアーカイブしました。",
"restoredToast": "ドキュメントを復元しました。",
"deletedToast": "ドキュメントを削除しました。",
"deleteConfirm": "ドキュメント「{{name}}」を削除しますか?",
"fileRequired": "アップロードするファイルを選択してください。",
"fileTooLarge": "ファイルは5MB以下である必要があります。",
"fileReadError": "ファイルを読み込めませんでした。",
"statusActive": "有効",
"statusArchived": "アーカイブ済み",
"visibility": {
"family": "家族全員",
"restricted": "選択したメンバー",
+1 -1
View File
@@ -923,7 +923,7 @@
"fileLabel": "Arquivo",
"fileHint": "PDF, imagens, texto e arquivos Office ate 5 MB.",
"visibilityLabel": "Visibilidade",
"statusLabel": "Status",
"statusLabel": "Estado",
"allowedMembersLabel": "Membros permitidos",
"uploadAction": "Enviar",
"downloadAction": "Baixar",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Приоритет",
"filterGroupStatus": "Статус",
"swipedDoneToast": "Отмечено как выполненное.",
"swipedOpenToast": "Отмечено как открытое."
"swipedOpenToast": "Отмечено как открытое.",
"statusArchived": "Архивирована",
"archiveButton": "Архивировать задачу",
"archivedToast": "Задача архивирована.",
"kanbanArchived": "Архивировано",
"reminderNeedsDueDate": "Установите срок выполнения, чтобы включить напоминания о задаче."
},
"shopping": {
"title": "Покупки",
@@ -903,38 +908,38 @@
"title": "Документы",
"addButton": "Добавить документ",
"searchPlaceholder": "Поиск документов...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Сетка",
"listView": "Список",
"viewToggle": "Вид документов",
"allCategories": "Все категории",
"emptyTitle": "Документов пока нет",
"emptyDescription": "Загружайте семейные документы и управляйте доступом к каждому файлу.",
"newTitle": "Новый документ",
"editTitle": "Настройки документа",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "Название",
"descriptionLabel": "Описание",
"categoryLabel": "Категория",
"fileLabel": "Файл",
"fileHint": "PDF, изображения, текст и файлы Office до 5 МБ.",
"visibilityLabel": "Видимость",
"statusLabel": "Статус",
"allowedMembersLabel": "Разрешённые участники",
"uploadAction": "Загрузить",
"downloadAction": "Скачать",
"editAction": "Настройки",
"archiveAction": "Архивировать",
"restoreAction": "Восстановить",
"savedToast": "Документ сохранён.",
"uploadedToast": "Документ загружен.",
"archivedToast": "Документ архивирован.",
"restoredToast": "Документ восстановлен.",
"deletedToast": "Документ удалён.",
"deleteConfirm": "Удалить документ «{{name}}»?",
"fileRequired": "Выберите файл для загрузки.",
"fileTooLarge": "Файл может быть не более 5 МБ.",
"fileReadError": "Не удалось прочитать файл.",
"statusActive": "Активный",
"statusArchived": "Архивированный",
"visibility": {
"family": "Вся семья",
"restricted": "Выбранные участники",
+32 -27
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Prioritet",
"filterGroupStatus": "Status",
"swipedDoneToast": "Markerad som klar.",
"swipedOpenToast": "Markerad som öppen."
"swipedOpenToast": "Markerad som öppen.",
"statusArchived": "Arkiverad",
"archiveButton": "Arkivera uppgift",
"archivedToast": "Uppgiften arkiverades.",
"kanbanArchived": "Arkiverad",
"reminderNeedsDueDate": "Ange ett förfallodatum för att aktivera påminnelser för uppgiften."
},
"shopping": {
"title": "Shopping",
@@ -903,38 +908,38 @@
"title": "Dokument",
"addButton": "Lägg till dokument",
"searchPlaceholder": "Sök dokument...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Rutnätsvy",
"listView": "Listvy",
"viewToggle": "Dokumentvy",
"allCategories": "Alla kategorier",
"emptyTitle": "Inga dokument ännu",
"emptyDescription": "Ladda upp familjedokument och styr vem som kan se varje fil.",
"newTitle": "Nytt dokument",
"editTitle": "Dokumentinställningar",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"nameLabel": "Namn",
"descriptionLabel": "Beskrivning",
"categoryLabel": "Kategori",
"fileLabel": "Fil",
"fileHint": "PDF, bilder, text och Office-filer upp till 5 MB.",
"visibilityLabel": "Synlighet",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"allowedMembersLabel": "Tillåtna medlemmar",
"uploadAction": "Ladda upp",
"downloadAction": "Ladda ner",
"editAction": "Inställningar",
"archiveAction": "Arkivera",
"restoreAction": "Återställ",
"savedToast": "Dokumentet sparades.",
"uploadedToast": "Dokumentet laddades upp.",
"archivedToast": "Dokumentet arkiverades.",
"restoredToast": "Dokumentet återställdes.",
"deletedToast": "Dokumentet raderades.",
"deleteConfirm": "Ta bort dokument \"{{name}}\"?",
"fileRequired": "Välj en fil att ladda upp.",
"fileTooLarge": "Filen får vara högst 5 MB.",
"fileReadError": "Filen kunde inte läsas.",
"statusActive": "Aktiv",
"statusArchived": "Arkiverad",
"visibility": {
"family": "Hela familjen",
"restricted": "Valda medlemmar",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Öncelik",
"filterGroupStatus": "Durum",
"swipedDoneToast": "Tamamlandı olarak işaretlendi.",
"swipedOpenToast": "Açık olarak işaretlendi."
"swipedOpenToast": "Açık olarak işaretlendi.",
"statusArchived": "Arşivlenmiş",
"archiveButton": "Görevi arşivle",
"archivedToast": "Görev arşivlendi.",
"kanbanArchived": "Arşivlenmiş",
"reminderNeedsDueDate": "Görev hatırlatıcılarını etkinleştirmek için bir son tarih belirleyin."
},
"shopping": {
"title": "Alışveriş",
@@ -903,38 +908,38 @@
"title": "Belgeler",
"addButton": "Belge ekle",
"searchPlaceholder": "Belgelerde ara...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Izgara görünümü",
"listView": "Liste görünümü",
"viewToggle": "Belge görünümü",
"allCategories": "Tüm kategoriler",
"emptyTitle": "Henüz belge yok",
"emptyDescription": "Aile belgelerini yükleyin ve her dosyayı kimlerin görebileceğini yönetin.",
"newTitle": "Yeni belge",
"editTitle": "Belge ayarları",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "Ad",
"descriptionLabel": "Açıklama",
"categoryLabel": "Kategori",
"fileLabel": "Dosya",
"fileHint": "PDF, resimler, metin ve Office dosyaları en fazla 5 MB.",
"visibilityLabel": "Görünürlük",
"statusLabel": "Durum",
"allowedMembersLabel": "İzin verilen üyeler",
"uploadAction": "Yükle",
"downloadAction": "İndir",
"editAction": "Ayarlar",
"archiveAction": "Arşivle",
"restoreAction": "Geri yükle",
"savedToast": "Belge kaydedildi.",
"uploadedToast": "Belge yüklendi.",
"archivedToast": "Belge arşivlendi.",
"restoredToast": "Belge geri yüklendi.",
"deletedToast": "Belge silindi.",
"deleteConfirm": "\"{{name}}\" belgesini sil?",
"fileRequired": "Yüklemek için bir dosya seçin.",
"fileTooLarge": "Dosya en fazla 5 MB olabilir.",
"fileReadError": "Dosya okunamadı.",
"statusActive": "Aktif",
"statusArchived": "Arşivlenmiş",
"visibility": {
"family": "Tüm aile",
"restricted": "Seçili üyeler",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "Пріоритет",
"filterGroupStatus": "Статус",
"swipedDoneToast": "Позначено як виконане.",
"swipedOpenToast": "Позначено як відкрите."
"swipedOpenToast": "Позначено як відкрите.",
"statusArchived": "Архівована",
"archiveButton": "Архівувати завдання",
"archivedToast": "Завдання архівовано.",
"kanbanArchived": "Архівовано",
"reminderNeedsDueDate": "Встановіть дату виконання, щоб увімкнути нагадування про завдання."
},
"shopping": {
"title": "Покупки",
@@ -911,38 +916,38 @@
"title": "Документи",
"addButton": "Додати документ",
"searchPlaceholder": "Пошук документів...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "Сітка",
"listView": "Список",
"viewToggle": "Вигляд документів",
"allCategories": "Усі категорії",
"emptyTitle": "Документів ще немає",
"emptyDescription": "Завантажуйте сімейні документи та керуйте доступом до кожного файлу.",
"newTitle": "Новий документ",
"editTitle": "Налаштування документа",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "Назва",
"descriptionLabel": "Опис",
"categoryLabel": "Категорія",
"fileLabel": "Файл",
"fileHint": "PDF, зображення, текст та файли Office до 5 МБ.",
"visibilityLabel": "Видимість",
"statusLabel": "Статус",
"allowedMembersLabel": "Дозволені учасники",
"uploadAction": "Завантажити",
"downloadAction": "Завантажити",
"editAction": "Налаштування",
"archiveAction": "Архівувати",
"restoreAction": "Відновити",
"savedToast": "Документ збережено.",
"uploadedToast": "Документ завантажено.",
"archivedToast": "Документ архівовано.",
"restoredToast": "Документ відновлено.",
"deletedToast": "Документ видалено.",
"deleteConfirm": "Видалити документ «{{name}}»?",
"fileRequired": "Виберіть файл для завантаження.",
"fileTooLarge": "Файл може бути не більше 5 МБ.",
"fileReadError": "Не вдалося прочитати файл.",
"statusActive": "Активний",
"statusArchived": "Архівований",
"visibility": {
"family": "Уся сім’я",
"restricted": "Вибрані учасники",
+33 -28
View File
@@ -180,7 +180,12 @@
"filterGroupPriority": "优先级",
"filterGroupStatus": "状态",
"swipedDoneToast": "已标记为完成。",
"swipedOpenToast": "已标记为未完成。"
"swipedOpenToast": "已标记为未完成。",
"statusArchived": "已归档",
"archiveButton": "归档任务",
"archivedToast": "任务已归档。",
"kanbanArchived": "已归档",
"reminderNeedsDueDate": "设置截止日期以启用任务提醒。"
},
"shopping": {
"title": "购物",
@@ -903,38 +908,38 @@
"title": "文档",
"addButton": "添加文档",
"searchPlaceholder": "搜索文档...",
"gridView": "Grid view",
"listView": "List view",
"viewToggle": "Document view",
"gridView": "网格视图",
"listView": "列表视图",
"viewToggle": "文档视图",
"allCategories": "所有类别",
"emptyTitle": "还没有文档",
"emptyDescription": "上传家庭文档并控制每个文件的可见成员。",
"newTitle": "新文档",
"editTitle": "文档设置",
"nameLabel": "Name",
"descriptionLabel": "Description",
"categoryLabel": "Category",
"fileLabel": "File",
"fileHint": "PDF, images, text and Office files up to 5 MB.",
"visibilityLabel": "Visibility",
"statusLabel": "Status",
"allowedMembersLabel": "Allowed members",
"uploadAction": "Upload",
"downloadAction": "Download",
"editAction": "Settings",
"archiveAction": "Archive",
"restoreAction": "Restore",
"savedToast": "Document saved.",
"uploadedToast": "Document uploaded.",
"archivedToast": "Document archived.",
"restoredToast": "Document restored.",
"deletedToast": "Document deleted.",
"deleteConfirm": "Delete document \"{{name}}\"?",
"fileRequired": "Select a file to upload.",
"fileTooLarge": "File may be at most 5 MB.",
"fileReadError": "File could not be read.",
"statusActive": "Active",
"statusArchived": "Archived",
"nameLabel": "名称",
"descriptionLabel": "描述",
"categoryLabel": "类别",
"fileLabel": "文件",
"fileHint": "PDF、图片、文本和Office文件,最大5 MB",
"visibilityLabel": "可见性",
"statusLabel": "状态",
"allowedMembersLabel": "允许的成员",
"uploadAction": "上传",
"downloadAction": "下载",
"editAction": "设置",
"archiveAction": "归档",
"restoreAction": "恢复",
"savedToast": "文档已保存。",
"uploadedToast": "文档已上传。",
"archivedToast": "文档已归档。",
"restoredToast": "文档已恢复。",
"deletedToast": "文档已删除。",
"deleteConfirm": "删除文档\"{{name}}\"",
"fileRequired": "请选择要上传的文件。",
"fileTooLarge": "文件最大为5 MB",
"fileReadError": "无法读取文件。",
"statusActive": "活跃",
"statusArchived": "已归档",
"visibility": {
"family": "整个家庭",
"restricted": "选定成员",
+41 -12
View File
@@ -131,7 +131,7 @@ let _pendingLoginRedirect = false;
const ROUTE_ORDER = ['/', '/tasks', '/calendar', '/birthdays', '/meals', '/recipes', '/shopping',
'/notes', '/contacts', '/budget', '/documents', '/settings'];
const PRIMARY_NAV = 4;
const PRIMARY_NAV = 3;
const DEFAULT_APP_NAME = 'Oikos';
const APP_NAME_STORAGE_KEY = 'oikos-app-name';
@@ -350,20 +350,12 @@ async function renderPage(route, previousPath = null) {
// Richtung bestimmen (previousPath ist der alte Pfad vor der Navigation)
const direction = getDirection(previousPath, route.path);
const outClass = direction === 'right' ? 'page-transition--out-left' : 'page-transition--out-right';
const inClass = direction === 'right' ? 'page-transition--in-right' : 'page-transition--in-left';
// Performance: backdrop-filter während Übergang deaktivieren (Android-Optimierung).
// glass.css setzt alle backdrop-filter im app-content auf none solange diese Klasse aktiv ist.
document.documentElement.classList.add('navigating');
// Alte Seite kurz ausfaden, falls vorhanden
const oldPage = content.querySelector('.page-transition');
if (oldPage) {
oldPage.classList.add(outClass);
await new Promise(r => setTimeout(r, 120));
}
// Alter Inhalt ist jetzt weg - altes Stylesheet kann entfernt werden
const pageWrapper = document.createElement('div');
pageWrapper.className = 'page-transition';
@@ -486,6 +478,20 @@ function renderAppShell(container) {
const bottomItems = document.createElement('div');
bottomItems.className = 'nav-bottom__items';
navItems().slice(0, PRIMARY_NAV).forEach((item) => bottomItems.appendChild(navItemEl(item)));
const searchNavBtn = document.createElement('button');
searchNavBtn.className = 'nav-item nav-item--search';
searchNavBtn.id = 'search-nav-btn';
searchNavBtn.setAttribute('aria-label', t('search.title'));
const searchNavIcon = document.createElement('i');
searchNavIcon.dataset.lucide = 'search';
searchNavIcon.className = 'nav-item__icon';
searchNavIcon.setAttribute('aria-hidden', 'true');
const searchNavLabel = document.createElement('span');
searchNavLabel.className = 'nav-item__label';
searchNavLabel.textContent = t('search.title');
searchNavBtn.appendChild(searchNavIcon);
searchNavBtn.appendChild(searchNavLabel);
bottomItems.appendChild(searchNavBtn);
const moreBtn = document.createElement('button');
moreBtn.className = 'nav-item nav-item--more';
moreBtn.id = 'more-btn';
@@ -758,6 +764,7 @@ function initMoreSheet(container) {
*/
function initSearch(container) {
const searchBtn = container.querySelector('#search-btn');
const searchNavBtn = container.querySelector('#search-nav-btn');
const searchClose = container.querySelector('#search-close');
const overlay = container.querySelector('#search-overlay');
const input = container.querySelector('#search-input');
@@ -770,6 +777,7 @@ function initSearch(container) {
let _searchTrapHandler = null;
function openSearch() {
window._openSearch = openSearch;
if (window._closeMoreSheet) window._closeMoreSheet();
overlay.setAttribute('aria-hidden', 'false');
overlay.classList.add('search-overlay--visible');
@@ -804,6 +812,7 @@ function initSearch(container) {
}
searchBtn.addEventListener('click', openSearch);
if (searchNavBtn) searchNavBtn.addEventListener('click', openSearch);
searchClose.addEventListener('click', closeSearch);
document.addEventListener('keydown', (e) => {
@@ -880,11 +889,11 @@ function navItems() {
return [
{ path: '/', label: t('nav.dashboard'), icon: 'layout-dashboard' },
{ path: '/tasks', label: t('nav.tasks'), icon: 'check-square' },
{ path: '/birthdays', label: t('nav.birthdays'), icon: 'cake' },
{ path: '/calendar', label: t('nav.calendar'), icon: 'calendar' },
{ path: '/shopping', label: t('nav.shopping'), icon: 'shopping-cart' },
{ path: '/meals', label: t('nav.meals'), icon: 'utensils' },
{ path: '/recipes', label: t('nav.recipes'), icon: 'book-text' },
{ path: '/shopping', label: t('nav.shopping'), icon: 'shopping-cart' },
{ path: '/birthdays', label: t('nav.birthdays'), icon: 'cake' },
{ path: '/notes', label: t('nav.notes'), icon: 'sticky-note' },
{ path: '/contacts', label: t('nav.contacts'), icon: 'book-user' },
{ path: '/budget', label: t('nav.budget'), icon: 'wallet' },
@@ -1128,7 +1137,27 @@ window.addEventListener('locale-changed', () => {
if (bottomItems) {
const moreBtn = bottomItems.querySelector('#more-btn');
const newItems = navItems().slice(0, PRIMARY_NAV).map(navItemEl);
bottomItems.replaceChildren(...newItems, moreBtn);
// Such-Button neu erstellen (wird durch replaceChildren entfernt)
const newSearchBtn = document.createElement('button');
newSearchBtn.className = 'nav-item nav-item--search';
newSearchBtn.id = 'search-nav-btn';
newSearchBtn.setAttribute('aria-label', t('search.title'));
const newSearchIcon = document.createElement('i');
newSearchIcon.dataset.lucide = 'search';
newSearchIcon.className = 'nav-item__icon';
newSearchIcon.setAttribute('aria-hidden', 'true');
const newSearchLbl = document.createElement('span');
newSearchLbl.className = 'nav-item__label';
newSearchLbl.textContent = t('search.title');
newSearchBtn.appendChild(newSearchIcon);
newSearchBtn.appendChild(newSearchLbl);
bottomItems.replaceChildren(...newItems, newSearchBtn, moreBtn);
// Event-Listener auf neuen Such-Button
if (newSearchBtn) {
newSearchBtn.addEventListener('click', () => {
if (window._openSearch) window._openSearch();
});
}
}
if (moreSheet) {
const searchBtn = moreSheet.querySelector('#search-btn');
+58 -1
View File
@@ -80,6 +80,11 @@
to { opacity: 0; transform: translateX(20px); }
}
@keyframes page-crossfade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.page-transition--in-right {
animation: page-slide-in-right 0.2s var(--ease-out);
}
@@ -95,6 +100,11 @@
pointer-events: none;
}
.page-transition--crossfade {
animation: page-crossfade-in 0.18s var(--ease-out);
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.page-transition--in-right,
.page-transition--in-left {
@@ -105,6 +115,10 @@
.page-transition--out-right {
animation: none;
}
.page-transition--crossfade {
animation: none;
opacity: 1;
}
}
/* --------------------------------------------------------
@@ -144,6 +158,11 @@
z-index: var(--z-nav);
backdrop-filter: var(--blur-md) saturate(180%);
-webkit-backdrop-filter: var(--blur-md) saturate(180%);
transition: transform 0.2s var(--ease-out);
}
.nav-bottom--hidden {
transform: translateY(100%);
}
/* ── Items-Reihe ── */
@@ -197,7 +216,7 @@
padding: var(--space-4) var(--space-4) calc(var(--space-4) + var(--safe-area-inset-bottom));
z-index: calc(var(--z-nav) + 2);
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(3, 1fr);
gap: var(--space-3);
transform: translateY(100%);
transition: transform 0.25s var(--ease-out);
@@ -644,6 +663,38 @@
}
}
/* Tooltip für collapsed Sidebar (nur Icons sichtbar bei 10241439px) */
@media (min-width: 1024px) and (max-width: 1439px) {
.nav-sidebar .nav-item {
overflow: visible;
}
.nav-sidebar .nav-item::after {
content: attr(title);
position: absolute;
left: calc(var(--sidebar-width) + var(--space-2));
top: 50%;
transform: translateY(-50%);
background: var(--color-surface);
color: var(--color-text-primary);
padding: var(--space-1) var(--space-3);
border-radius: var(--radius-sm);
box-shadow: var(--shadow-md);
border: 1px solid var(--color-border-subtle);
white-space: nowrap;
font-size: var(--text-sm);
font-weight: var(--font-weight-medium);
pointer-events: none;
opacity: 0;
transition: opacity 0.15s ease;
z-index: calc(var(--z-nav) + 10);
}
.nav-sidebar .nav-item:hover::after {
opacity: 1;
}
}
/* ================================================================
* Sidebar Expanded (≥ 1280px) - Labels sichtbar
* ================================================================ */
@@ -1590,6 +1641,12 @@
width: min(calc(100% - var(--space-8)), 380px);
}
@media (min-width: 768px) and (max-width: 1023px) {
.toast-container {
bottom: var(--space-8);
}
}
@media (min-width: 1024px) {
.toast-container {
bottom: var(--space-6);