diff options
Diffstat (limited to 'static/recipe.html')
| -rw-r--r-- | static/recipe.html | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/static/recipe.html b/static/recipe.html new file mode 100644 index 0000000..2a5614f --- /dev/null +++ b/static/recipe.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Recipe — Commis</title> + <link rel="stylesheet" href="style.css"> + <link rel="icon" href="logo.png" type="image/png"> +</head> +<body> + <header> + <div class="header-title"><img src="logo.png" alt="Commis" style="height:32px;width:32px;object-fit:contain;vertical-align:middle;margin-right:0.4rem;border-radius:6px;">Commis</div> + </header> + <main id="recipe-detail" style="max-width:720px;margin:2rem auto;padding:0 1rem;"> + <a href="/#menu" class="btn btn-secondary" style="margin-bottom:1.5rem;display:inline-block;">← Back to Menu</a> + <div id="recipe-content"><p>Loading…</p></div> + </main> + <script> + const params = new URLSearchParams(location.search); + const id = params.get('id'); + if (!id) { + document.getElementById('recipe-content').innerHTML = '<p>No recipe ID provided.</p>'; + } else { + fetch(`/api/recipes/${id}`) + .then(r => r.ok ? r.json() : Promise.reject(r.statusText)) + .then(recipe => { + let ingredients = []; + try { ingredients = JSON.parse(recipe.ingredients); } catch {} + + const mealType = recipe.meal_type || 'dinner'; + const typeDisplay = mealType.charAt(0).toUpperCase() + mealType.slice(1); + const time = recipe.estimated_time_minutes; + const serves = recipe.servings; + const meta = [time ? `${time} min` : '', serves ? `serves ${serves}` : ''].filter(Boolean).join(' · '); + + const ingredientList = Array.isArray(ingredients) + ? ingredients.map(i => { + if (typeof i === 'string') return `<li>${i}</li>`; + return `<li>${[i.quantity, i.unit, i.name].filter(Boolean).join(' ')}</li>`; + }).join('') + : ''; + + const instructionSteps = (recipe.instructions || '') + .split(/\n+| (?=\d+\. )/) + .map(s => s.trim()) + .filter(Boolean) + .map(s => `<p>${s}</p>`) + .join(''); + + document.title = `${recipe.name} — Commis`; + document.getElementById('recipe-content').innerHTML = ` + <div class="recipe-card-header" style="margin-bottom:0.5rem;"> + <h1 style="font-size:1.6rem;margin:0;">${recipe.name}</h1> + <span class="recipe-type-badge ${mealType}">${typeDisplay}</span> + </div> + ${recipe.description ? `<p style="color:var(--text-muted);margin:0.5rem 0 1rem;">${recipe.description}</p>` : ''} + ${meta ? `<div class="recipe-card-meta" style="margin-bottom:1.5rem;">${meta}</div>` : ''} + ${ingredientList ? `<h2 style="font-size:1.1rem;margin-bottom:0.5rem;">Ingredients</h2><ul style="padding-left:1.25rem;line-height:1.8;">${ingredientList}</ul>` : ''} + ${instructionSteps ? `<h2 style="font-size:1.1rem;margin:1.5rem 0 0.5rem;">Instructions</h2><div style="line-height:1.7;">${instructionSteps}</div>` : ''} + `; + }) + .catch(err => { + document.getElementById('recipe-content').innerHTML = `<p>Failed to load recipe: ${err}</p>`; + }); + } + </script> +</body> +</html> |
