713 lines
27 KiB
Python
713 lines
27 KiB
Python
import os
|
|
import platform
|
|
import math
|
|
from django.db.models import Q
|
|
from django.shortcuts import render, redirect
|
|
from django.contrib.auth import login, logout, authenticate
|
|
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib import messages
|
|
from django.utils import timezone
|
|
from django.contrib.auth.models import User
|
|
from .models import Donor, BloodRequest, BloodBank, VaccineRecord, UserProfile, BLOOD_GROUPS, DonationEvent, Notification, Hospital, Message, Badge, HealthReport
|
|
|
|
from .forms import UserUpdateForm, ProfileUpdateForm, UserRegisterForm
|
|
|
|
from django.http import JsonResponse
|
|
from django.views.decorators.http import require_POST
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
import json
|
|
|
|
@login_required
|
|
@csrf_exempt
|
|
def emergency_sms(request):
|
|
"""Concept demo for sending SMS to nearby donors."""
|
|
if request.method == "POST":
|
|
try:
|
|
data = json.loads(request.body)
|
|
blood_group = data.get('blood_group')
|
|
lat = data.get('latitude')
|
|
lng = data.get('longitude')
|
|
except json.JSONDecodeError:
|
|
blood_group = request.POST.get('blood_group')
|
|
lat = request.POST.get('latitude')
|
|
lng = request.POST.get('longitude')
|
|
|
|
if not (blood_group and lat and lng):
|
|
return JsonResponse({'status': 'error', 'message': 'Missing data'}, status=400)
|
|
|
|
if not (blood_group and lat and lng):
|
|
return JsonResponse({'status': 'error', 'message': 'Missing data'}, status=400)
|
|
|
|
try:
|
|
u_lat = float(lat)
|
|
u_lng = float(lng)
|
|
|
|
# Find donors within 10km
|
|
all_donors = Donor.objects.filter(blood_group=blood_group, is_available=True)
|
|
nearby_donors = []
|
|
|
|
for d in all_donors:
|
|
if d.latitude and d.longitude:
|
|
dist = haversine(u_lat, u_lng, float(d.latitude), float(d.longitude))
|
|
if dist <= 10.0: # 10 km radius
|
|
nearby_donors.append(d)
|
|
|
|
# Simulated SMS sending
|
|
count = len(nearby_donors)
|
|
for d in nearby_donors:
|
|
# In a real app, we'd call an SMS API here
|
|
# Notification.objects.create(user=d.user, message=f"EMERGENCY: {blood_group} blood needed nearby! Please check RaktaPulse.")
|
|
print(f"Simulated SMS to {d.phone}: EMERGENCY {blood_group} needed!")
|
|
|
|
return JsonResponse({
|
|
'status': 'success',
|
|
'message': f'SMS Alert sent to {count} nearby donors!',
|
|
'count': count
|
|
})
|
|
except Exception as e:
|
|
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Only POST allowed'}, status=405)
|
|
|
|
@login_required
|
|
@csrf_exempt
|
|
@require_POST
|
|
def update_location(request):
|
|
try:
|
|
data = json.loads(request.body)
|
|
lat = data.get('latitude')
|
|
lng = data.get('longitude')
|
|
|
|
if lat and lng:
|
|
profile = request.user.profile
|
|
profile.latitude = lat
|
|
profile.longitude = lng
|
|
profile.last_location_update = timezone.now()
|
|
profile.save()
|
|
return JsonResponse({'status': 'success'})
|
|
except Exception as e:
|
|
return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
|
|
return JsonResponse({'status': 'error', 'message': 'Invalid data'}, status=400)
|
|
|
|
def hospital_list(request):
|
|
user_lat = request.GET.get('lat')
|
|
user_lng = request.GET.get('lng')
|
|
|
|
hospitals = Hospital.objects.all()
|
|
hospital_list_data = list(hospitals)
|
|
|
|
if user_lat and user_lng:
|
|
try:
|
|
u_lat = float(user_lat)
|
|
u_lng = float(user_lng)
|
|
for h in hospital_list_data:
|
|
if h.latitude and h.longitude:
|
|
h.distance = haversine(u_lat, u_lng, float(h.latitude), float(h.longitude))
|
|
else:
|
|
h.distance = 999999
|
|
hospital_list_data.sort(key=lambda x: x.distance)
|
|
except ValueError:
|
|
hospital_list_data.sort(key=lambda x: x.name)
|
|
else:
|
|
hospital_list_data.sort(key=lambda x: x.name)
|
|
|
|
return render(request, 'core/hospital_list.html', {'hospitals': hospital_list_data})
|
|
|
|
@login_required
|
|
def profile(request):
|
|
# Ensure user has a profile
|
|
profile, created = UserProfile.objects.get_or_create(user=request.user)
|
|
|
|
if request.method == 'POST':
|
|
u_form = UserUpdateForm(request.POST, instance=request.user)
|
|
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=profile)
|
|
if u_form.is_valid() and p_form.is_valid():
|
|
u_form.save()
|
|
p_form.save()
|
|
messages.success(request, f'Your account has been updated!')
|
|
return redirect('profile')
|
|
else:
|
|
u_form = UserUpdateForm(instance=request.user)
|
|
p_form = ProfileUpdateForm(instance=profile)
|
|
|
|
context = {
|
|
'u_form': u_form,
|
|
'p_form': p_form
|
|
}
|
|
|
|
return render(request, 'core/profile.html', context)
|
|
|
|
@login_required
|
|
@require_POST
|
|
def delete_personal_info(request):
|
|
"""View to clear non-essential personal information."""
|
|
user = request.user
|
|
profile = user.profile
|
|
|
|
# Clear User fields
|
|
user.first_name = ""
|
|
user.last_name = ""
|
|
user.save()
|
|
|
|
# Clear Profile fields
|
|
profile.bio = ""
|
|
profile.location = ""
|
|
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()
|
|
|
|
messages.success(request, "Your non-essential personal information has been cleared.")
|
|
return redirect('profile')
|
|
|
|
def haversine(lat1, lon1, lat2, lon2):
|
|
# Radius of the Earth in km
|
|
R = 6371.0
|
|
|
|
dlat = math.radians(lat2 - lat1)
|
|
dlon = math.radians(lon2 - lon1)
|
|
|
|
a = math.sin(dlat / 2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2)**2
|
|
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
|
|
|
|
return R * c
|
|
|
|
def login_view(request):
|
|
if request.method == "POST":
|
|
form = AuthenticationForm(request, data=request.POST)
|
|
if form.is_valid():
|
|
user = form.get_user()
|
|
login(request, user)
|
|
messages.success(request, f"Welcome back, {user.username}!")
|
|
return redirect("home")
|
|
else:
|
|
messages.error(request, "Invalid username or password. Please try again.")
|
|
else:
|
|
form = AuthenticationForm()
|
|
return render(request, "core/login.html", {"form": form})
|
|
|
|
def logout_view(request):
|
|
logout(request)
|
|
return redirect("home")
|
|
|
|
def register_view(request):
|
|
if request.method == "POST":
|
|
form = UserRegisterForm(request.POST)
|
|
if form.is_valid():
|
|
user = form.save()
|
|
profile = user.profile
|
|
profile.blood_group = form.cleaned_data.get('blood_group')
|
|
profile.location = form.cleaned_data.get('location')
|
|
profile.phone = form.cleaned_data.get('phone')
|
|
profile.save()
|
|
|
|
login(request, user)
|
|
messages.success(request, f"Welcome to RaktaPulse, {user.username}! You are now a registered donor.")
|
|
return redirect("home")
|
|
else:
|
|
form = UserRegisterForm()
|
|
return render(request, "core/register.html", {"form": form})
|
|
|
|
def welcome(request):
|
|
"""Render a beautiful animated welcome page."""
|
|
if request.user.is_authenticated:
|
|
return redirect('home')
|
|
return render(request, "core/welcome.html")
|
|
|
|
def home(request):
|
|
"""Render the RaktaPulse Dashboard experience."""
|
|
query_blood = request.GET.get('blood_group', '')
|
|
query_location = request.GET.get('location', '')
|
|
user_lat = request.GET.get('lat')
|
|
user_lng = request.GET.get('lng')
|
|
|
|
# Initialize default badges if they don't exist (Demo purposes)
|
|
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='Life Saver', description='Completed 10+ donations!', icon_class='fas fa-heart')
|
|
|
|
donors = Donor.objects.all()
|
|
if query_blood:
|
|
donors = donors.filter(blood_group=query_blood)
|
|
if query_location:
|
|
donors = donors.filter(location__icontains=query_location)
|
|
|
|
donor_list_data = list(donors)
|
|
|
|
if user_lat and user_lng:
|
|
try:
|
|
u_lat = float(user_lat)
|
|
u_lng = float(user_lng)
|
|
for d in donor_list_data:
|
|
if d.latitude and d.longitude:
|
|
d.distance = haversine(u_lat, u_lng, float(d.latitude), float(d.longitude))
|
|
else:
|
|
d.distance = 999999 # Very far
|
|
donor_list_data.sort(key=lambda x: x.distance)
|
|
except ValueError:
|
|
donor_list_data.sort(key=lambda x: (-x.is_available, x.name))
|
|
else:
|
|
donor_list_data.sort(key=lambda x: (-x.is_available, x.name))
|
|
|
|
blood_requests = BloodRequest.objects.filter(status='Active').order_by('-urgency', '-created_at')
|
|
blood_banks = BloodBank.objects.all()
|
|
|
|
# Stats for Dashboard (Including Demo Data for Impact)
|
|
demo_donations = 157
|
|
demo_donors = 48
|
|
|
|
actual_completed = DonationEvent.objects.filter(is_completed=True).count()
|
|
completed_donations = actual_completed + demo_donations
|
|
|
|
stats = {
|
|
"total_donors": Donor.objects.count() + demo_donors,
|
|
"active_requests": BloodRequest.objects.filter(status='Active').count(),
|
|
"total_stock": sum([
|
|
bb.stock_a_plus + bb.stock_a_minus + bb.stock_b_plus + bb.stock_b_minus +
|
|
bb.stock_o_plus + bb.stock_o_minus + bb.stock_ab_plus + bb.stock_ab_minus
|
|
for bb in blood_banks
|
|
]),
|
|
"total_capacity": sum([bb.total_capacity * 8 for bb in blood_banks]), # 8 blood types
|
|
"vaccinated_percentage": 0,
|
|
"completed_donations": completed_donations,
|
|
"lives_saved": completed_donations * 3
|
|
}
|
|
|
|
total_d = stats["total_donors"]
|
|
if total_d > 0:
|
|
vaccinated_count = Donor.objects.filter(vaccination_status__icontains='Fully').count()
|
|
stats["vaccinated_percentage"] = int((vaccinated_count / total_d) * 100)
|
|
|
|
myths_vs_facts = [
|
|
{"myth": "Donating blood is painful.", "fact": "You only feel a quick pinch, like a mosquito bite."},
|
|
{"myth": "I'm too old to donate.", "fact": "There is no upper age limit as long as you're healthy."},
|
|
{"myth": "It takes all day to donate.", "fact": "The actual donation takes about 10 minutes, the whole process is under an hour."},
|
|
{"myth": "Giving blood makes you weak.", "fact": "Your body replaces fluids within 24 hours and cells within weeks."},
|
|
{"myth": "I can't donate because I have high BP.", "fact": "As long as it's within 180/100 at the time of donation, you're fine."},
|
|
]
|
|
|
|
context = {
|
|
"donors": donor_list_data[:8],
|
|
"blood_requests": blood_requests[:6],
|
|
"blood_banks": blood_banks,
|
|
"blood_groups": [g[0] for g in BLOOD_GROUPS],
|
|
"stats": stats,
|
|
"project_name": "RaktaPulse",
|
|
"current_time": timezone.now(),
|
|
"myths_vs_facts": myths_vs_facts,
|
|
}
|
|
|
|
if request.user.is_authenticated:
|
|
# Get active involvements
|
|
involved_events = DonationEvent.objects.filter(
|
|
(Q(donor_user=request.user) | Q(request__user=request.user)),
|
|
is_completed=False
|
|
)
|
|
context["involved_events"] = involved_events
|
|
context["user_badges"] = request.user.profile.badges.all()
|
|
|
|
return render(request, "core/index.html", context)
|
|
|
|
def donor_list(request):
|
|
query = request.GET.get('q', '')
|
|
blood_group = request.GET.get('blood_group', '')
|
|
district = request.GET.get('district', '')
|
|
user_lat = request.GET.get('lat')
|
|
user_lng = request.GET.get('lng')
|
|
|
|
donors = Donor.objects.all()
|
|
if query:
|
|
donors = donors.filter(Q(name__icontains=query) | Q(location__icontains=query))
|
|
if blood_group:
|
|
donors = donors.filter(blood_group=blood_group)
|
|
if district:
|
|
donors = donors.filter(district__icontains=district)
|
|
|
|
donor_list_data = list(donors)
|
|
|
|
if user_lat and user_lng:
|
|
try:
|
|
u_lat = float(user_lat)
|
|
u_lng = float(user_lng)
|
|
for d in donor_list_data:
|
|
if d.latitude and d.longitude:
|
|
d.distance = haversine(u_lat, u_lng, float(d.latitude), float(d.longitude))
|
|
else:
|
|
d.distance = 999999
|
|
donor_list_data.sort(key=lambda x: x.distance)
|
|
except ValueError:
|
|
donor_list_data.sort(key=lambda x: (-x.is_verified, x.name))
|
|
else:
|
|
donor_list_data.sort(key=lambda x: (-x.is_verified, x.name))
|
|
|
|
context = {
|
|
'donors': donor_list_data,
|
|
'blood_groups': [g[0] for g in BLOOD_GROUPS],
|
|
}
|
|
return render(request, 'core/donor_list.html', context)
|
|
|
|
def blood_request_list(request):
|
|
status = request.GET.get('status', '')
|
|
requests = BloodRequest.objects.all()
|
|
if status:
|
|
requests = requests.filter(status=status)
|
|
|
|
requests = requests.order_by('-created_at')
|
|
context = {
|
|
'requests': requests,
|
|
'current_status': status,
|
|
}
|
|
return render(request, 'core/blood_request_list.html', context)
|
|
|
|
def blood_bank_list(request):
|
|
user_lat = request.GET.get('lat')
|
|
user_lng = request.GET.get('lng')
|
|
|
|
banks = BloodBank.objects.all()
|
|
bank_list_data = list(banks)
|
|
|
|
if user_lat and user_lng:
|
|
try:
|
|
u_lat = float(user_lat)
|
|
u_lng = float(user_lng)
|
|
for b in bank_list_data:
|
|
if b.latitude and b.longitude:
|
|
b.distance = haversine(u_lat, u_lng, float(b.latitude), float(b.longitude))
|
|
else:
|
|
b.distance = 999999
|
|
bank_list_data.sort(key=lambda x: x.distance)
|
|
except ValueError:
|
|
pass
|
|
|
|
context = {
|
|
'banks': bank_list_data,
|
|
}
|
|
return render(request, 'core/blood_bank_list.html', context)
|
|
|
|
def vaccination_info(request):
|
|
stats = {
|
|
"total_donors": Donor.objects.count(),
|
|
"vaccinated_count": Donor.objects.filter(vaccination_status__icontains='Fully').count(),
|
|
}
|
|
if stats["total_donors"] > 0:
|
|
stats["percentage"] = int((stats["vaccinated_count"] / stats["total_donors"]) * 100)
|
|
else:
|
|
stats["percentage"] = 0
|
|
|
|
return render(request, 'core/vaccination_info.html', {'stats': stats})
|
|
|
|
def live_map(request):
|
|
"""View to display live alerts/requests on a map."""
|
|
active_requests = BloodRequest.objects.filter(status='Active').order_by('-created_at')
|
|
|
|
# Also include blood banks and donors optionally if we want a full map
|
|
# But focusing on alerts as requested.
|
|
context = {
|
|
'requests': active_requests,
|
|
'title': 'Live Alert Map',
|
|
}
|
|
return render(request, 'core/live_map.html', context)
|
|
|
|
def request_blood(request):
|
|
"""View to create a new blood request with geolocation."""
|
|
if request.method == "POST":
|
|
patient_name = request.POST.get('patient_name')
|
|
blood_group = request.POST.get('blood_group')
|
|
location = request.POST.get('location')
|
|
urgency = request.POST.get('urgency')
|
|
hospital = request.POST.get('hospital')
|
|
contact_number = request.POST.get('contact_number')
|
|
image = request.FILES.get('image')
|
|
latitude = request.POST.get('latitude')
|
|
longitude = request.POST.get('longitude')
|
|
|
|
if patient_name and blood_group and hospital and contact_number:
|
|
BloodRequest.objects.create(
|
|
user=request.user if request.user.is_authenticated else None,
|
|
patient_name=patient_name,
|
|
blood_group=blood_group,
|
|
location=location,
|
|
urgency=urgency,
|
|
hospital=hospital,
|
|
contact_number=contact_number,
|
|
image=image,
|
|
latitude=latitude if latitude else None,
|
|
longitude=longitude if longitude else None
|
|
)
|
|
messages.success(request, "Blood request posted successfully! Help is on the way.")
|
|
return redirect('blood_request_list')
|
|
else:
|
|
messages.error(request, "Please fill in all required fields.")
|
|
|
|
context = {
|
|
'blood_groups': [g[0] for g in BLOOD_GROUPS],
|
|
'urgency_levels': BloodRequest.URGENCY_LEVELS,
|
|
'selected_hospital': request.GET.get('hospital', ''),
|
|
}
|
|
return render(request, 'core/request_blood.html', context)
|
|
|
|
@login_required
|
|
@login_required
|
|
def vaccination_dashboard(request):
|
|
records = VaccineRecord.objects.filter(user=request.user).order_by('-date_taken')
|
|
reports = HealthReport.objects.filter(user=request.user).order_by('-report_date')
|
|
context = {
|
|
'records': records,
|
|
'reports': reports,
|
|
'project_name': "RaktaPulse",
|
|
}
|
|
return render(request, 'core/vaccination_dashboard.html', context)
|
|
|
|
@login_required
|
|
def add_vaccination(request):
|
|
if request.method == "POST":
|
|
vaccine_name = request.POST.get('vaccine_name')
|
|
dose_number = request.POST.get('dose_number')
|
|
date_taken = request.POST.get('date_taken')
|
|
location = request.POST.get('location')
|
|
center_name = request.POST.get('center_name')
|
|
notes = request.POST.get('notes')
|
|
photo = request.FILES.get('photo')
|
|
|
|
if vaccine_name and dose_number and date_taken:
|
|
VaccineRecord.objects.create(
|
|
user=request.user,
|
|
vaccine_name=vaccine_name,
|
|
dose_number=dose_number,
|
|
date_taken=date_taken,
|
|
location=location,
|
|
center_name=center_name,
|
|
notes=notes,
|
|
photo=photo
|
|
)
|
|
messages.success(request, "Vaccination record added successfully!")
|
|
return redirect('vaccination_dashboard')
|
|
else:
|
|
messages.error(request, "Please fill in all required fields.")
|
|
|
|
return render(request, 'core/add_vaccination.html')
|
|
|
|
@login_required
|
|
def volunteer_for_request(request, request_id):
|
|
blood_request = BloodRequest.objects.get(id=request_id)
|
|
donor_profile = getattr(request.user, 'donor_profile', None)
|
|
|
|
if not donor_profile:
|
|
messages.error(request, "You need to be registered as a donor to volunteer.")
|
|
return redirect('donor_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.")
|
|
return redirect('blood_request_list')
|
|
|
|
# Check if already volunteered
|
|
if DonationEvent.objects.filter(donor=donor_profile, request=blood_request).exists():
|
|
messages.warning(request, "You have already volunteered for this request.")
|
|
else:
|
|
DonationEvent.objects.create(
|
|
donor=donor_profile,
|
|
request=blood_request,
|
|
donor_user=request.user
|
|
)
|
|
messages.success(request, "Thank you for volunteering! The requester has been notified.")
|
|
|
|
# Notify the requester
|
|
if blood_request.user:
|
|
Notification.objects.create(
|
|
user=blood_request.user,
|
|
message=f"Donor {request.user.username} has volunteered to help {blood_request.patient_name}!"
|
|
)
|
|
|
|
return redirect('blood_request_list')
|
|
|
|
@login_required
|
|
def complete_donation(request, event_id):
|
|
event = DonationEvent.objects.get(id=event_id)
|
|
# Only the requester or the donor can mark as complete
|
|
if request.user == event.donor_user or (event.request.user and request.user == event.request.user):
|
|
event.is_completed = True
|
|
event.save()
|
|
|
|
# Award Badges Logic
|
|
donor_profile = event.donor_user.profile
|
|
completed_count = DonationEvent.objects.filter(donor_user=event.donor_user, is_completed=True).count()
|
|
|
|
if completed_count >= 1:
|
|
badge = Badge.objects.filter(name='First-Time Donor').first()
|
|
if badge:
|
|
donor_profile.badges.add(badge)
|
|
|
|
if completed_count >= 5:
|
|
badge = Badge.objects.filter(name='Community Hero').first()
|
|
if badge:
|
|
donor_profile.badges.add(badge)
|
|
|
|
if completed_count >= 10:
|
|
badge = Badge.objects.filter(name='Life Saver').first()
|
|
if badge:
|
|
donor_profile.badges.add(badge)
|
|
|
|
# Notify both
|
|
Notification.objects.create(
|
|
user=event.donor_user,
|
|
message=f"Thank you for your donation to {event.request.patient_name}! You've earned recognition for your impact."
|
|
)
|
|
if event.request.user:
|
|
Notification.objects.create(
|
|
user=event.request.user,
|
|
message=f"We hope the donation for {event.request.patient_name} went well."
|
|
)
|
|
|
|
messages.success(request, "Donation marked as completed. Thank you!")
|
|
else:
|
|
messages.error(request, "You are not authorized to complete this event.")
|
|
|
|
return redirect('home')
|
|
|
|
@login_required
|
|
def notifications_view(request):
|
|
notifications = Notification.objects.filter(user=request.user).order_by('-created_at')
|
|
# Mark as read when viewed
|
|
notifications.filter(is_read=False).update(is_read=True)
|
|
return render(request, 'core/notifications.html', {'notifications': notifications})
|
|
|
|
@login_required
|
|
def register_donor(request):
|
|
if hasattr(request.user, 'donor_profile'):
|
|
messages.info(request, "You are already registered as a donor.")
|
|
return redirect('profile')
|
|
|
|
if request.method == "POST":
|
|
blood_group = request.POST.get('blood_group')
|
|
location = request.POST.get('location')
|
|
phone = request.POST.get('phone')
|
|
|
|
if blood_group and phone:
|
|
Donor.objects.create(
|
|
user=request.user,
|
|
name=request.user.username,
|
|
blood_group=blood_group,
|
|
location=location,
|
|
phone=phone,
|
|
is_available=True
|
|
)
|
|
messages.success(request, "Congratulations! You are now a registered donor.")
|
|
return redirect('donor_list')
|
|
else:
|
|
messages.error(request, "Please fill in all required fields.")
|
|
|
|
return render(request, 'core/register_donor.html', {'blood_groups': [g[0] for g in BLOOD_GROUPS]})
|
|
|
|
def public_profile(request, username):
|
|
user = User.objects.get(username=username)
|
|
profile = user.profile
|
|
donor_profile = getattr(user, 'donor_profile', None)
|
|
|
|
context = {
|
|
'profile_user': user,
|
|
'profile': profile,
|
|
'donor': donor_profile,
|
|
}
|
|
return render(request, 'core/public_profile.html', context)
|
|
|
|
@login_required
|
|
def inbox(request):
|
|
# Get all users the current user has messaged or received messages from
|
|
sent_to = Message.objects.filter(sender=request.user).values_list('receiver', flat=True)
|
|
received_from = Message.objects.filter(receiver=request.user).values_list('sender', flat=True)
|
|
user_ids = set(list(sent_to) + list(received_from))
|
|
|
|
users = User.objects.filter(id__in=user_ids)
|
|
|
|
# Get last message for each conversation
|
|
conversations = []
|
|
for user in users:
|
|
last_message = Message.objects.filter(
|
|
(Q(sender=request.user) & Q(receiver=user)) |
|
|
(Q(sender=user) & Q(receiver=request.user))
|
|
).order_by('-timestamp').first()
|
|
conversations.append({
|
|
'user': user,
|
|
'last_message': last_message
|
|
})
|
|
|
|
conversations.sort(key=lambda x: x['last_message'].timestamp, reverse=True)
|
|
|
|
return render(request, 'core/inbox.html', {'conversations': conversations})
|
|
|
|
@login_required
|
|
def chat(request, username):
|
|
other_user = User.objects.get(username=username)
|
|
if request.method == "POST":
|
|
content = request.POST.get('content')
|
|
attachment = request.FILES.get('attachment')
|
|
sticker_id = request.POST.get('sticker_id')
|
|
|
|
msg_type = 'text'
|
|
if sticker_id:
|
|
msg_type = 'sticker'
|
|
elif attachment:
|
|
content_type = attachment.content_type
|
|
if content_type.startswith('image/'):
|
|
msg_type = 'image'
|
|
elif content_type.startswith('video/'):
|
|
msg_type = 'video'
|
|
else:
|
|
msg_type = 'file'
|
|
|
|
if content or attachment or sticker_id:
|
|
Message.objects.create(
|
|
sender=request.user,
|
|
receiver=other_user,
|
|
content=content,
|
|
attachment=attachment,
|
|
message_type=msg_type,
|
|
sticker_id=sticker_id
|
|
)
|
|
return redirect('chat', username=username)
|
|
|
|
messages = Message.objects.filter(
|
|
(Q(sender=request.user) & Q(receiver=other_user)) |
|
|
(Q(sender=other_user) & Q(receiver=request.user))
|
|
).order_by('timestamp')
|
|
|
|
# Mark as read
|
|
Message.objects.filter(sender=other_user, receiver=request.user, is_read=False).update(is_read=True)
|
|
|
|
return render(request, 'core/chat.html', {'other_user': other_user, 'chat_messages': messages})
|
|
|
|
@login_required
|
|
def upload_health_report(request):
|
|
if request.method == "POST":
|
|
title = request.POST.get('title')
|
|
hospital_name = request.POST.get('hospital_name')
|
|
report_file = request.FILES.get('report_file')
|
|
description = request.POST.get('description')
|
|
report_date = request.POST.get('report_date')
|
|
next_test_date = request.POST.get('next_test_date')
|
|
allow_notifications = request.POST.get('allow_notifications') == 'on'
|
|
|
|
if title and report_file and report_date:
|
|
HealthReport.objects.create(
|
|
user=request.user,
|
|
title=title,
|
|
hospital_name=hospital_name,
|
|
report_file=report_file,
|
|
description=description,
|
|
report_date=report_date,
|
|
next_test_date=next_test_date if next_test_date else None,
|
|
allow_notifications=allow_notifications
|
|
)
|
|
messages.success(request, "Health report uploaded successfully!")
|
|
return redirect('vaccination_dashboard')
|
|
else:
|
|
messages.error(request, "Please fill in all required fields.")
|
|
|
|
return render(request, 'core/upload_health_report.html')
|