release: v0.31.0 — family-contacts integration & settings restructure
- Family member records now store phone, email, and birthday, auto-synced to Contacts and Birthdays modules (PR #99 by @rafaelfoster) - Settings gets dedicated Family and API Tokens tabs (admin-only) - Avatar editor redesigned with icon buttons; tab bar fits standard width - Dentist calendar icon normalised to 'tooth'; theme reset bug fixed - i18n: missing family field translations added to 12 locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.31.0] - 2026-04-29
|
||||
|
||||
### Added
|
||||
- Family: phone, email, and birthday fields on family member records, automatically synced to Contacts and Birthdays
|
||||
- Settings: dedicated "Family Management" tab (admin-only) for managing family members including contact details
|
||||
- Settings: dedicated "API Tokens" tab (admin-only) for token management
|
||||
- Calendar: local tooth SVG icon for dentist events replaces the drill icon (migration 24 restores tooth icon for existing events)
|
||||
- i18n: `reset`, `tabFamily`, `tabApiTokens`, and family member field keys translated in all 15 locales
|
||||
|
||||
### Changed
|
||||
- Settings: avatar editor uses icon buttons instead of a file input label for a cleaner UX
|
||||
- Settings: tab bar constrained to standard app width so all tabs fit in one row on desktop
|
||||
- Family members page moved from Account tab to its own Family tab (admin only); Account tab stays focused on personal profile and password
|
||||
|
||||
### Fixed
|
||||
- Theme toggle: `data-theme` attribute removed when reset to system default (previously left stale)
|
||||
- Calendar: dentist icon normalised — `tooth` is now the canonical stored value (`drill` accepted as alias for backwards compatibility)
|
||||
- i18n: missing translations for family member fields added to ar, el, es, fr, hi, it, ja, ru, sv, tr, uk, zh
|
||||
|
||||
## [0.30.3] - 2026-04-28
|
||||
|
||||
### Changed
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "oikos",
|
||||
"version": "0.30.3",
|
||||
"version": "0.31.0",
|
||||
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
|
||||
"main": "server/index.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "مشترك"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "رقم الهاتف (اختياري)",
|
||||
"memberEmailLabel": "البريد الإلكتروني (اختياري)",
|
||||
"memberBirthDateLabel": "تاريخ الميلاد (اختياري)",
|
||||
"memberContactBirthdayHint": "تتم مزامنة هذا العضو تلقائيًا مع جهات الاتصال وأعياد الميلاد.",
|
||||
"memberBirthDateInvalid": "استخدم تاريخ ميلاد صحيحًا بالتنسيق المحدد.",
|
||||
"memberPhoneMeta": "الهاتف: {{value}}",
|
||||
"memberBirthdayMeta": "عيد الميلاد: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "تخطيط عائلي. آمن. يحترم الخصوصية. مفتوح المصدر.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Κοινόχρηστο"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Αριθμός τηλεφώνου (προαιρετικό)",
|
||||
"memberEmailLabel": "Email (προαιρετικό)",
|
||||
"memberBirthDateLabel": "Ημερομηνία γέννησης (προαιρετικό)",
|
||||
"memberContactBirthdayHint": "Αυτό το μέλος συγχρονίζεται αυτόματα με τις Επαφές και τα Γενέθλια.",
|
||||
"memberBirthDateInvalid": "Χρησιμοποιήστε μια έγκυρη ημερομηνία γέννησης στην επιλεγμένη μορφή.",
|
||||
"memberPhoneMeta": "Τηλέφωνο: {{value}}",
|
||||
"memberBirthdayMeta": "Γενέθλια: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Οικογενειακός προγραμματισμός. Ασφαλής. Φιλικός προς την ιδιωτικότητα. Ανοιχτός κώδικας.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Compartido"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Número de teléfono (opcional)",
|
||||
"memberEmailLabel": "Correo electrónico (opcional)",
|
||||
"memberBirthDateLabel": "Fecha de nacimiento (opcional)",
|
||||
"memberContactBirthdayHint": "Este miembro se sincroniza automáticamente con Contactos y Cumpleaños.",
|
||||
"memberBirthDateInvalid": "Usa una fecha de nacimiento válida en el formato seleccionado.",
|
||||
"memberPhoneMeta": "Teléfono: {{value}}",
|
||||
"memberBirthdayMeta": "Cumpleaños: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Planificación familiar. Segura. Privada. Código abierto.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Partagé"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Numéro de téléphone (facultatif)",
|
||||
"memberEmailLabel": "E-mail (facultatif)",
|
||||
"memberBirthDateLabel": "Date de naissance (facultatif)",
|
||||
"memberContactBirthdayHint": "Ce membre est automatiquement synchronisé avec les Contacts et les Anniversaires.",
|
||||
"memberBirthDateInvalid": "Utilisez une date de naissance valide dans le format sélectionné.",
|
||||
"memberPhoneMeta": "Téléphone : {{value}}",
|
||||
"memberBirthdayMeta": "Anniversaire : {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Planification familiale. Sécurisée. Respectueuse de la vie privée. Open source.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "साझा"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "फ़ोन नंबर (वैकल्पिक)",
|
||||
"memberEmailLabel": "ईमेल (वैकल्पिक)",
|
||||
"memberBirthDateLabel": "जन्म तिथि (वैकल्पिक)",
|
||||
"memberContactBirthdayHint": "यह सदस्य स्वचालित रूप से संपर्क और जन्मदिन के साथ समन्वयित होता है।",
|
||||
"memberBirthDateInvalid": "चयनित दिनांक प्रारूप में एक मान्य जन्म तिथि का उपयोग करें।",
|
||||
"memberPhoneMeta": "फ़ोन: {{value}}",
|
||||
"memberBirthdayMeta": "जन्मदिन: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "पारिवारिक योजना। सुरक्षित। गोपनीयता-अनुकूल। ओपन सोर्स।",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Condiviso"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Numero di telefono (opzionale)",
|
||||
"memberEmailLabel": "E-mail (opzionale)",
|
||||
"memberBirthDateLabel": "Data di nascita (opzionale)",
|
||||
"memberContactBirthdayHint": "Questo membro viene sincronizzato automaticamente con i Contatti e i Compleanni.",
|
||||
"memberBirthDateInvalid": "Usa una data di nascita valida nel formato selezionato.",
|
||||
"memberPhoneMeta": "Telefono: {{value}}",
|
||||
"memberBirthdayMeta": "Compleanno: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Pianificazione familiare. Sicura. Rispettosa della privacy. Open source.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "共有"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "電話番号(任意)",
|
||||
"memberEmailLabel": "メールアドレス(任意)",
|
||||
"memberBirthDateLabel": "生年月日(任意)",
|
||||
"memberContactBirthdayHint": "このメンバーは連絡先と誕生日と自動的に同期されます。",
|
||||
"memberBirthDateInvalid": "選択した日付形式で有効な生年月日を入力してください。",
|
||||
"memberPhoneMeta": "電話: {{value}}",
|
||||
"memberBirthdayMeta": "誕生日: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "家族計画。安全。プライバシー重視。オープンソース。",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Общее"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Номер телефона (необязательно)",
|
||||
"memberEmailLabel": "Электронная почта (необязательно)",
|
||||
"memberBirthDateLabel": "Дата рождения (необязательно)",
|
||||
"memberContactBirthdayHint": "Этот участник автоматически синхронизируется с контактами и днями рождения.",
|
||||
"memberBirthDateInvalid": "Используйте действительную дату рождения в выбранном формате.",
|
||||
"memberPhoneMeta": "Телефон: {{value}}",
|
||||
"memberBirthdayMeta": "День рождения: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Семейное планирование. Безопасно. С уважением к приватности. Открытый исходный код.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Delad"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Telefonnummer (valfritt)",
|
||||
"memberEmailLabel": "E-post (valfritt)",
|
||||
"memberBirthDateLabel": "Födelsedatum (valfritt)",
|
||||
"memberContactBirthdayHint": "Den här medlemmen synkroniseras automatiskt med Kontakter och Födelsedagar.",
|
||||
"memberBirthDateInvalid": "Använd ett giltigt födelsedatum i det valda datumformatet.",
|
||||
"memberPhoneMeta": "Telefon: {{value}}",
|
||||
"memberBirthdayMeta": "Födelsedag: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Familjeplanering. Säker. Sekretessvänlig. Öppen källkod.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Paylaşımlı"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Telefon numarası (isteğe bağlı)",
|
||||
"memberEmailLabel": "E-posta (isteğe bağlı)",
|
||||
"memberBirthDateLabel": "Doğum tarihi (isteğe bağlı)",
|
||||
"memberContactBirthdayHint": "Bu üye otomatik olarak Kişiler ve Doğum Günleri ile senkronize edilir.",
|
||||
"memberBirthDateInvalid": "Seçilen tarih formatında geçerli bir doğum tarihi kullanın.",
|
||||
"memberPhoneMeta": "Telefon: {{value}}",
|
||||
"memberBirthdayMeta": "Doğum günü: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Aile planlaması. Güvenli. Gizlilik dostu. Açık kaynak.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "Спільне"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "Номер телефону (необов'язково)",
|
||||
"memberEmailLabel": "Електронна пошта (необов'язково)",
|
||||
"memberBirthDateLabel": "Дата народження (необов'язково)",
|
||||
"memberContactBirthdayHint": "Цей учасник автоматично синхронізується з контактами та днями народження.",
|
||||
"memberBirthDateInvalid": "Використовуйте дійсну дату народження у вибраному форматі.",
|
||||
"memberPhoneMeta": "Телефон: {{value}}",
|
||||
"memberBirthdayMeta": "День народження: {{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "Планування для родини. Безпечно. Конфіденційно. Відкритий код.",
|
||||
|
||||
@@ -734,13 +734,13 @@
|
||||
"shared": "共享"
|
||||
}
|
||||
},
|
||||
"memberPhoneLabel": "Phone number (optional)",
|
||||
"memberEmailLabel": "Email (optional)",
|
||||
"memberBirthDateLabel": "Birthday date (optional)",
|
||||
"memberContactBirthdayHint": "This member is automatically synchronized with Contacts and Birthdays.",
|
||||
"memberBirthDateInvalid": "Use a valid birthday date in the selected date format.",
|
||||
"memberPhoneMeta": "Phone: {{value}}",
|
||||
"memberBirthdayMeta": "Birthday: {{date}}"
|
||||
"memberPhoneLabel": "电话号码(可选)",
|
||||
"memberEmailLabel": "电子邮件(可选)",
|
||||
"memberBirthDateLabel": "出生日期(可选)",
|
||||
"memberContactBirthdayHint": "此成员自动与联系人和生日同步。",
|
||||
"memberBirthDateInvalid": "请使用所选日期格式的有效出生日期。",
|
||||
"memberPhoneMeta": "电话:{{value}}",
|
||||
"memberBirthdayMeta": "生日:{{date}}"
|
||||
},
|
||||
"login": {
|
||||
"tagline": "家庭规划。安全。注重隐私。开源。",
|
||||
|
||||
Reference in New Issue
Block a user