diff --git a/backend/djangoindia/api/serializers/partner_and_sponsor.py b/backend/djangoindia/api/serializers/partner_and_sponsor.py index 7b57b3de..93a440f9 100644 --- a/backend/djangoindia/api/serializers/partner_and_sponsor.py +++ b/backend/djangoindia/api/serializers/partner_and_sponsor.py @@ -19,4 +19,4 @@ class CommunityPartnerSerializer(serializers.Serializer): class CommunityPartnerAndSponsorSerializer(serializers.Serializer): sponsors = SponsorSerializer(many=True, read_only=True, source='community_sponsors') - partners = CommunityPartnerSerializer(many=True, read_only=True) \ No newline at end of file + partners = CommunityPartnerSerializer(many=True, read_only=True, source='community_partners') \ No newline at end of file diff --git a/backend/djangoindia/api/views/event.py b/backend/djangoindia/api/views/event.py index b4974757..5a772e4b 100644 --- a/backend/djangoindia/api/views/event.py +++ b/backend/djangoindia/api/views/event.py @@ -12,7 +12,7 @@ from djangoindia.constants import POST, PRIMARY_KEY_SHORT from django.db.models import Prefetch - +from django.utils import timezone # Create your views here. class EventAPIView( @@ -56,24 +56,51 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): try: - if EventRegistration.objects.filter( - email=request.data.get("email"), event=request.data.get("event") - ).exists(): - return Response( - {"message": "We get it, you’re excited. But you've already secured your ticket!"}, - status=status.HTTP_409_CONFLICT, - ) - self.create(request, *args, **kwargs) - - # send email after registration - recipient_email = request.data.get("email") event_id = request.data.get("event") - registration_confirmation_email_task.delay(recipient_email, event_id) + email = request.data.get("email") + + event = self.get_event(event_id) + self.validate_event_registration(event) + self.check_existing_registration(email, event_id) + + self.create(request, *args, **kwargs) + self.send_confirmation_email(email, event_id) + return Response( {"message": "You're in! We've sent a shiny email to your inbox. Time to celebrate!"}, - status=status.HTTP_201_CREATED, + status=status.HTTP_201_CREATED ) + except ValidationError as e: + return Response({"message": str(e)}, status=status.HTTP_400_BAD_REQUEST) + except ConflictError as e: + return Response({"message": str(e)}, status=status.HTTP_409_CONFLICT) except Exception as e: - return Response( - {"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR - ) + return Response({"message": "An unexpected error occurred."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def get_event(self, event_id): + try: + return Event.objects.get(id=event_id) + except Event.DoesNotExist: + raise ValidationError("Event not found.") + + def validate_event_registration(self, event): + if event.registration_end_date <= timezone.now(): + raise ValidationError("Registration has already ended for this event.") + if event.seats_left is None: + raise ValidationError("Registration hasn't started yet.") + if event.seats_left < 1: + raise ValidationError("Unfortunately, there are no more seats left for the event.") + + + def check_existing_registration(self, email, event_id): + if EventRegistration.objects.filter(email=email, event=event_id).exists(): + raise ConflictError("We get it, you're excited. But you've already secured your ticket!") + + def send_confirmation_email(self, email, event_id): + registration_confirmation_email_task.delay(email, event_id) + +class ValidationError(Exception): + pass + +class ConflictError(Exception): + pass \ No newline at end of file diff --git a/backend/djangoindia/api/views/partner_and_sponsor.py b/backend/djangoindia/api/views/partner_and_sponsor.py index 32e1bd21..7af0f290 100644 --- a/backend/djangoindia/api/views/partner_and_sponsor.py +++ b/backend/djangoindia/api/views/partner_and_sponsor.py @@ -23,9 +23,4 @@ def get_queryset(self): return { 'community_partners': partners_queryset, 'community_sponsors': sponsors_queryset - } - - def get(self, request): - queryset = self.get_queryset() - serializer = CommunityPartnerAndSponsorSerializer(queryset) - return Response(serializer.data) \ No newline at end of file + } \ No newline at end of file diff --git a/backend/djangoindia/db/admin.py b/backend/djangoindia/db/admin.py index 0bb6b5c6..cd5b3396 100644 --- a/backend/djangoindia/db/admin.py +++ b/backend/djangoindia/db/admin.py @@ -29,7 +29,7 @@ def send_email_to_selected_users(modeladmin, request, queryset): class SponsorInline(admin.TabularInline): model = Sponsorship - extra = 1 + extra = 1 @admin.register(Event) class EventAdmin(admin.ModelAdmin): diff --git a/frontend/src/containers/Event/Event.tsx b/frontend/src/containers/Event/Event.tsx index aa92cf12..28767f40 100644 --- a/frontend/src/containers/Event/Event.tsx +++ b/frontend/src/containers/Event/Event.tsx @@ -70,8 +70,8 @@ const EventContainer = async ({

