feat(mockup): rename to Image Mockup Studio and add inline generator selector

This commit is contained in:
airent106 committed 2026-10-29 12:05:52 -06:00
1 parent 3368d7201c
commit 25d24a53a6
2 files changed
+68 -34

No files matched your search

+35 -11
View File
@@ -138,13 +138,17 @@ async function loadSettings() {
const keyStatus = document.getElementById("settings-key-status");
if (keyStatus) {
keyStatus.textContent = data.hasApiKey
? `Active key configured (${data.apiKeySource}: ${data.maskedKey})`
: "No key stored yet — paste your Gemini API key to enable live Nano Banana 2.1 generation.";
? `Active provider configured (${data.apiKeySource}: ${data.maskedKey})`
: "No Gemini API key stored — OpenAI Codex works automatically via OAuth.";
}
const modelSel = document.getElementById("settings-model-select");
if (modelSel && data.nanoBananaModel) {
modelSel.value = data.nanoBananaModel;
}
const studioGenSel = document.getElementById("nb-generator-select");
if (studioGenSel && data.nanoBananaModel) {
studioGenSel.value = data.nanoBananaModel;
}
const bgEl = document.getElementById("settings-user-background");
if (bgEl && data.userBackground !== undefined) {
bgEl.value = data.userBackground;
@@ -439,7 +443,7 @@ function renderColliderStage() {
💾 Log Breakthrough to Idea
</button>
<button type="button" id="btn-collider-to-mockup" class="btn btn-secondary">
🍌 Visualize This Twist in Nano Banana Studio
🖼️ Visualize Twist in Image Mockup Studio
</button>`
: ""
}
@@ -728,8 +732,8 @@ function renderTriageStage() {
<p style="color:var(--text-secondary);">${escapeHtml(item.elevator_pitch || "No elevator pitch yet — open Workbench or deal a Whack card to flesh it out.")}</p>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;padding-top:0.5rem;">
<button type="button" class="btn btn-primary" id="btn-triage-promote">🚀 Promote to ${nextStage.toUpperCase()}</button>
<button type="button" class="btn btn-secondary" id="btn-triage-mockup">🍌 Mock Up Image</button>
<button type="button" class="btn btn-ghost" id="btn-triage-whack">🃏 Whack It</button>
<button type="button" class="btn btn-secondary" id="btn-triage-mockup">🖼️ Mock Up Image</button>
<button type="button" class="btn btn-ghost" id="btn-triage-whack">💡 Prompt Twist</button>
<button type="button" class="btn btn-ghost" id="btn-triage-keep">✓ Keep & Next</button>
<button type="button" class="btn btn-danger-ghost" id="btn-triage-archive">📦 Archive</button>
</div>
@@ -1087,7 +1091,7 @@ function renderDrawerMockupGallery(idea) {
if (!container) return;
if (!idea.mockups || idea.mockups.length === 0) {
container.innerHTML = `<p class="muted-label">No mockups saved for this idea yet. Generate one with 🍌 Nano Banana 2.1 or save a layout from the T-Shirt Compositor!</p>`;
container.innerHTML = `<p class="muted-label">No mockups saved for this idea yet. Generate one in the Image Mockup Studio or save a layout from the T-Shirt Compositor!</p>`;
return;
}
@@ -1104,7 +1108,7 @@ function renderDrawerMockupGallery(idea) {
${m.editInstruction ? `<small class="muted-label">Edited: "${escapeHtml(m.editInstruction)}"</small>` : ""}
<div class="mockup-gallery-actions">
<button type="button" class="btn btn-primary btn-xs btn-mk-refine" data-mk-id="${escapeHtml(m.id)}">
🍌 Refine with Nano Banana
✨ Refine Mockup
</button>
<button type="button" class="btn btn-ghost btn-xs btn-mk-load-canvas" data-mk-url="${escapeHtml(m.imageUrl)}">
👕 Place on Tee Canvas
@@ -1458,7 +1462,7 @@ function renderDrawerActiveWhackStage() {
</label>
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;">
<button type="button" id="btn-drawer-save-whack" class="btn btn-primary btn-sm">💾 Save Breakthrough</button>
<button type="button" id="btn-drawer-whack-to-nb" class="btn btn-secondary btn-sm">🍌 Send Twist to Nano Banana Mockup Studio</button>
<button type="button" id="btn-drawer-whack-to-nb" class="btn btn-secondary btn-sm">🖼️ Send Twist to Image Mockup Studio</button>
</div>
</div>
</div>
@@ -2017,22 +2021,42 @@ function bindGlobalEvents() {
document.getElementById("nb-edit-instruction-input").value = "";
});
document.getElementById("nb-generator-select")?.addEventListener("change", async (e) => {
const chosenModel = e.target.value;
state.settings.nanoBananaModel = chosenModel;
const settingsSel = document.getElementById("settings-model-select");
if (settingsSel) settingsSel.value = chosenModel;
await apiFetch("/api/settings", {
method: "PUT",
body: JSON.stringify({ nanoBananaModel: chosenModel })
});
showToast(`Switched Image Mockup Generator to ${e.target.options[e.target.selectedIndex].text.split("—")[0].trim()}`);
});
document.getElementById("btn-generate-nano-banana")?.addEventListener("click", async () => {
if (!state.activeIdeaId) return;
const btn = document.getElementById("btn-generate-nano-banana");
const statusLabel = document.getElementById("nb-generation-status");
const selectedModel =
document.getElementById("nb-generator-select")?.value ||
state.settings.nanoBananaModel ||
"codex-image-gen";
const template = document.getElementById("nb-template-select").value;
const whackCardNumber = document.getElementById("nb-whack-twist-select").value;
const prompt = document.getElementById("nb-prompt-input").value.trim();
const editInstruction = document.getElementById("nb-edit-instruction-input").value.trim();
btn.disabled = true;
statusLabel.textContent = "🎨 Generating high-res AI mockup via OpenAI Codex (takes ~15–25s)...";
statusLabel.textContent =
selectedModel === "codex-image-gen"
? "🤖 Generating high-res PNG via OpenAI Codex (takes ~15–25s)..."
: `✨ Generating mockup via ${selectedModel}...`;
try {
const res = await apiFetch(`/api/ideas/${state.activeIdeaId}/mockups/nano-banana`, {
method: "POST",
body: JSON.stringify({
model: selectedModel,
template,
garmentColor: state.nbGarmentColor,
garmentColorName: state.nbGarmentColorName,
@@ -2046,8 +2070,8 @@ function bindGlobalEvents() {
state.nbEditParentMockup = null;
document.getElementById("nb-edit-mode-box").classList.add("hidden");
document.getElementById("nb-edit-instruction-input").value = "";
statusLabel.textContent = "✓ Saved new Nano Banana mockup to gallery!";
showToast("🍌 Nano Banana 2.1 generated & saved your mockup!");
statusLabel.textContent = `✓ Saved new mockup (${res.mockup.modelUsed}) to gallery!`;
showToast("🖼️ Generated & saved your new mockup!");
await loadIdeas();
} catch (err) {
statusLabel.textContent = `⚠️ ${err.message}`;