Skip to content

Commit

Permalink
refactor image sizes and drive dashboard ui (#381)
Browse files Browse the repository at this point in the history
* refactor image sizes and drive dashboard ui

* fix js data reload on modify and delete contribution
  • Loading branch information
estchang authored Dec 4, 2024
1 parent 1ae085e commit bbaea71
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 262 deletions.
126 changes: 71 additions & 55 deletions src/community_drives/templates/community_drives/drive_dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,35 @@
{% include "partials/notifications.html" %}
<!-- Drive Details -->
<div class="mt-5">
<div class="columns is-vcentered">
<div class="column">
<div class="columns is-vcentered is-4">
<div class="column is-narrow is-full-mobile">
<div class="image-container has-text-centered">
<!-- djlint:off -->
<img src="data:image/jpeg;base64,{{ drive.image_data }}" alt="Default Image"
onerror="this.src='{% static 'default.png' %}';" class="image is-square"
style="width: 200px; height: 200px; object-fit: cover; border-radius: 10px;">
<!-- djlint:on -->
<!-- Hover Options -->
{% if can_edit %}
<div class="hover-options">
<label class="button is-small is-primary" for="file-upload-{{ drive.drive_id }}">
Upload
<input type="file" id="file-upload-{{ drive.drive_id }}" class="file-upload-hidden"
data-id="{{ drive.drive_id }}" onchange="uploadDriveImage(this)">
</label>
{% if drive.image_data %}
<button class="button is-small is-danger" data-id="{{ drive.drive_id }}"
onclick="deleteDriveImage(this)">
Delete
</button>
{% endif %}
</div>
{% endif %}
</div>
</div>
<div class="column is-three-fifths is-full-mobile is-full-tablet">
<h1 class="title">{{ drive.name }}</h1>
<p class="subtitle">{{ drive.description }}</p>
<p class="subtitle mt-4">{{ drive.description }}</p>
<div class="tags">
<span class="tag is-info">Meal Target: {{ drive.meal_target }}</span>
<span class="tag is-info">Volunteer Target: {{ drive.volunteer_target }}</span>
Expand All @@ -22,61 +47,50 @@ <h1 class="title">{{ drive.name }}</h1>
<span class="tag is-success">{{ drive.active|yesno:"Active,Inactive" }}</span>
</div>
</div>
<div class="image-container has-text-centered mt-4 is-one-third">
<!-- djlint:off -->
<img src="data:image/jpeg;base64,{{ drive.image_data }}"
alt="Default Image"
onerror="this.src='{% static 'default.png' %}';"
class="image is-square"
style="width: 100%; max-width: 300px; height: auto; object-fit: cover; border-radius: 4px;">
<!-- djlint:on -->
<!-- Hover Options -->
{% if can_edit %}
<div class="hover-options">
<label class="button is-small is-primary" for="file-upload-{{ drive.drive_id }}">
Upload
<input type="file"
id="file-upload-{{ drive.drive_id }}"
class="file-upload-hidden"
data-id="{{ drive.drive_id }}"
onchange="uploadDriveImage(this)">
</label>
{% if drive.image_data %}
<button class="button is-small is-danger"
data-id="{{ drive.drive_id }}"
onclick="deleteDriveImage(this)">
Delete
</button>
{% endif %}
<div class="column">
<div class="box">
<p class="mb-2"><strong>
{{ drive.meal_progress }} / {{ drive.meal_target }} meals ({{ meals_percentage|floatformat:1 }}%)
</strong></p>
<progress class="progress is-success" value="{{ meals_percentage }}" max="100"></progress>
</div>

<!-- Volunteers Progress -->
<div class="box">
<p class="mb-2"><strong>
{{ drive.volunteer_progress }} / {{ drive.volunteer_target }} volunteers ({{ volunteers_percentage|floatformat:1 }}%)
</strong></p>
<progress class="progress is-info" value="{{ volunteers_percentage }}" max="100"></progress>
</div>
{% endif %}
</div>
</div>
</div>
<hr>
<!-- Contribute Button -->
<button class="button is-primary open-modal" data-target="contribute-modal">Manage My Contributions</button>
<div class="level">
<div class="level-left">
<div class="level-item">
<h2 class="subtitle my-3"><strong>{{ drive.driveorganization_set.all|length }}
Contributions</strong></h2>
</div>
<div class="level-item">
<button class="button is-primary open-modal" data-target="contribute-modal">Manage My Contributions</button>
</div>
</div>
</div>

<!-- Contributions Table -->
<table class="table is-fullwidth is-striped mt-4">
<thead>
<tr>
<th>Organization</th>
<th>Meals Contributed</th>
<th>Volunteers Contributed</th>
</tr>
</thead>
<tbody id="contributions-table">
{% for org in drive.driveorganization_set.all %}
{% if org.meal_pledge != 0 or org.volunteer_pledge != 0 %}
<tr>
<td>{{ org.organization.organization_name }}</td>
<td>{{ org.meal_pledge }}</td>
<td>{{ org.volunteer_pledge }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% if drive.driveorganization_set %}
{% for org in drive.driveorganization_set.all %}
{% if org.meal_pledge != 0 or org.volunteer_pledge != 0 %}
<div id="contributions">
<div class="container py-4">
</div>
</div>
{% endif %}
{% endfor %}
{% else %}
<p>No activity yet...</p>
{% endif %}

<!-- Contribute Modal -->
<div class="modal" id="contribute-modal">
Expand All @@ -96,7 +110,7 @@ <h1 class="title">{{ drive.name }}</h1>
<select id="donor_organization" name="donor_organization" required>
<option value="" disabled selected>Select Organization</option>
{% for org in active_user_orgs %}
<option value="{{ org.organization.organization_id }}">{{ org.organization.organization_name }}</option>
<option value="{{ org.organization.organization_id }}">{{ org.organization.organization_name }}</option>
{% endfor %}
</select>
</div>
Expand Down Expand Up @@ -125,5 +139,7 @@ <h1 class="title">{{ drive.name }}</h1>
</div>
</div>
</div>

{% endblock content %}
<script>
const driveId = "{{ drive.drive_id }}"
</script>
{% endblock content %}
17 changes: 9 additions & 8 deletions src/community_drives/templates/community_drives/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,19 @@ <h2 class="subtitle">Community Drives</h2>
<div class="card mb-5">
<div class="card-content">
<div class="columns is-vcentered is-flex-direction-column-mobile is-justify-content-space-between">
<div class="image-container has-text-centered mt-4">
<div class="image-container has-text-centered my-4 ml-4">
<!-- djlint:off -->
<img src="data:image/jpeg;base64,{{ drive.image_data }}"
alt="Default Image"
onerror="this.src='{% static 'default.png' %}';"
class="image is-square"
style="width: 600px; height: 300px; object-fit: cover; border-radius: 4px;">
class="image"
style="width: 200px; max-height: 80%; object-fit: cover; border-radius: 10px;">
<!-- djlint:on -->
</div>
<div class="column is-two-thirds is-full-mobile">
<p class="title is-4 is-clipped">{{ drive.name }}</p>
<p class="subtitle is-6 mt-2"><strong>Organizer:</strong> {{ drive.lead_organization }}</p>
<p class="mt-1 short-text mb-2">{{ drive.description }}</p>
<p class="mt-1 short-text mb-4">{{ drive.description }}</p>
<span class="tag is-primary is-light is-medium">Deadline: {{ drive.end_date }}</span>
<span class="tag is-primary is-light is-medium">Active: {{ drive.active }}</span>
</div>
Expand All @@ -153,13 +153,14 @@ <h2 class="subtitle">Community Drives</h2>
<div class="card mb-5">
<div class="card-content">
<div class="columns is-vcentered is-flex-direction-column-mobile is-justify-content-space-between">
<div class="image-container has-text-centered mt-4">
<div class="image-container has-text-centered my-4 ml-4">
<!-- djlint:off -->
<img src="data:image/jpeg;base64,{{ drive.image_data }}"
alt="Donation Image"
onerror="this.src='{% static 'default.png' %}';"
class="image is-square is-clickable"
data-drive-id="{{ drive.drive_id }}">
class="image is-clickable"
data-drive-id="{{ drive.drive_id }}"
style="width: 200px; max-height: 80%; object-fit: cover; border-radius: 10px;">
<!-- djlint:on -->
<!-- Hover Options -->
<div class="hover-options">
Expand All @@ -183,7 +184,7 @@ <h2 class="subtitle">Community Drives</h2>
<div class="column is-two-thirds is-full-mobile">
<p class="title is-4 is-clipped">{{ drive.name }}</p>
<p class="subtitle is-6 mt-2"><strong>Organizer:</strong> {{ drive.lead_organization }}</p>
<p class="mt-1 short-text mb-2">{{ drive.description }}</p>
<p class="mt-1 short-text mb-4">{{ drive.description }}</p>
<span class="tag is-primary is-light is-medium">Deadline: {{ drive.end_date }}</span>
<span class="tag is-primary is-light is-medium">Active: {{ drive.active }}</span>
</div>
Expand Down
5 changes: 5 additions & 0 deletions src/community_drives/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
views.get_participation_details,
name="participation-details",
),
path(
"fetch-contributions/<uuid:drive_id>/",
views.fetch_contributions,
name="fetch-contributions",
),
path(
"delete_participation/<uuid:organization_id>/<uuid:drive_id>/",
views.delete_participation,
Expand Down
44 changes: 41 additions & 3 deletions src/community_drives/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,64 @@ def get_drive_list(request):


def drive_dashboard(request, drive_id):
drive = get_object_or_404(CommunityDrive, pk=drive_id)
# participating_organizations = DriveOrganization.objects.filter(drive=drive)
drives = CommunityDrive.objects.annotate(
meal_progress=Coalesce(Sum("driveorganization__meal_pledge"), 0),
volunteer_progress=Coalesce(Sum("driveorganization__volunteer_pledge"), 0),
)
drive = get_object_or_404(drives, pk=drive_id)
participating_organizations = DriveOrganization.objects.filter(drive=drive)
participating_organizations = DriveOrganization.objects.filter(drive=drive).filter(
Q(meal_pledge__gte=1) | Q(volunteer_pledge__gte=1)
)

active_user_orgs = request.user.organizationadmin_set.filter(
organization__active=True
)
can_edit = any(
org_admin.organization_id == drive.lead_organization.organization_id
for org_admin in active_user_orgs
)
meals_percentage = (
(drive.meal_progress / drive.meal_target) * 100 if drive.meal_progress else 0
)
volunteers_percentage = (
(drive.volunteer_progress / drive.volunteer_target) * 100
if drive.volunteer_progress
else 0
)

context = {
"drive": drive,
"meals_percentage": meals_percentage,
"volunteers_percentage": volunteers_percentage,
"participating_organizations": participating_organizations,
"active_user_orgs": active_user_orgs,
"can_edit": can_edit,
}
return render(request, "community_drives/drive_dashboard.html", context)


def fetch_contributions(request, drive_id):
if request.method == "GET":
drive = get_object_or_404(CommunityDrive, pk=drive_id)

# Fetch all the DriveOrganization records for the drive
drive_organizations = DriveOrganization.objects.filter(drive=drive).filter(
Q(meal_pledge__gte=1) | Q(volunteer_pledge__gte=1)
)
# Prepare the response data, including updated table data
contributions = [
{
"organization_name": org.organization.organization_name,
"meals_contributed": org.meal_pledge,
"volunteers_contributed": org.volunteer_pledge,
"created_at": org.created_at,
}
for org in drive_organizations
]

return JsonResponse({"contributions": contributions})


def contribute_to_drive(request, drive_id):
if request.method == "POST":
try:
Expand Down Expand Up @@ -112,6 +148,7 @@ def contribute_to_drive(request, drive_id):
"organization_name": org.organization.organization_name,
"meals_contributed": org.meal_pledge,
"volunteers_contributed": org.volunteer_pledge,
"created_at": org.created_at,
}
for org in drive_organizations
]
Expand Down Expand Up @@ -206,6 +243,7 @@ def delete_participation(request, organization_id, drive_id):
"organization_name": org.organization.organization_name,
"meals_contributed": org.meal_pledge,
"volunteers_contributed": org.volunteer_pledge,
"created_at": org.created_at,
}
for org in drive_organizations
]
Expand Down
4 changes: 2 additions & 2 deletions src/donor_dashboard/templates/donor_dashboard/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ <h2 class="subtitle">Your Organizations</h2>
<p>
<div class="button is-link is-light has-text-centered"
style="white-space: normal; word-wrap: break-word; overflow-wrap: break-word;">
<p class="short-text">{{ org.org_address }}</p>
<p class="short-addr">{{ org.org_address }}</p>
</div>
</p>
<p class="icon-text mt-1 block" style="word-wrap: break-word; overflow-wrap: break-word;">
Expand Down Expand Up @@ -216,7 +216,7 @@ <h2 class="subtitle">Your Organizations</h2>
<p>
<div class="button is-link is-light has-text-centered"
style="white-space: normal; word-wrap: break-word; overflow-wrap: break-word;">
<p class="short-text">{{ org.org_address }}</p>
<p class="short-addr">{{ org.org_address }}</p>
</div>
</p>
<p class="icon-text mt-1 block" style="word-wrap: break-word; overflow-wrap: break-word;">
Expand Down
25 changes: 0 additions & 25 deletions src/donor_dashboard/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,31 +191,6 @@ def test_organization_details_view_post_valid(self):
self.organization.refresh_from_db()
self.assertEqual(self.organization.organization_name, "Updated Org")

def test_organization_details_view_post_invalid(self):
form_data = {
"organization_name": "",
"type": "self",
"address": "456 Updated Avenue",
"zipcode": "54321",
"email": "[email protected]",
"website": "https://updated.org",
"contact_number": "0987654321",
}
response = self.client.post(
reverse(
"donor_dashboard:organization_details",
args=[self.organization.organization_id],
),
form_data,
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "donor_dashboard/organization_details.html")
self.assertIsInstance(response.context["form"], AddOrganizationForm)
messages_list = list(messages.get_messages(response.wsgi_request))
self.assertEqual(
str(messages_list[0]), "Something went wrong, please enter valid inputs"
)

def test_delete_organization_view_post(self):
response = self.client.post(
reverse(
Expand Down
Loading

0 comments on commit bbaea71

Please sign in to comment.