Skip to content

Kanishk — Bell: Part A (48/24 PT week alerts) + Part B (task 50/75/90 alerts), PT week & time-travel#3932

Merged
one-community merged 1 commit intodevelopmentfrom
kanishk_fix_for_bell_notifications
Dec 6, 2025
Merged

Kanishk — Bell: Part A (48/24 PT week alerts) + Part B (task 50/75/90 alerts), PT week & time-travel#3932
one-community merged 1 commit intodevelopmentfrom
kanishk_fix_for_bell_notifications

Conversation

@kanishkagarwal6101
Copy link
Copy Markdown
Contributor

Description

This PR implements and tests two improvements to the Dashboard bell:
Screenshot 2025-08-20 at 10 47 52 AM
Screenshot 2025-08-20 at 10 48 00 AM

Part A (High Priority):

  • Pacific Time week boundary fix (DST-safe, TZ-agnostic).
  • Hours-left warnings at 48h and 24h before PT-week deadline.
  • Per-week localStorage “seen” flags so each threshold shows only once/week.
  • Non-blocking dev time-travel kit for testing (no page reload needed).
  • Safe reset of week flags when PT week flips (Sunday 00:00 PT).

Part B (High Priority):

  • Task progress alerts at 50% / 75% / 90% of a task’s estimated hours.
  • Pulls the current user’s tasks (via getUserTasks(userId)) and aggregates logged time per task from timeEntries.
  • Shows a modal list: “Hey! Your is <50|75|90>% complete…” as requested.
  • Per-week + per-task localStorage seen flags (reset when a new week starts).
  • “Mark all as read” option for task alerts.

Related PRs (if any)

N/A

Main changes explained

  • BellNotification.jsx (existing bell)
    • Added PT week helpers: startOfPSTWeek, endOfPSTWeek.
    • Added 48h/24h threshold logic and per-week seen flags (::hours::seen48, ::hours::seen24).
    • Added dev time-travel API (window.__setBellNow + bellTest helper) for testing without reload in dev environment.
    • Added task progress logic:
      • Collect logged hours per task from timeEntries.
      • Normalize tasks from Redux (state.userTask.tasks via getUserTasks) and fallback paths.
      • Compute % logged vs. estimated hours and trigger alerts at 50/75/90%.
      • Use per-week, per-task seen flags (${userId}::${weekKey}::taskHours::<taskId>::seen::<bucket>).
      • Modal lists multiple alerts; includes a “Mark all as read” button.
      • Import and dispatch getUserTasks(userId) to ensure the volunteer’s tasks are available on Dashboard.

How to test

A) Part A – Hours warnings at 48h/24h before PT week end

  1. Log in (any role) and go to Dashboard so the bell is mounted.
  2. Open the browser console and paste the following script to load the dev test kit (if not already present):
(() => {
  const toLA = d => new Date(d.toLocaleString('en-US',{ timeZone: 'America/Los_Angeles' }));
  const startOfPSTWeek = d => {
    const laNow = toLA(d);
    const laStart = new Date(laNow);
    laStart.setHours(0,0,0,0);
    laStart.setDate(laStart.getDate() - laNow.getDay());
    const offset = d.getTime() - laNow.getTime();
    return new Date(laStart.getTime() + offset); // true Sun 00:00 PT instant
  };
  const endOfPSTWeek = d => new Date(startOfPSTWeek(d).getTime() + 7*24*3600*1000);
  window.bellTest = {
    toLA, startOfPSTWeek, endOfPSTWeek,
    setNow(iso) {
      if (!window.__setBellNow) throw new Error('Component not mounted yet');
      window.__setBellNow(iso);
      return iso;
    },
    keys() {
      const uid = Object.keys(localStorage).find(k => k.endsWith('::lastWeekKey'))?.split('::')[0] || null;
      const now = new Date(window.__BELL_TEST_NOW || Date.now());
      const wk = startOfPSTWeek(now).toISOString();
      const base = uid ? `${uid}::${wk}` : null;
      return { uid, wk, base };
    },
    listKeys() {
      const { uid } = bellTest.keys();
      return Object.keys(localStorage).filter(k =>
        (uid ? k.startsWith(uid + '::') : true) &&
        (k.includes('::hours::') || k.endsWith('::lastWeekKey'))
      );
    },
    clearSeen() {
      const { base } = bellTest.keys();
      if (!base) return [];
      const ks = [`${base}::hours::seen48`, `${base}::hours::seen24`];
      ks.forEach(k => localStorage.removeItem(k));
      return ks;
    },
    nukeAllHours() {
      const { uid } = bellTest.keys();
      const removed = [];
      Object.keys(localStorage).forEach(k => {
        if (k.startsWith(`${uid}::`) && (k.includes('::hours::') || k.endsWith('::lastWeekKey'))) {
          removed.push(k);
          localStorage.removeItem(k);
        }
      });
      return removed;
    },
    goTo(hoursBefore = 0, minutesBefore = 0) {
      const baseNow = new Date(window.__BELL_TEST_NOW || Date.now());
      const end = endOfPSTWeek(baseNow);
      const t = new Date(end.getTime() - (hoursBefore*3600 + minutesBefore*60)*1000);
      return bellTest.setNow(t.toISOString());
    }
  };
  console.log('bellTest loaded:', bellTest);
})();

