Merge pull request 'feature/meetings' (#45) from feature/meetings into main
Reviewed-on: https://gitea.blackbusinesslabs.com/ATTUNE-HEART-THERAPY/alternative-backend-service/pulls/45
This commit is contained in:
commit
88cb7986cc
@ -18,10 +18,10 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email', 'first_name', 'last_name', 'password', 'password2'],
|
'required_fields': ['email', 'first_name', 'last_name', 'password', 'password2'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'first_name': 'John',
|
'first_name': 'Saani',
|
||||||
'last_name': 'Doe',
|
'last_name': 'Iddi',
|
||||||
'phone_number': '+1234567890',
|
'phone_number': '+233552732025',
|
||||||
'password': 'SecurePassword123',
|
'password': 'SecurePassword123',
|
||||||
'password2': 'SecurePassword123'
|
'password2': 'SecurePassword123'
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email', 'otp'],
|
'required_fields': ['email', 'otp'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'otp': '123456'
|
'otp': '123456'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -42,7 +42,7 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email', 'password'],
|
'required_fields': ['email', 'password'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'password': 'SecurePassword123'
|
'password': 'SecurePassword123'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -53,7 +53,7 @@ def api_root(request, format=None):
|
|||||||
'required_fields': ['email'],
|
'required_fields': ['email'],
|
||||||
'optional_fields': ['context (registration/password_reset)'],
|
'optional_fields': ['context (registration/password_reset)'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'context': 'registration'
|
'context': 'registration'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -63,7 +63,7 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email'],
|
'required_fields': ['email'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com'
|
'email': 'saanii929@gmail'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'verify_password_reset_otp': {
|
'verify_password_reset_otp': {
|
||||||
@ -72,7 +72,7 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email', 'otp'],
|
'required_fields': ['email', 'otp'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'otp': '123456'
|
'otp': '123456'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -82,7 +82,7 @@ def api_root(request, format=None):
|
|||||||
'methods': ['POST'],
|
'methods': ['POST'],
|
||||||
'required_fields': ['email', 'otp', 'new_password', 'confirm_password'],
|
'required_fields': ['email', 'otp', 'new_password', 'confirm_password'],
|
||||||
'example_request': {
|
'example_request': {
|
||||||
'email': 'user@example.com',
|
'email': 'saanii929@gmail',
|
||||||
'otp': '123456',
|
'otp': '123456',
|
||||||
'new_password': 'NewSecurePassword123',
|
'new_password': 'NewSecurePassword123',
|
||||||
'confirm_password': 'NewSecurePassword123'
|
'confirm_password': 'NewSecurePassword123'
|
||||||
@ -104,9 +104,9 @@ def api_root(request, format=None):
|
|||||||
"authentication": "Required (Authenticated users only)",
|
"authentication": "Required (Authenticated users only)",
|
||||||
"required_fields": ["first_name", "last_name", "phone_number"],
|
"required_fields": ["first_name", "last_name", "phone_number"],
|
||||||
"example_request": {
|
"example_request": {
|
||||||
"first_name": "John",
|
"first_name": "Saani",
|
||||||
"last_name": "Doe",
|
"last_name": "Iddi",
|
||||||
"phone_number": "+1234567890"
|
"phone_number": "+233552732025"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"get_profile": {
|
"get_profile": {
|
||||||
@ -291,8 +291,10 @@ def api_root(request, format=None):
|
|||||||
"user_appointments": {
|
"user_appointments": {
|
||||||
"description": "Get appointments for the authenticated user",
|
"description": "Get appointments for the authenticated user",
|
||||||
"url": request.build_absolute_uri("/api/meetings/user/appointments/"),
|
"url": request.build_absolute_uri("/api/meetings/user/appointments/"),
|
||||||
"methods": ["GET"],
|
"methods": ["GET", "POST"],
|
||||||
"authentication": "Required",
|
"authentication": "Required",
|
||||||
|
"request_fields": ["email"],
|
||||||
|
"example_request": {"email": "saanii929@gmail.com"},
|
||||||
"response": "List of user's appointment requests with enhanced availability data"
|
"response": "List of user's appointment requests with enhanced availability data"
|
||||||
},
|
},
|
||||||
"schedule_appointment": {
|
"schedule_appointment": {
|
||||||
|
|||||||
@ -232,7 +232,6 @@ class WeeklyAvailabilityView(generics.GenericAPIView):
|
|||||||
|
|
||||||
return Response(weekly_availability)
|
return Response(weekly_availability)
|
||||||
|
|
||||||
|
|
||||||
class UserAppointmentsView(generics.ListAPIView):
|
class UserAppointmentsView(generics.ListAPIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
serializer_class = AppointmentRequestSerializer
|
serializer_class = AppointmentRequestSerializer
|
||||||
@ -242,6 +241,26 @@ class UserAppointmentsView(generics.ListAPIView):
|
|||||||
email=self.request.user.email
|
email=self.request.user.email
|
||||||
).order_by('-created_at')
|
).order_by('-created_at')
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
email = request.data.get('email')
|
||||||
|
|
||||||
|
if not email:
|
||||||
|
return Response(
|
||||||
|
{"error": "Email is required"},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
|
if email != request.user.email:
|
||||||
|
return Response(
|
||||||
|
{"error": "You can only view your own appointments"},
|
||||||
|
status=status.HTTP_403_FORBID_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
|
appointments = AppointmentRequest.objects.filter(email__iexact=email).order_by('-created_at')
|
||||||
|
|
||||||
|
serializer = self.get_serializer(appointments, many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class AppointmentStatsView(generics.GenericAPIView):
|
class AppointmentStatsView(generics.GenericAPIView):
|
||||||
permission_classes = [IsAuthenticated, IsAdminUser]
|
permission_classes = [IsAuthenticated, IsAdminUser]
|
||||||
@ -285,15 +304,14 @@ class UserAppointmentStatsView(generics.GenericAPIView):
|
|||||||
status=status.HTTP_403_FORBIDDEN
|
status=status.HTTP_403_FORBIDDEN
|
||||||
)
|
)
|
||||||
|
|
||||||
stats = AppointmentRequest.objects.filter(
|
appointments = AppointmentRequest.objects.filter(email__iexact=email)
|
||||||
email=email
|
stats = {
|
||||||
).aggregate(
|
'total': appointments.count(),
|
||||||
total=Count('id'),
|
'pending': appointments.filter(status='pending_review').count(),
|
||||||
pending=Count('id', filter=Q(status='pending_review')),
|
'scheduled': appointments.filter(status='scheduled').count(),
|
||||||
scheduled=Count('id', filter=Q(status='scheduled')),
|
'rejected': appointments.filter(status='rejected').count(),
|
||||||
rejected=Count('id', filter=Q(status='rejected')),
|
'completed': appointments.filter(status='completed').count(),
|
||||||
completed=Count('id', filter=Q(status='completed'))
|
}
|
||||||
)
|
|
||||||
|
|
||||||
total = stats['total']
|
total = stats['total']
|
||||||
scheduled = stats['scheduled']
|
scheduled = stats['scheduled']
|
||||||
@ -309,7 +327,6 @@ class UserAppointmentStatsView(generics.GenericAPIView):
|
|||||||
'email': email
|
'email': email
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class MatchingAvailabilityView(generics.GenericAPIView):
|
class MatchingAvailabilityView(generics.GenericAPIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
|||||||
@ -286,14 +286,6 @@
|
|||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div class="email-footer">
|
<div class="email-footer">
|
||||||
<div class="company-name">{{ settings.SITE_NAME|default:"Attune Heart Therapy" }}</div>
|
<div class="company-name">{{ settings.SITE_NAME|default:"Attune Heart Therapy" }}</div>
|
||||||
<p class="support-info">
|
|
||||||
Need help? Contact our support team at
|
|
||||||
<a
|
|
||||||
href="mailto:hello@attunehearttherapy.com"
|
|
||||||
style="color: #fff; text-decoration: none"
|
|
||||||
>hello@attunehearttherapy.com</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p class="copyright">
|
<p class="copyright">
|
||||||
© {% now "Y" %} {{ settings.SITE_NAME|default:"Attune Heart Therapy" }}.
|
© {% now "Y" %} {{ settings.SITE_NAME|default:"Attune Heart Therapy" }}.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|||||||
@ -295,9 +295,9 @@
|
|||||||
<p class="support-info">
|
<p class="support-info">
|
||||||
Need help? Contact our support team at
|
Need help? Contact our support team at
|
||||||
<a
|
<a
|
||||||
href="mailto:hello@attunehearttherapy.com"
|
href="mailto:admin@attunehearttherapy.com"
|
||||||
style="color: #fff; text-decoration: none"
|
style="color: #fff; text-decoration: none"
|
||||||
>hello@attunehearttherapy.com</a
|
>admin@attunehearttherapy.com</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="copyright">
|
<p class="copyright">
|
||||||
|
|||||||
@ -274,9 +274,9 @@
|
|||||||
<p class="support-info">
|
<p class="support-info">
|
||||||
Need help? Contact our support team at
|
Need help? Contact our support team at
|
||||||
<a
|
<a
|
||||||
href="mailto:{{ support_email }}"
|
href="mailto:admin@attunehearttherapy.com"
|
||||||
style="color: #fff; text-decoration: none"
|
style="color: #fff; text-decoration: none"
|
||||||
>hello@attunehearttherapy.com</a
|
>admin@attunehearttherapy.com</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="copyright">
|
<p class="copyright">
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{% block title %}Attune Heart Therapy{% endblock %}</title>
|
<title>{% block title %}Attune Heart Therapy{% endblock %}</title>
|
||||||
<style>
|
<style>
|
||||||
/* Reset styles for email compatibility */
|
|
||||||
body, table, td, div, p, a {
|
body, table, td, div, p, a {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@ -165,9 +165,9 @@
|
|||||||
<p class="support-info">
|
<p class="support-info">
|
||||||
Need help? Contact our support team at
|
Need help? Contact our support team at
|
||||||
<a
|
<a
|
||||||
href="mailto:{{ support_email }}"
|
href="mailto:admin@attunehearttherapy.com"
|
||||||
style="color: #fff; text-decoration: none"
|
style="color: #fff; text-decoration: none"
|
||||||
>{{ support_email }}</a
|
>admin@attunehearttherapy.com</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="copyright">
|
<p class="copyright">
|
||||||
|
|||||||
@ -156,9 +156,9 @@
|
|||||||
<p class="support-info">
|
<p class="support-info">
|
||||||
Need help? Contact our support team at
|
Need help? Contact our support team at
|
||||||
<a
|
<a
|
||||||
href="mailto:{{ support_email }}"
|
href="mailto:admin@attunehearttherapy.com"
|
||||||
style="color: #fff; text-decoration: none"
|
style="color: #fff; text-decoration: none"
|
||||||
>{{ support_email }}</a
|
>admin@attunehearttherapy.com</a
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="copyright">
|
<p class="copyright">
|
||||||
|
|||||||
@ -17,7 +17,7 @@ def send_otp_via_email(email, otp, user_name=None, context='registration'):
|
|||||||
'otp': otp,
|
'otp': otp,
|
||||||
'expiry_minutes': 10,
|
'expiry_minutes': 10,
|
||||||
'company_name': 'Attune Heart Therapy',
|
'company_name': 'Attune Heart Therapy',
|
||||||
'support_email': 'hello@attunehearttherapy.com',
|
'support_email': 'admin@attunehearttherapy.com',
|
||||||
'current_year': timezone.now().year,
|
'current_year': timezone.now().year,
|
||||||
'email_context': context
|
'email_context': context
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user