{name}

{start_date?(Starts {dayjs(start_date).format('DD MMMM, YYYY')} at {dayjs(start_date).format('hh:mm A')}):(Starts: TBA)} {city && City: {city}} - {seats_left && Seats left: {seats_left}} - + {seats_left != null&& Seats left: {seats_left}} +
Hey Everyone @@ -92,7 +92,7 @@ const EventContainer = async ({ {dayjs(start_date).format('hh:mm A')} - {end_date && ` - ${dayjs(end_date).format('DD MMMM, YYYY')}`} + {end_date && ` - ${dayjs(end_date).format('hh:mm A')}`} {/* TODO: Use text variant of button */}
) diff --git a/frontend/src/containers/RegisterEvent/RegisterEvent.tsx b/frontend/src/containers/RegisterEvent/RegisterEvent.tsx index 16d6abc7..57f83cb7 100644 --- a/frontend/src/containers/RegisterEvent/RegisterEvent.tsx +++ b/frontend/src/containers/RegisterEvent/RegisterEvent.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react' import { yupResolver } from '@hookform/resolvers/yup' +import dayjs from 'dayjs'; import { Drawer, @@ -33,7 +34,7 @@ import { REGISTER_FORM_FIELDS } from './RegisterEvent.config' import { fetchData } from '@/utils' import { enqueueSnackbar } from 'notistack' -export const RegisterEvent = ({ eventId }: { eventId: string }) => { +export const RegisterEvent = ({ eventId, seats_left, registration_end_date }: { eventId: string, seats_left: number, registration_end_date: string }) => { const [isOpen, setIsOpen] = useState(false) const { @@ -76,14 +77,21 @@ export const RegisterEvent = ({ eventId }: { eventId: string }) => { reset() setIsOpen(false) } - + + const currentDate = dayjs(); return ( - + {seats_left !== 0 && seats_left != null && currentDate.isBefore(dayjs(registration_end_date)) ? ( + + ) : ( seats_left != null && + + )}
diff --git a/frontend/src/sections/EventSection/EventCard.tsx b/frontend/src/sections/EventSection/EventCard.tsx index e1dce514..23204323 100644 --- a/frontend/src/sections/EventSection/EventCard.tsx +++ b/frontend/src/sections/EventSection/EventCard.tsx @@ -17,7 +17,7 @@ interface EventProps { venue: string time: string event_mode: string - seats_left: BigInteger + seats_left: number } const EventCard: React.FC = ({ diff --git a/frontend/src/types/events.ts b/frontend/src/types/events.ts index 8d6fe8f3..8c66b155 100644 --- a/frontend/src/types/events.ts +++ b/frontend/src/types/events.ts @@ -11,7 +11,7 @@ export type Event = { end_date: string registration_end_date: string event_mode: string - seats_left: BigInteger + seats_left: number } export type EventsResponse = Event[]