Skip to main content

Overview

The frontend is a single-page application built with React 18 and Vite, featuring real-time progress tracking through Server-Sent Events (SSE) and a responsive UI powered by TailwindCSS.

Tech Stack

React 18

Modern React with Hooks for component logic

Vite

Lightning-fast dev server and build tool

TailwindCSS

Utility-first styling with custom gradients

Axios

Promise-based HTTP client for API calls

Component Hierarchy

Key Components

App.jsx

Purpose: Root component managing application state and routing between views State Management:
const [view, setView] = useState('home'); // 'home' | 'preview'
const [generatedData, setGeneratedData] = useState(null);
Responsibilities:
  • Switch between Home (input form) and Preview (video player) views
  • Store generated presentation data
  • Pass callbacks to child components
Code Location: frontend/src/App.jsx

Home.jsx

Purpose: Input form for video generation with real-time progress tracking State Variables:
const [topic, setTopic] = useState("");
const [numSlides, setNumSlides] = useState(5);
const [language, setLanguage] = useState("english");
const [tone, setTone] = useState("formal");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [generationId, setGenerationId] = useState(null);
Key Features:
  • Topic: Text input with Enter key support
  • Number of Slides: Range 3-10
  • Language: Select (English, Hindi, Kannada, Telugu)
  • Tone: Select (Formal, Casual, Enthusiastic)
Uses useSSEProgress hook to display real-time generation status via StepProgress component
  1. Sanitize topic for ID generation
  2. Trigger SSE connection
  3. Call /api/generate endpoint
  4. Display progress
  5. On completion, call onGenerationComplete(data)
Code Location: frontend/src/components/Home.jsx:733-1060

StepProgress.jsx

Purpose: Visual progress tracker displaying pipeline stages Props:
{
  status: string,      // Current pipeline stage
  progress: number,    // 0-100 percentage
  message: string,     // Current status message
  isConnected: boolean // SSE connection status
}
Pipeline Steps:
const STEPS = [
  { id: 'started', label: 'Initializing', icon: '🚀' },
  { id: 'generating_content', label: 'Generating Content', icon: '📝' },
  { id: 'generating_scripts', label: 'Creating Scripts', icon: '📜' },
  { id: 'generating_audio', label: 'Generating Audio', icon: '🎤' },
  { id: 'combining_audio', label: 'Combining Audio', icon: '🎵' },
  { id: 'generating_media', label: 'Creating Visuals', icon: '🎨' },
  { id: 'generating_animation', label: 'Rendering Animation', icon: '🎬' },
  { id: 'fetching_image', label: 'Fetching Images', icon: '🖼️' },
  { id: 'generating_slide', label: 'Creating Slides', icon: '📄' },
  { id: 'composing_video', label: 'Composing Video', icon: '🎞️' },
  { id: 'completed', label: 'Complete', icon: '✅' },
];
Visual Features:
  • Color-coded step indicators (gray → blue → green)
  • Animated progress bar with gradient
  • Connection status indicator
  • Current message display
  • Completed/Active/Pending states
Code Location: frontend/src/components/StepProgress.jsx:1-241

VideoPlayer.jsx

Purpose: Video playback with slide timeline navigation Key Features:
  • HTML5 <video> element with custom controls
  • Timeline with slide markers
  • Slide navigation buttons
  • Current slide highlight
  • Video download option
Code Location: frontend/src/components/VideoPlayer.jsx

SlideEditor.jsx

Purpose: Slide-by-slide preview and editing interface Features:
  • Slide carousel navigation
  • Individual slide preview
  • Export to PowerPoint (via pptExport.js)
  • Slide metadata display
Code Location: frontend/src/components/SlideEditor.jsx

State Management

The application uses React Hooks for state management - no Redux or external state libraries needed due to simple data flow.

State Flow Pattern

Prop Drilling Pattern

// App.jsx passes callbacks down
<Home onGenerationComplete={(data) => {
  setGeneratedData(data);
  setView('preview');
}} />

