v6 Phase C: Cookbook diversifiziert + 'Beste Wahl' hervorgehoben
- recipes.py: best-in-class je Use-Case, herstelleruebergreifend (Qwen3-Coder, Gemma 3, Mistral Small, DeepSeek-R1, Qwen3-VL) + neue Kategorie 'Nachdenken & Logik'. - recipes-Endpoint: recommended_id = reichstes Setup das komplett passt. - cookbook.js + CSS: 'Beste Wahl fuer dein System' (Rahmen + Badge). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -216,5 +216,7 @@ button:disabled{opacity:.5;cursor:not-allowed}
|
||||
border-radius:var(--radius);padding:var(--sp-3) var(--sp-4);cursor:pointer;transition:border-color .15s,background .15s;
|
||||
color:var(--tx);font-family:var(--sans)}
|
||||
.card-btn:hover,.card-btn:focus{border-color:var(--accent);background:var(--bg2);outline:none}
|
||||
.card-btn.cb-best{border:2px solid var(--accent);background:rgba(45,212,191,.05)}
|
||||
.cb-best-tag{display:inline-block;font-size:11px;color:var(--accent-ink);background:var(--accent);border-radius:6px;padding:2px 9px;margin-bottom:8px;font-weight:500}
|
||||
.card-btn h3{margin:0;font-size:var(--text-lg);font-weight:500}
|
||||
.card-btn p{margin:var(--sp-2) 0 0;font-size:var(--text-sm);color:var(--mut)}
|
||||
|
||||
@@ -17,6 +17,7 @@ let currentResults = [];
|
||||
let currentAnalysis = null;
|
||||
let activeFilter = "";
|
||||
let RECIPES = [];
|
||||
let RECOMMENDED = null;
|
||||
|
||||
const fitCls = lvl => lvl === "perfect" ? "ok" : lvl === "marginal" ? "warn" : "bad";
|
||||
const fitWord = lvl => lvl === "perfect" ? "Passt locker" : lvl === "marginal" ? "Wird knapp" : "Zu groß";
|
||||
@@ -117,6 +118,7 @@ async function loadRecipes() {
|
||||
try {
|
||||
const d = await api("/api/cookbook/recipes");
|
||||
RECIPES = d.recipes || [];
|
||||
RECOMMENDED = d.recommended_id || null;
|
||||
renderRecipes();
|
||||
} catch (e) {
|
||||
$("#cb-recipes").innerHTML = `<div class="alert err" style="grid-column:1/-1">Setups nicht ladbar: ${esc(e.message)}</div>`;
|
||||
@@ -124,8 +126,10 @@ async function loadRecipes() {
|
||||
}
|
||||
|
||||
function renderRecipes() {
|
||||
$("#cb-recipes").innerHTML = RECIPES.map(r => `
|
||||
<button class="card-btn" data-recipe="${esc(r.id)}">
|
||||
$("#cb-recipes").innerHTML = RECIPES.map(r => {
|
||||
const best = r.id === RECOMMENDED;
|
||||
return `<button class="card-btn${best ? " cb-best" : ""}" data-recipe="${esc(r.id)}">
|
||||
${best ? `<div class="cb-best-tag">★ Beste Wahl für dein System</div>` : ""}
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="flex items-center gap-2"><span class="text-accent">${icon(r.icon)}</span>
|
||||
<h3 style="margin:0;font-size:15px">${esc(r.title)}</h3></span>
|
||||
@@ -133,7 +137,8 @@ function renderRecipes() {
|
||||
</div>
|
||||
<p>${esc(r.desc)}</p>
|
||||
<div class="text-xs text-mut">${r.models.length} Modell${r.models.length > 1 ? "e" : ""} im Setup</div>
|
||||
</button>`).join("");
|
||||
</button>`;
|
||||
}).join("");
|
||||
$("#cb-recipes").querySelectorAll("[data-recipe]").forEach(b =>
|
||||
b.addEventListener("click", () => openRecipe(b.getAttribute("data-recipe"))));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user