"""
SkillSync: Generative AI Mastery Course Platform
Coursera-inspired design for Hugging Face Spaces
"""
import gradio as gr
import json
import os
from datetime import datetime
# Import configuration
from config import Config
# Import utilities
from utils.progress_manager import ProgressManager
from utils.quiz_handler import QuizHandler
# Load course data
def load_course_data():
"""Load course data from JSON file"""
try:
with open('data/course_data.json', 'r') as f:
return json.load(f)
except Exception as e:
print(f"Error loading course data: {e}")
return None
# Initialize managers
progress_manager = ProgressManager()
quiz_handler = QuizHandler()
COURSE_DATA = load_course_data()
# Custom CSS
CUSTOM_CSS = """
/* Main Styles */
.gradio-container {
max-width: 1400px !important;
margin: 0 auto !important;
padding: 0 !important;
}
/* Hero Section */
.hero-section {
background: linear-gradient(135deg, #0056D2 0%, #0044A8 100%);
color: white;
padding: 48px 32px;
margin-bottom: 24px;
border-radius: 16px;
}
/* Module Cards */
.module-card {
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
margin-bottom: 16px;
overflow: hidden;
border: 1px solid #E0E0E0;
transition: all 0.3s ease;
}
.module-card:hover {
box-shadow: 0 4px 16px rgba(0,0,0,0.12);
transform: translateY(-2px);
}
/* Progress Bar */
.progress-bar {
background: #E0E0E0;
border-radius: 8px;
height: 8px;
overflow: hidden;
}
.progress-fill {
background: linear-gradient(90deg, #0056D2 0%, #0044A8 100%);
height: 100%;
border-radius: 8px;
transition: width 0.5s ease;
}
/* Stats Cards */
.stat-card {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border-radius: 12px;
padding: 20px;
text-align: center;
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Lesson Items */
.lesson-item {
padding: 16px 24px;
border-bottom: 1px solid #F5F5F5;
display: flex;
align-items: center;
gap: 12px;
}
.lesson-item:hover {
background: #FAFAFA;
}
.lesson-icon {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
}
.video-icon { background: #E3F2FD; color: #1565C0; }
.reading-icon { background: #E8F5E9; color: #2E7D32; }
.quiz-icon { background: #FFF3E0; color: #EF6C00; }
.assignment-icon { background: #FCE4EC; color: #C2185B; }
/* Quiz Styles */
.quiz-option {
padding: 16px 20px;
border: 2px solid #E0E0E0;
border-radius: 8px;
margin-bottom: 12px;
cursor: pointer;
transition: all 0.2s ease;
}
.quiz-option:hover {
border-color: #0056D2;
background: #E8F0FE;
}
/* Buttons */
.primary-btn {
background: #0056D2 !important;
color: white !important;
border: none !important;
border-radius: 8px !important;
padding: 12px 24px !important;
font-weight: 600 !important;
}
.primary-btn:hover {
background: #0044A8 !important;
}
/* Instructor Card */
.instructor-card {
display: flex;
align-items: center;
gap: 16px;
padding: 16px;
background: #F5F5F5;
border-radius: 8px;
margin-bottom: 12px;
}
.instructor-avatar {
width: 56px;
height: 56px;
border-radius: 50%;
background: linear-gradient(135deg, #0056D2 0%, #0044A8 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 700;
font-size: 18px;
}
/* Tags */
.tag {
display: inline-block;
padding: 4px 12px;
border-radius: 16px;
font-size: 12px;
font-weight: 600;
margin-right: 8px;
}
.tag-beginner { background: #E8F5E9; color: #2E7D32; }
.tag-intermediate { background: #FFF3E0; color: #EF6C00; }
.tag-advanced { background: #FCE4EC; color: #C2185B; }
/* Accordion */
.accordion-content {
padding: 0 24px 24px;
}
/* Responsive */
@media (max-width: 768px) {
.hero-section {
padding: 32px 16px;
}
.stat-card {
padding: 16px;
}
}
"""
def create_app():
"""Create the main Gradio application"""
with gr.Blocks(
theme=gr.themes.Soft(
primary_hue=Config.PRIMARY_HUE,
secondary_hue=Config.SECONDARY_HUE
),
css=CUSTOM_CSS,
title=Config.APP_TITLE
) as app:
# Header
gr.HTML("""
đ SkillSync: Generative AI Mastery
From Fundamentals to Production Deployment
""")
# Progress Display
with gr.Row():
with gr.Column(scale=1):
progress_display = gr.HTML(value=update_progress_display())
# Main Tabs
with gr.Tabs():
# Course Overview Tab
with gr.TabItem("đ Course Overview"):
if COURSE_DATA:
create_course_overview()
# Module Tabs
if COURSE_DATA:
for module in COURSE_DATA['modules']:
with gr.TabItem(f"Module {module['id']}: {module['title'][:25]}..."):
create_module_tab(module)
# Capstone Tab
with gr.TabItem("đ Capstone Project"):
create_capstone_tab()
# Resources Tab
with gr.TabItem("đ Resources"):
create_resources_tab()
# Footer
gr.HTML("""
Š 2025 SkillSync
Master the future of AI with our comprehensive Generative AI course.
""")
return app
def update_progress_display():
"""Update the progress display HTML"""
if not COURSE_DATA:
return ""
total_lessons = sum(len(m['lessons']) for m in COURSE_DATA['modules'])
completed = progress_manager.get_total_completed()
percentage = int((completed / total_lessons) * 100) if total_lessons > 0 else 0
quizzes_passed = progress_manager.get_quizzes_passed()
return f"""
đ Your Progress
{percentage}%
Overall Completion
{completed}/{total_lessons}
Lessons Completed
{quizzes_passed}/5
Quizzes Passed
Course Progress
{percentage}%
"""
def create_course_overview():
"""Create the course overview section"""
course = COURSE_DATA.get('course', {})
gr.HTML(f"""
{course.get('title', 'Generative AI Mastery')}
{course.get('subtitle', '')}
{course.get('description', '')}
{course.get('level', 'Intermediate')}
{course.get('duration', '25+ hours')}
Certificate Available
""")
# What You'll Learn
gr.HTML("""
đ¯ What You'll Learn
""")
for skill in course.get('skills', [])[:8]:
gr.HTML(f"""
""")
gr.HTML("
")
# Instructors
gr.HTML("""
đ¨âđĢ Instructors
""")
for instructor in course.get('instructors', []):
gr.HTML(f"""
{instructor.get('image', 'AI')}
{instructor.get('name', 'Instructor')}
{instructor.get('title', '')}
â {instructor.get('rating', 4.8)} âĸ {instructor.get('students', 0):,} students
""")
gr.HTML("
")
def create_module_tab(module):
"""Create a module tab with all content"""
# Calculate progress
completed_lessons = progress_manager.get_completed_lessons(module['id'])
total_lessons = len(module['lessons'])
progress_pct = int((len(completed_lessons) / total_lessons) * 100) if total_lessons > 0 else 0
# Module Header
gr.HTML(f"""
{module['id']}
{module['title']}
{module.get('subtitle', '')}
{module['description']}
âąī¸
{module.get('duration', '5 hours')}
đ
{total_lessons} lessons
đ
Level: {module.get('level', 'Intermediate')}
Progress: {len(completed_lessons)}/{total_lessons} lessons
{progress_pct}%
""")
# Learning Objectives
with gr.Accordion("đ¯ Learning Objectives", open=False):
objectives = module.get('learning_objectives', [])
for obj in objectives:
gr.HTML(f"""
""")
# Lessons
gr.HTML("đ Lessons
")
for lesson in module['lessons']:
is_completed = lesson['id'] in completed_lessons
status_icon = "â
" if is_completed else "âŦ"
icon_class = "video-icon" if lesson['type'] == "video" else "reading-icon"
icon_emoji = "đŦ" if lesson['type'] == "video" else "đ"
gr.HTML(f"""
{icon_emoji}
{lesson['title']}
{lesson['duration']} âĸ {lesson['type'].title()}
{status_icon}
""")
# Mark Lesson Complete
gr.HTML("")
lesson_dropdown = gr.Dropdown(
choices=[lesson['title'] for lesson in module['lessons']],
label="Mark Lesson as Complete",
info="Select a lesson you've completed"
)
mark_btn = gr.Button("â
Mark as Complete", variant="primary")
status_msg = gr.HTML()
def mark_complete(module_id, lesson_title):
for lesson in module['lessons']:
if lesson['title'] == lesson_title:
result = progress_manager.mark_lesson_complete(module_id, lesson['id'])
if result:
return f"
â
Successfully marked '{lesson_title}' as complete!
"
else:
return f"
âšī¸ '{lesson_title}' is already marked as complete.
"
return "
â Lesson not found.
"
mark_btn.click(
fn=lambda x: mark_complete(module['id'], x),
inputs=[lesson_dropdown],
outputs=[status_msg]
)
gr.HTML("
")
# Assignment Section
if 'assignment' in module:
assignment = module['assignment']
with gr.Accordion(f"đ Assignment: {assignment['title']}", open=False):
gr.HTML(f"""
{assignment['description']}
âąī¸ {assignment.get('time_estimate', '3-4 hours')}
đ {assignment.get('difficulty', 'Intermediate')}
""")
gr.HTML("Tasks:
")
for i, task in enumerate(assignment.get('tasks', [])):
if isinstance(task, dict):
gr.HTML(f"{i+1}. {task.get('title', task.get('description', ''))}
")
else:
gr.HTML(f"{i+1}. {task}
")
gr.HTML("Deliverables:
")
for item in assignment.get('deliverables', []):
gr.HTML(f"âĸ {item}
")
# Quiz Section
if 'quiz' in module:
quiz = module['quiz']
with gr.Accordion(f"đ {quiz['title']}", open=False):
current_score = progress_manager.get_quiz_score(module['id'])
gr.HTML(f"""
Instructions: Answer all {len(quiz['questions'])} questions. You need 80% to pass.
Current Best Score: {current_score}%
""")
question_inputs = []
for i, question in enumerate(quiz['questions']):
q_input = gr.Radio(
choices=question['options'],
label=f"Question {i+1}: {question['question']}",
type="index"
)
question_inputs.append(q_input)
submit_btn = gr.Button("Submit Quiz", variant="primary")
result_display = gr.HTML()
def evaluate_quiz(module_id, *answers):
evaluation = quiz_handler.evaluate_answers(quiz['questions'], answers)
progress_manager.save_quiz_score(module_id, evaluation['score'])
result_html = f"""
{'đ Congratulations!' if evaluation['passed'] else 'đ Keep Learning!'}
Score: {evaluation['score']}%
{evaluation['correct_count']} out of {evaluation['total_questions']} correct
{'You passed!' if evaluation['passed'] else 'You need 80% to pass. Try again!'}
"""
return result_html
submit_btn.click(
fn=lambda *answers: evaluate_quiz(module['id'], *answers),
inputs=question_inputs,
outputs=[result_display]
)
def create_capstone_tab():
"""Create the capstone project tab"""
capstone = COURSE_DATA.get('capstone', {})
gr.HTML(f"""
đ {capstone.get('title', 'Capstone Project')}
{capstone.get('subtitle', '')}
{capstone.get('description', '')}
âąī¸ {capstone.get('duration', '20-25 hours')}
đ {capstone.get('difficulty', 'Advanced')}
""")
# Requirements
with gr.Accordion("đ Requirements", open=True):
for i, req in enumerate(capstone.get('requirements', [])):
if isinstance(req, dict):
gr.HTML(f"""
{i+1}. {req.get('title', '')}
{req.get('description', '')}
""")
else:
gr.HTML(f"{i+1}. {req}
")
# Evaluation Criteria
with gr.Accordion("đ Evaluation Criteria", open=False):
criteria = capstone.get('evaluation_criteria', {})
for criterion, weight in criteria.items():
gr.HTML(f"""
{criterion.replace('_', ' ')}
{weight}
""")
# Submission Form
gr.HTML("đ Submit Your Project
")
with gr.Row():
with gr.Column():
project_title = gr.Textbox(
label="Project Title",
placeholder="Enter your project title"
)
project_description = gr.Textbox(
label="Project Description",
lines=5,
placeholder="Describe your project, approach, and key features"
)
project_url = gr.Textbox(
label="Demo URL (Optional)",
placeholder="https://your-demo-url.com"
)
project_file = gr.File(
label="Upload Project Files",
file_types=[".zip", ".pdf", ".ipynb"]
)
submit_btn = gr.Button("Submit Project", variant="primary")
submission_status = gr.HTML()
def submit_project(title, desc, url, file):
success, message = progress_manager.submit_capstone(title, desc, url, file)
if success:
return f"""
â
Project Submitted Successfully!
Title: {title}
Your project will be reviewed within 5-7 business days.
"""
else:
return f"""
â {message}
"""
submit_btn.click(
fn=submit_project,
inputs=[project_title, project_description, project_url, project_file],
outputs=[submission_status]
)
def create_resources_tab():
"""Create the resources tab"""
resources = COURSE_DATA.get('resources', {})
with gr.Tabs():
with gr.TabItem("đ Books"):
gr.HTML("")
for book in resources.get('books', []):
gr.HTML(f"""
{book.get('title', '')}
by {book.get('authors', '')}
""")
gr.HTML("
")
with gr.TabItem("đ Online Resources"):
gr.HTML("")
for resource in resources.get('online_resources', []):
gr.HTML(f"""
""")
gr.HTML("
")
with gr.TabItem("đ ī¸ Tools"):
gr.HTML("")
for tool in resources.get('tools', []):
gr.HTML(f"""
{tool.get('name', '')}
{tool.get('description', '')}
""")
gr.HTML("
")
with gr.TabItem("đē Video Courses"):
gr.HTML("""
Stanford CS229: Machine Learning
Comprehensive ML course from Stanford University
Fast.ai Practical Deep Learning
Hands-on deep learning course
DeepLearning.AI
Courses by Andrew Ng
""")
# Launch the app
if __name__ == "__main__":
print("Starting SkillSync: Generative AI Mastery...")
print(f"Version: {Config.APP_VERSION}")
print("-" * 50)
app = create_app()
app.launch(
server_name=Config.GRADIO_SERVER_NAME,
server_port=Config.GRADIO_SERVER_PORT,
share=Config.GRADIO_SHARE
)