# Nazareth Church Management – Implementation Plan

This document outlines a phased plan to implement the following enhancements:

1. **Member directory / PDF** – Printable directory by fellowship or ministry with optional photos  
2. **Scheduled birthday messages** – Cron job to send birthday wishes automatically  
3. **Reusable templates** – SMS/email templates for events, reminders, announcements  
4. **Dashboard: Upcoming preaching plan** – Next 1–2 Sundays on dashboard  
5. **Dashboard: Quick stats** – This month’s offerings, events count, new members  
6. **Dashboard: Recent activity** – Last transactions, new members, events  
7. **Pledges** – Record pledges per member/fund and compare with actual giving  
8. **Fund targets** – Target per fund and progress display  
9. **Event reminders** – Email/SMS reminder to members or groups before an event  
10. **Recurring events** – Define pattern and generate future event dates  

---

## Phase 1: Foundation (Templates + Dashboard)

**Goal:** Reusable message templates and a richer dashboard. No new tables for templates if we use the existing `settings` table with a prefix; otherwise add a small `message_templates` table.

### 1.1 Reusable SMS/Email Templates

| Task | Details |
|------|--------|
| **DB** | Add table `message_templates` (id, name, type enum('sms','email'), subject nullable, body text, placeholders text/json, created_at, updated_at). Or store as settings with prefix `template_<id>_` / named keys in settings. |
| **Settings UI** | New section under Settings: "Message templates". List templates; Add/Edit form: name, type (SMS/Email), subject (email only), body with placeholder help (e.g. `{member_name}`, `{event_title}`, `{date}`). |
| **Code** | Helper `getTemplate($name)` or `getTemplateById($id)` returning subject + body; replace placeholders with context array. Use for events, reminders, announcements (later phases). |
| **Files** | `install/install.php` (table if new), `includes/settings.php` or new `includes/templates.php`, `pages/settings/index.php` (new section or `pages/settings/templates.php`), `public/css/style.css` if needed. |

**Dependencies:** None.  
**Deliverable:** Admins can create/edit SMS and email templates; other features can reference them by name or id.

---

### 1.2 Dashboard: Upcoming Preaching Plan

| Task | Details |
|------|--------|
| **Query** | From `preaching_plan`: next 1–2 Sundays from today (e.g. next 14 days, filter by day-of-week = Sunday). Select service_date, occasion, preacher, service_type. |
| **Dashboard** | New card "Upcoming preaching" in `pages/dashboard.php`: list next 1–2 Sundays with date, occasion, preacher (and service type if multiple). Link to Events → Preaching plan. |
| **Files** | `pages/dashboard.php` (query + HTML card). |

**Dependencies:** Preaching plan table exists (already in place).  
**Deliverable:** Dashboard shows next 1–2 Sundays with preacher and occasion.

---

### 1.3 Dashboard: Quick Stats (refine existing + new)

| Task | Details |
|------|--------|
| **Existing** | You already have: members, households, ministries, groups, events this month, birthdays today, offerings this month. |
| **New stats** | (1) **New members this month** – `WHERE join_date >= ? AND join_date <= ?` (members table has `join_date`). (2) Keep/rename "Events this month" and "Offerings this month" as quick stats. |
| **Layout** | Ensure offerings and events count are visible; add "New members (this month)" stat card linking to Members (optional filter by join_date). |
| **Files** | `pages/dashboard.php` (one new query, one new stat card). |

**Dependencies:** None.  
**Deliverable:** Dashboard shows new members this month; quick stats remain clear.

---

### 1.4 Dashboard: Recent Activity

| Task | Details |
|------|--------|
| **Data** | (1) Last 5–10 transactions (transaction_date, amount, fund name, member name if any). (2) Last 5 new members (join_date, name) – e.g. ORDER BY created_at DESC. (3) Last 5 events (event_date, title). |
| **UI** | One card "Recent activity" with three sections or tabs: Recent transactions | New members | Recent events. Or three small lists in one card. Link each to the relevant module. |
| **Files** | `pages/dashboard.php` (queries + HTML). |

