diff --git a/backend/djangoindia/bg_tasks/event_registration.py b/backend/djangoindia/bg_tasks/event_registration.py index 1ea4c97..4641e6b 100644 --- a/backend/djangoindia/bg_tasks/event_registration.py +++ b/backend/djangoindia/bg_tasks/event_registration.py @@ -55,8 +55,8 @@ def registration_confirmation_email_task(email, event_id): print(f"Error sending email: {e}") -@shared_task(bind=True, max_retries=3) -def send_mass_mail_task(self, emails, **kwargs): +@shared_task +def send_mass_mail_task(emails, **kwargs): """ Converts django.core.mail.send_mass_email into a background task. @@ -73,7 +73,7 @@ def send_mass_mail_task(self, emails, **kwargs): ) try: - return send_mass_mail(emails, **kwargs) + send_mass_mail(emails, **kwargs) except Exception: logger.exception("Failed to send mass emails.") logger.debug("Detailed exception information:", exc_info=True) diff --git a/backend/djangoindia/db/admin.py b/backend/djangoindia/db/admin.py index 828d42c..00d8a8c 100644 --- a/backend/djangoindia/db/admin.py +++ b/backend/djangoindia/db/admin.py @@ -125,7 +125,7 @@ def send_email_view(self, request): recipient_email = registration.email emails.append((subject, message, from_email, [recipient_email])) - send_mass_mail_task(emails, fail_silently=False) + send_mass_mail_task.delay(emails, fail_silently=False) messages.success( request, f"{len(emails)} emails sent successfully." ) diff --git a/backend/djangoindia/db/models/event.py b/backend/djangoindia/db/models/event.py index 489944d..1998ea0 100644 --- a/backend/djangoindia/db/models/event.py +++ b/backend/djangoindia/db/models/event.py @@ -1,4 +1,7 @@ +import html + from cabinet.models import Folder +from django_prose_editor.fields import ProseEditorField from django.core.exceptions import ValidationError from django.db import models @@ -22,7 +25,7 @@ class EventModes(models.TextChoices): name = models.CharField(max_length=255, unique=True) slug = models.SlugField(max_length=255) cover_image = models.ImageField(upload_to="event_images/", blank=True) - description = models.TextField() + description = ProseEditorField() venue = models.TextField(default="TBA", null=True, blank=True) city = models.CharField(max_length=255, default="TBA", null=True, blank=True) venue_map_link = models.TextField(null=True, blank=True) @@ -42,6 +45,7 @@ def __str__(self) -> str: def save(self, *args, **kwargs): self.slug = slugify(self.name) + self.description = html.unescape(self.description) super().save(*args, **kwargs) diff --git a/backend/djangoindia/db/templatetags/__init__.py b/backend/djangoindia/db/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/djangoindia/db/templatetags/form_tags.py b/backend/djangoindia/db/templatetags/form_tags.py new file mode 100644 index 0000000..0b9d35d --- /dev/null +++ b/backend/djangoindia/db/templatetags/form_tags.py @@ -0,0 +1,14 @@ +from django import template + + +register = template.Library() + + +@register.filter(name="add_class") +def add_class(value, arg): + css_classes = value.field.widget.attrs.get("class", "") + if css_classes: + css_classes = f"{css_classes} {arg}" + else: + css_classes = arg + return value.as_widget(attrs={"class": css_classes}) diff --git a/backend/templates/admin/send_email.html b/backend/templates/admin/send_email.html index ef7e89b..c11010f 100644 --- a/backend/templates/admin/send_email.html +++ b/backend/templates/admin/send_email.html @@ -1,12 +1,87 @@ - {% extends "admin/base_site.html" %} +{% load form_tags %} -{% block content %} -

Send Email to Selected Users

-
- {% csrf_token %} - {{ form.as_p }} - -
- Cancel +{% block extrastyle %} +{{ block.super }} + {% endblock %} + +{% block content %} +
+

Send Email to Selected Users

+ +
+ {% csrf_token %} +
+ {% if form.errors %} +

+ {% if form.errors|length == 1 %}Please correct the error below.{% else %}Please correct the errors below.{% endif %} +

+ {% endif %} + +
+ {% for field in form %} +
+ {{ field.label_tag }} + {{ field|add_class:"vTextField" }} + {% if field.help_text %} +

{{ field.help_text }}

+ {% endif %} + {% if field.errors %} +
    + {% for error in field.errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} +
+ {% endfor %} +
+ +
+ + +
+
+
+
+{% endblock %} diff --git a/frontend/src/containers/Event/Event.tsx b/frontend/src/containers/Event/Event.tsx index e5ae797..41d0cd1 100644 --- a/frontend/src/containers/Event/Event.tsx +++ b/frontend/src/containers/Event/Event.tsx @@ -46,11 +46,8 @@ const EventContainer = async ({ event: Event; }) => { const sanitizedDescription = sanitizeHtml(description, { - allowedTags: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'button', 'ul', 'l'], - allowedAttributes: { - a: ['href', 'target', 'style'], - button: ['onclick', 'style', 'type', 'class'], - }, + allowedTags: false, + allowedAttributes: false, }); const duration = calculateDuration(end_date, start_date); diff --git a/frontend/src/sections/EventSection/EventCard.tsx b/frontend/src/sections/EventSection/EventCard.tsx index 3d960ca..64ad693 100644 --- a/frontend/src/sections/EventSection/EventCard.tsx +++ b/frontend/src/sections/EventSection/EventCard.tsx @@ -49,11 +49,18 @@ const EventCard: React.FC = ({ width={400} height={400} className='rounded-t-lg' - style={{ - maxWidth: '100%', - height: '100%', - objectFit: 'cover', - }} + style={ + imageSrc + ? { + maxWidth: '100%', + height: '100%', + objectFit: 'cover', + } + : { + maxWidth: '100%', + height: 'auto', + } + } />