From d5c3f12dbb6abfc0f0c544c83c3d567e2bee1a6a Mon Sep 17 00:00:00 2001 From: saani Date: Mon, 1 Dec 2025 18:40:56 +0000 Subject: [PATCH] feat: refactor contact message handling and update appointment request model --- ...ntrequest_jitsi_meeting_config_and_more.py | 77 +++++++++++++++++++ ...meetings_ap_jitsi_m_f3c488_idx_and_more.py | 66 ++++++++++++++++ users/urls.py | 2 +- users/views.py | 31 ++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 meetings/migrations/0003_appointmentrequest_jitsi_meeting_config_and_more.py create mode 100644 meetings/migrations/0004_remove_appointmentrequest_meetings_ap_jitsi_m_f3c488_idx_and_more.py diff --git a/meetings/migrations/0003_appointmentrequest_jitsi_meeting_config_and_more.py b/meetings/migrations/0003_appointmentrequest_jitsi_meeting_config_and_more.py new file mode 100644 index 0000000..081cbe4 --- /dev/null +++ b/meetings/migrations/0003_appointmentrequest_jitsi_meeting_config_and_more.py @@ -0,0 +1,77 @@ +# Generated by Django 5.2.8 on 2025-12-01 16:22 + +import meetings.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('meetings', '0002_alter_appointmentrequest_jitsi_room_id'), + ] + + operations = [ + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_meeting_config', + field=models.JSONField(default=dict, help_text='Jitsi meeting configuration and settings'), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_meeting_created', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_meeting_data', + field=models.JSONField(default=dict, help_text='Additional meeting data (participants, duration, etc)'), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_meeting_password', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_moderator_token', + field=meetings.models.EncryptedTextField(blank=True, null=True), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_participant_token', + field=meetings.models.EncryptedTextField(blank=True, null=True), + ), + migrations.AddField( + model_name='appointmentrequest', + name='jitsi_recording_url', + field=models.URLField(blank=True, help_text='URL to meeting recording', null=True), + ), + migrations.AddField( + model_name='appointmentrequest', + name='meeting_duration_actual', + field=models.PositiveIntegerField(default=0, help_text='Actual meeting duration in minutes'), + ), + migrations.AddField( + model_name='appointmentrequest', + name='meeting_ended_at', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='appointmentrequest', + name='meeting_started_at', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AlterField( + model_name='appointmentrequest', + name='jitsi_room_id', + field=models.CharField(blank=True, help_text='Jitsi room ID', max_length=100, null=True, unique=True), + ), + migrations.AddIndex( + model_name='appointmentrequest', + index=models.Index(fields=['jitsi_meeting_created', 'scheduled_datetime'], name='meetings_ap_jitsi_m_f3c488_idx'), + ), + migrations.AddIndex( + model_name='appointmentrequest', + index=models.Index(fields=['meeting_started_at'], name='meetings_ap_meeting_157142_idx'), + ), + ] diff --git a/meetings/migrations/0004_remove_appointmentrequest_meetings_ap_jitsi_m_f3c488_idx_and_more.py b/meetings/migrations/0004_remove_appointmentrequest_meetings_ap_jitsi_m_f3c488_idx_and_more.py new file mode 100644 index 0000000..4ec9658 --- /dev/null +++ b/meetings/migrations/0004_remove_appointmentrequest_meetings_ap_jitsi_m_f3c488_idx_and_more.py @@ -0,0 +1,66 @@ +# Generated by Django 5.2.8 on 2025-12-01 18:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('meetings', '0003_appointmentrequest_jitsi_meeting_config_and_more'), + ] + + operations = [ + migrations.RemoveIndex( + model_name='appointmentrequest', + name='meetings_ap_jitsi_m_f3c488_idx', + ), + migrations.RemoveIndex( + model_name='appointmentrequest', + name='meetings_ap_meeting_157142_idx', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_meeting_config', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_meeting_created', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_meeting_data', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_meeting_password', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_moderator_token', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_participant_token', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='jitsi_recording_url', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='meeting_duration_actual', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='meeting_ended_at', + ), + migrations.RemoveField( + model_name='appointmentrequest', + name='meeting_started_at', + ), + migrations.AlterField( + model_name='appointmentrequest', + name='jitsi_room_id', + field=models.CharField(blank=True, default=None, help_text='Jitsi room ID', max_length=100, null=True, unique=True), + ), + ] diff --git a/users/urls.py b/users/urls.py index 34d68f6..26335c2 100644 --- a/users/urls.py +++ b/users/urls.py @@ -3,7 +3,7 @@ from rest_framework_simplejwt.views import TokenRefreshView from . import views urlpatterns = [ - path('contact/', views.ContactMessageView.as_view(), name='contact-message'), + path('contact/', views.contact_message, name='contact-message'), path('register/', views.register_user, name='register'), diff --git a/users/views.py b/users/views.py index c088f75..a6ba58e 100644 --- a/users/views.py +++ b/users/views.py @@ -17,6 +17,8 @@ import logging logger = logging.getLogger(__name__) class ContactMessageView(APIView): + permission_classes = [AllowAny] + def post(self, request): serializer = ContactMessageSerializer(data=request.data) @@ -44,7 +46,36 @@ class ContactMessageView(APIView): 'message': 'Please check your input and try again.', 'errors': serializer.errors }, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +@permission_classes([AllowAny]) +def contact_message(request): + serializer = ContactMessageSerializer(data=request.data) + if serializer.is_valid(): + try: + contact_message = serializer.save() + + send_email_notifications(contact_message) + + return Response({ + 'success': True, + 'message': 'Thank you for your message. We will get back to you soon!', + 'data': serializer.data + }, status=status.HTTP_201_CREATED) + + except Exception as e: + logger.error(f"Error processing contact form: {str(e)}") + return Response({ + 'success': False, + 'message': 'There was an error processing your request. Please try again later.' + }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + return Response({ + 'success': False, + 'message': 'Please check your input and try again.', + 'errors': serializer.errors + }, status=status.HTTP_400_BAD_REQUEST) -- 2.39.5