Skip to content

Comments

feat: add alert notification system for each eventcard#473

Merged
HarshPatel5940 merged 8 commits intoFOSSUChennai:mainfrom
Som23Git:feat/event-alert-notifications
Feb 22, 2026
Merged

feat: add alert notification system for each eventcard#473
HarshPatel5940 merged 8 commits intoFOSSUChennai:mainfrom
Som23Git:feat/event-alert-notifications

Conversation

@Som23Git
Copy link
Contributor

@Som23Git Som23Git commented Dec 10, 2025

This PR adds an alert notification system to each event, allowing event organizers to display important notices (postponements, venue changes, cancellations, and important notice) directly on event cards.

Motivation & Inspiration

This feature was inspired by a real-world scenario where a community event had to be postponed due to a cyclone alert. Attendees were confused and asking questions like:

  • "Is the meetup postponed or cancelled?"
  • "What's the new date and venue?"
  • "Where can I find the updated information?"

Without a clear way to communicate these changes directly on the event card, organizers had to rely on social media posts and external announcements, leading to confusion and missed updates.

Example scenario: A Build2Learn event in Chennai was postponed from November 29th to December 6th due to a cyclone alert. While the organizer posted updates on LinkedIn, (assuming) attendees visiting the TamilNadu.tech website couldn't see this critical information directly on the event card.

Reference: LinkedIn Post - Build2Learn Event Postponement

This feature solves this problem by allowing event organizers to add alerts directly to their event data, making important updates immediately visible to all new visitors.

What's Changed

  • Type Definition: Added optional alert field to Event interface in src/types/event.d.ts

    • Supports message (required) and type (optional: 'postponed', 'venue-change', 'cancelled', 'general')
  • EventCard Component: Updated both home events and archive pages

    • Alert icon appears next to community name badge when alert exists
    • Hover tooltip displays formatted alert message with type-specific headers
    • Non-intrusive design that doesn't affect existing layout
  • Backward Compatible: All existing events without alerts continue to work normally

Example screenshots:

  • Events with and without Alerts:
image
  • On hovering the alert:
image

Usage Example

(updated the CONTRIBUTING.md with clear examples)

To add an alert to an event in events.json:

{
  "eventName": "Example Event",
  ...
  <everything_remains_the_same>
  ...
  "alert": {
    "message": "Please note: The event time has been changed to 10:00 AM.",
    "type": "venue-change"
  }
}

I'm open to any suggestions, feedback, and improvements. Let me know. Thanks.

Summary by CodeRabbit

  • New Features

    • Events now support optional alerts with a warning icon beside event names.
    • Tapping the warning opens a contextual panel showing alert type (postponed, venue change, cancelled, general) and message.
    • Alerts appear across event lists (home, monthly, archive) wherever events include alert data.
  • Documentation

    • Contribution guide updated with examples and validation notes for adding optional event alerts.

Som M and others added 2 commits December 10, 2025 10:38
- Add optional alert field to Event interface with message and type
- Display alert icon next to community name badge when alert exists
- Show alert tooltip on hover with formatted message
- Support alert types: postponed, venue-change, cancelled, general
- Apply alert functionality to both home events and archive pages
- Add alert field to event template
- Document alert types: postponed, venue-change, cancelled, general
- Include usage examples for different alert scenarios
- Update validation section to include alert message requirements
@Som23Git Som23Git marked this pull request as ready for review December 10, 2025 05:51
@Som23Git
Copy link
Contributor Author

Tagging: @nammahari @bupd @JustinBenito @Sarveshmrao for visibility. Thanks in advance.

@HarshPatel5940
Copy link
Member

This is actually good

@HarshPatel5940 HarshPatel5940 added the enhancement New feature or request label Dec 24, 2025
- Remove Warning icon component from tooltip content in events.tsx
- Remove Warning icon component from tooltip content in archive.tsx
- Simplify tooltip structure by removing unnecessary flex wrapper
@Som23Git
Copy link
Contributor Author

[REMOVED REDUNDANT WARNING ICON]

image

HarshPatel5940
HarshPatel5940 previously approved these changes Jan 3, 2026
Copy link
Member

@HarshPatel5940 HarshPatel5940 left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@Som23Git
Copy link
Contributor Author

