diff --git a/assets/javascripts/discourse/components/upcoming-events-list.gjs b/assets/javascripts/discourse/components/upcoming-events-list.gjs
index adaf42602..e3b70bbad 100644
--- a/assets/javascripts/discourse/components/upcoming-events-list.gjs
+++ b/assets/javascripts/discourse/components/upcoming-events-list.gjs
@@ -118,13 +118,20 @@ export default class UpcomingEventsList extends Component {
groupByMonthAndDay(data) {
return data.reduce((result, item) => {
- const date = new Date(item.starts_at);
+ const startDate = moment(item.starts_at);
+ const endDate = moment(item.ends_at);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
-
const monthKey = `${year}-${month}`;
+ if (startDate.isSameOrBefore(endDate, "day")) {
+ result[monthKey][day].push(item);
+
+ // Move to the next day
+ startDate.add(1, "day");
+ }
+
result[monthKey] = result[monthKey] ?? {};
result[monthKey][day] = result[monthKey][day] ?? [];
@@ -174,6 +181,7 @@ export default class UpcomingEventsList extends Component {
{{this.formatDate month day}}
+ {{log events}}
{{#each events as |event|}}
diff --git a/test/javascripts/integration/components/upcoming-events-list-test.gjs b/test/javascripts/integration/components/upcoming-events-list-test.gjs
index 078941e3b..aed6d9f1f 100644
--- a/test/javascripts/integration/components/upcoming-events-list-test.gjs
+++ b/test/javascripts/integration/components/upcoming-events-list-test.gjs
@@ -140,6 +140,35 @@ module("Integration | Component | upcoming-events-list", function (hooks) {
exists(".upcoming-events-list__view-all"),
"it displays the view-all link"
);
+
+ test("with multi-day events, standard formats", async function (assert) {
+ pretender.get(
+ "/discourse-post-event/events",
+ multiDayEventResponseHandler
+ );
+
+ await render(
);
+
+ this.appEvents.trigger("page:changed", { url: "/" });
+
+ await waitFor(".loading-container .spinner", { count: 0 });
+
+ assert.deepEqual(
+ [...queryAll(".upcoming-events-list__event-name")].map(
+ (el) => el.innerText
+ ),
+ ["Awesome Event", "Another Awesome Event"],
+ "it displays the multiday event on all scheduled dates"
+ );
+
+ assert.deepEqual(
+ [...queryAll(".upcoming-events-list__event-name")].map(
+ (el) => el.innerText
+ ),
+ ["Awesome Event", "Another Awesome Event"],
+ "it displays the multiday event that has two different months"
+ );
+ });
});
test("with events, view-all navigation", async function (assert) {
@@ -394,3 +423,37 @@ function twoEventsResponseHandler({ queryParams }) {
return response({ events });
}
+
+function multiDayEventResponseHandler({ queryParams }) {
+ let events = [
+ {
+ id: 67503,
+ starts_at: tomorrowAllDay,
+ ends_at: nextMonth,
+ timezone: "Asia/Calcutta",
+ post: {
+ id: 67501,
+ post_number: 1,
+ url: "/t/this-is-an-event/18451/1",
+ topic: {
+ id: 18449,
+ title: "This is a multiday event",
+ },
+ },
+ name: "Awesome MultiDay Event",
+ category_id: 1,
+ },
+ ];
+
+ if (queryParams.limit) {
+ events.splice(queryParams.limit);
+ }
+
+ if (queryParams.before) {
+ events = events.filter((event) => {
+ return moment(event.starts_at).isBefore(queryParams.before);
+ });
+ }
+
+ return response({ events });
+}