Skip to content

Add-Date-filter-functionality#156

Open
Kirubapanneers wants to merge 11 commits into
FOSSUChennai:mainfrom
Kirubapanneers:add-location-date-search
Open

Add-Date-filter-functionality#156
Kirubapanneers wants to merge 11 commits into
FOSSUChennai:mainfrom
Kirubapanneers:add-location-date-search

Conversation

@Kirubapanneers
Copy link
Copy Markdown

@Kirubapanneers Kirubapanneers commented Feb 22, 2025

Hi @nammahari,Thanks for your feedback on my previous PR. I have now implemented a filter functionality as you said instead of search, allowing users to refine events based on location and date. Could you review the changes and let me know if this aligns with the site scope before I create a new PR?
image

Summary by CodeRabbit

  • New Features

    • Location filter added to the events section with case-insensitive substring searching
    • Events support optional end datetimes and show formatted ranges when different from start
  • Bug Fixes / Improvements

    • Month classification now uses event end datetime to assign events to the current-month view
    • Event loading falls back to local data when remote fetches fail
  • UI

    • Header updated to include the location input and minor layout refinements for event listings

@JustinBenito
Copy link
Copy Markdown
Contributor

Hey @Kirubapanneers the layout looks really cool, with just minor tweeks I think we can get it to prod.
Can you please change the PR from a draft, so that once everything is done we can merge it asap

Cheers :)

@Kirubapanneers Kirubapanneers marked this pull request as ready for review March 11, 2025 16:09
@Kirubapanneers
Copy link
Copy Markdown
Author

Hey @JustinBenito , I'll make the minor tweaks and update the PR shortly. I've also marked the PR as ready for review. Let me know if there's anything else to refine.

@JustinBenito
Copy link
Copy Markdown
Contributor

Hey @Kirubapanneers are you working on it or is this the updated PR buddy

Cheers :)

@Kirubapanneers
Copy link
Copy Markdown
Author

Hiii,@JustinBenito, This is the updated PR . Let me know if any changes are needed.

@JustinBenito
Copy link
Copy Markdown
Contributor

Hey @Kirubapanneers just ran the code and I must admit, I see so much of work here. That is something really great.
But one thing I noticed, was that most of them seems to be redundant, like the sorting is something that we already do based on the date of the event and it works just fine. Coming to the sorting, we wont really store the previous months events and no community will also be adding communities into the far future. So the split of the current month and upcoming months also works just fine. If there is an important sorting that we would need to do, it would be of location.

I just designed this quick design, lmk your thoughts.
Reducing the space used by the filters would be a great addition, I feel.

Screenshot 2025-03-24 at 4 56 11 PM

Cheers :)

@Kirubapanneers
Copy link
Copy Markdown
Author

Hey @JustinBenito, I have now refined the filtering to focus only on location based filter as suggested. let me know if any further adjustments are needed!........
image

@nammahari
Copy link
Copy Markdown
Collaborator

@Kirubapanneers can you just resolve the conflicts.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Added a location filter input and case-insensitive substring filtering; compute event end datetime (use eventEndDate ?? eventDate normalized to end-of-day) for "this month" classification; wired end values into EventCard rendering; tightened fetch fallback to local eventsJson and applied minor JSX/formatting tweaks.

Changes

Cohort / File(s) Summary
Home events component
src/components/pages/home/events.tsx
Introduced filterLocation state and a case-insensitive location-matching helper; applied location filter to both monthlyEvents and upcomingEvents; changed "this month" logic to compute event end datetime (end-of-day fallback) and require eventEndDate >= today; passed end values into EventCard to render ranges; added location <input> in header; tightened remote fetch handling to fall back to local eventsJson when fetch fails or JSON falsy; minor JSX/layout and formatting changes.

Sequence Diagram(s)

sequenceDiagram
  participant UI as "HomeEvents UI"
  participant API as "Remote Events API"
  participant Local as "local eventsJson"
  UI->>API: fetch events
  alt fetch succeeds and JSON truthy
    API-->>UI: events JSON
    UI->>UI: parse JSON, setEvents(parsed)
  else fetch succeeds but JSON falsy
    API-->>UI: empty/falsy
    UI->>Local: load local eventsJson
    Local-->>UI: local events
    UI->>UI: setEvents(local)
  else fetch fails
    API--x UI: network error
    UI->>Local: load local eventsJson
    Local-->>UI: local events
    UI->>UI: setEvents(local)
  end
  UI->>UI: compute event end datetime (endDate ∥ eventDate at end-of-day) for "this month" classification
  UI->>UI: apply filterLocation (case-insensitive substring) to monthly & upcoming lists
  UI->>UI: render EventCard with start and optional end ranges
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through dates both start and end,

