diff --git a/web/templates/base.html b/web/templates/base.html index 7afa700a9..b054bb0bd 100644 --- a/web/templates/base.html +++ b/web/templates/base.html @@ -345,6 +345,8 @@ - -
@@ -1119,5 +1120,71 @@

CONNECT WITH {% block extra_js %} {% endblock extra_js %} + diff --git a/web/urls.py b/web/urls.py index 3fb4e298a..2e925f9f4 100644 --- a/web/urls.py +++ b/web/urls.py @@ -102,6 +102,7 @@ # Course Management path("courses/create/", views.create_course, name="create_course"), path("courses/search/", views.course_search, name="course_search"), + path("search/autocomplete/", views.search_autocomplete, name="search_autocomplete"), path("courses//", views.course_detail, name="course_detail"), path("courses//enroll/", views.enroll_course, name="enroll_course"), path("courses//add-session/", views.add_session, name="add_session"), diff --git a/web/views.py b/web/views.py index b4d485749..1cb13a9fc 100644 --- a/web/views.py +++ b/web/views.py @@ -1462,6 +1462,48 @@ def send_welcome_teach_course_email(request, user, temp_password): ) + +@require_GET +def search_autocomplete(request: HttpRequest) -> JsonResponse: + """Return course autocomplete results for navbar search. + + Args: + request: HTTP GET request with 'q' query parameter. + + Returns: + JsonResponse with list of matching courses (up to 8). + """ + query = request.GET.get("q", "").strip() + if len(query) > 64: + return JsonResponse({"results": []}) + results = [] + if len(query) >= 2: + courses = Course.objects.filter( + status="published" + ).filter( + Q(title__icontains=query) + | Q(tags__icontains=query) + | Q(teacher__username__icontains=query) + | Q(teacher__first_name__icontains=query) + | Q(teacher__last_name__icontains=query) + ).order_by("title").values( + "title", "slug", "teacher__username", "teacher__first_name", "teacher__last_name" + )[:8] + for course in courses: + teacher_name = " ".join( + part for part in [course["teacher__first_name"], course["teacher__last_name"]] if part + ) or course["teacher__username"] + results.append( + { + "type": "course", + "title": course["title"], + "url": reverse("course_detail", kwargs={"slug": course["slug"]}), + "teacher": teacher_name, + } + ) + return JsonResponse({"results": results}) + + def course_search(request): query = request.GET.get("q", "") subject = request.GET.get("subject", "")