luigi12345 commited on
Commit
3ca1cd5
·
verified ·
1 Parent(s): a4cda04

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +403 -372
index.html CHANGED
@@ -3,435 +3,466 @@
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">
132
- Your browser does not support the video tag.
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');
308
- const videoOutputSection = document.getElementById('videoOutputSection');
309
- historyItems.forEach(item => {
310
- item.addEventListener('click', function() {
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;
335
- const videoGenKey = document.getElementById('videoGenApiKey').value;
336
- const statusMessagesDiv = document.getElementById('statusMessages');
337
- const errorMessageDiv = document.getElementById('errorMessage');
338
- const generateButton = document.getElementById('generateButton');
339
- const resetButton = document.getElementById('resetButton');
340
- const statusSection = document.getElementById('statusSection');
341
- const videoOutputSection = document.getElementById('videoOutputSection');
342
- const videoTitleSpan = document.getElementById('videoTitle');
343
- const videoTitleOverlay = document.getElementById('videoTitleOverlay');
344
- const progressBar = document.getElementById('progressBar');
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 = [
358
- { message: "Analyzing Topic...", delay: 800 },
359
- { message: "Generating Script...", delay: 1500 },
360
- { message: "Creating Voiceover...", delay: 2200 },
361
- { message: "Synthesizing Scenes...", delay: 2000 },
362
- { message: "Selecting Visuals...", delay: 1800 },
363
- { message: "Assembling Video...", delay: 2500 },
364
- { message: "Adding Effects...", delay: 1500 },
365
- { message: "Rendering Video...", delay: 3000 }
366
- ];
367
-
368
- let currentStepIndex = 0;
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();
390
 
 
 
 
 
391
 
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
 
413
- function simulateStep(statusDiv, message, delay, callback, isSuccess = true) {
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;
431
- if (callback) callback();
432
- }, delay + Math.random() * 500);
433
- }
434
- </script>
435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  </body>
437
  </html>
 
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</title>
7
+ <link rel="manifest" href="manifest.json"> <!-- Create this file for PWA -->
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@7/css/ionic.bundle.css">
13
 
14
+ <!-- Google Fonts (Inter) -->
 
 
 
15
  <link rel="preconnect" href="https://fonts.googleapis.com">
16
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
18
+ <style>
 
19
  :root {
20
  --ion-font-family: 'Inter', sans-serif;
21
+ /* Define app-specific colors (based on previous designs, refined)*/
22
+ --app-primary: #4f46e5; /* Indigo-600 from Tailwind/Radix */
23
+ --app-primary-rgb: 79,70,229;
24
+ --app-primary-contrast: #ffffff;
25
+ --app-primary-contrast-rgb: 255,255,255;
26
+ --app-primary-shade: #4640cc; /* Slightly darker shade */
27
+ --app-primary-tint: #615ce6; /* Slightly lighter tint */
28
+
29
+ --ion-color-primary: var(--app-primary);
30
+ --ion-color-primary-rgb: var(--app-primary-rgb);
31
+ --ion-color-primary-contrast: var(--app-primary-contrast);
32
+ --ion-color-primary-contrast-rgb: var(--app-primary-contrast-rgb);
33
+ --ion-color-primary-shade: var(--app-primary-shade);
34
+ --ion-color-primary-tint: var(--app-primary-tint);
35
  }
36
+
37
+ /* Global Style Tweaks */
38
  body {
39
  font-family: var(--ion-font-family);
40
+ -webkit-font-smoothing: antialiased;
41
+ -moz-osx-font-smoothing: grayscale;
42
  }
43
+
44
+ .video-preview-container {
45
+ border-radius: var(--ion-border-radius);
46
  overflow: hidden;
47
+ position: relative; /* For overlay */
48
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Subtle shadow */
49
  }
50
+
51
+ .video-title-overlay {
52
  position: absolute;
53
  bottom: 16px;
54
  left: 16px;
55
  color: white;
56
+ font-size: 1.2em;
57
  font-weight: 600;
58
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
 
 
 
 
 
 
 
59
  }
60
+ .hidden {
61
+ display: none !important;
62
  }
63
+
64
  </style>
65
  </head>
66
  <body>
 
67
  <ion-app>
68
+ <ion-header>
69
+ <ion-toolbar color="primary">
 
70
  <ion-title>Autotutorial.ai</ion-title>
71
+ <ion-buttons slot="end">
72
+ <ion-button id="helpButton">
73
+ <ion-icon slot="icon-only" name="help-circle"></ion-icon>
74
+ </ion-button>
75
+ </ion-buttons>
76
  </ion-toolbar>
77
  </ion-header>
78
 
79
+ <ion-content class="ion-padding">
80
+ <!-- Main Content: Generate Tutorial -->
81
+ <div id="generate-content">
82
+
83
+ <ion-card>
84
+ <ion-card-header>
85
+ <ion-card-title>Generate Tutorial</ion-card-title>
86
+ <ion-card-subtitle>Create a new video tutorial</ion-card-subtitle>
87
+ </ion-card-header>
88
+
89
+ <ion-card-content>
90
+ <ion-list lines="full">
91
+ <ion-item>
92
+ <ion-label position="floating">Tutorial Topic</ion-label>
93
+ <ion-input id="tutorialTopic" value="CSS Grid Layout"></ion-input>
94
+ </ion-item>
95
+ <ion-item>
96
+ <ion-label>Duration</ion-label>
97
+ <ion-select id="tutorialDuration" value="10">
98
+ <ion-select-option value="5">5 Minutes</ion-select-option>
99
+ <ion-select-option value="10">10 Minutes</ion-select-option>
100
+ <ion-select-option value="15">15 Minutes</ion-select-option>
101
+ <ion-select-option value="20">20 Minutes</ion-select-option>
102
+ </ion-select>
103
+ </ion-item>
104
+ <ion-item>
105
+ <ion-label position="floating">OpenAI API Key (Optional)</ion-label>
106
+ <ion-input id="openaiApiKey" type="text" placeholder="sk-..." value="sk-DEMO_OPENAI_KEY"></ion-input>
107
+ </ion-item>
108
+ <ion-item>
109
+ <ion-label position="floating">Video Gen. API Key (Optional)</ion-label>
110
+ <ion-input id="videoGenApiKey" type="text" placeholder="vg-..." value="vg-DEMO_VIDEO_KEY"></ion-input>
111
+ </ion-item>
112
+ </ion-list>
113
+
114
+ <ion-button id="generateButton" expand="block" color="primary" style="margin-top: 20px;">
115
+ <ion-icon slot="start" name="play-circle"></ion-icon>
116
+ Generate
117
+ </ion-button>
118
+ <ion-button id="resetButton" expand="block" color="medium" style="margin-top: 10px;" class="hidden">
119
+ <ion-icon slot="start" name="refresh"></ion-icon>
120
+ Reset
121
+ </ion-button>
122
+ </ion-card-content>
123
+ </ion-card>
124
+
125
+
126
+
127
+ <ion-card id="statusCard" class="hidden">
128
+ <ion-card-header>
129
+ <ion-card-title>Status</ion-card-title>
130
+ </ion-card-header>
131
+ <ion-card-content>
132
+ <ion-list id="statusList"></ion-list>
133
+ <ion-progress-bar id="progressBar" type="indeterminate"></ion-progress-bar> <!-- Changed to indeterminate -->
134
+ <ion-text color="danger" id="errorMessage" class="hidden"></ion-text>
135
+ </ion-card-content>
136
+ </ion-card>
137
+
138
+ <ion-card id="previewCard" class="hidden">
139
+ <ion-card-header>
140
+ <ion-card-title>Tutorial Preview</ion-card-title>
141
+ </ion-card-header>
142
+ <ion-card-content>
143
+ <div class="video-preview-container">
144
+ <video id="tutorialVideo" controls width="100%" preload="metadata">
145
+ <source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4"> <!-- Better demo video -->
146
+ Your browser does not support the video tag.
147
+ </video>
148
+ <div id="videoTitleOverlay" class="video-title-overlay"></div>
149
  </div>
150
+ <ion-button expand="block" id="downloadButton" style="margin-top: 16px;">
151
+ <ion-icon slot="start" name="download"></ion-icon>
152
+ Download (Demo)
153
+ </ion-button>
154
+ </ion-card-content>
155
+ </ion-card>
156
+ </div>
157
+
158
+
159
+ <!-- Tutorial History (Initially Hidden) -->
160
+ <div id="history-content" class="hidden">
161
+ <ion-card>
162
+ <ion-card-header>
163
+ <ion-card-title>Tutorial History</ion-card-title>
164
+ <ion-card-subtitle>View your past tutorials</ion-card-subtitle>
165
+ </ion-card-header>
166
+ <ion-card-content>
167
+ <ion-list id="historyList">
168
+ <ion-item button class="history-item" data-title="React Hooks Guide">
169
+ <ion-label>React Hooks Guide</ion-label>
170
+ <ion-note slot="end">Oct 28, 2023</ion-note> <!-- Use ion-note for date -->
171
+ </ion-item>
172
+ <ion-item button class="history-item" data-title="Vue.js Composition API">
173
+ <ion-label>Vue.js Composition API</ion-label>
174
+ <ion-note slot="end">Oct 27, 2023</ion-note>
175
+ </ion-item>
176
+ <ion-item button class="history-item" data-title="Python for Data Science">
177
+ <ion-label>Python for Data Science</ion-label>
178
+ <ion-note slot="end">Oct 26, 2023</ion-note>
179
+ </ion-item>
180
+ </ion-list>
181
+ <ion-text color="medium">
182
+ <p>This is a simulated history for demo purposes.</p>
183
+ </ion-text>
184
+ </ion-card-content>
185
+ </ion-card>
186
+ </div>
187
+
188
+ <!-- Settings (Initially Hidden) -->
189
+ <div id="settings-content" class="hidden">
190
+ <ion-card>
191
+ <ion-card-header>
192
+ <ion-card-title>Settings</ion-card-title>
193
+ <ion-card-subtitle>Configure app preferences</ion-card-subtitle>
194
+ </ion-card-header>
195
+ <ion-card-content>
196
+ <ion-list lines="full">
197
+ <ion-item>
198
+ <ion-label>Default Duration</ion-label>
199
+ <ion-select id="defaultDuration" value="10">
200
+ <ion-select-option value="5">5 Minutes</ion-select-option>
201
+ <ion-select-option value="10">10 Minutes</ion-select-option>
202
+ <ion-select-option value="15">15 Minutes</ion-select-option>
203
+ <ion-select-option value="20">20 Minutes</ion-select-option>
204
+ </ion-select>
205
+ </ion-item>
206
+ <ion-item>
207
+ <ion-label>Default Quality</ion-label>
208
+ <ion-select id="defaultQuality" value="720p">
209
+ <ion-select-option value="720p">720p</ion-select-option>
210
+ <ion-select-option value="1080p">1080p</ion-select-option>
211
+ <ion-select-option value="4k">4K (Premium)</ion-select-option>
212
+ </ion-select>
213
+ </ion-item>
214
+ <ion-item>
215
+ <ion-label>Voiceover Language</ion-label>
216
+ <ion-select id="defaultVoiceover" value="en-US">
217
+ <ion-select-option value="en-US">English (US)</ion-select-option>
218
+ <ion-select-option value="en-GB">English (UK)</ion-select-option>
219
+ <ion-select-option value="es-ES">Spanish (ES)</ion-select-option>
220
+ </ion-select>
221
+ </ion-item>
222
+ <ion-item>
223
+ <ion-label>Output Format</ion-label>
224
+ <ion-select id="defaultOutput" value="mp4">
225
+ <ion-select-option value="mp4">MP4</ion-select-option>
226
+ <ion-select-option value="mov">MOV</ion-select-option>
227
+ <ion-select-option value="webm">WebM</ion-select-option>
228
+ </ion-select>
229
+ </ion-item>
230
+ </ion-list>
231
+ <ion-button id="applySettingsButton" expand="block" style="margin-top: 20px;">
232
+ <ion-icon slot="start" name="save"></ion-icon>
233
+ Apply Settings
234
+ </ion-button>
235
+ </ion-card-content>
236
+ </ion-card>
237
+ </div>
238
+
239
+ <!-- Help Modal (Initially Hidden) -->
240
+ <ion-modal id="helpModal" trigger="helpButton">
241
+ <ion-header>
242
+ <ion-toolbar>
243
+ <ion-title>Help & Support</ion-title>
244
+ <ion-buttons slot="end">
245
+ <ion-button onclick="closeHelpModal()">
246
+ <ion-icon slot="icon-only" name="close"></ion-icon>
247
+ </ion-button>
248
+ </ion-buttons>
249
+ </ion-toolbar>
250
+ </ion-header>
251
+ <ion-content class="ion-padding">
252
+ <p>Welcome to Autotutorial.ai, the app that makes creating video tutorials a breeze!</p>
253
+ <p><strong>Getting Started:</strong></p>
254
+ <ol>
255
+ <li>Navigate to the <strong>Generate Tutorial</strong> section.</li>
256
+ <li>Enter the topic of your tutorial in the <strong>Tutorial Topic</strong> field.</li>
257
+ <li>Select your desired tutorial length using the <strong>Duration</strong> dropdown.</li>
258
+ <li><em>(Optional)</em> If you have API keys for OpenAI and a video generation service, you can enter them in the respective fields for enhanced tutorial creation. This is not required for basic functionality.</li>
259
+ <li>Click the <strong>Generate</strong> button to start the automated tutorial creation process.</li>
260
+ <li>Monitor the <strong>Status</strong> section to see the progress of your tutorial generation.</li>
261
+ <li>Once complete, preview your generated tutorial in the <strong>Tutorial Preview</strong> section.</li>
262
+ </ol>
263
+ <p><strong>Tutorial History</strong> allows you to view a list of your previously generated tutorials (simulated in this demo).</p>
264
+ <p><strong>Settings</strong> let you configure default preferences for new tutorials (also simulated in this demo).</p>
265
+ <p>For any questions or support, please contact us at: <a href="mailto:[email protected]">[email protected]</a></p>
266
+ </ion-content>
267
+ </ion-modal>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
269
  </ion-content>
270
 
271
+ <ion-footer>
272
+ <ion-toolbar>
273
+ <ion-tabs>
274
+ <ion-tab-bar slot="bottom">
275
+ <ion-tab-button tab="generate" onclick="showSection('generate')">
276
+ <ion-icon name="play-circle"></ion-icon>
277
+ <ion-label>Generate</ion-label>
278
+ </ion-tab-button>
279
+ <ion-tab-button tab="history" onclick="showSection('history')">
280
+ <ion-icon name="time"></ion-icon>
281
+ <ion-label>History</ion-label>
282
+ </ion-tab-button>
283
+ <ion-tab-button tab="settings" onclick="showSection('settings')">
284
+ <ion-icon name="settings"></ion-icon>
285
+ <ion-label>Settings</ion-label>
286
+ </ion-tab-button>
287
+ </ion-tab-bar>
288
+ </ion-tabs>
289
+ </ion-toolbar>
290
+ </ion-footer>
291
 
292
  </ion-app>
293
 
294
+ <!-- Ionic JavaScript -->
295
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/ionic.esm.js"></script>
296
+ <script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/ionic.js"></script>
297
 
298
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
 
300
+ function showSection(sectionId) {
301
+ // Hide all content sections
302
+ document.getElementById('generate-content').classList.add('hidden');
303
+ document.getElementById('history-content').classList.add('hidden');
304
+ document.getElementById('settings-content').classList.add('hidden');
305
 
306
+ // Remove active class from all tab buttons. Important for visual state.
307
+ document.querySelectorAll('ion-tab-button').forEach(btn => btn.classList.remove('tab-selected'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
 
 
 
 
 
 
 
309
 
310
+ // Show the selected section
311
+ document.getElementById(`${sectionId}-content`).classList.remove('hidden');
312
 
313
+ // Highlight active tab button
314
+ document.querySelector(`ion-tab-button[tab="${sectionId}"]`).classList.add('tab-selected');
 
 
 
 
 
 
 
 
 
 
 
 
315
 
316
+ // Hide preview and status cards when switching tabs *away* from generate
317
+ if (sectionId !== 'generate') {
318
+ document.getElementById('previewCard').classList.add('hidden');
319
+ document.getElementById('statusCard').classList.add('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
+ }
322
 
323
+ function closeHelpModal() {
324
+ const modal = document.getElementById('helpModal');
325
+ modal.dismiss();
326
+ }
327
 
 
328
 
329
+ document.addEventListener('DOMContentLoaded', () => {
 
 
330
  const generateButton = document.getElementById('generateButton');
331
  const resetButton = document.getElementById('resetButton');
332
+ const statusCard = document.getElementById('statusCard');
333
+ const statusList = document.getElementById('statusList');
334
  const progressBar = document.getElementById('progressBar');
335
+ const previewCard = document.getElementById('previewCard');
336
+ const videoTitleOverlay = document.getElementById('videoTitleOverlay');
337
+ const tutorialVideo = document.getElementById('tutorialVideo');
338
+ const errorMessage = document.getElementById('errorMessage');
339
+
340
+ // History click handler (simulated "load")
341
+ const historyList = document.getElementById('historyList');
342
+ historyList.addEventListener('click', (event) => {
343
+ const item = event.target.closest('.history-item'); // Find closest item
344
+ if (item) {
345
+ const title = item.dataset.title;
346
+ videoTitleOverlay.textContent = title;
347
+ previewCard.classList.remove('hidden'); // Show preview card
348
+ // You could simulate loading different videos here if you have multiple sources
349
+ // tutorialVideo.src = 'another_video.mp4';
350
+ // tutorialVideo.load();
351
+ statusCard.classList.remove('hidden'); // Show status
352
+ statusList.innerHTML = `<ion-item><ion-label color="primary">Loading ${title}...</ion-label></ion-item>`; // Show loading message
353
+
354
+ }
355
 
356
+ });
357
+
358
+ // Apply Settings simulation
359
+ document.getElementById('applySettingsButton').addEventListener('click', () => {
360
+ // Simulate setting changes (could visually update UI elements if desired)
361
+ statusCard.classList.remove('hidden');
362
+ statusList.innerHTML = `<ion-item><ion-label color="success">Settings applied!</ion-label></ion-item>`;
363
+ });
 
364
 
365
 
366
+ // Generate Button Click Handler
367
+ generateButton.addEventListener('click', () => {
368
+ const topic = document.getElementById('tutorialTopic').value;
369
+ const duration = document.getElementById('tutorialDuration').value;
370
+ const openaiKey = document.getElementById('openaiApiKey').value;
371
+ const videoGenKey = document.getElementById('videoGenApiKey').value;
372
+
373
+ // Clear previous status and error messages
374
+ statusList.innerHTML = '';
375
+ errorMessage.textContent = '';
376
+ errorMessage.classList.add('hidden');
377
+
378
+ // Show status and progress bar
379
+ statusCard.classList.remove('hidden');
380
+ progressBar.type = 'indeterminate'; // Start indeterminate
381
+
382
+ // Hide preview card (until generation is complete)
383
+ previewCard.classList.add('hidden');
384
+
385
+ // Hide Generate, show Reset
386
+ generateButton.classList.add('hidden');
387
+ resetButton.classList.remove('hidden');
388
+
389
+ const steps = [
390
+ { message: "Analyzing Topic...", delay: 800 },
391
+ { message: "Generating Script Outline (AI)...", delay: 1500 },
392
+ { message: "Writing Script Content (AI)...", delay: 2200 },
393
+ { message: "Synthesizing Voiceover (AI)...", delay: 1800 },
394
+ { message: "Selecting Relevant Visuals...", delay: 1600 },
395
+ { message: "Assembling Video Scenes...", delay: 2400 },
396
+ { message: "Adding Transitions and Effects...", delay: 1500 },
397
+ { message: "Rendering Final Video...", delay: 3000 }
398
+ ];
399
+
400
+ let currentStep = 0;
401
+
402
+ function simulateStep() {
403
+ if (currentStep < steps.length) {
404
+ const listItem = document.createElement('ion-item');
405
+ listItem.innerHTML = `<ion-label>${steps[currentStep].message}</ion-label>`;
406
+ statusList.appendChild(listItem);
407
+
408
+ // Simulate varying delays
409
+ const delay = steps[currentStep].delay + (Math.random() * 500 - 250); // +/- 250ms variation
410
+
411
+ setTimeout(() => {
412
+ currentStep++;
413
+ simulateStep();
414
+ }, delay);
415
+
416
+ } else {
417
+ // Generation "complete"
418
+ progressBar.type = 'determinate'; // Switch to determinate for final "fill"
419
+ progressBar.value = 1; // Set to 100%
420
+
421
+ statusList.innerHTML = `<ion-item><ion-label color="success">Tutorial generation complete!</ion-label></ion-item>`;
422
+
423
+ videoTitleOverlay.textContent = `${topic} (${duration} min)`;
424
+ previewCard.classList.remove('hidden');
425
+
426
+ // Show generate, hide reset
427
+ generateButton.classList.remove('hidden');
428
+ resetButton.classList.add('hidden');
429
+ }
430
  }
 
 
 
 
 
 
431
 
432
+ simulateStep();
433
+ });
434
+
435
+ // Reset Button Click Handler
436
+ resetButton.addEventListener('click', () => {
437
+ // Clear form fields
438
+ document.getElementById('tutorialTopic').value = '';
439
+ document.getElementById('tutorialDuration').value = '10';
440
+ document.getElementById('openaiApiKey').value = '';
441
+ document.getElementById('videoGenApiKey').value = '';
442
+
443
+ // Hide status, error, and preview cards
444
+ statusCard.classList.add('hidden');
445
+ errorMessage.classList.add('hidden');
446
+ previewCard.classList.add('hidden');
447
+
448
+ // Clear status list
449
+ statusList.innerHTML = '';
450
+
451
+ // Reset progress bar
452
+ progressBar.value = 0;
453
+ progressBar.type = 'indeterminate';
454
+
455
+ // Show Generate, hide Reset
456
+ generateButton.classList.remove('hidden');
457
+ resetButton.classList.add('hidden');
458
+ });
459
+
460
+ document.getElementById('downloadButton').addEventListener('click', () => {
461
+ // Simulate download
462
+ statusCard.classList.remove('hidden');
463
+ statusList.innerHTML = `<ion-item><ion-label color="primary">Downloading (simulated)...</ion-label></ion-item>`;
464
+ });
465
+ });
466
+ </script>
467
  </body>
468
  </html>