From 3b38317d4544d7a8227be890c33cfa87a3de57e9 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sun, 14 Dec 2025 08:17:44 +0545 Subject: [PATCH] feat(clients): add client management views and URL routes Implement client management functionality with CRUD operations, including list, create, edit, and delete views. The changes introduce URL routing and form handling for client interactions. **New Features** - **Client CRUD operations**: Added views for listing, creating, editing, and deleting client records - **ClientForm**: Introduced a model form with phone number formatting and initial country code - **HTMX support**: Implemented conditional template rendering for HTMX-based partial updates **Enhancements & Refinements** - **Form styling**: Enhanced phone number input fields with custom widget attributes - **Form behavior**: Disabled short_code field input while maintaining model structure - **Route organization**: Structured URL patterns for client operations in `urls.py` --- src/api/clients/urls.py | 10 +++++ src/api/clients/views.py | 91 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/api/clients/urls.py b/src/api/clients/urls.py index e69de29..939194d 100644 --- a/src/api/clients/urls.py +++ b/src/api/clients/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from src.api.clients import views + +urlpatterns = [ + path("", views.client_list, name="client_list"), + path("create/", views.client_create, name="client_create"), + path("/edit/", views.client_edit, name="client_edit"), + path("/delete/", views.client_delete, name="client_delete"), +] diff --git a/src/api/clients/views.py b/src/api/clients/views.py index e69de29..220dbdb 100644 --- a/src/api/clients/views.py +++ b/src/api/clients/views.py @@ -0,0 +1,91 @@ +from django import forms +from django.shortcuts import get_object_or_404, redirect, render +from django.views.decorators.http import require_http_methods +from phonenumber_field.formfields import SplitPhoneNumberField + +from src.models.clients import Client + + +class ClientForm(forms.ModelForm): + phone = SplitPhoneNumberField(initial="+977") + + class Meta: + model = Client + fields = ["name", "email", "phone", "company_name", "address", "short_code"] + widgets = { + "short_code": forms.TextInput(attrs={"placeholder": "Optional"}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["phone"].widget.widgets[0].attrs.update( + {"class": "select select-bordered join-item"} + ) + self.fields["phone"].widget.widgets[1].attrs.update( + {"class": "input input-bordered join-item w-full"} + ) + self.fields["short_code"].disabled = True + + +def client_list(request): + clients = Client.objects.all() + return render(request, "clients/client_list.html", {"clients": clients}) + + +@require_http_methods(["GET", "POST"]) +def client_create(request): + if request.method == "POST": + form = ClientForm(request.POST) + if form.is_valid(): + form.save() + if request.htmx: + clients = Client.objects.all() + return render( + request, "clients/partials/client_list.html", {"clients": clients} + ) + return redirect("client_list") + else: + form = ClientForm() + + template = ( + "clients/partials/client_form.html" + if request.htmx + else "clients/client_form.html" + ) + return render(request, template, {"form": form}) + + +@require_http_methods(["GET", "POST"]) +def client_edit(request, pk): + client = get_object_or_404(Client, pk=pk) + if request.method == "POST": + form = ClientForm(request.POST, instance=client) + if form.is_valid(): + form.save() + if request.htmx: + clients = Client.objects.all() + return render( + request, "clients/partials/client_list.html", {"clients": clients} + ) + return redirect("client_list") + else: + form = ClientForm(instance=client) + + template = ( + "clients/partials/client_form.html" + if request.htmx + else "clients/client_form.html" + ) + return render(request, template, {"form": form, "client": client}) + + +@require_http_methods(["DELETE", "POST"]) +def client_delete(request, pk): + client = get_object_or_404(Client, pk=pk) + client.delete() + if request.htmx: + clients = Client.objects.all() + return render( + request, "clients/partials/client_list.html", {"clients": clients} + ) + return redirect("client_list")