Add a reusable notification system; wire it into news publishing
New `notifications` app: Notification (club-scoped, keyed to the member it's about, generic `source` via a ContentType/object_id pair so future activities can reuse this without a new model each time) plus notify_members(), which resolves each member's own email (if they hold a login) and every parent/guardian's, always -- a child with their own account doesn't opt their parents out -- and emails the club-branded template to whichever addresses that resolves to. Delivery is email-only for now (no in-app feed exists yet); the row is created either way, ready for one later. news.tasks.notify_news_published resolves the audience (a team-scoped item's current rosters, or every active member if it's club-wide) and calls notify_members with the item's title/plain-text body. NewsPublishForm gained a "Notify linked members" checkbox (opt-in, default off); when checked, NewsPublishView schedules the task with Celery's `eta` set to the item's own published_at -- a scheduled item's notification arrives when it actually goes live, and an immediate publish (eta in the past) just runs right away, no separate branch needed. Registered the new notification email on the Club identity page's Email tab alongside the others. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
{% extends "email/_base.html" %}
|
||||
{% load i18n club_email %}
|
||||
|
||||
{% comment %}
|
||||
HTML sibling of notification.txt -- same content, same context (club,
|
||||
notification, request), laid out for an inbox. Same shell/branding as
|
||||
every other transactional email in this app (club/templates/club/email/*.html,
|
||||
members/.../claim_approved.html) -- see that convention before changing this.
|
||||
{% endcomment %}
|
||||
|
||||
{% block title %}{% blocktrans with club=club.name title=notification.title %}{{ club }} — {{ title }}{% endblocktrans %}{% endblock title %}
|
||||
|
||||
{% block preheader %}{{ notification.title }}{% endblock preheader %}
|
||||
|
||||
{% block header %}
|
||||
{% absolute_media_url club.logo as logo_url %}
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
{% if club.logo %}
|
||||
<img src="{{ logo_url }}" alt="{{ club.name }}" width="48" height="48" style="display:block; width:48px; height:48px; border-radius:24px; object-fit:contain; background-color:#f3f4f6;">
|
||||
{% else %}
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="48" style="width:48px;">
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="48" height="48" bgcolor="{{ club.secondary_color|default:"#ec4899" }}" style="width:48px; height:48px; border-radius:24px; background-color:{{ club.secondary_color|default:"#ec4899" }}; color:{{ club.secondary_color|default:"#ec4899"|contrast_color }}; font-family: Arial, Helvetica, sans-serif; font-size:16px; font-weight:bold;">
|
||||
{{ club.initials }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="padding-left:14px;" valign="middle">
|
||||
<span style="font-family: Arial, Helvetica, sans-serif; font-size:18px; font-weight:bold; color:#111827;">{{ club.name }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock header %}
|
||||
|
||||
{% block content %}
|
||||
<p style="margin:0 0 16px 0; font-size:18px; font-weight:bold; color:#111827;">{{ notification.title }}</p>
|
||||
<div style="margin:0;">{{ notification.body|linebreaks }}</div>
|
||||
{% endblock content %}
|
||||
|
||||
{% block footer %}
|
||||
{% if club.contact_email %}
|
||||
<p style="margin:0 0 8px 0;">{% blocktrans with email=club.contact_email %}Questions? Reply to this note or write to {{ email }}.{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
<p style="margin:0;">{% blocktrans with club=club.name %}— {{ club }}{% endblocktrans %}</p>
|
||||
{% endblock footer %}
|
||||
@@ -0,0 +1,7 @@
|
||||
{% load i18n %}{{ notification.title }}
|
||||
|
||||
{{ notification.body }}
|
||||
{% if club.contact_email %}
|
||||
{% blocktrans with email=club.contact_email %}Questions? Reply to this note or write to {{ email }}.{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% blocktrans with club=club.name %}— {{ club }}{% endblocktrans %}
|
||||
@@ -0,0 +1 @@
|
||||
{% load i18n %}{% blocktrans with club=club.name title=notification.title %}{{ club }} — {{ title }}{% endblocktrans %}
|
||||
Reference in New Issue
Block a user