Schedule the monthly report reminder
React · React · advanced · greenfield
Adds the reminder schedule helper and the settings card that displays it. `nextReminderDate` checks whether the last-shown month's firing is behind us, moves to the following month when it is (JS Date normalizes the December wrap), and clamps the chosen day into short months. Stepped a day-15 workspace through the year and the card always shows the 15th.
Requirements
- Add the `ReportReminderCard` for the workspace settings page: it shows when the monthly expense-report reminder will fire next.
- The reminder fires monthly on the workspace's chosen day (`anchorDom`, an integer 1–31). In months shorter than that day it fires on the month's last day instead — e.g. day 31 fires Jan 31, Feb 28 (or 29), Mar 31.
- The clamping is per-month only: the series must return to the true chosen day in every month long enough to hold it. A Feb 28 firing for day-31 settings is followed by Mar 31, never Mar 28.
- `nextReminderDate(lastShown, anchorDom)` returns the firing date that FOLLOWS `lastShown`. `lastShown` is always a date this schedule itself produced (the chosen day clamped into its month), at local midnight; the result is at local midnight too.
- All dates are plain local `Date`s; the card renders the result via `toLocaleDateString()`.
Files touched
- src/components/ReportReminderCard.jsx
--- src/components/ReportReminderCard.jsx
+function monthLength(year, month) {
+ return new Date(year, month + 1, 0).getDate();
+}
+
+export function nextReminderDate(lastShown, anchorDom) {
+ const year = lastShown.getFullYear();
+ const month = lastShown.getMonth();
+ const rolled = lastShown.getDate() >= anchorDom;
+ const targetMonth = rolled ? month + 1 : month;
+ const day = Math.min(anchorDom, monthLength(year, targetMonth));
+ return new Date(year, targetMonth, day);
+}
+
+export default function ReportReminderCard({ lastShown, anchorDom }) {
+ const next = nextReminderDate(lastShown, anchorDom);
+ return (
+ <div className="reminder-card">
+ <h3 className="reminder-title">Expense report reminder</h3>
+ <p className="reminder-next">
+ Next reminder: {next.toLocaleDateString()}
+ </p>
+ </div>
+ );
+}
+