Luigi commited on
Commit
a4cda04
·
verified ·
1 Parent(s): bf4a5d3

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +282 -430
index.html CHANGED
@@ -2,276 +2,130 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> <!-- iOS viewport settings -->
6
- <title>Autotutorial.ai - iOS Demo</title> <!-- iOS Style Title -->
7
- <link rel="manifest" href="manifest.json"> <!-- PWA manifest (placeholder - create manifest.json for full PWA) -->
8
- <meta name="apple-mobile-web-app-capable" content="yes"> <!-- iOS PWA meta -->
9
- <meta name="apple-mobile-web-app-status-bar-style" content="default"> <!-- iOS status bar style -->
10
- <!-- Radix UI Styles -->
11
- <link rel="stylesheet" href="https://unpkg.com/@radix-ui/[email protected]/dist/index.css">
12
- <!-- Tailwind CSS CDN -->
13
- <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
14
  <!-- Font Awesome CDN -->
15
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
16
- <!-- Inter & SF Pro Display Fonts (SF Pro Display approximation) -->
 
17
  <link rel="preconnect" href="https://fonts.googleapis.com">
18
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
19
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=SF+Pro+Display:wght@400;500;600;700&display=swap" rel="stylesheet"> <!-- SF Pro Display approximation -->
20
 
21
  <style>
22
- /* iOS App Reset and Base Styles */
23
- body {
24
- font-family: 'Inter', sans-serif; /* Default to Inter, fallback if SF Pro Display doesn't load perfectly */
25
- -webkit-font-smoothing: antialiased;
26
- -moz-osx-font-smoothing: grayscale;
27
- background-color: var(--gray-100); /* Lighter iOS-like background */
28
- color: var(--gray-900);
29
- margin: 0; /* Reset margins */
30
- padding-bottom: 50px; /* Padding for bottom tab bar */
31
  }
32
-
33
- /* Use SF Pro Display if available, for headings and key UI text - approximation */
34
- @font-face {
35
- font-family: 'SF Pro Display'; /* Name to use in CSS */
36
- src: url('https://cdn.jsdelivr.net/gh/fontsource/fontsource-sf-pro-display@latest/files/sf-pro-display-latin-400-normal.woff2') format('woff2'), /* Example CDN - consider hosting or local */
37
- url('https://cdn.jsdelivr.net/gh/fontsource/fontsource-sf-pro-display@latest/files/sf-pro-display-latin-400-normal.woff') format('woff');
38
- /* Add other weights as needed */
39
- font-weight: 400;
40
- font-style: normal;
41
- font-display: swap; /* or optional */
42
  }
43
-
44
- h1, h2, h3, h4, h5, h6, .ios-title-font { font-family: 'SF Pro Display', sans-serif; } /* Apply to titles and key text */
45
-
46
-
47
- .app-container {
48
- max-width: 768px; /* Mobile-first max width */
49
- margin: 0 auto; /* Center on larger screens */
50
- background-color: var(--gray-50); /* Even lighter background, closer to iOS */
51
- border-radius: 0px; /* No border radius for full-screen app feel */
52
  overflow: hidden;
53
- box-shadow: none; /* Remove shadow for flatter iOS style */
54
- min-height: 100vh; /* Full viewport height */
55
- display: flex;
56
- flex-direction: column; /* Vertical flex layout */
57
- }
58
-
59
- header {
60
- background-color: var(--gray-50); /* White header background */
61
- padding: 2rem 1.5rem 1rem 1.5rem; /* Adjusted header padding - less top, more bottom */
62
- color: var(--gray-900);
63
- border-bottom: 1px solid var(--gray-200); /* iOS-style separator */
64
- }
65
-
66
- header h1 {
67
- font-size: 2.25rem; /* Large iOS title size */
68
- font-weight: 700;
69
- letter-spacing: -0.02em;
70
- margin-bottom: 0.25rem; /* Reduced bottom margin */
71
- text-align: left; /* Left-align iOS style */
72
- }
73
-
74
- header p {
75
- font-size: 1.1rem; /* Slightly smaller subtitle */
76
- color: var(--gray-600); /* Muted subtitle color */
77
- font-weight: 400;
78
  }
79
-
80
- main {
81
- padding: 1.5rem; /* Reduced main padding for mobile */
82
- flex-grow: 1; /* Main content takes up remaining space */
83
- }
84
-
85
- section {
86
- margin-bottom: 2rem; /* Reduced section margin */
87
- }
88
-
89
- section h2 {
90
- font-size: 1.7rem; /* Section title size */
91
  font-weight: 600;
92
- color: var(--gray-800);
93
- margin-bottom: 1.25rem; /* Reduced section title margin */
94
- letter-spacing: -0.015em;
95
- text-align: left; /* Left-align section titles */
96
- }
97
-
98
- section h3 {
99
- font-size: 1.3rem; /* Subtitle size */
100
- font-weight: 500;
101
- color: var(--gray-700);
102
- margin-bottom: 0.8rem; /* Reduced subtitle margin */
103
- letter-spacing: -0.01em;
104
- text-align: left; /* Left-align subtitles */
105
- }
106
-
107
- .input-label { @apply block text-gray-700 text-sm font-semibold mb-1; } /* Smaller label margin */
108
- .status-box { @apply border rounded-md p-4 mb-3 bg-gray-50 border-gray-200 relative overflow-hidden; } /* Reduced status box margin */
109
- .error-text { @apply text-red-500 mt-1 text-sm; } /* Smaller error text margin */
110
- .video-player-container { @apply rounded-md overflow-hidden shadow-md; } /* Keep shadow for video player */
111
- .video-overlay-title { position: absolute; bottom: 15px; left: 15px; color: white; font-size: 1.5rem; font-weight: 600; text-shadow: 1px 1px 2px rgba(0,0,0,0.6); } /* Smaller video overlay title */
112
-
113
- footer {
114
- background-color: var(--gray-50); /* White footer */
115
- border-top: 1px solid var(--gray-200); /* iOS footer separator */
116
- padding: 1.25rem 1.5rem; /* Reduced footer padding */
117
- text-center text-gray-500 text-sm;
118
  }
