diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 45dee05..f390f90 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index f85f89d..b7e7236 100644 --- a/config/settings.py +++ b/config/settings.py @@ -69,6 +69,7 @@ MIDDLEWARE = [ 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'core.middleware.LoginRequiredMiddleware', + 'core.middleware.TimezoneMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Disable X-Frame-Options middleware to allow Flatlogic preview iframes. # 'django.middleware.clickjacking.XFrameOptionsMiddleware', @@ -188,4 +189,4 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_API_KEY", "AIzaSyAluZTEjH-RSiGJUHnfrSqWbcAXCGzGOq4") LOGIN_URL = 'login' LOGIN_REDIRECT_URL = 'index' -LOGOUT_REDIRECT_URL = 'login' +LOGOUT_REDIRECT_URL = 'login' \ No newline at end of file diff --git a/core/__pycache__/middleware.cpython-311.pyc b/core/__pycache__/middleware.cpython-311.pyc index 9875fd6..26f434d 100644 Binary files a/core/__pycache__/middleware.cpython-311.pyc and b/core/__pycache__/middleware.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 80c2cd4..48a8496 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/middleware.py b/core/middleware.py index 65898ba..963937e 100644 --- a/core/middleware.py +++ b/core/middleware.py @@ -1,6 +1,9 @@ +import zoneinfo from django.shortcuts import redirect from django.urls import reverse from django.conf import settings +from django.utils import timezone +from core.models import CampaignSettings, Tenant class LoginRequiredMiddleware: def __init__(self, get_response): @@ -11,7 +14,6 @@ class LoginRequiredMiddleware: path = request.path_info # Allow access to login, logout, admin, and any other exempted paths - # We use try/except in case URLs are not defined yet try: login_url = reverse('login') logout_url = reverse('logout') @@ -32,4 +34,35 @@ class LoginRequiredMiddleware: return redirect(f"{login_url}?next={path}") response = self.get_response(request) - return response \ No newline at end of file + return response + +class TimezoneMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + tzname = None + + # 1. Try to get tenant from session + tenant_id = request.session.get("tenant_id") + if tenant_id: + try: + campaign_settings = CampaignSettings.objects.get(tenant_id=tenant_id) + tzname = campaign_settings.timezone + except CampaignSettings.DoesNotExist: + pass + + # 2. If not found and user is authenticated, maybe they are in admin? + # In admin, we might not have tenant_id in session if they went directly there. + # But this is a multi-tenant app, usually they select a campaign first. + # If they are superuser in admin, we might want to default to something or let them see UTC. + + if tzname: + try: + timezone.activate(zoneinfo.ZoneInfo(tzname)) + except: + timezone.deactivate() + else: + timezone.deactivate() + + return self.get_response(request) diff --git a/core/templates/core/door_visit_history.html b/core/templates/core/door_visit_history.html index 859abe7..015ba79 100644 --- a/core/templates/core/door_visit_history.html +++ b/core/templates/core/door_visit_history.html @@ -18,6 +18,57 @@ + +
+ +
+
+
+
Filter by Date Range
+
+
+ + +
+
+ + +
+
+ +
+ {% if start_date or end_date %} + + {% endif %} +
+
+
+
+ + +
+
+
+
Visits per Volunteer
+
+ {% for v_name, count in volunteer_counts %} +
+ {{ v_name }} + {{ count }} +
+ {% empty %} +

No volunteer data available for this selection.

+ {% endfor %} +
+
+
+
+
+
@@ -33,8 +84,9 @@ Household Address Voters Visited Last Visit + Volunteer Outcome - Interactions + Comments @@ -66,25 +118,37 @@
{{ household.last_visit_date|date:"M d, Y" }}
{{ household.last_visit_date|date:"H:i" }}
+ + {% if household.last_volunteer %} +
+
+ {{ household.last_volunteer.first_name|first }}{{ household.last_volunteer.last_name|first }} +
+ {{ household.last_volunteer }} +
+ {% else %} + N/A + {% endif %} + {{ household.last_outcome }} - - {{ household.interaction_count }} Visit{{ household.interaction_count|pluralize }} - +
+ {{ household.notes|default:"-" }} +
{% empty %} - +
-

No door visits logged yet.

-

Visit the Planned Visits page to start logging visits.

+

No door visits found for this selection.

+

Try clearing your filters or visit the Planned Visits page to log more visits.

{% endfor %} @@ -98,12 +162,12 @@