783 lines
42 KiB
HTML
783 lines
42 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block content %}
|
|
<div class="container py-5">
|
|
<!-- Breadcrumb -->
|
|
<nav aria-label="breadcrumb" class="mb-4">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'index' %}" class="text-decoration-none">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'voter_list' %}" class="text-decoration-none">Voters</a></li>
|
|
<li class="breadcrumb-item active" aria-current="page">{{ voter.first_name }} {{ voter.last_name }}</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<!-- Header / Demographics Card -->
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-body p-4 p-md-5">
|
|
<div class="row align-items-center">
|
|
<div class="col-md-auto mb-3 mb-md-0">
|
|
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center shadow-sm" style="width: 80px; height: 80px; font-size: 2rem;">
|
|
{{ voter.first_name|first }}{{ voter.last_name|first }}
|
|
</div>
|
|
</div>
|
|
<div class="col-md">
|
|
<div class="d-flex align-items-center">
|
|
<h1 class="h3 mb-1 me-3">{{ voter.first_name }} {{ voter.last_name }}</h1>
|
|
<button class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#editVoterModal">
|
|
<i class="bi bi-pencil me-1"></i>Edit
|
|
</button>
|
|
</div>
|
|
<p class="text-muted mb-0">
|
|
<i class="bi bi-geo-alt me-1"></i> {{ voter.address|default:"No address on file" }}
|
|
</p>
|
|
<div class="mt-2">
|
|
<span class="badge bg-light text-dark border me-1">Voter ID: {{ voter.voter_id|default:"N/A" }}</span>
|
|
<span class="badge bg-light text-dark border me-1">District: {{ voter.district|default:"-" }}</span>
|
|
<span class="badge bg-light text-dark border">Precinct: {{ voter.precinct|default:"-" }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-auto text-md-end mt-3 mt-md-0">
|
|
{% if voter.candidate_support == 'supporting' %}
|
|
<div class="h4 text-success mb-0"><i class="bi bi-check-circle-fill me-2"></i>Supporting</div>
|
|
{% elif voter.candidate_support == 'not_supporting' %}
|
|
<div class="h4 text-danger mb-0"><i class="bi bi-x-circle-fill me-2"></i>Not Supporting</div>
|
|
{% else %}
|
|
<div class="h4 text-secondary mb-0"><i class="bi bi-question-circle-fill me-2"></i>Unknown Support</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Left Column: Quick Stats & Likelihood -->
|
|
<div class="col-lg-4">
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="card-title mb-0">Contact Information</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li class="mb-3">
|
|
<label class="small text-muted d-block">Email</label>
|
|
<span class="fw-semibold">{{ voter.email|default:"N/A" }}</span>
|
|
</li>
|
|
<li class="mb-3">
|
|
<label class="small text-muted d-block">Phone</label>
|
|
<span class="fw-semibold">{{ voter.phone|default:"N/A" }}</span>
|
|
</li>
|
|
<li>
|
|
<label class="small text-muted d-block">Registration Date</label>
|
|
<span class="fw-semibold">{{ voter.registration_date|date:"M d, Y"|default:"Unknown" }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<h5 class="card-title mb-0">Likelihood to Vote</h5>
|
|
<button class="btn btn-sm btn-link text-primary p-0" data-bs-toggle="modal" data-bs-target="#addLikelihoodModal">
|
|
<i class="bi bi-plus-circle"></i>
|
|
</button>
|
|
</div>
|
|
<div class="card-body">
|
|
{% for likelihood in likelihoods %}
|
|
<div class="d-flex justify-content-between align-items-center mb-3 last-child-mb-0">
|
|
<div>
|
|
<span class="text-muted">{{ likelihood.election_type.name }}</span>
|
|
{% if likelihood.likelihood == 'very_likely' %}
|
|
<span class="badge bg-success ms-2">Very Likely</span>
|
|
{% elif likelihood.likelihood == 'somewhat_likely' %}
|
|
<span class="badge bg-info ms-2">Somewhat Likely</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary ms-2">Not Likely</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="text-nowrap ms-2">
|
|
<button class="btn btn-sm btn-link text-primary p-0 me-2" data-bs-toggle="modal" data-bs-target="#editLikelihoodModal{{ likelihood.id }}">
|
|
<i class="bi bi-pencil small"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-link text-danger p-0" data-bs-toggle="modal" data-bs-target="#deleteLikelihoodModal{{ likelihood.id }}">
|
|
<i class="bi bi-trash small"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<p class="text-muted mb-0 italic">No likelihood data available.</p>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="card-title mb-0">Campaign Assets</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<span class="text-muted">Yard Sign Status</span>
|
|
</div>
|
|
<div>
|
|
{% if voter.yard_sign == 'has' %}
|
|
<span class="badge bg-warning text-dark">Has Sign</span>
|
|
{% elif voter.yard_sign == 'wants' %}
|
|
<span class="badge bg-info">Wants Sign</span>
|
|
{% else %}
|
|
<span class="badge bg-light text-dark border">None</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column: Timeline & Detailed Records -->
|
|
<div class="col-lg-8">
|
|
<!-- Nav Tabs -->
|
|
<ul class="nav nav-tabs border-0 mb-4" id="voterTabs" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link active border-0 py-3 px-4" id="interactions-tab" data-bs-toggle="tab" data-bs-target="#interactions" type="button" role="tab">Interactions</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link border-0 py-3 px-4" id="voting-tab" data-bs-toggle="tab" data-bs-target="#voting" type="button" role="tab">Voting History</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link border-0 py-3 px-4" id="donations-tab" data-bs-toggle="tab" data-bs-target="#donations" type="button" role="tab">Donations</button>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link border-0 py-3 px-4" id="events-tab" data-bs-toggle="tab" data-bs-target="#events" type="button" role="tab">Events</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content" id="voterTabsContent">
|
|
<!-- Interactions Tab -->
|
|
<div class="tab-pane fade show active" id="interactions" role="tabpanel">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0">Interaction History</h6>
|
|
<button class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#addInteractionModal">
|
|
<i class="bi bi-plus-lg me-1"></i>New Interaction
|
|
</button>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">Date</th>
|
|
<th>Type</th>
|
|
<th>Description</th>
|
|
<th>Notes</th>
|
|
<th class="pe-4 text-end">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for interaction in interactions %}
|
|
<tr>
|
|
<td class="ps-4 text-nowrap">{{ interaction.date|date:"M d, Y" }}</td>
|
|
<td><span class="badge bg-light text-dark border">{{ interaction.type.name }}</span></td>
|
|
<td>{{ interaction.description }}</td>
|
|
<td class="small text-muted">{{ interaction.notes|truncatechars:30 }}</td>
|
|
<td class="pe-4 text-end">
|
|
<button class="btn btn-sm btn-link text-primary p-0 me-2" data-bs-toggle="modal" data-bs-target="#editInteractionModal{{ interaction.id }}">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-link text-danger p-0" data-bs-toggle="modal" data-bs-target="#deleteInteractionModal{{ interaction.id }}">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr><td colspan="5" class="text-center py-4 text-muted">No interactions recorded.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Voting History Tab -->
|
|
<div class="tab-pane fade" id="voting" role="tabpanel">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">Election Date</th>
|
|
<th>Description</th>
|
|
<th class="pe-4">Party</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for record in voting_records %}
|
|
<tr>
|
|
<td class="ps-4 text-nowrap">{{ record.election_date|date:"M d, Y" }}</td>
|
|
<td>{{ record.election_description }}</td>
|
|
<td class="pe-4">{{ record.primary_party|default:"-" }}</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr><td colspan="3" class="text-center py-4 text-muted">No voting records found.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Donations Tab -->
|
|
<div class="tab-pane fade" id="donations" role="tabpanel">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0">Donation History</h6>
|
|
<button class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#addDonationModal">
|
|
<i class="bi bi-plus-lg me-1"></i>Add Donation
|
|
</button>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">Date</th>
|
|
<th>Method</th>
|
|
<th class="text-end">Amount</th>
|
|
<th class="pe-4 text-end">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for donation in donations %}
|
|
<tr>
|
|
<td class="ps-4 text-nowrap">{{ donation.date|date:"M d, Y" }}</td>
|
|
<td>{{ donation.method.name }}</td>
|
|
<td class="text-end fw-semibold text-success">${{ donation.amount }}</td>
|
|
<td class="pe-4 text-end">
|
|
<button class="btn btn-sm btn-link text-primary p-0 me-2" data-bs-toggle="modal" data-bs-target="#editDonationModal{{ donation.id }}">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-link text-danger p-0" data-bs-toggle="modal" data-bs-target="#deleteDonationModal{{ donation.id }}">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr><td colspan="4" class="text-center py-4 text-muted">No donations recorded.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Events Tab -->
|
|
<div class="tab-pane fade" id="events" role="tabpanel">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0">Event Participation</h6>
|
|
<button class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#addEventParticipationModal">
|
|
<i class="bi bi-plus-lg me-1"></i>Add Participation
|
|
</button>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th class="ps-4">Date</th>
|
|
<th>Event Type</th>
|
|
<th>Description</th>
|
|
<th class="pe-4 text-end">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for participation in event_participations %}
|
|
<tr>
|
|
<td class="ps-4 text-nowrap">{{ participation.event.date|date:"M d, Y" }}</td>
|
|
<td><span class="badge bg-light text-dark border">{{ participation.event.event_type.name }}</span></td>
|
|
<td class="small text-muted">{{ participation.event.description|truncatechars:60 }}</td>
|
|
<td class="pe-4 text-end">
|
|
<button class="btn btn-sm btn-link text-primary p-0 me-2" data-bs-toggle="modal" data-bs-target="#editEventParticipationModal{{ participation.id }}">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-link text-danger p-0" data-bs-toggle="modal" data-bs-target="#deleteEventParticipationModal{{ participation.id }}">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr><td colspan="4" class="text-center py-4 text-muted">No event participations found.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Voter Modal -->
|
|
<div class="modal fade" id="editVoterModal" tabindex="-1" aria-labelledby="editVoterModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title" id="editVoterModalLabel">Edit Voter Profile</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'voter_edit' voter.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.first_name.label }}</label>
|
|
{{ voter_form.first_name }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.last_name.label }}</label>
|
|
{{ voter_form.last_name }}
|
|
</div>
|
|
<div class="col-12 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.address.label }}</label>
|
|
{{ voter_form.address }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.phone.label }}</label>
|
|
{{ voter_form.phone }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.email.label }}</label>
|
|
{{ voter_form.email }}
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.voter_id.label }}</label>
|
|
{{ voter_form.voter_id }}
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.district.label }}</label>
|
|
{{ voter_form.district }}
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.precinct.label }}</label>
|
|
{{ voter_form.precinct }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.registration_date.label }}</label>
|
|
{{ voter_form.registration_date }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.candidate_support.label }}</label>
|
|
{{ voter_form.candidate_support }}
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-medium">{{ voter_form.yard_sign.label }}</label>
|
|
{{ voter_form.yard_sign }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-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>
|
|
|
|
<!-- Add Interaction Modal -->
|
|
<div class="modal fade" id="addInteractionModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">New Interaction</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'add_interaction' voter.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ interaction_form.type.label }}</label>
|
|
{{ interaction_form.type }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ interaction_form.date.label }}</label>
|
|
{{ interaction_form.date }}
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ interaction_form.description.label }}</label>
|
|
{{ interaction_form.description }}
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">{{ interaction_form.notes.label }}</label>
|
|
{{ interaction_form.notes }}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary px-4">Log Interaction</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Interaction Modals -->
|
|
{% for interaction in interactions %}
|
|
<div class="modal fade" id="editInteractionModal{{ interaction.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Edit Interaction</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'edit_interaction' interaction.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Type</label>
|
|
<select name="type" class="form-select">
|
|
{% for type in interaction_form.fields.type.queryset %}
|
|
<option value="{{ type.id }}" {% if type.id == interaction.type.id %}selected{% endif %}>{{ type.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Date</label>
|
|
<input type="date" name="date" class="form-control" value="{{ interaction.date|date:'Y-m-d' }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Description</label>
|
|
<input type="text" name="description" class="form-control" value="{{ interaction.description }}">
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">Notes</label>
|
|
<textarea name="notes" class="form-control" rows="2">{{ interaction.notes }}</textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-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>
|
|
|
|
<!-- Delete Interaction Modal -->
|
|
<div class="modal fade" id="deleteInteractionModal{{ interaction.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Delete Interaction?</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4 text-center">
|
|
<p class="text-muted mb-0">Are you sure you want to delete this interaction?</p>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0 justify-content-center">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">No, Keep</button>
|
|
<form action="{% url 'delete_interaction' interaction.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<!-- Add Donation Modal -->
|
|
<div class="modal fade" id="addDonationModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Add Donation</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'add_donation' voter.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ donation_form.amount.label }}</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">$</span>
|
|
{{ donation_form.amount }}
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ donation_form.date.label }}</label>
|
|
{{ donation_form.date }}
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">{{ donation_form.method.label }}</label>
|
|
{{ donation_form.method }}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary px-4">Record Donation</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Donation Modals -->
|
|
{% for donation in donations %}
|
|
<div class="modal fade" id="editDonationModal{{ donation.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Edit Donation</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'edit_donation' donation.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Amount</label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">$</span>
|
|
<input type="number" name="amount" class="form-control" step="0.01" value="{{ donation.amount }}">
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Date</label>
|
|
<input type="date" name="date" class="form-control" value="{{ donation.date|date:'Y-m-d' }}">
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">Method</label>
|
|
<select name="method" class="form-select">
|
|
{% for method in donation_form.fields.method.queryset %}
|
|
<option value="{{ method.id }}" {% if method.id == donation.method.id %}selected{% endif %}>{{ method.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-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>
|
|
|
|
<!-- Delete Donation Modal -->
|
|
<div class="modal fade" id="deleteDonationModal{{ donation.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Delete Donation?</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4 text-center">
|
|
<p class="text-muted mb-0">Are you sure you want to delete this donation record?</p>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0 justify-content-center">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">No, Keep</button>
|
|
<form action="{% url 'delete_donation' donation.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<!-- Add Likelihood Modal -->
|
|
<div class="modal fade" id="addLikelihoodModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Update Voter Likelihood</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'add_likelihood' voter.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">{{ likelihood_form.election_type.label }}</label>
|
|
{{ likelihood_form.election_type }}
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">{{ likelihood_form.likelihood.label }}</label>
|
|
{{ likelihood_form.likelihood }}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary px-4">Update</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Likelihood Modals -->
|
|
{% for likelihood in likelihoods %}
|
|
<div class="modal fade" id="editLikelihoodModal{{ likelihood.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Edit Likelihood</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'edit_likelihood' likelihood.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-medium">Election Type</label>
|
|
<select name="election_type" class="form-select">
|
|
{% for et in likelihood_form.fields.election_type.queryset %}
|
|
<option value="{{ et.id }}" {% if et.id == likelihood.election_type.id %}selected{% endif %}>{{ et.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">Likelihood</label>
|
|
<select name="likelihood" class="form-select">
|
|
<option value="not_likely" {% if likelihood.likelihood == 'not_likely' %}selected{% endif %}>Not Likely</option>
|
|
<option value="somewhat_likely" {% if likelihood.likelihood == 'somewhat_likely' %}selected{% endif %}>Somewhat Likely</option>
|
|
<option value="very_likely" {% if likelihood.likelihood == 'very_likely' %}selected{% endif %}>Very Likely</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-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>
|
|
|
|
<!-- Delete Likelihood Modal -->
|
|
<div class="modal fade" id="deleteLikelihoodModal{{ likelihood.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Delete Likelihood?</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4 text-center">
|
|
<p class="text-muted mb-0">Delete likelihood for <strong>{{ likelihood.election_type.name }}</strong>?</p>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0 justify-content-center">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">No</button>
|
|
<form action="{% url 'delete_likelihood' likelihood.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-danger">Yes, Delete</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<!-- Add Event Participation Modal -->
|
|
<div class="modal fade" id="addEventParticipationModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Add Event Participation</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'add_event_participation' voter.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">Select Event</label>
|
|
{{ event_participation_form.event }}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary px-4">Add Participation</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Event Participation Modals -->
|
|
{% for participation in event_participations %}
|
|
<div class="modal fade" id="editEventParticipationModal{{ participation.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Edit Participation</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form action="{% url 'edit_event_participation' participation.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<div class="modal-body p-4">
|
|
<div class="mb-0">
|
|
<label class="form-label fw-medium">Event</label>
|
|
<select name="event" class="form-select">
|
|
{% for ev in event_participation_form.fields.event.queryset %}
|
|
<option value="{{ ev.id }}" {% if ev.id == participation.event.id %}selected{% endif %}>{{ ev.event_type.name }} on {{ ev.date }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-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>
|
|
|
|
<!-- Delete Event Participation Modal -->
|
|
<div class="modal fade" id="deleteEventParticipationModal{{ participation.id }}" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-sm">
|
|
<div class="modal-content border-0">
|
|
<div class="modal-header border-0 bg-light">
|
|
<h5 class="modal-title">Remove Participation?</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4 text-center">
|
|
<p class="text-muted mb-0">Are you sure you want to remove this event participation?</p>
|
|
</div>
|
|
<div class="modal-footer border-0 p-4 pt-0 justify-content-center">
|
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">No</button>
|
|
<form action="{% url 'delete_event_participation' participation.id %}" method="POST">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-danger">Yes, Remove</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<style>
|
|
.nav-tabs .nav-link {
|
|
color: #6c757d;
|
|
font-weight: 500;
|
|
border-radius: 0;
|
|
}
|
|
.nav-tabs .nav-link.active {
|
|
color: #059669;
|
|
background: transparent;
|
|
border-bottom: 2px solid #059669 !important;
|
|
}
|
|
.last-child-mb-0:last-child {
|
|
margin-bottom: 0 !important;
|
|
}
|
|
.modal-content {
|
|
border-radius: 1rem;
|
|
overflow: hidden;
|
|
}
|
|
.form-control, .form-select {
|
|
border-color: #e5e7eb;
|
|
padding: 0.6rem 0.8rem;
|
|
}
|
|
.form-control:focus, .form-select:focus {
|
|
border-color: #059669;
|
|
box-shadow: 0 0 0 0.25rem rgba(5, 150, 105, 0.1);
|
|
}
|
|
</style>
|
|
{% endblock %}
|