Clear the weekly seen flags:

bellTest.clearSeen();     // should remove ::seen48 / ::seen24 for current week
bellTest.listKeys();      // verify keys present (should keep ::lastWeekKey)

Jump to these checkpoints and open the bell to confirm:

bellTest.goTo(49);  // 49h before Sunday 00:00 PT -> no alert
bellTest.goTo(48);  // 48h before -> 48h alert appears (if under committed hours)
bellTest.goTo(36);  // 36h before -> no new 48h alert (already seen)
bellTest.goTo(24);  // 24h before -> 24h alert appears (if still under committed hours)

B) Part B – Task progress alerts at 50/75/90% of estimated hours

We test with two roles (or two logins).

Admin setup

  1. Log in as Admin.
  2. Create/choose a task for the volunteer with estimatedHours = 7 (example).
  3. Assign the task to the volunteer user (the one used for Dashboard testing).

Volunteer flow

  1. Log in as the Volunteer (the same userId passed to the Bell).

  2. Navigate to the Dashboard (bell mounted).

  3. The app auto-fetches tasks with getUserTasks(userId); wait a second for Redux to populate.

  4. Log time entries against that task so that totals cross:

3.5h / 7h → 50% alert shows.
5.25h / 7h → 75% alert shows.
6.3h / 7h → 90% alert shows.

  1. Click the bell → a modal lists alerts:
    “Hey! Your is <50|75|90>% complete…”

  2. Click “Mark all as read” to set seen flags for the current week (per task & bucket).

  3. To test again in the same week, clear task flags in console:

Object.keys(localStorage)
.filter(k => k.includes('::taskHours::') && k.includes('::seen::'))
.forEach(k => localStorage.removeItem(k));

Acceptance criteria

At 50/75/90% of estimated hours, the bell shows a red dot and the modal lists each alert once per bucket per week.
“Mark all as read” hides them until a higher bucket is reached or the week flips.
No alerts for tasks without an estimate or when pct >= 100.

Screenshots

Screenshot 2025-08-20 at 9 49 15 AM Screenshot 2025-08-14 at 10 27 56 AM

Notes

All logic is week-scoped to Pacific Time (Sunday 00:00 PT).
localStorage keys are namespaced by userId and week start time.
If you see no Part B alerts, ensure:
You are logged in as the assigned volunteer.
estimatedHours is set and > 0.
Time entries reference the assigned taskId field the reducer uses.

@netlify
Copy link
Copy Markdown

netlify Bot commented Aug 20, 2025

Deploy Preview for highestgoodnetwork-dev ready!

Name Link
🔨 Latest commit 76feead
🔍 Latest deploy log https://app.netlify.com/projects/highestgoodnetwork-dev/deploys/68a60ec547ade8000843faa4
😎 Deploy Preview https://deploy-preview-3932--highestgoodnetwork-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@kanishkagarwal6101 kanishkagarwal6101 added the High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible label Aug 29, 2025
Copy link
Copy Markdown

@Anusha-Gali Anusha-Gali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Kanishk,

I have reviewed the PR locally and have verified all the requirements and the test have passed as per the criteria mentioned.
PART A
Screenshot 2025-12-04 at 12 14 16 AM
Screenshot 2025-12-04 at 12 34 27 AM
Screenshot 2025-12-04 at 12 34 51 AM
Screenshot 2025-12-04 at 12 35 04 AM
Screenshot 2025-12-04 at 12 35 08 AM
PART B
Screenshot 2025-12-04 at 12 51 38 AM
Screenshot 2025-12-04 at 1 03 19 AM
Screenshot 2025-12-04 at 1 05 36 AM

@one-community
Copy link
Copy Markdown
Member

Thank you all, merging!

@one-community one-community merged commit efd9372 into development Dec 6, 2025
8 checks passed
Copy link
Copy Markdown
Contributor

@Shravan-neelamsetty Shravan-neelamsetty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Kanishk , While testing locally, I’m consistently running into an issue with the dev time-travel helper: calling bellTest.goTo(...) keeps throwing a “Component not mounted yet” error (attached screenshot), even after waiting and retrying on the dashboard. The bell UI is visible, but the helper never seems to hook in for me, so I’m unable to exercise the 48h/24h scenarios via the test kit. This looks like a dev-only mounting/timing issue rather than a logic problem with the alerts themselves, but I wanted to flag it since it blocks local testing on my end.
Screenshot 2026-01-16 at 6 16 35 PM

Copy link
Copy Markdown

@Vikas-8055 Vikas-8055 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Kanishk, while testing locally, bellTest.goTo(...) keeps throwing a "Component not mounted yet" error even though the bell UI is visible on the dashboard. This seems like a dev-only mounting/timing issue rather than a logic problem with the alerts. Just flagging since it blocks local testing of the 48h/24h scenarios.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

High Priority - Please Review First This is an important PR we'd like to get merged as soon as possible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants