π Title
Fix `NotificationsPanel` β connect to real API, fix animation close race condition, fix `pointerEvents` bug
π Description
`NotificationsPanel` has three distinct bugs and uses entirely hardcoded mock data.
Bug 1 β Animation close race condition:
`NotificationsPanel.tsx` line ~147:
```ts
if (!isOpen && translateX.value === SCREEN_WIDTH) return null;
```
When `isOpen` flips to false, the close animation fires (`withTiming(SCREEN_WIDTH, β¦)`), but on the very next re-render the guard checks `translateX.value === SCREEN_WIDTH` β because the animated value hasn't finished yet, it's not equal to `SCREEN_WIDTH` yet, so the panel stays rendered. BUT if the component re-renders mid-animation (e.g. state update), the value may momentarily equal `SCREEN_WIDTH` and immediately unmount the component, cutting the closing animation short. The panel disappears abruptly instead of sliding out.
Fix: Use a `isMounted` flag controlled by `runOnJS` in the animation's `callback` argument:
```ts
withTiming(SCREEN_WIDTH, { duration: 300 }, (finished) => {
if (finished) runOnJS(setIsMounted)(false);
});
```
Bug 2 β `pointerEvents` as style prop:
`animatedBackdropStyle` in `NotificationsPanel.tsx` includes `pointerEvents` inside the style object. In React Native, `pointerEvents` is a prop on the View element, not a style property. It has no effect as a style β backdrop taps pass through even when the panel is open.
Bug 3 β All notification data is hardcoded:
`MOCK_NOTIFICATIONS` is a static constant. Mark-as-read and delete actions only mutate local state β no API call is made.
β
Tasks to complete
π Documentation/context for AI
https://github.com/TrustUp-app/TrustUp-Frontend/tree/main/docs
Files to create:
- `hooks/notifications/use-notifications.ts`
Files to modify:
- `components/shared/NotificationsPanel.tsx` (animation fix, pointerEvents fix, real data)
- `components/shared/Header.tsx` (real unread badge count on bell icon)
ποΈ Additional notes
- API endpoints: `GET /notifications`, `PATCH /notifications/:id/read`, `PATCH /notifications/read-all`
- Optimistic update: when tapping "mark as read", update local state immediately before the API call completes; roll back on error
- The notification bell badge should show the count as a red circle with number; hide it when `unreadCount === 0`
- On Android, `BlurView` with `intensity={40}` is unreliable β add a fallback semi-transparent `backgroundColor` for Android: `Platform.OS === 'android' ? 'rgba(0,0,0,0.5)' : undefined`
- Empty state: show "No notifications" centered in the panel with a subtle icon
π Title
Fix `NotificationsPanel` β connect to real API, fix animation close race condition, fix `pointerEvents` bug
π Description
`NotificationsPanel` has three distinct bugs and uses entirely hardcoded mock data.
Bug 1 β Animation close race condition:
`NotificationsPanel.tsx` line ~147:
```ts
if (!isOpen && translateX.value === SCREEN_WIDTH) return null;
```
When `isOpen` flips to false, the close animation fires (`withTiming(SCREEN_WIDTH, β¦)`), but on the very next re-render the guard checks `translateX.value === SCREEN_WIDTH` β because the animated value hasn't finished yet, it's not equal to `SCREEN_WIDTH` yet, so the panel stays rendered. BUT if the component re-renders mid-animation (e.g. state update), the value may momentarily equal `SCREEN_WIDTH` and immediately unmount the component, cutting the closing animation short. The panel disappears abruptly instead of sliding out.
Fix: Use a `isMounted` flag controlled by `runOnJS` in the animation's `callback` argument:
```ts
withTiming(SCREEN_WIDTH, { duration: 300 }, (finished) => {
if (finished) runOnJS(setIsMounted)(false);
});
```
Bug 2 β `pointerEvents` as style prop:
`animatedBackdropStyle` in `NotificationsPanel.tsx` includes `pointerEvents` inside the style object. In React Native, `pointerEvents` is a prop on the View element, not a style property. It has no effect as a style β backdrop taps pass through even when the panel is open.
Bug 3 β All notification data is hardcoded:
`MOCK_NOTIFICATIONS` is a static constant. Mark-as-read and delete actions only mutate local state β no API call is made.
β Tasks to complete
π Documentation/context for AI
https://github.com/TrustUp-app/TrustUp-Frontend/tree/main/docs
Files to create:
Files to modify:
ποΈ Additional notes