119
-
120
- footer a { color: var(--gray-600); text-decoration: none; }
121
- footer a:hover { text-decoration: underline; }
122
-
123
- .tutorial-item { @apply bg-white p-3.5 rounded-md shadow-sm border border-gray-100 hover:shadow-md transition-shadow duration-200 cursor-pointer mb-2; } /* Reduced tutorial item padding and margin */
124
- .tutorial-item h3 { @apply font-semibold text-gray-800 mb-1; font-size: 1.1rem; } /* Smaller tutorial item title */
125
- .tutorial-item p { @apply text-gray-600 text-sm; }
126
- .tutorial-list-section { display: flex; flex-direction: column; gap: 0.75rem; } /* Vertical tutorial list */
127
- .settings-grid { display: grid; grid-template-columns: 1fr; gap: 1.75rem; } /* Single column settings on mobile */
128
- @media (min-width: 768px) { /* Medium screens and up */
129
- .settings-grid { grid-template-columns: 1fr 1fr; } /* Two-column settings on larger screens */
130
- }
131
- .help-section p { line-height: 1.6; margin-bottom: 1rem; }
132
-
133
- /* Radix UI Button Styling - iOS Style Refinements */
134
- .radix-button {
135
- @apply inline-flex items-center justify-center rounded-md px-4 py-2 font-semibold text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors duration-200; /* Reduced button padding */
136
- -webkit-tap-highlight-color: transparent; /* Remove tap highlight on iOS */
137
- }
138
- .radix-button-primary { @apply radix-button bg-indigo-600 hover:bg-indigo-700 active:bg-indigo-800 text-white shadow-sm hover:shadow-md; }
139
- .radix-button-primary:disabled { @apply bg-indigo-300 cursor-not-allowed hover:bg-indigo-300 focus:ring-0 shadow-none; }
140
- .radix-button-secondary { @apply radix-button bg-gray-200 hover:bg-gray-300 active:bg-gray-400 text-gray-700 shadow-sm hover:shadow-md; }
141
- .radix-button-apply { @apply radix-button bg-green-500 hover:bg-green-600 active:bg-green-700 text-white shadow-sm hover:shadow-md; }
142
-
143
- /* Radix UI Input Styling - iOS Style Refinements */
144
- .radix-input {
145
- @apply appearance-none border rounded-md w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-shadow duration-200; /* Reduced input padding */
146
- border-color: var(--gray-300);
147
- background-color: var(--gray-50); /* Light gray input background */
148
- color: var(--gray-900);
149
- box-shadow: inset 0 0 0 1px var(--gray-300); /* iOS-like border shadow */
150
- }
151
- .radix-input:focus { @apply shadow-none border-indigo-500; box-shadow: inset 0 0 0 2px var(--indigo-500); } /* iOS-like focus */
152
-
153
- /* Radix UI Select Styling - iOS Style - Needs more JS for true iOS Picker */
154
- .radix-select-trigger {
155
- @apply radix-button radix-button-secondary w-full justify-between;
156
- border-radius: 8px; /* More rounded select */
157
- padding-left: 1rem; padding-right: 1rem; /* Adjust select padding */
158
  }
159
- .radix-select-content {
160
- @apply rounded-md shadow-md bg-white border border-gray-200 overflow-hidden;
161
  }
162
- .radix-select-item {
163
- @apply px-3.5 py-2 text-sm text-gray-700 cursor-pointer hover:bg-gray-100 focus:outline-none focus:bg-gray-100;
164
- }
165
- .radix-select-item[data-highlighted] { @apply bg-indigo-50 text-indigo-900; }
166
-
167
- /* Progress Bar - iOS Style - Thinner */
168
- .status-progress-bar { position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background-color: var(--indigo-500); transform-origin: 0% 0%; transform: scaleX(0); transition: transform 0.4s ease-out; }
169
- .status-progress-bar.active { transform: scaleX(1); }
170
-
171
- /* Transitions */
172
- .transition-opacity { transition-property: opacity; transition-timing-function: ease-out; transition-duration: 200ms; }
173
-
174
- /* Bottom Tab Bar Navigation - iOS Style */
175
- .bottom-tab-bar {
176
- position: fixed; bottom: 0; left: 0; right: 0;
177
- background-color: var(--gray-50); /* White tab bar background */
178
- border-top: 1px solid var(--gray-200); /* iOS tab bar border */
179
- padding-top: 0.5rem; padding-bottom: calc(env(safe-area-inset-bottom) + 0.5rem); /* Safe area padding for iOS */
180
- display: flex; justify-content: space-around;
181
- z-index: 100; /* Ensure it's on top */
182
- }
183
-
184
- .bottom-tab-button {
185
- display: flex; flex-direction: column; align-items: center;
186
- color: var(--gray-500); /* Inactive tab color */
187
- text-decoration: none;
188
- font-size: 0.85rem; /* Smaller tab label */
189
- padding: 0.5rem 1rem; border-radius: 8px; /* Tab button padding and rounded corners */
190
- -webkit-tap-highlight-color: transparent; /* Remove tap highlight on iOS */
191
- }
192
-
193
- .bottom-tab-button.active, .bottom-tab-button:active, .bottom-tab-button:hover {
194
- color: var(--indigo-600); /* Active/tapped tab color */
195
- background-color: var(--gray-100); /* Slightly highlight active tab */
196
- }
197
-
198
- .bottom-tab-icon {
199
- font-size: 1.3rem; /* Tab icon size */
200
- margin-bottom: 0.25rem;
201
- }
202
-
203
- /* Scrollbar - minimal for mobile */
204
- ::-webkit-scrollbar { width: 4px; height: 4px; }
205
- ::-webkit-scrollbar-track { background: transparent; } /* Transparent track */
206
- ::-webkit-scrollbar-thumb { background: var(--gray-400); border-radius: 2px; } /* Thinner, lighter thumb */
207
- ::-webkit-scrollbar-thumb:hover { background: var(--gray-500); }
208
- * { scrollbar-width: thin; scrollbar-color: var(--gray-400) transparent; } /* Firefox scrollbar */
209
-
210
-
211
  </style>
212
  </head>