**Dependencies:** None.  
**Deliverable:** Dashboard shows recent transactions, new members, and recent events in one place.

---

## Phase 2: Member Directory / PDF

**Goal:** Generate a printable member directory, filterable by fellowship or ministry, with optional photos.

### 2.1 Member Directory (web view + print CSS)

| Task | Details |
|------|--------|
| **Page** | New page e.g. `pages/members/directory.php` or `pages/directory.php`. Route: `/members/directory` or `/directory`. |
| **Filters** | Dropdown or tabs: All | By fellowship (use `getMemberFellowship()` and filter in PHP or SQL by age/gender) | By ministry (join member_ministries, ministries). Optional: "Include photo" checkbox. |
| **Query** | List members with: name, phone, email, fellowship (computed), ministry names (GROUP_CONCAT). If "by ministry" selected, filter by ministry_id; if "by fellowship" selected, compute fellowship and filter in PHP or via HAVING if you add a computed column. |
| **Layout** | Card or table layout; each member: optional thumbnail, name, contact, fellowship, ministries. Print-friendly CSS: hide nav/sidebar, expand layout, good font size. |
| **Files** | `pages/members/directory.php` (or under members), `includes/header.php` (link in sidebar if desired), `public/css/style.css` (print styles). |

### 2.2 PDF Export (optional but recommended)

| Task | Details |
|------|--------|
| **Option A** | Server-side: use a PHP library (e.g. TCPDF, Dompdf, mPDF) to generate PDF from the same data + HTML layout. Add "Download PDF" button on directory page; pass same filters (fellowship/ministry, include photos). |
| **Option B** | Client-side: keep "Print" with print CSS; user chooses "Save as PDF" in browser. Simpler; no new dependency. |
| **Files** | If Option A: new script or action e.g. `pages/members/directory-pdf.php`, Composer dependency for PDF library. |

**Dependencies:** Phase 1 not required. Fellowship logic exists in `includes/fellowships.php`; ministries and member_ministries exist.  
**Deliverable:** Printable (and optionally PDF) member directory by fellowship or ministry with optional photos.

---

## Phase 3: Scheduled Birthday Messages (Cron)

**Goal:** Automatically send birthday wishes on the day without opening the app.

### 3.1 Cron Entry Point

| Task | Details |
|------|--------|
| **Script** | New CLI script e.g. `cron/birthday-wishes.php` (or `scripts/send-birthday-wishes.php`). No web access; run via cron. |
| **Logic** | Bootstrap app (DB + settings). Get today’s month/day; fetch members with birthday today (reuse `getMembersWithBirthdayOn($pdo, $month, $day)`). For each member, call existing `sendBirthdayWishes()` (from birthdays.php/mail/sms). Use existing birthday template and SMS/email settings. |
| **Safety** | Idempotent: sending twice the same day is acceptable, or add a simple "last_sent_birthday_date" per member to avoid duplicates (optional). Log success/failures to a file or log table. |

### 3.2 Cron Schedule

| Task | Details |
|------|--------|
| **Example** | Run once per day at 8:00 AM: `0 8 * * * cd /path/to/nazareth && php cron/birthday-wishes.php`. |
| **Docs** | Add to IMPLEMENTATION_PLAN or README: how to set up cron (server or user crontab). |

**Dependencies:** Existing `sendBirthdayWishes`, SMTP/SMS settings, birthday message template.  
**Deliverable:** Cron job that sends birthday messages automatically each day.

---

## Phase 4: Pledges

**Goal:** Record pledges per member per fund and compare with actual giving.

### 4.1 Database

| Task | Details |
|------|--------|
| **Table** | `pledges` (id, member_id, fund_id, amount DECIMAL(12,2), pledge_year YEAR or period_start/period_end, notes, created_at, updated_at). Optional: status (active/cancelled). |
| **Index** | (member_id, fund_id, pledge_year) or (member_id, fund_id, period_start). |

### 4.2 Pledge Entry and List