// Home.jsx calls callback on success
if (response.data.status === "success") {
  onGenerationComplete({
    content: response.data.content_data,
    script: response.data.script_data,
    videoPath: response.data.video_path,
    videoFilename: response.data.video_filename,
    generationId: genId
  });
}

Custom Hooks

useSSEProgress

Purpose: Manage Server-Sent Events connection for real-time progress Location: frontend/src/hooks/useSSEProgress.jsx Usage:
const { 
  progress,      // Current progress (0-100)
  status,        // Pipeline stage ID
  message,       // Human-readable message
  logs,          // Array of log entries
  isConnected,   // Connection status
  clearLogs,     // Reset logs function
  disconnect     // Close SSE connection
} = useSSEProgress(generationId, autoConnect);
Implementation Details:
1

Connection Setup

Creates EventSource to /api/progress/{generationId} endpoint
2

Message Handling

Parses JSON data and updates state on each message
3

Duplicate Prevention

Checks last log message to avoid duplicate entries
4

Auto-disconnect

Closes connection on completed, error, or done status
5

Cleanup

Closes EventSource on component unmount
Key Code:
eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  setProgress(data.progress || 0);
  setStatus(data.status || 'processing');
  setMessage(data.message || '');
  
  // Add to logs (skip duplicates)
  setLogs((prev) => {
    const lastLog = prev[prev.length - 1];
    if (lastLog && lastLog.message === data.message) {
      return prev;
    }
    return [...prev, {
      timestamp: data.timestamp,
      message: data.message,
      progress: data.progress,
      status: data.status
    }];
  });
  
  // Close on completion
  if (data.status === 'completed' || data.status === 'error') {
    eventSource.close();
  }
};

API Integration

API Client: utils/api.js

Location: frontend/src/utils/api.js Configuration:
import axios from "axios";

const API_BASE_URL = "http://localhost:8000";

export const generateSlides = async ({
  topic, 
  slideCount, 
  contentStyle, 
  includeImages
}) => {
  const res = await axios.post(
    `${API_BASE_URL}/api/generate`,
    { topic, slideCount, contentStyle, includeImages },
    { 
      timeout: 60000,
      headers: { 'Content-Type': 'application/json' }
    }
  );
  
  if (!res.data || !res.data.slides) {
    throw new Error("Invalid response format");
  }
  
  return res.data.slides;
};
Error Handling:
  • Server errors: Display error message from response
  • Network errors: Show “backend not running” message
  • Timeout errors: 60-second timeout with clear feedback

Real-time Progress with SSE

Why SSE over WebSockets?

Advantages

  • Built-in browser API (EventSource)
  • Automatic reconnection
  • Simpler server implementation
  • One-way communication sufficient

Trade-offs

  • No bidirectional communication
  • Text-based only (JSON)
  • Limited browser support (IE)

SSE Flow Diagram

Styling Approach

TailwindCSS Utilities

Gradient Backgrounds:
<div className="bg-gradient-to-br from-purple-50 via-blue-50 to-indigo-100">
Responsive Grid:
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
Animations:
<div className="animate-pulse">Loading...</div>
<svg className="animate-spin h-5 w-5">...</svg>
Custom Theme: frontend/src/styles/theme.css

Performance Optimizations

Use React.memo for expensive renders (not currently needed due to simple structure)
SSE messages throttled to 0.5s intervals to prevent UI overload
Video player loads on-demand in preview view
Range request support allows video seeking without full download

Development Workflow

# Install dependencies
cd frontend
npm install

# Start dev server (with hot reload)
npm run dev
# → http://localhost:5173

# Build for production
npm run build

# Preview production build
npm run preview

Next Steps

Backend Architecture

Learn about FastAPI structure and generators

Pipeline Flow

Understand the complete generation process

Dependencies

Frontend dependencies and versions

Build docs developers (and LLMs) love