Autotutorial / index.html
Luigi
Update index.html
a4cda04 verified
raw
history blame
24.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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">
<title>Autotutorial.ai - Ionic Demo</title>
<link rel="manifest" href="manifest.json">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- Ionic CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@latest/css/ionic.bundle.css">
<!-- Font Awesome CDN -->
<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" />
<!-- Inter Font from Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--ion-font-family: 'Inter', sans-serif;
}
body {
font-family: var(--ion-font-family);
}
.video-player-container {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
position: relative; /* For video overlay */
}
.video-overlay-title {
position: absolute;
bottom: 16px;
left: 16px;
color: white;
font-size: 1.5em;
font-weight: 600;
text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
}
.status-box {
border-radius: 8px;
border: 1px solid var(--ion-color-light);
background-color: var(--ion-color-light-contrast);
padding: 16px;
margin-bottom: 16px;
}
.status-progress-bar {
margin-top: 8px;
}
</style>
</head>
<body>
<ion-app>
<ion-header translucent="true">
<ion-toolbar>
<ion-title>Autotutorial.ai</ion-title>
</ion-toolbar>
</ion-header>
<ion-content fullscreen="true">
<ion-card>
<ion-card-header>
<ion-card-title>Generate Tutorial</ion-card-title>
<ion-card-subtitle>Create a new video tutorial</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-list lines="full">
<ion-item>
<ion-label position="floating">Tutorial Topic</ion-label>
<ion-input type="text" id="tutorialTopic" value="React State Management Best Practices"></ion-input>
</ion-item>
<ion-item>
<ion-label>Desired Duration</ion-label>
<ion-select value="10" id="desiredDuration">
<ion-select-option value="5">5 Minutes</ion-select-option>
<ion-select-option value="10">10 Minutes</ion-select-option>
<ion-select-option value="15">15 Minutes</ion-select-option>
<ion-select-option value="20">20 Minutes</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label position="floating">OpenAI API Key (Optional)</ion-label>
<ion-input type="text" id="openaiApiKey" value="sk-DEMO_OPENAI_KEY" placeholder="For enhanced script generation"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Video Generation API Key (Optional)</ion-label>
<ion-input type="text" id="videoGenApiKey" value="vg-DEMO_VIDEO_GEN_KEY" placeholder="For advanced video synthesis"></ion-input>
</ion-item>
</ion-list>
<div style="margin-top: 20px; display: flex; gap: 10px;">
<ion-button id="generateButton" expand="block"><ion-icon slot="start" icon="magic"></ion-icon>Generate Tutorial</ion-button>
<ion-button id="resetButton" expand="block" color="secondary" class="ion-hide"><ion-icon slot="start" icon="refresh"></ion-icon>Reset</ion-button>
</div>
</ion-card-content>
</ion-card>
<ion-card id="statusSection" class="status-box">
<ion-card-header>
<ion-card-title><ion-icon icon="information-circle" style="margin-right: 8px;"></ion-icon>Status Updates</ion-card-title>
</ion-card-header>
<ion-card-content>
<div id="statusMessages">
<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>
</div>
<p id="errorMessage" class="ion-text-color-danger ion-hide" style="margin-top: 8px;"></p>
<ion-progress-bar value="0" buffer="0" reversed="false" class="status-progress-bar" id="progressBar"></ion-progress-bar>
</ion-card-content>
</ion-card>
<ion-card id="videoOutputSection" class="ion-hide">
<ion-card-header>
<ion-card-title><ion-icon icon="film" style="margin-right: 8px;"></ion-icon>Tutorial Preview</ion-card-title>
</ion-card-header>
<ion-card-content>
<div class="video-player-container">
<video id="tutorialVideo" controls width="100%">
<source src="https://joy.videvo.net/videvo_files/video/free/2016-06/small_watermarked/Drone_Flying_Above_City_Skyline_preview.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div id="videoTitleOverlay" class="video-overlay-title"></div>
</div>
<div style="margin-top: 16px; display: flex; justify-content: space-between; align-items: center;">
<div>
<p><strong id="videoTitle"></strong></p>
<ion-text color="secondary"><p>Generated tutorial preview</p></ion-text>
</div>
<ion-button id="downloadButton" download="tutorial.mp4"><ion-icon slot="start" icon="download"></ion-icon>Download</ion-button>
</div>
</ion-card-content>
</ion-card>
<ion-card id="history-section" class="ion-hide">
<ion-card-header>
<ion-card-title><ion-icon icon="time" style="margin-right: 8px;"></ion-icon>Tutorial History</ion-card-title>
<ion-card-subtitle>Access past tutorials</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-list id="historyList">
<ion-item button class="history-item" data-video-title="Mastering JavaScript Promises">
<ion-label>
<h3>Mastering JavaScript Promises</h3>
<p>Generated: Oct 26, 2023</p>
</ion-label>
</ion-item>
<ion-item button class="history-item" data-video-title="Introduction to Python for Data Science">
<ion-label>
<h3>Introduction to Python for Data Science</h3>
<p>Generated: Oct 25, 2023</p>
</ion-label>
</ion-item>
<ion-item button class="history-item" data-video-title="Building a REST API with Express.js">
<ion-label>
<h3>Building a REST API with Express.js</h3>
<p>Generated: Oct 20, 2023</p>
</ion-label>
</ion-item>
</ion-list>
<ion-text color="secondary"><p style="margin-top: 16px;">Demo history is simulated.</p></ion-text>
</ion-card-content>
</ion-card>
<ion-card id="settings-section" class="ion-hide">
<ion-card-header>
<ion-card-title><ion-icon icon="settings" style="margin-right: 8px;"></ion-icon>Settings</ion-card-title>
<ion-card-subtitle>Customize preferences</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-list lines="full">
<ion-item>
<ion-label>Default Duration</ion-label>
<ion-select value="10" id="defaultDurationSetting">
<ion-select-option value="5">5 Minutes</ion-select-option>
<ion-select-option value="10">10 Minutes</ion-select-option>
<ion-select-option value="15">15 Minutes</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Video Quality</ion-label>
<ion-select value="720p" id="videoQualitySetting">
<ion-select-option value="720p">720p HD</ion-select-option>
<ion-select-option value="1080p">1080p Full HD</ion-select-option>
<ion-select-option value="4k">4K Ultra HD (Premium)</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Voiceover Language</ion-label>
<ion-select value="en-US" id="voiceoverLanguage">
<ion-select-option value="en-US">English (US)</ion-select-option>
<ion-select-option value="en-GB">English (UK)</ion-select-option>
<ion-select-option value="es-ES">Spanish</ion-select-option>
<ion-select-option value="fr-FR">French</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Output Format</ion-label>
<ion-select value="mp4" id="outputFormat">
<ion-select-option value="mp4">MP4 (Recommended)</ion-select-option>
<ion-select-option value="mov">MOV</ion-select-option>
<ion-select-option value="webm">WebM</ion-select-option>
</ion-select>
</ion-item>
</ion-list>
<div style="margin-top: 20px;">
<ion-button id="applySettingsButton" expand="block" color="success"><ion-icon slot="start" icon="checkmark"></ion-icon>Apply Settings</ion-button>
</div>
<ion-text color="secondary"><p style="margin-top: 16px;">Demo settings only.</p></ion-text>
</ion-card-content>
</ion-card>
<ion-card id="help-section" class="ion-hide">
<ion-card-header>
<ion-card-title><ion-icon icon="help-circle" style="margin-right: 8px;"></ion-icon>Help & Support</ion-card-title>
<ion-card-subtitle>Guidance and resources</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<p>Welcome to Autotutorial.ai! Generate tutorials with ease.</p>
<p><strong>Getting Started:</strong></p>
<ol>
<li>Go to "Generate Tutorial" tab.</li>
<li>Enter your tutorial topic.</li>
<li>Select desired duration.</li>
<li>(Optional) Add API keys for enhanced features.</li>
<li>Tap "Generate Tutorial" to start.</li>
<li>Monitor "Status Updates" for progress.</li>
<li>Preview tutorial in "Tutorial Preview" section.</li>
</ol>
<p><strong>Tutorial History:</strong></p>
<p>Access and manage past tutorials in "Tutorial History" (demo feature).</p>
<p><strong>Settings:</strong></p>
<p>Customize default preferences in "Settings" (basic demo settings).</p>
<p>For further assistance, contact support at <a href="mailto:[email protected]">[email protected]</a>.</p>
</ion-card-content>
</ion-card>
</ion-content>
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="generate" data-section="generate" class="tab-button-link active">
<ion-icon icon="magic"></ion-icon>
<ion-label>Generate</ion-label>
</ion-tab-button>
<ion-tab-button tab="history" data-section="history" class="tab-button-link">
<ion-icon icon="time"></ion-icon>
<ion-label>History</ion-label>
</ion-tab-button>
<ion-tab-button tab="settings" data-section="settings" class="tab-button-link">
<ion-icon icon="settings"></ion-icon>
<ion-label>Settings</ion-label>
</ion-tab-button>
<ion-tab-button tab="help" data-section="help" class="tab-button-link">
<ion-icon icon="help-circle"></ion-icon>
<ion-label>Help</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
</ion-app>
<!-- Ionic Scripts -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/ionic/ionic.esm.js"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@latest/dist/ionic/ionic.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Tab Navigation
const tabButtons = document.querySelectorAll('.tab-button-link');
const sections = ['generate-section', 'history-section', 'settings-section', 'help-section'];
tabButtons.forEach(button => {
button.addEventListener('click', function(event) {
event.preventDefault();
const sectionId = this.getAttribute('data-section') + '-section';
tabButtons.forEach(btn => btn.classList.remove('active'));
sections.forEach(sec => document.getElementById(sec).classList.add('ion-hide'));
this.classList.add('active');
document.getElementById(sectionId).classList.remove('ion-hide');
if (sectionId === 'generate-section') {
document.getElementById('videoOutputSection').classList.add('ion-hide');
document.getElementById('videoOutputSection').classList.remove('opacity-0');
}
});
});
document.querySelector('.tab-button-link[data-section="generate"]').classList.add('active');
sections.filter(sec => sec !== 'generate-section').forEach(sec => document.getElementById(sec).classList.add('ion-hide'));
// Tutorial History Item Click Simulation
const historyItems = document.querySelectorAll('.history-item');
const videoTitleSpan = document.getElementById('videoTitle');
const videoTitleOverlay = document.getElementById('videoTitleOverlay');
const videoOutputSection = document.getElementById('videoOutputSection');
historyItems.forEach(item => {
item.addEventListener('click', function() {
const title = this.getAttribute('data-video-title');
videoTitleSpan.textContent = title + " (Preview)";
videoTitleOverlay.textContent = title;
videoOutputSection.classList.remove('ion-hide');
videoOutputSection.classList.remove('opacity-0');
const statusMessagesDiv = document.getElementById('statusMessages');
statusMessagesDiv.innerHTML = `<p class="ion-text-color-secondary"><ion-icon icon="video" color="primary" style="margin-right: 4px;"></ion-icon>Loading: ${title}</p>`;
statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
});
});
// Apply Settings Button Simulation
document.getElementById('applySettingsButton').addEventListener('click', function() {
const statusMessagesDiv = document.getElementById('statusMessages');
statusMessagesDiv.innerHTML = `<p class="ion-text-color-success"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Settings Applied.</p>`;
statusMessagesDiv.scrollTop = statusMessagesDiv.scrollHeight;
});
});
document.getElementById('generateButton').addEventListener('click', function() {
const topic = document.getElementById('tutorialTopic').value;
const duration = document.getElementById('desiredDuration').value;
const openaiKey = document.getElementById('openaiApiKey').value;
const videoGenKey = document.getElementById('videoGenApiKey').value;
const statusMessagesDiv = document.getElementById('statusMessages');
const errorMessageDiv = document.getElementById('errorMessage');
const generateButton = document.getElementById('generateButton');
const resetButton = document.getElementById('resetButton');
const statusSection = document.getElementById('statusSection');
const videoOutputSection = document.getElementById('videoOutputSection');
const videoTitleSpan = document.getElementById('videoTitle');
const videoTitleOverlay = document.getElementById('videoTitleOverlay');
const progressBar = document.getElementById('progressBar');
// Reset status and hide video output
statusMessagesDiv.innerHTML = '';
errorMessageDiv.classList.add('ion-hide');
videoOutputSection.classList.add('ion-hide');
videoOutputSection.classList.remove('opacity-0');
resetButton.classList.remove('ion-hide');
generateButton.classList.add('ion-hide'); // Hide generate, show reset
resetButton.classList.remove('ion-hide');
progressBar.value = 0;
const steps = [
{ message: "Analyzing Topic...", delay: 800 },
{ message: "Generating Script...", delay: 1500 },
{ message: "Creating Voiceover...", delay: 2200 },
{ message: "Synthesizing Scenes...", delay: 2000 },
{ message: "Selecting Visuals...", delay: 1800 },
{ message: "Assembling Video...", delay: 2500 },
{ message: "Adding Effects...", delay: 1500 },
{ message: "Rendering Video...", delay: 3000 }
];
let currentStepIndex = 0;
function processStep() {
if (currentStepIndex < steps.length) {
simulateStep(statusMessagesDiv, steps[currentStepIndex].message, steps[currentStepIndex].delay, () => {
progressBar.value = ((currentStepIndex + 1) / steps.length);
currentStepIndex++;
processStep();
}, true);
} else {
progressBar.value = 1;
statusMessagesDiv.innerHTML = '<p class="ion-text-color-success"><ion-icon icon="checkmark-circle" color="success" style="margin-right: 4px;"></ion-icon>Generation Complete!</p>';
videoTitleSpan.textContent = topic + " (" + duration + "min Preview)";
videoTitleOverlay.textContent = topic;
videoOutputSection.classList.remove('ion-hide');
setTimeout(() => videoOutputSection.classList.remove('opacity-0'), 50);
generateButton.classList.remove('ion-hide'); // Show generate, hide reset
generateButton.classList.add('ion-hide');
resetButton.classList.remove('ion-hide');
}
}
processStep();
});
document.getElementById('resetButton').addEventListener('click', function() {
const statusMessagesDiv = document.getElementById('statusMessages');
const errorMessageDiv = document.getElementById('errorMessage');
const generateButton = document.getElementById('generateButton');
const resetButton = document.getElementById('resetButton');
const videoOutputSection = document.getElementById('videoOutputSection');
const progressBar = document.getElementById('progressBar');
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>';
errorMessageDiv.classList.add('ion-hide');
videoOutputSection.classList.add('ion-hide');
videoOutputSection.classList.remove('opacity-0');
generateButton.classList.remove('ion-hide'); // Show generate, hide reset
generateButton.classList.remove('ion-hide');
resetButton.classList.add('ion-hide');
progressBar.value = 0;
});
function simulateStep(statusDiv, message, delay, callback, isSuccess = true) {
setTimeout(function() {
const messageElement = document.createElement('p');
if (isSuccess) {
messageElement.classList.add('ion-text-color-secondary');
messageElement.innerHTML = `<ion-icon icon="radio-button-on" color="primary" style="margin-right: 4px;"></ion-icon> ${message}`;
} else {
messageElement.classList.add('ion-text-color-danger');
messageElement.innerHTML = `<ion-icon icon="close-circle" color="danger" style="margin-right: 4px;"></ion-icon> ${message}`;
document.getElementById('errorMessage').textContent = "Error generating tutorial. Check API keys.";
document.getElementById('errorMessage').classList.remove('ion-hide');
generateButton.classList.remove('ion-hide'); // Show generate, hide reset
generateButton.classList.add('ion-hide');
resetButton.classList.remove('ion-hide');
document.getElementById('progressBar').value = 0;
}
statusDiv.appendChild(messageElement);
statusDiv.scrollTop = statusDiv.scrollHeight;
if (callback) callback();
}, delay + Math.random() * 500);
}
</script>
</body>
</html>