diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index c051bcf..9aced4f 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 291d043..0b62db9 100644 --- a/config/settings.py +++ b/config/settings.py @@ -180,3 +180,6 @@ if EMAIL_USE_SSL: # https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +LOGIN_URL = '/login/' +LOGIN_REDIRECT_URL = '/' diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index c16c351..7b9a1bb 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 33dad94..a179ffa 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index bd06905..1c540d8 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 bbc52d0..976cbe8 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index d255c1f..660771f 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,5 +1,11 @@ from django.contrib import admin -from .models import Donor, BloodRequest, BloodBank +from .models import Donor, BloodRequest, BloodBank, VaccineRecord + +@admin.register(VaccineRecord) +class VaccineRecordAdmin(admin.ModelAdmin): + list_display = ('vaccine_name', 'user', 'dose_number', 'date_taken', 'location') + list_filter = ('vaccine_name', 'date_taken') + search_fields = ('vaccine_name', 'user__username', 'location') @admin.register(Donor) class DonorAdmin(admin.ModelAdmin): diff --git a/core/migrations/0004_vaccinerecord.py b/core/migrations/0004_vaccinerecord.py new file mode 100644 index 0000000..71a2d25 --- /dev/null +++ b/core/migrations/0004_vaccinerecord.py @@ -0,0 +1,30 @@ +# Generated by Django 5.2.7 on 2026-02-17 14:37 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_donor_citizenship_no_donor_district_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='VaccineRecord', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vaccine_name', models.CharField(max_length=100)), + ('dose_number', models.PositiveIntegerField(default=1)), + ('date_taken', models.DateField()), + ('location', models.CharField(max_length=255)), + ('center_name', models.CharField(blank=True, max_length=255, null=True)), + ('notes', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vaccine_records', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0005_bloodbank_latitude_bloodbank_longitude.py b/core/migrations/0005_bloodbank_latitude_bloodbank_longitude.py new file mode 100644 index 0000000..a1a60e1 --- /dev/null +++ b/core/migrations/0005_bloodbank_latitude_bloodbank_longitude.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2026-02-17 15:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_vaccinerecord'), + ] + + operations = [ + migrations.AddField( + model_name='bloodbank', + name='latitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True), + ), + migrations.AddField( + model_name='bloodbank', + name='longitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True), + ), + ] diff --git a/core/migrations/0006_bloodrequest_latitude_bloodrequest_longitude.py b/core/migrations/0006_bloodrequest_latitude_bloodrequest_longitude.py new file mode 100644 index 0000000..dc1ede4 --- /dev/null +++ b/core/migrations/0006_bloodrequest_latitude_bloodrequest_longitude.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.7 on 2026-02-17 15:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0005_bloodbank_latitude_bloodbank_longitude'), + ] + + operations = [ + migrations.AddField( + model_name='bloodrequest', + name='latitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True), + ), + migrations.AddField( + model_name='bloodrequest', + name='longitude', + field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True), + ), + ] diff --git a/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc b/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc new file mode 100644 index 0000000..2dabec1 Binary files /dev/null and b/core/migrations/__pycache__/0004_vaccinerecord.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc b/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc new file mode 100644 index 0000000..e1a0ddd Binary files /dev/null and b/core/migrations/__pycache__/0005_bloodbank_latitude_bloodbank_longitude.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc b/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc new file mode 100644 index 0000000..144b2a2 Binary files /dev/null and b/core/migrations/__pycache__/0006_bloodrequest_latitude_bloodrequest_longitude.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index b7d3d8f..1c10aac 100644 --- a/core/models.py +++ b/core/models.py @@ -1,5 +1,19 @@ from django.db import models from django.utils import timezone +from django.contrib.auth.models import User + +class VaccineRecord(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='vaccine_records') + vaccine_name = models.CharField(max_length=100) + dose_number = models.PositiveIntegerField(default=1) + date_taken = models.DateField() + location = models.CharField(max_length=255) + center_name = models.CharField(max_length=255, null=True, blank=True) + notes = models.TextField(blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"{self.vaccine_name} - Dose {self.dose_number} for {self.user.username}" class Donor(models.Model): BLOOD_GROUPS = [ @@ -38,6 +52,8 @@ class BloodRequest(models.Model): location = models.CharField(max_length=255) urgency = models.CharField(max_length=10, choices=URGENCY_LEVELS, default='NORMAL') hospital = models.CharField(max_length=255) + latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) + longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) contact_number = models.CharField(max_length=20) required_date = models.DateField(default=timezone.now) status = models.CharField(max_length=20, default='Active') @@ -49,6 +65,8 @@ class BloodRequest(models.Model): class BloodBank(models.Model): name = models.CharField(max_length=100) location = models.CharField(max_length=255) + latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) + longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True) contact_number = models.CharField(max_length=20, null=True, blank=True) is_24_7 = models.BooleanField(default=True) stock_a_plus = models.IntegerField(default=0) diff --git a/core/templates/base.html b/core/templates/base.html index 73ae1ea..1437535 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -199,14 +199,18 @@
  • Donors
  • Blood Requests
  • Blood Banks
  • +
  • Live Alerts
  • Vaccination
  • + {% if user.is_authenticated %} +
  • My Records
  • + {% endif %}
  • Settings
  • Need Help?

    - Emergency: 911 + Emergency: 1115
    @@ -226,6 +230,10 @@
    +
    + + Detect Location +
    {{ current_time|date:"D, M d, Y" }} @@ -245,6 +253,16 @@
    + {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} {% block content %}{% endblock %}
    @@ -265,7 +283,51 @@ } }); - // Active class is handled server-side via Django templates. + function detectLocation() { + const text = document.getElementById('location-text'); + const originalText = text.innerText; + text.innerText = "Locating..."; + + if ("geolocation" in navigator) { + navigator.geolocation.getCurrentPosition(function(position) { + const lat = position.coords.latitude; + const lng = position.coords.longitude; + text.innerText = lat.toFixed(4) + ", " + lng.toFixed(4); + + // Save to cookies for 1 day + document.cookie = `user_lat=${lat}; path=/; max-age=86400`; + document.cookie = `user_lng=${lng}; path=/; max-age=86400`; + + // If we are on a list page without lat/lng, reload with them + const urlParams = new URLSearchParams(window.location.search); + if (!urlParams.has('lat')) { + urlParams.set('lat', lat); + urlParams.set('lng', lng); + window.location.search = urlParams.toString(); + } + }, function(error) { + text.innerText = "Error"; + console.error(error); + }); + } else { + text.innerText = "Not supported"; + } + } + + // Check if location is already in cookies + function checkLocationCookie() { + const cookies = document.cookie.split(';'); + let lat = null, lng = null; + for (let cookie of cookies) { + const [name, value] = cookie.trim().split('='); + if (name === 'user_lat') lat = value; + if (name === 'user_lng') lng = value; + } + if (lat && lng) { + document.getElementById('location-text').innerText = parseFloat(lat).toFixed(4) + ", " + parseFloat(lng).toFixed(4); + } + } + checkLocationCookie(); {% block scripts %}{% endblock %} diff --git a/core/templates/core/add_vaccination.html b/core/templates/core/add_vaccination.html new file mode 100644 index 0000000..502a9cb --- /dev/null +++ b/core/templates/core/add_vaccination.html @@ -0,0 +1,74 @@ +{% extends "base.html" %} +{% load static %} + +{% block title %}Add Vaccination Record - {{ project_name }}{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    +
    + +
    +

    Add Vaccine Record

    +

    Keep your immunization data accurate and up to date.

    +
    + +
    + {% csrf_token %} + +
    + + +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + Cancel +
    +
    +
    +
    +
    +
    +{% endblock %} diff --git a/core/templates/core/blood_bank_list.html b/core/templates/core/blood_bank_list.html index dff5f0f..d133653 100644 --- a/core/templates/core/blood_bank_list.html +++ b/core/templates/core/blood_bank_list.html @@ -6,24 +6,47 @@ {% block content %}
    -
    +

    Blood Banks

    Official blood repositories and their current inventory levels.

    +
    + + Reset + +
    {% for bank in banks %}
    -
    +

    {{ bank.name }}

    {% if bank.is_24_7 %} 24/7 Available {% endif %}
    -

    {{ bank.location }}

    -

    {{ bank.contact_number }}

    + + {% if bank.distance and bank.distance < 1000 %} +
    + + {{ bank.distance|floatformat:1 }} km away from you + +
    + {% endif %} + +

    {{ bank.location }}

    +

    + + {{ bank.contact_number }} + +

    Inventory Levels (Units)
    @@ -77,7 +100,7 @@
    - + Contact Bank
    {% empty %} @@ -89,3 +112,30 @@
    {% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/core/templates/core/blood_request_list.html b/core/templates/core/blood_request_list.html index f4ff8fd..71f97e8 100644 --- a/core/templates/core/blood_request_list.html +++ b/core/templates/core/blood_request_list.html @@ -24,7 +24,7 @@

    Blood Requests

    Current active requirements for blood in various hospitals.

    - + Post a Request diff --git a/core/templates/core/donor_list.html b/core/templates/core/donor_list.html index c91d16f..b391186 100644 --- a/core/templates/core/donor_list.html +++ b/core/templates/core/donor_list.html @@ -70,10 +70,13 @@

    Phone: {{ donor.phone }}

    - - - - {% endblock %} + Contact Now + + {% endfor %} + + + +{% endblock %} {% block scripts %} +{% endblock %} diff --git a/core/templates/core/login.html b/core/templates/core/login.html index b95e6de..0fefcb6 100644 --- a/core/templates/core/login.html +++ b/core/templates/core/login.html @@ -3,58 +3,97 @@ {% block title %}Login - RaktaPulse{% endblock %} {% block content %} -
    +
    -
    -
    -