feat(recipes): add tools_needed field — appliances shown as chips above ingredients
This commit is contained in:
+9
-4
@@ -3020,6 +3020,7 @@ PROMPT;
|
|||||||
'error_empty_reply' => 'Risposta vuota da Gemini',
|
'error_empty_reply' => 'Risposta vuota da Gemini',
|
||||||
'prompt_lang_rule' => 'IMPORTANTE: scrivi tutti i campi testuali della ricetta in Italiano.',
|
'prompt_lang_rule' => 'IMPORTANTE: scrivi tutti i campi testuali della ricetta in Italiano.',
|
||||||
'prompt_step_example' => 'Passo 1…',
|
'prompt_step_example' => 'Passo 1…',
|
||||||
|
'tools_title' => 'Strumenti necessari',
|
||||||
],
|
],
|
||||||
'en' => [
|
'en' => [
|
||||||
'status_analyze_pantry' => '📦 Analyzing pantry...',
|
'status_analyze_pantry' => '📦 Analyzing pantry...',
|
||||||
@@ -3042,6 +3043,7 @@ PROMPT;
|
|||||||
'error_empty_reply' => 'Empty response from Gemini',
|
'error_empty_reply' => 'Empty response from Gemini',
|
||||||
'prompt_lang_rule' => 'IMPORTANT: write all textual recipe fields in English only. Do not use Italian or German.',
|
'prompt_lang_rule' => 'IMPORTANT: write all textual recipe fields in English only. Do not use Italian or German.',
|
||||||
'prompt_step_example' => 'Step 1…',
|
'prompt_step_example' => 'Step 1…',
|
||||||
|
'tools_title' => 'Equipment needed',
|
||||||
],
|
],
|
||||||
'de' => [
|
'de' => [
|
||||||
'status_analyze_pantry' => '📦 Vorrat wird analysiert...',
|
'status_analyze_pantry' => '📦 Vorrat wird analysiert...',
|
||||||
@@ -3064,6 +3066,7 @@ PROMPT;
|
|||||||
'error_empty_reply' => 'Leere Antwort von Gemini',
|
'error_empty_reply' => 'Leere Antwort von Gemini',
|
||||||
'prompt_lang_rule' => 'WICHTIG: schreibe alle textuellen Rezeptfelder nur auf Deutsch. Verwende kein Italienisch oder Englisch.',
|
'prompt_lang_rule' => 'WICHTIG: schreibe alle textuellen Rezeptfelder nur auf Deutsch. Verwende kein Italienisch oder Englisch.',
|
||||||
'prompt_step_example' => 'Schritt 1…',
|
'prompt_step_example' => 'Schritt 1…',
|
||||||
|
'tools_title' => 'Benötigte Geräte',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
$text = $dict[$lang][$key] ?? $dict['it'][$key] ?? $key;
|
$text = $dict[$lang][$key] ?? $dict['it'][$key] ?? $key;
|
||||||
@@ -3441,14 +3444,15 @@ REGOLE:
|
|||||||
4. "qty_number": valore NUMERICO nella STESSA unità della dispensa (g/ml/pz/conf, MAI kg o litri). Per non-dispensa: 0. IMPORTANTE: per ingredienti con unità "pz" scrivi qty_number come numero di PEZZI (es. 2, non 200g).
|
4. "qty_number": valore NUMERICO nella STESSA unità della dispensa (g/ml/pz/conf, MAI kg o litri). Per non-dispensa: 0. IMPORTANTE: per ingredienti con unità "pz" scrivi qty_number come numero di PEZZI (es. 2, non 200g).
|
||||||
5. "name": usa ESATTAMENTE il nome dalla lista (il sistema lo usa per scalare l'inventario).
|
5. "name": usa ESATTAMENTE il nome dalla lista (il sistema lo usa per scalare l'inventario).
|
||||||
6. Includi nella lista ingredienti TUTTI quelli citati nei passi (tranne acqua/sale/pepe/olio).
|
6. Includi nella lista ingredienti TUTTI quelli citati nei passi (tranne acqua/sale/pepe/olio).
|
||||||
7. Language rule: {$recipeLangName} only for all textual fields (`title`, `tags`, `expiry_note`, `ingredients.qty`, `steps`, `nutrition_note`). Keep `meal` unchanged.
|
7. Language rule: {$recipeLangName} only for all textual fields (`title`, `tags`, `expiry_note`, `ingredients.qty`, `steps`, `nutrition_note`, `tools_needed`). Keep `meal` unchanged.
|
||||||
|
8. `tools_needed`: array of kitchen tools/appliances actually required by this recipe (e.g. ["Forno","Frullatore"]). Use the same language as all other text fields. Empty array [] if only stovetop/knife/pan needed.
|
||||||
|
|
||||||
DISPENSA:
|
DISPENSA:
|
||||||
$ingredientsText
|
$ingredientsText
|
||||||
|
|
||||||
Rispondi SOLO JSON valido (no markdown):
|
Rispondi SOLO JSON valido (no markdown):
|
||||||
{$promptLanguageRule}
|
{$promptLanguageRule}
|
||||||
{"title":"…","meal":"$mealType","persons":$persons,"prep_time":"…","cook_time":"…","tags":["…"],"expiry_note":"…","ingredients":[{"name":"…","qty":"200 g","qty_number":200,"from_pantry":true}],"steps":["{$promptStepExample}"],"nutrition_note":"…"}
|
{"title":"…","meal":"$mealType","persons":$persons,"prep_time":"…","cook_time":"…","tags":["…"],"expiry_note":"…","tools_needed":["…"],"ingredients":[{"name":"…","qty":"200 g","qty_number":200,"from_pantry":true}],"steps":["{$promptStepExample}"],"nutrition_note":"…"}
|
||||||
PROMPT;
|
PROMPT;
|
||||||
|
|
||||||
$payload = [
|
$payload = [
|
||||||
@@ -4317,14 +4321,15 @@ REGOLE:
|
|||||||
4. "qty_number": valore NUMERICO nella STESSA unità della dispensa (g/ml/pz/conf, MAI kg o litri). Per non-dispensa: 0. IMPORTANTE: per ingredienti con unità "pz" scrivi qty_number come numero di PEZZI (es. 2, non 200g).
|
4. "qty_number": valore NUMERICO nella STESSA unità della dispensa (g/ml/pz/conf, MAI kg o litri). Per non-dispensa: 0. IMPORTANTE: per ingredienti con unità "pz" scrivi qty_number come numero di PEZZI (es. 2, non 200g).
|
||||||
5. "name": usa ESATTAMENTE il nome dalla lista (il sistema lo usa per scalare l'inventario).
|
5. "name": usa ESATTAMENTE il nome dalla lista (il sistema lo usa per scalare l'inventario).
|
||||||
6. Includi nella lista ingredienti TUTTI quelli citati nei passi (tranne acqua/sale/pepe/olio).
|
6. Includi nella lista ingredienti TUTTI quelli citati nei passi (tranne acqua/sale/pepe/olio).
|
||||||
7. Language rule: {$recipeLangName} only for all textual fields (`title`, `tags`, `expiry_note`, `ingredients.qty`, `steps`, `nutrition_note`). Keep `meal` unchanged.
|
7. Language rule: {$recipeLangName} only for all textual fields (`title`, `tags`, `expiry_note`, `ingredients.qty`, `steps`, `nutrition_note`, `tools_needed`). Keep `meal` unchanged.
|
||||||
|
8. `tools_needed`: array of kitchen tools/appliances actually required by this recipe (e.g. ["Forno","Frullatore"]). Use the same language as all other text fields. Empty array [] if only stovetop/knife/pan needed.
|
||||||
|
|
||||||
DISPENSA:
|
DISPENSA:
|
||||||
$ingredientsText
|
$ingredientsText
|
||||||
|
|
||||||
Rispondi SOLO JSON valido (no markdown):
|
Rispondi SOLO JSON valido (no markdown):
|
||||||
{$promptLanguageRule}
|
{$promptLanguageRule}
|
||||||
{"title":"…","meal":"$mealType","persons":$persons,"prep_time":"…","cook_time":"…","tags":["…"],"expiry_note":"…","ingredients":[{"name":"…","qty":"200 g","qty_number":200,"from_pantry":true}],"steps":["{$promptStepExample}"],"nutrition_note":"…"}
|
{"title":"…","meal":"$mealType","persons":$persons,"prep_time":"…","cook_time":"…","tags":["…"],"expiry_note":"…","tools_needed":["…"],"ingredients":[{"name":"…","qty":"200 g","qty_number":200,"from_pantry":true}],"steps":["{$promptStepExample}"],"nutrition_note":"…"}
|
||||||
PROMPT;
|
PROMPT;
|
||||||
|
|
||||||
$genConfig = [
|
$genConfig = [
|
||||||
|
|||||||
@@ -3918,6 +3918,29 @@ body.server-offline .bottom-nav {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recipe-tools-banner {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
background: #f0f4ff;
|
||||||
|
border: 1px solid #c7d2fe;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #3730a3;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.recipe-tool-chip {
|
||||||
|
background: #e0e7ff;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #3730a3;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
/* Recipe ingredient use buttons */
|
/* Recipe ingredient use buttons */
|
||||||
.recipe-ingredients {
|
.recipe-ingredients {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|||||||
@@ -11954,6 +11954,12 @@ function renderRecipe(r) {
|
|||||||
html += `<div class="recipe-expiry-note">⚠️ ${r.expiry_note}</div>`;
|
html += `<div class="recipe-expiry-note">⚠️ ${r.expiry_note}</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tools/appliances banner (shown only when specific equipment is needed)
|
||||||
|
const tools = (r.tools_needed || []).filter(t => t && t.trim());
|
||||||
|
if (tools.length > 0) {
|
||||||
|
html += `<div class="recipe-tools-banner">🔧 <strong>${t('recipes.tools_title')}:</strong> ${tools.map(t => `<span class="recipe-tool-chip">${t}</span>`).join('')}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
// Ingredients
|
// Ingredients
|
||||||
html += `<h3>${t('recipes.ingredients_title')}</h3><ul class="recipe-ingredients">`;
|
html += `<h3>${t('recipes.ingredients_title')}</h3><ul class="recipe-ingredients">`;
|
||||||
(r.ingredients || []).forEach((ing, idx) => {
|
(r.ingredients || []).forEach((ing, idx) => {
|
||||||
|
|||||||
@@ -341,6 +341,7 @@
|
|||||||
"regenerate": "🔄 Noch eins generieren",
|
"regenerate": "🔄 Noch eins generieren",
|
||||||
"close_btn": "✅ Schließen",
|
"close_btn": "✅ Schließen",
|
||||||
"ingredients_title": "🧾 Zutaten",
|
"ingredients_title": "🧾 Zutaten",
|
||||||
|
"tools_title": "Benötigte Geräte",
|
||||||
"steps_title": "👨🍳 Zubereitung",
|
"steps_title": "👨🍳 Zubereitung",
|
||||||
"no_steps": "Keine Zubereitungsschritte verfügbar",
|
"no_steps": "Keine Zubereitungsschritte verfügbar",
|
||||||
"generate_error": "Fehler bei der Generierung",
|
"generate_error": "Fehler bei der Generierung",
|
||||||
|
|||||||
@@ -341,6 +341,7 @@
|
|||||||
"regenerate": "🔄 Generate another one",
|
"regenerate": "🔄 Generate another one",
|
||||||
"close_btn": "✅ Close",
|
"close_btn": "✅ Close",
|
||||||
"ingredients_title": "🧾 Ingredients",
|
"ingredients_title": "🧾 Ingredients",
|
||||||
|
"tools_title": "Equipment needed",
|
||||||
"steps_title": "👨🍳 Steps",
|
"steps_title": "👨🍳 Steps",
|
||||||
"no_steps": "No steps available",
|
"no_steps": "No steps available",
|
||||||
"generate_error": "Generation error",
|
"generate_error": "Generation error",
|
||||||
|
|||||||
@@ -341,6 +341,7 @@
|
|||||||
"regenerate": "🔄 Generane un'altra",
|
"regenerate": "🔄 Generane un'altra",
|
||||||
"close_btn": "✅ Chiudi",
|
"close_btn": "✅ Chiudi",
|
||||||
"ingredients_title": "🧾 Ingredienti",
|
"ingredients_title": "🧾 Ingredienti",
|
||||||
|
"tools_title": "Strumenti necessari",
|
||||||
"steps_title": "👨🍳 Procedimento",
|
"steps_title": "👨🍳 Procedimento",
|
||||||
"no_steps": "Nessun procedimento disponibile",
|
"no_steps": "Nessun procedimento disponibile",
|
||||||
"generate_error": "Errore nella generazione",
|
"generate_error": "Errore nella generazione",
|
||||||
|
|||||||
Reference in New Issue
Block a user