From 09c35101323404163574858ab93f342ddbd7f32a Mon Sep 17 00:00:00 2001 From: kernel-404 Date: Sat, 28 Feb 2026 00:21:31 +0530 Subject: [PATCH 1/3] feat(virtual-lab): improve subject nav and restructure home labs add subject-based hover menus with direct lab links move physics labs into a dedicated physics page normalize chemistry routes update home to subject cards + code editor entry --- .../templates/virtual_lab/home.html | 69 +++++++++--------- .../templates/virtual_lab/layout.html | 34 ++++----- .../templates/virtual_lab/physics/index.html | 51 +++++++++++++ web/virtual_lab/urls.py | 14 ++-- web/virtual_lab/views.py | 72 +++++++++++++++---- 5 files changed, 169 insertions(+), 71 deletions(-) create mode 100644 web/virtual_lab/templates/virtual_lab/physics/index.html diff --git a/web/virtual_lab/templates/virtual_lab/home.html b/web/virtual_lab/templates/virtual_lab/home.html index 159d14f36..a22ceeb6f 100644 --- a/web/virtual_lab/templates/virtual_lab/home.html +++ b/web/virtual_lab/templates/virtual_lab/home.html @@ -2,47 +2,46 @@ {% extends "virtual_lab/layout.html" %} {% load static %} +{% load i18n %} {% block virtual_lab_content %}

Welcome to the Alpha Science Lab

-

- Dive into interactive experiments and deepen your understanding of fundamental concepts. Click on any card below to begin. -

