diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 384084c..198b087 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 50e031b..6abdf0f 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/templates/core/blood_request_list.html b/core/templates/core/blood_request_list.html index a128447..86d24d8 100644 --- a/core/templates/core/blood_request_list.html +++ b/core/templates/core/blood_request_list.html @@ -76,7 +76,13 @@ {% endif %} {% if user.is_authenticated and user.donor_profile and req.user != user %} - Volunteer + {% if can_volunteer %} + Volunteer + {% else %} + + {% endif %} {% endif %} Call diff --git a/core/templates/core/chat.html b/core/templates/core/chat.html index d6b7d29..e868a41 100644 --- a/core/templates/core/chat.html +++ b/core/templates/core/chat.html @@ -115,13 +115,28 @@ Online -
+
+
diff --git a/core/templates/core/donation_history.html b/core/templates/core/donation_history.html index 775b4af..9756377 100644 --- a/core/templates/core/donation_history.html +++ b/core/templates/core/donation_history.html @@ -84,7 +84,7 @@
{{ donation.donor_user.username }}
-
Verified Hero
+
Verified Champion
diff --git a/core/templates/core/donor_list.html b/core/templates/core/donor_list.html index a8c4345..b7caea6 100644 --- a/core/templates/core/donor_list.html +++ b/core/templates/core/donor_list.html @@ -78,8 +78,8 @@
- - {% if donor.is_available %}Available{% else %}Unavailable{% endif %} + + {% if donor.on_break %}On Break ({{ donor.days_remaining }}d){% elif donor.is_available %}Available{% else %}Unavailable{% endif %}

Phone: {{ donor.phone }}

