Initial commit after fork. Moving Budget categories to Database and adding subcategories, with customization options

This commit is contained in:
Rafael Foster
2026-04-25 10:05:27 -03:00
parent a97f8651ac
commit 140fa78ca1
25 changed files with 1322 additions and 161 deletions
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- مثل {{month}}",
"validAmountRequired": "أدخل مبلغاً صحيحاً",
"dateRequired": "التاريخ مطلوب",
"catFood": "الطعام",
"catFood": "Food",
"catRent": "الإيجار",
"catInsurance": "التأمين",
"catMobility": "التنقل",
"catLeisure": "الترفيه",
"catLeisure": "Leisure and Entertainment",
"catClothing": "الملابس",
"catHealth": "الصحة",
"catEducation": "التعليم",
"catEducation": "Education",
"catMisc": "متنوع",
"catEarnedIncome": "دخل العمل",
"catInvestmentIncome": "دخل الاستثمار",
"catTransferGiftIncome": "التحويلات والهدايا",
"catGovernmentBenefits": "المزايا الاجتماعية",
"catOtherIncome": "دخل آخر",
"loadingIndicator": "جارٍ التحميل…"
"loadingIndicator": "جارٍ التحميل…",
"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": "الإعدادات",
+50 -3
View File
@@ -469,11 +469,11 @@
"trendNeutral": "- wie {{month}}",
"validAmountRequired": "Gültigen Betrag eingeben",
"dateRequired": "Datum ist erforderlich",
"catFood": "Lebensmittel",
"catFood": "Ernährung",
"catRent": "Miete",
"catInsurance": "Versicherung",
"catMobility": "Mobilität",
"catLeisure": "Freizeit",
"catLeisure": "Freizeit und Unterhaltung",
"catClothing": "Kleidung",
"catHealth": "Gesundheit",
"catEducation": "Bildung",
@@ -483,7 +483,54 @@
"catTransferGiftIncome": "Geschenke & Transfers",
"catGovernmentBenefits": "Sozialleistungen",
"catOtherIncome": "Sonstiges Einkommen",
"loadingIndicator": "Lade…"
"loadingIndicator": "Lade…",
"subcategoryLabel": "Unterkategorie",
"catHousing": "Wohnen / Zuhause",
"catTransport": "Transport",
"catPersonalHealth": "Körperpflege / Gesundheit",
"catShoppingClothing": "Einkäufe und Kleidung",
"catFinancialOther": "Finanzdienstleistungen und Sonstiges",
"subcatRentMortgage": "Miete / Kreditrate",
"subcatCondominium": "Hausgeld",
"subcatUtilities": "Strom / Wasser / Gas",
"subcatInternetTvPhone": "Internet / TV / Telefon",
"subcatRenovationMaintenance": "Renovierung / Instandhaltung",
"subcatCleaning": "Reinigung",
"subcatGroceries": "Supermarkt",
"subcatRestaurantsBars": "Restaurants / Bars",
"subcatSnacksFastFood": "Snacks / Fast Food",
"subcatBakery": "Bäckerei",
"subcatFuel": "Kraftstoff",
"subcatParkingTolls": "Parken / Maut",
"subcatPublicTransport": "Öffentliche Verkehrsmittel",
"subcatAppsTaxi": "Apps / Taxi",
"subcatMaintenanceInsurance": "Wartung / Versicherung",
"subcatPharmacy": "Apotheke",
"subcatHealthInsurance": "Krankenversicherung",
"subcatGymSports": "Fitnessstudio / Sport",
"subcatBeautyCosmetics": "Schönheit / Kosmetik",
"subcatTravel": "Reisen",
"subcatStreaming": "Streaming",
"subcatEvents": "Veranstaltungen",
"subcatHobbies": "Hobbys",
"subcatClothesShoes": "Kleidung / Schuhe",
"subcatElectronics": "Elektronik",
"subcatGifts": "Geschenke",
"subcatCoursesCollege": "Kurse / Hochschule",
"subcatSchoolSupplies": "Schulmaterial",
"subcatLanguages": "Sprachen",
"subcatLoansInterest": "Kredite / Zinsen",
"subcatBankFees": "Bankgebühren",
"subcatInsuranceOther": "Versicherungen",
"subcatInvestments": "Investitionen",
"subcatTaxes": "Steuern",
"metaLoadError": "Budget-Kategorien konnten nicht geladen werden.",
"addCategory": "+ Kategorie",
"addSubcategory": "+ Unterkategorie",
"newCategoryPrompt": "Name der neuen Kategorie:",
"newSubcategoryPrompt": "Name der neuen Unterkategorie:",
"categoryAddedToast": "Kategorie hinzugefügt.",
"subcategoryAddedToast": "Unterkategorie hinzugefügt."
},
"settings": {
"title": "Einstellungen",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- ίδιο με {{month}}",
"validAmountRequired": "Παρακαλώ εισαγάγετε έγκυρο ποσό",
"dateRequired": "Η ημερομηνία είναι υποχρεωτική",
"catFood": "Τρόφιμα",
"catFood": "Food",
"catRent": "Ενοίκιο",
"catInsurance": "Ασφάλεια",
"catMobility": "Μεταφορές",
"catLeisure": "Ελεύθερος χρόνος",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Ρουχισμός",
"catHealth": "Υγεία",
"catEducation": "Εκπαίδευση",
"catEducation": "Education",
"catMisc": "Διάφορα",
"catEarnedIncome": "Εισόδημα από εργασία",
"catInvestmentIncome": "Επενδυτικό εισόδημα",
"catTransferGiftIncome": "Μεταφορές και δώρα",
"catGovernmentBenefits": "Κοινωνικές παροχές",
"catOtherIncome": "Άλλο εισόδημα",
"loadingIndicator": "Φόρτωση…"
"loadingIndicator": "Φόρτωση…",
"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": "Ρυθμίσεις",
+50 -3
View File
@@ -463,11 +463,11 @@
"trendNeutral": "- same as {{month}}",
"validAmountRequired": "Please enter a valid amount",
"dateRequired": "Date is required",
"catFood": "Groceries",
"catFood": "Food",
"catRent": "Rent",
"catInsurance": "Insurance",
"catMobility": "Transport",
"catLeisure": "Leisure",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Clothing",
"catHealth": "Health",
"catEducation": "Education",
@@ -477,7 +477,54 @@
"catTransferGiftIncome": "Transfer & Gift Income",
"catGovernmentBenefits": "Government & Social Benefits",
"catOtherIncome": "Other Income",
"loadingIndicator": "Loading…"
"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",
+49 -2
View File
@@ -467,7 +467,7 @@
"catRent": "Alquiler",
"catInsurance": "Seguro",
"catMobility": "Movilidad",
"catLeisure": "Ocio",
"catLeisure": "Ocio y entretenimiento",
"catClothing": "Ropa",
"catHealth": "Salud",
"catEducation": "Educación",
@@ -477,7 +477,54 @@
"catTransferGiftIncome": "Transferencias y Regalos",
"catGovernmentBenefits": "Prestaciones Sociales",
"catOtherIncome": "Otros Ingresos",
"loadingIndicator": "Cargando…"
"loadingIndicator": "Cargando…",
"subcategoryLabel": "Subcategoría",
"catHousing": "Vivienda / Casa",
"catTransport": "Transporte",
"catPersonalHealth": "Cuidado personal / Salud",
"catShoppingClothing": "Compras y ropa",
"catFinancialOther": "Servicios financieros y otros",
"subcatRentMortgage": "Alquiler / Hipoteca",
"subcatCondominium": "Comunidad",
"subcatUtilities": "Luz / Agua / Gas",
"subcatInternetTvPhone": "Internet / TV / Teléfono",
"subcatRenovationMaintenance": "Reforma / Mantenimiento",
"subcatCleaning": "Limpieza",
"subcatGroceries": "Supermercado",
"subcatRestaurantsBars": "Restaurantes / Bares",
"subcatSnacksFastFood": "Snacks / Comida rápida",
"subcatBakery": "Panadería",
"subcatFuel": "Combustible",
"subcatParkingTolls": "Aparcamiento / Peajes",
"subcatPublicTransport": "Transporte público",
"subcatAppsTaxi": "Apps / Taxi",
"subcatMaintenanceInsurance": "Mantenimiento / Seguro",
"subcatPharmacy": "Farmacia",
"subcatHealthInsurance": "Seguro médico",
"subcatGymSports": "Gimnasio / Deportes",
"subcatBeautyCosmetics": "Belleza / Cosmética",
"subcatTravel": "Viajes",
"subcatStreaming": "Streaming",
"subcatEvents": "Eventos",
"subcatHobbies": "Aficiones",
"subcatClothesShoes": "Ropa / Calzado",
"subcatElectronics": "Electrónica",
"subcatGifts": "Regalos",
"subcatCoursesCollege": "Cursos / Universidad",
"subcatSchoolSupplies": "Material escolar",
"subcatLanguages": "Idiomas",
"subcatLoansInterest": "Préstamos / Intereses",
"subcatBankFees": "Comisiones bancarias",
"subcatInsuranceOther": "Seguros",
"subcatInvestments": "Inversiones",
"subcatTaxes": "Impuestos",
"metaLoadError": "No se pudieron cargar las categorías del presupuesto.",
"addCategory": "+ categoría",
"addSubcategory": "+ subcategoría",
"newCategoryPrompt": "Nombre de la nueva categoría:",
"newSubcategoryPrompt": "Nombre de la nueva subcategoría:",
"categoryAddedToast": "Categoría añadida.",
"subcategoryAddedToast": "Subcategoría añadida."
},
"settings": {
"title": "Ajustes",
+49 -2
View File
@@ -467,7 +467,7 @@
"catRent": "Loyer",
"catInsurance": "Assurance",
"catMobility": "Transport",
"catLeisure": "Loisirs",
"catLeisure": "Loisirs et divertissement",
"catClothing": "Vêtements",
"catHealth": "Santé",
"catEducation": "Éducation",
@@ -477,7 +477,54 @@
"catTransferGiftIncome": "Transferts et Cadeaux",
"catGovernmentBenefits": "Allocations Sociales",
"catOtherIncome": "Autres Revenus",
"loadingIndicator": "Chargement…"
"loadingIndicator": "Chargement…",
"subcategoryLabel": "Sous-catégorie",
"catHousing": "Logement / Maison",
"catTransport": "Transport",
"catPersonalHealth": "Soins personnels / Santé",
"catShoppingClothing": "Achats et vêtements",
"catFinancialOther": "Services financiers et autres",
"subcatRentMortgage": "Loyer / Crédit immobilier",
"subcatCondominium": "Copropriété",
"subcatUtilities": "Électricité / Eau / Gaz",
"subcatInternetTvPhone": "Internet / TV / Téléphone",
"subcatRenovationMaintenance": "Rénovation / Entretien",
"subcatCleaning": "Nettoyage",
"subcatGroceries": "Supermarché",
"subcatRestaurantsBars": "Restaurants / Bars",
"subcatSnacksFastFood": "Snacks / Fast-food",
"subcatBakery": "Boulangerie",
"subcatFuel": "Carburant",
"subcatParkingTolls": "Parking / Péages",
"subcatPublicTransport": "Transports publics",
"subcatAppsTaxi": "Apps / Taxi",
"subcatMaintenanceInsurance": "Entretien / Assurance",
"subcatPharmacy": "Pharmacie",
"subcatHealthInsurance": "Assurance santé",
"subcatGymSports": "Salle de sport / Sports",
"subcatBeautyCosmetics": "Beauté / Cosmétiques",
"subcatTravel": "Voyages",
"subcatStreaming": "Streaming",
"subcatEvents": "Événements",
"subcatHobbies": "Loisirs",
"subcatClothesShoes": "Vêtements / Chaussures",
"subcatElectronics": "Électronique",
"subcatGifts": "Cadeaux",
"subcatCoursesCollege": "Cours / Université",
"subcatSchoolSupplies": "Fournitures scolaires",
"subcatLanguages": "Langues",
"subcatLoansInterest": "Prêts / Intérêts",
"subcatBankFees": "Frais bancaires",
"subcatInsuranceOther": "Assurances",
"subcatInvestments": "Investissements",
"subcatTaxes": "Impôts",
"metaLoadError": "Impossible de charger les catégories du budget.",
"addCategory": "+ catégorie",
"addSubcategory": "+ sous-catégorie",
"newCategoryPrompt": "Nom de la nouvelle catégorie :",
"newSubcategoryPrompt": "Nom de la nouvelle sous-catégorie :",
"categoryAddedToast": "Catégorie ajoutée.",
"subcategoryAddedToast": "Sous-catégorie ajoutée."
},
"settings": {
"title": "Paramètres",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- {{month}} जैसा",
"validAmountRequired": "वैध राशि दर्ज करें",
"dateRequired": "तारीख आवश्यक है",
"catFood": "भोजन",
"catFood": "Food",
"catRent": "किराया",
"catInsurance": "बीमा",
"catMobility": "परिवहन",
"catLeisure": "मनोरंजन",
"catLeisure": "Leisure and Entertainment",
"catClothing": "कपड़े",
"catHealth": "स्वास्थ्य",
"catEducation": "शिक्षा",
"catEducation": "Education",
"catMisc": "विविध",
"catEarnedIncome": "कमाई आय",
"catInvestmentIncome": "निवेश आय",
"catTransferGiftIncome": "स्थानांतरण और उपहार",
"catGovernmentBenefits": "सामाजिक लाभ",
"catOtherIncome": "अन्य आय",
"loadingIndicator": "लोड हो रहा है…"
"loadingIndicator": "लोड हो रहा है…",
"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": "सेटिंग्स",
+76 -29
View File
@@ -43,7 +43,7 @@
"main": "Navigazione principale",
"navigation": "Navigazione",
"quickActions": "Azioni rapide",
"recipes": "Ricette",
"recipes": "Recipes",
"more": "Altro"
},
"dashboard": {
@@ -255,10 +255,10 @@
"recipeUrlLabel": "Link ricetta (opzionale)",
"recipeUrlPlaceholder": "https://…",
"openRecipe": "Apri ricetta",
"savedRecipeLabel": "Ricette salvate",
"savedRecipePlaceholder": "Seleziona ricetta",
"saveAsRecipe": "Salva come ricetta",
"recipeScaleLabel": "Scala ingredienti"
"savedRecipeLabel": "Saved recipe",
"savedRecipePlaceholder": "Select recipe",
"saveAsRecipe": "Save as recipe",
"recipeScaleLabel": "Scale ingredients"
},
"calendar": {
"title": "Calendario",
@@ -463,11 +463,11 @@
"trendNeutral": "- come {{month}}",
"validAmountRequired": "Inserisci un importo valido",
"dateRequired": "La data è obbligatoria",
"catFood": "Spesa alimentare",
"catFood": "Alimentazione",
"catRent": "Affitto",
"catInsurance": "Assicurazione",
"catMobility": "Trasporti",
"catLeisure": "Tempo libero",
"catLeisure": "Tempo libero e intrattenimento",
"catClothing": "Abbigliamento",
"catHealth": "Salute",
"catEducation": "Istruzione",
@@ -477,7 +477,54 @@
"catTransferGiftIncome": "Trasferimenti e Regali",
"catGovernmentBenefits": "Prestazioni Sociali",
"catOtherIncome": "Altro Reddito",
"loadingIndicator": "Caricamento…"
"loadingIndicator": "Caricamento…",
"subcategoryLabel": "Sottocategoria",
"catHousing": "Abitazione / Casa",
"catTransport": "Trasporti",
"catPersonalHealth": "Cura personale / Salute",
"catShoppingClothing": "Acquisti e abbigliamento",
"catFinancialOther": "Servizi finanziari e altro",
"subcatRentMortgage": "Affitto / Mutuo",
"subcatCondominium": "Condominio",
"subcatUtilities": "Luce / Acqua / Gas",
"subcatInternetTvPhone": "Internet / TV / Telefono",
"subcatRenovationMaintenance": "Ristrutturazione / Manutenzione",
"subcatCleaning": "Pulizia",
"subcatGroceries": "Supermercato",
"subcatRestaurantsBars": "Ristoranti / Bar",
"subcatSnacksFastFood": "Snack / Fast food",
"subcatBakery": "Panetteria",
"subcatFuel": "Carburante",
"subcatParkingTolls": "Parcheggio / Pedaggi",
"subcatPublicTransport": "Trasporto pubblico",
"subcatAppsTaxi": "App / Taxi",
"subcatMaintenanceInsurance": "Manutenzione / Assicurazione",
"subcatPharmacy": "Farmacia",
"subcatHealthInsurance": "Assicurazione sanitaria",
"subcatGymSports": "Palestra / Sport",
"subcatBeautyCosmetics": "Bellezza / Cosmetici",
"subcatTravel": "Viaggi",
"subcatStreaming": "Streaming",
"subcatEvents": "Eventi",
"subcatHobbies": "Hobby",
"subcatClothesShoes": "Vestiti / Scarpe",
"subcatElectronics": "Elettronica",
"subcatGifts": "Regali",
"subcatCoursesCollege": "Corsi / Università",
"subcatSchoolSupplies": "Materiale scolastico",
"subcatLanguages": "Lingue",
"subcatLoansInterest": "Prestiti / Interessi",
"subcatBankFees": "Commissioni bancarie",
"subcatInsuranceOther": "Assicurazioni",
"subcatInvestments": "Investimenti",
"subcatTaxes": "Imposte",
"metaLoadError": "Impossibile caricare le categorie del budget.",
"addCategory": "+ categoria",
"addSubcategory": "+ sottocategoria",
"newCategoryPrompt": "Nome della nuova categoria:",
"newSubcategoryPrompt": "Nome della nuova sottocategoria:",
"categoryAddedToast": "Categoria aggiunta.",
"subcategoryAddedToast": "Sottocategoria aggiunta."
},
"settings": {
"title": "Impostazioni",
@@ -659,28 +706,28 @@
"unitMonths": "mesi"
},
"recipes": {
"title": "Ricette",
"addRecipe": "Aggiungi ricetta",
"editRecipe": "Modifica ricetta",
"emptyTitle": "Nessuna ricetta",
"emptyDescription": "Salva le tue ricette preferite e riutilizzale nella pianificazione dei pasti.",
"titleLabel": "Titolo *",
"titlePlaceholder": "es. Pasta Carbonara",
"notesLabel": "Note",
"notesPlaceholder": "Opzionale...",
"urlLabel": "Link della ricetta",
"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": "Ingredienti",
"addToMeals": "Aggiungi al piano alimentare",
"openLink": "Apri il link della ricetta",
"deleteConfirm": "Eliminare la ricetta \"{{title}}\"?",
"created": "Ricetta salvata.",
"updated": "Ricetta aggiornata.",
"deleted": "Ricetta eliminata.",
"titleRequired": "È richiesto il titolo",
"duplicate": "Duplicato",
"duplicated": "Ricetta duplicata.",
"copySuffix": "copia"
"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": "Ricerca",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- {{month}} と同じ",
"validAmountRequired": "有効な金額を入力してください",
"dateRequired": "日付は必須です",
"catFood": "食費",
"catFood": "Food",
"catRent": "家賃",
"catInsurance": "保険",
"catMobility": "交通費",
"catLeisure": "娯楽",
"catLeisure": "Leisure and Entertainment",
"catClothing": "衣服",
"catHealth": "医療",
"catEducation": "教育",
"catEducation": "Education",
"catMisc": "その他",
"catEarnedIncome": "給与・報酬",
"catInvestmentIncome": "投資収入",
"catTransferGiftIncome": "譲渡・贈与",
"catGovernmentBenefits": "社会保障給付",
"catOtherIncome": "その他の収入",
"loadingIndicator": "読み込み中…"
"loadingIndicator": "読み込み中…",
"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": "設定",
+49 -2
View File
@@ -467,7 +467,7 @@
"catRent": "Aluguel",
"catInsurance": "Seguro",
"catMobility": "Transporte",
"catLeisure": "Lazer",
"catLeisure": "Lazer e Entretenimento",
"catClothing": "Roupas",
"catHealth": "Saúde",
"catEducation": "Educação",
@@ -477,7 +477,54 @@
"catTransferGiftIncome": "Transferências e Presentes",
"catGovernmentBenefits": "Benefícios Sociais",
"catOtherIncome": "Outras Rendas",
"loadingIndicator": "Carregando…"
"loadingIndicator": "Carregando…",
"subcategoryLabel": "Subcategoria",
"catHousing": "Habitação / Casa",
"catTransport": "Transporte",
"catPersonalHealth": "Cuidados Pessoais / Saúde",
"catShoppingClothing": "Compras e Vestuário",
"catFinancialOther": "Serviços Financeiros e Outros",
"subcatRentMortgage": "Aluguel / Prestação",
"subcatCondominium": "Condomínio",
"subcatUtilities": "Luz / Água / Gás",
"subcatInternetTvPhone": "Internet / TV / Telefone",
"subcatRenovationMaintenance": "Reforma / Manutenção",
"subcatCleaning": "Limpeza",
"subcatGroceries": "Supermercado",
"subcatRestaurantsBars": "Restaurante / Bares",
"subcatSnacksFastFood": "Lanches / Fast Food",
"subcatBakery": "Padaria",
"subcatFuel": "Combustível",
"subcatParkingTolls": "Estacionamento / Pedágio",
"subcatPublicTransport": "Transporte Público",
"subcatAppsTaxi": "Aplicativos / Táxi",
"subcatMaintenanceInsurance": "Manutenção / Seguro",
"subcatPharmacy": "Farmácia",
"subcatHealthInsurance": "Plano de Saúde",
"subcatGymSports": "Academia / Esportes",
"subcatBeautyCosmetics": "Beleza / Cosméticos",
"subcatTravel": "Viagens",
"subcatStreaming": "Streaming",
"subcatEvents": "Eventos",
"subcatHobbies": "Hobbies",
"subcatClothesShoes": "Roupas / Calçados",
"subcatElectronics": "Eletrônicos",
"subcatGifts": "Presentes",
"subcatCoursesCollege": "Cursos / Faculdade",
"subcatSchoolSupplies": "Material Escolar",
"subcatLanguages": "Idiomas",
"subcatLoansInterest": "Empréstimos / Juros",
"subcatBankFees": "Tarifas Bancárias",
"subcatInsuranceOther": "Seguros",
"subcatInvestments": "Investimentos",
"subcatTaxes": "Impostos",
"metaLoadError": "Categorias do orçamento não puderam ser carregadas.",
"addCategory": "+ categoria",
"addSubcategory": "+ subcategoria",
"newCategoryPrompt": "Nome da nova categoria:",
"newSubcategoryPrompt": "Nome da nova subcategoria:",
"categoryAddedToast": "Categoria adicionada.",
"subcategoryAddedToast": "Subcategoria adicionada."
},
"settings": {
"title": "Configurações",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "— как в {{month}}",
"validAmountRequired": "Введите корректную сумму",
"dateRequired": "Дата обязательна",
"catFood": "Продукты",
"catFood": "Food",
"catRent": "Аренда",
"catInsurance": "Страховка",
"catMobility": "Транспорт",
"catLeisure": "Досуг",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Одежда",
"catHealth": "Здоровье",
"catEducation": "Образование",
"catEducation": "Education",
"catMisc": "Разное",
"catEarnedIncome": "Трудовой доход",
"catInvestmentIncome": "Инвестиционный доход",
"catTransferGiftIncome": "Переводы и подарки",
"catGovernmentBenefits": "Социальные пособия",
"catOtherIncome": "Прочие доходы",
"loadingIndicator": "Загрузка…"
"loadingIndicator": "Загрузка…",
"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": "Настройки",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- samma som {{month}}",
"validAmountRequired": "Ange ett giltigt belopp",
"dateRequired": "Datum krävs",
"catFood": "Specerier",
"catFood": "Food",
"catRent": "Hyra",
"catInsurance": "Försäkring",
"catMobility": "Transport",
"catLeisure": "Fritid",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Kläder",
"catHealth": "Hälsa",
"catEducation": "Utbildning",
"catEducation": "Education",
"catMisc": "Diverse",
"catEarnedIncome": "Arbetsinkomst",
"catInvestmentIncome": "Investeringsinkomst",
"catTransferGiftIncome": "Överföringar och gåvor",
"catGovernmentBenefits": "Socialförmåner",
"catOtherIncome": "Övrig inkomst",
"loadingIndicator": "Laddar…"
"loadingIndicator": "Laddar…",
"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": "Inställningar",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- {{month}} ile aynı",
"validAmountRequired": "Lütfen geçerli bir tutar girin",
"dateRequired": "Tarih zorunludur",
"catFood": "Market",
"catFood": "Food",
"catRent": "Kira",
"catInsurance": "Sigorta",
"catMobility": "Ulaşım",
"catLeisure": "Eğlence",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Giyim",
"catHealth": "Sağlık",
"catEducation": "Eğitim",
"catEducation": "Education",
"catMisc": "Diğer",
"catEarnedIncome": "Kazanç Geliri",
"catInvestmentIncome": "Yatırım Geliri",
"catTransferGiftIncome": "Transferler ve Hediyeler",
"catGovernmentBenefits": "Sosyal Yardımlar",
"catOtherIncome": "Diğer Gelir",
"loadingIndicator": "Yükleniyor…"
"loadingIndicator": "Yükleniyor…",
"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": "Ayarlar",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "— так само, як у {{month}}",
"validAmountRequired": "Будь ласка, введіть коректну суму",
"dateRequired": "Дата є обов'язковою",
"catFood": "Продукти",
"catFood": "Food",
"catRent": "Оренда",
"catInsurance": "Страхування",
"catMobility": "Транспорт",
"catLeisure": "Дозвілля",
"catLeisure": "Leisure and Entertainment",
"catClothing": "Одяг",
"catHealth": "Здоров'я",
"catEducation": "Освіта",
"catEducation": "Education",
"catMisc": "Різне",
"catEarnedIncome": "Трудовий дохід",
"catInvestmentIncome": "Інвестиційний дохід",
"catTransferGiftIncome": "Переводи та подарунки",
"catGovernmentBenefits": "Соціальні виплати",
"catOtherIncome": "Інші доходи",
"loadingIndicator": "Завантаження…"
"loadingIndicator": "Завантаження…",
"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": "Налаштування",
+51 -4
View File
@@ -463,21 +463,68 @@
"trendNeutral": "- 与 {{month}} 相同",
"validAmountRequired": "请输入有效金额",
"dateRequired": "日期为必填项",
"catFood": "食品",
"catFood": "Food",
"catRent": "租金",
"catInsurance": "保险",
"catMobility": "出行",
"catLeisure": "休闲",
"catLeisure": "Leisure and Entertainment",
"catClothing": "服装",
"catHealth": "健康",
"catEducation": "教育",
"catEducation": "Education",
"catMisc": "其他",
"catEarnedIncome": "劳动收入",
"catInvestmentIncome": "投资收入",
"catTransferGiftIncome": "转账和礼物",
"catGovernmentBenefits": "社会福利",
"catOtherIncome": "其他收入",
"loadingIndicator": "加载中…"
"loadingIndicator": "加载中…",
"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": "设置",
+191 -38
View File
@@ -15,29 +15,16 @@ import { esc } from '/utils/html.js';
// Konstanten
// --------------------------------------------------------
const EXPENSE_CATEGORIES = [
'Lebensmittel', 'Miete', 'Versicherung', 'Mobilität',
'Freizeit', 'Kleidung', 'Gesundheit', 'Bildung', 'Sonstiges',
];
const INCOME_CATEGORIES = [
'Erwerbseinkommen', 'Kapitalerträge', 'Geschenke & Transfers',
'Sozialleistungen', 'Sonstiges Einkommen',
];
const CATEGORIES = [...EXPENSE_CATEGORIES, ...INCOME_CATEGORIES];
const CATEGORY_LABELS = () => ({
const CATEGORY_I18N = () => ({
// Expense categories
'Lebensmittel': t('budget.catFood'),
'Miete': t('budget.catRent'),
'Versicherung': t('budget.catInsurance'),
'Mobilität': t('budget.catMobility'),
'Freizeit': t('budget.catLeisure'),
'Kleidung': t('budget.catClothing'),
'Gesundheit': t('budget.catHealth'),
'Bildung': t('budget.catEducation'),
'Sonstiges': t('budget.catMisc'),
housing: t('budget.catHousing'),
food: t('budget.catFood'),
transport: t('budget.catTransport'),
personal_health: t('budget.catPersonalHealth'),
leisure: t('budget.catLeisure'),
shopping_clothing: t('budget.catShoppingClothing'),
education: t('budget.catEducation'),
financial_other: t('budget.catFinancialOther'),
// Income categories
'Erwerbseinkommen': t('budget.catEarnedIncome'),
'Kapitalerträge': t('budget.catInvestmentIncome'),
@@ -46,6 +33,82 @@ const CATEGORY_LABELS = () => ({
'Sonstiges Einkommen': t('budget.catOtherIncome'),
});
const SUBCATEGORY_I18N = () => ({
rent_mortgage: t('budget.subcatRentMortgage'),
condominium: t('budget.subcatCondominium'),
utilities: t('budget.subcatUtilities'),
internet_tv_phone: t('budget.subcatInternetTvPhone'),
renovation_maintenance: t('budget.subcatRenovationMaintenance'),
cleaning: t('budget.subcatCleaning'),
groceries: t('budget.subcatGroceries'),
restaurants_bars: t('budget.subcatRestaurantsBars'),
snacks_fast_food: t('budget.subcatSnacksFastFood'),
bakery: t('budget.subcatBakery'),
fuel: t('budget.subcatFuel'),
parking_tolls: t('budget.subcatParkingTolls'),
public_transport: t('budget.subcatPublicTransport'),
apps_taxi: t('budget.subcatAppsTaxi'),
maintenance_insurance: t('budget.subcatMaintenanceInsurance'),
pharmacy: t('budget.subcatPharmacy'),
health_insurance: t('budget.subcatHealthInsurance'),
gym_sports: t('budget.subcatGymSports'),
beauty_cosmetics: t('budget.subcatBeautyCosmetics'),
travel: t('budget.subcatTravel'),
streaming: t('budget.subcatStreaming'),
events: t('budget.subcatEvents'),
hobbies: t('budget.subcatHobbies'),
clothes_shoes: t('budget.subcatClothesShoes'),
electronics: t('budget.subcatElectronics'),
gifts: t('budget.subcatGifts'),
courses_college: t('budget.subcatCoursesCollege'),
school_supplies: t('budget.subcatSchoolSupplies'),
languages: t('budget.subcatLanguages'),
loans_interest: t('budget.subcatLoansInterest'),
bank_fees: t('budget.subcatBankFees'),
insurance_other: t('budget.subcatInsuranceOther'),
investments: t('budget.subcatInvestments'),
taxes: t('budget.subcatTaxes'),
});
function categoryLabel(category) {
const item = typeof category === 'object'
? category
: [...expenseCategories(), ...incomeCategories()].find((c) => c.key === category);
const key = item?.key ?? category;
const name = item?.name ?? category;
return CATEGORY_I18N()[key] ?? name;
}
function subcategoryLabel(subcategory) {
const item = typeof subcategory === 'object'
? subcategory
: Object.values(state.meta.expenseSubcategories ?? {}).flat().find((s) => s.key === subcategory);
const key = item?.key ?? subcategory;
const name = item?.name ?? subcategory;
return SUBCATEGORY_I18N()[key] ?? name;
}
function expenseCategories() {
return state.meta.expenseCategories ?? [];
}
function incomeCategories() {
return state.meta.incomeCategories ?? [];
}
function getSubcategories(category) {
return state.meta.expenseSubcategories?.[category] || [];
}
function defaultSubcategory(category) {
return getSubcategories(category)[0]?.key || '';
}
function defaultCategory(type) {
const cats = type === 'income' ? incomeCategories() : expenseCategories();
return cats[0]?.key || '';
}
function getMonthName(monthIndex) {
// monthIndex: 0-based (0=Januar, 11=Dezember)
const date = new Date(2000, monthIndex, 1);
@@ -62,6 +125,7 @@ let state = {
summary: null,
prevSummary: null, // Vormonat für Monatsvergleich
currency: 'EUR',
meta: { expenseCategories: [], incomeCategories: [], expenseSubcategories: {} },
};
let _container = null;
@@ -110,6 +174,21 @@ async function loadMonth(month) {
}
}
async function loadBudgetMeta() {
try {
const res = await api.get('/budget/meta');
state.meta = {
expenseCategories: res.data?.expenseCategories ?? [],
incomeCategories: res.data?.incomeCategories ?? [],
expenseSubcategories: res.data?.expenseSubcategories ?? {},
};
} catch (err) {
console.error('[Budget] meta Fehler:', err);
state.meta = { expenseCategories: [], incomeCategories: [], expenseSubcategories: {} };
window.oikos?.showToast(t('budget.metaLoadError'), 'danger');
}
}
// --------------------------------------------------------
// Entry Point
// --------------------------------------------------------
@@ -120,7 +199,10 @@ export async function render(container, { user }) {
state.month = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}`;
try {
const prefsRes = await api.get('/preferences');
const [prefsRes] = await Promise.all([
api.get('/preferences'),
loadBudgetMeta(),
]);
state.currency = prefsRes.data?.currency ?? 'EUR';
} catch (_) { /* Fallback auf EUR */ }
@@ -274,7 +356,7 @@ function renderCategoryBars(byCategory) {
return `
<div class="budget-bar-row">
<div class="budget-bar-row__label" title="${esc(CATEGORY_LABELS()[c.category] ?? c.category)}">${esc(CATEGORY_LABELS()[c.category] ?? c.category)}</div>
<div class="budget-bar-row__label" title="${esc(categoryLabel(c.category))}">${esc(categoryLabel(c.category))}</div>
<div class="budget-bar-row__track">
<div class="budget-bar-row__fill ${cls}" style="width:${pct}%;"></div>
</div>
@@ -305,13 +387,16 @@ function renderEntries() {
const sign = isIncome ? '+' : '';
const date = formatEntryDate(e.date);
const recurTag = e.is_recurring ? ' 🔁' : (e.recurrence_parent_id ? ' ↩' : '');
const categoryMeta = isIncome || !e.subcategory
? categoryLabel(e.category)
: `${categoryLabel(e.category)} · ${subcategoryLabel(e.subcategory)}`;
return `
<div class="budget-entry" data-id="${e.id}">
<div class="budget-entry__indicator ${indClass}"></div>
<div class="budget-entry__body">
<div class="budget-entry__title">${esc(e.title)}</div>
<div class="budget-entry__meta">${date} · ${esc(CATEGORY_LABELS()[e.category] ?? e.category)}${recurTag}</div>
<div class="budget-entry__meta">${date} · ${esc(categoryMeta)}${recurTag}</div>
</div>
<div class="budget-entry__amount ${amtClass}">${sign}${formatAmount(e.amount)}</div>
<button class="budget-entry__delete" data-action="delete" data-id="${e.id}" aria-label="${t('budget.deleteLabel')}">
@@ -359,10 +444,14 @@ function openBudgetModal({ mode, entry = null }) {
const isExpense = isEdit ? entry.amount < 0 : true;
const absAmount = isEdit ? Math.abs(entry.amount).toFixed(2) : '';
const catLabels = CATEGORY_LABELS();
const initialCats = isExpense ? EXPENSE_CATEGORIES : INCOME_CATEGORIES;
const initialCats = isExpense ? expenseCategories() : incomeCategories();
const catOpts = initialCats.map((c) =>
`<option value="${c}" ${isEdit && entry.category === c ? 'selected' : ''}>${catLabels[c] || c}</option>`
`<option value="${esc(c.key)}" ${isEdit && entry.category === c.key ? 'selected' : ''}>${esc(categoryLabel(c))}</option>`
).join('');
const initialCategory = isEdit ? entry.category : initialCats[0]?.key;
const initialSubcategory = isEdit ? entry.subcategory : defaultSubcategory(initialCategory);
const subcatOpts = getSubcategories(initialCategory).map((s) =>
`<option value="${esc(s.key)}" ${initialSubcategory === s.key ? 'selected' : ''}>${esc(subcategoryLabel(s))}</option>`
).join('');
const content = `
@@ -387,10 +476,21 @@ function openBudgetModal({ mode, entry = null }) {
</div>
<div class="form-group">
<label class="form-label" for="bm-category">${t('budget.categoryLabel')}</label>
<div class="budget-field-header">
<label class="form-label" for="bm-category">${t('budget.categoryLabel')}</label>
<button class="btn btn--secondary budget-inline-add" type="button" id="bm-add-category">${t('budget.addCategory')}</button>
</div>
<select class="form-input" id="bm-category">${catOpts}</select>
</div>
<div class="form-group" id="bm-subcategory-group" ${isExpense ? '' : 'hidden'}>
<div class="budget-field-header">
<label class="form-label" for="bm-subcategory">${t('budget.subcategoryLabel')}</label>
<button class="btn btn--secondary budget-inline-add" type="button" id="bm-add-subcategory">${t('budget.addSubcategory')}</button>
</div>
<select class="form-input" id="bm-subcategory">${subcatOpts}</select>
</div>
<div class="form-group">
<label class="form-label" for="bm-date">${t('budget.dateLabel')}</label>
<input type="date" class="form-input" id="bm-date"
@@ -422,20 +522,70 @@ function openBudgetModal({ mode, entry = null }) {
onSave(panel) {
let currentType = isExpense ? 'expense' : 'income';
const updateCategoryOptions = () => {
const catLabels = CATEGORY_LABELS();
const cats = currentType === 'income' ? INCOME_CATEGORIES : EXPENSE_CATEGORIES;
const updateCategoryOptions = (preferredCategory = '') => {
const cats = currentType === 'income' ? incomeCategories() : expenseCategories();
const catSelect = panel.querySelector('#bm-category');
const currentValue = catSelect.value;
const currentValue = preferredCategory || catSelect.value;
const options = cats.map((c) => {
const opt = document.createElement('option');
opt.value = c;
opt.textContent = catLabels[c] || c;
opt.selected = currentValue === c;
opt.value = c.key;
opt.textContent = categoryLabel(c);
opt.selected = currentValue === c.key;
return opt;
});
catSelect.replaceChildren(...options);
if (!cats.some((c) => c.key === catSelect.value)) catSelect.value = cats[0]?.key || '';
updateSubcategoryOptions();
};
const updateSubcategoryOptions = (preferredSubcategory = '') => {
const catSelect = panel.querySelector('#bm-category');
const subcatGroup = panel.querySelector('#bm-subcategory-group');
const subcatSelect = panel.querySelector('#bm-subcategory');
const subcategories = currentType === 'expense' ? getSubcategories(catSelect.value) : [];
const currentValue = preferredSubcategory || subcatSelect.value;
subcatGroup.hidden = currentType !== 'expense';
subcatSelect.replaceChildren(...subcategories.map((s) => {
const opt = document.createElement('option');
opt.value = s.key;
opt.textContent = subcategoryLabel(s);
opt.selected = currentValue === s.key;
return opt;
}));
if (subcategories.length && !subcategories.some((s) => s.key === subcatSelect.value)) {
subcatSelect.value = subcategories[0].key;
}
};
const addCategory = async () => {
const name = window.prompt(t('budget.newCategoryPrompt'));
if (!name?.trim()) return;
try {
const res = await api.post('/budget/categories', { name: name.trim(), type: currentType });
await loadBudgetMeta();
updateCategoryOptions(res.data.key);
window.oikos?.showToast(t('budget.categoryAddedToast'), 'success');
} catch (err) {
window.oikos?.showToast(err.data?.error ?? t('common.unknownError'), 'error');
}
};
const addSubcategory = async () => {
if (currentType !== 'expense') return;
const category = panel.querySelector('#bm-category').value;
if (!category) return;
const name = window.prompt(t('budget.newSubcategoryPrompt'));
if (!name?.trim()) return;
try {
const res = await api.post(`/budget/categories/${encodeURIComponent(category)}/subcategories`, { name: name.trim() });
await loadBudgetMeta();
updateSubcategoryOptions(res.data.key);
window.oikos?.showToast(t('budget.subcategoryAddedToast'), 'success');
} catch (err) {
window.oikos?.showToast(err.data?.error ?? t('common.unknownError'), 'error');
}
};
panel.querySelector('#type-expense').addEventListener('click', () => {
@@ -450,6 +600,9 @@ function openBudgetModal({ mode, entry = null }) {
panel.querySelector('#type-expense').classList.remove('amount-type-btn--active');
updateCategoryOptions();
});
panel.querySelector('#bm-category').addEventListener('change', () => updateSubcategoryOptions());
panel.querySelector('#bm-add-category').addEventListener('click', addCategory);
panel.querySelector('#bm-add-subcategory').addEventListener('click', addSubcategory);
panel.querySelector('#bm-cancel').addEventListener('click', closeModal);
@@ -463,6 +616,7 @@ function openBudgetModal({ mode, entry = null }) {
const title = panel.querySelector('#bm-title').value.trim();
const absVal = parseFloat(panel.querySelector('#bm-amount').value);
const category = panel.querySelector('#bm-category').value;
const subcategory = currentType === 'expense' ? panel.querySelector('#bm-subcategory').value : '';
const date = panel.querySelector('#bm-date').value;
const recurring = panel.querySelector('#bm-recurring').checked ? 1 : 0;
@@ -476,7 +630,7 @@ function openBudgetModal({ mode, entry = null }) {
saveBtn.textContent = '…';
try {
const body = { title, amount, category, date, is_recurring: recurring };
const body = { title, amount, category, subcategory, date, is_recurring: recurring };
if (mode === 'create') {
const res = await api.post('/budget', body);
state.entries.unshift(res.data);
@@ -523,4 +677,3 @@ async function deleteEntry(id) {
// --------------------------------------------------------
// Hilfsfunktion
// --------------------------------------------------------
+17
View File
@@ -331,3 +331,20 @@
color: var(--color-text-on-accent);
}
.budget-field-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
margin-bottom: var(--space-1);
}
.budget-field-header .form-label {
margin-bottom: 0;
}
.budget-inline-add {
min-height: auto;
padding: 2px var(--space-2);
font-size: var(--text-xs);
}
+3 -3
View File
@@ -13,9 +13,9 @@
* → bypassCacheUntil (in-memory + Cache API für SW-Restart-Robustheit)
*/
const SHELL_CACHE = 'oikos-shell-v50';
const PAGES_CACHE = 'oikos-pages-v45';
const ASSETS_CACHE = 'oikos-assets-v45';
const SHELL_CACHE = 'oikos-shell-v52';
const PAGES_CACHE = 'oikos-pages-v47';
const ASSETS_CACHE = 'oikos-assets-v47';
const BYPASS_CACHE = 'oikos-bypass-flag';
const ALL_CACHES = [SHELL_CACHE, PAGES_CACHE, ASSETS_CACHE];