From eb00b2d19214f3b54042d9324ed482984f9962c7 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 10 Dec 2025 14:57:30 +0000 Subject: [PATCH] v01 Student Portal - until Call Teacher --- config/__pycache__/__init__.cpython-311.pyc | Bin 159 -> 159 bytes config/__pycache__/settings.cpython-311.pyc | Bin 5552 -> 5552 bytes config/__pycache__/urls.cpython-311.pyc | Bin 1557 -> 1557 bytes config/__pycache__/wsgi.cpython-311.pyc | Bin 679 -> 679 bytes core/__pycache__/__init__.cpython-311.pyc | Bin 157 -> 157 bytes core/__pycache__/admin.cpython-311.pyc | Bin 212 -> 212 bytes core/__pycache__/apps.cpython-311.pyc | Bin 524 -> 524 bytes .../context_processors.cpython-311.pyc | Bin 763 -> 763 bytes core/__pycache__/models.cpython-311.pyc | Bin 209 -> 2912 bytes core/__pycache__/urls.cpython-311.pyc | Bin 347 -> 789 bytes core/__pycache__/views.cpython-311.pyc | Bin 1364 -> 4048 bytes core/migrations/0001_initial.py | 53 +++++ .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 2799 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 168 -> 168 bytes core/models.py | 33 ++- core/templates/base.html | 5 + core/templates/core/assignment_detail.html | 63 ++++++ core/templates/core/index.html | 188 +++++------------- core/templates/core/student_dashboard.html | 18 ++ core/urls.py | 8 +- core/views.py | 48 ++++- static/css/custom.css | 99 ++++++++- staticfiles/css/custom.css | 112 +++++++++-- 23 files changed, 464 insertions(+), 163 deletions(-) create mode 100644 core/migrations/0001_initial.py create mode 100644 core/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 core/templates/core/assignment_detail.html create mode 100644 core/templates/core/student_dashboard.html diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 3d6501c67fa5c80fdda8a8ee57862699aabd319d..afd339e845fc4386235e2380bc3e5a25403b976c 100644 GIT binary patch delta 20 acmbQwIG>ScIWI340}veOu*{suGZ_Fe!38n^ delta 20 acmbQwIG>ScIWI340}vQ{e#)50GZ_Fd1qB`e diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 5be02db206d695487566bb415cb6b1e287631fb4..daefbd7156f9f7e6b9b2d45685e1ab85533f6ba4 100644 GIT binary patch delta 20 acmdm>y+NCMIWI340}veOu-wSKR1^R@VFiQ$ delta 20 acmdm>y+NCMIWI340}#CB)!4|rR1^R>Wd$Vw diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 28817aa35512298e6df4bc5c0b678c917f71e36c..5cc9909ffeac5ed4f5a1a075354e9fae4839eb06 100644 GIT binary patch delta 20 acmbQrGnI#XIWI340}veOu-wSa#RdQ{z653f delta 20 acmbQrGnI#XIWI340}#kssBGlsVgmpw00UkC diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 79ce690f602e05f6bfa8a8e253edcb377296b788..2fc44a7a7633ccfa24c8889dd89e383090736d3a 100644 GIT binary patch delta 21 bcmZ3^x}23~IWI340}veOu*}@ZGn)wjIb8*G delta 21 bcmZ3^x}23~IWI340}vQ{e#+R$Gn)wjH;n~g diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 3b7774ea363dc0bd4dc92284fe89acea2051acd3..5aa352b22d230de906d0e54a9ab30bd40f072240 100644 GIT binary patch delta 20 acmbQsIG2%UIWI340}veOu*{suGZ6qWa|J8_ delta 20 acmbQsIG2%UIWI340}vQ{e#)50GZ6qUw*?pg diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index cd6f855b12f4883b1ba9de01c54245c53aacd714..7282dec58e74cdaa425735b865e6deb970e8691e 100644 GIT binary patch delta 20 acmcb@c!iN?IWI340}veOu*{sua{>T4)CJK1 delta 20 acmcb@c!iN?IWI340}y=Q^($i{&j|oPLI(N( diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 6435d92a257f85ac41d6fd22a9e528c3da4a1ec5..2762cf2d1498700a13433503ab4d419ce5e523a0 100644 GIT binary patch delta 20 acmeBS>0#kn&dbZi00aj*EHfAKFaZEA`UH^x delta 20 acmeBS>0#kn&dbZi00hRKpE4HmFaZE9J_LOL diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index e85aca40f0f4920ee0b279872e312058145a2a15..79369cc5133712911ed38932253e007a8a459cba 100644 GIT binary patch delta 20 acmey(`kR$|IWI340}veOu-wS~fe8RWt_B7G delta 20 acmey(`kR$|IWI340}$+-qq33v0}}v1j0OGx diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b9d5171b2bb0d207f045e07f9fbbb95a64..88861c03e7d93005a73fe579fb50b42a6567a32f 100644 GIT binary patch literal 2912 zcmbuB&u(A(e8-0f_^ulv79qha6DFpU^`OYiSSGUVB2l1ceiq_Ptr#i4!M9>e&1B{CGR_ zcHU>+`e`f{CQzRK`epfRA0dBXqh0*1%I@z_c}!HI3Kdcn3W9)jPsLO97Q6!SkSj#> z{z6nA6&7F)w`_O`c?OqT3Vv?o2dls_Rsn7m1S|0vt01=ufmQezD^ZQil3er^I*=2b zK((&YiUu{`Ese5L%Q61bc5|0O^D&{MAgH9^@eu0WdmvSK?%5FFq2O{0J``94+U*Uf zJZm>d0o;U9vE6ZCG=y7L2&+DD((i;XX*(-q0^~7yNEYDNEwf}xn1NgUdRec~EqGLoR^~LkBlC7_e7;_#<3`b_>Bcx+q9sGG zv+?_N_M>)JDbev#ozZc3m&WcsaDuX|=}eZFQ+vLRwfaIZqlVy^q$!rq+0XDAhSgrWaVXmVa*(`8ywS%kN5(j}d@orp@c5-Z=; z%k`QQ%PTs)S*}udOjHdjtI)+HxND0r+y@p%!ANjH3bk)R%+9A79ax#RqXU~>D>~YU zj@r>tbE=uju6<;uvW?WRofIJKMOzwbNM~*7ta)|EC;0n!$YF68#r3*C>YNx8 zMvelB`c+{+Hh>lE$G)@jAK)B|RhVNHX<;Q!EdlCfjXEI+IIn429w*9Z1vXISfpS9i znhZyS>h#??V;FoOO}uAN4Wq=O(BYEi#sY)0oM^A#1}BMDd*J+Ji35BqXL3=7V=RSo z0);aYo(3r4U|gpUcwn929lSgtzj%!2CAd1Jll+R%bu`xhFZp%7HGNmh zfP#M>RAYm%Y8QLQz9`!XEQB}9I=p#$lM}@y+RR{z*_XY3w#2~}9g%mYgXgNxVWOVF z{tO3D@M*LekY2%l8T{k?pBF8u(2xqYRDf_NGHU@lk!d8db|PzjgYo+i!*@{J(BT3z zxsVf57nIta`j}dDvu%H?U8>h~RxXYyhCV;${v+U2JN_H^C(3=#@^s4K&SrZc24q%h_%Y=G)Yb5iY! ZIDle|KwK<4IhRX{`vQXu5EZcjMF1{kAf*5R diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 1f807fae1897c89361c99c5e868a26d00799b73f..142d4618507c85c7cb9f4097d1bb888a6c71dab7 100644 GIT binary patch literal 789 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 X9y;zJKZcP#G(?dLmekv*buIq^BZQ*n delta 461 zcmZWkyH3L}6t(kk)0RFE5_I4p)F}&MW2u0J4Y9CALa3_U2TEeNc0gij2X=%y@Ck^8 zg^9n&zz}6(W$WCD>$FS7y;sNQ99hTL>E3sx{#L712-eqNKJ3^p_15?l)hpqI(~ty< zlLi#E6Eomj6qaOLmYjshArKPBPC6wm4ino6fB9irOn!hupe2EsdOBznYvah+l9A;6 zFg@hZLwn;!dgGLqA)V3uY#LWyjacSSmR>EH=z}k9x``+89Z@=Ar z(r;~T5f0kpU&f4IC64=tb^I1;DlfkU)JlutnP!8k*JhKH#!Ez`UDvLRh z=LGH&rw4!H^biUa!+xU80LMLntI={{ouA{9;&ax$p5&?IAlEg_f|C?zq-+#y%{463 zp<>z6QOU_S$9cE*X6NN!knbUfJUlr;=W_vpL&2htnM2}h&*$O!a5Y+i&q-da>|1m} zXQLy?g#+i-`4MwFasc+DpNzdrKlUE%fdkg1`y;UT9DqIM`8)U63~u$lv(G+# ze#f@rZ|*SIm5EPf>-DqtZr(!ZZPp6G+!4JGYCu1gXZ`a&Pa|2!F$!iGnJyI!eTE8G zrjkM0s#RS}&D%(GkxpAGwo%sXHT5o9qq2i+Ln|5g5p7*Y_JZXg)zr#}hFrrfq38bs zdr)8^Wo=b0A+z8v(H0#!dE2P45u@t?Iz;_2f}1sU8wlr4dzyLR&2%&|6jYUR5hGDxeoOOv43!ZC3wir?a9}D%t`B z>ZpQD$dq5RSy`v;*<16M)mwAZH`Uo2Q`6UI>t2L`9NIGJE#53E=QgX*wDqD<$ilMD zFt({Yxun@mbsm^#sBKfg*St|ijc#NH=!NZZ71mwUi<()msGu*v8Zv?zC*jHL++=oY z8nRnf32A0?pjAQ5SIT4VB|M#b^>up5Dx-9Dp=!F-G!UEzEOvUuvhO+-EsxTS`1Jm( zD4oe@rdB*oP4N00@wEh-DqB#nU97#!6-<+Kpo;H_npS$y#iP#D=hvg6ZJC z%*Hb5%WR*0Iz}e0l8JdT@dLiQT<5qS`B?#O{nv#Tp4{~$SfV$CgD`e|0LEUNNNp^V zM5>m^kVFP6!yX$chC8)=^l3L4yF$iplCc~%D)884ewyJ)%rHD40S`!q=aNtl2N`E! z#uH;7(XN1XK-J()|VxHS*%?AU!baq z<5n$hk+_AG%1*Qg_YQ5$klvwf@u^HkFO$*l$msX@&LX+9jC)sVy(^@51uLud7LnnX z8GaDEOw`W}bcpNUu%A8Q@86_EyBmior7xr!A6zN_MA@ey3@WB~*iw1RTx=Y7d2fVQ z8N4IiI1=M5ub2EhXs@L6jmq+seF3`c3(Rpr)B`-v!wKO(!(4ykzvC;fSx#W?J^#8m W#EW(AUGX47l;ba$WA{B?57mF(f61l* literal 0 HcmV?d00001 diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 58b1c14eb06fea9cfb9a0d59788218572a75b51c..96e163f33240ed10969b44c78a3f7306c108b776 100644 GIT binary patch delta 20 acmZ3%xPp;qIWI340}veOu*{suGY0@OAO%eT delta 20 acmZ3%xPp;qIWI340}vQ{e#)50GY0@MWCb|@ 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" }} -

-
-
-
- Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC) -
-{% 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

+ +
+{% 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