diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 3d6501c..afd339e 100644 Binary files a/config/__pycache__/__init__.cpython-311.pyc and b/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 5be02db..daefbd7 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 28817aa..5cc9909 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 79ce690..2fc44a7 100644 Binary files a/config/__pycache__/wsgi.cpython-311.pyc and b/config/__pycache__/wsgi.cpython-311.pyc differ diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 3b7774e..5aa352b 100644 Binary files a/core/__pycache__/__init__.cpython-311.pyc and b/core/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index cd6f855..7282dec 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 6435d92..2762cf2 100644 Binary files a/core/__pycache__/apps.cpython-311.pyc and b/core/__pycache__/apps.cpython-311.pyc differ diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index e85aca4..79369cc 100644 Binary files a/core/__pycache__/context_processors.cpython-311.pyc and b/core/__pycache__/context_processors.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b..88861c0 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 1f807fa..142d461 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 6867ddf..cf2ae9f 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..d77eecd --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,53 @@ +# Generated by Django 5.2.7 on 2025-12-10 14:54 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Assignment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255)), + ('description', models.TextField()), + ('due_date', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='Exercise', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('question', models.TextField()), + ('answer', models.TextField()), + ('assignment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='core.assignment')), + ], + ), + migrations.CreateModel( + name='Hint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('hint_text', models.TextField()), + ('exercise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hints', to='core.exercise')), + ], + ), + migrations.CreateModel( + name='Submission', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('submitted_answer', models.TextField()), + ('is_correct', models.BooleanField(default=False)), + ('exercise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.exercise')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..7b25000 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 58b1c14..96e163f 100644 Binary files a/core/migrations/__pycache__/__init__.cpython-311.pyc and b/core/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..b8e34ee 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,34 @@ from django.db import models +from django.contrib.auth.models import User -# Create your models here. +class Assignment(models.Model): + title = models.CharField(max_length=255) + description = models.TextField() + due_date = models.DateTimeField() + + def __str__(self): + return self.title + +class Exercise(models.Model): + assignment = models.ForeignKey(Assignment, related_name='exercises', on_delete=models.CASCADE) + question = models.TextField() + answer = models.TextField() + + def __str__(self): + return self.question + +class Submission(models.Model): + exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE) + student = models.ForeignKey(User, on_delete=models.CASCADE) + submitted_answer = models.TextField() + is_correct = models.BooleanField(default=False) + + def __str__(self): + return f'{self.student.username} - {self.exercise.question}' + +class Hint(models.Model): + exercise = models.ForeignKey(Exercise, related_name='hints', on_delete=models.CASCADE) + hint_text = models.TextField() + + def __str__(self): + return self.hint_text diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..b186626 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -14,12 +14,17 @@ {% endif %} {% load static %} + + + + {% block head %}{% endblock %} {% block content %}{% endblock %} + {% block extra_js %}{% endblock %} diff --git a/core/templates/core/assignment_detail.html b/core/templates/core/assignment_detail.html new file mode 100644 index 0000000..9caae81 --- /dev/null +++ b/core/templates/core/assignment_detail.html @@ -0,0 +1,63 @@ +{% extends 'base.html' %} + +{% block content %} +
+

{{ assignment.title }}

+

{{ assignment.description }}

+
+

Exercises

+ {% for exercise in assignment.exercises.all %} +
+
+

{{ exercise.question }}

