LearningApplication / index.html
parthib07's picture
Update index.html
88c4fa8 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EduLoom - Modern AI-Ready Learning Platform</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.14.1/cdn.min.js" defer></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.glass-effect {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.gradient-text {
background: linear-gradient(45deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hover-scale {
transition: transform 0.3s ease;
}
.hover-scale:hover {
transform: translateY(-5px) scale(1.02);
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.slide-in {
animation: slideIn 0.5s ease-out;
}
@keyframes slideIn {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.typing-effect {
border-right: 2px solid #667eea;
animation: blink 1s infinite;
}
@keyframes blink {
0%, 50% { border-color: #667eea; }
51%, 100% { border-color: transparent; }
}
.course-card {
background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
border: 1px solid rgba(255,255,255,0.2);
transition: all 0.3s ease;
}
.course-card:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
}
.progress-ring {
transform: rotate(-90deg);
}
.progress-ring__circle {
transition: stroke-dashoffset 0.35s;
stroke: #667eea;
stroke-width: 4;
fill: transparent;
stroke-dasharray: 251.2;
stroke-dashoffset: 251.2;
}
.floating-nav {
position: fixed;
top: 50%;
right: 2rem;
transform: translateY(-50%);
z-index: 1000;
}
.nav-dot {
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(255,255,255,0.5);
margin: 10px 0;
cursor: pointer;
transition: all 0.3s ease;
}
.nav-dot.active {
background: #667eea;
transform: scale(1.5);
}
.video-container {
position: relative;
overflow: hidden;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.quiz-option {
transition: all 0.3s ease;
cursor: pointer;
}
.quiz-option:hover {
background: rgba(102, 126, 234, 0.2);
transform: translateX(5px);
}
.quiz-option.selected {
background: rgba(102, 126, 234, 0.3);
border-color: #667eea;
}
.quiz-option.correct {
background: rgba(34, 197, 94, 0.3);
border-color: #22c55e;
}
.quiz-option.incorrect {
background: rgba(239, 68, 68, 0.3);
border-color: #ef4444;
}
.modal-backdrop {
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(5px);
}
.modal-content {
transform: scale(0.9);
transition: transform 0.3s ease;
}
.modal-content.show {
transform: scale(1);
}
.notification {
position: fixed;
top: 20px;
right: 20px;
z-index: 1001;
animation: slideInRight 0.5s ease;
}
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.search-bar {
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
transition: all 0.3s ease;
}
.search-bar:focus {
background: rgba(255,255,255,0.2);
border-color: #667eea;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.3);
}
.category-pill {
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
transition: all 0.3s ease;
}
.category-pill:hover,
.category-pill.active {
background: rgba(102, 126, 234, 0.3);
border-color: #667eea;
transform: translateY(-2px);
}
.instructor-avatar {
width: 60px;
height: 60px;
border-radius: 50%;
border: 3px solid #667eea;
background: linear-gradient(135deg, #667eea, #764ba2);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 1.2rem;
}
.rating-stars {
color: #fbbf24;
}
.progress-bar {
background: rgba(255,255,255,0.1);
border-radius: 10px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #667eea, #764ba2);
transition: width 0.5s ease;
}
.ai-chat {
position: fixed;
bottom: 20px;
right: 20px;
width: 350px;
height: 500px;
background: rgba(255,255,255,0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 20px;
overflow: hidden;
transition: all 0.3s ease;
}
.ai-chat.minimized {
height: 60px;
width: 200px;
}
.chat-messages {
height: calc(100% - 120px);
overflow-y: auto;
padding: 10px;
}
.chat-message {
margin: 10px 0;
padding: 10px 15px;
border-radius: 15px;
max-width: 80%;
word-wrap: break-word;
}
.chat-message.user {
background: rgba(102, 126, 234, 0.3);
margin-left: auto;
}
.chat-message.ai {
background: rgba(255,255,255,0.1);
margin-right: auto;
}
.payment-modal {
background: rgba(255,255,255,0.05);
backdrop-filter: blur(20px);
border: 1px solid rgba(255,255,255,0.1);
}
.stripe-card {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 20px;
border-radius: 15px;
margin: 10px 0;
}
</style>
</head>
<body class="bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900">
<div x-data="eduLoomApp()" x-init="init()" class="min-h-screen">
<!-- Navigation -->
<nav class="glass-effect fixed top-0 w-full z-50 px-6 py-4">
<div class="max-w-7xl mx-auto flex justify-between items-center">
<div class="flex items-center space-x-4">
<h1 class="text-2xl font-bold text-white">
<i class="fas fa-graduation-cap mr-2"></i>EduLoom
</h1>
</div>
<div class="hidden md:flex items-center space-x-6">
<button @click="currentPage = 'home'"
:class="{'text-white': currentPage === 'home', 'text-gray-300': currentPage !== 'home'}"
class="hover:text-white transition">Home</button>
<button @click="currentPage = 'courses'"
:class="{'text-white': currentPage === 'courses', 'text-gray-300': currentPage !== 'courses'}"
class="hover:text-white transition">Courses</button>
<button @click="currentPage = 'dashboard'"
x-show="user"
:class="{'text-white': currentPage === 'dashboard', 'text-gray-300': currentPage !== 'dashboard'}"
class="hover:text-white transition">Dashboard</button>
<button @click="currentPage = 'instructor'"
x-show="user?.role === 'instructor'"
:class="{'text-white': currentPage === 'instructor', 'text-gray-300': currentPage !== 'instructor'}"
class="hover:text-white transition">Teach</button>
</div>
<div class="flex items-center space-x-4">
<div class="relative">
<input type="text"
x-model="searchQuery"
@input="searchCourses()"
placeholder="Search courses..."
class="search-bar rounded-full px-4 py-2 text-white placeholder-gray-300 w-48 md:w-64">
<i class="fas fa-search absolute right-3 top-3 text-gray-300"></i>
</div>
<div x-show="!user" class="flex space-x-2">
<button @click="openModal('login')"
class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-full transition">
Login
</button>
<button @click="openModal('register')"
class="bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white px-4 py-2 rounded-full transition">
Sign Up
</button>
</div>
<div x-show="user" class="flex items-center space-x-4">
<button @click="toggleNotifications()" class="relative">
<i class="fas fa-bell text-white text-xl"></i>
<span x-show="notifications.length > 0"
class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
<span x-text="notifications.length"></span>
</span>
</button>
<div class="relative">
<button @click="profileDropdown = !profileDropdown"
class="w-10 h-10 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center text-white">
<span x-text="user?.name?.charAt(0)?.toUpperCase() || 'U'"></span>
</button>
<div x-show="profileDropdown"
@click.away="profileDropdown = false"
class="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg py-2">
<button @click="currentPage = 'profile'; profileDropdown = false"
class="block w-full text-left px-4 py-2 hover:bg-gray-100">Profile</button>
<button @click="logout()"
class="block w-full text-left px-4 py-2 hover:bg-gray-100 text-red-600">Logout</button>
</div>
</div>
</div>
</div>
</div>
</nav>
<!-- Floating Navigation -->
<div class="floating-nav hidden lg:block">
<div class="nav-dot" :class="{'active': currentPage === 'home'}" @click="currentPage = 'home'"></div>
<div class="nav-dot" :class="{'active': currentPage === 'courses'}" @click="currentPage = 'courses'"></div>
<div class="nav-dot" :class="{'active': currentPage === 'dashboard'}" @click="currentPage = 'dashboard'" x-show="user"></div>
<div class="nav-dot" :class="{'active': currentPage === 'instructor'}" @click="currentPage = 'instructor'" x-show="user?.role === 'instructor'"></div>
</div>
<!-- Main Content -->
<main class="pt-20">
<!-- Home Page -->
<div x-show="currentPage === 'home'" class="px-6 py-12">
<div class="max-w-7xl mx-auto">
<!-- Hero Section -->
<div class="text-center mb-16">
<h1 class="text-5xl md:text-7xl font-bold text-white mb-6">
Learn Without <span class="gradient-text">Limits</span>
</h1>
<p class="text-xl text-gray-300 mb-8 max-w-2xl mx-auto">
Join millions of learners worldwide. Master new skills with AI-powered courses designed for your success.
</p>
<div class="flex justify-center space-x-4">
<button @click="currentPage = 'courses'"
class="bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white px-8 py-4 rounded-full text-lg font-semibold transition transform hover:scale-105">
Explore Courses
</button>
<button @click="openModal('register')"
class="bg-white/20 hover:bg-white/30 text-white px-8 py-4 rounded-full text-lg font-semibold transition">
Start Free Trial
</button>
</div>
</div>
<!-- Stats -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-8 mb-16">
<div class="glass-effect rounded-2xl p-6 text-center hover-scale">
<div class="text-3xl font-bold text-white mb-2">50K+</div>
<div class="text-gray-300">Students</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center hover-scale">
<div class="text-3xl font-bold text-white mb-2">1.2K+</div>
<div class="text-gray-300">Courses</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center hover-scale">
<div class="text-3xl font-bold text-white mb-2">200+</div>
<div class="text-gray-300">Instructors</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center hover-scale">
<div class="text-3xl font-bold text-white mb-2">95%</div>
<div class="text-gray-300">Success Rate</div>
</div>
</div>
<!-- Featured Courses -->
<div class="mb-16">
<h2 class="text-3xl font-bold text-white mb-8">Featured Courses</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<template x-for="course in featuredCourses" :key="course.id">
<div class="course-card rounded-2xl p-6 hover-scale cursor-pointer" @click="viewCourse(course)">
<div class="relative mb-4">
<img :src="course.thumbnail" :alt="course.title" class="w-full h-48 rounded-xl object-cover">
<div class="absolute top-4 right-4 bg-green-500 text-white px-3 py-1 rounded-full text-sm">
<span x-text="course.price === 0 ? 'FREE' : '$' + course.price"></span>
</div>
</div>
<h3 class="text-xl font-bold text-white mb-2" x-text="course.title"></h3>
<p class="text-gray-300 text-sm mb-3" x-text="course.description.substring(0, 80) + '...'"></p>
<div class="flex items-center justify-between">
<div class="flex items-center">
<div class="w-8 h-8 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center text-white text-sm mr-2">
<span x-text="course.instructor.charAt(0)"></span>
</div>
<span class="text-gray-300 text-sm" x-text="course.instructor"></span>
</div>
<div class="flex items-center">
<i class="fas fa-star text-yellow-400 mr-1"></i>
<span class="text-white" x-text="course.rating"></span>
</div>
</div>
</div>
</template>
</div>
</div>
<!-- Categories -->
<div class="mb-16">
<h2 class="text-3xl font-bold text-white mb-8">Browse by Category</h2>
<div class="flex flex-wrap gap-4">
<template x-for="category in categories" :key="category">
<button @click="filterByCategory(category)"
class="category-pill px-6 py-3 rounded-full text-white transition">
<span x-text="category"></span>
</button>
</template>
</div>
</div>
</div>
</div>
<!-- Courses Page -->
<div x-show="currentPage === 'courses'" class="px-6 py-12">
<div class="max-w-7xl mx-auto">
<h1 class="text-4xl font-bold text-white mb-8">Explore Courses</h1>
<!-- Filters -->
<div class="glass-effect rounded-2xl p-6 mb-8">
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<select x-model="filters.level" class="search-bar rounded-lg px-4 py-2 text-white">
<option value="">All Levels</option>
<option value="beginner">Beginner</option>
<option value="intermediate">Intermediate</option>
<option value="advanced">Advanced</option>
</select>
<select x-model="filters.price" class="search-bar rounded-lg px-4 py-2 text-white">
<option value="">Any Price</option>
<option value="free">Free</option>
<option value="paid">Paid</option>
</select>
<select x-model="filters.rating" class="search-bar rounded-lg px-4 py-2 text-white">
<option value="">Any Rating</option>
<option value="4">4+ Stars</option>
<option value="4.5">4.5+ Stars</option>
</select>
<button @click="resetFilters()"
class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition">
Reset Filters
</button>
</div>
</div>
<!-- Course Grid -->
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-6">
<template x-for="course in filteredCourses" :key="course.id">
<div class="course-card rounded-2xl p-4 hover-scale cursor-pointer" @click="viewCourse(course)">
<img :src="course.thumbnail" :alt="course.title" class="w-full h-40 rounded-xl object-cover mb-4">
<h3 class="text-lg font-bold text-white mb-2" x-text="course.title"></h3>
<p class="text-gray-300 text-sm mb-2" x-text="course.instructor"></p>
<div class="flex items-center justify-between">
<div class="flex items-center">
<i class="fas fa-star text-yellow-400 mr-1"></i>
<span class="text-white text-sm" x-text="course.rating"></span>
</div>
<span class="text-white font-bold" x-text="course.price === 0 ? 'FREE' : '$' + course.price"></span>
</div>
</div>
</template>
</div>
</div>
</div>
<!-- Course Detail Page -->
<div x-show="currentPage === 'course-detail'" class="px-6 py-12">
<div class="max-w-6xl mx-auto">
<button @click="currentPage = 'courses'" class="text-white mb-6 flex items-center">
<i class="fas fa-arrow-left mr-2"></i> Back to Courses
</button>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Main Content -->
<div class="lg:col-span-2">
<!-- Video Player -->
<div class="video-container mb-6">
<video :src="selectedCourse?.videoUrl" controls class="w-full h-96">
Your browser does not support the video tag.
</video>
</div>
<!-- Course Info -->
<div class="glass-effect rounded-2xl p-6 mb-6">
<h1 class="text-3xl font-bold text-white mb-4" x-text="selectedCourse?.title"></h1>
<p class="text-gray-300 mb-4" x-text="selectedCourse?.description"></p>
<div class="flex items-center space-x-4 mb-4">
<div class="flex items-center">
<div class="instructor-avatar mr-3">
<span x-text="selectedCourse?.instructor?.charAt(0)"></span>
</div>
<div>
<div class="text-white font-semibold" x-text="selectedCourse?.instructor"></div>
<div class="text-gray-400 text-sm">Instructor</div>
</div>
</div>
<div class="flex items-center">
<i class="fas fa-star text-yellow-400 mr-1"></i>
<span class="text-white" x-text="selectedCourse?.rating"></span>
<span class="text-gray-400 ml-1">(1,234 reviews)</span>
</div>
<div class="text-white">
<span x-text="selectedCourse?.students + ' students'"></span>
</div>
</div>
<div class="flex items-center space-x-4">
<button @click="enrollCourse(selectedCourse)"
x-show="!isEnrolled(selectedCourse?.id)"
class="bg-gradient-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600 text-white px-8 py-3 rounded-full font-semibold transition">
Enroll Now
</button>
<button @click="toggleWishlist(selectedCourse)"
class="bg-white/20 hover:bg-white/30 text-white px-4 py-3 rounded-full transition">
<i :class="isInWishlist(selectedCourse?.id) ? 'fas fa-heart text-red-500' : 'far fa-heart'"></i>
</button>
</div>
</div>
<!-- Course Content -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-2xl font-bold text-white mb-4">Course Content</h2>
<div class="space-y-4">
<template x-for="section in selectedCourse?.sections" :key="section.id">
<div>
<h3 class="text-lg font-semibold text-white mb-2" x-text="section.title"></h3>
<div class="space-y-2">
<template x-for="lecture in section.lectures" :key="lecture.id">
<div class="flex items-center justify-between p-3 bg-white/10 rounded-lg">
<div class="flex items-center">
<i :class="lecture.completed ? 'fas fa-check-circle text-green-400' : 'far fa-circle text-gray-400'"
class="mr-3"></i>
<span class="text-white" x-text="lecture.title"></span>
</div>
<span class="text-gray-400 text-sm" x-text="lecture.duration"></span>
</div>
</template>
</div>
</div>
</template>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="space-y-6">
<!-- Course Stats -->
<div class="glass-effect rounded-2xl p-6">
<h3 class="text-xl font-bold text-white mb-4">Course Stats</h3>
<div class="space-y-4">
<div>
<div class="flex justify-between text-white mb-1">
<span>Progress</span>
<span x-text="getCourseProgress(selectedCourse?.id) + '%'"></span>
</div>
<div class="progress-bar h-2">
<div class="progress-fill" :style="`width: ${getCourseProgress(selectedCourse?.id)}%`"></div>
</div>
</div>
<div class="text-gray-300">
<i class="fas fa-clock mr-2"></i>
<span x-text="selectedCourse?.totalHours + ' hours'"></span>
</div>
<div class="text-gray-300">
<i class="fas fa-certificate mr-2"></i>
<span>Certificate of Completion</span>
</div>
</div>
</div>
<!-- Discussion -->
<div class="glass-effect rounded-2xl p-6">
<h3 class="text-xl font-bold text-white mb-4">Recent Discussions</h3>
<div class="space-y-4">
<template x-for="comment in selectedCourse?.comments" :key="comment.id">
<div class="border-b border-white/10 pb-3">
<div class="flex items-center mb-2">
<div class="w-8 h-8 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center text-white text-sm mr-2">
<span x-text="comment.user.charAt(0)"></span>
</div>
<span class="text-white text-sm" x-text="comment.user"></span>
</div>
<p class="text-gray-300 text-sm" x-text="comment.text"></p>
</div>
</template>
</div>
<div class="mt-4">
<textarea x-model="newComment"
placeholder="Ask a question..."
class="search-bar rounded-lg px-3 py-2 text-white w-full mb-2"></textarea>
<button @click="postComment()"
class="bg-gradient-to-r from-purple-500 to-blue-500 text-white px-4 py-2 rounded-lg w-full">
Post Comment
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Dashboard -->
<div x-show="currentPage === 'dashboard'" class="px-6 py-12">
<div class="max-w-7xl mx-auto">
<h1 class="text-4xl font-bold text-white mb-8">My Dashboard</h1>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="enrolledCourses.length"></div>
<div class="text-gray-300">Enrolled Courses</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="completedCourses.length"></div>
<div class="text-gray-300">Completed</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="certificatesEarned"></div>
<div class="text-gray-300">Certificates</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="totalHours"></div>
<div class="text-gray-300">Hours Learned</div>
</div>
</div>
<!-- My Courses -->
<div class="glass-effect rounded-2xl p-6 mb-8">
<h2 class="text-2xl font-bold text-white mb-4">My Courses</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<template x-for="course in enrolledCourses" :key="course.id">
<div class="course-card rounded-xl p-4">
<img :src="course.thumbnail" :alt="course.title" class="w-full h-32 rounded-lg object-cover mb-3">
<h3 class="text-white font-semibold mb-2" x-text="course.title"></h3>
<div class="mb-3">
<div class="flex justify-between text-sm text-gray-300 mb-1">
<span>Progress</span>
<span x-text="getCourseProgress(course.id) + '%'"></span>
</div>
<div class="progress-bar h-2">
<div class="progress-fill" :style="`width: ${getCourseProgress(course.id)}%`"></div>
</div>
</div>
<button @click="currentPage = 'course-detail'; selectedCourse = course"
class="w-full bg-gradient-to-r from-purple-500 to-blue-500 text-white py-2 rounded-lg">
Continue Learning
</button>
</div>
</template>
</div>
</div>
<!-- Achievements -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-2xl font-bold text-white mb-4">Achievements</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<template x-for="badge in achievements" :key="badge.id">
<div class="text-center">
<div class="w-16 h-16 mx-auto mb-2 bg-gradient-to-r from-purple-500 to-blue-500 rounded-full flex items-center justify-center">
<i :class="badge.icon" class="text-white text-2xl"></i>
</div>
<div class="text-white text-sm" x-text="badge.name"></div>
</div>
</template>
</div>
</div>
</div>
</div>
<!-- Instructor Dashboard -->
<div x-show="currentPage === 'instructor'" class="px-6 py-12">
<div class="max-w-7xl mx-auto">
<h1 class="text-4xl font-bold text-white mb-8">Instructor Dashboard</h1>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Stats -->
<div class="lg:col-span-2">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="publishedCourses.length"></div>
<div class="text-gray-300">Published Courses</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2" x-text="totalStudents"></div>
<div class="text-gray-300">Total Students</div>
</div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="text-3xl font-bold text-white mb-2">$<span x-text="totalRevenue"></span></div>
<div class="text-gray-300">Total Revenue</div>
</div>
</div>
<!-- Create Course -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-2xl font-bold text-white mb-4">Create New Course</h2>
<form @submit.prevent="createCourse()" class="space-y-4">
<div>
<label class="text-white mb-2 block">Course Title</label>
<input type="text" x-model="newCourse.title"
class="search-bar rounded-lg px-4 py-2 text-white w-full">
</div>
<div>
<label class="text-white mb-2 block">Description</label>
<textarea x-model="newCourse.description"
class="search-bar rounded-lg px-4 py-2 text-white w-full h-24"></textarea>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-white mb-2 block">Category</label>
<select x-model="newCourse.category" class="search-bar rounded-lg px-4 py-2 text-white w-full">
<option value="">Select Category</option>
<template x-for="category in categories" :key="category">
<option :value="category" x-text="category"></option>
</template>
</select>
</div>
<div>
<label class="text-white mb-2 block">Price ($)</label>
<input type="number" x-model="newCourse.price"
class="search-bar rounded-lg px-4 py-2 text-white w-full">
</div>
</div>
<button type="submit"
class="bg-gradient-to-r from-purple-500 to-blue-500 text-white px-6 py-2 rounded-lg">
Create Course
</button>
</form>
</div>
</div>
<!-- My Courses -->
<div>
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-4">My Courses</h2>
<div class="space-y-4">
<template x-for="course in publishedCourses" :key="course.id">
<div class="flex items-center space-x-3">
<img :src="course.thumbnail" class="w-12 h-12 rounded-lg object-cover">
<div>
<div class="text-white font-semibold" x-text="course.title"></div>
<div class="text-gray-400 text-sm" x-text="course.students + ' students'"></div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Profile Page -->
<div x-show="currentPage === 'profile'" class="px-6 py-12">
<div class="max-w-4xl mx-auto">
<h1 class="text-4xl font-bold text-white mb-8">Profile Settings</h1>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div class="lg:col-span-2">
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-2xl font-bold text-white mb-4">Personal Information</h2>
<form @submit.prevent="updateProfile()" class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-white mb-2 block">First Name</label>
<input type="text" x-model="userProfile.firstName"
class="search-bar rounded-lg px-4 py-2 text-white w-full">
</div>
<div>
<label class="text-white mb-2 block">Last Name</label>
<input type="text" x-model="userProfile.lastName"
class="search-bar rounded-lg px-4 py-2 text-white w-full">
</div>
</div>
<div>
<label class="text-white mb-2 block">Email</label>
<input type="email" x-model="userProfile.email"
class="search-bar rounded-lg px-4 py-2 text-white w-full">
</div>
<div>
<label class="text-white mb-2 block">Bio</label>
<textarea x-model="userProfile.bio"
class="search-bar rounded-lg px-4 py-2 text-white w-full h-24"></textarea>
</div>
<button type="submit"
class="bg-gradient-to-r from-purple-500 to-blue-500 text-white px-6 py-2 rounded-lg">
Save Changes
</button>
</form>
</div>
</div>
<div>
<div class="glass-effect rounded-2xl p-6 text-center">
<div class="w-24 h-24 mx-auto mb-4 rounded-full bg-gradient-to-r from-purple-500 to-blue-500 flex items-center justify-center">
<span class="text-white text-3xl font-bold" x-text="user?.name?.charAt(0)"></span>
</div>
<h3 class="text-xl font-bold text-white" x-text="user?.name"></h3>
<p class="text-gray-300" x-text="user?.email"></p>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Modals -->
<div x-show="showModal"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 modal-backdrop flex items-center justify-center z-50">
<div class="modal-content bg-white rounded-2xl p-8 max-w-md w-full mx-4"
:class="{'show': showModal}">
<button @click="closeModal()" class="absolute top-4 right-4 text-gray-500 hover:text-gray-700">
<i class="fas fa-times text-xl"></i>
</button>
<!-- Login Modal -->
<div x-show="modalType === 'login'">
<h2 class="text-2xl font-bold text-gray-800 mb-6 text-center">Welcome Back</h2>
<form @submit.prevent="login()" class="space-y-4">
<div>
<label class="block text-gray-700 mb-2">Email</label>
<input type="email" x-model="loginForm.email"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
</div>
<div>
<label class="block text-gray-700 mb-2">Password</label>
<input type="password" x-model="loginForm.password"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
</div>
<button type="submit"
class="w-full bg-gradient-to-r from-purple-500 to-blue-500 text-white py-3 rounded-lg font-semibold">
Sign In
</button>
</form>
<div class="text-center mt-4">
<button @click="modalType = 'register'" class="text-purple-600 hover:underline">
Don't have an account? Sign up
</button>
</div>
</div>
<!-- Register Modal -->
<div x-show="modalType === 'register'">
<h2 class="text-2xl font-bold text-gray-800 mb-6 text-center">Join EduLoom</h2>
<form @submit.prevent="register()" class="space-y-4">
<div>
<label class="block text-gray-700 mb-2">Full Name</label>
<input type="text" x-model="registerForm.name"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
</div>
<div>
<label class="block text-gray-700 mb-2">Email</label>
<input type="email" x-model="registerForm.email"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
</div>
<div>
<label class="block text-gray-700 mb-2">Password</label>
<input type="password" x-model="registerForm.password"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
</div>
<div>
<label class="block text-gray-700 mb-2">I want to</label>
<select x-model="registerForm.role"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:border-purple-500">
<option value="student">Learn</option>
<option value="instructor">Teach</option>
</select>
</div>
<button type="submit"
class="w-full bg-gradient-to-r from-purple-500 to-blue-500 text-white py-3 rounded-lg font-semibold">
Create Account
</button>
</form>
<div class="text-center mt-4">
<button @click="modalType = 'login'" class="text-purple-600 hover:underline">
Already have an account? Sign in
</button>
</div>
</div>
<!-- Payment Modal -->
<div x-show="modalType === 'payment'">
<h2 class="text-2xl font-bold text-gray-800 mb-6 text-center">Complete Your Purchase</h2>
<div class="payment-modal rounded-2xl p-6">
<div class="text-center mb-4">
<h3 class="text-xl font-bold text-white" x-text="selectedCourse?.title"></h3>
<p class="text-3xl font-bold text-white mt-2">$<span x-text="selectedCourse?.price"></span></p>
</div>
<form @submit.prevent="processPayment()" class="space-y-4">
<div class="stripe-card">
<div class="mb-4">
<label class="text-white mb-2 block">Card Number</label>
<input type="text" placeholder="1234 5678 9012 3456"
class="w-full px-4 py-2 bg-white/20 border border-white/30 rounded-lg text-white placeholder-white/70">
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-white mb-2 block">Expiry</label>
<input type="text" placeholder="MM/YY"
class="w-full px-4 py-2 bg-white/20 border border-white/30 rounded-lg text-white placeholder-white/70">
</div>
<div>
<label class="text-white mb-2 block">CVC</label>
<input type="text" placeholder="123"
class="w-full px-4 py-2 bg-white/20 border border-white/30 rounded-lg text-white placeholder-white/70">
</div>
</div>
</div>
<button type="submit"
class="w-full bg-white text-purple-600 py-3 rounded-lg font-semibold">
Complete Purchase
</button>
</form>
</div>
</div>
<!-- Quiz Modal -->
<div x-show="modalType === 'quiz'" class="max-w-2xl">
<h2 class="text-2xl font-bold text-gray-800 mb-6 text-center">Quiz Time!</h2>
<div class="space-y-6">
<div class="text-center">
<h3 class="text-xl font-bold text-gray-800 mb-2" x-text="currentQuiz?.title"></h3>
<p class="text-gray-600">Question <span x-text="currentQuestionIndex + 1"></span> of <span x-text="currentQuiz?.questions?.length"></span></p>
</div>
<div class="bg-gray-50 rounded-lg p-6">
<h4 class="text-lg font-semibold text-gray-800 mb-4" x-text="currentQuestion?.question"></h4>
<div class="space-y-3">
<template x-for="(option, index) in currentQuestion?.options" :key="index">
<div @click="selectAnswer(index)"
class="quiz-option p-4 border-2 border-gray-200 rounded-lg"
:class="{
'selected': selectedAnswer === index,
'correct': showAnswer && index === currentQuestion?.correctAnswer,
'incorrect': showAnswer && selectedAnswer === index && index !== currentQuestion?.correctAnswer
}">
<span x-text="option"></span>
</div>
</template>
</div>
</div>
<div class="flex justify-between">
<button @click="previousQuestion()"
:disabled="currentQuestionIndex === 0"
class="bg-gray-200 text-gray-700 px-6 py-2 rounded-lg disabled:opacity-50">
Previous
</button>
<button @click="nextQuestion()"
x-show="!showAnswer"
:disabled="selectedAnswer === null"
class="bg-gradient-to-r from-purple-500 to-blue-500 text-white px-6 py-2 rounded-lg disabled:opacity-50">
Next
</button>
<button @click="submitQuiz()"
x-show="showAnswer && currentQuestionIndex === currentQuiz?.questions?.length - 1"
class="bg-green-500 text-white px-6 py-2 rounded-lg">
Finish Quiz
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Notifications -->
<div class="notification" x-show="showNotification">
<div class="glass-effect rounded-lg p-4 text-white">
<div class="flex items-center">
<i :class="notificationType === 'success' ? 'fas fa-check-circle text-green-400' : 'fas fa-exclamation-circle text-red-400'"
class="mr-2"></i>
<span x-text="notificationMessage"></span>
</div>
</div>
</div>
<!-- AI Chat Assistant -->
<div class="ai-chat" :class="{'minimized': !chatOpen}">
<div class="bg-white/10 p-4 flex justify-between items-center">
<h3 class="text-white font-semibold">AI Assistant</h3>
<button @click="chatOpen = !chatOpen" class="text-white">
<i :class="chatOpen ? 'fas fa-minus' : 'fas fa-plus'"></i>
</button>
</div>
<div x-show="chatOpen" class="chat-messages">
<template x-for="message in chatMessages" :key="message.id">
<div :class="{'chat-message user': message.type === 'user', 'chat-message ai': message.type === 'ai'}"
x-text="message.text">
</div>
</template>
</div>
<div x-show="chatOpen" class="p-4">
<input type="text"
x-model="chatInput"
@keyup.enter="sendChatMessage()"
placeholder="Ask me anything..."
class="w-full px-3 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-gray-300">
</div>
</div>
<!-- Loading Spinner -->
<div x-show="loading"
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div class="w-16 h-16 border-4 border-purple-500 border-t-transparent rounded-full animate-spin"></div>
</div>
</div>
<script>
function eduLoomApp() {
return {
currentPage: 'home',
user: null,
userProfile: {
firstName: '',
lastName: '',
email: '',
bio: ''
},
showModal: false,
modalType: 'login',
loading: false,
searchQuery: '',
filters: {
level: '',
price: '',
rating: ''
},
courses: [],
featuredCourses: [],
enrolledCourses: [],
completedCourses: [],
certificatesEarned: 0,
totalHours: 0,
totalStudents: 0,
totalRevenue: 0,
publishedCourses: [],
achievements: [],
notifications: [],
showNotification: false,
notificationMessage: '',
notificationType: 'success',
profileDropdown: false,
selectedCourse: null,
newComment: '',
newCourse: {
title: '',
description: '',
category: '',
price: 0
},
loginForm: {
email: '',
password: ''
},
registerForm: {
name: '',
email: '',
password: '',
role: 'student'
},
chatOpen: false,
chatInput: '',
chatMessages: [],
currentQuiz: null,
currentQuestionIndex: 0,
currentQuestion: null,
selectedAnswer: null,
showAnswer: false,
wishlist: [],
categories: [
'Web Development',
'Data Science',
'AI & Machine Learning',
'Mobile Development',
'Cloud Computing',
'Cybersecurity',
'Digital Marketing',
'Business'
],
init() {
// Initialize mock data
this.loadMockData();
// Check for user in localStorage
const savedUser = localStorage.getItem('eduLoomUser');
if (savedUser) {
this.user = JSON.parse(savedUser);
}
// Initialize achievements
this.achievements = [
{ id: 1, name: 'First Course', icon: 'fas fa-graduation-cap' },
{ id: 2, name: 'Quiz Master', icon: 'fas fa-trophy' },
{ id: 3, name: '100 Hours', icon: 'fas fa-clock' },
{ id: 4, name: 'Top Student', icon: 'fas fa-medal' }
];
},
loadMockData() {
this.courses = [
{
id: 1,
title: 'Complete Web Development Bootcamp',
description: 'Learn HTML, CSS, JavaScript, React, Node.js and more',
thumbnail: 'https://images.unsplash.com/photo-1517694712202-14dd9538aa97',
instructor: 'John Doe',
rating: 4.8,
students: 1234,
price: 89,
category: 'Web Development',
level: 'beginner',
totalHours: 40,
videoUrl: 'https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4',
sections: [
{
id: 1,
title: 'Introduction',
lectures: [
{ id: 1, title: 'Course Overview', duration: '5:30', completed: true },
{ id: 2, title: 'Setting Up Environment', duration: '10:15', completed: false }
]
}
],
comments: [
{ id: 1, user: 'Alice', text: 'Great course! Really helped me understand React.' },
{ id: 2, user: 'Bob', text: 'The instructor explains concepts very clearly.' }
]
},
{
id: 2,
title: 'Machine Learning A-Z',
description: 'Master machine learning algorithms and techniques',
thumbnail: 'https://images.unsplash.com/photo-1555949963-aa79dcee981c',
instructor: 'Jane Smith',
rating: 4.9,
students: 892,
price: 129,
category: 'AI & Machine Learning',
level: 'advanced',
totalHours: 60
},
{
id: 3,
title: 'iOS Development with Swift',
description: 'Build iOS apps from scratch using Swift',
thumbnail: 'https://images.unsplash.com/photo-1555774698-0b77e916bb71',
instructor: 'Mike Johnson',
rating: 4.7,
students: 567,
price: 0,
category: 'Mobile Development',
level: 'intermediate',
totalHours: 35
}
];
this.featuredCourses = this.courses.slice(0, 3);
this.enrolledCourses = this.courses.slice(0, 2);
this.publishedCourses = this.courses.slice(0, 1);
this.totalStudents = 1234;
this.totalRevenue = 8940;
this.certificatesEarned = 3;
this.totalHours = 75;
},
openModal(type) {
this.modalType = type;
this.showModal = true;
},
closeModal() {
this.showModal = false;
this.modalType = '';
},
login() {
// Mock login
this.user = {
id: 1,
name: this.loginForm.email.split('@')[0],
email: this.loginForm.email,
role: 'student'
};
localStorage.setItem('eduLoomUser', JSON.stringify(this.user));
this.closeModal();
this.showNotification = true;
this.notificationMessage = 'Successfully logged in!';
this.notificationType = 'success';
setTimeout(() => this.showNotification = false, 3000);
},
register() {
// Mock registration
this.user = {
id: Date.now(),
name: this.registerForm.name,
email: this.registerForm.email,
role: this.registerForm.role
};
localStorage.setItem('eduLoomUser', JSON.stringify(this.user));
this.closeModal();
this.showNotification = true;
this.notificationMessage = 'Account created successfully!';
this.notificationType = 'success';
setTimeout(() => this.showNotification = false, 3000);
},
logout() {
this.user = null;
localStorage.removeItem('eduLoomUser');
this.currentPage = 'home';
this.profileDropdown = false;
},
searchCourses() {
// Implement search functionality
if (this.searchQuery.length > 0) {
this.filteredCourses = this.courses.filter(course =>
course.title.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
course.description.toLowerCase().includes(this.searchQuery.toLowerCase())
);
} else {
this.filteredCourses = this.courses;
}
},
filterByCategory(category) {
this.filteredCourses = this.courses.filter(course => course.category === category);
},
resetFilters() {
this.filters = {
level: '',
price: '',
rating: ''
};
this.filteredCourses = this.courses;
},
viewCourse(course) {
this.selectedCourse = course;
this.currentPage = 'course-detail';
},
enrollCourse(course) {
this.enrolledCourses.push(course);
this.showNotification = true;
this.notificationMessage = `Successfully enrolled in ${course.title}!`;
this.notificationType = 'success';
setTimeout(() => this.showNotification = false, 3000);
},
isEnrolled(courseId) {
return this.enrolledCourses.some(course => course.id === courseId);
},
getCourseProgress(courseId) {
// Mock progress calculation
return Math.floor(Math.random() * 100);
},
toggleWishlist(course) {
const index = this.wishlist.findIndex(c => c.id === course.id);
if (index > -1) {
this.wishlist.splice(index, 1);
} else {
this.wishlist.push(course);
}
},
isInWishlist(courseId) {
return this.wishlist.some(course => course.id === courseId);
},
createCourse() {
const course = {
id: Date.now(),
title: this.newCourse.title,
description: this.newCourse.description,
category: this.newCourse.category,
price: this.newCourse.price,
instructor: this.user.name,
thumbnail: 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3',
rating: 0,
students: 0
};
this.publishedCourses.push(course);
this.newCourse = { title: '', description: '', category: '', price: 0 };
this.showNotification = true;
this.notificationMessage = 'Course created successfully!';
setTimeout(() => this.showNotification = false, 3000);
},
updateProfile() {
this.user.name = `${this.userProfile.firstName} ${this.userProfile.lastName}`;
this.showNotification = true;
this.notificationMessage = 'Profile updated successfully!';
setTimeout(() => this.showNotification = false, 3000);
},
processPayment() {
// Mock payment processing
this.closeModal();
this.enrollCourse(this.selectedCourse);
},
sendChatMessage() {
if (this.chatInput.trim()) {
this.chatMessages.push({
id: Date.now(),
type: 'user',
text: this.chatInput
});
// Mock AI response
setTimeout(() => {
this.chatMessages.push({
id: Date.now() + 1,
type: 'ai',
text: `I understand you're asking about "${this.chatInput}". How can I help you with this topic?`
});
}, 1000);
this.chatInput = '';
}
},
toggleNotifications() {
// Toggle notifications panel
console.log('Notifications toggled');
},
postComment() {
if (this.newComment.trim() && this.selectedCourse) {
const comment = {
id: Date.now(),
user: this.user.name,
text: this.newComment
};
this.selectedCourse.comments.push(comment);
this.newComment = '';
}
}
}
}
</script>
</body>
</html>