From 888059a61281e649eaaf79c4914add523785c1af Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 15 Aug 2025 14:39:22 +0200 Subject: [PATCH] Implement dues reminder system with monthly payment cycle - Add API endpoint and email templates for dues reminders - Change due date calculation from yearly to monthly billing - Add visual status indicators for overdue and due-soon members - Enhance member cards with status stripes and styling --- components/AddMemberDialog.vue | 4 +- components/EditMemberDialog.vue | 4 +- components/MemberCard.vue | 44 ++++- .../members/[id]/send-dues-reminder.post.ts | 177 ++++++++++++++++++ server/templates/dues-due-soon.hbs | 138 ++++++++++++++ server/templates/dues-overdue.hbs | 160 ++++++++++++++++ utils/dues-calculations.ts | 2 +- 7 files changed, 523 insertions(+), 6 deletions(-) create mode 100644 server/api/members/[id]/send-dues-reminder.post.ts create mode 100644 server/templates/dues-due-soon.hbs create mode 100644 server/templates/dues-overdue.hbs diff --git a/components/AddMemberDialog.vue b/components/AddMemberDialog.vue index 4c3e877..6a2ffee 100644 --- a/components/AddMemberDialog.vue +++ b/components/AddMemberDialog.vue @@ -254,10 +254,10 @@ watch(duesPaid, (newValue) => { } else { form.value['Membership Date Paid'] = ''; if (!form.value['Payment Due Date']) { - // Set due date to one year from member since date or today + // Set due date to one month from member since date or today const memberSince = form.value['Member Since'] || new Date().toISOString().split('T')[0]; const dueDate = new Date(memberSince); - dueDate.setFullYear(dueDate.getFullYear() + 1); + dueDate.setMonth(dueDate.getMonth() + 1); form.value['Payment Due Date'] = dueDate.toISOString().split('T')[0]; } } diff --git a/components/EditMemberDialog.vue b/components/EditMemberDialog.vue index 7ec356c..bc3207f 100644 --- a/components/EditMemberDialog.vue +++ b/components/EditMemberDialog.vue @@ -415,10 +415,10 @@ watch(duesPaid, (newValue) => { } else { form.value.membership_date_paid = ''; if (!form.value.payment_due_date) { - // Set due date to one year from member since date or today + // Set due date to one month from member since date or today const memberSince = form.value.member_since || new Date().toISOString().split('T')[0]; const dueDate = new Date(memberSince); - dueDate.setFullYear(dueDate.getFullYear() + 1); + dueDate.setMonth(dueDate.getMonth() + 1); form.value.payment_due_date = dueDate.toISOString().split('T')[0]; } } diff --git a/components/MemberCard.vue b/components/MemberCard.vue index 9bf9296..8c8bba9 100644 --- a/components/MemberCard.vue +++ b/components/MemberCard.vue @@ -1,10 +1,23 @@