| Task | Details |
|------|--------|
| **UI** | New section under Finance: "Pledges". List pledges (member, fund, amount, year/period). Add pledge form: select member, fund, amount, year (or period). Edit/delete. |
| **Files** | `pages/finance/pledges.php` (list + add/edit), or `pages/pledges/` if you prefer a top-level section. Route: e.g. `/finance/pledges`. |

### 4.3 Pledge vs Actual Comparison

| Task | Details |
|------|--------|
| **Logic** | For a given member and year (and optionally fund): sum(pledges) vs sum(transactions) for that member/fund/year. |
| **Display** | On member financial page or new "Pledge vs giving" report: table or summary "Pledged: GH¢ X | Given: GH¢ Y | Difference: GH¢ Z". Option: report by fund, by member, or both. |
| **Files** | `pages/finance/reports.php` (new tab/section) or `pages/members/financial.php` (add pledge summary), plus pledge list page. |

**Dependencies:** Existing `transactions`, `funds`, `members`.  
**Deliverable:** Record pledges; view pledge vs actual giving per member/fund/year.

---

## Phase 5: Fund Targets

**Goal:** Set a target amount per fund and show progress (e.g. building fund).

### 5.1 Database

| Task | Details |
|------|--------|
| **Schema** | Add to `funds` table: `target_amount DECIMAL(12,2) NULL`, `target_period` VARCHAR(20) NULL (e.g. '2026', '2026-Q1', or leave NULL for "all time"). Or new table `fund_targets` (fund_id, target_amount, period_label, from_date, to_date) for multiple targets. Simpler: add `target_amount` and `target_year` to `funds`. |

### 5.2 UI: Set Target and Show Progress

| Task | Details |
|------|--------|
| **Finance / Funds** | If you have a funds list/edit page: add fields "Target amount" and "Target year" (or period). If funds are only in settings/dropdowns, add a "Funds & targets" admin page to set name, description, target_amount, target_year. |
| **Progress** | On Finance dashboard or Reports: for each fund with target, show "GH¢ X / GH¢ Y (Z%)" and a simple progress bar. Sum transactions for that fund in the target year (or period). |
| **Files** | `install/install.php` or migration: ALTER funds add target_amount, target_year. `pages/finance/index.php` or reports: display targets and progress. Fund edit page or new fund management page. |

**Dependencies:** Existing `funds` and `transactions`.  
**Deliverable:** Set a target per fund (e.g. yearly); see progress on dashboard or reports.

---

## Phase 6: Event Reminders

**Goal:** Optional email/SMS reminder to selected members or groups before an event.

### 6.1 Data and Logic

| Task | Details |
|------|--------|
| **Schema** | Option A: Add to `events` table: `reminder_sent_at` DATETIME NULL; reminder sent when cron runs. Option B: `event_reminders` (id, event_id, scheduled_at, sent_at, recipient_type enum('all','group','custom'), recipient_ids text/json). Start simple: one reminder per event, "send 1 day before" or "send at 9am day-of". |
| **Template** | Use Phase 1 templates: e.g. template "Event reminder" with placeholders {event_title}, {event_date}, {event_time}, {member_name}. |
| **Send logic** | For each event with event_date = tomorrow (or today): get list of recipients (all members, or members of selected groups). For each, replace placeholders and send SMS/email via existing mail.php and sms.php. Mark reminder_sent_at or record in event_reminders. |

### 6.2 UI and Cron

| Task | Details |
|------|--------|
| **Event form** | Checkbox "Send reminder (day before)" or "Send reminder" + dropdown "When: 1 day before / morning of". Optional: "Recipients: All members / Select groups". If "Select groups", store group_ids in event (new column or JSON). |
| **Cron** | New script `cron/event-reminders.php`: find events where reminder should go (e.g. event_date = tomorrow or today) and reminder not yet sent; send to chosen recipients; mark sent. Run daily (e.g. 7:00 AM). |
| **Files** | `pages/events/form.php` (reminder options), `cron/event-reminders.php`, possibly new columns on `events`, template usage from Phase 1. |