213
- <body class="bg-gray-100"> <!-- Body background for overscroll effect -->
214
- <div class="app-container">
215
- <!-- Header Section (iOS Style - Large Title) -->
216
- <header>
217
- <h1 class="ios-title-font">Autotutorial.ai</h1>
218
- <p>Generate Video Tutorials</p>
219
- </header>
220
-
221
- <!-- Main Content Area -->
222
- <main>
223
- <!-- Generate Tutorial Section -->
224
- <section id="generate-section">
225
- <h2 class="text-xl">New Tutorial</h2>
226
- <p class="text-gray-700 mb-6">Set topic and duration to begin.</p>
227
-
228
- <div class="grid grid-cols-1 md:grid-cols-2 gap-5 mb-5">
229
- <div>
230
- <label for="tutorialTopic" class="input-label">Topic <span class="text-gray-500">(e.g., "React Forms")</span></label>
231
- <input type="text" id="tutorialTopic" class="radix-input" placeholder="Enter topic" value="Vue.js Teleport Feature" required>
232
- </div>
233
- <div>
234
- <label for="desiredDuration" class="input-label">Duration (Minutes)</label>
235
- <select id="desiredDuration" class="radix-select-trigger">
236
- <option value="5" class="radix-select-item">5 Minutes</option>
237
- <option value="10" selected class="radix-select-item">10 Minutes</option>
238
- <option value="15" class="radix-select-item">15 Minutes</option>
239
- <option value="20" class="radix-select-item">20 Minutes</option>
240
- </select>
241
- </div>
242
- </div>
243
-
244
- <section class="mb-5">
245
- <h3 class="text-lg font-semibold mb-3 text-gray-800">API Keys <span class="text-gray-500">(Optional)</span></h3>
246
- <div class="settings-grid">
247
- <div>
248
- <label for="openaiApiKey" class="input-label">OpenAI Key <span class="text-gray-500">(Script AI)</span></label>
249
- <input type="text" id="openaiApiKey" class="radix-input" placeholder="OpenAI API Key (Optional)" value="sk-DEMO_OPENAI_KEY">
250
- </div>
251
- <div>
252
- <label for="videoGenApiKey" class="input-label">Video Key <span class="text-gray-500">(Video AI)</span></label>
253
- <input type="text" id="videoGenApiKey" class="radix-input" placeholder="Video API Key (Optional)" value="vg-DEMO_VIDEO_GEN_KEY">
254
- </div>
 
 
 
 
 
 
 
 
255
  </div>
256
- <p class="text-sm text-gray-500 mt-2">For enhanced AI features.</p>
257
- </section>
258
 
259
- <section class="mb-5 flex justify-start gap-3">
260
- <button id="generateButton" class="radix-button-primary"><i class="fas fa-magic mr-2"></i> Generate</button>
261
- <button id="resetButton" class="radix-button-secondary hidden"><i class="fas fa-redo mr-2"></i> Reset</button>
262
- </section>
263
 
264
- <section id="statusSection" class="status-box">
265
- <h3 class="font-semibold text-gray-700 mb-2"><i class="fas fa-info-circle mr-2"></i> Status</h3>
 
 
 
266
  <div id="statusMessages">
267
- <p class="text-gray-600"><i class="fas fa-check-circle text-green-500 mr-1"></i> Ready. Tap "Generate".</p>
268
  </div>
269
- <p id="errorMessage" class="error-text hidden"></p>
270
- <div id="progressBar" class="status-progress-bar"></div>
271
- </section>
272
-
273
- <section id="videoOutputSection" class="hidden transition-opacity opacity-0 duration-200">
274
- <h2 class="text-lg font-semibold mb-3 text-gray-800"><i class="fas fa-film mr-2"></i> Preview</h2>
 
 
 
 
275
  <div class="video-player-container">
276
  <video id="tutorialVideo" controls width="100%">
277
  <source src="https://joy.videvo.net/videvo_files/video/free/2016-06/small_watermarked/Drone_Flying_Above_City_Skyline_preview.mp4" type="video/mp4">
@@ -279,160 +133,175 @@
279
  </video>
280
  <div id="videoTitleOverlay" class="video-overlay-title"></div>
281
  </div>
282
- <div class="mt-3 flex justify-between items-center">
283
  <div>
284
- <p class="text-gray-700 text-sm"><strong>Title:</strong> <span id="videoTitle"></span></p>
 
285
  </div>
286
- <div>
287
- <a href="#" id="downloadButton" class="radix-button-primary" download="tutorial.mp4"><i class="fas fa-download mr-2"></i> Download</a>
288
- </div>
289
- </div>
290
- </section>
291
- </section>
292
-
293
- <!-- Tutorial History Section -->
294
- <section id="history-section" class="hidden">
295
- <h2 class="text-xl">History</h2>
296
- <p class="text-gray-700 mb-6">Past tutorials.</p>
297
-
298
- <div class="tutorial-list-section">
299
- <div class="tutorial-item history-item" data-video-title="Mastering JavaScript Promises">
300
- <h3>JavaScript Promises</h3>
301
- <p>Oct 26, 2023</p>
302
- </div>
303
- <div class="tutorial-item history-item" data-video-title="Introduction to Python for Data Science">
304
- <h3>Python for Data Science</h3>
305
- <p>Oct 25, 2023</p>
306
  </div>
