55eca32db3
- Add Birthdays module: CRUD with calendar/reminder auto-sync, photo upload, age notes - Add DB migration 18 (birthdays table with calendar_event_id, trigger, indexes) - Add dashboard widgets: birthdays, family participants, budget overview - Add Settings > General: admins can set a custom app name (reflected in title/sidebar/login) - Improve service worker: network-first caching for mutable JS/CSS assets - Add translations for 16 locales (birthday keys) Fixes applied during integration: - innerHTML replaced with insertAdjacentHTML/replaceChildren throughout birthdays.js and dashboard.js - docker-compose.yml personal dev changes reverted Co-authored-by: Rafael Foster <rafaelgfoster@gmail.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
850 lines
30 KiB
JSON
850 lines
30 KiB
JSON
{
|
||
"common": {
|
||
"save": "Save",
|
||
"cancel": "Cancel",
|
||
"delete": "Delete",
|
||
"edit": "Edit",
|
||
"close": "Close",
|
||
"create": "Create",
|
||
"add": "Add",
|
||
"back": "Back",
|
||
"next": "Next",
|
||
"loading": "Loading…",
|
||
"saving": "Saving…",
|
||
"required": "This field is required.",
|
||
"error": "Error",
|
||
"allFieldsRequired": "Please fill in all fields.",
|
||
"today": "Today",
|
||
"tomorrow": "Tomorrow",
|
||
"skipToContent": "Skip to content",
|
||
"reload": "Reload",
|
||
"errorOccurred": "Something went wrong.",
|
||
"unexpectedError": "An unexpected error occurred.",
|
||
"errorGeneric": "An error occurred.",
|
||
"updateAvailable": "Update available - reload the page to get the latest version.",
|
||
"titleRequired": "Title is required",
|
||
"nameRequired": "Name is required",
|
||
"contentRequired": "Content is required",
|
||
"all": "All",
|
||
"unknownError": "Unknown error",
|
||
"confirm": "Confirm",
|
||
"undo": "Undo"
|
||
},
|
||
"nav": {
|
||
"dashboard": "Overview",
|
||
"tasks": "Tasks",
|
||
"calendar": "Calendar",
|
||
"meals": "Meals",
|
||
"shopping": "Shopping",
|
||
"notes": "Board",
|
||
"contacts": "Contacts",
|
||
"birthdays": "Birthdays",
|
||
"budget": "Budget",
|
||
"settings": "Settings",
|
||
"main": "Main navigation",
|
||
"navigation": "Navigation",
|
||
"quickActions": "Quick actions",
|
||
"recipes": "Recipes",
|
||
"more": "More"
|
||
},
|
||
"dashboard": {
|
||
"title": "Overview",
|
||
"greetingMorning": "Good morning, {{name}}",
|
||
"greetingDay": "Good afternoon, {{name}}",
|
||
"greetingEvening": "Good evening, {{name}}",
|
||
"allDone": "All done",
|
||
"noEvents": "No events",
|
||
"noPinnedNotes": "No pinned notes",
|
||
"todayMeals": "Today's meals",
|
||
"allLink": "All",
|
||
"weekLink": "Week",
|
||
"urgentTasksChip": "{{count}} task due soon",
|
||
"urgentTasksChipPlural": "{{count}} tasks due soon",
|
||
"eventsChip": "{{count}} event today",
|
||
"eventsChipPlural": "{{count}} events today",
|
||
"todayMealChip": "Today: {{title}}",
|
||
"loadError": "Dashboard could not be fully loaded.",
|
||
"weatherRefresh": "Refresh weather",
|
||
"weatherRefreshTitle": "Refresh",
|
||
"weatherUpdated": "Weather updated",
|
||
"weatherFeelsLike": "Feels like {{temp}}° · {{humidity}}% · Wind {{wind}} {{windUnit}}",
|
||
"fabTaskLabel": "Add task",
|
||
"fabCalendarLabel": "Add event",
|
||
"fabShoppingLabel": "Add shopping",
|
||
"fabNoteLabel": "Add note",
|
||
"fabTask": "Task",
|
||
"fabCalendar": "Event",
|
||
"fabShopping": "Shopping",
|
||
"fabNote": "Note",
|
||
"overdue": "Overdue",
|
||
"dueSoon": "Due today",
|
||
"dueToday": "Due today",
|
||
"dueTomorrow": "Due tomorrow",
|
||
"allDay": "All day",
|
||
"shoppingMore": "+{{count}} more",
|
||
"weather": "Weather",
|
||
"familyMembers": "Family members",
|
||
"participantsAdded": "participants added",
|
||
"upcomingBirthdays": "Upcoming birthdays",
|
||
"noBirthdays": "No birthdays yet",
|
||
"daysLeft": "{{count}} days",
|
||
"budgetOverview": "Budget overview",
|
||
"monthlyIncome": "Income",
|
||
"monthlyExpenses": "Expenses",
|
||
"monthlyBalance": "Balance",
|
||
"savingsRate": "Savings rate",
|
||
"topExpense": "Top expense",
|
||
"budgetEntries": "Entries",
|
||
"noBudgetData": "No budget data this month.",
|
||
"customize": "Customize",
|
||
"customizeTitle": "Customize widgets",
|
||
"customizeReset": "Reset",
|
||
"customizeSaved": "Dashboard saved",
|
||
"customizeMoveUp": "Move up",
|
||
"customizeMoveDown": "Move down",
|
||
"overdueTasksChip": "{{count}} overdue task",
|
||
"overdueTasksChipPlural": "{{count}} overdue tasks"
|
||
},
|
||
"tasks": {
|
||
"title": "Tasks",
|
||
"newTask": "New Task",
|
||
"editTask": "Edit Task",
|
||
"emptyTitle": "No tasks - all done?",
|
||
"emptyDescription": "Create new tasks with the + button.",
|
||
"titleLabel": "Title *",
|
||
"titlePlaceholder": "What needs to be done?",
|
||
"descriptionLabel": "Note",
|
||
"descriptionPlaceholder": "Optional details…",
|
||
"priorityLabel": "Priority",
|
||
"categoryLabel": "Category",
|
||
"dueDateLabel": "Due date",
|
||
"dueTimeLabel": "Time",
|
||
"assignedLabel": "Assigned to",
|
||
"assignedNobody": "- Nobody -",
|
||
"statusLabel": "Status",
|
||
"priorityUrgent": "Urgent",
|
||
"priorityHigh": "High",
|
||
"priorityMedium": "Medium",
|
||
"priorityLow": "Low",
|
||
"priorityNone": "None",
|
||
"statusOpen": "Open",
|
||
"statusInProgress": "In Progress",
|
||
"statusDone": "Done",
|
||
"categoryHousehold": "Household",
|
||
"categorySchool": "School",
|
||
"categoryShopping": "Shopping",
|
||
"categoryRepair": "Repair",
|
||
"categoryHealth": "Health",
|
||
"categoryFinance": "Finance",
|
||
"categoryLeisure": "Leisure",
|
||
"categoryMisc": "Miscellaneous",
|
||
"overdue": "Overdue",
|
||
"overdueDay": "{{count}}d overdue",
|
||
"dueToday": "Due today",
|
||
"dueTomorrow": "Due tomorrow",
|
||
"groupOverdue": "Overdue",
|
||
"groupToday": "Today",
|
||
"groupThisWeek": "This week",
|
||
"groupNextWeek": "Next week",
|
||
"groupLater": "Later",
|
||
"groupNoDate": "No date",
|
||
"markDone": "Mark {{title}} as done",
|
||
"markOpen": "Mark {{title}} as open",
|
||
"editButton": "Edit task",
|
||
"swipeOpen": "Reopen",
|
||
"swipeDone": "Done",
|
||
"swipeEdit": "Edit",
|
||
"subtaskAdd": "+ Add subtask",
|
||
"subtaskToggle": "Show subtasks",
|
||
"subtaskMarkDone": "Mark {{title}} as done",
|
||
"deleteConfirm": "Delete task and all subtasks?",
|
||
"savedToast": "Task saved.",
|
||
"createdToast": "Task created.",
|
||
"deletedToast": "Task deleted.",
|
||
"loadError": "Task could not be loaded.",
|
||
"subtaskPrompt": "Subtask:",
|
||
"kanbanOpen": "Open",
|
||
"kanbanInProgress": "In Progress",
|
||
"kanbanDone": "Done",
|
||
"kanbanMoveToInProgress": "Set to in progress",
|
||
"kanbanMoveToDone": "Mark as done",
|
||
"kanbanMoveToOpen": "Reopen",
|
||
"recurring": "Recurring",
|
||
"listView": "List view",
|
||
"kanbanView": "Kanban view",
|
||
"filterBtn": "Filter",
|
||
"filterClearAll": "Clear all filters",
|
||
"filterGroupPerson": "Person",
|
||
"filterGroupPriority": "Priority",
|
||
"filterGroupStatus": "Status",
|
||
"swipedDoneToast": "Marked as done.",
|
||
"swipedOpenToast": "Marked as open."
|
||
},
|
||
"shopping": {
|
||
"title": "Shopping",
|
||
"noLists": "No lists",
|
||
"noListsDescription": "Create a list with the + button.",
|
||
"emptyList": "The list is empty",
|
||
"emptyListDescription": "Add items using the input field above.",
|
||
"newListPrompt": "Name for the new list:",
|
||
"newListButton": "Create new list",
|
||
"renameListPrompt": "New list name:",
|
||
"deleteListConfirm": "Delete list \"{{name}}\" and all items?",
|
||
"deletedListToast": "List deleted.",
|
||
"itemDeletedToast": "\"{{name}}\" removed.",
|
||
"itemsRemovedToast": "{{count}} items removed.",
|
||
"clearChecked": "Remove checked ({{count}})",
|
||
"itemNamePlaceholder": "Add item…",
|
||
"itemQtyPlaceholder": "Quantity",
|
||
"itemNameLabel": "Item name",
|
||
"itemQtyLabel": "Quantity",
|
||
"categoryLabel": "Category",
|
||
"addItemLabel": "Add item",
|
||
"renameListLabel": "Rename list",
|
||
"deleteListLabel": "Delete list",
|
||
"swipeBack": "Undo",
|
||
"swipeCheck": "Check off",
|
||
"swipeDelete": "Delete",
|
||
"markDoneLabel": "Check off {{name}}",
|
||
"markUndoneLabel": "Uncheck {{name}}",
|
||
"deleteItemLabel": "Delete {{name}}",
|
||
"listsLoadError": "Lists could not be loaded.",
|
||
"itemsLoadError": "Items could not be loaded.",
|
||
"catFruitVeg": "Fruit & Vegetables",
|
||
"catBakery": "Bakery",
|
||
"catDairy": "Dairy",
|
||
"catMeatFish": "Meat & Fish",
|
||
"catFrozen": "Frozen",
|
||
"catDrinks": "Drinks",
|
||
"catHousehold": "Household",
|
||
"catDrugstore": "Drugstore",
|
||
"catMisc": "Miscellaneous"
|
||
},
|
||
"meals": {
|
||
"title": "Meal Plan",
|
||
"noMealPlanned": "No meal planned",
|
||
"addMeal": "Add {{type}}",
|
||
"editMeal": "Edit meal",
|
||
"addMealTitle": "Add meal",
|
||
"deleteMeal": "Delete meal",
|
||
"transferToShoppingList": "Add ingredients to shopping list",
|
||
"today": "Today",
|
||
"prevWeek": "Previous week",
|
||
"nextWeek": "Next week",
|
||
"loadError": "Meal plan could not be loaded.",
|
||
"typeBreakfast": "Breakfast",
|
||
"typeLunch": "Lunch",
|
||
"typeDinner": "Dinner",
|
||
"typeSnack": "Snack",
|
||
"dayMo": "Mon",
|
||
"dayDi": "Tue",
|
||
"dayMi": "Wed",
|
||
"dayDo": "Thu",
|
||
"dayFr": "Fri",
|
||
"daySa": "Sat",
|
||
"daySo": "Sun",
|
||
"dateLabel": "Date",
|
||
"mealTypeLabel": "Meal",
|
||
"titleLabel": "Title *",
|
||
"titlePlaceholder": "e.g. Spaghetti Bolognese",
|
||
"notesLabel": "Notes",
|
||
"notesPlaceholder": "Optional…",
|
||
"ingredientsLabel": "Ingredients",
|
||
"addIngredient": "Add ingredient",
|
||
"ingredientNamePlaceholder": "Ingredient",
|
||
"ingredientQtyPlaceholder": "Quantity",
|
||
"ingredientCategoryLabel": "Category",
|
||
"ingredientCategoryDefault": "Miscellaneous",
|
||
"removeIngredient": "Remove ingredient",
|
||
"transferLabel": "Transfer ingredients to shopping list",
|
||
"transferNow": "Transfer now",
|
||
"noShoppingLists": "No shopping lists available",
|
||
"transferSuccess": "{{count}} ingredient transferred",
|
||
"transferSuccessPlural": "{{count}} ingredients transferred",
|
||
"transferAlreadyDone": "All ingredients already transferred",
|
||
"ingredientCount": "{{count}} ingredient",
|
||
"ingredientCountPlural": "{{count}} ingredients",
|
||
"titleRequired": "Title is required",
|
||
"loadingIndicator": "Loading…",
|
||
"recipeUrlLabel": "Recipe link (optional)",
|
||
"recipeUrlPlaceholder": "https://…",
|
||
"openRecipe": "Open recipe",
|
||
"savedRecipeLabel": "Saved recipe",
|
||
"savedRecipePlaceholder": "Select recipe",
|
||
"saveAsRecipe": "Save as recipe",
|
||
"recipeScaleLabel": "Scale ingredients",
|
||
"deletedToast": "Meal deleted"
|
||
},
|
||
"calendar": {
|
||
"title": "Calendar",
|
||
"newEvent": "New Event",
|
||
"editEvent": "Edit Event",
|
||
"addEvent": "Add event",
|
||
"deleteEvent": "Delete event",
|
||
"noEvents": "No events in the selected period.",
|
||
"today": "Today",
|
||
"back": "Back",
|
||
"forward": "Forward",
|
||
"viewMonth": "Month",
|
||
"viewWeek": "Week",
|
||
"viewDay": "Day",
|
||
"viewAgenda": "Agenda",
|
||
"allDay": "All day",
|
||
"allDayShort": "all day",
|
||
"moreEvents": "+{{count}} more",
|
||
"weekNumberLabel": "W{{week}} · {{month}} {{year}}",
|
||
"agendaFrom": "From {{date}}",
|
||
"titleLabel": "Title *",
|
||
"titlePlaceholder": "e.g. Dentist",
|
||
"allDayToggle": "All day",
|
||
"startDateLabel": "Start date",
|
||
"startTimeLabel": "Start time",
|
||
"endDateLabel": "End date",
|
||
"endTimeLabel": "End time",
|
||
"fromLabel": "From",
|
||
"toLabel": "To",
|
||
"locationLabel": "Location",
|
||
"locationPlaceholder": "Optional",
|
||
"assignedLabel": "Assigned to",
|
||
"assignedNobody": "- Nobody -",
|
||
"colorLabel": "Color {{color}}",
|
||
"descriptionLabel": "Description",
|
||
"descriptionPlaceholder": "Optional…",
|
||
"popupEdit": "Edit",
|
||
"deleteConfirm": "Really delete \"{{title}}\"?",
|
||
"createdToast": "Event created",
|
||
"savedToast": "Event saved",
|
||
"deletedToast": "Event deleted",
|
||
"loadError": "Events could not be loaded.",
|
||
"saveError": "Error saving",
|
||
"deleteError": "Error deleting",
|
||
"titleRequired": "Title is required",
|
||
"monthJanuary": "January",
|
||
"monthFebruary": "February",
|
||
"monthMarch": "March",
|
||
"monthApril": "April",
|
||
"monthMay": "May",
|
||
"monthJune": "June",
|
||
"monthJuly": "July",
|
||
"monthAugust": "August",
|
||
"monthSeptember": "September",
|
||
"monthOctober": "October",
|
||
"monthNovember": "November",
|
||
"monthDecember": "December",
|
||
"dayShortSunday": "Sun",
|
||
"dayShortMonday": "Mon",
|
||
"dayShortTuesday": "Tue",
|
||
"dayShortWednesday": "Wed",
|
||
"dayShortThursday": "Thu",
|
||
"dayShortFriday": "Fri",
|
||
"dayShortSaturday": "Sat",
|
||
"dayLongSunday": "Sunday",
|
||
"dayLongMonday": "Monday",
|
||
"dayLongTuesday": "Tuesday",
|
||
"dayLongWednesday": "Wednesday",
|
||
"dayLongThursday": "Thursday",
|
||
"dayLongFriday": "Friday",
|
||
"dayLongSaturday": "Saturday",
|
||
"timeSuffix": "",
|
||
"ics": {
|
||
"reset": "Reset to original",
|
||
"resetToast": "Changes reset."
|
||
}
|
||
},
|
||
"notes": {
|
||
"title": "Board",
|
||
"newNote": "New Note",
|
||
"editNote": "Edit Note",
|
||
"addNoteLabel": "New Note",
|
||
"searchPlaceholder": "Search notes…",
|
||
"emptyTitle": "No notes yet",
|
||
"emptyDescription": "Create a new note with the + button.",
|
||
"noResultsTitle": "No results",
|
||
"noResultsDescription": "No note contains \"{{query}}\".",
|
||
"titleLabel": "Title (optional)",
|
||
"titlePlaceholder": "No title",
|
||
"contentLabel": "Content",
|
||
"contentMarkdownHint": "(Markdown formatting supported)",
|
||
"contentPlaceholder": "Enter note…",
|
||
"colorLabel": "Color",
|
||
"pinnedLabel": "Pin (appears on dashboard)",
|
||
"pinAction": "Pin",
|
||
"unpinAction": "Unpin",
|
||
"deleteLabel": "Delete note",
|
||
"deleteConfirm": "Really delete this note?",
|
||
"createdToast": "Note created",
|
||
"savedToast": "Note saved",
|
||
"deletedToast": "Note deleted",
|
||
"loadError": "Notes could not be loaded.",
|
||
"formatBold": "Bold (Ctrl+B)",
|
||
"formatItalic": "Italic (Ctrl+I)",
|
||
"formatUnderline": "Underline (Ctrl+U)",
|
||
"formatStrikethrough": "Strikethrough",
|
||
"formatHeading": "Heading",
|
||
"formatList": "Bullet list",
|
||
"formatOrderedList": "Numbered list",
|
||
"formatChecklist": "Checklist",
|
||
"formatLink": "Link",
|
||
"formatCode": "Code",
|
||
"formatQuote": "Quote",
|
||
"formatDivider": "Divider"
|
||
},
|
||
"contacts": {
|
||
"title": "Contacts",
|
||
"newContact": "New Contact",
|
||
"editContact": "Edit Contact",
|
||
"addButton": "New",
|
||
"newContactLabel": "New Contact",
|
||
"searchPlaceholder": "Search by name, phone or email…",
|
||
"importButton": "Import",
|
||
"importLabel": "Import contact from vCard",
|
||
"importTooltip": "Import vCard",
|
||
"emptyTitle": "No contacts yet",
|
||
"emptyDescription": "Add new contacts with the + button.",
|
||
"filterAll": "All",
|
||
"nameLabel": "Name *",
|
||
"namePlaceholder": "Full name",
|
||
"categoryLabel": "Category",
|
||
"phoneLabel": "Phone",
|
||
"phonePlaceholder": "+1 …",
|
||
"emailLabel": "Email",
|
||
"emailPlaceholder": "name@example.com",
|
||
"addressLabel": "Address",
|
||
"addressPlaceholder": "Street, ZIP City",
|
||
"notesLabel": "Notes",
|
||
"notesPlaceholder": "Optional…",
|
||
"callLabel": "Call",
|
||
"emailActionLabel": "Email",
|
||
"mapsLabel": "Open in Maps",
|
||
"exportLabel": "Export as vCard",
|
||
"exportTooltip": "Export vCard",
|
||
"deleteLabel": "Delete contact",
|
||
"deleteConfirm": "Really delete this contact?",
|
||
"deletePersonConfirm": "Really delete \"{{name}}\"?",
|
||
"savedToast": "Contact saved",
|
||
"updatedToast": "Contact updated",
|
||
"deletedToast": "Contact deleted",
|
||
"importedToast": "{{name}} imported.",
|
||
"importError": "Import failed: {{error}}",
|
||
"vcardNoName": "vCard does not contain a name.",
|
||
"catDoctor": "Doctor",
|
||
"catSchool": "School/Childcare",
|
||
"catAuthority": "Authority",
|
||
"catInsurance": "Insurance",
|
||
"catCraftsman": "Tradesperson",
|
||
"catEmergency": "Emergency",
|
||
"catMisc": "Miscellaneous",
|
||
"categoryDoctor": "Doctor",
|
||
"categorySchool": "School/Daycare",
|
||
"categoryAuthority": "Authority",
|
||
"categoryInsurance": "Insurance",
|
||
"categoryCraftsman": "Tradesperson",
|
||
"categoryEmergency": "Emergency",
|
||
"categoryOther": "Other"
|
||
},
|
||
"budget": {
|
||
"title": "Budget",
|
||
"newEntry": "New Entry",
|
||
"editEntry": "Edit Entry",
|
||
"addEntryLabel": "Add entry",
|
||
"newEntryFabLabel": "New Entry",
|
||
"currentMonth": "Current",
|
||
"prevMonth": "Previous month",
|
||
"nextMonth": "Next month",
|
||
"income": "Income",
|
||
"expenses": "Expenses",
|
||
"balance": "Balance",
|
||
"byCategory": "By category",
|
||
"transactions": "Transactions",
|
||
"emptyTitle": "No entries this month",
|
||
"emptyDescription": "Add budget entries with the + button.",
|
||
"csvExport": "CSV",
|
||
"typeExpense": "Expense",
|
||
"typeIncome": "Income",
|
||
"titleLabel": "Title *",
|
||
"titlePlaceholder": "e.g. Supermarket",
|
||
"amountLabel": "Amount *",
|
||
"amountPlaceholder": "0.00",
|
||
"categoryLabel": "Category",
|
||
"dateLabel": "Date *",
|
||
"recurringLabel": "Recurring",
|
||
"deleteLabel": "Delete entry",
|
||
"deleteConfirm": "Really delete this entry?",
|
||
"deletePersonConfirm": "Really delete \"{{title}}\"?",
|
||
"addedToast": "Entry added",
|
||
"savedToast": "Entry saved",
|
||
"deletedToast": "Entry deleted",
|
||
"loadError": "Budget could not be loaded.",
|
||
"trendNeutral": "- same as {{month}}",
|
||
"validAmountRequired": "Please enter a valid amount",
|
||
"dateRequired": "Date is required",
|
||
"catFood": "Food",
|
||
"catRent": "Rent",
|
||
"catInsurance": "Insurance",
|
||
"catMobility": "Transport",
|
||
"catLeisure": "Leisure and Entertainment",
|
||
"catClothing": "Clothing",
|
||
"catHealth": "Health",
|
||
"catEducation": "Education",
|
||
"catMisc": "Miscellaneous",
|
||
"catEarnedIncome": "Earned Income",
|
||
"catInvestmentIncome": "Investment Income",
|
||
"catTransferGiftIncome": "Transfer & Gift Income",
|
||
"catGovernmentBenefits": "Government & Social Benefits",
|
||
"catOtherIncome": "Other Income",
|
||
"loadingIndicator": "Loading…",
|
||
"subcategoryLabel": "Subcategory",
|
||
"catHousing": "Housing / Home",
|
||
"catTransport": "Transport",
|
||
"catPersonalHealth": "Personal Care / Health",
|
||
"catShoppingClothing": "Shopping and Clothing",
|
||
"catFinancialOther": "Financial Services and Other",
|
||
"subcatRentMortgage": "Rent / Mortgage",
|
||
"subcatCondominium": "Condominium fees",
|
||
"subcatUtilities": "Electricity / Water / Gas",
|
||
"subcatInternetTvPhone": "Internet / TV / Phone",
|
||
"subcatRenovationMaintenance": "Renovation / Maintenance",
|
||
"subcatCleaning": "Cleaning",
|
||
"subcatGroceries": "Groceries",
|
||
"subcatRestaurantsBars": "Restaurants / Bars",
|
||
"subcatSnacksFastFood": "Snacks / Fast Food",
|
||
"subcatBakery": "Bakery",
|
||
"subcatFuel": "Fuel",
|
||
"subcatParkingTolls": "Parking / Tolls",
|
||
"subcatPublicTransport": "Public transport",
|
||
"subcatAppsTaxi": "Apps / Taxi",
|
||
"subcatMaintenanceInsurance": "Maintenance / Insurance",
|
||
"subcatPharmacy": "Pharmacy",
|
||
"subcatHealthInsurance": "Health insurance",
|
||
"subcatGymSports": "Gym / Sports",
|
||
"subcatBeautyCosmetics": "Beauty / Cosmetics",
|
||
"subcatTravel": "Travel",
|
||
"subcatStreaming": "Streaming",
|
||
"subcatEvents": "Events",
|
||
"subcatHobbies": "Hobbies",
|
||
"subcatClothesShoes": "Clothes / Shoes",
|
||
"subcatElectronics": "Electronics",
|
||
"subcatGifts": "Gifts",
|
||
"subcatCoursesCollege": "Courses / College",
|
||
"subcatSchoolSupplies": "School supplies",
|
||
"subcatLanguages": "Languages",
|
||
"subcatLoansInterest": "Loans / Interest",
|
||
"subcatBankFees": "Bank fees",
|
||
"subcatInsuranceOther": "Insurance",
|
||
"subcatInvestments": "Investments",
|
||
"subcatTaxes": "Taxes",
|
||
"metaLoadError": "Budget categories could not be loaded.",
|
||
"addCategory": "+ category",
|
||
"addSubcategory": "+ subcategory",
|
||
"newCategoryPrompt": "Name of the new category:",
|
||
"newSubcategoryPrompt": "Name of the new subcategory:",
|
||
"categoryAddedToast": "Category added.",
|
||
"subcategoryAddedToast": "Subcategory added."
|
||
},
|
||
"settings": {
|
||
"title": "Settings",
|
||
"tabGeneral": "General",
|
||
"tabMeals": "Meals",
|
||
"tabBudget": "Budget",
|
||
"tabShopping": "Shopping",
|
||
"tabCalendar": "Calendar",
|
||
"tabAccount": "Account",
|
||
"tabsAriaLabel": "Settings sections",
|
||
"sectionDesign": "Appearance",
|
||
"sectionAppName": "Application name",
|
||
"sectionShopping": "Shopping",
|
||
"shoppingCategoriesLabel": "Shopping Categories",
|
||
"shoppingCategoriesHint": "Add, rename, delete or reorder categories.",
|
||
"shoppingCategoryPlaceholder": "New category…",
|
||
"shoppingCategoryRenameHint": "Click to rename",
|
||
"shoppingCategoryRenamePrompt": "New category name:",
|
||
"shoppingCategoryMoveUp": "Move category up",
|
||
"shoppingCategoryMoveDown": "Move category down",
|
||
"shoppingCategoryDelete": "Delete category",
|
||
"shoppingCategoryDeleteConfirm": "Delete category \"{{name}}\"? Existing items will be moved to the next category.",
|
||
"shoppingCategoryAdded": "Category added.",
|
||
"shoppingCategoryRenamed": "Category renamed.",
|
||
"shoppingCategoryDeleted": "Category deleted.",
|
||
"sectionAccount": "My Account",
|
||
"sectionCalendarSync": "Calendar Sync",
|
||
"sectionFamily": "Family Members",
|
||
"cardAppearance": "Display",
|
||
"appNameTitle": "App name",
|
||
"appNameLabel": "Application name",
|
||
"appNameHint": "This name appears in the sidebar, browser title and login screen.",
|
||
"appNamePlaceholder": "Oikos",
|
||
"appNameSavedToast": "Application name saved.",
|
||
"sectionDate": "Date",
|
||
"dateFormatTitle": "Date format",
|
||
"dateFormatLabel": "Preferred date format",
|
||
"dateFormatHint": "Choose how dates are displayed throughout the app.",
|
||
"dateFormatSavedToast": "Date format saved.",
|
||
"themeSystem": "System",
|
||
"themeSysLabel": "Use system setting",
|
||
"themeLight": "Light",
|
||
"themeLightLabel": "Light mode",
|
||
"themeDark": "Dark",
|
||
"themeDarkLabel": "Dark mode",
|
||
"changePassword": "Change password",
|
||
"currentPasswordLabel": "Current password",
|
||
"newPasswordLabel": "New password",
|
||
"confirmPasswordLabel": "Confirm new password",
|
||
"savePassword": "Save password",
|
||
"passwordMismatch": "Passwords do not match.",
|
||
"passwordSavedToast": "Password changed successfully.",
|
||
"googleCalendar": "Google Calendar",
|
||
"appleCalendar": "Apple Calendar (iCloud)",
|
||
"syncNow": "Sync now",
|
||
"disconnect": "Disconnect",
|
||
"connectGoogle": "Connect with Google",
|
||
"connected": "Connected",
|
||
"connectedLastSync": "Connected · Last: {{date}}",
|
||
"notConnected": "Not connected",
|
||
"notConfigured": "Not configured (missing .env variables)",
|
||
"configured": "Configured (via .env)",
|
||
"configuredLastSync": "Configured (via .env) · Last: {{date}}",
|
||
"syncSuccess": "{{provider}} synced.",
|
||
"disconnectedToast": "{{provider}} disconnected.",
|
||
"googleOnlyAdmin": "Only admin can connect Google Calendar.",
|
||
"appleOnlyAdmin": "Only admin can connect Apple Calendar.",
|
||
"caldavUrlLabel": "CalDAV Server URL",
|
||
"caldavUrlPlaceholder": "https://caldav.icloud.com",
|
||
"appleIdLabel": "Apple ID (email)",
|
||
"applePasswordLabel": "App-specific password",
|
||
"applePasswordHint": "Create password at <strong>appleid.apple.com → Security</strong>.",
|
||
"appleConnectBtn": "Connect & test",
|
||
"appleConnecting": "Connecting…",
|
||
"appleConnectedToast": "Apple Calendar connected.",
|
||
"syncSuccessGoogle": "Calendar sync with Google connected successfully.",
|
||
"syncSuccessApple": "Calendar sync with Apple connected successfully.",
|
||
"syncErrorGoogle": "Connection to Google failed. Please try again.",
|
||
"syncErrorApple": "Connection to Apple failed. Please try again.",
|
||
"addMember": "+ Add member",
|
||
"newMemberTitle": "New Family Member",
|
||
"usernameLabel": "Username",
|
||
"displayNameLabel": "Display name",
|
||
"memberPasswordLabel": "Password",
|
||
"colorLabel": "Color",
|
||
"roleLabel": "Role",
|
||
"roleMember": "Member",
|
||
"roleAdmin": "Admin",
|
||
"createMember": "Create",
|
||
"cancelAddMember": "Cancel",
|
||
"memberAddedToast": "{{name}} added.",
|
||
"deleteMemberConfirm": "Really delete {{name}}?",
|
||
"memberDeletedToast": "{{name}} deleted.",
|
||
"deleteMemberLabel": "Delete",
|
||
"logout": "Log out",
|
||
"synchronizing": "Syncing…",
|
||
"googleDisconnectConfirm": "Disconnect Google Calendar?",
|
||
"appleDisconnectConfirm": "Disconnect Apple Calendar?",
|
||
"localeSystem": "System",
|
||
"localeLabel": "Language",
|
||
"languageTitle": "Language",
|
||
"sectionMeals": "Meal Plan",
|
||
"mealTypesLabel": "Visible meals",
|
||
"mealTypesHint": "Only selected meal types are shown in the meal planner.",
|
||
"mealTypesSaved": "Meal plan settings saved.",
|
||
"mealTypesMinOne": "At least one meal type must be active.",
|
||
"sectionBudget": "Budget",
|
||
"currencyLabel": "Currency",
|
||
"currencyHint": "Sets the currency used throughout the budget section.",
|
||
"currencySaved": "Currency saved.",
|
||
"apiTokensTitle": "API Tokens",
|
||
"apiTokensCardTitle": "Access Tokens",
|
||
"apiTokensHint": "Create API tokens for external integrations. The full token is shown only once after creation.",
|
||
"apiTokenNameLabel": "Token name",
|
||
"apiTokenExpiresLabel": "Expiration date",
|
||
"apiTokenExpiresHint": "Leave empty to create a token without expiration.",
|
||
"apiTokenCreatedLabel": "New API token",
|
||
"apiTokenCreatedHint": "Store this token securely. It cannot be shown again.",
|
||
"apiTokenCreate": "Create token",
|
||
"apiTokenInvalidExpiration": "Please enter a valid expiration date.",
|
||
"apiTokenCreatedToast": "API token created.",
|
||
"apiTokenRevokedToast": "API token revoked.",
|
||
"apiTokenRevokeConfirm": "Revoke API token \"{{name}}\"?",
|
||
"apiTokenRevoke": "Revoke token",
|
||
"apiTokenRevoked": "Revoked",
|
||
"apiTokenExpired": "Expired",
|
||
"apiTokenActive": "Active",
|
||
"apiTokenPrefix": "Prefix",
|
||
"apiTokenExpires": "Expires",
|
||
"apiTokenNeverExpires": "No expiration",
|
||
"apiTokenLastUsed": "Last used",
|
||
"apiTokenNeverUsed": "Never used",
|
||
"ics": {
|
||
"title": "ICS Subscriptions",
|
||
"add": "Add subscription",
|
||
"addedToast": "Subscription added.",
|
||
"deletedToast": "Subscription deleted.",
|
||
"syncedToast": "Subscription synced.",
|
||
"confirm_delete": "Do you really want to delete this subscription? All associated events will also be deleted.",
|
||
"empty": "No subscriptions yet.",
|
||
"form": {
|
||
"name": "Name",
|
||
"url": "ICS URL",
|
||
"color": "Color",
|
||
"shared": "Visible to everyone"
|
||
},
|
||
"actions": {
|
||
"submit": "Add",
|
||
"save": "Save",
|
||
"cancel": "Cancel",
|
||
"delete": "Delete",
|
||
"edit": "Edit",
|
||
"sync": "Sync now"
|
||
},
|
||
"status": {
|
||
"lastSync": "Last synced:",
|
||
"never": "Not yet synced",
|
||
"syncing": "Syncing...",
|
||
"syncError": "Sync error"
|
||
},
|
||
"badges": {
|
||
"private": "Private",
|
||
"shared": "Shared"
|
||
}
|
||
}
|
||
},
|
||
"login": {
|
||
"tagline": "Family planning. Secure. Privacy-friendly. Open source.",
|
||
"usernameLabel": "Username",
|
||
"usernamePlaceholder": "username",
|
||
"passwordLabel": "Password",
|
||
"passwordPlaceholder": "••••••••",
|
||
"loginButton": "Log in",
|
||
"loggingIn": "Logging in…",
|
||
"tooManyAttempts": "Too many attempts. Please wait a moment.",
|
||
"invalidCredentials": "Invalid credentials.",
|
||
"version": "v{{version}}"
|
||
},
|
||
"install": {
|
||
"title": "Install Oikos",
|
||
"subtitle": "Add to home screen",
|
||
"iosTip1": "Tap ",
|
||
"iosTip2": " → \"Add to Home Screen\"",
|
||
"installButton": "Install",
|
||
"dismissLabel": "Close"
|
||
},
|
||
"modal": {
|
||
"closeLabel": "Close",
|
||
"overlayLabel": "Modal dialog background",
|
||
"unsavedChanges": "Discard changes?",
|
||
"discardChanges": "Discard"
|
||
},
|
||
"rrule": {
|
||
"freqNone": "No recurrence",
|
||
"freqDaily": "Daily",
|
||
"freqWeekly": "Weekly",
|
||
"freqMonthly": "Monthly",
|
||
"dayMo": "Mo",
|
||
"dayTu": "Tu",
|
||
"dayWe": "We",
|
||
"dayTh": "Th",
|
||
"dayFr": "Fr",
|
||
"daySa": "Sa",
|
||
"daySu": "Su",
|
||
"labelRepeat": "Recurrence",
|
||
"labelEvery": "Every",
|
||
"labelOnDays": "On these days",
|
||
"labelUntil": "Ends on (optional)",
|
||
"unitDay": "day",
|
||
"unitDays": "days",
|
||
"unitWeek": "week",
|
||
"unitWeeks": "weeks",
|
||
"unitMonth": "month",
|
||
"unitMonths": "months"
|
||
},
|
||
"reminders": {
|
||
"sectionTitle": "Reminder",
|
||
"enableLabel": "Set reminder",
|
||
"dateLabel": "Date",
|
||
"timeLabel": "Time",
|
||
"offsetLabel": "Remind me",
|
||
"offsetNone": "None",
|
||
"offset15min": "15 minutes before",
|
||
"offset1hour": "1 hour before",
|
||
"offset1day": "1 day before",
|
||
"offsetAtTime": "At event time",
|
||
"toastTitle": "Reminder",
|
||
"dismiss": "Dismiss",
|
||
"notificationPermission": "Browser notifications",
|
||
"notificationEnable": "Enable notifications",
|
||
"notificationEnabled": "Notifications active",
|
||
"notificationDenied": "Notifications blocked",
|
||
"notificationHint": "Receive notifications while the app is open.",
|
||
"pendingBadgeTitle": "{{count}} reminder due",
|
||
"pendingBadgeTitlePlural": "{{count}} reminders due"
|
||
},
|
||
"birthdays": {
|
||
"title": "Birthdays",
|
||
"addButton": "Add birthday",
|
||
"searchPlaceholder": "Search birthdays…",
|
||
"upcomingTitle": "Next birthdays",
|
||
"upcomingHint": "The next people to celebrate, already synced to the calendar.",
|
||
"peopleTitle": "People",
|
||
"peopleHint": "Search, review and edit every saved birthday.",
|
||
"emptyTitle": "No birthdays yet",
|
||
"emptyDescription": "Add a birthday to keep it visible in the calendar and reminders.",
|
||
"newTitle": "New birthday",
|
||
"editTitle": "Edit birthday",
|
||
"nameLabel": "Name",
|
||
"birthDateLabel": "Birth date",
|
||
"photoLabel": "Profile picture",
|
||
"photoOptional": "Optional: you can save without a profile picture.",
|
||
"removePhoto": "Remove picture",
|
||
"notesLabel": "Notes",
|
||
"notesPlaceholder": "Gift ideas, favorite cake, family notes…",
|
||
"calendarHint": "Each birthday is automatically added to the calendar and reminder system.",
|
||
"requiredFields": "Name and birth date are required.",
|
||
"createdToast": "Birthday saved.",
|
||
"updatedToast": "Birthday updated.",
|
||
"deletedToast": "Birthday deleted.",
|
||
"deleteConfirm": "Delete birthday for \"{{name}}\"?",
|
||
"ageNoteToday": "Turns {{age}} today.",
|
||
"ageNoteTomorrow": "Turns {{age}} tomorrow.",
|
||
"ageNoteDays": "Turns {{age}} in {{days}} days."
|
||
},
|
||
"recipes": {
|
||
"title": "Recipes",
|
||
"addRecipe": "Add recipe",
|
||
"editRecipe": "Edit recipe",
|
||
"emptyTitle": "No recipes yet",
|
||
"emptyDescription": "Save your favorite recipes and reuse them in meal planning.",
|
||
"titleLabel": "Title *",
|
||
"titlePlaceholder": "e.g. Pasta Carbonara",
|
||
"notesLabel": "Notes",
|
||
"notesPlaceholder": "Optional...",
|
||
"urlLabel": "Recipe link",
|
||
"urlPlaceholder": "https://...",
|
||
"ingredientsLabel": "Ingredients",
|
||
"addToMeals": "Add to meal plan",
|
||
"openLink": "Open recipe link",
|
||
"deleteConfirm": "Delete recipe \"{{title}}\"?",
|
||
"created": "Recipe saved.",
|
||
"updated": "Recipe updated.",
|
||
"deleted": "Recipe deleted.",
|
||
"titleRequired": "Title is required",
|
||
"duplicate": "Duplicate",
|
||
"duplicated": "Recipe duplicated.",
|
||
"copySuffix": "copy"
|
||
},
|
||
"search": {
|
||
"title": "Search",
|
||
"open": "Open search",
|
||
"placeholder": "Search…",
|
||
"noResults": "No results found."
|
||
},
|
||
"onboarding": {
|
||
"step1Title": "Welcome to Oikos",
|
||
"step1Body": "Your personal family planner. Tasks, calendar, shopping and more – all in one place.",
|
||
"step2Title": "Everything at a glance",
|
||
"step2Body": "Use the navigation below to reach all modules. The + button creates new entries quickly.",
|
||
"step3Title": "Ready to go",
|
||
"step3Body": "The dashboard shows you the most important information at a glance. Customize it under \"Customize\".",
|
||
"next": "Next",
|
||
"done": "Get started",
|
||
"skip": "Skip"
|
||
}
|
||
}
|