diff --git a/core/templates/core/inbox.html b/core/templates/core/inbox.html index 025d72a..6de5e22 100644 --- a/core/templates/core/inbox.html +++ b/core/templates/core/inbox.html @@ -13,30 +13,40 @@ {% if conversations %}
{% for conv in conversations %} - -
- {% if conv.user.profile.profile_pic %} - {{ conv.user.username }} - {% else %} -
- -
- {% endif %} -
-
- {% else %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index d16a1a1..d7a3b4b 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -111,50 +111,6 @@ border-radius: 10px; } - .hero-section { - background: linear-gradient(135deg, #1a1a1a, #2d1b1b); - border: 1px solid rgba(255, 215, 0, 0.3); - border-radius: 16px; - padding: 12px 16px; - margin-bottom: 20px; - position: relative; - } - .hero-item { - background: rgba(255, 255, 255, 0.05); - border-radius: 12px; - padding: 8px 12px; - margin-right: 10px; - border: 1px solid rgba(255, 215, 0, 0.1); - display: inline-flex; - align-items: center; - gap: 10px; - min-width: 180px; - } - .live-pulse { - width: 8px; - height: 8px; - background: #FF4D4D; - border-radius: 50%; - display: inline-block; - margin-right: 5px; - box-shadow: 0 0 0 rgba(255, 77, 77, 0.4); - animation: pulse 2s infinite; - } - @keyframes pulse { - 0% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0.7); } - 70% { box-shadow: 0 0 0 10px rgba(255, 77, 77, 0); } - 100% { box-shadow: 0 0 0 0 rgba(255, 77, 77, 0); } - } - .heroes-scroll { - display: flex; - overflow-x: auto; - padding: 5px 0; - scrollbar-width: none; - } - .heroes-scroll::-webkit-scrollbar { - display: none; - } - .filter-btn { background: #ffffff; border: 1px solid var(--border-color); @@ -292,7 +248,6 @@
-

Hero Community

@@ -300,35 +255,6 @@
- {% if recent_heroes %} -
-
- - - Live: Today's Heroes (Last 24h) - - {{ recent_heroes.count }} Active -
-
- {% for hero in recent_heroes %} -
- {% if hero.donor.user and hero.donor.user.profile.profile_pic %} - - {% else %} -
- {{ hero.donor.blood_group }} -
- {% endif %} -
-

{{ hero.donor.name }}

-

Saved Life {{ hero.date|timesince }} ago

-
-
- {% endfor %} -
-
- {% endif %} - diff --git a/core/templates/core/lives_saved.html b/core/templates/core/lives_saved.html index becbc6a..089f410 100644 --- a/core/templates/core/lives_saved.html +++ b/core/templates/core/lives_saved.html @@ -44,7 +44,7 @@ - + diff --git a/core/templates/core/profile.html b/core/templates/core/profile.html index 1ee9c72..82c6acd 100644 --- a/core/templates/core/profile.html +++ b/core/templates/core/profile.html @@ -174,12 +174,18 @@

Clearing personal info will remove your bio, location, phone number, and profile picture. Your account and donation history will remain intact.

-
+ {% csrf_token %} - +
+ {% csrf_token %} + +
diff --git a/core/templates/core/register.html b/core/templates/core/register.html index 002a541..93569b9 100644 --- a/core/templates/core/register.html +++ b/core/templates/core/register.html @@ -11,7 +11,7 @@

Join RaktaPulse

-

Be a hero. Start saving lives today.

+

Join our mission. Start saving lives today.

diff --git a/core/urls.py b/core/urls.py index 18c4bf7..bb63c67 100644 --- a/core/urls.py +++ b/core/urls.py @@ -18,6 +18,8 @@ urlpatterns = [ path("chat//", views.chat, name="chat"), path("notifications/", views.notifications_view, name="notifications"), path("delete-personal-info/", views.delete_personal_info, name="delete_personal_info"), + path("delete-messages//", views.delete_messages, name="delete_messages"), + path("delete-account/", views.delete_account, name="delete_account"), # Donor & Blood Management path("donors/", views.donor_list, name="donor_list"), diff --git a/core/views.py b/core/views.py index 9795189..56e8139 100644 --- a/core/views.py +++ b/core/views.py @@ -172,14 +172,40 @@ def delete_personal_info(request): profile.phone = "" profile.birth_date = None profile.profile_pic = None - # We keep blood_group as it's often essential for the app's functionality (blood donation) - # but we can clear it if the user really wants to. - # For now, let's just clear the "soft" personal info. profile.save() + # If they have a donor profile, clear that too (or keep it but mark unavailable) + if hasattr(user, 'donor_profile'): + donor = user.donor_profile + donor.phone = "" + donor.location = "" + donor.save() + messages.success(request, "Your non-essential personal information has been cleared.") return redirect('profile') +@login_required +@require_POST +def delete_messages(request, username): + """Delete all messages between the current user and another user.""" + other_user = User.objects.get(username=username) + Message.objects.filter( + (Q(sender=request.user) & Q(receiver=other_user)) | + (Q(sender=other_user) & Q(receiver=request.user)) + ).delete() + messages.success(request, f"Conversation with {username} has been deleted.") + return redirect('inbox') + +@login_required +@require_POST +def delete_account(request): + """Delete the user's account and all associated data.""" + user = request.user + logout(request) # Logout before deleting to clear session + user.delete() + messages.success(request, "Your account and all associated data have been permanently deleted.") + return redirect('welcome') + def haversine(lat1, lon1, lat2, lon2): # Radius of the Earth in km R = 6371.0 @@ -244,7 +270,7 @@ def home(request): # Ensure default badges exist if Badge.objects.count() == 0: Badge.objects.create(name='First-Time Donor', description='Completed your first donation!', icon_class='fas fa-award') - Badge.objects.create(name='Community Hero', description='Completed 5 donations!', icon_class='fas fa-medal') + Badge.objects.create(name='Community Champion', description='Completed 5 donations!', icon_class='fas fa-medal') Badge.objects.create(name='Life Saver', description='Completed 10+ donations!', icon_class='fas fa-heart') donors = Donor.objects.all() @@ -285,9 +311,9 @@ def home(request): actual_completed = DonationEvent.objects.filter(is_completed=True).count() completed_donations = actual_completed + demo_donations - # Find Recent Heroes (Last 24 Hours) + # Find Recent Contributions (Last 24 Hours) last_24_hours = timezone.now() - timezone.timedelta(hours=24) - recent_heroes = DonationEvent.objects.filter( + recent_contributions = DonationEvent.objects.filter( is_completed=True, date__gte=last_24_hours ).select_related('donor').order_by('-date') @@ -327,7 +353,7 @@ def home(request): "blood_banks": blood_banks, "blood_groups": [g[0] for g in BLOOD_GROUPS], "stats": stats, - "recent_heroes": recent_heroes, + "recent_contributions": recent_contributions, "project_name": "RaktaPulse", "current_time": timezone.now(), "myths_vs_facts": myths_vs_facts, @@ -378,6 +404,15 @@ def donor_list(request): else: donor_list_data.sort(key=lambda x: (-x.is_verified, x.name)) + # Check 90-day availability + for d in donor_list_data: + if d.last_donation_date: + days_since = (timezone.now().date() - d.last_donation_date).days + if days_since < 90: + d.is_available = False + d.on_break = True + d.days_remaining = 90 - days_since + context = { 'donors': donor_list_data, 'blood_groups': [g[0] for g in BLOOD_GROUPS], @@ -391,9 +426,22 @@ def blood_request_list(request): requests = requests.filter(status=status) requests = requests.order_by('-created_at') + + can_volunteer = True + days_until_eligible = 0 + if request.user.is_authenticated: + donor_profile = getattr(request.user, 'donor_profile', None) + if donor_profile and donor_profile.last_donation_date: + days_since = (timezone.now().date() - donor_profile.last_donation_date).days + if days_since < 90: + can_volunteer = False + days_until_eligible = 90 - days_since + context = { 'requests': requests, 'current_status': status, + 'can_volunteer': can_volunteer, + 'days_until_eligible': days_until_eligible, } return render(request, 'core/blood_request_list.html', context) @@ -604,6 +652,14 @@ def volunteer_for_request(request, request_id): messages.error(request, "You need to be registered as a donor to volunteer.") return redirect('donor_list') + # Check for 3-month (90 days) restriction + if donor_profile.last_donation_date: + days_since_last_donation = (timezone.now().date() - donor_profile.last_donation_date).days + if days_since_last_donation < 90: + remaining_days = 90 - days_since_last_donation + messages.error(request, f"For your safety, you must wait 3 months (90 days) between donations. You can volunteer again in {remaining_days} days.") + return redirect('blood_request_list') + # Prevent requester from volunteering for their own request if blood_request.user == request.user: messages.error(request, "You cannot volunteer for your own blood request.") @@ -642,6 +698,11 @@ def complete_donation(request, event_id): event.is_completed = True event.save() + # Update donor's last donation date + if event.donor: + event.donor.last_donation_date = timezone.now().date() + event.donor.save() + # Award Badges Logic donor_profile = event.donor_user.profile completed_count = DonationEvent.objects.filter(donor_user=event.donor_user, is_completed=True).count() @@ -652,7 +713,7 @@ def complete_donation(request, event_id): donor_profile.badges.add(badge) if completed_count >= 5: - badge = Badge.objects.filter(name='Community Hero').first() + badge = Badge.objects.filter(name='Community Champion').first() if badge: donor_profile.badges.add(badge)
HeroChampion Impact Location Date