import gradio as gr
import json
import random
import string
from datetime import datetime, timedelta
from pathlib import Path
# Admin password
ADMIN_PASSWORD = "@mikaelJ46"
# Storage file for school codes
STORAGE_FILE = Path("school_codes.json")
# Platform links - UPDATE THESE WITH YOUR ACTUAL HUGGINGFACE SPACE URLS
PLATFORMS = [
{
"name": "Chemistry & Biology",
"description": "Deep understanding focus with AI-powered learning",
"subjects": ["Chemistry", "Biology"],
"url": "https://mikaelj46-chembio.hf.space/",
"emoji": ""
},
{
"name": "Geography, History & Business",
"description": "Comprehensive humanities and business studies",
"subjects": ["Geography", "History", "Business"],
"url": "https://mikaelj46-goehistbusn.hf.space/",
"emoji": ""
},
{
"name": "French & EFL",
"description": "Language learning with AI translation and dictionary",
"subjects": ["French", "EFL"],
"url": "https://mikaelj46-language-app.hf.space/",
"emoji": ""
},
{
"name": "Mathematics & Physics",
"description": "Step-by-step problem solving and practice",
"subjects": ["Mathematics", "Physics"],
"url": "https://mikaelj46-mathphysicstool.hf.space/",
"emoji": ""
},
{
"name": "Physical education $ ICT",
"description": "Step-by-step problem solving and practice",
"subjects": ["PE", "ICT"],
"url": "https://mikaelj46-peict.hf.space/",
"emoji": ""
}
]
# Storage functions
def load_codes():
"""Load school codes from storage file"""
if STORAGE_FILE.exists():
with open(STORAGE_FILE, 'r') as f:
return json.load(f)
return {}
def save_codes(codes):
"""Save school codes to storage file"""
with open(STORAGE_FILE, 'w') as f:
json.dump(codes, f, indent=2)
def generate_code():
"""Generate random 8-character school code"""
chars = string.ascii_uppercase + string.digits
return ''.join(random.choice(chars) for _ in range(8))
# Authentication functions
def verify_student(school_code):
"""Verify student school code"""
codes = load_codes()
code = school_code.upper().strip()
if code in codes:
if codes[code]['active']:
# Check expiry
try:
expiry = datetime.fromisoformat(codes[code].get('expiry_date', datetime.now().isoformat()))
if datetime.now() < expiry:
return True, f" Welcome! Access granted with code: {code}", codes[code].get('name', 'Unknown School')
else:
return False, " This school code has expired", None
except:
return True, f" Welcome! Access granted with code: {code}", codes[code].get('name', 'Unknown School')
else:
return False, " This school code has been deactivated", None
return False, " Invalid school code", None
def verify_admin(password):
"""Verify admin password"""
if password == ADMIN_PASSWORD:
return True, " Admin access granted"
return False, " Incorrect admin password"
def create_school_code(school_name, admin_password, expiry_days=365):
"""Admin function to create new school code"""
if admin_password != ADMIN_PASSWORD:
return " Invalid admin password", ""
if not school_name.strip():
return " Please enter a school name", ""
codes = load_codes()
new_code = generate_code()
expiry_date = (datetime.now() + timedelta(days=expiry_days)).isoformat()
codes[new_code] = {
"name": school_name,
"code": new_code,
"active": True,
"created_at": datetime.now().isoformat(),
"expiry_date": expiry_date
}
save_codes(codes)
return f" Code generated successfully!\n\n**School Code:** `{new_code}`\n**School Name:** {school_name}\n**Expires:** {expiry_date[:10]}", new_code
def get_all_codes(admin_password):
"""Get list of all school codes for admin"""
if admin_password != ADMIN_PASSWORD:
return " Invalid admin password"
codes = load_codes()
if not codes:
return " No school codes created yet"
output = f"# All School Codes ({len(codes)})\n\n"
for code, data in codes.items():
status = "🟢 Active" if data['active'] else "🔴 Inactive"
created = datetime.fromisoformat(data['created_at']).strftime("%Y-%m-%d %H:%M")
# Check expiry
try:
expiry = datetime.fromisoformat(data.get('expiry_date', datetime.now().isoformat()))
expiry_str = expiry.strftime("%Y-%m-%d")
if datetime.now() >= expiry:
status = " Expired"
except:
expiry_str = "N/A"
output += f"### {status} `{code}`\n"
output += f"- **School:** {data['name']}\n"
output += f"- **Created:** {created}\n"
output += f"- **Expires:** {expiry_str}\n\n"
return output
def toggle_code_status(school_code, admin_password):
"""Toggle active status of a school code"""
if admin_password != ADMIN_PASSWORD:
return " Invalid admin password"
codes = load_codes()
code = school_code.upper().strip()
if code not in codes:
return " Code not found"
codes[code]['active'] = not codes[code]['active']
save_codes(codes)
status = "activated" if codes[code]['active'] else "deactivated"
return f" Code {code} has been {status}"
def create_platform_links():
"""Create HTML for platform links"""
html = "
"
for platform in PLATFORMS:
subjects = ", ".join(platform['subjects'])
html += f"""
{platform['emoji']} {platform['name']}
{platform['description']}
Subjects: {subjects}
Open Platform →
"""
html += "
"
return html
# Create the Gradio interface
with gr.Blocks(title="IGCSE/GCSE Master Platform", theme=gr.themes.Soft(), css="""
.gradio-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.platform-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 12px rgba(0,0,0,0.15);
}
""") as app:
# Header
gr.Markdown("""
IGCSE/GCSE Master Platform
AI-Powered Learning Platform for All Subjects
🤖 AI Tutors
📝 Past Papers
🎯 Practice Questions
💯 Detailed Feedback
""")
with gr.Tabs() as tabs:
# HOME TAB - REMOVED PLATFORM LINKS
with gr.Tab(" Home"):
gr.Markdown("""
## Welcome to IGCSE/GCSE Master!
Our comprehensive learning platform covers all major subjects with AI tutors, practice questions,
past papers, and deep understanding focus.
### Access Required
To view and access our learning platforms, please log in using the **Student Login** tab with your school code.
---
### ✨ Platform Features:
Justice AI Tutors
Get personalized help with deep understanding focus
Past Papers
Access real exam questions indexed by topic
Practice Questions
Generate unlimited practice with detailed feedback
Detailed Marking
Comprehensive feedback on all answers
---
### Getting Started:
**Students**: Enter your school code in the **Student Login** tab to access all platforms
**Teachers & Admins**: Use your respective tabs to manage content and school codes
""")
# STUDENT LOGIN TAB
with gr.Tab(" Student Login"):
gr.Markdown("""
Student Access
Enter your school code to access all learning platforms
""")
student_school_state = gr.State(None)
with gr.Row():
with gr.Column(scale=1):
pass
with gr.Column(scale=2):
with gr.Group() as student_login_section:
student_code_input = gr.Textbox(
label="Enter Your School Code",
placeholder="8-character code (e.g., ABC12345)",
max_lines=1
)
student_login_btn = gr.Button(" Verify Access", variant="primary", size="lg")
student_status = gr.Markdown("")
with gr.Column(scale=1):
pass
with gr.Group(visible=False) as student_platforms_section:
gr.Markdown("""
Access Granted!
""")
student_info_display = gr.Markdown("")
gr.Markdown("### Choose Your Learning Platform:")
student_platforms_html = gr.HTML()
student_logout_btn = gr.Button("🚪 Logout", variant="secondary")
def student_login(code):
success, message, school_name = verify_student(code)
if success:
return {
student_login_section: gr.update(visible=False),
student_platforms_section: gr.update(visible=True),
student_status: gr.update(value=""),
student_info_display: gr.update(value=f"**School:** {school_name}\n**Code:** {code.upper()}"),
student_platforms_html: gr.update(value=create_platform_links()),
student_school_state: school_name
}
return {
student_status: gr.update(value=message),
student_platforms_section: gr.update(visible=False)
}
def student_logout():
return {
student_login_section: gr.update(visible=True),
student_platforms_section: gr.update(visible=False),
student_code_input: gr.update(value=""),
student_status: gr.update(value=""),
student_school_state: None
}
student_login_btn.click(
student_login,
inputs=[student_code_input],
outputs=[student_login_section, student_platforms_section, student_status,
student_info_display, student_platforms_html, student_school_state]
)
student_logout_btn.click(
student_logout,
outputs=[student_login_section, student_platforms_section, student_code_input,
student_status, student_school_state]
)
# ADMIN TAB
with gr.Tab(" Admin Panel"):
gr.Markdown("""
Administrator Panel
Manage school codes and platform access
""")
admin_password_global = gr.Textbox(
label="Admin Password",
type="password",
placeholder="Enter admin password"
)
admin_verify_btn = gr.Button(" Login", variant="primary")
admin_login_status = gr.Markdown("")
with gr.Group(visible=False) as admin_tools:
gr.Markdown("### Admin Access Granted")
admin_logout_btn = gr.Button(" Logout", variant="secondary")
with gr.Tabs():
with gr.Tab(" Create Code"):
gr.Markdown("### Generate New School Code")
with gr.Row():
school_name_input = gr.Textbox(
label="School/Institution Name",
placeholder="Enter school or group name"
)
expiry_days_slider = gr.Slider(
minimum=30,
maximum=730,
value=365,
step=30,
label="Validity (days)"
)
create_code_btn = gr.Button(" Generate Code", variant="primary")
create_status = gr.Markdown("")
with gr.Tab("📋 Manage Codes"):
gr.Markdown("### All School Codes")
view_codes_btn = gr.Button(" View All Codes", variant="secondary")
codes_display = gr.Markdown("")
gr.Markdown("---")
gr.Markdown("### Activate/Deactivate Code")
with gr.Row():
toggle_code_input = gr.Textbox(
label="School Code",
placeholder="Enter code to toggle"
)
toggle_btn = gr.Button(" Toggle Status", variant="secondary")
toggle_status = gr.Markdown("")
def admin_login(password):
success, message = verify_admin(password)
if success:
return {
admin_tools: gr.update(visible=True),
admin_login_status: gr.update(value=message),
admin_password_global: gr.update(visible=False),
admin_verify_btn: gr.update(visible=False)
}
return {
admin_login_status: gr.update(value=message),
admin_tools: gr.update(visible=False)
}
def admin_logout_fn():
return {
admin_tools: gr.update(visible=False),
admin_password_global: gr.update(visible=True, value=""),
admin_verify_btn: gr.update(visible=True),
admin_login_status: gr.update(value="")
}
admin_verify_btn.click(
admin_login,
inputs=[admin_password_global],
outputs=[admin_tools, admin_login_status, admin_password_global, admin_verify_btn]
)
admin_logout_btn.click(
admin_logout_fn,
outputs=[admin_tools, admin_password_global, admin_verify_btn, admin_login_status]
)
create_code_btn.click(
lambda name, days, pwd: create_school_code(name, pwd, days),
inputs=[school_name_input, expiry_days_slider, admin_password_global],
outputs=[create_status]
)
view_codes_btn.click(
get_all_codes,
inputs=[admin_password_global],
outputs=[codes_display]
)
toggle_btn.click(
toggle_code_status,
inputs=[toggle_code_input, admin_password_global],
outputs=[toggle_status]
)
# Footer
gr.Markdown("""
---
© @mikael Jutice IGCSE/GCSE Master Platform
Powered by Justice AI
system ensures 24/7 availability
""")
# Launch the app
if __name__ == "__main__":
app.launch()