diff --git a/client/src/components/EventCard.tsx b/client/src/components/EventCard.tsx
index 7d3e35bb..856874a9 100644
--- a/client/src/components/EventCard.tsx
+++ b/client/src/components/EventCard.tsx
@@ -147,6 +147,7 @@ export interface EventCardProps {
vendors?: Vendor[];
price?: number;
showActions?: boolean;
+ showShareButton?: boolean;
showDetailedView?: boolean;
showAttendees?: boolean;
showRegisterButton?: boolean;
@@ -196,6 +197,7 @@ export default function EventCard({
registrationDeadline,
vendors = [],
showActions = true,
+ showShareButton = true,
showDetailedView = false,
showAttendees = true,
showRegisterButton = true,
@@ -1685,7 +1687,7 @@ export default function EventCard({
)}
- {inlineShareButton && (
+ {showShareButton && inlineShareButton && (
@@ -1742,7 +1744,7 @@ export default function EventCard({
)}
- {!inlineShareButton && (
+ {showShareButton && !inlineShareButton && (
diff --git a/client/src/components/EventsDetailsDialog.tsx b/client/src/components/EventsDetailsDialog.tsx
index 97653b66..2896f78b 100644
--- a/client/src/components/EventsDetailsDialog.tsx
+++ b/client/src/components/EventsDetailsDialog.tsx
@@ -94,20 +94,40 @@ export default function EventDetailsDialog({
const startTime =
formatStringTime(event.startTime) ||
- (event.startDate
- ? new Date(event.startDate).toLocaleTimeString("en-US", {
- hour: "2-digit",
- minute: "2-digit",
- })
- : null);
+ (() => {
+ if (!event.startDate) return null;
+ const date = new Date(event.startDate);
+ if (
+ date.getHours() === 0 &&
+ date.getMinutes() === 0 &&
+ date.getSeconds() === 0
+ ) {
+ return null;
+ }
+ return date.toLocaleTimeString("en-US", {
+ hour: "2-digit",
+ minute: "2-digit",
+ hour12: true,
+ });
+ })();
const endTime =
formatStringTime(event.endTime) ||
- (event.endDate
- ? new Date(event.endDate).toLocaleTimeString("en-US", {
- hour: "2-digit",
- minute: "2-digit",
- })
- : null);
+ (() => {
+ if (!event.endDate) return null;
+ const date = new Date(event.endDate);
+ if (
+ date.getHours() === 0 &&
+ date.getMinutes() === 0 &&
+ date.getSeconds() === 0
+ ) {
+ return null;
+ }
+ return date.toLocaleTimeString("en-US", {
+ hour: "2-digit",
+ minute: "2-digit",
+ hour12: true,
+ });
+ })();
const startDateStr = formatDate(event.startDate);
const endDateStr = formatDate(event.endDate);
diff --git a/client/src/lib/favoritesApi.ts b/client/src/lib/favoritesApi.ts
index ea7a7e97..3efcd7b4 100644
--- a/client/src/lib/favoritesApi.ts
+++ b/client/src/lib/favoritesApi.ts
@@ -8,6 +8,8 @@ export interface FavoriteEvent {
location: string;
startDate: string;
endDate: string;
+ startTime?: string;
+ endTime?: string;
bannerImage?: string;
status: string;
eventType?: string;
diff --git a/client/src/pages/FavoritesPage.tsx b/client/src/pages/FavoritesPage.tsx
index 1cadd474..cef56530 100644
--- a/client/src/pages/FavoritesPage.tsx
+++ b/client/src/pages/FavoritesPage.tsx
@@ -83,6 +83,47 @@ export default function FavoritesPage() {
});
};
+ // Convert a stored 24-hour time string (e.g. "14:05") to 12-hour ("2:05 PM")
+ const formatStringTime = (timeStr?: string) => {
+ if (!timeStr) return null;
+ if (/^\d{1,2}:\d{2}$/.test(timeStr)) {
+ const [hoursStr, minutesStr] = timeStr.split(":");
+ let hours = parseInt(hoursStr, 10);
+ const suffix = hours >= 12 ? "PM" : "AM";
+ hours = hours % 12;
+ hours = hours ? hours : 12;
+ return `${hours}:${minutesStr} ${suffix}`;
+ }
+ return timeStr;
+ };
+
+ const getEventTimeLabel = (event: any) => {
+ const start = formatStringTime(event?.startTime);
+ const end = formatStringTime(event?.endTime);
+
+ // If we don't have explicit times, only derive a time from Date fields
+ // when the Date actually contains a non-midnight time component.
+ const deriveTimeFromDateIfMeaningful = (dateString?: string) => {
+ if (!dateString) return null;
+ const date = new Date(dateString);
+ if (
+ date.getHours() === 0 &&
+ date.getMinutes() === 0 &&
+ date.getSeconds() === 0
+ ) {
+ return null;
+ }
+ return formatEventTime(dateString);
+ };
+
+ const startLabel =
+ start || deriveTimeFromDateIfMeaningful(event?.startDate);
+ const endLabel = end || deriveTimeFromDateIfMeaningful(event?.endDate);
+
+ if (startLabel && endLabel) return `${startLabel} - ${endLabel}`;
+ return startLabel || "";
+ };
+
const formatBoothDate = (event: any) => {
// If platform booth has startDate and endDate, show dates
if (event.startDate && event.endDate) {
@@ -211,7 +252,7 @@ export default function FavoritesPage() {
time={
isBoothEvent && !event.startDate
? ""
- : formatEventTime(event.startDate)
+ : getEventTimeLabel(event)
}
location={
event.location ||
@@ -225,6 +266,8 @@ export default function FavoritesPage() {
description={event.description}
startDate={event.startDate}
endDate={event.endDate}
+ dbStartTime={event.startTime}
+ dbEndTime={event.endTime}
durationWeeks={event.durationWeeks}
showActions={true}
showDetailedView={false}
diff --git a/client/src/pages/MyEvents.tsx b/client/src/pages/MyEvents.tsx
index 6b2dced1..b319a232 100644
--- a/client/src/pages/MyEvents.tsx
+++ b/client/src/pages/MyEvents.tsx
@@ -204,6 +204,7 @@ export default function MyEvents() {
endDate={event.endDate}
durationWeeks={event.durationWeeks}
showActions={true}
+ showShareButton={false}
isRegistered={true}
hideRegisterButton={
userRole === "student" ||
diff --git a/server/src/features/facilities/facility.service.js b/server/src/features/facilities/facility.service.js
index 283344a2..666ceafd 100644
--- a/server/src/features/facilities/facility.service.js
+++ b/server/src/features/facilities/facility.service.js
@@ -33,8 +33,6 @@ class FacilitiesServiceClass {
if (bookingDate < today) throw new Error("Cannot book a past date");
- const formattedDate = this.getLocalDateString(bookingDate);
-
// Check availability directly
const existingBooking = await CourtBooking.findOne({
courtType,
diff --git a/server/src/features/users/user.service.js b/server/src/features/users/user.service.js
index 41a3aed5..d4874b88 100644
--- a/server/src/features/users/user.service.js
+++ b/server/src/features/users/user.service.js
@@ -284,7 +284,7 @@ class UserService {
.populate({
path: "favoriteEvents",
select:
- "name description location locationPreference startDate endDate bannerImage status eventType type category durationWeeks attendees attendeesCount application archivedAt", // Added archivedAt
+ "name description location locationPreference startDate endDate startTime endTime bannerImage status eventType type category durationWeeks attendees attendeesCount application archivedAt", // Added archivedAt
match: {
deletedAt: null,
archivedAt: null, // ✅ Exclude archived events