nudged places with a sniff and filter blend.
I checked the ends before the month began,
fetched local lists when networks ran.
A joyful thump — events now span!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'Add-Date-filter-functionality' describes adding date filtering, but the actual changes primarily implement location-based filtering with minimal date logic changes. The title does not accurately reflect the main change. Revise the title to accurately reflect the primary change, such as 'Add location filter to events' or 'Implement location-based event filtering' to better represent the actual implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

@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

Caution

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

⚠️ Outside diff range comments (1)
package.json (1)

16-25: ⚠️ Potential issue | 🔴 Critical

Restore the rss runtime dependency.

src/app/api/rss/route.ts imports and instantiates RSS at runtime, but rss is missing from dependencies. @types/rss in devDependencies provides only type definitions, not the runtime package. This will break the /api/rss endpoint in production.

🔧 Minimal fix
  "next-umami": "^1.0.0",
  "phosphor-react": "^1.4.1",
  "react": "^19.0.0",
  "react-dom": "^19.0.0",
+ "rss": "^1.2.2",
  "react-select": "^5.10.0"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 16 - 25, The package.json is missing the runtime
"rss" dependency required by the RSS import/instantiation used in
src/app/api/rss/route.ts (the RSS symbol), so add "rss" to the dependencies in
package.json (matching the version you want to ship) and run install to ensure
the /api/rss endpoint has the runtime package available; keep `@types/rss` in
devDependencies for types only.
🧹 Nitpick comments (2)
src/components/pages/home/events.tsx (2)

126-129: Use a stable key instead of the array index.

This list is filtered on every keystroke, so key={index} can preserve the wrong child state when cards shift positions. A stable event identifier is safer here, especially with AddToCalendar inside each card.

