File size: 15,836 Bytes
910f58d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a666ef
 
 
910f58d
 
 
 
 
 
 
 
 
5a666ef
910f58d
 
 
37b43e8
 
 
d44c0bc
 
 
 
 
010247e
37b43e8
 
 
 
 
 
 
 
 
910f58d
 
37b43e8
910f58d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52a2d9e
910f58d
 
 
 
 
52a2d9e
910f58d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a666ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<!DOCTYPE html>
<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>