Som23Git commented Jan 8, 2026

@Sarveshmrao Any inputs or blockers from your end?

@Sarveshmrao
Copy link
Collaborator

Hi @Som23Git amazing.

As there are changes in UI, I'll just have @JustinBenito review this once and then we can proceed.

@Som23Git
Copy link
Contributor Author

As there are changes in UI, I'll just have @/JustinBenito review this once and then we can proceed.

@JustinBenito, any thoughts?

@HarshPatel5940
Copy link
Member

HarshPatel5940 commented Feb 8, 2026

@Som23Git can you resolve conflicts bro?, would like this feature to be merged.

@coderabbitai
Copy link

coderabbitai bot commented Feb 9, 2026

📝 Walkthrough

Walkthrough

Adds an optional per-event alert (message + type) to the Event type and EventCard props; surfaces alerts in EventCard UI on Home and Archive pages with a warning icon and toggleable tooltip; updates event JSON indentation and documents the alert field and validation in CONTRIBUTING.md.

Changes

Cohort / File(s) Summary
EventCard UI (Home & Archive)
src/components/pages/home/events.tsx, src/components/pages/Archive/archive.tsx
Add `alert?: { message: string; type?: 'postponed'
Type Definitions
src/types/event.d.ts
Introduce optional alert field on Event with required message: string and optional type union.
Event Data
src/data/events.json
Whitespace/indentation changes for two event entries only; no semantic data changes.
Documentation / Contribution Guide
.github/CONTRIBUTING.md
Add "Adding Event Alerts (Optional)" section with examples; require message when alert is present; document allowed alert types and JSON examples.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

documentation

Suggested reviewers

  • Sarveshmrao
  • JustinBenito
  • nammahari

Poem

🐰 A tiny warning on the way,
I twitch my whiskers, save the day,
A hop, a poke, a message clear,
"Venue changed" or "postponed" near,
I bounce — so plans are set and gay!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding an alert notification system for event cards across the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/components/pages/Archive/archive.tsx`:
- Around line 240-244: The JSX currently uses {!alert.type} to show the
"Important Notice" header, but alerts with type === 'general' are truthy so that
branch never renders; update the conditional to explicitly check for alert.type
=== 'general' (or use a default fallback like (alert.type === 'general' ||
!alert.type)) in the same JSX block where alert.type is inspected so the "⚠️
Important Notice" label renders for general alerts (refer to the alert variable
and the JSX lines that render {alert.type === 'postponed' ...}).

In `@src/components/pages/home/events.tsx`:
- Around line 211-243: The tooltip can overflow for right-edge cards; update the
component to compute placement at render/toggle and apply conditional classes
instead of always using left-0 w-64: add a ref to the event card container,
create a placement state (e.g., tooltipPlacement) and in the handler that
toggles setShowAlert (or a useEffect when showAlert becomes true) measure
containerRef.getBoundingClientRect().right vs window.innerWidth and set
tooltipPlacement to 'left' (use left-0), 'right' (use right-0 left-auto), or
'center' (use left-1/2 transform -translate-x-1/2) so the tooltip div (the
element that currently has className='absolute left-0 top-8 z-50 w-64 ...')
conditionally renders the appropriate Tailwind classes to keep it inside the
viewport; keep using showAlert/alert/Warning button handlers but swap the fixed
left-0 class for the placement-dependent class string.
- Around line 231-236: The alert header currently checks only for 'postponed',
'venue-change', 'cancelled' and a falsy type, so alert.type === 'general'
renders empty; update the conditional rendering inside the <p className='text-sm
font-semibold text-yellow-900'> to include alert.type === 'general' (or a final
fallback case for any unmatched truthy type) and render a default label like '⚠️
Important Notice' so that any non-empty alert.type (e.g., 'general') shows an
appropriate header; adjust the three explicit checks and the fallback around
alert.type to ensure a default branch covers all other string values.
🧹 Nitpick comments (3)
src/components/pages/home/events.tsx (2)

213-220: Conflicting click-toggle and hover interactions on the alert button.

The button has both onClick (toggles showAlert) and onMouseEnter/onMouseLeave (sets showAlert to true/false). On desktop, the click toggle is effectively overridden by hover events. On mobile (touch), hover events don't fire, so click-toggle works — but there's no way to dismiss the tooltip except tapping the button again (tapping elsewhere won't close it since there's no outside-click handler).

Consider either:

  • Hover-only on desktop + click-toggle with outside-click-to-dismiss on mobile, or
  • Simplifying to hover-only (removing onClick) if mobile isn't a primary concern.

9-38: Event and EventCardProps types are duplicated — consider importing from event.d.ts.

The Event type here (lines 9–22) duplicates the canonical definition in src/types/event.d.ts. The alert shape { message: string; type?: ... } is also repeated in EventCardProps. Consider importing the Event type and extracting the alert type to avoid drift between files.

src/components/pages/Archive/archive.tsx (1)

9-38: Massive duplication: EventCard, Tooltip, and types are nearly identical to events.tsx.

The Event type, EventCardProps type, EventCard component (including all alert UI logic), and Tooltip component are copy-pasted between archive.tsx and events.tsx. This PR extends the duplicated surface area with the alert feature. Consider extracting into shared modules:

  • A shared EventCard component (e.g., src/components/EventCard.tsx)
  • A shared Tooltip component
  • Import the Event type from src/types/event.d.ts

This would make future alert changes (or any card changes) a single-file edit instead of two.

Also applies to: 121-312, 406-427

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/pages/home/events.tsx`:
- Line 266: The tooltip arrow div in events.tsx is hardcoded to 'left-4' which
breaks alignment when tooltipPlacement !== 'left'; update the arrow element that
currently uses class 'absolute -top-2 left-4 h-3 w-3 rotate-45 ...' to compute
its horizontal positioning from the tooltipPlacement prop/variable (e.g., when
tooltipPlacement === 'right' use 'right-4', when 'left' keep 'left-4', and when
centered placements like 'top'/'bottom' use 'left-1/2 transform
-translate-x-1/2'); implement this by building the arrow's className
conditionally based on tooltipPlacement so the arrow mirrors the tooltip
alignment.
- Around line 134-146: Replace the useEffect that computes tooltip placement
with useLayoutEffect so placement is computed synchronously to avoid the
one-frame flash; inside the effect (still reading alertContainerRef.current and
showAlert) compute tooltipWidth and setTooltipPlacement to 'right' when
rect.left + tooltipWidth > window.innerWidth, otherwise set it to 'left' (remove
the 'center' branch entirely because rect.left < tooltipWidth/2 should not map
to 'center'); keep using alertContainerRef and setTooltipPlacement exactly as
before but in useLayoutEffect and with the same dependency on showAlert.
🧹 Nitpick comments (3)
src/components/pages/home/events.tsx (3)

18-21: Extract the alert shape into a shared type to reduce duplication.

The same { message: string; type?: 'postponed' | 'venue-change' | 'cancelled' | 'general' } literal is repeated in Event, EventCardProps, and likely in src/types/event.d.ts. Extract it once and reference it everywhere.

♻️ Suggested shared type
+type EventAlert = {
+  message: string;
+  type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
+};
+
 type Event = {
   // ...
-  alert?: {
-    message: string;
-    type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
-  };
+  alert?: EventAlert;
 };

 type EventCardProps = {
   // ...
-  alert?: {
-    message: string;
-    type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
-  };
+  alert?: EventAlert;
 };

Also applies to: 34-37


229-236: onClick toggle conflicts with onMouseEnter/onMouseLeave on desktop.

On desktop, hovering opens the tooltip via onMouseEnter, but clicking while hovering toggles showAlert to false, causing the tooltip to disappear while the cursor is still over the button. Consider removing the onClick toggle (let hover drive desktop) and relying on onClick only for touch devices, or use a single interaction model.


227-270: Alert tooltip lacks keyboard accessibility.

The tooltip cannot be dismissed via Escape, and the tooltip content isn't associated with the button via aria-describedby (or similar). Screen-reader users won't know the tooltip content exists or be able to access it via keyboard alone. Consider:

  • Adding an onKeyDown handler for Escape to close the tooltip.
  • Linking the button to the tooltip panel with aria-describedby and an id on the tooltip <div>.
  • Adding role="tooltip" to the popover.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/pages/home/events.tsx (2)

74-76: ⚠️ Potential issue | 🟠 Major

Array.sort() mutates events state in place — use toSorted() or spread first.

events.sort(...) mutates the state array directly, which violates React's immutability contract for state. This can cause subtle rendering bugs.

🐛 Proposed fix
-  const sortedEvents = events.sort(
+  const sortedEvents = [...events].sort(
     (a, b) => new Date(a.eventDate).getTime() - new Date(b.eventDate).getTime()
   );

112-123: ⚠️ Potential issue | 🟠 Major

EventCard defined inside Events is recreated every render — causes unmount/remount of all cards.

Because EventCard is declared inside the parent component body, React sees a new component type on every render. This means all cards unmount and remount on any parent state change (e.g., height recalculation), destroying local state like showAlert and mousePosition.

Move EventCard outside Events and pass monthlyCardHeight/upcomingCardHeight as props (or via context).

🧹 Nitpick comments (4)
src/components/pages/home/events.tsx (4)

18-21: Extract a shared AlertInfo type to avoid duplication.

The alert shape is duplicated between Event and EventCardProps. Consider extracting it:

♻️ Suggested refactor
+type AlertInfo = {
+  message: string;
+  type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
+};
+
 type Event = {
   // ...
-  alert?: {
-    message: string;
-    type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
-  };
+  alert?: AlertInfo;
 };
 
 type EventCardProps = {
   // ...
-  alert?: {
-    message: string;
-    type?: 'postponed' | 'venue-change' | 'cancelled' | 'general';
-  };
+  alert?: AlertInfo;
 };

Also note that src/types/event.d.ts defines the canonical Event type — ideally both files should reference the same type rather than re-declaring it here.

Also applies to: 34-37


229-241: Mixed onClick toggle + onMouseEnter/onMouseLeave can feel inconsistent.

On desktop, hover controls visibility completely, making the click toggle superfluous (mouse leave immediately closes after click). On touch devices, onMouseLeave may fire immediately after tap in some browsers, preventing the tooltip from staying open.

Consider using only hover for desktop and only click (with outside-click-to-close) for touch, or pick one interaction model. This is minor and can be deferred.


255-263: Consider simplifying the alert header rendering with a map lookup.

The current chain of && conditions works but is verbose and fragile if new types are added. A lookup map would be cleaner:

♻️ Suggested refactor
+const ALERT_HEADERS: Record<string, string> = {
+  postponed: 'Event Postponed',
+  'venue-change': 'Venue Changed',
+  cancelled: 'Event Cancelled',
+};

 <p className='text-sm font-semibold text-yellow-900'>
-  {alert.type === 'postponed' && 'Event Postponed'}
-  {alert.type === 'venue-change' && 'Venue Changed'}
-  {alert.type === 'cancelled' && 'Event Cancelled'}
-  {(!alert.type ||
-    alert.type === 'general' ||
-    !['postponed', 'venue-change', 'cancelled'].includes(alert.type)) &&
-    'Important Notice'}
+  {(alert.type && ALERT_HEADERS[alert.type]) || 'Important Notice'}
 </p>

107-110: useEffect dependencies monthlyEvents and upcomingEvents are new array references every render.

Since filter() creates a new array on every render, this effect fires every render cycle. It doesn't cause an infinite loop (React bails out on same-value setState), but it's wasteful. Consider memoizing the filtered arrays with useMemo.

@Som23Git
Copy link
Contributor Author

@HarshPatel5940, take a look. Let me know if you need any updates from my end. Thanks.

@HarshPatel5940
Copy link
Member

@Som23Git thanks for the updates! will review shortly.

Copy link
Member

@HarshPatel5940 HarshPatel5940 left a comment

Choose a reason for hiding this comment

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

seems fine on an high level, will clone and check as well for any issues.

Copy link
Contributor

@bupd bupd left a comment

Choose a reason for hiding this comment

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

/lgtm

Merge this

Copy link
Member

@HarshPatel5940 HarshPatel5940 left a comment

Choose a reason for hiding this comment

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

@bupd approves

@HarshPatel5940 HarshPatel5940 merged commit 513bfc2 into FOSSUChennai:main Feb 22, 2026
1 check passed
@HarshPatel5940
Copy link
Member

It will be in release soon.

cc: @JustinBenito

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants