.8
This commit is contained in:
parent
14a93b6b2b
commit
e4aeae1b74
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -30,7 +30,6 @@ class VoterForm(forms.ModelForm):
|
|||||||
self.fields['yard_sign'].widget.attrs.update({'class': 'form-select'})
|
self.fields['yard_sign'].widget.attrs.update({'class': 'form-select'})
|
||||||
|
|
||||||
class InteractionForm(forms.ModelForm):
|
class InteractionForm(forms.ModelForm):
|
||||||
# ... (rest of the file remains the same)
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Interaction
|
model = Interaction
|
||||||
fields = ['type', 'date', 'description', 'notes']
|
fields = ['type', 'date', 'description', 'notes']
|
||||||
@ -107,15 +106,3 @@ class EventForm(forms.ModelForm):
|
|||||||
for field in self.fields.values():
|
for field in self.fields.values():
|
||||||
field.widget.attrs.update({'class': 'form-control'})
|
field.widget.attrs.update({'class': 'form-control'})
|
||||||
self.fields['event_type'].widget.attrs.update({'class': 'form-select'})
|
self.fields['event_type'].widget.attrs.update({'class': 'form-select'})
|
||||||
|
|
||||||
class EventTypeForm(forms.ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = EventType
|
|
||||||
fields = ['name', 'is_active']
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
for field in self.fields.values():
|
|
||||||
if not isinstance(field.widget, forms.CheckboxInput):
|
|
||||||
field.widget.attrs.update({'class': 'form-control'})
|
|
||||||
self.fields['is_active'].widget.attrs.update({'class': 'form-check-input'})
|
|
||||||
@ -40,9 +40,6 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/voters/">Voters</a>
|
<a class="nav-link" href="/voters/">Voters</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="{% url 'event_type_list' %}">Maintenance</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<a href="/admin/" class="btn btn-outline-primary btn-sm me-2">Admin Panel</a>
|
<a href="/admin/" class="btn btn-outline-primary btn-sm me-2">Admin Panel</a>
|
||||||
|
|||||||
@ -1,127 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="container py-4">
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
||||||
<div>
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ol class="breadcrumb mb-1">
|
|
||||||
<li class="breadcrumb-item"><a href="{% url 'index' %}">Home</a></li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">Maintenance</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
<h1 class="h3 mb-0">Event Types</h1>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addTypeModal">
|
|
||||||
<i class="bi bi-plus-lg me-1"></i> Add Event Type
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card border-0 shadow-sm">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover align-middle mb-0">
|
|
||||||
<thead class="bg-light">
|
|
||||||
<tr>
|
|
||||||
<th class="ps-4">Name</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th class="text-end pe-4">Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for type in event_types %}
|
|
||||||
<tr>
|
|
||||||
<td class="ps-4 fw-medium">{{ type.name }}</td>
|
|
||||||
<td>
|
|
||||||
{% if type.is_active %}
|
|
||||||
<span class="badge bg-success-subtle text-success border border-success-subtle px-2">Active</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="badge bg-secondary-subtle text-secondary border border-secondary-subtle px-2">Inactive</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td class="text-end pe-4">
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-secondary me-1"
|
|
||||||
data-bs-toggle="modal" data-bs-target="#editTypeModal{{ type.id }}">
|
|
||||||
<i class="bi bi-pencil"></i>
|
|
||||||
</button>
|
|
||||||
<form action="{% url 'event_type_delete' type.id %}" method="POST" class="d-inline">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button type="submit" class="btn btn-sm btn-outline-danger"
|
|
||||||
onclick="return confirm('Are you sure you want to delete this event type?')">
|
|
||||||
<i class="bi bi-trash"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<!-- Edit Modal -->
|
|
||||||
<div class="modal fade" id="editTypeModal{{ type.id }}" tabindex="-1">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<form action="{% url 'event_type_edit' type.id %}" method="POST">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div class="modal-header border-0">
|
|
||||||
<h5 class="modal-title">Edit Event Type</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Name</label>
|
|
||||||
<input type="text" name="name" class="form-control" value="{{ type.name }}" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" name="is_active" id="activeSwitch{{ type.id }}" {% if type.is_active %}checked{% endif %}>
|
|
||||||
<label class="form-check-label" for="activeSwitch{{ type.id }}">Active</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer border-0">
|
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
||||||
<button type="submit" class="btn btn-primary px-4">Save Changes</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% empty %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="3" class="text-center py-5 text-muted">
|
|
||||||
<i class="bi bi-info-circle fs-4 d-block mb-2"></i>
|
|
||||||
No event types defined yet.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Add Modal -->
|
|
||||||
<div class="modal fade" id="addTypeModal" tabindex="-1">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<form action="{% url 'event_type_add' %}" method="POST">
|
|
||||||
{% csrf_token %}
|
|
||||||
<div class="modal-header border-0">
|
|
||||||
<h5 class="modal-title">Add Event Type</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Name</label>
|
|
||||||
{{ form.name }}
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
{{ form.is_active }}
|
|
||||||
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">Active</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer border-0">
|
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
||||||
<button type="submit" class="btn btn-primary px-4">Add Type</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@ -24,10 +24,4 @@ urlpatterns = [
|
|||||||
path('voters/<int:voter_id>/event-participation/add/', views.add_event_participation, name='add_event_participation'),
|
path('voters/<int:voter_id>/event-participation/add/', views.add_event_participation, name='add_event_participation'),
|
||||||
path('event-participation/<int:participation_id>/edit/', views.edit_event_participation, name='edit_event_participation'),
|
path('event-participation/<int:participation_id>/edit/', views.edit_event_participation, name='edit_event_participation'),
|
||||||
path('event-participation/<int:participation_id>/delete/', views.delete_event_participation, name='delete_event_participation'),
|
path('event-participation/<int:participation_id>/delete/', views.delete_event_participation, name='delete_event_participation'),
|
||||||
|
]
|
||||||
# Maintenance
|
|
||||||
path('maintenance/event-types/', views.event_type_list, name='event_type_list'),
|
|
||||||
path('maintenance/event-types/add/', views.event_type_add, name='event_type_add'),
|
|
||||||
path('maintenance/event-types/<int:type_id>/edit/', views.event_type_edit, name='event_type_edit'),
|
|
||||||
path('maintenance/event-types/<int:type_id>/delete/', views.event_type_delete, name='event_type_delete'),
|
|
||||||
]
|
|
||||||
@ -4,7 +4,7 @@ from django.shortcuts import render, redirect, get_object_or_404
|
|||||||
from django.db.models import Q, Sum
|
from django.db.models import Q, Sum
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from .models import Voter, Tenant, Interaction, Donation, VoterLikelihood, EventParticipation, Event, EventType, InteractionType, DonationMethod, ElectionType
|
from .models import Voter, Tenant, Interaction, Donation, VoterLikelihood, EventParticipation, Event, EventType, InteractionType, DonationMethod, ElectionType
|
||||||
from .forms import VoterForm, InteractionForm, DonationForm, VoterLikelihoodForm, EventParticipationForm, EventTypeForm
|
from .forms import VoterForm, InteractionForm, DonationForm, VoterLikelihoodForm, EventParticipationForm
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -315,63 +315,6 @@ def delete_event_participation(request, participation_id):
|
|||||||
messages.success(request, "Event participation removed.")
|
messages.success(request, "Event participation removed.")
|
||||||
return redirect(reverse('voter_detail', kwargs={'voter_id': voter_id}) + '?active_tab=events')
|
return redirect(reverse('voter_detail', kwargs={'voter_id': voter_id}) + '?active_tab=events')
|
||||||
|
|
||||||
def event_type_list(request):
|
|
||||||
"""
|
|
||||||
Maintenance page for Event Types.
|
|
||||||
"""
|
|
||||||
selected_tenant_id = request.session.get('tenant_id')
|
|
||||||
if not selected_tenant_id:
|
|
||||||
messages.warning(request, "Please select a campaign first.")
|
|
||||||
return redirect('index')
|
|
||||||
|
|
||||||
tenant = get_object_or_404(Tenant, id=selected_tenant_id)
|
|
||||||
event_types = EventType.objects.filter(tenant=tenant)
|
|
||||||
|
|
||||||
context = {
|
|
||||||
'event_types': event_types,
|
|
||||||
'selected_tenant': tenant,
|
|
||||||
'form': EventTypeForm(),
|
|
||||||
}
|
|
||||||
return render(request, 'core/event_type_list.html', context)
|
|
||||||
|
|
||||||
def event_type_add(request):
|
|
||||||
selected_tenant_id = request.session.get('tenant_id')
|
|
||||||
tenant = get_object_or_404(Tenant, id=selected_tenant_id)
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = EventTypeForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
event_type = form.save(commit=False)
|
|
||||||
event_type.tenant = tenant
|
|
||||||
event_type.save()
|
|
||||||
messages.success(request, "Event type added.")
|
|
||||||
return redirect('event_type_list')
|
|
||||||
|
|
||||||
def event_type_edit(request, type_id):
|
|
||||||
selected_tenant_id = request.session.get('tenant_id')
|
|
||||||
tenant = get_object_or_404(Tenant, id=selected_tenant_id)
|
|
||||||
event_type = get_object_or_404(EventType, id=type_id, tenant=tenant)
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = EventTypeForm(request.POST, instance=event_type)
|
|
||||||
if form.is_valid():
|
|
||||||
form.save()
|
|
||||||
messages.success(request, "Event type updated.")
|
|
||||||
return redirect('event_type_list')
|
|
||||||
|
|
||||||
def event_type_delete(request, type_id):
|
|
||||||
selected_tenant_id = request.session.get('tenant_id')
|
|
||||||
tenant = get_object_or_404(Tenant, id=selected_tenant_id)
|
|
||||||
event_type = get_object_or_404(EventType, id=type_id, tenant=tenant)
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
try:
|
|
||||||
event_type.delete()
|
|
||||||
messages.success(request, "Event type deleted.")
|
|
||||||
except Exception as e:
|
|
||||||
messages.error(request, f"Cannot delete event type: {e}")
|
|
||||||
return redirect('event_type_list')
|
|
||||||
|
|
||||||
def voter_geocode(request, voter_id):
|
def voter_geocode(request, voter_id):
|
||||||
"""
|
"""
|
||||||
Manually trigger geocoding for a voter, potentially using values from the request.
|
Manually trigger geocoding for a voter, potentially using values from the request.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user