♻️ Safer key
-            filteredEvents.map((event, index) => (
+            filteredEvents.map((event) => (
               <EventCard
-                key={index}
+                key={`${event.eventLink}-${event.eventDate}`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 126 - 129, Replace the
unstable key={index} on the EventCard in the filteredEvents.map with a stable
unique identifier from the event object (e.g., key={event.id} or
key={event.uuid} or key={`${event.id}-${event.start}`}), so child components
like EventCard and its AddToCalendar maintain correct state when the array is
filtered or reordered; update the map where filteredEvents and EventCard are
used to reference that unique property.

5-5: Avoid introducing a second phosphor package for one icon.

The repo already depends on @phosphor-icons/react, and src/components/no-events-card.tsx:1-5 still imports from it. Pulling MapPin from phosphor-react adds another icon package for the same job and makes the dependency graph heavier than needed.

♻️ Small cleanup
-import { MapPin } from "phosphor-react";
+import { MapPin } from "@phosphor-icons/react";

That also lets you drop phosphor-react from package.json.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` at line 5, Replace the MapPin import in
src/components/pages/home/events.tsx so it imports MapPin from
"@phosphor-icons/react" (the same package used by
src/components/no-events-card.tsx) instead of "phosphor-react"; update the
import statement referencing MapPin and ensure any JSX usage remains unchanged,
then remove the unused "phosphor-react" entry from package.json/dependencies to
avoid the duplicate icon package.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/pages/home/events.tsx`:
- Around line 115-121: The location filter input relies solely on placeholder
text which is not accessible; update the input in the events component to
include an accessible name by either adding a <label> tied to the input id
(e.g., create a label with htmlFor="location-filter" and give the input
id="location-filter") or add an aria-label (e.g., aria-label="Filter by
location") to the input that uses filterLocation and setFilterLocation so screen
readers can identify the control.
- Around line 39-43: The AddToCalendar button is nested inside the outer anchor
(href={link}) creating invalid nested interactive elements; remove the
AddToCalendar component from inside that <a> and instead place it outside the
anchor (or replace the anchor with a non-interactive container and add an
onClick/onKeyDown to simulate navigation). Update the wrapping element around
the card (the element using href={link} and className="group ...") to be a div
with a click handler that calls window.open(link, "_blank") and keyboard
handlers (role="link" and tabIndex=0) for accessibility, or keep the <a> but
move AddToCalendar out and ensure the button calls event.stopPropagation() if
you must keep it adjacent to a clickable parent; locate references to
AddToCalendar and the anchor with href={link} in events.tsx to apply these
changes.
- Around line 89-104: Remove the unnecessary client-only gating: delete the
isClient state (const [isClient, setIsClient]), its useEffect, and the early
return that shows "Loading..."; since the file is already "use client" and
browser APIs (e.g., window.open used in AddToCalendar) are only invoked in event
handlers, render the UI directly using the existing filteredEvents computation
(filterLocation, events, Event) without delaying with the isClient flag.

---

Outside diff comments:
In `@package.json`:
- Around line 16-25: The package.json is missing the runtime "rss" dependency
required by the RSS import/instantiation used in src/app/api/rss/route.ts (the
RSS symbol), so add "rss" to the dependencies in package.json (matching the
version you want to ship) and run install to ensure the /api/rss endpoint has
the runtime package available; keep `@types/rss` in devDependencies for types
only.

---

Nitpick comments:
In `@src/components/pages/home/events.tsx`:
- Around line 126-129: Replace the unstable key={index} on the EventCard in the
filteredEvents.map with a stable unique identifier from the event object (e.g.,
key={event.id} or key={event.uuid} or key={`${event.id}-${event.start}`}), so
child components like EventCard and its AddToCalendar maintain correct state
when the array is filtered or reordered; update the map where filteredEvents and
EventCard are used to reference that unique property.
- Line 5: Replace the MapPin import in src/components/pages/home/events.tsx so
it imports MapPin from "@phosphor-icons/react" (the same package used by
src/components/no-events-card.tsx) instead of "phosphor-react"; update the
import statement referencing MapPin and ensure any JSX usage remains unchanged,
then remove the unused "phosphor-react" entry from package.json/dependencies to
avoid the duplicate icon package.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ffff9237-3068-4a75-91ae-f1f0581f654a

📥 Commits

Reviewing files that changed from the base of the PR and between f23577c and de8a546.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • git
  • package.json
  • src/components/pages/home/events.tsx

Comment thread src/components/pages/home/events.tsx Outdated
Comment thread src/components/pages/home/events.tsx Outdated
Comment thread src/components/pages/home/events.tsx
@nammahari
Copy link
Copy Markdown
Collaborator

@Kirubapanneers, I still see major conflicts.

Copy link
Copy Markdown

@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

Caution

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

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

59-75: ⚠️ Potential issue | 🟠 Major

Handle rejected fetches so fallback data always loads.

At Line 61, only non-OK HTTP responses trigger fallback. A network failure/rejected promise skips this path and can leave events empty.

💡 Suggested fix
     if (process.env.NODE_ENV !== 'development') {
       fetch(
         'https://raw.githubusercontent.com/FOSSUChennai/Communities/refs/heads/main/src/data/events.json'
       )
         .then((response) => {
           if (!response.ok) {
             setEvents(eventsJson as Event[]);
             return null;
           }
           return response.json();
         })
         .then((json) => {
           if (json) {
             setEvents(json);
           }
-        });
+        })
+        .catch(() => {
+          setEvents(eventsJson as Event[]);
+        });
     } else {
       setEvents(eventsJson as Event[]);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 59 - 75, The current
useEffect fetch chain only falls back to eventsJson on non-OK responses and does
not handle network rejections; update the fetch logic in the useEffect (the
fetch(...) promise chain) to catch rejected promises and call
setEvents(eventsJson as Event[]) on any fetch/network error or JSON parse error;
you can add a .catch(...) to the existing chain (or convert to async/await with
try/catch) and ensure setEvents(eventsJson as Event[]) is invoked in the catch
block so events is always populated when fetch fails.
🧹 Nitpick comments (1)
src/components/pages/home/events.tsx (1)

9-24: Unify event typing with the shared model to prevent drift.

This file defines a local Event type (Lines 9–24) that now includes eventEndDate/eventEndTime, but src/types/event.d.ts does not. Keeping two event contracts will drift over time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 9 - 24, Replace the local
Event type in events.tsx with the canonical shared Event type: remove the inline
type declaration named Event, import the exported Event interface/type from the
shared types module, and update that shared Event model to include the new
optional fields (eventEndDate, eventEndTime) and the alert.type union (including
'general') so both places use the same contract; ensure any property names and
optional markers match exactly between the component usage (events.tsx) and the
shared type to prevent drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/pages/home/events.tsx`:
- Around line 323-341: The AddToCalendar export currently only takes eventDate
and maps it to both start and end, so multi-day or time-ranged events are lost;
update the AddToCalendar component to accept eventEndDate (and optionally
eventStartTime/eventEndTime) and change the Google Calendar URL construction in
AddToCalendar (where dateFormatter is used) to use dateFormatter(eventDate) for
the start and dateFormatter(eventEndDate) for the end (or combine start/end
times when provided); then update the usage in the events render (the
AddToCalendar instance in events.tsx that passes eventDate={date}) to pass the
new props (eventEndDate and/or time props) using the existing date/time
variables that produce formattedDate/formattedTime so the exported calendar item
reflects the actual range.
- Around line 92-99: The code creates eventEndDate with new
Date(event.eventEndDate ?? event.eventDate) which yields a UTC-parsed Date from
"YYYY-MM-DD" strings and causes month/day shifts in negative-offset timezones;
instead, parse the YYYY-MM-DD string manually and construct a local Date using
new Date(year, monthIndex, day) for both eventDate and eventEndDate (where
eventDate is the variable used in the monthly checks) so comparisons using
getMonth()/getFullYear() and the >= today check behave correctly; update the
parsing logic near the eventDate/eventEndDate construction and keep the rest of
the filter (including matchesLocation) unchanged.

---

Outside diff comments:
In `@src/components/pages/home/events.tsx`:
- Around line 59-75: The current useEffect fetch chain only falls back to
eventsJson on non-OK responses and does not handle network rejections; update
the fetch logic in the useEffect (the fetch(...) promise chain) to catch
rejected promises and call setEvents(eventsJson as Event[]) on any fetch/network
error or JSON parse error; you can add a .catch(...) to the existing chain (or
convert to async/await with try/catch) and ensure setEvents(eventsJson as
Event[]) is invoked in the catch block so events is always populated when fetch
fails.

---

Nitpick comments:
In `@src/components/pages/home/events.tsx`:
- Around line 9-24: Replace the local Event type in events.tsx with the
canonical shared Event type: remove the inline type declaration named Event,
import the exported Event interface/type from the shared types module, and
update that shared Event model to include the new optional fields (eventEndDate,
eventEndTime) and the alert.type union (including 'general') so both places use
the same contract; ensure any property names and optional markers match exactly
between the component usage (events.tsx) and the shared type to prevent drift.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f35e2894-15b7-40a6-8bf8-1e76e990e26c

📥 Commits

Reviewing files that changed from the base of the PR and between de8a546 and f9e8889.

📒 Files selected for processing (1)
  • src/components/pages/home/events.tsx

Comment on lines +92 to +99
const eventEndDate = new Date(event.eventEndDate ?? event.eventDate);
eventEndDate.setHours(23, 59, 59, 999);

return (
eventDate.getMonth() === today.getMonth() &&
eventDate.getFullYear() === today.getFullYear() &&
eventDate >= today
eventEndDate >= today &&
matchesLocation(event)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In JavaScript, does new Date('YYYY-MM-DD') parse as UTC or local time, and what timezone-related pitfalls can affect month/day comparisons?

💡 Result:

new Date('YYYY-MM-DD') parses the date-only ISO 8601 string as UTC midnight (00:00:00Z). It does not parse as local time. This is explicitly stated in MDN documentation: "When the time zone offset is absent, date-only forms are interpreted as a UTC time" (sources 1,2,3,6). For example, new Date('1970-01-01') creates a Date representing 1970-01-01T00:00:00Z, which displays as 1969-12-31 19:00:00 GMT-0500 (EST) in New York due to local timezone offset (source 4). Timezone-related pitfalls for month/day comparisons: 1. Local vs UTC getters: getMonth/getDate return local time components, getUTCMonth/getUTCDate return UTC components. Comparing across timezones or using mixed getters can yield wrong results (sources 1,9,10). 2. DST transitions: getTimezoneOffset varies; operations near DST boundaries can shift dates unexpectedly (source 1). 3. Date mutations: setMonth/setDate interpret in local time and can overflow/underflow days, altering the timestamp unexpectedly (sources 10,12). 4. String parsing ambiguity: Non-ISO formats may parse as local, leading to inconsistencies (sources 2,9). To avoid pitfalls for date-only comparisons, parse to UTC explicitly (e.g., new Date('YYYY-MM-DD') then use UTC methods), normalize to UTC midnight with Date.UTC(year, month-1, day), or use libraries like date-fns parseISO (treats date-only as local) or Temporal.PlainDate (upcoming, date-only without time).

Citations:


🏁 Script executed:

find . -name "events.tsx" -type f

Repository: FOSSUChennai/Communities

Length of output: 106


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '80,110p'

Repository: FOSSUChennai/Communities

Length of output: 1355


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '1,95p' | tail -40

Repository: FOSSUChennai/Communities

Length of output: 1633


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '40,60p'

Repository: FOSSUChennai/Communities

Length of output: 975


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '25,45p'

Repository: FOSSUChennai/Communities

Length of output: 650


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '103,115p'

Repository: FOSSUChennai/Communities

Length of output: 615


🏁 Script executed:

cat -n ./src/components/pages/home/events.tsx | sed -n '1,25p'

Repository: FOSSUChennai/Communities

Length of output: 915


🏁 Script executed:

head -100 ./src/data/events.json

Repository: FOSSUChennai/Communities

Length of output: 6014


Use local-date parsing to avoid timezone-shifted month/day classification.

At lines 92-93, new Date(event.eventDate ?? event.eventDate) parsing YYYY-MM-DD strings creates UTC dates, but comparison uses .getMonth() and .getFullYear() (local timezone methods). In timezones with negative UTC offsets (e.g., US Eastern), events are misclassified: "2025-01-01" becomes 2024-12-31 19:00 locally, failing the monthly filter and appearing as "upcoming" instead.

💡 Suggested fix
+  const parseLocalDate = (value: string, endOfDay = false) => {
+    const [y, m, d] = value.split('-').map(Number);
+    return endOfDay
+      ? new Date(y, m - 1, d, 23, 59, 59, 999)
+      : new Date(y, m - 1, d, 0, 0, 0, 0);
+  };
+
   const monthlyEvents = sortedEvents.filter((event) => {
-    const eventDate = new Date(event.eventDate);
-    const eventEndDate = new Date(event.eventEndDate ?? event.eventDate);
-    eventEndDate.setHours(23, 59, 59, 999);
+    const eventDate = parseLocalDate(event.eventDate);
+    const eventEndDate = parseLocalDate(event.eventEndDate ?? event.eventDate, true);

     return (
       eventDate.getMonth() === today.getMonth() &&
       eventDate.getFullYear() === today.getFullYear() &&
       eventEndDate >= today &&
       matchesLocation(event)
     );
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 92 - 99, The code creates
eventEndDate with new Date(event.eventEndDate ?? event.eventDate) which yields a
UTC-parsed Date from "YYYY-MM-DD" strings and causes month/day shifts in
negative-offset timezones; instead, parse the YYYY-MM-DD string manually and
construct a local Date using new Date(year, monthIndex, day) for both eventDate
and eventEndDate (where eventDate is the variable used in the monthly checks) so
comparisons using getMonth()/getFullYear() and the >= today check behave
correctly; update the parsing logic near the eventDate/eventEndDate construction
and keep the rest of the filter (including matchesLocation) unchanged.

Comment on lines +323 to +341
<div className='flex-row items-center text-sm text-gray-600'>
<div className='flex flex-wrap items-center gap-2'>
<span className='rounded bg-green-100 px-2 py-0.5 text-xs text-green-800'>
{location}
</span>
<span className='rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-800'>
{formattedDate}
</span>
<span className='rounded bg-yellow-100 px-2 py-0.5 text-xs text-yellow-800'>
{formattedTime}
</span>
<span className='shrink-0'>
<AddToCalendar
eventTitle={title}
eventVenue={venue}
eventDate={date}
eventLink={link}
/>
</div>
<div className='mt-auto flex flex-grow flex-col justify-end'>
<span className='mt-4 flex items-start gap-1 text-xs'>
<MapPin size={16} className='min-w-[16px]' />{' '}
<span className='break-words'>{validateAndFormatVenue(venue)}</span>{' '}
</span>
</div>
</span>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify AddToCalendar prop surface and whether end date/time are supported.
fd -i 'AddToCalendar.tsx' --exec sed -n '1,240p' {}
rg -n -C3 'interface|type|eventDate|eventTime|endDate|endTime|eventEndDate|eventEndTime' src/components/AddToCalendar.tsx

Repository: FOSSUChennai/Communities

Length of output: 2363


AddToCalendar component does not support event end dates or time ranges.

The AddToCalendar component only accepts eventDate as a prop and maps it to both start and end dates in the Google Calendar URL (dates: ${dateFormatter(eventDate)}/${dateFormatter(eventDate)}). The UI displays what appear to be date/time ranges (formattedDate/formattedTime), but this information is not passed to the component, resulting in all events being exported as single-day events. Support for eventEndDate and/or time parameters is needed to accurately export multi-day or ranged events.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 323 - 341, The
AddToCalendar export currently only takes eventDate and maps it to both start
and end, so multi-day or time-ranged events are lost; update the AddToCalendar
component to accept eventEndDate (and optionally eventStartTime/eventEndTime)
and change the Google Calendar URL construction in AddToCalendar (where
dateFormatter is used) to use dateFormatter(eventDate) for the start and
dateFormatter(eventEndDate) for the end (or combine start/end times when
provided); then update the usage in the events render (the AddToCalendar
instance in events.tsx that passes eventDate={date}) to pass the new props
(eventEndDate and/or time props) using the existing date/time variables that
produce formattedDate/formattedTime so the exported calendar item reflects the
actual range.

Copy link
Copy Markdown

@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 (1)
src/components/pages/home/events.tsx (1)

56-73: ⚠️ Potential issue | 🟠 Major

Add a catch fallback for rejected fetches.

If fetch() rejects (network/CORS), events remains empty because only non-OK HTTP responses are handled. Please keep the local JSON fallback in the rejection path too.

💡 Suggested patch
   useEffect(() => {
+    const fallbackToLocal = () => setEvents(eventsJson as Event[]);
+
     if (process.env.NODE_ENV !== 'development') {
       fetch(
         'https://raw.githubusercontent.com/FOSSUChennai/Communities/refs/heads/main/src/data/events.json'
       )
         .then((response) => {
           if (!response.ok) {
-            // If the fetch fails or in development mode, use the local eventsJson
-            setEvents(eventsJson as Event[]);
+            fallbackToLocal();
             return null;
           }
           return response.json();
         })
         .then((json) => {
           if (json) {
             setEvents(json);
           }
-        });
+        })
+        .catch(() => {
+          fallbackToLocal();
+        });
     } else {
-      // In development, use the local eventsJson directly
-      setEvents(eventsJson as Event[]);
+      fallbackToLocal();
     }
   }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 56 - 73, The fetch in the
useEffect currently only handles non-OK HTTP responses but not rejections; add a
.catch handler on the fetch promise chain (or use try/catch with async/await) to
handle network/CORS failures and call setEvents(eventsJson as Event[]) as the
fallback, and optionally log the error; target the existing fetch(...) promise
chain inside the useEffect (references: useEffect, fetch(...), setEvents,
eventsJson) so rejected fetches also populate events from the local JSON.
♻️ Duplicate comments (2)
src/components/pages/home/events.tsx (2)

89-91: ⚠️ Potential issue | 🟠 Major

Use local date parsing for month/day comparisons.

new Date('YYYY-MM-DD') can shift into the previous day/month in negative-offset timezones when later compared via local getters (getMonth, getFullYear). That can misclassify events in both monthly and upcoming buckets.

💡 Suggested patch
+  const parseLocalDate = (value: string, endOfDay = false) => {
+    const [y, m, d] = value.split('-').map(Number);
+    return endOfDay
+      ? new Date(y, m - 1, d, 23, 59, 59, 999)
+      : new Date(y, m - 1, d, 0, 0, 0, 0);
+  };
+
   const monthlyEvents = sortedEvents.filter((event) => {
-    const eventDate = new Date(event.eventDate);
-    const eventEndDate = new Date(event.eventEndDate ?? event.eventDate);
-    eventEndDate.setHours(23, 59, 59, 999);
+    const eventDate = parseLocalDate(event.eventDate);
+    const eventEndDate = parseLocalDate(event.eventEndDate ?? event.eventDate, true);

     return (
       eventDate.getMonth() === today.getMonth() &&
       eventDate.getFullYear() === today.getFullYear() &&
       eventEndDate >= today &&
       matchesLocation(event)
     );
   });

   const upcomingEvents = sortedEvents.filter((event) => {
-    const eventDate = new Date(event.eventDate);
+    const eventDate = parseLocalDate(event.eventDate, true);
     return (
       eventDate > endOfToday &&
       (eventDate.getMonth() !== today.getMonth() ||
         eventDate.getFullYear() !== today.getFullYear()) &&
       matchesLocation(event)
     );
   });
In JavaScript, when parsing date-only strings like "2025-01-01", does new Date("YYYY-MM-DD") use UTC or local time, and what is the recommended way to avoid timezone-related month/day shifts when using getMonth()/getFullYear()?

Also applies to: 102-107

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 89 - 91, The code
constructs eventDate and eventEndDate using new Date(string) which can be parsed
as UTC and shift when using local getters; change parsing to build local dates
by extracting year, month, day from event.eventDate (and event.eventEndDate
fallback) and calling new Date(year, month-1, day) so getMonth/getFullYear
operate on local values; apply the same local-construction logic for the
eventEndDate used later (then setHours(23,59,59,999) on that local Date) and
update any other occurrences (the block around eventDate/eventEndDate and the
similar code at lines ~102-107) to use these local-date constructors instead of
new Date(string).

331-336: ⚠️ Potential issue | 🟡 Minor

Calendar export still drops end date/time range.

The card now displays ranged date/time, but AddToCalendar is still called with start date only, so exported entries likely remain single-day/single-time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 331 - 336, The
AddToCalendar call is only passing a single datetime (eventDate) so exported
calendar entries lose the range; update the AddToCalendar invocation to also
pass the event end values from this component (e.g., eventEndDate and/or
eventEndTime or eventEnd depending on the AddToCalendar prop names) using the
existing end-range variables in scope (such as endDate/end or similar) alongside
eventTitle/eventVenue/eventLink; verify the exact prop names on the
AddToCalendar component and supply the matching end-range props so exports
include the full start-to-end range.
🧹 Nitpick comments (1)
src/components/pages/home/events.tsx (1)

9-24: Avoid local Event type drift from the shared event contract.

This file now carries a local Event shape with eventEndDate/eventEndTime, but src/types/event.d.ts does not include them. Consider extending the shared type (or importing and composing it) to keep event typing consistent across components.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 9 - 24, You added a local
Event type that includes eventEndDate and eventEndTime which diverges from the
shared event contract; instead import or extend the shared Event interface and
augment it with the optional eventEndDate and eventEndTime fields (or compose a
LocalEvent type that extends SharedEvent) so components use the canonical shape;
update references to the local Event type in this file to the composed/extended
type to prevent type drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/components/pages/home/events.tsx`:
- Around line 56-73: The fetch in the useEffect currently only handles non-OK
HTTP responses but not rejections; add a .catch handler on the fetch promise
chain (or use try/catch with async/await) to handle network/CORS failures and
call setEvents(eventsJson as Event[]) as the fallback, and optionally log the
error; target the existing fetch(...) promise chain inside the useEffect
(references: useEffect, fetch(...), setEvents, eventsJson) so rejected fetches
also populate events from the local JSON.

---

Duplicate comments:
In `@src/components/pages/home/events.tsx`:
- Around line 89-91: The code constructs eventDate and eventEndDate using new
Date(string) which can be parsed as UTC and shift when using local getters;
change parsing to build local dates by extracting year, month, day from
event.eventDate (and event.eventEndDate fallback) and calling new Date(year,
month-1, day) so getMonth/getFullYear operate on local values; apply the same
local-construction logic for the eventEndDate used later (then
setHours(23,59,59,999) on that local Date) and update any other occurrences (the
block around eventDate/eventEndDate and the similar code at lines ~102-107) to
use these local-date constructors instead of new Date(string).
- Around line 331-336: The AddToCalendar call is only passing a single datetime
(eventDate) so exported calendar entries lose the range; update the
AddToCalendar invocation to also pass the event end values from this component
(e.g., eventEndDate and/or eventEndTime or eventEnd depending on the
AddToCalendar prop names) using the existing end-range variables in scope (such
as endDate/end or similar) alongside eventTitle/eventVenue/eventLink; verify the
exact prop names on the AddToCalendar component and supply the matching
end-range props so exports include the full start-to-end range.

---

Nitpick comments:
In `@src/components/pages/home/events.tsx`:
- Around line 9-24: You added a local Event type that includes eventEndDate and
eventEndTime which diverges from the shared event contract; instead import or
extend the shared Event interface and augment it with the optional eventEndDate
and eventEndTime fields (or compose a LocalEvent type that extends SharedEvent)
so components use the canonical shape; update references to the local Event type
in this file to the composed/extended type to prevent type drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b20a582-e78d-4574-b8ec-a57c9dccd9dd

📥 Commits

Reviewing files that changed from the base of the PR and between f9e8889 and a8b7e4b.

📒 Files selected for processing (1)
  • src/components/pages/home/events.tsx

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
src/components/pages/home/events.tsx (1)

88-97: ⚠️ Potential issue | 🟠 Major

UTC date parsing can still shift month/day classification in US timezones.

Line 89 and Line 90 parse YYYY-MM-DD via new Date(...) (UTC), but Line 94-95 use local-time getters. In negative UTC offsets, some events can move to the previous local day/month and be filtered incorrectly.

💡 Suggested fix
+  const parseLocalDate = (value: string, endOfDay = false) => {
+    const [year, month, day] = value.split('-').map(Number);
+    return endOfDay
+      ? new Date(year, month - 1, day, 23, 59, 59, 999)
+      : new Date(year, month - 1, day, 0, 0, 0, 0);
+  };
+
   const monthlyEvents = sortedEvents.filter((event) => {
-    const eventDate = new Date(event.eventDate);
-    const eventEndDate = new Date(event.eventEndDate ?? event.eventDate);
-    eventEndDate.setHours(23, 59, 59, 999);
+    const eventDate = parseLocalDate(event.eventDate);
+    const eventEndDate = parseLocalDate(event.eventEndDate ?? event.eventDate, true);

     return (
       eventDate.getMonth() === today.getMonth() &&
       eventDate.getFullYear() === today.getFullYear() &&
       eventEndDate >= today &&
       matchesLocation(event)
     );
   });
In JavaScript, does `new Date('YYYY-MM-DD')` parse as UTC, and can using local getters like `getMonth()`/`getFullYear()` cause month/day shifts in negative-offset timezones?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 88 - 97, The filter is
parsing YYYY-MM-DD with new Date(...) (which is treated as UTC) but then uses
local getters (getMonth/getFullYear) and setHours, causing day/month shifts in
negative-offset zones; in the monthlyEvents filter (sortedEvents.filter) convert
all date comparisons to UTC consistently — e.g., parse
event.eventDate/event.eventEndDate into UTC timestamps (or use Date.UTC after
splitting the YYYY-MM-DD string) and compare against a UTC-based "today" (or use
getUTCMonth/getUTCFullYear and setUTCHours on eventEndDate) so eventDate,
eventEndDate and today are all compared in the same timezone context (UTC) and
matchesLocation(event) logic remains unchanged.
🧹 Nitpick comments (1)
src/components/pages/home/events.tsx (1)

361-373: Filter scope is ambiguous in the current placement.

The control appears under the this month heading, but it also filters upcoming events. Consider moving it to a shared top-level area or updating label text to “Filter all events by location.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/pages/home/events.tsx` around lines 361 - 373, The location
filter input inside the events list (the JSX block containing the h2 "this
month" and the input bound to filterLocation / setFilterLocation in
src/components/pages/home/events.tsx) has ambiguous scope; either move this
input out of the "this month" section into a shared top-level area (e.g., above
both "this month" and "upcoming" lists) so it clearly filters all events, or
keep it in place but update its accessible label and placeholder to indicate
global scope by changing aria-label and placeholder to "Filter all events by
location" (and update any visible label text accordingly) so users understand it
filters both "this month" and "upcoming".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/pages/home/events.tsx`:
- Around line 88-97: The filter is parsing YYYY-MM-DD with new Date(...) (which
is treated as UTC) but then uses local getters (getMonth/getFullYear) and
setHours, causing day/month shifts in negative-offset zones; in the
monthlyEvents filter (sortedEvents.filter) convert all date comparisons to UTC
consistently — e.g., parse event.eventDate/event.eventEndDate into UTC
timestamps (or use Date.UTC after splitting the YYYY-MM-DD string) and compare
against a UTC-based "today" (or use getUTCMonth/getUTCFullYear and setUTCHours
on eventEndDate) so eventDate, eventEndDate and today are all compared in the
same timezone context (UTC) and matchesLocation(event) logic remains unchanged.

---

Nitpick comments:
In `@src/components/pages/home/events.tsx`:
- Around line 361-373: The location filter input inside the events list (the JSX
block containing the h2 "this month" and the input bound to filterLocation /
setFilterLocation in src/components/pages/home/events.tsx) has ambiguous scope;
either move this input out of the "this month" section into a shared top-level
area (e.g., above both "this month" and "upcoming" lists) so it clearly filters
all events, or keep it in place but update its accessible label and placeholder
to indicate global scope by changing aria-label and placeholder to "Filter all
events by location" (and update any visible label text accordingly) so users
understand it filters both "this month" and "upcoming".

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3fabbeaa-38a8-4392-a7fb-ad900e069172

📥 Commits

Reviewing files that changed from the base of the PR and between a8b7e4b and 8416b74.

📒 Files selected for processing (1)
  • src/components/pages/home/events.tsx

@Kirubapanneers
Copy link
Copy Markdown
Author

Hi @nammahari, I have resolved the conflicts. Can you take a quick look and let me know if I need to do anything else?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants