Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Gemini Code Generator & Preview (Config Modal)</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> | |
<link rel="preconnect" href="https://rsms.me/"> | |
<link rel="stylesheet" href="https://rsms.me/inter/inter.css"> | |
<link rel="stylesheet" href="style.css"> | |
</head> | |
<body class="font-sans"> | |
<div id="top-left-controls"> | |
<button id="new-button" aria-label="New Session" title="Start New Session (Refresh)"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg> | |
</button> | |
<button id="show-prompt-modal-button" aria-label="Open Prompt Modal" title="Open Prompt (Alt / Option + P)"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil"><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg> | |
</button> | |
<button id="config-button" aria-label="Open Configuration" title="Open Configuration (Alt / Option + O)"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings-2"><path d="M20 7h-9"/><path d="M14 17H5"/><circle cx="17" cy="17" r="3"/><circle cx="7" cy="7" r="3"/></svg> | |
</button> | |
</div> | |
<div id="main-content" class="p-6 flex flex-col space-y-4"> | |
<div class="text-center mt-8"> | |
<h1 id="main-content-title" class="text-2xl font-bold text-cyan-400">Live Previews</h1> | |
<h2 id="main-content-subtitle" class="text-base font-semibold text-slate-300 mt-2">Powered by Gemini Models</h2> | |
<div id="error-message" class="mt-2 text-red-400 text-sm font-medium"></div> | |
</div> | |
<div id="initial-setup-cta" class="hidden flex-col items-center justify-center text-slate-300 text-lg p-4 space-y-6"> | |
<!-- This div will be shown by script.js in the initial state --> | |
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Google_Gemini_logo.svg/2560px-Google_Gemini_logo.svg.png" alt="Gemini Logo" id="gemini-logo-initial-cta"> | |
<div class="w-full flex justify-center"> | |
<input type="password" id="initial-api-key-input" class="futuristic-input w-[70%] text-sm" placeholder="Enter your Gemini API Key"> | |
</div> | |
<div class="w-full flex justify-center text-center"> | |
<p class="text-xs text-slate-400 mt-1"> | |
<a href="https://aistudio.google.com/app/" target="_blank" rel="noopener noreferrer" class="text-cyan-400 hover:text-cyan-300 underline"> | |
Get your Gemini API Key from Google AI Studio | |
</a> | |
</p> | |
</div> | |
<div id="example-prompts-container" class="flex flex-col items-center gap-3"> | |
</div> | |
<p class="mt-4 text-sm text-slate-500">Once you have an API key and a prompt (either typed or from an example),<br>click the pencil icon or press Alt+P to open the prompt window and generate.</p> | |
</div> | |
<div id="perspective-viewport"> | |
<div id="preview-grid-wrapper" class="grid-mode"> | |
<!-- Content will be dynamically inserted here by script.js --> | |
</div> | |
</div> | |
<p class="mt-2 text-xs text-slate-500 flex-shrink-0 text-center">Note: Some JS/external resources might be restricted by the sandbox.</p> | |
</div> | |
<div id="history-panel-controls"> | |
<button id="history-nav-left-button" class="history-nav-button" aria-label="Previous History Step" title="Previous History (Alt + Page Up)" disabled> | |
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-left"><path d="m15 18-6-6 6-6"/></svg> | |
</button> | |
<button id="history-toggle-button" aria-label="Toggle History Panel"> | |
<svg id="history-arrow-down" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down hidden"><path d="m6 9 6 6 6-6"/></svg> | |
<svg id="history-arrow-up" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-up"><path d="m18 15-6-6-6 6"/></svg> | |
</button> | |
<button id="history-nav-right-button" class="history-nav-button" aria-label="Next History Step" title="Next History (Alt + Page Down)" disabled> | |
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right"><path d="m9 18 6-6-6-6"/></svg> | |
</button> | |
</div> | |
<div id="history-panel" class="history-collapsed"> | |
<div id="history-panel-placeholder">Evolution history will appear here.</div> | |
</div> | |
<div id="refinement-loading-indicator"> | |
<span>Refining code...</span> | |
<svg class="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> | |
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> | |
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> | |
</svg> | |
</div> | |
<div id="fullscreen-overlay"> | |
<div id="fullscreen-history-nav"> | |
<button id="history-nav-prev" title="Previous History (W)"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="inline-block mr-1"><polyline points="15 18 9 12 15 6"></polyline></svg> | |
Prev (W) | |
</button> | |
<button id="history-nav-next" title="Next History (D)"> | |
Next (D) | |
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="inline-block ml-1"><polyline points="9 18 15 12 9 6"></polyline></svg> | |
</button> | |
</div> | |
<button id="exit-fullscreen-btn" class="px-3 py-1 text-sm font-medium rounded hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-1 focus:ring-offset-slate-900" title="Exit Full Screen"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="inline-block mr-1 -mt-px"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg> | |
Exit | |
</button> | |
<iframe id="fullscreen-iframe" title="Full Screen Preview"></iframe> | |
</div> | |
<div id="prompt-modal-overlay" class="modal-overlay"> | |
<div id="prompt-modal-content" class="modal-content"> | |
<h3 class="text-xl font-semibold text-cyan-300">Enter Prompt (Alt+P)</h3> | |
<textarea id="modal-user-prompt" rows="6" class="futuristic-input block w-full px-3 py-2 sm:text-sm" placeholder="Describe the web page/app to build or refine..."></textarea> | |
<div class="flex items-center mt-2"> | |
<input id="modal-refinement-checkbox" name="modal-refinement-checkbox" type="checkbox" class="h-4 w-4 text-cyan-500 focus:ring-cyan-400 border-slate-600 rounded bg-slate-700 focus:ring-offset-slate-800"> | |
<label for="modal-refinement-checkbox" class="ml-2 block text-sm text-slate-200">Use prompt to refine active evolution</label> | |
</div> | |
<div class="mt-2"> | |
<label for="num-variations-slider" class="block text-sm font-medium text-slate-300 mb-1">Number of Variations: <span id="num-variations-value">4</span></label> | |
<input type="range" id="num-variations-slider" name="num-variations-slider" min="1" max="4" step="1" value="4" class="futuristic-slider w-full h-2 rounded-lg appearance-none cursor-pointer"> | |
</div> | |
<div class="mt-2"> | |
<label for="model-select" class="block text-sm font-medium text-slate-300 mb-1">Select Model:</label> | |
<select id="model-select" name="model-select" class="futuristic-select block w-full sm:text-sm"> | |
<option value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> | |
<option value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> | |
<option value="gemini-2.0-flash">gemini-2.0-flash</option> | |
<option value="gemini-2.0-flash-lite">gemini-2.0-flash-lite</option> | |
</select> | |
</div> | |
<div class="mt-3"> | |
<label for="modal-thinking-budget-slider" class="block text-sm font-medium text-slate-300 mb-1">Thinking Budget: <span id="modal-thinking-budget-value">0</span></label> | |
<input type="range" id="modal-thinking-budget-slider" name="modal-thinking-budget-slider" min="0" max="24576" step="1024" value="0" class="futuristic-slider w-full h-2 rounded-lg appearance-none cursor-pointer"> | |
<p class="mt-1 text-xs text-slate-400">Set to 0 to disable. Higher values may improve quality for complex prompts but increase latency.</p> | |
</div> | |
<p class="text-xs text-slate-400 mt-1">Use Ctrl/Cmd+Enter to generate, Esc to close.</p> | |
<div class="flex justify-end gap-3 mt-2"> | |
<button id="modal-cancel-button" class="futuristic-button modal-button-secondary px-4 py-2 text-sm">Cancel</button> | |
<button id="modal-generate-button" class="futuristic-button px-4 py-2 text-sm"> | |
Generate | |
<svg id="modal-loading-indicator" class="animate-spin -mr-1 ml-3 h-5 w-5 text-white hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> | |
</button> | |
</div> | |
</div> | |
</div> | |
<div id="config-modal-overlay" class="modal-overlay"> | |
<div id="config-modal-content" class="modal-content"> | |
<h3 class="text-xl font-semibold text-cyan-300">Configuration (Alt+O)</h3> | |
<div class="space-y-4"> | |
<div> | |
<label for="api-key" class="block text-sm font-medium text-slate-300 mb-1">Gemini API Key (AI Studio):</label> | |
<input type="password" id="api-key" name="api-key" class="futuristic-input block w-full sm:text-sm" placeholder="Enter your API Key"> | |
</div> | |
<div class="pt-1"> | |
<label for="preview-interval-slider" class="block text-sm font-medium text-slate-300 mb-1">Live Preview Update Interval: <span id="interval-value">500</span>ms</label> | |
<input type="range" id="preview-interval-slider" name="preview-interval-slider" min="100" max="2000" step="100" value="500" class="futuristic-slider w-full h-2 rounded-lg appearance-none cursor-pointer"> | |
<p class="mt-1 text-xs text-slate-400">Min time between preview updates (higher = less frequent).</p> | |
</div> | |
<div id="code-output-container"> | |
<div id="code-output-header"> | |
<h3 id="selected-code-title" class="text-lg font-medium text-cyan-300 flex-shrink-0">Selected Code:</h3> | |
<div class="flex items-center gap-2"> | |
<button id="copy-code-button" title="Copy Code"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg> | |
</button> | |
<button id="export-code-button" title="Export Code as ZIP"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg> | |
</button> | |
</div> | |
</div> | |
<div class="flex-grow overflow-hidden min-h-0 flex"> | |
<pre id="code-output" class="h-full"><code class="language-html">// Select a variation or history item to view its code.</code></pre> | |
</div> | |
</div> | |
</div> | |
<div class="flex justify-end gap-3 mt-4"> | |
<button id="config-modal-close-button" class="futuristic-button modal-button-secondary px-4 py-2 text-sm">Close</button> | |
</div> | |
</div> | |
</div> | |
<div id="confirm-modal-overlay" class="modal-overlay"> | |
<div id="confirm-modal-content" class="modal-content max-w-md"> | |
<h3 class="text-xl font-semibold text-cyan-300">Confirm Action</h3> | |
<p id="confirm-modal-message" class="text-sm text-slate-300">Are you sure?</p> | |
<div class="flex justify-end gap-3 mt-4"> | |
<button id="confirm-modal-cancel-button" class="futuristic-button modal-button-secondary px-4 py-2 text-sm">Cancel</button> | |
<button id="confirm-modal-confirm-button" class="futuristic-button px-4 py-2 text-sm bg-red-600 hover:bg-red-700">Confirm</button> | |
</div> | |
</div> | |
</div> | |
<div id="prompt-display-modal-overlay" class="modal-overlay"> | |
<div id="prompt-display-modal-content" class="modal-content max-w-2xl"> | |
<h3 class="text-xl font-semibold text-cyan-300 mb-2">Full Prompt</h3> | |
<pre id="full-prompt-text" class="text-sm text-slate-300 whitespace-pre-wrap break-words bg-slate-800 p-3 rounded border border-slate-600 max-h-96 overflow-y-auto"></pre> | |
<div class="flex justify-end gap-3 mt-4"> | |
<button id="prompt-display-modal-close-button" class="futuristic-button modal-button-secondary px-4 py-2 text-sm">Close</button> | |
</div> | |
</div> | |
</div> | |
<script src="script.js"></script> | |
</body> | |
</html> |