238 lines
7.2 KiB
JavaScript
238 lines
7.2 KiB
JavaScript
// State
|
|
let currentSlideIndex = 0;
|
|
let presentationSlides = [];
|
|
|
|
// Demo presentation data
|
|
const demoSlides = [
|
|
{
|
|
title: "AI Video Analytics — B2B Product",
|
|
bullets: ["Transforming video data into actionable business insights", "Powered by advanced computer vision and machine learning", "Built for enterprise-scale deployments"]
|
|
},
|
|
{
|
|
title: "Business Problem",
|
|
bullets: ["Organizations generate 1000s of hours of video footage daily", "Manual review is time-consuming and error-prone", "Critical insights remain hidden in unstructured data", "Security and operational teams lack real-time visibility"]
|
|
},
|
|
{
|
|
title: "Our Solution",
|
|
bullets: ["AI-powered video analytics platform", "Real-time object detection and behavior analysis", "Automated alerting and reporting", "Seamless integration with existing camera infrastructure"]
|
|
},
|
|
{
|
|
title: "How It Works",
|
|
bullets: ["Connect existing IP cameras to our platform", "AI models process video streams in real-time", "Detect anomalies, track objects, recognize patterns", "Dashboard provides instant insights and alerts"]
|
|
},
|
|
{
|
|
title: "Business Benefits",
|
|
bullets: ["Reduce manual monitoring costs by 70%", "Faster incident response time (from hours to seconds)", "Data-driven decision making", "Scalable from 10 to 10,000+ cameras"]
|
|
},
|
|
{
|
|
title: "Next Steps",
|
|
bullets: ["Schedule a live demo of the platform", "Discuss your specific use cases", "Pilot program: 30-day free trial", "ROI analysis for your organization"]
|
|
}
|
|
];
|
|
|
|
// Navigation
|
|
function navigateTo(page) {
|
|
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
|
|
document.querySelectorAll('.nav-link').forEach(l => l.classList.remove('active'));
|
|
|
|
document.getElementById('page-' + page).classList.add('active');
|
|
const navLink = document.querySelector('.nav-link[data-page="' + page + '"]');
|
|
if (navLink) navLink.classList.add('active');
|
|
|
|
window.scrollTo(0, 0);
|
|
}
|
|
|
|
// Form submission
|
|
document.getElementById('create-form').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const topic = document.getElementById('topic').value;
|
|
const audience = document.querySelector('input[name="audience"]:checked').value;
|
|
const style = document.querySelector('input[name="style"]:checked').value;
|
|
const slides = document.querySelector('input[name="slides"]:checked').value;
|
|
|
|
// Show loading
|
|
document.getElementById('loading').classList.add('active');
|
|
|
|
// Simulate AI generation (2 seconds)
|
|
setTimeout(function() {
|
|
document.getElementById('loading').classList.remove('active');
|
|
|
|
// Use demo slides (in real app, this would be AI-generated)
|
|
presentationSlides = demoSlides.slice(0, Math.min(slides, demoSlides.length));
|
|
currentSlideIndex = 0;
|
|
|
|
// Navigate to editor
|
|
navigateTo('editor');
|
|
renderEditor();
|
|
}, 1500);
|
|
});
|
|
|
|
// Render editor
|
|
function renderEditor() {
|
|
renderThumbnails();
|
|
renderSlidePreview();
|
|
updateSlideCounter();
|
|
}
|
|
|
|
// Render thumbnails
|
|
function renderThumbnails() {
|
|
const container = document.getElementById('slide-thumbnails');
|
|
container.innerHTML = presentationSlides.map(function(slide, index) {
|
|
return '<div class="thumbnail' + (index === currentSlideIndex ? ' active' : '') + '" onclick="goToSlide(' + index + ')">' +
|
|
'<div class="thumbnail-number">Slide ' + (index + 1) + '</div>' +
|
|
'<div class="thumbnail-title">' + escapeHtml(slide.title) + '</div>' +
|
|
'</div>';
|
|
}).join('');
|
|
}
|
|
|
|
// Render slide preview
|
|
function renderSlidePreview() {
|
|
const container = document.getElementById('slide-preview');
|
|
const slide = presentationSlides[currentSlideIndex];
|
|
|
|
container.innerHTML = '<div class="slide-content">' +
|
|
'<h2>' + escapeHtml(slide.title) + '</h2>' +
|
|
'<ul>' + slide.bullets.map(function(bullet) {
|
|
return '<li>' + escapeHtml(bullet) + '</li>';
|
|
}).join('') + '</ul>' +
|
|
'</div>';
|
|
}
|
|
|
|
// Update counter
|
|
function updateSlideCounter() {
|
|
document.getElementById('slide-counter').textContent = (currentSlideIndex + 1) + ' / ' + presentationSlides.length;
|
|
}
|
|
|
|
// Navigation
|
|
function goToSlide(index) {
|
|
if (index >= 0 && index < presentationSlides.length) {
|
|
currentSlideIndex = index;
|
|
renderThumbnails();
|
|
renderSlidePreview();
|
|
updateSlideCounter();
|
|
}
|
|
}
|
|
|
|
function prevSlide() {
|
|
goToSlide(currentSlideIndex - 1);
|
|
}
|
|
|
|
function nextSlide() {
|
|
goToSlide(currentSlideIndex + 1);
|
|
}
|
|
|
|
// Editor actions
|
|
function editSlide() {
|
|
const slide = presentationSlides[currentSlideIndex];
|
|
const newTitle = prompt('Edit slide title:', slide.title);
|
|
if (newTitle && newTitle.trim()) {
|
|
slide.title = newTitle.trim();
|
|
renderEditor();
|
|
}
|
|
}
|
|
|
|
function regenerateSlide() {
|
|
// Simulate regeneration
|
|
const loading = document.getElementById('loading');
|
|
loading.classList.add('active');
|
|
loading.querySelector('p').textContent = 'Regenerating slide...';
|
|
|
|
setTimeout(function() {
|
|
loading.classList.remove('active');
|
|
loading.querySelector('p').textContent = 'Generating your presentation...';
|
|
|
|
// For demo, just shuffle bullets slightly
|
|
const slide = presentationSlides[currentSlideIndex];
|
|
if (slide.bullets.length > 1) {
|
|
const temp = slide.bullets[0];
|
|
slide.bullets[0] = slide.bullets[1];
|
|
slide.bullets[1] = temp;
|
|
renderSlidePreview();
|
|
renderThumbnails();
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
function addSlide() {
|
|
const newSlide = {
|
|
title: 'New Slide',
|
|
bullets: ['Add your content here', 'Click Edit to modify']
|
|
};
|
|
presentationSlides.splice(currentSlideIndex + 1, 0, newSlide);
|
|
currentSlideIndex++;
|
|
renderEditor();
|
|
}
|
|
|
|
function deleteSlide() {
|
|
if (presentationSlides.length <= 1) {
|
|
alert('Cannot delete the last slide');
|
|
return;
|
|
}
|
|
|
|
if (confirm('Delete this slide?')) {
|
|
presentationSlides.splice(currentSlideIndex, 1);
|
|
if (currentSlideIndex >= presentationSlides.length) {
|
|
currentSlideIndex = presentationSlides.length - 1;
|
|
}
|
|
renderEditor();
|
|
}
|
|
}
|
|
|
|
// Download presentation
|
|
function downloadPresentation() {
|
|
if (!window.PptxGenJS) {
|
|
alert('PPTX library not loaded');
|
|
return;
|
|
}
|
|
|
|
const pptx = new PptxGenJS();
|
|
pptx.defineLayout({ name: 'W', width: 13.33, height: 7.5 });
|
|
pptx.layout = 'W';
|
|
|
|
presentationSlides.forEach(function(slide) {
|
|
const sl = pptx.addSlide();
|
|
sl.background = { color: 'FFFFFF' };
|
|
sl.addText(slide.title, {
|
|
x: 0.7,
|
|
y: 0.5,
|
|
w: 12,
|
|
h: 1.2,
|
|
fontSize: 32,
|
|
bold: true,
|
|
color: '1A1A1A'
|
|
});
|
|
|
|
if (slide.bullets && slide.bullets.length > 0) {
|
|
sl.addText(slide.bullets.map(function(bullet) {
|
|
return { text: bullet, options: { bullet: true, breakLine: true } };
|
|
}), {
|
|
x: 0.9,
|
|
y: 2.0,
|
|
w: 11.5,
|
|
h: 4.8,
|
|
fontSize: 18,
|
|
color: '495057',
|
|
lineSpacingMultiple: 1.4
|
|
});
|
|
}
|
|
});
|
|
|
|
pptx.writeFile({ fileName: 'AI-Presentation.pptx' });
|
|
}
|
|
|
|
// Utility
|
|
function escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
// Keyboard navigation
|
|
document.addEventListener('keydown', function(e) {
|
|
if (document.getElementById('page-editor').classList.contains('active')) {
|
|
if (e.key === 'ArrowRight') nextSlide();
|
|
if (e.key === 'ArrowLeft') prevSlide();
|
|
}
|
|
});
|