**Dependencies:** Phase 1 (templates), existing events and groups/members, mail/sms.  
**Deliverable:** Option on event to send reminder; cron sends it to selected audience.

---

## Phase 7: Recurring Events

**Goal:** Define a recurrence pattern and generate future event dates.

### 7.1 Database

| Task | Details |
|------|--------|
| **Option A** | New table `recurring_events` (id, title, description, location, recurrence_rule VARCHAR (e.g. 'weekly', 'monthly'), recurrence_param (e.g. weekday number, day of month), start_date, end_date nullable, time TIME nullable, created_at). A cron or admin action "Generate" creates actual `events` rows from this. |
| **Option B** | Add to `events`: `recurring_from_id INT NULL` (parent event id), `recurrence_rule`, `recurrence_until`. Then generate next N occurrences on demand or via cron. |

### 7.2 Recurrence Rules and Generation

| Task | Details |
|------|--------|
| **Rules** | Support at least: Weekly (e.g. every Sunday), Bi-weekly, Monthly (e.g. first Tuesday). Store as enum or string: 'weekly', 'monthly'; param: weekday (0–6) or day_of_month (1–31). |
| **Generator** | Function: given recurring_events row and a date range (e.g. next 3 months), return array of (event_date, event_time, title, …). Insert into `events` (or show preview first). |
| **UI** | "Add recurring event" form: title, description, location, time, recurrence (weekly/weekday or monthly/day), start date, end date (or "generate up to 3 months"). Button "Generate events" creates actual events. List recurring definitions and allow "Generate next month" or "Generate next 3 months". |
| **Files** | New table + migration, `pages/events/recurring.php` or section in events, helper in `includes/` for date generation. |

**Dependencies:** Existing `events` table.  
**Deliverable:** Define recurring events and generate future event records.

---

## Suggested Order of Implementation

| Order | Phase | Reason |
|-------|--------|--------|
| 1 | **Phase 1** (Templates + Dashboard) | Templates are needed for event reminders; dashboard improvements are high visibility and low risk. |
| 2 | **Phase 2** (Member directory / PDF) | Standalone, high value for church office. |
| 3 | **Phase 3** (Scheduled birthday messages) | Small, uses existing logic; quick win. |
| 4 | **Phase 4** (Pledges) | Core finance feature; no dependency on reminders. |
| 5 | **Phase 5** (Fund targets) | Builds on funds and transactions; good for stewardship. |
| 6 | **Phase 6** (Event reminders) | Uses Phase 1 templates; improves event engagement. |
| 7 | **Phase 7** (Recurring events) | More complex; can follow after reminders. |

---

## File and Route Summary

| Feature | New/updated files | Routes |
|--------|--------------------|--------|
| Templates | `includes/templates.php`, settings section or `pages/settings/templates.php`, install (table) | `/settings/templates` or section under Settings |
| Upcoming preaching | `pages/dashboard.php` | (dashboard) |
| Quick stats / Recent activity | `pages/dashboard.php` | (dashboard) |
| Member directory | `pages/members/directory.php`, optional `directory-pdf.php` | `/members/directory` |
| Birthday cron | `cron/birthday-wishes.php` | CLI only |
| Pledges | `pages/finance/pledges.php`, install (pledges table) | `/finance/pledges` |
| Fund targets | Alter `funds`; finance index or fund management page | (finance dashboard / reports) |
| Event reminders | `pages/events/form.php`, `cron/event-reminders.php`, possibly `event_reminders` table | (event form + cron) |
| Recurring events | `pages/events/recurring.php`, table `recurring_events`, helper | `/events/recurring` |

---

## Notes

- **Permissions:** Reuse existing roles (admin, finance, clerk). Directory and pledges may be admin/finance only; cron scripts run outside web context.
- **Testing:** After each phase, test with a small data set: one member, one event, one fund, one pledge.
- **Migrations:** For existing installs, provide ALTER scripts or a single `migrate.php` that checks and adds new columns/tables so the install folder can remain deleted in production.

This plan can be executed phase by phase; each phase’s deliverable is usable on its own.
