feat: v1.1.0 - Docker, i18n, setup wizard, rate limiting, OpenAPI
New features: - Docker support (Dockerfile + docker-compose.yml) - GitHub Actions CI pipeline (PHP lint, JS lint, Docker build, i18n validation) - Internationalization system with 3 languages (it, en, de) and 347 translation keys - First-run setup wizard (4-step configuration) - File-based API rate limiting (120/15/5 req/min tiers) - OpenAPI 3.1.0 specification for all 43 API endpoints - CONTRIBUTING.md with translation and development guide - Screenshots directory placeholder Modified: - README.md: Docker badges, install instructions, translations section - api/index.php: rate limiting middleware - assets/js/app.js: i18n system, setup wizard, t() function - assets/css/style.css: setup wizard styles - index.html: data-i18n attributes, setup wizard overlay, language settings - .gitignore: rate_limits exclusion
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "Dispensa Manager",
|
||||
"loading": "Laden..."
|
||||
},
|
||||
"nav": {
|
||||
"title": "🏠 Vorratskammer",
|
||||
"home": "Home",
|
||||
"inventory": "Vorrat",
|
||||
"recipes": "Rezepte",
|
||||
"shopping": "Einkauf",
|
||||
"log": "Log"
|
||||
},
|
||||
"btn": {
|
||||
"back": "← Zurück",
|
||||
"save": "💾 Speichern",
|
||||
"cancel": "✕ Abbrechen",
|
||||
"close": "Schließen",
|
||||
"add": "✅ Hinzufügen",
|
||||
"delete": "Löschen",
|
||||
"edit": "✏️ Bearbeiten",
|
||||
"search": "🔍 Suchen",
|
||||
"go": "✅ Los",
|
||||
"toggle_password": "👁️ Anzeigen/Ausblenden",
|
||||
"load_more": "Mehr laden...",
|
||||
"save_config": "💾 Konfiguration speichern",
|
||||
"save_product": "💾 Produkt speichern",
|
||||
"restart": "↺ Neustart",
|
||||
"reset_default": "↺ Standard wiederherstellen"
|
||||
},
|
||||
"locations": {
|
||||
"dispensa": "Vorratskammer",
|
||||
"frigo": "Kühlschrank",
|
||||
"freezer": "Gefrierschrank",
|
||||
"altro": "Sonstiges"
|
||||
},
|
||||
"categories": {
|
||||
"latticini": "Milchprodukte",
|
||||
"carne": "Fleisch",
|
||||
"pesce": "Fisch",
|
||||
"frutta": "Obst",
|
||||
"verdura": "Gemüse",
|
||||
"pasta": "Pasta & Reis",
|
||||
"pane": "Brot & Backwaren",
|
||||
"surgelati": "Tiefkühl",
|
||||
"bevande": "Getränke",
|
||||
"condimenti": "Gewürze",
|
||||
"snack": "Snacks & Süßes",
|
||||
"conserve": "Konserven",
|
||||
"cereali": "Getreide & Hülsenfrüchte",
|
||||
"igiene": "Hygiene",
|
||||
"pulizia": "Reinigung",
|
||||
"altro": "Sonstiges",
|
||||
"select": "-- Auswählen --"
|
||||
},
|
||||
"units": {
|
||||
"pz": "Stk",
|
||||
"conf": "Pkg",
|
||||
"g": "g",
|
||||
"ml": "ml",
|
||||
"pieces": "Stück",
|
||||
"grams": "Gramm",
|
||||
"box": "Packung",
|
||||
"boxes": "Packungen"
|
||||
},
|
||||
"shopping_sections": {
|
||||
"frutta_verdura": "Obst & Gemüse",
|
||||
"carne_pesce": "Fleisch & Fisch",
|
||||
"latticini": "Milchprodukte & Frisches",
|
||||
"pane_dolci": "Brot & Süßes",
|
||||
"pasta": "Pasta & Getreide",
|
||||
"conserve": "Konserven & Soßen",
|
||||
"surgelati": "Tiefkühl",
|
||||
"bevande": "Getränke",
|
||||
"pulizia_igiene": "Reinigung & Hygiene",
|
||||
"altro": "Sonstiges"
|
||||
},
|
||||
"dashboard": {
|
||||
"expired_title": "🚫 Abgelaufen",
|
||||
"expiring_title": "⏰ Bald ablaufend",
|
||||
"stats_period": "📊 Letzte 30 Tage",
|
||||
"opened_title": "📦 Geöffnete Produkte",
|
||||
"review_title": "🔍 Zu prüfen",
|
||||
"review_hint": "Mengen, die ungewöhnlich erscheinen. Bestätigen oder ändern.",
|
||||
"quick_recipe": "🍳 Schnelles Rezept mit ablaufenden Produkten"
|
||||
},
|
||||
"inventory": {
|
||||
"title": "Vorrat",
|
||||
"filter_all": "Alle",
|
||||
"search_placeholder": "🔍 Produkt suchen...",
|
||||
"empty": "Keine Produkte hier.\nScanne ein Produkt, um es hinzuzufügen!",
|
||||
"no_items_found": "Keine Bestandseinträge gefunden"
|
||||
},
|
||||
"scan": {
|
||||
"title": "Produkt scannen",
|
||||
"mode_shopping": "🛒 Einkaufsmodus",
|
||||
"mode_shopping_end": "✅ Einkauf beenden",
|
||||
"zoom": "Zoom",
|
||||
"barcode_placeholder": "Barcode eingeben...",
|
||||
"quick_name_divider": "oder Name eingeben",
|
||||
"quick_name_placeholder": "z.B.: Äpfel, Zucchini, Brot...",
|
||||
"manual_entry": "✏️ Manuelle Eingabe",
|
||||
"ai_identify": "🤖 Mit KI identifizieren",
|
||||
"hint": "Barcode scannen, Produktname eingeben oder KI zur Identifikation nutzen",
|
||||
"debug_toggle": "🐛 Debug Log",
|
||||
"barcode_acquired": "🔖 Barcode gescannt: {code}",
|
||||
"scan_barcode": "🔖 Barcode scannen"
|
||||
},
|
||||
"action": {
|
||||
"title": "Was möchtest du tun?",
|
||||
"add_btn": "📥 HINZUFÜGEN",
|
||||
"add_sub": "in Vorrat/Kühlschrank",
|
||||
"use_btn": "📤 VERWENDEN / VERBRAUCHEN",
|
||||
"use_sub": "aus Vorrat/Kühlschrank"
|
||||
},
|
||||
"add": {
|
||||
"title": "Zum Vorrat hinzufügen",
|
||||
"location_label": "📍 Wohin?",
|
||||
"quantity_label": "📦 Menge",
|
||||
"conf_size_label": "📦 Jede Packung enthält:",
|
||||
"conf_size_placeholder": "z.B. 300",
|
||||
"vacuum_label": "🫙 Vakuumiert",
|
||||
"vacuum_hint": "Ablaufdatum wird automatisch verlängert",
|
||||
"submit": "✅ Hinzufügen"
|
||||
},
|
||||
"use": {
|
||||
"title": "Verwenden / Verbrauchen",
|
||||
"location_label": "📍 Woher?",
|
||||
"quantity_label": "Wie viel hast du benutzt?",
|
||||
"partial_hint": "Oder genaue Menge angeben:",
|
||||
"use_all": "🗑️ ALLES verwendet / Aufgebraucht",
|
||||
"submit": "📤 Diese Menge verwenden",
|
||||
"available": "📦 Verfügbar:",
|
||||
"not_in_inventory": "⚠️ Produkt nicht im Bestand.",
|
||||
"expiry_warning": "⚠️ Verwende zuerst die{loc}, die am {date} abläuft — {when}!"
|
||||
},
|
||||
"product": {
|
||||
"title_new": "Neues Produkt",
|
||||
"title_edit": "Produkt bearbeiten",
|
||||
"ai_fill": "📷 Foto machen und mit KI identifizieren",
|
||||
"ai_fill_hint": "KI füllt die Produktfelder automatisch aus",
|
||||
"name_label": "🏷️ Produktname *",
|
||||
"name_placeholder": "z.B.: Vollmilch, Penne Nudeln...",
|
||||
"brand_label": "🏢 Marke",
|
||||
"brand_placeholder": "z.B.: Barilla, Müller, Knorr...",
|
||||
"category_label": "📂 Kategorie",
|
||||
"unit_label": "📏 Maßeinheit",
|
||||
"default_qty_label": "🔢 Standardmenge",
|
||||
"conf_size_label": "📦 Jede Packung enthält:",
|
||||
"conf_size_placeholder": "z.B. 300",
|
||||
"notes_label": "📝 Notizen",
|
||||
"notes_placeholder": "z.B.: laktosefrei, bio, nach dem Öffnen im Kühlschrank aufbewahren...",
|
||||
"barcode_label": "🔖 Barcode",
|
||||
"barcode_placeholder": "Barcode (falls vorhanden)",
|
||||
"barcode_hint": "⚠️ Barcode hinzufügen, damit du beim nächsten Einkauf nur scannen musst!",
|
||||
"submit": "💾 Produkt speichern",
|
||||
"name_required": "Produktname eingeben",
|
||||
"conf_size_required": "Packungsinhalt angeben",
|
||||
"expiry_estimated": "Geschätztes Ablaufdatum:",
|
||||
"scan_expiry": "Ablaufdatum scannen",
|
||||
"expiry_hint": "📝 Du kannst das Datum ändern oder mit der Kamera scannen",
|
||||
"add_batch": "📦 + Charge mit anderem Ablaufdatum",
|
||||
"package_info": "📦 Packung: {info}",
|
||||
"edit_catalog": "⚙️ Produktinfo bearbeiten (Name, Marke, Kategorie…)",
|
||||
"not_recognized": "⚠️ Produkt nicht erkannt",
|
||||
"edit_info": "✏️ Informationen bearbeiten",
|
||||
"modify_details": "BEARBEITEN\nAblauf, Ort…"
|
||||
},
|
||||
"products": {
|
||||
"title": "📦 Alle Produkte",
|
||||
"search_placeholder": "🔍 Produkt suchen...",
|
||||
"empty": "Keine Produkte in der Datenbank.\nScanne ein Produkt zum Starten!",
|
||||
"no_category": "Keine Produkte in dieser Kategorie"
|
||||
},
|
||||
"recipes": {
|
||||
"title": "🍳 Rezepte",
|
||||
"generate": "✨ Neues Rezept generieren"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Einkaufsliste",
|
||||
"bring_loading": "Verbindung zu Bring!...",
|
||||
"tab_to_buy": "🛍️ Zu kaufen",
|
||||
"tab_forecast": "🧠 Vorhersage",
|
||||
"total_label": "💰 Geschätzter Gesamtbetrag",
|
||||
"section_to_buy": "🛍️ Zu kaufen",
|
||||
"suggestions_title": "💡 KI-Vorschläge",
|
||||
"suggestions_add": "✅ Ausgewählte zu Bring! hinzufügen",
|
||||
"search_prices": "🔍 Alle Preise suchen",
|
||||
"suggest_btn": "🤖 Einkaufsvorschläge",
|
||||
"smart_title": "🧠 Intelligente Vorhersagen",
|
||||
"smart_empty": "Keine Vorhersagen verfügbar.<br>Füge Produkte zur Vorratskammer hinzu, um intelligente Vorhersagen zu erhalten.",
|
||||
"smart_filter_all": "Alle",
|
||||
"smart_filter_critical": "🔴 Dringend",
|
||||
"smart_filter_high": "🟠 Bald",
|
||||
"smart_filter_medium": "🟡 Planen",
|
||||
"smart_filter_low": "🟢 Vorhersage",
|
||||
"smart_add": "🛒 Ausgewählte zu Bring! hinzufügen",
|
||||
"empty": "Einkaufsliste leer!\nNutze den Button unten, um Vorschläge zu generieren.",
|
||||
"already_in_list": "🛒 \"{name}\" ist bereits in der Einkaufsliste",
|
||||
"already_in_list_short": "ℹ️ Bereits in der Einkaufsliste",
|
||||
"add_prompt": "Möchtest du es zur Einkaufsliste hinzufügen?",
|
||||
"smart_already": "📊 Intelligenter Einkauf sagt bereits {name} voraus",
|
||||
"all_searched": "Alle Produkte wurden bereits gesucht. Nutze 🔄 für einzelne Suchen.",
|
||||
"search_complete": "Suche abgeschlossen: {count} Produkte",
|
||||
"removed_sufficient": "🧹 {removed} Produkt(e) mit ausreichendem Bestand von der Liste entfernt"
|
||||
},
|
||||
"ai": {
|
||||
"title": "🤖 KI-Identifikation",
|
||||
"capture": "📸 Foto aufnehmen",
|
||||
"retake": "🔄 Neu aufnehmen",
|
||||
"hint": "Mache ein Foto des Produkts und die KI versucht es zu identifizieren",
|
||||
"identifying": "🤖 Identifiziere Produkt...",
|
||||
"no_api_key": "⚠️ Gemini API-Schlüssel nicht konfiguriert.\n<small>Füge GEMINI_API_KEY in der .env Datei auf dem Server hinzu.</small>",
|
||||
"fields_filled": "✅ Felder von KI ausgefüllt"
|
||||
},
|
||||
"log": {
|
||||
"title": "📒 Operationslog"
|
||||
},
|
||||
"chat": {
|
||||
"title": "Gemini Chef",
|
||||
"welcome": "Hallo! Ich bin dein Küchenassistent",
|
||||
"welcome_desc": "Frag mich, dir einen Saft, einen Snack, ein schnelles Gericht zu machen... Ich kenne deinen Vorrat, deine Geräte und deine Vorlieben!",
|
||||
"suggestion_snack": "🍿 Schneller Snack",
|
||||
"suggestion_juice": "🥤 Saft/Smoothie",
|
||||
"suggestion_light": "🥗 Etwas Leichtes",
|
||||
"suggestion_expiry": "⏰ Ablaufende nutzen",
|
||||
"clear": "Neues Gespräch",
|
||||
"placeholder": "Frag etwas..."
|
||||
},
|
||||
"cooking": {
|
||||
"close": "Schließen",
|
||||
"tts_btn": "Vorlesen",
|
||||
"restart": "↺ Neustart",
|
||||
"replay": "🔊 Nochmal",
|
||||
"timer": "⏱️ {time} · Timer",
|
||||
"prev": "◀ Zurück",
|
||||
"next": "Weiter ▶"
|
||||
},
|
||||
"settings": {
|
||||
"title": "⚙️ Einstellungen",
|
||||
"tab_api": "API Keys",
|
||||
"tab_bring": "Bring!",
|
||||
"tab_recipe": "Rezepte",
|
||||
"tab_mealplan": "Wochenplan",
|
||||
"tab_appliances": "Geräte",
|
||||
"tab_spesa": "Online-Einkauf",
|
||||
"tab_camera": "Kamera",
|
||||
"tab_security": "Sicherheit",
|
||||
"tab_tts": "Sprache (TTS)",
|
||||
"tab_language": "Sprache",
|
||||
"gemini": {
|
||||
"title": "🤖 Google Gemini AI",
|
||||
"hint": "API-Schlüssel für Produkterkennung, Ablaufdaten und Rezepte.",
|
||||
"key_label": "Gemini API Key"
|
||||
},
|
||||
"bring": {
|
||||
"title": "🛒 Bring! Einkaufsliste",
|
||||
"hint": "Zugangsdaten für die Bring! Einkaufslisten-Integration.",
|
||||
"email_label": "📧 Bring! E-Mail",
|
||||
"password_label": "🔒 Bring! Passwort"
|
||||
},
|
||||
"recipe": {
|
||||
"title": "🍳 Rezept-Einstellungen",
|
||||
"hint": "Konfiguriere die Standardoptionen für die Rezeptgenerierung.",
|
||||
"persons_label": "👥 Standard-Portionen",
|
||||
"options_label": "🎯 Standard-Rezeptoptionen",
|
||||
"fast": "⚡ Schnelles Gericht",
|
||||
"light": "🥗 Leichte Mahlzeit",
|
||||
"expiry": "⏰ Ablauf-Priorität",
|
||||
"healthy": "💚 Extra Gesund",
|
||||
"opened": "📦 Offene Produkte zuerst",
|
||||
"zerowaste": "♻️ Keine Verschwendung",
|
||||
"dietary_label": "🚫 Unverträglichkeiten / Einschränkungen",
|
||||
"dietary_placeholder": "z.B.: glutenfrei, laktosefrei, vegetarisch..."
|
||||
},
|
||||
"mealplan": {
|
||||
"title": "📅 Wöchentlicher Essensplan",
|
||||
"hint": "Lege die Mahlzeitenart für jeden Tag fest. Wird als Leitfaden bei der Rezeptgenerierung verwendet.",
|
||||
"enabled": "✅ Wöchentlichen Essensplan aktivieren",
|
||||
"legend": "🌤️ = Mittagessen · 🌙 = Abendessen · Tippe auf ein Badge, um es zu ändern.",
|
||||
"types_title": "📋 Verfügbare Typen"
|
||||
},
|
||||
"appliances": {
|
||||
"title": "🔌 Verfügbare Geräte",
|
||||
"hint": "Gib an, welche Geräte du hast. Sie werden bei der Rezeptgenerierung berücksichtigt.",
|
||||
"new_placeholder": "z.B.: Brotbackmaschine, Thermomix, Heißluftfritteuse...",
|
||||
"quick_title": "Schnell hinzufügen:",
|
||||
"oven": "🔥 Backofen",
|
||||
"microwave": "📡 Mikrowelle",
|
||||
"air_fryer": "🍟 Heißluftfritteuse",
|
||||
"bread_maker": "🍞 Brotbackmaschine",
|
||||
"bimby": "🤖 Thermomix/Cookeo",
|
||||
"mixer": "🌀 Küchenmaschine",
|
||||
"steamer": "♨️ Dampfgarer",
|
||||
"pressure_cooker": "🫕 Schnellkochtopf",
|
||||
"toaster": "🍞 Toaster",
|
||||
"blender": "🍹 Mixer",
|
||||
"empty": "Keine Geräte hinzugefügt"
|
||||
},
|
||||
"spesa": {
|
||||
"title": "🛍️ Online-Einkauf",
|
||||
"hint": "Online-Einkaufsanbieter konfigurieren.",
|
||||
"provider_label": "🏪 Anbieter",
|
||||
"email_label": "📧 E-Mail",
|
||||
"password_label": "🔒 Passwort",
|
||||
"login_btn": "🔐 Anmelden",
|
||||
"ai_prompt_label": "🤖 KI-Produktauswahl Prompt",
|
||||
"ai_prompt_placeholder": "Anweisungen für die KI bei der Auswahl zwischen mehreren Produkten...",
|
||||
"ai_prompt_hint": "Die KI verwendet diesen Prompt zur Auswahl des passendsten Produkts. Leer lassen für Standardverhalten.",
|
||||
"configure_first": "Konfiguriere zuerst den Online-Einkauf in den Einstellungen"
|
||||
},
|
||||
"camera": {
|
||||
"title": "📷 Kamera",
|
||||
"hint": "Wähle die Kamera für Barcode-Scanning und KI-Identifikation.",
|
||||
"device_label": "📸 Standardkamera",
|
||||
"back": "📱 Rückkamera (Standard)",
|
||||
"front": "🤳 Frontkamera",
|
||||
"devices_hint": "Bei mehreren Kameras kannst du nach Freigabe der Berechtigungen eine bestimmte aus der Liste oben wählen.",
|
||||
"detect_btn": "🔄 Kameras erkennen"
|
||||
},
|
||||
"security": {
|
||||
"title": "🔒 HTTPS-Zertifikat",
|
||||
"hint": "Wenn der Browser den Fehler \"Verbindung nicht sicher\" (ERR_CERT_AUTHORITY_INVALID) zeigt, installiere das CA-Zertifikat auf dem Gerät.",
|
||||
"download_btn": "📥 CA-Zertifikat herunterladen"
|
||||
},
|
||||
"tts": {
|
||||
"title": "🔊 Sprache & TTS",
|
||||
"hint": "Sprachsynthese über externe REST-API konfigurieren. Rezeptschritte und abgelaufene Timer werden an den Endpunkt gesendet.",
|
||||
"enabled": "✅ TTS aktivieren",
|
||||
"url_label": "🌐 Endpunkt-URL",
|
||||
"method_label": "📡 HTTP-Methode",
|
||||
"auth_label": "🔐 Authentifizierung",
|
||||
"auth_bearer": "Bearer Token",
|
||||
"auth_custom": "Benutzerdefinierter Header",
|
||||
"auth_none": "Keine",
|
||||
"token_label": "🔑 Bearer Token",
|
||||
"custom_header_name": "📋 Header-Name",
|
||||
"custom_header_value": "📋 Header-Wert",
|
||||
"content_type_label": "📄 Content-Type",
|
||||
"payload_key_label": "🗝️ Textfeld im Payload",
|
||||
"payload_key_hint": "Name des JSON-Feldes für den zu lesenden Text (z.B.: message, text).",
|
||||
"extra_fields_label": "➕ Zusätzliche Felder (JSON)",
|
||||
"extra_fields_placeholder": "{\"entity_id\": \"media_player.living_room\"}",
|
||||
"extra_fields_hint": "Zusätzliche Felder im Payload, im JSON-Format. Leer lassen wenn nicht benötigt.",
|
||||
"test_btn": "🔊 Testansage senden"
|
||||
},
|
||||
"language": {
|
||||
"title": "🌐 Sprache",
|
||||
"hint": "Wähle die Sprache der Benutzeroberfläche.",
|
||||
"label": "🌐 Sprache",
|
||||
"restart_notice": "Die Seite wird neu geladen, um die neue Sprache anzuwenden."
|
||||
},
|
||||
"saved": "✅ Konfiguration gespeichert!",
|
||||
"saved_local": "✅ Konfiguration lokal gespeichert",
|
||||
"saved_local_error": "⚠️ Lokal gespeichert, Serverfehler: {error}"
|
||||
},
|
||||
"expiry": {
|
||||
"today": "HEUTE",
|
||||
"tomorrow": "Morgen",
|
||||
"days": "{days} Tage",
|
||||
"expired_days": "Seit {days}T",
|
||||
"expired_yesterday": "Seit gestern",
|
||||
"expired_today": "Heute"
|
||||
},
|
||||
"status": {
|
||||
"ok": "OK",
|
||||
"check": "Prüfen",
|
||||
"discard": "Entsorgen"
|
||||
},
|
||||
"toast": {
|
||||
"product_saved": "Produkt gespeichert!",
|
||||
"product_created": "Produkt erstellt!",
|
||||
"product_updated": "✅ Produkt aktualisiert!",
|
||||
"product_removed": "Produkt entfernt",
|
||||
"updated": "Aktualisiert!",
|
||||
"quantity_confirmed": "✓ Menge bestätigt",
|
||||
"added_to_inventory": "✅ {name} hinzugefügt!",
|
||||
"removed_from_list": "✅ {name} von der Liste entfernt!",
|
||||
"removed_from_list_short": "Von der Liste entfernt",
|
||||
"added_to_shopping": "🛒 Zur Einkaufsliste hinzugefügt!",
|
||||
"removed_from_shopping": "🛒 Von der Einkaufsliste entfernt",
|
||||
"finished_to_bring": "🛒 Produkt aufgebraucht → zu Bring! hinzugefügt",
|
||||
"thrown_away": "🗑️ {name} weggeworfen!",
|
||||
"thrown_away_partial": "🗑️ {qty} {unit} von {name} weggeworfen",
|
||||
"appliance_added": "Gerät hinzugefügt",
|
||||
"item_added": "{name} hinzugefügt"
|
||||
},
|
||||
"error": {
|
||||
"generic": "Fehler",
|
||||
"loading": "Fehler beim Laden des Produkts",
|
||||
"not_found": "Produkt nicht gefunden",
|
||||
"not_found_manual": "Produkt nicht gefunden. Manuell eingeben.",
|
||||
"search": "Suchfehler. Nochmal versuchen.",
|
||||
"search_short": "Suchfehler",
|
||||
"save": "Fehler beim Speichern",
|
||||
"connection": "Verbindungsfehler",
|
||||
"camera": "Kamera nicht verfügbar",
|
||||
"bring_add": "Fehler beim Hinzufügen zu Bring!",
|
||||
"bring_connection": "Bring! Verbindungsfehler",
|
||||
"identification": "Identifikationsfehler",
|
||||
"barcode_empty": "Barcode eingeben",
|
||||
"barcode_format": "Barcode darf nur Zahlen enthalten (4-14 Ziffern)",
|
||||
"min_chars": "Mindestens 2 Zeichen eingeben",
|
||||
"not_in_inventory": "Produkt nicht im Bestand",
|
||||
"appliance_exists": "Gerät bereits vorhanden",
|
||||
"already_exists": "Bereits vorhanden"
|
||||
},
|
||||
"confirm": {
|
||||
"remove_item": "Möchtest du dieses Produkt wirklich aus dem Bestand entfernen?"
|
||||
},
|
||||
"edit": {
|
||||
"title": "{name} bearbeiten"
|
||||
},
|
||||
"screensaver": {
|
||||
"recipe_btn": "Rezepte",
|
||||
"scan_btn": "Produkt scannen"
|
||||
},
|
||||
"days": {
|
||||
"mon": "Montag",
|
||||
"tue": "Dienstag",
|
||||
"wed": "Mittwoch",
|
||||
"thu": "Donnerstag",
|
||||
"fri": "Freitag",
|
||||
"sat": "Samstag",
|
||||
"sun": "Sonntag"
|
||||
},
|
||||
"meal_types": {
|
||||
"lunch": "Mittagessen",
|
||||
"dinner": "Abendessen"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "Dispensa Manager",
|
||||
"loading": "Loading..."
|
||||
},
|
||||
"nav": {
|
||||
"title": "🏠 Pantry",
|
||||
"home": "Home",
|
||||
"inventory": "Pantry",
|
||||
"recipes": "Recipes",
|
||||
"shopping": "Shopping",
|
||||
"log": "Log"
|
||||
},
|
||||
"btn": {
|
||||
"back": "← Back",
|
||||
"save": "💾 Save",
|
||||
"cancel": "✕ Cancel",
|
||||
"close": "Close",
|
||||
"add": "✅ Add",
|
||||
"delete": "Delete",
|
||||
"edit": "✏️ Edit",
|
||||
"search": "🔍 Search",
|
||||
"go": "✅ Go",
|
||||
"toggle_password": "👁️ Show/Hide",
|
||||
"load_more": "Load more...",
|
||||
"save_config": "💾 Save Configuration",
|
||||
"save_product": "💾 Save Product",
|
||||
"restart": "↺ Restart",
|
||||
"reset_default": "↺ Reset to default"
|
||||
},
|
||||
"locations": {
|
||||
"dispensa": "Pantry",
|
||||
"frigo": "Fridge",
|
||||
"freezer": "Freezer",
|
||||
"altro": "Other"
|
||||
},
|
||||
"categories": {
|
||||
"latticini": "Dairy",
|
||||
"carne": "Meat",
|
||||
"pesce": "Fish",
|
||||
"frutta": "Fruit",
|
||||
"verdura": "Vegetables",
|
||||
"pasta": "Pasta & Rice",
|
||||
"pane": "Bread & Bakery",
|
||||
"surgelati": "Frozen",
|
||||
"bevande": "Beverages",
|
||||
"condimenti": "Condiments",
|
||||
"snack": "Snacks & Sweets",
|
||||
"conserve": "Canned Goods",
|
||||
"cereali": "Cereals & Legumes",
|
||||
"igiene": "Hygiene",
|
||||
"pulizia": "Household",
|
||||
"altro": "Other",
|
||||
"select": "-- Select --"
|
||||
},
|
||||
"units": {
|
||||
"pz": "pcs",
|
||||
"conf": "pkg",
|
||||
"g": "g",
|
||||
"ml": "ml",
|
||||
"pieces": "Pieces",
|
||||
"grams": "Grams",
|
||||
"box": "Package",
|
||||
"boxes": "Packages"
|
||||
},
|
||||
"shopping_sections": {
|
||||
"frutta_verdura": "Fruits & Vegetables",
|
||||
"carne_pesce": "Meat & Fish",
|
||||
"latticini": "Dairy & Fresh",
|
||||
"pane_dolci": "Bread & Sweets",
|
||||
"pasta": "Pasta & Cereals",
|
||||
"conserve": "Canned & Sauces",
|
||||
"surgelati": "Frozen",
|
||||
"bevande": "Beverages",
|
||||
"pulizia_igiene": "Cleaning & Hygiene",
|
||||
"altro": "Other"
|
||||
},
|
||||
"dashboard": {
|
||||
"expired_title": "🚫 Expired",
|
||||
"expiring_title": "⏰ Expiring Soon",
|
||||
"stats_period": "📊 Last 30 days",
|
||||
"opened_title": "📦 Opened Products",
|
||||
"review_title": "🔍 To Review",
|
||||
"review_hint": "Quantities that seem unusual. Confirm if correct or modify.",
|
||||
"quick_recipe": "🍳 Quick recipe with expiring products"
|
||||
},
|
||||
"inventory": {
|
||||
"title": "Pantry",
|
||||
"filter_all": "All",
|
||||
"search_placeholder": "🔍 Search product...",
|
||||
"empty": "No products here.\nScan a product to add it!",
|
||||
"no_items_found": "No inventory items found"
|
||||
},
|
||||
"scan": {
|
||||
"title": "Scan Product",
|
||||
"mode_shopping": "🛒 Shopping Mode",
|
||||
"mode_shopping_end": "✅ End shopping",
|
||||
"zoom": "Zoom",
|
||||
"barcode_placeholder": "Enter barcode...",
|
||||
"quick_name_divider": "or type the name",
|
||||
"quick_name_placeholder": "E.g.: Apples, Zucchini, Bread...",
|
||||
"manual_entry": "✏️ Manual Entry",
|
||||
"ai_identify": "🤖 Identify with AI",
|
||||
"hint": "Scan the barcode, type the product name, or use AI to identify it",
|
||||
"debug_toggle": "🐛 Debug Log",
|
||||
"barcode_acquired": "🔖 Barcode scanned: {code}",
|
||||
"scan_barcode": "🔖 Scan Barcode"
|
||||
},
|
||||
"action": {
|
||||
"title": "What do you want to do?",
|
||||
"add_btn": "📥 ADD",
|
||||
"add_sub": "to pantry/fridge",
|
||||
"use_btn": "📤 USE / CONSUME",
|
||||
"use_sub": "from pantry/fridge"
|
||||
},
|
||||
"add": {
|
||||
"title": "Add to Pantry",
|
||||
"location_label": "📍 Where do you put it?",
|
||||
"quantity_label": "📦 Quantity",
|
||||
"conf_size_label": "📦 Each package contains:",
|
||||
"conf_size_placeholder": "e.g. 300",
|
||||
"vacuum_label": "🫙 Vacuum sealed",
|
||||
"vacuum_hint": "Expiry date will be extended automatically",
|
||||
"submit": "✅ Add"
|
||||
},
|
||||
"use": {
|
||||
"title": "Use / Consume",
|
||||
"location_label": "📍 From where?",
|
||||
"quantity_label": "How much did you use?",
|
||||
"partial_hint": "Or specify the quantity used:",
|
||||
"use_all": "🗑️ Used ALL / Finished",
|
||||
"submit": "📤 Use this quantity",
|
||||
"available": "📦 Available:",
|
||||
"not_in_inventory": "⚠️ Product not in inventory.",
|
||||
"expiry_warning": "⚠️ Use first the one{loc} that expires on {date} — {when}!"
|
||||
},
|
||||
"product": {
|
||||
"title_new": "New Product",
|
||||
"title_edit": "Edit Product",
|
||||
"ai_fill": "📷 Take photo and identify with AI",
|
||||
"ai_fill_hint": "AI will automatically fill in the product fields",
|
||||
"name_label": "🏷️ Product Name *",
|
||||
"name_placeholder": "E.g.: Whole milk, Penne pasta...",
|
||||
"brand_label": "🏢 Brand",
|
||||
"brand_placeholder": "E.g.: Barilla, Granarolo, Mutti...",
|
||||
"category_label": "📂 Category",
|
||||
"unit_label": "📏 Unit of measure",
|
||||
"default_qty_label": "🔢 Default quantity",
|
||||
"conf_size_label": "📦 Each package contains:",
|
||||
"conf_size_placeholder": "e.g. 300",
|
||||
"notes_label": "📝 Notes",
|
||||
"notes_placeholder": "E.g.: lactose free, organic, store in fridge after opening...",
|
||||
"barcode_label": "🔖 Barcode",
|
||||
"barcode_placeholder": "Barcode (if available)",
|
||||
"barcode_hint": "⚠️ Add the barcode so next time you just need to scan it!",
|
||||
"submit": "💾 Save Product",
|
||||
"name_required": "Enter the product name",
|
||||
"conf_size_required": "Specify the package content",
|
||||
"expiry_estimated": "Estimated expiry:",
|
||||
"scan_expiry": "Scan expiry date",
|
||||
"expiry_hint": "📝 You can edit the date or scan it with the camera",
|
||||
"add_batch": "📦 + Batch with different expiry",
|
||||
"package_info": "📦 Package: {info}",
|
||||
"edit_catalog": "⚙️ Edit product info (name, brand, category…)",
|
||||
"not_recognized": "⚠️ Product not recognized",
|
||||
"edit_info": "✏️ Edit information",
|
||||
"modify_details": "EDIT\nexpiry, location…"
|
||||
},
|
||||
"products": {
|
||||
"title": "📦 All Products",
|
||||
"search_placeholder": "🔍 Search product...",
|
||||
"empty": "No products in database.\nScan a product to get started!",
|
||||
"no_category": "No products in this category"
|
||||
},
|
||||
"recipes": {
|
||||
"title": "🍳 Recipes",
|
||||
"generate": "✨ Generate new recipe"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Shopping List",
|
||||
"bring_loading": "Connecting to Bring!...",
|
||||
"tab_to_buy": "🛍️ To buy",
|
||||
"tab_forecast": "🧠 Forecast",
|
||||
"total_label": "💰 Estimated total",
|
||||
"section_to_buy": "🛍️ To buy",
|
||||
"suggestions_title": "💡 AI Suggestions",
|
||||
"suggestions_add": "✅ Add selected to Bring!",
|
||||
"search_prices": "🔍 Search all prices",
|
||||
"suggest_btn": "🤖 Suggest what to buy",
|
||||
"smart_title": "🧠 Smart Predictions",
|
||||
"smart_empty": "No predictions available.<br>Add products to your pantry to receive smart predictions.",
|
||||
"smart_filter_all": "All",
|
||||
"smart_filter_critical": "🔴 Urgent",
|
||||
"smart_filter_high": "🟠 Soon",
|
||||
"smart_filter_medium": "🟡 Plan",
|
||||
"smart_filter_low": "🟢 Forecast",
|
||||
"smart_add": "🛒 Add selected to Bring!",
|
||||
"empty": "Shopping list empty!\nUse the button below to generate suggestions.",
|
||||
"already_in_list": "🛒 \"{name}\" is already in the shopping list",
|
||||
"already_in_list_short": "ℹ️ Already in the shopping list",
|
||||
"add_prompt": "Do you want to add it to the shopping list?",
|
||||
"smart_already": "📊 Smart shopping already predicts {name}",
|
||||
"all_searched": "All products have already been searched. Use 🔄 to search individual ones.",
|
||||
"search_complete": "Search complete: {count} products",
|
||||
"removed_sufficient": "🧹 {removed} product(s) with sufficient stock removed from the list"
|
||||
},
|
||||
"ai": {
|
||||
"title": "🤖 AI Identification",
|
||||
"capture": "📸 Take Photo",
|
||||
"retake": "🔄 Retake",
|
||||
"hint": "Take a photo of the product and AI will try to identify it",
|
||||
"identifying": "🤖 Identifying product...",
|
||||
"no_api_key": "⚠️ Gemini API key not configured.\n<small>Add GEMINI_API_KEY to the .env file on the server.</small>",
|
||||
"fields_filled": "✅ Fields filled by AI"
|
||||
},
|
||||
"log": {
|
||||
"title": "📒 Operations Log"
|
||||
},
|
||||
"chat": {
|
||||
"title": "Gemini Chef",
|
||||
"welcome": "Hi! I'm your kitchen assistant",
|
||||
"welcome_desc": "Ask me to make you a juice, a snack, a quick dish... I know your pantry, your appliances and your preferences!",
|
||||
"suggestion_snack": "🍿 Quick snack",
|
||||
"suggestion_juice": "🥤 Juice/Smoothie",
|
||||
"suggestion_light": "🥗 Something light",
|
||||
"suggestion_expiry": "⏰ Use expiring items",
|
||||
"clear": "New conversation",
|
||||
"placeholder": "Ask something..."
|
||||
},
|
||||
"cooking": {
|
||||
"close": "Close",
|
||||
"tts_btn": "Read aloud",
|
||||
"restart": "↺ Restart",
|
||||
"replay": "🔊 Replay",
|
||||
"timer": "⏱️ {time} · Timer",
|
||||
"prev": "◀ Previous",
|
||||
"next": "Next ▶"
|
||||
},
|
||||
"settings": {
|
||||
"title": "⚙️ Settings",
|
||||
"tab_api": "API Keys",
|
||||
"tab_bring": "Bring!",
|
||||
"tab_recipe": "Recipes",
|
||||
"tab_mealplan": "Weekly Plan",
|
||||
"tab_appliances": "Appliances",
|
||||
"tab_spesa": "Online Shopping",
|
||||
"tab_camera": "Camera",
|
||||
"tab_security": "Security",
|
||||
"tab_tts": "Voice (TTS)",
|
||||
"tab_language": "Language",
|
||||
"gemini": {
|
||||
"title": "🤖 Google Gemini AI",
|
||||
"hint": "API key for product identification, expiry dates and recipes.",
|
||||
"key_label": "Gemini API Key"
|
||||
},
|
||||
"bring": {
|
||||
"title": "🛒 Bring! Shopping List",
|
||||
"hint": "Credentials for the Bring! shopping list integration.",
|
||||
"email_label": "📧 Bring! Email",
|
||||
"password_label": "🔒 Bring! Password"
|
||||
},
|
||||
"recipe": {
|
||||
"title": "🍳 Recipe Preferences",
|
||||
"hint": "Configure the default options for recipe generation.",
|
||||
"persons_label": "👥 Default servings",
|
||||
"options_label": "🎯 Default recipe options",
|
||||
"fast": "⚡ Quick Meal",
|
||||
"light": "🥗 Light Meal",
|
||||
"expiry": "⏰ Expiry Priority",
|
||||
"healthy": "💚 Extra Healthy",
|
||||
"opened": "📦 Open Items Priority",
|
||||
"zerowaste": "♻️ Zero Waste",
|
||||
"dietary_label": "🚫 Intolerances / Restrictions",
|
||||
"dietary_placeholder": "E.g.: gluten free, lactose free, vegetarian..."
|
||||
},
|
||||
"mealplan": {
|
||||
"title": "📅 Weekly Meal Plan",
|
||||
"hint": "Set the meal type for each day. It will be used as a guide in recipe generation.",
|
||||
"enabled": "✅ Enable weekly meal plan",
|
||||
"legend": "🌤️ = Lunch · 🌙 = Dinner · Tap a badge to change it.",
|
||||
"types_title": "📋 Available types"
|
||||
},
|
||||
"appliances": {
|
||||
"title": "🔌 Available Appliances",
|
||||
"hint": "Indicate the appliances you have. They will be considered in recipe generation.",
|
||||
"new_placeholder": "E.g.: Bread machine, Thermomix, Air fryer...",
|
||||
"quick_title": "Quick add:",
|
||||
"oven": "🔥 Oven",
|
||||
"microwave": "📡 Microwave",
|
||||
"air_fryer": "🍟 Air fryer",
|
||||
"bread_maker": "🍞 Bread maker",
|
||||
"bimby": "🤖 Thermomix/Cookeo",
|
||||
"mixer": "🌀 Stand mixer",
|
||||
"steamer": "♨️ Steamer",
|
||||
"pressure_cooker": "🫕 Pressure cooker",
|
||||
"toaster": "🍞 Toaster",
|
||||
"blender": "🍹 Blender",
|
||||
"empty": "No appliances added"
|
||||
},
|
||||
"spesa": {
|
||||
"title": "🛍️ Online Shopping",
|
||||
"hint": "Configure the online shopping provider.",
|
||||
"provider_label": "🏪 Provider",
|
||||
"email_label": "📧 Email",
|
||||
"password_label": "🔒 Password",
|
||||
"login_btn": "🔐 Login",
|
||||
"ai_prompt_label": "🤖 AI product selection prompt",
|
||||
"ai_prompt_placeholder": "Instructions for AI when choosing between multiple products...",
|
||||
"ai_prompt_hint": "AI uses this prompt to choose the most appropriate product from results. Leave empty for default behavior.",
|
||||
"configure_first": "Configure Online Shopping in settings first"
|
||||
},
|
||||
"camera": {
|
||||
"title": "📷 Camera",
|
||||
"hint": "Choose which camera to use for barcode scanning and AI identification.",
|
||||
"device_label": "📸 Default camera",
|
||||
"back": "📱 Rear (default)",
|
||||
"front": "🤳 Front",
|
||||
"devices_hint": "If you have multiple cameras, you can select a specific one from the list above after granting permissions.",
|
||||
"detect_btn": "🔄 Detect cameras"
|
||||
},
|
||||
"security": {
|
||||
"title": "🔒 HTTPS Certificate",
|
||||
"hint": "If the browser shows the error \"Your connection is not private\" (ERR_CERT_AUTHORITY_INVALID), you need to install the CA certificate on the device.",
|
||||
"download_btn": "📥 Download CA Certificate"
|
||||
},
|
||||
"tts": {
|
||||
"title": "🔊 Voice & TTS",
|
||||
"hint": "Configure text-to-speech via any external REST API. Recipe steps and expired timers will be sent to the configured endpoint.",
|
||||
"enabled": "✅ Enable TTS",
|
||||
"url_label": "🌐 Endpoint URL",
|
||||
"method_label": "📡 HTTP Method",
|
||||
"auth_label": "🔐 Authentication",
|
||||
"auth_bearer": "Bearer Token",
|
||||
"auth_custom": "Custom Header",
|
||||
"auth_none": "None",
|
||||
"token_label": "🔑 Bearer Token",
|
||||
"custom_header_name": "📋 Header name",
|
||||
"custom_header_value": "📋 Header value",
|
||||
"content_type_label": "📄 Content-Type",
|
||||
"payload_key_label": "🗝️ Text field in payload",
|
||||
"payload_key_hint": "Name of the JSON field that will contain the text to read (e.g.: message, text).",
|
||||
"extra_fields_label": "➕ Extra fields (JSON)",
|
||||
"extra_fields_placeholder": "{\"entity_id\": \"media_player.living_room\"}",
|
||||
"extra_fields_hint": "Additional fields to include in the payload, in JSON format. Leave empty if not needed.",
|
||||
"test_btn": "🔊 Send Test Voice"
|
||||
},
|
||||
"language": {
|
||||
"title": "🌐 Language",
|
||||
"hint": "Select the interface language.",
|
||||
"label": "🌐 Language",
|
||||
"restart_notice": "The page will reload to apply the new language."
|
||||
},
|
||||
"saved": "✅ Configuration saved!",
|
||||
"saved_local": "✅ Configuration saved locally",
|
||||
"saved_local_error": "⚠️ Saved locally, server error: {error}"
|
||||
},
|
||||
"expiry": {
|
||||
"today": "TODAY",
|
||||
"tomorrow": "Tomorrow",
|
||||
"days": "{days} days",
|
||||
"expired_days": "{days}d ago",
|
||||
"expired_yesterday": "Yesterday",
|
||||
"expired_today": "Today"
|
||||
},
|
||||
"status": {
|
||||
"ok": "OK",
|
||||
"check": "Check",
|
||||
"discard": "Discard"
|
||||
},
|
||||
"toast": {
|
||||
"product_saved": "Product saved!",
|
||||
"product_created": "Product created!",
|
||||
"product_updated": "✅ Product updated!",
|
||||
"product_removed": "Product removed",
|
||||
"updated": "Updated!",
|
||||
"quantity_confirmed": "✓ Quantity confirmed",
|
||||
"added_to_inventory": "✅ {name} added!",
|
||||
"removed_from_list": "✅ {name} removed from the list!",
|
||||
"removed_from_list_short": "Removed from the list",
|
||||
"added_to_shopping": "🛒 Added to the shopping list!",
|
||||
"removed_from_shopping": "🛒 Removed from the shopping list",
|
||||
"finished_to_bring": "🛒 Product finished → added to Bring!",
|
||||
"thrown_away": "🗑️ {name} thrown away!",
|
||||
"thrown_away_partial": "🗑️ Thrown away {qty} {unit} of {name}",
|
||||
"appliance_added": "Appliance added",
|
||||
"item_added": "{name} added"
|
||||
},
|
||||
"error": {
|
||||
"generic": "Error",
|
||||
"loading": "Error loading product",
|
||||
"not_found": "Product not found",
|
||||
"not_found_manual": "Product not found. Enter it manually.",
|
||||
"search": "Search error. Try again.",
|
||||
"search_short": "Search error",
|
||||
"save": "Error saving",
|
||||
"connection": "Connection error",
|
||||
"camera": "Cannot access camera",
|
||||
"bring_add": "Error adding to Bring!",
|
||||
"bring_connection": "Bring! connection error",
|
||||
"identification": "Identification error",
|
||||
"barcode_empty": "Enter a barcode",
|
||||
"barcode_format": "Barcode must contain only numbers (4-14 digits)",
|
||||
"min_chars": "Type at least 2 characters",
|
||||
"not_in_inventory": "Product not in inventory",
|
||||
"appliance_exists": "Appliance already exists",
|
||||
"already_exists": "Already exists"
|
||||
},
|
||||
"confirm": {
|
||||
"remove_item": "Do you really want to remove this product from inventory?"
|
||||
},
|
||||
"edit": {
|
||||
"title": "Edit {name}"
|
||||
},
|
||||
"screensaver": {
|
||||
"recipe_btn": "Recipes",
|
||||
"scan_btn": "Scan product"
|
||||
},
|
||||
"days": {
|
||||
"mon": "Monday",
|
||||
"tue": "Tuesday",
|
||||
"wed": "Wednesday",
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"sat": "Saturday",
|
||||
"sun": "Sunday"
|
||||
},
|
||||
"meal_types": {
|
||||
"lunch": "Lunch",
|
||||
"dinner": "Dinner"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
{
|
||||
"app": {
|
||||
"name": "Dispensa Manager",
|
||||
"loading": "Caricamento..."
|
||||
},
|
||||
"nav": {
|
||||
"title": "🏠 Dispensa",
|
||||
"home": "Home",
|
||||
"inventory": "Dispensa",
|
||||
"recipes": "Ricette",
|
||||
"shopping": "Spesa",
|
||||
"log": "Log"
|
||||
},
|
||||
"btn": {
|
||||
"back": "← Indietro",
|
||||
"save": "💾 Salva",
|
||||
"cancel": "✕ Annulla",
|
||||
"close": "Chiudi",
|
||||
"add": "✅ Aggiungi",
|
||||
"delete": "Elimina",
|
||||
"edit": "✏️ Modifica",
|
||||
"search": "🔍 Cerca",
|
||||
"go": "✅ Vai",
|
||||
"toggle_password": "👁️ Mostra/Nascondi",
|
||||
"load_more": "Carica altri...",
|
||||
"save_config": "💾 Salva Configurazione",
|
||||
"save_product": "💾 Salva Prodotto",
|
||||
"restart": "↺ Ricomincia",
|
||||
"reset_default": "↺ Ripristina default"
|
||||
},
|
||||
"locations": {
|
||||
"dispensa": "Dispensa",
|
||||
"frigo": "Frigo",
|
||||
"freezer": "Freezer",
|
||||
"altro": "Altro"
|
||||
},
|
||||
"categories": {
|
||||
"latticini": "Latticini",
|
||||
"carne": "Carne",
|
||||
"pesce": "Pesce",
|
||||
"frutta": "Frutta",
|
||||
"verdura": "Verdura",
|
||||
"pasta": "Pasta & Riso",
|
||||
"pane": "Pane & Forno",
|
||||
"surgelati": "Surgelati",
|
||||
"bevande": "Bevande",
|
||||
"condimenti": "Condimenti",
|
||||
"snack": "Snack & Dolci",
|
||||
"conserve": "Conserve",
|
||||
"cereali": "Cereali & Legumi",
|
||||
"igiene": "Igiene",
|
||||
"pulizia": "Pulizia Casa",
|
||||
"altro": "Altro",
|
||||
"select": "-- Seleziona --"
|
||||
},
|
||||
"units": {
|
||||
"pz": "pz",
|
||||
"conf": "conf",
|
||||
"g": "g",
|
||||
"ml": "ml",
|
||||
"pieces": "Pezzi",
|
||||
"grams": "Grammi",
|
||||
"box": "Confezione",
|
||||
"boxes": "Confezioni"
|
||||
},
|
||||
"shopping_sections": {
|
||||
"frutta_verdura": "Frutta & Verdura",
|
||||
"carne_pesce": "Carne & Pesce",
|
||||
"latticini": "Latticini & Fresco",
|
||||
"pane_dolci": "Pane & Dolci",
|
||||
"pasta": "Pasta & Cereali",
|
||||
"conserve": "Conserve & Salse",
|
||||
"surgelati": "Surgelati",
|
||||
"bevande": "Bevande",
|
||||
"pulizia_igiene": "Pulizia & Igiene",
|
||||
"altro": "Altro"
|
||||
},
|
||||
"dashboard": {
|
||||
"expired_title": "🚫 Scaduti",
|
||||
"expiring_title": "⏰ Prossime Scadenze",
|
||||
"stats_period": "📊 Ultimi 30 giorni",
|
||||
"opened_title": "📦 Prodotti Aperti",
|
||||
"review_title": "🔍 Da revisionare",
|
||||
"review_hint": "Quantità che sembrano anomale. Conferma se corrette o modifica.",
|
||||
"quick_recipe": "🍳 Ricetta veloce con prodotti in scadenza"
|
||||
},
|
||||
"inventory": {
|
||||
"title": "Dispensa",
|
||||
"filter_all": "Tutti",
|
||||
"search_placeholder": "🔍 Cerca prodotto...",
|
||||
"empty": "Nessun prodotto qui.\nScansiona un prodotto per aggiungerlo!",
|
||||
"no_items_found": "Nessuna voce di inventario trovata"
|
||||
},
|
||||
"scan": {
|
||||
"title": "Scansiona Prodotto",
|
||||
"mode_shopping": "🛒 Modalità Spesa",
|
||||
"mode_shopping_end": "✅ Fine spesa",
|
||||
"zoom": "Zoom",
|
||||
"barcode_placeholder": "Inserisci codice a barre...",
|
||||
"quick_name_divider": "oppure scrivi il nome",
|
||||
"quick_name_placeholder": "Es: Mele, Zucchine, Pane...",
|
||||
"manual_entry": "✏️ Inserimento Manuale",
|
||||
"ai_identify": "🤖 Identifica con AI",
|
||||
"hint": "Scansiona il barcode, scrivi il nome del prodotto, oppure usa l'AI per identificarlo",
|
||||
"debug_toggle": "🐛 Debug Log",
|
||||
"barcode_acquired": "🔖 Barcode acquisito: {code}",
|
||||
"scan_barcode": "🔖 Scansiona Barcode"
|
||||
},
|
||||
"action": {
|
||||
"title": "Cosa vuoi fare?",
|
||||
"add_btn": "📥 AGGIUNGI",
|
||||
"add_sub": "in dispensa/frigo",
|
||||
"use_btn": "📤 USA / CONSUMA",
|
||||
"use_sub": "dalla dispensa/frigo"
|
||||
},
|
||||
"add": {
|
||||
"title": "Aggiungi alla Dispensa",
|
||||
"location_label": "📍 Dove lo metti?",
|
||||
"quantity_label": "📦 Quantità",
|
||||
"conf_size_label": "📦 Ogni confezione contiene:",
|
||||
"conf_size_placeholder": "es. 300",
|
||||
"vacuum_label": "🫙 Sotto vuoto",
|
||||
"vacuum_hint": "La scadenza verrà estesa automaticamente",
|
||||
"submit": "✅ Aggiungi"
|
||||
},
|
||||
"use": {
|
||||
"title": "Usa / Consuma",
|
||||
"location_label": "📍 Da dove?",
|
||||
"quantity_label": "Quanto hai usato?",
|
||||
"partial_hint": "Oppure specifica la quantità usata:",
|
||||
"use_all": "🗑️ Usato TUTTO / Finito",
|
||||
"submit": "📤 Usa questa quantità",
|
||||
"available": "📦 Disponibile:",
|
||||
"not_in_inventory": "⚠️ Prodotto non presente nell'inventario.",
|
||||
"expiry_warning": "⚠️ Usa prima quella{loc} che scade il {date} — {when}!"
|
||||
},
|
||||
"product": {
|
||||
"title_new": "Nuovo Prodotto",
|
||||
"title_edit": "Modifica Prodotto",
|
||||
"ai_fill": "📷 Scatta foto e identifica con AI",
|
||||
"ai_fill_hint": "L'AI compilerà automaticamente i campi del prodotto",
|
||||
"name_label": "🏷️ Nome Prodotto *",
|
||||
"name_placeholder": "Es: Latte intero, Pasta penne rigate...",
|
||||
"brand_label": "🏢 Marca",
|
||||
"brand_placeholder": "Es: Barilla, Granarolo, Mutti...",
|
||||
"category_label": "📂 Categoria",
|
||||
"unit_label": "📏 Unità di misura",
|
||||
"default_qty_label": "🔢 Quantità default",
|
||||
"conf_size_label": "📦 Ogni confezione contiene:",
|
||||
"conf_size_placeholder": "es. 300",
|
||||
"notes_label": "📝 Note",
|
||||
"notes_placeholder": "Es: senza lattosio, bio, conservare in frigo dopo apertura...",
|
||||
"barcode_label": "🔖 Barcode",
|
||||
"barcode_placeholder": "Codice a barre (se disponibile)",
|
||||
"barcode_hint": "⚠️ Aggiungi il barcode così al prossimo acquisto basta scansionarlo!",
|
||||
"submit": "💾 Salva Prodotto",
|
||||
"name_required": "Inserisci il nome del prodotto",
|
||||
"conf_size_required": "Specifica il contenuto di ogni confezione",
|
||||
"expiry_estimated": "Scadenza stimata:",
|
||||
"scan_expiry": "Scansiona data scadenza",
|
||||
"expiry_hint": "📝 Puoi modificare la data o scansionarla con la fotocamera",
|
||||
"add_batch": "📦 + Lotto con scadenza diversa",
|
||||
"package_info": "📦 Confezione: {info}",
|
||||
"edit_catalog": "⚙️ Modifica scheda prodotto (nome, marca, categoria…)",
|
||||
"not_recognized": "⚠️ Prodotto non riconosciuto",
|
||||
"edit_info": "✏️ Modifica informazioni",
|
||||
"modify_details": "MODIFICA\nscadenza, luogo…"
|
||||
},
|
||||
"products": {
|
||||
"title": "📦 Tutti i Prodotti",
|
||||
"search_placeholder": "🔍 Cerca prodotto...",
|
||||
"empty": "Nessun prodotto nel database.\nScansiona un prodotto per iniziare!",
|
||||
"no_category": "Nessun prodotto in questa categoria"
|
||||
},
|
||||
"recipes": {
|
||||
"title": "🍳 Ricette",
|
||||
"generate": "✨ Genera nuova ricetta"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Lista della Spesa",
|
||||
"bring_loading": "Connessione a Bring!...",
|
||||
"tab_to_buy": "🛍️ Da comprare",
|
||||
"tab_forecast": "🧠 In previsione",
|
||||
"total_label": "💰 Totale stimato",
|
||||
"section_to_buy": "🛍️ Da comprare",
|
||||
"suggestions_title": "💡 Suggerimenti AI",
|
||||
"suggestions_add": "✅ Aggiungi selezionati a Bring!",
|
||||
"search_prices": "🔍 Cerca tutti i prezzi",
|
||||
"suggest_btn": "🤖 Suggerisci cosa comprare",
|
||||
"smart_title": "🧠 Previsioni intelligenti",
|
||||
"smart_empty": "Nessuna previsione disponibile.<br>Aggiungi prodotti alla dispensa per ricevere previsioni intelligenti.",
|
||||
"smart_filter_all": "Tutti",
|
||||
"smart_filter_critical": "🔴 Urgenti",
|
||||
"smart_filter_high": "🟠 Presto",
|
||||
"smart_filter_medium": "🟡 Pianifica",
|
||||
"smart_filter_low": "🟢 Previsione",
|
||||
"smart_add": "🛒 Aggiungi selezionati a Bring!",
|
||||
"empty": "Lista della spesa vuota!\nUsa il pulsante sotto per generare suggerimenti.",
|
||||
"already_in_list": "🛒 \"{name}\" già nella lista della spesa",
|
||||
"already_in_list_short": "ℹ️ Già nella lista della spesa",
|
||||
"add_prompt": "Vuoi aggiungerlo alla lista della spesa?",
|
||||
"smart_already": "📊 La spesa intelligente prevede già {name}",
|
||||
"all_searched": "Tutti i prodotti sono già stati cercati. Usa 🔄 per ricercare singoli.",
|
||||
"search_complete": "Ricerca completata: {count} prodotti",
|
||||
"removed_sufficient": "🧹 {removed} prodotto/i con scorte sufficienti rimosso/i dalla lista"
|
||||
},
|
||||
"ai": {
|
||||
"title": "🤖 Identificazione AI",
|
||||
"capture": "📸 Scatta Foto",
|
||||
"retake": "🔄 Riscatta",
|
||||
"hint": "Scatta una foto del prodotto e l'AI cercherà di identificarlo",
|
||||
"identifying": "🤖 Identifico il prodotto...",
|
||||
"no_api_key": "⚠️ Chiave API Gemini non configurata.\n<small>Aggiungi GEMINI_API_KEY nel file .env sul server.</small>",
|
||||
"fields_filled": "✅ Campi compilati dall'AI"
|
||||
},
|
||||
"log": {
|
||||
"title": "📒 Log Operazioni"
|
||||
},
|
||||
"chat": {
|
||||
"title": "Gemini Chef",
|
||||
"welcome": "Ciao! Sono il tuo assistente cucina",
|
||||
"welcome_desc": "Chiedimi di prepararti un succo, uno spuntino, un piatto veloce... Conosco la tua dispensa, i tuoi elettrodomestici e le tue preferenze!",
|
||||
"suggestion_snack": "🍿 Spuntino veloce",
|
||||
"suggestion_juice": "🥤 Succo/Frullato",
|
||||
"suggestion_light": "🥗 Qualcosa di leggero",
|
||||
"suggestion_expiry": "⏰ Usa le scadenze",
|
||||
"clear": "Nuova conversazione",
|
||||
"placeholder": "Chiedi qualcosa..."
|
||||
},
|
||||
"cooking": {
|
||||
"close": "Chiudi",
|
||||
"tts_btn": "Leggi ad alta voce",
|
||||
"restart": "↺ Ricomincia",
|
||||
"replay": "🔊 Rileggi",
|
||||
"timer": "⏱️ {time} · Timer",
|
||||
"prev": "◀ Precedente",
|
||||
"next": "Successivo ▶"
|
||||
},
|
||||
"settings": {
|
||||
"title": "⚙️ Configurazione",
|
||||
"tab_api": "API Keys",
|
||||
"tab_bring": "Bring!",
|
||||
"tab_recipe": "Ricette",
|
||||
"tab_mealplan": "Piano Settimanale",
|
||||
"tab_appliances": "Elettrodomestici",
|
||||
"tab_spesa": "Spesa Online",
|
||||
"tab_camera": "Fotocamera",
|
||||
"tab_security": "Sicurezza",
|
||||
"tab_tts": "Voce (TTS)",
|
||||
"tab_language": "Lingua",
|
||||
"gemini": {
|
||||
"title": "🤖 Google Gemini AI",
|
||||
"hint": "Chiave API per identificazione prodotti, scadenze e ricette.",
|
||||
"key_label": "API Key Gemini"
|
||||
},
|
||||
"bring": {
|
||||
"title": "🛒 Bring! Shopping List",
|
||||
"hint": "Credenziali per l'integrazione con la lista della spesa Bring!",
|
||||
"email_label": "📧 Email Bring!",
|
||||
"password_label": "🔒 Password Bring!"
|
||||
},
|
||||
"recipe": {
|
||||
"title": "🍳 Preferenze Ricette",
|
||||
"hint": "Configura le opzioni predefinite per la generazione delle ricette.",
|
||||
"persons_label": "👥 Persone predefinite",
|
||||
"options_label": "🎯 Opzioni ricetta predefinite",
|
||||
"fast": "⚡ Pasto Veloce",
|
||||
"light": "🥗 Poca Fame",
|
||||
"expiry": "⏰ Priorità Scadenze",
|
||||
"healthy": "💚 Extra Salutare",
|
||||
"opened": "📦 Priorità Cose Aperte",
|
||||
"zerowaste": "♻️ Zero Sprechi",
|
||||
"dietary_label": "🚫 Intolleranze / Restrizioni",
|
||||
"dietary_placeholder": "Es: senza glutine, senza lattosio, vegetariano..."
|
||||
},
|
||||
"mealplan": {
|
||||
"title": "📅 Piano Pasti Settimanale",
|
||||
"hint": "Imposta la tipologia di pasto per ogni giorno. Sarà usata come guida nella generazione delle ricette.",
|
||||
"enabled": "✅ Attiva piano pasti settimanale",
|
||||
"legend": "🌤️ = Pranzo · 🌙 = Cena · Tocca un badge per cambiarlo.",
|
||||
"types_title": "📋 Tipologie disponibili"
|
||||
},
|
||||
"appliances": {
|
||||
"title": "🔌 Elettrodomestici Disponibili",
|
||||
"hint": "Indica gli elettrodomestici che hai a disposizione. Saranno considerati nella generazione delle ricette.",
|
||||
"new_placeholder": "Es: Macchina del pane, Bimby, Friggitrice ad aria...",
|
||||
"quick_title": "Aggiungi velocemente:",
|
||||
"oven": "🔥 Forno",
|
||||
"microwave": "📡 Microonde",
|
||||
"air_fryer": "🍟 Friggitrice ad aria",
|
||||
"bread_maker": "🍞 Macchina pane",
|
||||
"bimby": "🤖 Bimby/Cookeo",
|
||||
"mixer": "🌀 Planetaria",
|
||||
"steamer": "♨️ Vaporiera",
|
||||
"pressure_cooker": "🫕 Pentola pressione",
|
||||
"toaster": "🍞 Tostapane",
|
||||
"blender": "🍹 Frullatore",
|
||||
"empty": "Nessun elettrodomestico aggiunto"
|
||||
},
|
||||
"spesa": {
|
||||
"title": "🛍️ Spesa Online",
|
||||
"hint": "Configura il provider per la spesa online.",
|
||||
"provider_label": "🏪 Provider",
|
||||
"email_label": "📧 Email",
|
||||
"password_label": "🔒 Password",
|
||||
"login_btn": "🔐 Accedi",
|
||||
"ai_prompt_label": "🤖 Prompt AI selezione prodotto",
|
||||
"ai_prompt_placeholder": "Istruzioni per l'AI quando deve scegliere tra più prodotti...",
|
||||
"ai_prompt_hint": "L'AI usa questo prompt per scegliere il prodotto più appropriato tra i risultati. Lascia vuoto per il comportamento predefinito.",
|
||||
"configure_first": "Configura prima la Spesa Online nelle impostazioni"
|
||||
},
|
||||
"camera": {
|
||||
"title": "📷 Fotocamera",
|
||||
"hint": "Scegli quale fotocamera utilizzare per la scansione barcode e l'identificazione AI.",
|
||||
"device_label": "📸 Fotocamera predefinita",
|
||||
"back": "📱 Posteriore (default)",
|
||||
"front": "🤳 Anteriore",
|
||||
"devices_hint": "Se hai più fotocamere, puoi selezionarne una specifica dall'elenco sopra dopo aver concesso i permessi.",
|
||||
"detect_btn": "🔄 Rileva fotocamere"
|
||||
},
|
||||
"security": {
|
||||
"title": "🔒 Certificato HTTPS",
|
||||
"hint": "Se il browser mostra l'errore \"La connessione non è privata\" (ERR_CERT_AUTHORITY_INVALID), devi installare il certificato CA nel dispositivo.",
|
||||
"download_btn": "📥 Scarica Certificato CA"
|
||||
},
|
||||
"tts": {
|
||||
"title": "🔊 Voce & TTS",
|
||||
"hint": "Configura la sintesi vocale tramite qualsiasi API REST esterna. I passi della ricetta e i timer scaduti verranno inviati all'endpoint configurato.",
|
||||
"enabled": "✅ Attiva TTS",
|
||||
"url_label": "🌐 URL Endpoint",
|
||||
"method_label": "📡 Metodo HTTP",
|
||||
"auth_label": "🔐 Autenticazione",
|
||||
"auth_bearer": "Bearer Token",
|
||||
"auth_custom": "Header personalizzato",
|
||||
"auth_none": "Nessuna",
|
||||
"token_label": "🔑 Bearer Token",
|
||||
"custom_header_name": "📋 Nome header",
|
||||
"custom_header_value": "📋 Valore header",
|
||||
"content_type_label": "📄 Content-Type",
|
||||
"payload_key_label": "🗝️ Campo testo nel payload",
|
||||
"payload_key_hint": "Nome del campo JSON che conterrà il testo da leggere (es: message, text).",
|
||||
"extra_fields_label": "➕ Campi extra (JSON)",
|
||||
"extra_fields_placeholder": "{\"entity_id\": \"media_player.living_room\"}",
|
||||
"extra_fields_hint": "Campi aggiuntivi da includere nel payload, in formato JSON. Lascia vuoto se non necessario.",
|
||||
"test_btn": "🔊 Invia Test Vocale"
|
||||
},
|
||||
"language": {
|
||||
"title": "🌐 Lingua / Language",
|
||||
"hint": "Seleziona la lingua dell'interfaccia. Select the interface language.",
|
||||
"label": "🌐 Lingua",
|
||||
"restart_notice": "La pagina verrà ricaricata per applicare la nuova lingua."
|
||||
},
|
||||
"saved": "✅ Configurazione salvata!",
|
||||
"saved_local": "✅ Configurazione salvata localmente",
|
||||
"saved_local_error": "⚠️ Salvato localmente, errore server: {error}"
|
||||
},
|
||||
"expiry": {
|
||||
"today": "OGGI",
|
||||
"tomorrow": "Domani",
|
||||
"days": "{days} giorni",
|
||||
"expired_days": "Da {days}g",
|
||||
"expired_yesterday": "Da ieri",
|
||||
"expired_today": "Oggi"
|
||||
},
|
||||
"status": {
|
||||
"ok": "OK",
|
||||
"check": "Controlla",
|
||||
"discard": "Buttare"
|
||||
},
|
||||
"toast": {
|
||||
"product_saved": "Prodotto salvato!",
|
||||
"product_created": "Prodotto creato!",
|
||||
"product_updated": "✅ Prodotto aggiornato!",
|
||||
"product_removed": "Prodotto rimosso",
|
||||
"updated": "Aggiornato!",
|
||||
"quantity_confirmed": "✓ Quantità confermata",
|
||||
"added_to_inventory": "✅ {name} aggiunto!",
|
||||
"removed_from_list": "✅ {name} rimosso dalla lista!",
|
||||
"removed_from_list_short": "Rimosso dalla lista",
|
||||
"added_to_shopping": "🛒 Aggiunto alla lista della spesa!",
|
||||
"removed_from_shopping": "🛒 Rimosso dalla lista della spesa",
|
||||
"finished_to_bring": "🛒 Prodotto finito → aggiunto a Bring!",
|
||||
"thrown_away": "🗑️ {name} buttato!",
|
||||
"thrown_away_partial": "🗑️ Buttato {qty} {unit} di {name}",
|
||||
"appliance_added": "Elettrodomestico aggiunto",
|
||||
"item_added": "{name} aggiunto"
|
||||
},
|
||||
"error": {
|
||||
"generic": "Errore",
|
||||
"loading": "Errore nel caricamento del prodotto",
|
||||
"not_found": "Prodotto non trovato",
|
||||
"not_found_manual": "Prodotto non trovato. Inseriscilo manualmente.",
|
||||
"search": "Errore nella ricerca. Riprova.",
|
||||
"search_short": "Errore nella ricerca",
|
||||
"save": "Errore nel salvataggio",
|
||||
"connection": "Errore di connessione",
|
||||
"camera": "Impossibile accedere alla fotocamera",
|
||||
"bring_add": "Errore nell'aggiunta a Bring!",
|
||||
"bring_connection": "Errore connessione Bring!",
|
||||
"identification": "Errore nell'identificazione",
|
||||
"barcode_empty": "Inserisci un codice a barre",
|
||||
"barcode_format": "Il codice a barre deve contenere solo numeri (4-14 cifre)",
|
||||
"min_chars": "Scrivi almeno 2 caratteri",
|
||||
"not_in_inventory": "Prodotto non nell'inventario",
|
||||
"appliance_exists": "Elettrodomestico già presente",
|
||||
"already_exists": "Già presente"
|
||||
},
|
||||
"confirm": {
|
||||
"remove_item": "Vuoi davvero rimuovere questo prodotto dall'inventario?"
|
||||
},
|
||||
"edit": {
|
||||
"title": "Modifica {name}"
|
||||
},
|
||||
"screensaver": {
|
||||
"recipe_btn": "Ricette",
|
||||
"scan_btn": "Scansiona prodotto"
|
||||
},
|
||||
"days": {
|
||||
"mon": "Lunedì",
|
||||
"tue": "Martedì",
|
||||
"wed": "Mercoledì",
|
||||
"thu": "Giovedì",
|
||||
"fri": "Venerdì",
|
||||
"sat": "Sabato",
|
||||
"sun": "Domenica"
|
||||
},
|
||||
"meal_types": {
|
||||
"lunch": "Pranzo",
|
||||
"dinner": "Cena"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user