feat: add housekeeping module for household staff management

* Adding flexible reminder options to birthdays

* Fix database migration merge conflict

* Truncate calendar popup descriptions

* Log app version on backend startup

* Add host-mounted data and backup folders

* feat: add housekeeping module

* fix: align housekeeping UI and add task creation

* refactor: rebuild housekeeping experience

* feat: support multiple housekeeping staff

* feat: integrate housekeeping visits with calendar

* feat: refine housekeeping visits and payments

* feat: add housekeeping staff visit logs

* feat: add housekeeping receipts and document folders

* feat: localize housekeeping folders and chores

* feat: refine housekeeping tabs and document folders

* fix: sync housekeeping tab active state

* feat: use configured app name in onboarding and manifest
This commit is contained in:
Rafael Foster
2026-05-08 15:14:51 -03:00
committed by GitHub
parent d19689a1ab
commit 22ec13e559
38 changed files with 7127 additions and 235 deletions
+250 -7
View File
@@ -54,7 +54,8 @@
"more": "Mais",
"documents": "Documentos",
"kitchen": "Cozinha",
"search": "Pesquisar"
"search": "Pesquisar",
"housekeeping": "Faxina"
},
"dashboard": {
"title": "Painel",
@@ -205,7 +206,18 @@
"swipedOpenToast": "Marcado como aberto.",
"reminderNeedsDueDate": "Defina uma data de vencimento para habilitar lembretes da tarefa.",
"emptyAction": "Criar tarefa",
"navLabelOverdue": "Tarefas, {{count}} atrasadas"
"navLabelOverdue": "Tarefas, {{count}} atrasadas",
"bulkArchive": "Archive",
"bulkArchived": "Tasks archived.",
"bulkDelete": "Delete",
"bulkDeleteConfirm": "Delete {{count}} tasks permanently?",
"bulkDeleted": "Tasks deleted.",
"bulkMarkDone": "Mark done",
"bulkMarkOpen": "Mark open",
"bulkSelect": "Bulk select",
"bulkSelectedCount": "{{count}} selected",
"bulkStatusChanged": "Status changed.",
"selectTask": "Select task"
},
"shopping": {
"title": "Compras",
@@ -479,7 +491,13 @@
"colorPurple": "Roxo",
"colorRed": "Vermelho",
"colorSkyBlue": "Azul céu",
"colorYellow": "Amarelo"
"colorYellow": "Amarelo",
"iconCleaning": "Faxina",
"caldavTargetHint": "Choose a CalDAV calendar to sync this event.",
"caldavTargetLabel": "Sync to CalDAV",
"caldavTargetLocal": "Store locally only",
"attachmentDocumentName": "{{title}} - {{name}}",
"attachmentDocumentDescription": "Anexo enviado para o evento \"{{title}}\" do calendário."
},
"notes": {
"title": "Quadro de notas",
@@ -977,7 +995,72 @@
"addressbookEnabled": "Addressbook enabled",
"addressbookDisabled": "Addressbook disabled",
"addressbooksRefreshed": "Addressbooks refreshed",
"deleteCardDAVAccountConfirm": "Really delete CardDAV account? All synced contacts will remain but lose their CardDAV link."
"deleteCardDAVAccountConfirm": "Really delete CardDAV account? All synced contacts will remain but lose their CardDAV link.",
"sectionHousekeeping": "Faxina",
"housekeepingPaymentsTitle": "Tarefas de pagamento",
"housekeepingPaymentTasksLabel": "Criar uma tarefa de pagamento a cada entrada da faxineira",
"housekeepingPaymentTasksHint": "Quando ativo, cada entrada cria uma tarefa para pagar a pessoa da equipe. Ao concluir essa tarefa, o pagamento da visita é marcado como pago.",
"housekeepingPaymentTasksSaved": "Configuração de pagamento da faxina salva.",
"backupSchedulerDisabled": "Disabled",
"backupSchedulerEnabled": "Enabled",
"backupSchedulerHint": "Scheduled backups are created automatically and old backups are rotated.",
"backupSchedulerKeep": "Retention",
"backupSchedulerKeepCount": "{{count}} backups",
"backupSchedulerLastBackup": "Last backup",
"backupSchedulerLastFail": "{{date}} (failed)",
"backupSchedulerLastSuccess": "{{date}} (successful)",
"backupSchedulerNever": "No backup created yet",
"backupSchedulerSchedule": "Schedule",
"backupSchedulerStatus": "Status",
"backupSchedulerTitle": "Automatic Backups",
"backupSchedulerTrigger": "Create backup now",
"backupSchedulerTriggeredToast": "Backup created successfully.",
"backupSchedulerTriggering": "Creating backup...",
"breadcrumbLabel": "Pfad",
"caldavAccountAdded": "CalDAV account added successfully",
"caldavAccountDeleted": "CalDAV account removed",
"caldavAddAccount": "Add CalDAV Account",
"caldavCalendarsToggle": "Show/hide calendars",
"caldavConnectionFailed": "Connection to CalDAV server failed",
"caldavDescription": "Connect multiple CalDAV accounts (iCloud, Nextcloud, Radicale, Baikal, etc.) and choose which calendars to sync.",
"caldavEmptyState": "No CalDAV accounts connected yet. Add your first account to get started.",
"caldavNameLabel": "Account Name",
"caldavNamePlaceholder": "e.g. My Radicale, iCloud, Nextcloud",
"caldavPasswordHint": "For iCloud: Use app-specific password from appleid.apple.com",
"caldavPasswordLabel": "Password",
"caldavRefreshCalendars": "Refresh calendars",
"caldavSyncFailed": "CalDAV sync failed",
"caldavSyncSuccess": "CalDAV sync successful",
"caldavTitle": "CalDAV Calendars",
"caldavUrlHint": "The base URL of your CalDAV server",
"caldavUsernameLabel": "Username",
"calendarDisabled": "Calendar disabled",
"calendarEnabled": "Calendar enabled",
"calendarsRefreshed": "Calendars refreshed",
"deleteAccountConfirm": "Really delete CalDAV account? All synced calendars will be removed.",
"emptyStateAddFirst": "Füge dein erstes Konto hinzu",
"emptyStateNoAccounts": "Noch keine Konten verbunden",
"helpTooltipCalDAV": "CalDAV ermöglicht die Synchronisation von Kalendern mit iCloud, Nextcloud und anderen CalDAV-Servern.",
"helpTooltipCardDAV": "CardDAV ermöglicht die Synchronisation von Kontakten mit iCloud, Nextcloud und anderen CardDAV-Servern.",
"lastSync": "Last synced",
"modulesHint": "Disabled modules disappear from the navigation. Data is preserved and reappears once a module is re-enabled.",
"modulesSaved": "Module visibility saved.",
"modulesTitle": "Active modules",
"navigationLabel": "Einstellungsnavigation",
"sectionAdmin": "Administration",
"sectionCloudServices": "Cloud-Dienste",
"sectionModules": "Modules",
"sectionModulesNav": "Module",
"sectionOpenStandards": "CalDAV & CardDAV",
"sectionPersonal": "Persönlich",
"sectionSync": "Synchronisation",
"statusError": "Fehler",
"statusNeverSynced": "Noch nie synchronisiert",
"statusSynced": "Synchronisiert",
"statusSyncing": "Synchronisiert…",
"syncedAgo": "vor {{time}}",
"tabSyncCalendar": "Kalender",
"tabSyncContacts": "Kontakte"
},
"login": {
"tagline": "Planejamento familiar. Seguro. Privado. Código aberto.",
@@ -1120,7 +1203,7 @@
"customWeeks": "Semanas"
},
"onboarding": {
"step1Title": "Welcome to Oikos",
"step1Title": "Bem-vindo ao {{name}}",
"step1Body": "Your personal family planner. Tasks, calendar, shopping and more all in one place.",
"step2Title": "Navegação e módulos",
"step2Body": "Na parte inferior acessa diretamente o Painel e o Calendário. Com o botão ··· abre módulos adicionais como Cozinha, Notas e Contactos.",
@@ -1203,7 +1286,18 @@
},
"dropzoneTitle": "Solte o arquivo aqui ou clique para escolher",
"dropzoneHint": "Arraste um arquivo para esta area, ou use o seletor de arquivos.",
"selectedFileLabel": "Selecionado: {{name}}"
"selectedFileLabel": "Selecionado: {{name}}",
"addFolderButton": "Adicionar pasta",
"allFolders": "Todas as pastas",
"folderLabel": "Pasta",
"noFolder": "Sem pasta",
"newFolderTitle": "Nova pasta",
"folderNameLabel": "Nome da pasta",
"createFolderAction": "Criar pasta",
"folderCreatedToast": "Pasta criada.",
"housekeepingFolder": "Faxina",
"calendarItemsFolder": "Itens do calendário",
"folderBrowserTitle": "Navegar por pastas"
},
"shortcuts": {
"goKitchen": "Cozinha",
@@ -1215,5 +1309,154 @@
"help": "Atalhos de teclado",
"new": "Criar nova entrada",
"search": "Abrir pesquisa"
},
"housekeeping": {
"title": "Área da faxineira",
"bottomNav": "Navegação da faxina",
"home": "Início",
"tasks": "Tarefas",
"report": "Reportar",
"notCheckedIn": "Ponto não iniciado",
"checkedInAt": "Entrada às",
"monthTotal": "Mês atual · {{count}} diárias",
"dailyRate": "Valor da diária",
"extras": "Extras",
"checkIn": "Entrar",
"checkOut": "Sair",
"quickSupply": "Faltou produto",
"supplyName": "Nome do produto",
"supplyPlaceholder": "O que faltou?",
"checkedInToast": "Entrada registrada.",
"checkedOutToast": "Saída registrada.",
"supplyAddedToast": "Adicionado à lista de compras.",
"overdue": "Atrasada",
"dueToday": "Hoje",
"ok": "Em dia",
"noTasks": "Nenhuma tarefa de faxina cadastrada.",
"everyDays": "A cada {{days}} dias",
"completeTask": "Concluir {{name}}",
"taskDoneToast": "Tarefa concluída.",
"reportTitle": "Reportar problema",
"problemDescription": "Descrição do problema",
"problemPlaceholder": "Ex: lâmpada queimada",
"addPhoto": "Adicionar foto",
"sendReport": "Enviar ocorrência",
"reportSentToast": "Problema reportado.",
"recentReports": "Ocorrências recentes",
"addTask": "Adicionar tarefa",
"taskName": "Tarefa",
"taskNamePlaceholder": "Ex: Limpar banheiros",
"taskArea": "Área",
"taskAreaPlaceholder": "Ex: Banheiro",
"taskFrequency": "Frequência",
"createTask": "Criar tarefa",
"taskCreatedToast": "Tarefa de faxina criada.",
"dashboard": "Painel",
"reports": "Relatórios",
"visitsThisMonth": "Visitas no mês",
"lastVisit": "Última visita",
"pendingChores": "Tarefas pendentes",
"finishedChores": "Tarefas concluídas",
"payments": "Pagamentos",
"pendingPayments": "Pagamentos pendentes",
"monthlyPayments": "Pagamentos mensais",
"noPaymentData": "Ainda não há dados de pagamento.",
"noVisits": "Nenhuma visita ainda",
"noWorkerTitle": "Nenhum perfil de faxineira",
"noWorkerHint": "Crie o perfil para definir contatos, diária e agenda de pagamento.",
"taskTemplates": "Tarefas sugeridas",
"addCustomTask": "Adicionar tarefa personalizada",
"noReports": "Nenhuma ocorrência ainda.",
"profileTitle": "Perfil da faxineira",
"profilePicture": "Foto de perfil da faxineira",
"workerName": "Nome",
"workerUsername": "Usuário",
"workerPhone": "Telefone",
"workerEmail": "E-mail",
"workerBirthDate": "Aniversário",
"paymentSchedule": "Agenda de pagamento",
"scheduleDaily": "A cada visita",
"scheduleTwiceMonthly": "Duas vezes por mês",
"scheduleMonthly": "Mensal",
"profileColor": "Cor do perfil",
"workerNotes": "Observações",
"workerSavedToast": "Perfil da faxineira salvo.",
"staff": "Equipe",
"staffTitle": "Equipe de faxina",
"addWorker": "Adicionar faxineira",
"editWorker": "Editar faxineira",
"noWorkers": "Nenhuma faxineira cadastrada.",
"moreWorkers": "+{{count}} a mais",
"checkInDisabled": "Cadastre uma faxineira antes de fazer check-in.",
"calendarColor": "Cor no calendário",
"visitRecordedAt": "Visita registrada às",
"checkedInToday": "Registrada hoje",
"visitReports": "Relatórios de visitas da equipe",
"noVisitReports": "Nenhuma visita da equipe registrada neste mês.",
"openVisitReport": "Abrir relatório da visita",
"visitReportDetails": "Relatório da visita",
"paymentPaid": "Pago",
"paymentPending": "Pendente",
"totalPayment": "Pagamento total",
"paymentStatus": "Status do pagamento",
"paymentTask": "Tarefa de pagamento",
"calendarEvent": "Evento do calendário",
"notAvailable": "Não disponível",
"calendarVisitTitle": "Faxina: {{name}}",
"paymentTaskTitle": "Pagar {{name}} pela faxina",
"paymentTaskDescription": "Visita de faxina em {{date}}. Valor devido: {{amount}}.",
"staffLogTitle": "Visitas de {{name}}",
"staffLogHint": "Edite datas, valores e registros vinculados.",
"filterMonth": "Mês",
"editVisit": "Editar visita",
"deleteVisit": "Excluir visita",
"deleteVisitConfirm": "Excluir esta visita? O evento do calendário e a tarefa de pagamento vinculados também serão removidos.",
"visitDeletedToast": "Visita excluída.",
"visitSavedToast": "Visita atualizada.",
"visitDate": "Data da visita",
"markPaid": "Marcar pago",
"visitPaidToast": "Pagamento marcado como pago.",
"receiptUploadTitle": "Enviar comprovante de pagamento",
"receiptUploadHint": "Anexe um comprovante de pagamento. Ele aparecerá em Documentos.",
"receiptDocumentName": "Comprovante - {{name}} - {{date}}",
"receiptDocumentDescription": "Comprovante de pagamento da visita de faxina de {{name}} em {{date}}.",
"taskTemplateData": {
"cleanBathrooms": {
"name": "Limpar banheiros",
"area": "Banheiros"
},
"mopKitchenFloor": {
"name": "Passar pano no piso da cozinha",
"area": "Cozinha"
},
"dustLivingRoom": {
"name": "Tirar pó da sala",
"area": "Sala"
},
"changeBedLinens": {
"name": "Trocar roupa de cama",
"area": "Quartos"
},
"cleanRefrigerator": {
"name": "Limpar geladeira",
"area": "Cozinha"
},
"cleanWindows": {
"name": "Limpar janelas",
"area": "Casa toda"
},
"deepCleanOven": {
"name": "Limpeza profunda do forno",
"area": "Cozinha"
},
"washOutdoor": {
"name": "Lavar varanda/pátio",
"area": "Área externa"
}
}
},
"userMultiSelect": {
"moreUsers": "weitere",
"nobody": "- Niemand -"
}
}
}