307
- <div class="tutorial-item history-item" data-video-title="Building a REST API with Express.js">
308
- <h3>REST API with Express.js</h3>
309
- <p>Oct 20, 2023</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  </div>
311
- </div>
312
- <p class="mt-3 text-sm text-gray-500">Demo history.</p>
313
- </section>
314
-
315
- <!-- Settings Section -->
316
- <section id="settings-section" class="hidden">
317
- <h2 class="text-xl">Settings</h2>
318
- <p class="text-gray-700 mb-6">App preferences.</p>
319
-
320
- <div class="settings-grid">
321
- <div>
322
- <label for="defaultDurationSetting" class="input-label">Default Duration</label>
323
- <select id="defaultDurationSetting" class="radix-select-trigger">
324
- <option value="5" class="radix-select-item">5 Minutes</option>
325
- <option value="10" selected class="radix-select-item">10 Minutes</option>
326
- <option value="15" class="radix-select-item">15 Minutes</option>
327
- </select>
328
- </div>
329
- <div>
330
- <label for="videoQualitySetting" class="input-label">Video Quality</label>
331
- <select id="videoQualitySetting" class="radix-select-trigger">
332
- <option value="720p" selected class="radix-select-item">720p HD</option>
333
- <option value="1080p" class="radix-select-item">1080p Full HD</option>
334
- <option value="4k" class="radix-select-item">4K Ultra HD (Premium)</option>
335
- </select>
336
- </div>
337
- <div>
338
- <label for="voiceoverLanguage" class="input-label">Voiceover Language</label>
339
- <select id="voiceoverLanguage" class="radix-select-trigger">
340
- <option value="en-US" selected class="radix-select-item">English (US)</option>
341
- <option value="en-GB" class="radix-select-item">English (UK)</option>
342
- <option value="es-ES" class="radix-select-item">Spanish</option>
343
- <option value="fr-FR" class="radix-select-item">French</option>
344
- </select>
345
- </div>
346
- <div>
347
- <label for="outputFormat" class="input-label">Output Format</label>
348
- <select id="outputFormat" class="radix-select-trigger">
349
- <option value="mp4" selected class="radix-select-item">MP4 (Recommended)</option>
350
- <option value="mov" class="radix-select-item">MOV</option>
351
- <option value="webm" class="radix-select-item">WebM</option>
352
- </select>
353
- </div>
354
- </div>
355
- <div class="mt-4 flex justify-start">
356
- <button id="applySettingsButton" class="radix-button-apply"><i class="fas fa-check mr-2"></i> Apply</button>
357
- </div>
358
- <p class="mt-3 text-sm text-gray-500">Demo settings.</p>
359
- </section>
360
-
361
- <!-- Help Section -->
362
- <section id="help-section" class="hidden">
363
- <h2 class="text-xl">Help</h2>
364
- <p class="text-gray-700 mb-6">App guidance.</p>
365
-
366
- <div class="help-section">
367
- <p>Welcome to Autotutorial.ai! Generate videos easily.</p>
368
  <p><strong>Getting Started:</strong></p>
369
- <ol class="list-decimal pl-5 mb-4">
370
- <li>Go to "Generate" tab.</li>
371
- <li>Enter tutorial topic.</li>
372
- <li>Select duration.</li>
373
- <li>(Optional) Add API keys.</li>
374
- <li>Tap "Generate".</li>
375
- <li>See "Status" for progress.</li>
376
- <li>Preview in "Preview" section.</li>
377
  </ol>
378
- <p><strong>History:</strong></p>
379
- <p>Access past tutorials in "History" (demo).</p>
380
  <p><strong>Settings:</strong></p>
381
- <p>Customize preferences in "Settings" (demo).</p>
382
- <p>For support, contact <a href="mailto:[email protected]">[email protected]</a>.</p>
383
- </div>
384
- </section>
385
-
386
- </main>
387
-
388
- <!-- Bottom Tab Bar Navigation -->
389
- <nav class="bottom-tab-bar">
390
- <a href="#generate" class="bottom-tab-button active" data-section="generate">
391
- <i class="fas fa-magic bottom-tab-icon"></i>
392
- Generate
393
- </a>
394
- <a href="#history" class="bottom-tab-button" data-section="history">
395
- <i class="fas fa-history bottom-tab-icon"></i>
396
- History
397
- </a>
398
- <a href="#settings" class="bottom-tab-button" data-section="settings">
399
- <i class="fas fa-cog bottom-tab-icon"></i>
400
- Settings
401
- </a>
402
- <a href="#help" class="bottom-tab-button" data-section="help">
403
- <i class="fas fa-question-circle bottom-tab-icon"></i>
404
- Help
405
- </a>
406
- </nav>
407
-
408
- </div>
 
 
 
 
 
409
 
410
  <script>
411
  document.addEventListener('DOMContentLoaded', () => {
412
- // Bottom Tab Navigation functionality
413
- const tabButtons = document.querySelectorAll('.bottom-tab-button');
414
- const sections = document.querySelectorAll('main > section');
415
 
416
  tabButtons.forEach(button => {
417
  button.addEventListener('click', function(event) {
418
  event.preventDefault();
419
- const sectionId = this.getAttribute('data-section');
420
 
421
  tabButtons.forEach(btn => btn.classList.remove('active'));
422
- sections.forEach(sec => sec.classList.add('hidden'));
423
 
424
  this.classList.add('active');
425
- document.getElementById(`${sectionId}-section`).classList.remove('hidden');
426
- if (sectionId === 'generate') {
427
- document.getElementById('videoOutputSection').classList.add('hidden');
428
  document.getElementById('videoOutputSection').classList.remove('opacity-0');
429
  }
430
  });
431
  });
432
- document.querySelector('.bottom-tab-button[data-section="generate"]').classList.add('active');
433
- document.getElementById('generate-section').classList.remove('hidden');
434
 
435
- // Tutorial History Item Click Simulation (same as before)
 
436
  const historyItems = document.querySelectorAll('.history-item');
437
  const videoTitleSpan = document.getElementById('videoTitle');
438
  const videoTitleOverlay = document.getElementById('videoTitleOverlay');
@@ -442,25 +311,24 @@
442
  const title = this.getAttribute('data-video-title');
443
  videoTitleSpan.textContent = title + " (Preview)";
444
  videoTitleOverlay.textContent = title;
445
- videoOutputSection.classList.remove('hidden');
446
  videoOutputSection.classList.remove('opacity-0');
447
  const statusMessagesDiv = document.getElementById('statusMessages');
448
- statusMessagesDiv.innerHTML = `<p class="text-gray-600"><i class="fas fa-video text-indigo-500 mr-1"></i> Loading: ${title}</p>`;
449
  statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
450
  });
451
  });
452
 
453
- // Apply Settings Button Simulation (same as before)
454
  document.getElementById('applySettingsButton').addEventListener('click', function() {
455
  const statusMessagesDiv = document.getElementById('statusMessages');
456
- statusMessagesDiv.innerHTML = `<p class="text-green-600"><i class="fas fa-check-circle text-green-500 mr-1"></i> Settings Applied.</p>`;
457
  statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
458
  });
459
  });
460
 
461
 