+
+ {% csrf_token %} + +
+ +
+ + + +
+ +
+
+ {% endfor %} +
+ +{% block extra_js %} + +{% endblock %} + +{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..7a5d234 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,145 +1,53 @@ {% extends "base.html" %} +{% load static %} -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} - - - - -{% endblock %} +{% block title %}CodeCraft - Your Coding Challenge Platform{% endblock %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
+ +
+
+
+
+

Welcome to CodeCraft

+

The ultimate platform for coding challenges and assignments. Sharpen your skills, compete with peers, and get feedback from instructors.

+ +
+
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
-
- -{% endblock %} \ No newline at end of file + + +
+
+
+
+
+
+

Diverse Challenges

+

From simple algorithms to complex data structures, we have a wide range of challenges to test your skills.

+
+
+
+
+
+

Hint System

+

Stuck on a problem? Our hint system will guide you towards the solution without giving it away.

+
+
+
+
+
+

Instructor Support

+

Teachers can create assignments, provide feedback, and even queue up to help students in real-time.

+
+
+
+
+
+ + +{% endblock %} diff --git a/core/templates/core/student_dashboard.html b/core/templates/core/student_dashboard.html new file mode 100644 index 0000000..dc1d234 --- /dev/null +++ b/core/templates/core/student_dashboard.html @@ -0,0 +1,18 @@ +{% extends 'base.html' %} + +{% block content %} +
+

Student Dashboard

+
+ {% for assignment in assignments %} + +
+
{{ assignment.title }}
+ Due: {{ assignment.due_date }} +
+

{{ assignment.description }}

+
+ {% endfor %} +
+
+{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..ee00cbc 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,13 @@ from django.urls import path -from .views import home +from .views import home, student_dashboard, assignment_detail, get_hint, call_teacher + +app_name = "core" urlpatterns = [ path("", home, name="home"), + path("dashboard/", student_dashboard, name="student_dashboard"), + path("assignment//", assignment_detail, name="assignment_detail"), + path("hint//", get_hint, name="get_hint"), + path("call-teacher/", call_teacher, name="call_teacher"), ] diff --git a/core/views.py b/core/views.py index c9aed12..9a8f107 100644 --- a/core/views.py +++ b/core/views.py @@ -1,13 +1,16 @@ import os import platform +import random from django import get_version as django_version -from django.shortcuts import render +from django.http import JsonResponse +from django.shortcuts import render, get_object_or_404 from django.utils import timezone +from .models import Assignment, Exercise, Hint, Submission def home(request): - """Render the landing screen with loader and environment details.""" + """Render the landing screen with loader and environment details.""" host_name = request.get_host().lower() agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" now = timezone.now() @@ -23,3 +26,44 @@ def home(request): "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), } return render(request, "core/index.html", context) + +def student_dashboard(request): + assignments = Assignment.objects.all() + return render(request, "core/student_dashboard.html", {"assignments": assignments}) + +def assignment_detail(request, assignment_id): + assignment = get_object_or_404(Assignment, pk=assignment_id) + if request.method == 'POST': + exercise_id = request.POST.get('exercise_id') + submitted_answer = request.POST.get('answer') + exercise = get_object_or_404(Exercise, pk=exercise_id) + submission, created = Submission.objects.get_or_create( + exercise=exercise, + student=request.user, + defaults={'submitted_answer': submitted_answer} + ) + if not created: + submission.submitted_answer = submitted_answer + submission.save() + + if submission.submitted_answer.lower() == exercise.answer.lower(): + submission.is_correct = True + submission.save() + # You might want to add a message here + else: + submission.is_correct = False + submission.save() + + return render(request, "core/assignment_detail.html", {"assignment": assignment}) + +def get_hint(request, exercise_id): + exercise = get_object_or_404(Exercise, pk=exercise_id) + hints = exercise.hints.all() + if hints: + hint = random.choice(hints) + return JsonResponse({'hint': hint.hint_text}) + return JsonResponse({'hint': 'No hints available for this exercise.'}) + +def call_teacher(request): + # In a real application, this would trigger a notification to the teacher + return JsonResponse({'message': 'A teacher has been called to help you.'}) diff --git a/static/css/custom.css b/static/css/custom.css index 925f6ed..14aa7b7 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -1,4 +1,99 @@ /* Custom styles for the application */ -body { - font-family: system-ui, -apple-system, sans-serif; +:root { + --primary-color: #4285F4; + --secondary-color: #FBBC05; + --accent-color: #34A853; + --neutral-light-gray: #F8F9FA; + --neutral-dark-text: #202124; + --font-headings: 'Poppins', sans-serif; + --font-body: 'Roboto', sans-serif; } + +body { + font-family: var(--font-body); + color: var(--neutral-dark-text); + background-color: #fff; + line-height: 1.6; +} + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-headings); + font-weight: 700; +} + +.btn { + font-family: var(--font-headings); + font-weight: 600; + border-radius: 8px; + padding: 12px 28px; + text-transform: uppercase; + letter-spacing: 1px; + transition: all 0.3s ease; +} + +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + color: #fff; +} + +.btn-primary:hover { + background-color: #3367D6; + border-color: #3367D6; +} + +.btn-secondary { + background-color: var(--secondary-color); + border-color: var(--secondary-color); + color: var(--neutral-dark-text); +} + +.btn-secondary:hover { + background-color: #F9A825; + border-color: #F9A825; +} + +.hero { + padding: 100px 0; + background: linear-gradient(135deg, #E3F2FD, #FFFFFF); + text-align: center; + position: relative; + overflow: hidden; +} + +.hero h1 { + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 20px; + color: var(--neutral-dark-text); +} + +.hero .lead { + font-size: 1.25rem; + margin-bottom: 40px; + color: #5f6368; +} + +.features-section { + padding: 80px 0; +} + +.feature-card { + background-color: var(--neutral-light-gray); + border: none; + border-radius: 12px; + padding: 30px; + text-align: center; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.feature-card:hover { + transform: translateY(-10px); + box-shadow: 0 10px 20px rgba(0,0,0,0.05); +} + +.feature-card .icon { + font-size: 3rem; + color: var(--primary-color); + margin-bottom: 20px; +} \ No newline at end of file diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 108056f..14aa7b7 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -1,21 +1,99 @@ - +/* Custom styles for the application */ :root { - --bg-color-start: #6a11cb; - --bg-color-end: #2575fc; - --text-color: #ffffff; - --card-bg-color: rgba(255, 255, 255, 0.01); - --card-border-color: rgba(255, 255, 255, 0.1); + --primary-color: #4285F4; + --secondary-color: #FBBC05; + --accent-color: #34A853; + --neutral-light-gray: #F8F9FA; + --neutral-dark-text: #202124; + --font-headings: 'Poppins', sans-serif; + --font-body: 'Roboto', sans-serif; } + body { - margin: 0; - font-family: 'Inter', sans-serif; - background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); - color: var(--text-color); - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; - text-align: center; - overflow: hidden; - position: relative; + font-family: var(--font-body); + color: var(--neutral-dark-text); + background-color: #fff; + line-height: 1.6; } + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-headings); + font-weight: 700; +} + +.btn { + font-family: var(--font-headings); + font-weight: 600; + border-radius: 8px; + padding: 12px 28px; + text-transform: uppercase; + letter-spacing: 1px; + transition: all 0.3s ease; +} + +.btn-primary { + background-color: var(--primary-color); + border-color: var(--primary-color); + color: #fff; +} + +.btn-primary:hover { + background-color: #3367D6; + border-color: #3367D6; +} + +.btn-secondary { + background-color: var(--secondary-color); + border-color: var(--secondary-color); + color: var(--neutral-dark-text); +} + +.btn-secondary:hover { + background-color: #F9A825; + border-color: #F9A825; +} + +.hero { + padding: 100px 0; + background: linear-gradient(135deg, #E3F2FD, #FFFFFF); + text-align: center; + position: relative; + overflow: hidden; +} + +.hero h1 { + font-size: 3.5rem; + font-weight: 700; + margin-bottom: 20px; + color: var(--neutral-dark-text); +} + +.hero .lead { + font-size: 1.25rem; + margin-bottom: 40px; + color: #5f6368; +} + +.features-section { + padding: 80px 0; +} + +.feature-card { + background-color: var(--neutral-light-gray); + border: none; + border-radius: 12px; + padding: 30px; + text-align: center; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.feature-card:hover { + transform: translateY(-10px); + box-shadow: 0 10px 20px rgba(0,0,0,0.05); +} + +.feature-card .icon { + font-size: 3rem; + color: var(--primary-color); + margin-bottom: 20px; +} \ No newline at end of file