- diff --git a/web/virtual_lab/templates/virtual_lab/layout.html b/web/virtual_lab/templates/virtual_lab/layout.html index dd8ebcdc3..e3747b75e 100644 --- a/web/virtual_lab/templates/virtual_lab/layout.html +++ b/web/virtual_lab/templates/virtual_lab/layout.html @@ -14,25 +14,25 @@
diff --git a/web/virtual_lab/templates/virtual_lab/physics/index.html b/web/virtual_lab/templates/virtual_lab/physics/index.html new file mode 100644 index 000000000..4f44e27c7 --- /dev/null +++ b/web/virtual_lab/templates/virtual_lab/physics/index.html @@ -0,0 +1,51 @@ +{% extends "virtual_lab/layout.html" %} + +{% load i18n %} + +{% block virtual_lab_content %} + +{% endblock virtual_lab_content %} diff --git a/web/virtual_lab/urls.py b/web/virtual_lab/urls.py index bd8b6714c..65f90d989 100644 --- a/web/virtual_lab/urls.py +++ b/web/virtual_lab/urls.py @@ -6,6 +6,7 @@ evaluate_code, ph_indicator_view, physics_electrical_circuit_view, + physics_home, physics_inclined_view, physics_mass_spring_view, physics_pendulum_view, @@ -21,17 +22,18 @@ urlpatterns = [ path("", virtual_lab_home, name="virtual_lab_home"), + path("physics/", physics_home, name="physics_home"), path("physics/pendulum/", physics_pendulum_view, name="physics_pendulum"), path("physics/projectile/", physics_projectile_view, name="physics_projectile"), path("physics/inclined/", physics_inclined_view, name="physics_inclined"), path("physics/mass_spring/", physics_mass_spring_view, name="physics_mass_spring"), path("physics/circuit/", physics_electrical_circuit_view, name="physics_electrical_circuit"), - path("virtual_lab/chemistry/", chemistry_home, name="chemistry_home"), - path("virtual_lab/chemistry/titration/", titration_view, name="titration"), - path("virtual_lab/chemistry/reaction-rate/", reaction_rate_view, name="reaction_rate"), - path("virtual_lab/chemistry/solubility/", solubility_view, name="solubility"), - path("virtual_lab/chemistry/precipitation/", precipitation_view, name="precipitation"), - path("virtual_lab/chemistry/ph-indicator/", ph_indicator_view, name="ph_indicator"), + path("chemistry/", chemistry_home, name="chemistry_home"), + path("chemistry/titration/", titration_view, name="titration"), + path("chemistry/reaction-rate/", reaction_rate_view, name="reaction_rate"), + path("chemistry/solubility/", solubility_view, name="solubility"), + path("chemistry/precipitation/", precipitation_view, name="precipitation"), + path("chemistry/ph-indicator/", ph_indicator_view, name="ph_indicator"), path("code-editor/", code_editor_view, name="code_editor"), path("evaluate-code/", evaluate_code, name="evaluate_code"), ] diff --git a/web/virtual_lab/views.py b/web/virtual_lab/views.py index cee652a8e..7c92efece 100644 --- a/web/virtual_lab/views.py +++ b/web/virtual_lab/views.py @@ -6,75 +6,121 @@ import requests from django.http import JsonResponse from django.shortcuts import render +from django.utils.translation import gettext_lazy as _ from django.views.decorators.http import require_POST logger = logging.getLogger(__name__) +def build_virtual_lab_subjects(): + """Return subject and lab metadata for virtual lab navigation and landing pages.""" + return [ + { + "key": "physics", + "label": _("Physics"), + "url_name": "virtual_lab:physics_home", + "labs": [ + {"label": _("Pendulum Motion"), "url_name": "virtual_lab:physics_pendulum"}, + {"label": _("Projectile Motion"), "url_name": "virtual_lab:physics_projectile"}, + {"label": _("Inclined Plane"), "url_name": "virtual_lab:physics_inclined"}, + {"label": _("Mass-Spring Oscillation"), "url_name": "virtual_lab:physics_mass_spring"}, + {"label": _("Basic Electrical Circuit"), "url_name": "virtual_lab:physics_electrical_circuit"}, + ], + }, + { + "key": "chemistry", + "label": _("Chemistry"), + "url_name": "virtual_lab:chemistry_home", + "labs": [ + {"label": _("Acid-Base Titration"), "url_name": "virtual_lab:titration"}, + {"label": _("Reaction Rate"), "url_name": "virtual_lab:reaction_rate"}, + {"label": _("Solubility & Saturation"), "url_name": "virtual_lab:solubility"}, + {"label": _("Precipitation Reaction"), "url_name": "virtual_lab:precipitation"}, + {"label": _("pH Indicator"), "url_name": "virtual_lab:ph_indicator"}, + ], + }, + ] + + +def render_virtual_lab_page(request, template_name, extra_context=None): + """Render a virtual lab template with common navigation context.""" + context = { + "virtual_lab_subjects": build_virtual_lab_subjects(), + } + if extra_context: + context.update(extra_context) + return render(request, template_name, context) + + def virtual_lab_home(request): """ Renders the Virtual Lab home page (home.html). """ - return render(request, "virtual_lab/home.html") + return render_virtual_lab_page(request, "virtual_lab/home.html") + + +def physics_home(request): + """Render the Physics lab overview page.""" + return render_virtual_lab_page(request, "virtual_lab/physics/index.html") def physics_pendulum_view(request): """ Renders the Pendulum Motion simulation page (physics/pendulum.html). """ - return render(request, "virtual_lab/physics/pendulum.html") + return render_virtual_lab_page(request, "virtual_lab/physics/pendulum.html") def physics_projectile_view(request): """ Renders the Projectile Motion simulation page (physics/projectile.html). """ - return render(request, "virtual_lab/physics/projectile.html") + return render_virtual_lab_page(request, "virtual_lab/physics/projectile.html") def physics_inclined_view(request): """ Renders the Inclined Plane simulation page (physics/inclined.html). """ - return render(request, "virtual_lab/physics/inclined.html") + return render_virtual_lab_page(request, "virtual_lab/physics/inclined.html") def physics_mass_spring_view(request): """ Renders the Mass-Spring Oscillation simulation page (physics/mass_spring.html). """ - return render(request, "virtual_lab/physics/mass_spring.html") + return render_virtual_lab_page(request, "virtual_lab/physics/mass_spring.html") def physics_electrical_circuit_view(request): """ Renders the Electrical Circuit simulation page (physics/circuit.html). """ - return render(request, "virtual_lab/physics/circuit.html") + return render_virtual_lab_page(request, "virtual_lab/physics/circuit.html") def chemistry_home(request): - return render(request, "virtual_lab/chemistry/index.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/index.html") def titration_view(request): - return render(request, "virtual_lab/chemistry/titration.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/titration.html") def reaction_rate_view(request): - return render(request, "virtual_lab/chemistry/reaction_rate.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/reaction_rate.html") def solubility_view(request): - return render(request, "virtual_lab/chemistry/solubility.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/solubility.html") def precipitation_view(request): - return render(request, "virtual_lab/chemistry/precipitation.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/precipitation.html") def ph_indicator_view(request): - return render(request, "virtual_lab/chemistry/ph_indicator.html") + return render_virtual_lab_page(request, "virtual_lab/chemistry/ph_indicator.html") # Piston’s public execute endpoint (rate-limited to 5 req/s) :contentReference[oaicite:0]{index=0} @@ -89,7 +135,7 @@ def ph_indicator_view(request): def code_editor_view(request): - return render(request, "virtual_lab/code_editor/code_editor.html") + return render_virtual_lab_page(request, "virtual_lab/code_editor/code_editor.html") @require_POST From af253592daa2f58984403814f78a866f35ace283 Mon Sep 17 00:00:00 2001 From: kernel-404 Date: Sat, 28 Feb 2026 00:58:17 +0530 Subject: [PATCH 2/3] address coderabbit requested changes --- .../templates/virtual_lab/home.html | 8 +++---- .../templates/virtual_lab/layout.html | 22 ++++++++++++++----- .../templates/virtual_lab/physics/index.html | 2 +- web/virtual_lab/views.py | 16 +++++++++++--- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/web/virtual_lab/templates/virtual_lab/home.html b/web/virtual_lab/templates/virtual_lab/home.html index a22ceeb6f..c3f532715 100644 --- a/web/virtual_lab/templates/virtual_lab/home.html +++ b/web/virtual_lab/templates/virtual_lab/home.html @@ -14,7 +14,7 @@