462
  document.getElementById('generateButton').addEventListener('click', function() {
463
- // ... (same generateButton event listener logic as before) ...
464
  const topic = document.getElementById('tutorialTopic').value;
465
  const duration = document.getElementById('desiredDuration').value;
466
  const openaiKey = document.getElementById('openaiApiKey').value;
@@ -477,16 +345,13 @@
477
 
478
  // Reset status and hide video output
479
  statusMessagesDiv.innerHTML = '';
480
- errorMessageDiv.classList.add('hidden');
481
- videoOutputSection.classList.add('hidden');
482
  videoOutputSection.classList.remove('opacity-0');
483
- resetButton.classList.add('hidden');
484
- generateButton.disabled = true;
485
- statusSection.querySelector('h3 i').classList.remove('fa-check-circle', 'text-green-500', 'fa-times-circle', 'text-red-500');
486
- statusSection.querySelector('h3 i').classList.add('fa-spinner', 'fa-spin', 'mr-2');
487
- statusSection.querySelector('h3').innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Status';
488
- progressBar.style.transform = 'scaleX(0)';
489
- progressBar.classList.add('active');
490
 
491
 
492
  const steps = [
@@ -504,24 +369,21 @@
504
  function processStep() {
505
  if (currentStepIndex < steps.length) {
506
  simulateStep(statusMessagesDiv, steps[currentStepIndex].message, steps[currentStepIndex].delay, () => {
507
- progressBar.style.transform = `scaleX(${((currentStepIndex + 1) / steps.length)})`;
508
  currentStepIndex++;
509
  processStep();
510
  }, true);
511
  } else {
512
- progressBar.classList.remove('active');
513
- statusMessagesDiv.innerHTML = '<p class="text-green-600"><i class="fas fa-check-circle text-green-500 mr-1"></i> Generation Complete!</p>';
514
- statusSection.querySelector('h3 i').classList.remove('fa-spinner', 'fa-spin', 'mr-2');
515
- statusSection.querySelector('h3 i').classList.add('fa-check-circle', 'text-green-500', 'mr-2');
516
- statusSection.querySelector('h3').innerHTML = '<i class="fas fa-check-circle text-green-500 mr-2"></i> Status';
517
 
518
  videoTitleSpan.textContent = topic + " (" + duration + "min Preview)";
519
  videoTitleOverlay.textContent = topic;
520
- videoOutputSection.classList.remove('hidden');
521
  setTimeout(() => videoOutputSection.classList.remove('opacity-0'), 50);
522
- generateButton.disabled = false;
523
- generateButton.classList.add('hidden');
524
- resetButton.classList.remove('hidden');
525
  }
526
  }
527
  processStep();
@@ -530,28 +392,21 @@
530
  });
531
 
532
  document.getElementById('resetButton').addEventListener('click', function() {
533
- // ... (same resetButton event listener logic as before) ...
534
  const statusMessagesDiv = document.getElementById('statusMessages');
535
  const errorMessageDiv = document.getElementById('errorMessage');
536
  const generateButton = document.getElementById('generateButton');
537
  const resetButton = document.getElementById('resetButton');
538
- const statusSection = document.getElementById('statusSection');
539
  const videoOutputSection = document.getElementById('videoOutputSection');
540
  const progressBar = document.getElementById('progressBar');
541
 
542
- statusMessagesDiv.innerHTML = '<p class="text-gray-600"><i class="fas fa-check-circle text-green-500 mr-1"></i> Ready. Tap "Generate".</p>';
543
- errorMessageDiv.classList.add('hidden');
544
- videoOutputSection.classList.add('hidden');
545
  videoOutputSection.classList.remove('opacity-0');
546
- generateButton.disabled = false;
547
- generateButton.classList.remove('hidden');
548
- resetButton.classList.add('hidden');
549
- statusSection.querySelector('h3 i').classList.remove('fa-times-circle', 'text-red-500', 'fa-spinner', 'fa-spin', 'mr-2');
550
- statusSection.querySelector('h3 i').classList.add('fa-check-circle', 'text-green-500', 'mr-2');
551
- statusSection.querySelector('h3').innerHTML = '<i class="fas fa-check-circle text-green-500 mr-2"></i> Status';
552
- progressBar.classList.remove('active');
553
- progressBar.style.transform = 'scaleX(0)';
554
-
555
  });
556
 
557
 
@@ -559,20 +414,17 @@
559
  setTimeout(function() {
560
  const messageElement = document.createElement('p');
561
  if (isSuccess) {
562
- messageElement.classList.add('text-gray-600');
563
- messageElement.innerHTML = `<i class="fas fa-spinner fa-pulse text-indigo-500 mr-1"></i> ${message}`;
564
  } else {
565
- messageElement.classList.add('text-red-500');
566
- messageElement.innerHTML = `<i class="fas fa-times-circle text-red-500 mr-1"></i> ${message}`;
567
  document.getElementById('errorMessage').textContent = "Error generating tutorial. Check API keys.";
568
- document.getElementById('errorMessage').classList.remove('hidden');
569
- document.getElementById('statusSection').querySelector('h3 i').classList.remove('fa-spinner', 'fa-spin', 'mr-2');
570
- document.getElementById('statusSection').querySelector('h3 i').classList.add('fa-times-circle', 'text-red-500', 'mr-2');
571
- document.getElementById('statusSection').querySelector('h3').innerHTML = '<i class="fas fa-times-circle text-red-500 mr-2"></i> Status';
572
- document.getElementById('generateButton').disabled = false;
573
- document.getElementById('generateButton').classList.add('hidden');
574
- document.getElementById('resetButton').classList.remove('hidden');
575
- document.getElementById('progressBar').classList.remove('active');
576
  }
577
  statusDiv.appendChild(messageElement);
578
  statusDiv.scrollTop = statusDiv.scrollHeight;
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>Autotutorial.ai - Ionic Demo</title>
7
+ <link rel="manifest" href="manifest.json">
8
+ <meta name="apple-mobile-web-app-capable" content="yes">
9
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
10
+
11
+ <!-- Ionic CSS -->
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@latest/css/ionic.bundle.css">
13
+
14
  <!-- Font Awesome CDN -->
15
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
16
+
17
+ <!-- Inter Font from Google Fonts -->
18
  <link rel="preconnect" href="https://fonts.googleapis.com">
19
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
20
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
21
 
22
  <style>
23
+ :root {
24
+ --ion-font-family: 'Inter', sans-serif;
 
 
 
 
 
 
 
25
  }
26
+ body {
27
+ font-family: var(--ion-font-family);
 
 
 
 
 
 
 
 
28
  }
29
+ .video-player-container {
30
+ border-radius: 8px;
 
 
 
 
 
 
 
31
  overflow: hidden;
32
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
33
+ position: relative; /* For video overlay */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
+ .video-overlay-title {
36
+ position: absolute;
37
+ bottom: 16px;
38
+ left: 16px;
39
+ color: white;
40
+ font-size: 1.5em;
 
 
 
 
 
 
41
  font-weight: 600;
42
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
+ .status-box {
45
+ border-radius: 8px;
46
+ border: 1px solid var(--ion-color-light);
47
+ background-color: var(--ion-color-light-contrast);
48
+ padding: 16px;
49
+ margin-bottom: 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
+ .status-progress-bar {
52
+ margin-top: 8px;
53
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  </style>
55
  </head>
56
+ <body>
57
+
58
+ <ion-app>
59
+
60
+ <ion-header translucent="true">
61
+ <ion-toolbar>
62
+ <ion-title>Autotutorial.ai</ion-title>
63
+ </ion-toolbar>
64
+ </ion-header>
65
+
66
+ <ion-content fullscreen="true">
67
+
68
+ <ion-card>
69
+ <ion-card-header>
70
+ <ion-card-title>Generate Tutorial</ion-card-title>
71
+ <ion-card-subtitle>Create a new video tutorial</ion-card-subtitle>
72
+ </ion-card-header>
73
+
74
+ <ion-card-content>
75
+
76
+ <ion-list lines="full">
77
+ <ion-item>
78
+ <ion-label position="floating">Tutorial Topic</ion-label>
79
+ <ion-input type="text" id="tutorialTopic" value="React State Management Best Practices"></ion-input>
80
+ </ion-item>
81
+
82
+ <ion-item>
83
+ <ion-label>Desired Duration</ion-label>
84
+ <ion-select value="10" id="desiredDuration">
85
+ <ion-select-option value="5">5 Minutes</ion-select-option>
86
+ <ion-select-option value="10">10 Minutes</ion-select-option>
87
+ <ion-select-option value="15">15 Minutes</ion-select-option>
88
+ <ion-select-option value="20">20 Minutes</ion-select-option>
89
+ </ion-select>
90
+ </ion-item>
91
+
92
+ <ion-item>
93
+ <ion-label position="floating">OpenAI API Key (Optional)</ion-label>
94
+ <ion-input type="text" id="openaiApiKey" value="sk-DEMO_OPENAI_KEY" placeholder="For enhanced script generation"></ion-input>
95
+ </ion-item>
96
+
97
+ <ion-item>
98
+ <ion-label position="floating">Video Generation API Key (Optional)</ion-label>
99
+ <ion-input type="text" id="videoGenApiKey" value="vg-DEMO_VIDEO_GEN_KEY" placeholder="For advanced video synthesis"></ion-input>
100
+ </ion-item>
101
+ </ion-list>
102
+
103
+ <div style="margin-top: 20px; display: flex; gap: 10px;">
104
+ <ion-button id="generateButton" expand="block"><ion-icon slot="start" icon="magic"></ion-icon>Generate Tutorial</ion-button>
105
+ <ion-button id="resetButton" expand="block" color="secondary" class="ion-hide"><ion-icon slot="start" icon="refresh"></ion-icon>Reset</ion-button>
106
  </div>
 
 
107
 
108
+ </ion-card-content>
109
+ </ion-card>
 
 
110
 
111
+ <ion-card id="statusSection" class="status-box">
112
+ <ion-card-header>
113
+ <ion-card-title><ion-icon icon="information-circle" style="margin-right: 8px;"></ion-icon>Status Updates</ion-card-title>
114
+ </ion-card-header>
115
+ <ion-card-content>
116
  <div id="statusMessages">
117
+ <p class="ion-text-color-secondary"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Ready to generate. Click "Generate Tutorial".</p>
118
  </div>
119
+ <p id="errorMessage" class="ion-text-color-danger ion-hide" style="margin-top: 8px;"></p>
120
+ <ion-progress-bar value="0" buffer="0" reversed="false" class="status-progress-bar" id="progressBar"></ion-progress-bar>
121
+ </ion-card-content>
122
+ </ion-card>
123
+
124
+ <ion-card id="videoOutputSection" class="ion-hide">
125
+ <ion-card-header>
126
+ <ion-card-title><ion-icon icon="film" style="margin-right: 8px;"></ion-icon>Tutorial Preview</ion-card-title>
127
+ </ion-card-header>
128
+ <ion-card-content>
129
  <div class="video-player-container">
130
  <video id="tutorialVideo" controls width="100%">
131
  <source src="https://joy.videvo.net/videvo_files/video/free/2016-06/small_watermarked/Drone_Flying_Above_City_Skyline_preview.mp4" type="video/mp4">
 
133
  </video>
134
  <div id="videoTitleOverlay" class="video-overlay-title"></div>
135
  </div>
136
+ <div style="margin-top: 16px; display: flex; justify-content: space-between; align-items: center;">
137
  <div>
138
+ <p><strong id="videoTitle"></strong></p>
139
+ <ion-text color="secondary"><p>Generated tutorial preview</p></ion-text>
140
  </div>
141
+ <ion-button id="downloadButton" download="tutorial.mp4"><ion-icon slot="start" icon="download"></ion-icon>Download</ion-button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  </div>
143
+ </ion-card-content>
144
+ </ion-card>
145
+
146
+ <ion-card id="history-section" class="ion-hide">
147
+ <ion-card-header>
148
+ <ion-card-title><ion-icon icon="time" style="margin-right: 8px;"></ion-icon>Tutorial History</ion-card-title>
149
+ <ion-card-subtitle>Access past tutorials</ion-card-subtitle>
150
+ </ion-card-header>
151
+ <ion-card-content>
152
+ <ion-list id="historyList">
153
+ <ion-item button class="history-item" data-video-title="Mastering JavaScript Promises">
154
+ <ion-label>
155
+ <h3>Mastering JavaScript Promises</h3>
156
+ <p>Generated: Oct 26, 2023</p>
157
+ </ion-label>
158
+ </ion-item>
159
+ <ion-item button class="history-item" data-video-title="Introduction to Python for Data Science">
160
+ <ion-label>
161
+ <h3>Introduction to Python for Data Science</h3>
162
+ <p>Generated: Oct 25, 2023</p>
163
+ </ion-label>
164
+ </ion-item>
165
+ <ion-item button class="history-item" data-video-title="Building a REST API with Express.js">
166
+ <ion-label>
167
+ <h3>Building a REST API with Express.js</h3>
168
+ <p>Generated: Oct 20, 2023</p>
169
+ </ion-label>
170
+ </ion-item>
171
+ </ion-list>
172
+ <ion-text color="secondary"><p style="margin-top: 16px;">Demo history is simulated.</p></ion-text>
173
+ </ion-card-content>
174
+ </ion-card>
175
+
176
+ <ion-card id="settings-section" class="ion-hide">
177
+ <ion-card-header>
178
+ <ion-card-title><ion-icon icon="settings" style="margin-right: 8px;"></ion-icon>Settings</ion-card-title>
179
+ <ion-card-subtitle>Customize preferences</ion-card-subtitle>
180
+ </ion-card-header>
181
+ <ion-card-content>
182
+ <ion-list lines="full">
183
+ <ion-item>
184
+ <ion-label>Default Duration</ion-label>
185
+ <ion-select value="10" id="defaultDurationSetting">
186
+ <ion-select-option value="5">5 Minutes</ion-select-option>
187
+ <ion-select-option value="10">10 Minutes</ion-select-option>
188
+ <ion-select-option value="15">15 Minutes</ion-select-option>
189
+ </ion-select>
190
+ </ion-item>
191
+ <ion-item>
192
+ <ion-label>Video Quality</ion-label>
193
+ <ion-select value="720p" id="videoQualitySetting">
194
+ <ion-select-option value="720p">720p HD</ion-select-option>
195
+ <ion-select-option value="1080p">1080p Full HD</ion-select-option>
196
+ <ion-select-option value="4k">4K Ultra HD (Premium)</ion-select-option>
197
+ </ion-select>
198
+ </ion-item>
199
+ <ion-item>
200
+ <ion-label>Voiceover Language</ion-label>
201
+ <ion-select value="en-US" id="voiceoverLanguage">
202
+ <ion-select-option value="en-US">English (US)</ion-select-option>
203
+ <ion-select-option value="en-GB">English (UK)</ion-select-option>
204
+ <ion-select-option value="es-ES">Spanish</ion-select-option>
205
+ <ion-select-option value="fr-FR">French</ion-select-option>
206
+ </ion-select>
207
+ </ion-item>
208
+ <ion-item>
209
+ <ion-label>Output Format</ion-label>
210
+ <ion-select value="mp4" id="outputFormat">
211
+ <ion-select-option value="mp4">MP4 (Recommended)</ion-select-option>
212
+ <ion-select-option value="mov">MOV</ion-select-option>
213
+ <ion-select-option value="webm">WebM</ion-select-option>
214
+ </ion-select>
215
+ </ion-item>
216
+ </ion-list>
217
+ <div style="margin-top: 20px;">
218
+ <ion-button id="applySettingsButton" expand="block" color="success"><ion-icon slot="start" icon="checkmark"></ion-icon>Apply Settings</ion-button>
219
  </div>
220
+ <ion-text color="secondary"><p style="margin-top: 16px;">Demo settings only.</p></ion-text>
221
+ </ion-card-content>
222
+ </ion-card>
223
+
224
+ <ion-card id="help-section" class="ion-hide">
225
+ <ion-card-header>
226
+ <ion-card-title><ion-icon icon="help-circle" style="margin-right: 8px;"></ion-icon>Help & Support</ion-card-title>
227
+ <ion-card-subtitle>Guidance and resources</ion-card-subtitle>
228
+ </ion-card-header>
229
+ <ion-card-content>
230
+ <p>Welcome to Autotutorial.ai! Generate tutorials with ease.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  <p><strong>Getting Started:</strong></p>
232
+ <ol>
233
+ <li>Go to "Generate Tutorial" tab.</li>
234
+ <li>Enter your tutorial topic.</li>
235
+ <li>Select desired duration.</li>
236
+ <li>(Optional) Add API keys for enhanced features.</li>
237
+ <li>Tap "Generate Tutorial" to start.</li>
238
+ <li>Monitor "Status Updates" for progress.</li>
239
+ <li>Preview tutorial in "Tutorial Preview" section.</li>
240
  </ol>
241
+ <p><strong>Tutorial History:</strong></p>
242
+ <p>Access and manage past tutorials in "Tutorial History" (demo feature).</p>
243
  <p><strong>Settings:</strong></p>
244
+ <p>Customize default preferences in "Settings" (basic demo settings).</p>
245
+ <p>For further assistance, contact support at <a href="mailto:[email protected]">[email protected]</a>.</p>
246
+ </ion-card-content>
247
+ </ion-card>
248
+
249
+ </ion-content>
250
+
251
+ <ion-tabs>
252
+ <ion-tab-bar slot="bottom">
253
+ <ion-tab-button tab="generate" data-section="generate" class="tab-button-link active">
254
+ <ion-icon icon="magic"></ion-icon>
255
+ <ion-label>Generate</ion-label>
256
+ </ion-tab-button>
257
+ <ion-tab-button tab="history" data-section="history" class="tab-button-link">
258
+ <ion-icon icon="time"></ion-icon>
259
+ <ion-label>History</ion-label>
260
+ </ion-tab-button>
261
+ <ion-tab-button tab="settings" data-section="settings" class="tab-button-link">
262
+ <ion-icon icon="settings"></ion-icon>
263
+ <ion-label>Settings</ion-label>
264
+ </ion-tab-button>
265
+ <ion-tab-button tab="help" data-section="help" class="tab-button-link">
266
+ <ion-icon icon="help-circle"></ion-icon>
267
+ <ion-label>Help</ion-label>
268
+ </ion-tab-button>
269
+ </ion-tab-bar>
270
+ </ion-tabs>
271
+
272
+ </ion-app>
273
+
274
+ <!-- Ionic Scripts -->
275
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/ionic/ionic.esm.js"></script>
276
+ <script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/ionic/ionic.js"></script>
277
 
278
  <script>
279
  document.addEventListener('DOMContentLoaded', () => {
280
+ // Tab Navigation
281
+ const tabButtons = document.querySelectorAll('.tab-button-link');
282
+ const sections = ['generate-section', 'history-section', 'settings-section', 'help-section'];
283
 
284
  tabButtons.forEach(button => {
285
  button.addEventListener('click', function(event) {
286
  event.preventDefault();
287
+ const sectionId = this.getAttribute('data-section') + '-section';
288
 
289
  tabButtons.forEach(btn => btn.classList.remove('active'));
290
+ sections.forEach(sec => document.getElementById(sec).classList.add('ion-hide'));
291
 
292
  this.classList.add('active');
293
+ document.getElementById(sectionId).classList.remove('ion-hide');
294
+ if (sectionId === 'generate-section') {
295
+ document.getElementById('videoOutputSection').classList.add('ion-hide');
296
  document.getElementById('videoOutputSection').classList.remove('opacity-0');
297
  }
298
  });
299
  });
300
+ document.querySelector('.tab-button-link[data-section="generate"]').classList.add('active');
301
+ sections.filter(sec => sec !== 'generate-section').forEach(sec => document.getElementById(sec).classList.add('ion-hide'));
302
 
303
+
304
+ // Tutorial History Item Click Simulation
305
  const historyItems = document.querySelectorAll('.history-item');
306
  const videoTitleSpan = document.getElementById('videoTitle');
307
  const videoTitleOverlay = document.getElementById('videoTitleOverlay');
 
311
  const title = this.getAttribute('data-video-title');
312
  videoTitleSpan.textContent = title + " (Preview)";
313
  videoTitleOverlay.textContent = title;
314
+ videoOutputSection.classList.remove('ion-hide');
315
  videoOutputSection.classList.remove('opacity-0');
316
  const statusMessagesDiv = document.getElementById('statusMessages');
317
+ statusMessagesDiv.innerHTML = `<p class="ion-text-color-secondary"><ion-icon icon="video" color="primary" style="margin-right: 4px;"></ion-icon>Loading: ${title}</p>`;
318
  statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
319
  });
320
  });
321
 
322
+ // Apply Settings Button Simulation
323
  document.getElementById('applySettingsButton').addEventListener('click', function() {
324
  const statusMessagesDiv = document.getElementById('statusMessages');
325
+ statusMessagesDiv.innerHTML = `<p class="ion-text-color-success"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Settings Applied.</p>`;
326
  statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
327
  });
328
  });
329
 
330
 
331
  document.getElementById('generateButton').addEventListener('click', function() {
 
332
  const topic = document.getElementById('tutorialTopic').value;
333
  const duration = document.getElementById('desiredDuration').value;
334
  const openaiKey = document.getElementById('openaiApiKey').value;
 
345
 
346
  // Reset status and hide video output
347
  statusMessagesDiv.innerHTML = '';
348
+ errorMessageDiv.classList.add('ion-hide');
349
+ videoOutputSection.classList.add('ion-hide');
350
  videoOutputSection.classList.remove('opacity-0');
351
+ resetButton.classList.remove('ion-hide');
352
+ generateButton.classList.add('ion-hide'); // Hide generate, show reset
353
+ resetButton.classList.remove('ion-hide');
354
+ progressBar.value = 0;
 
 
 
355
 
356
 
357
  const steps = [
 
369
  function processStep() {
370
  if (currentStepIndex < steps.length) {
371
  simulateStep(statusMessagesDiv, steps[currentStepIndex].message, steps[currentStepIndex].delay, () => {
372
+ progressBar.value = ((currentStepIndex + 1) / steps.length);
373
  currentStepIndex++;
374
  processStep();
375
  }, true);
376
  } else {
377
+ progressBar.value = 1;
378
+ statusMessagesDiv.innerHTML = '<p class="ion-text-color-success"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Generation Complete!</p>';
 
 
 
379
 
380
  videoTitleSpan.textContent = topic + " (" + duration + "min Preview)";
381
  videoTitleOverlay.textContent = topic;
382
+ videoOutputSection.classList.remove('ion-hide');
383
  setTimeout(() => videoOutputSection.classList.remove('opacity-0'), 50);
384
+ generateButton.classList.remove('ion-hide'); // Show generate, hide reset
385
+ generateButton.classList.add('ion-hide');
386
+ resetButton.classList.remove('ion-hide');
387
  }
388
  }
389
  processStep();
 
392
  });
393
 
394
  document.getElementById('resetButton').addEventListener('click', function() {
 
395
  const statusMessagesDiv = document.getElementById('statusMessages');
396
  const errorMessageDiv = document.getElementById('errorMessage');
397
  const generateButton = document.getElementById('generateButton');
398
  const resetButton = document.getElementById('resetButton');
 
399
  const videoOutputSection = document.getElementById('videoOutputSection');
400
  const progressBar = document.getElementById('progressBar');
401
 
402
+ statusMessagesDiv.innerHTML = '<p class="ion-text-color-secondary"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Ready to generate. Click "Generate Tutorial".</p>';
403
+ errorMessageDiv.classList.add('ion-hide');
404
+ videoOutputSection.classList.add('ion-hide');
405
  videoOutputSection.classList.remove('opacity-0');
406
+ generateButton.classList.remove('ion-hide'); // Show generate, hide reset
407
+ generateButton.classList.remove('ion-hide');
408
+ resetButton.classList.add('ion-hide');
409
+ progressBar.value = 0;
 
 
 
 
 
410
  });
411
 
412
 
 
414
  setTimeout(function() {
415
  const messageElement = document.createElement('p');
416
  if (isSuccess) {
417
+ messageElement.classList.add('ion-text-color-secondary');
418
+ messageElement.innerHTML = `<ion-icon icon="radio-button-on" color="primary" style="margin-right: 4px;"></ion-icon> ${message}`;
419
  } else {
420
+ messageElement.classList.add('ion-text-color-danger');
421
+ messageElement.innerHTML = `<ion-icon icon="close-circle" color="danger" style="margin-right: 4px;"></ion-icon> ${message}`;
422
  document.getElementById('errorMessage').textContent = "Error generating tutorial. Check API keys.";
423
+ document.getElementById('errorMessage').classList.remove('ion-hide');
424
+ generateButton.classList.remove('ion-hide'); // Show generate, hide reset
425
+ generateButton.classList.add('ion-hide');
426
+ resetButton.classList.remove('ion-hide');
427
+ document.getElementById('progressBar').value = 0;
 
 
 
428
  }
429
  statusDiv.appendChild(messageElement);
430
  statusDiv.scrollTop = statusDiv.scrollHeight;