Welcom {% for subject in virtual_lab_subjects %} {% if subject.key == "physics" %} + class="block bg-blue-50 dark:bg-blue-900 border border-blue-200 dark:border-blue-700 rounded-lg p-6 shadow hover:shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-300 dark:focus:ring-blue-400 dark:focus:ring-offset-gray-800">

{{ subject.label }}

{% blocktrans with count=subject.labs|length %}Explore {{ count }} labs{% endblocktrans %} @@ -22,7 +22,7 @@

{{ subj {% elif subject.key == "chemistry" %} + class="block bg-green-50 dark:bg-green-900 border border-green-200 dark:border-green-700 rounded-lg p-6 shadow hover:shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-300 dark:focus:ring-green-400 dark:focus:ring-offset-gray-800">

{{ subject.label }}

{% blocktrans with count=subject.labs|length %}Explore {{ count }} labs{% endblocktrans %} @@ -30,7 +30,7 @@

{{ su {% else %} + class="block bg-indigo-50 dark:bg-indigo-900 border border-indigo-200 dark:border-indigo-700 rounded-lg p-6 shadow hover:shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-300 dark:focus:ring-indigo-400 dark:focus:ring-offset-gray-800">

{{ subject.label }}

{% blocktrans with count=subject.labs|length %}Explore {{ count }} labs{% endblocktrans %} @@ -39,7 +39,7 @@

{{ {% endif %} {% endfor %} + class="block bg-teal-50 dark:bg-teal-900 border border-teal-200 dark:border-teal-700 rounded-lg p-6 shadow hover:shadow-md transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-300 dark:focus:ring-teal-400 dark:focus:ring-offset-gray-800">

{% trans "Code Editor" %}

{% trans "Write and run code directly from the virtual lab." %}

diff --git a/web/virtual_lab/templates/virtual_lab/layout.html b/web/virtual_lab/templates/virtual_lab/layout.html index e3747b75e..a07ff657a 100644 --- a/web/virtual_lab/templates/virtual_lab/layout.html +++ b/web/virtual_lab/templates/virtual_lab/layout.html @@ -14,17 +14,29 @@

diff --git a/web/virtual_lab/templates/virtual_lab/physics/index.html b/web/virtual_lab/templates/virtual_lab/physics/index.html index 4f44e27c7..2756740f8 100644 --- a/web/virtual_lab/templates/virtual_lab/physics/index.html +++ b/web/virtual_lab/templates/virtual_lab/physics/index.html @@ -3,7 +3,7 @@ {% load i18n %} {% block virtual_lab_content %} -
+

{% trans "Physics Experiments" %}

diff --git a/web/virtual_lab/views.py b/web/virtual_lab/views.py index 7c92efece..91e5b3820 100644 --- a/web/virtual_lab/views.py +++ b/web/virtual_lab/views.py @@ -2,9 +2,10 @@ import json import logging +from typing import Any, Dict, List, Optional import requests -from django.http import JsonResponse +from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import render from django.utils.translation import gettext_lazy as _ from django.views.decorators.http import require_POST @@ -12,7 +13,7 @@ logger = logging.getLogger(__name__) -def build_virtual_lab_subjects(): +def build_virtual_lab_subjects() -> List[Dict[str, Any]]: """Return subject and lab metadata for virtual lab navigation and landing pages.""" return [ { @@ -42,7 +43,9 @@ def build_virtual_lab_subjects(): ] -def render_virtual_lab_page(request, template_name, extra_context=None): +def render_virtual_lab_page( + request: HttpRequest, template_name: str, extra_context: Optional[Dict[str, Any]] = None +) -> HttpResponse: """Render a virtual lab template with common navigation context.""" context = { "virtual_lab_subjects": build_virtual_lab_subjects(), @@ -100,26 +103,32 @@ def physics_electrical_circuit_view(request): def chemistry_home(request): + """Render the Chemistry lab overview page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/index.html") def titration_view(request): + """Render the Acid-Base Titration simulation page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/titration.html") def reaction_rate_view(request): + """Render the Reaction Rate simulation page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/reaction_rate.html") def solubility_view(request): + """Render the Solubility and Saturation simulation page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/solubility.html") def precipitation_view(request): + """Render the Precipitation Reaction simulation page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/precipitation.html") def ph_indicator_view(request): + """Render the pH Indicator simulation page.""" return render_virtual_lab_page(request, "virtual_lab/chemistry/ph_indicator.html") @@ -135,6 +144,7 @@ def ph_indicator_view(request): def code_editor_view(request): + """Render the virtual lab code editor page.""" return render_virtual_lab_page(request, "virtual_lab/code_editor/code_editor.html") From 80eef70f531d6c2f7b3dffc6d0ae4b19c82c1702 Mon Sep 17 00:00:00 2001 From: kernel-404 Date: Sat, 28 Feb 2026 11:04:24 +0530 Subject: [PATCH 3/3] changes requested by coderabbitai --- web/virtual_lab/templates/virtual_lab/home.html | 6 ++++-- web/virtual_lab/templates/virtual_lab/layout.html | 5 ++++- web/virtual_lab/views.py | 5 ++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/web/virtual_lab/templates/virtual_lab/home.html b/web/virtual_lab/templates/virtual_lab/home.html index c3f532715..16ae85a74 100644 --- a/web/virtual_lab/templates/virtual_lab/home.html +++ b/web/virtual_lab/templates/virtual_lab/home.html @@ -5,10 +5,12 @@ {% load i18n %} {% block virtual_lab_content %} -
+
-

Welcome to the Alpha Science Lab

+

+ {% trans "Welcome to the Alpha Science Lab" %} +

{% trans "Choose a subject to explore available virtual labs." %}

{% for subject in virtual_lab_subjects %} diff --git a/web/virtual_lab/templates/virtual_lab/layout.html b/web/virtual_lab/templates/virtual_lab/layout.html index a07ff657a..7e733c813 100644 --- a/web/virtual_lab/templates/virtual_lab/layout.html +++ b/web/virtual_lab/templates/virtual_lab/layout.html @@ -8,7 +8,7 @@
-
+
Alpha Science Lab