Skip to content

Commit f197457

Browse files
Merge pull request #4370 from OneCommunityGlobal/kanishk_finish_calendar_full_view
Kanishk – Finish community calendar full view
2 parents 163b3e8 + 4bd95e9 commit f197457

3 files changed

Lines changed: 723 additions & 30 deletions

File tree

src/components/CommunityPortal/Calendar/CalendarActivitySection.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@ function CalendarActivitySection() {
1616
darkMode ? styles.calendarActivitySectionDarkMode : ''
1717
}`}
1818
>
19-
<h2 className={`activity-header ${darkMode ? 'activity-header-dark-mode' : ''}`}>
19+
<h2 className={`${styles.activityHeader} ${darkMode ? styles.activityHeaderDark : ''}`}>
2020
Latest News
2121
</h2>
2222
<ul className={styles.calendarActivityList}>
2323
{calendarActivities.map(activity => (
2424
<li
2525
key={activity.id}
2626
className={`${styles.calendarActivityItem} ${
27-
darkMode ? styles.calendarActivityItemDarkMode : ''
27+
darkMode ? styles.calendarActivityItemDark : ''
2828
}`}
2929
>
30-
<p className={`activity-message ${darkMode ? styles.activityMessageDarkMode : ''}`}>
30+
<p
31+
className={`${styles.activityMessage} ${darkMode ? styles.activityMessageDark : ''}`}
32+
>
3133
<strong>{activity.author}</strong>: {activity.message}
3234
</p>
33-
<small className={`activity-time ${darkMode ? styles.activityTimeDarkMode : ''}`}>
35+
<small className={`${styles.activityTime} ${darkMode ? styles.activityTimeDark : ''}`}>
3436
{activity.time}
3537
</small>
3638
</li>

src/components/CommunityPortal/Calendar/CommunityCalendar.jsx

Lines changed: 186 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const TIMES = ['10:00 AM', '1:00 PM', '3:00 PM', '5:00 PM'];
1212

1313
function CommunityCalendar() {
1414
const [filter, setFilter] = useState({ type: 'all', location: 'all', status: 'all' });
15+
const [selectedDate, setSelectedDate] = useState(new Date());
1516
const [selectedEvent, setSelectedEvent] = useState(null);
1617
const [showEventModal, setShowEventModal] = useState(false);
1718
const [overflowDate, setOverflowDate] = useState(null);
@@ -74,6 +75,40 @@ function CommunityCalendar() {
7475
eventCache,
7576
]);
7677

78+
const selectedDateEvents = useMemo(() => {
79+
const dateKey = selectedDate?.toDateString();
80+
if (!dateKey) {
81+
return [];
82+
}
83+
return filteredEvents.filter(event => event.date.toDateString() === dateKey);
84+
}, [filteredEvents, selectedDate]);
85+
86+
const formattedSelectedDate = useMemo(() => {
87+
if (!selectedDate) {
88+
return '';
89+
}
90+
return selectedDate.toLocaleDateString(undefined, {
91+
weekday: 'long',
92+
month: 'long',
93+
day: 'numeric',
94+
year: 'numeric',
95+
});
96+
}, [selectedDate]);
97+
98+
const handleDateSelect = useCallback(
99+
date => {
100+
setSelectedDate(date);
101+
const eventsForDate = getEventsForDate(date);
102+
if (eventsForDate.length > 0) {
103+
setSelectedEvent(eventsForDate[0]);
104+
} else {
105+
setSelectedEvent(null);
106+
}
107+
setShowEventModal(false);
108+
},
109+
[getEventsForDate],
110+
);
111+
77112
const handleEventClick = useCallback(event => {
78113
setSelectedEvent(event);
79114
setShowEventModal(true);
@@ -107,6 +142,27 @@ function CommunityCalendar() {
107142
return () => document.removeEventListener('mousedown', handleClickOutside);
108143
}, []);
109144

145+
useEffect(() => {
146+
const eventsForDate = getEventsForDate(selectedDate);
147+
if (eventsForDate.length === 0) {
148+
if (selectedEvent !== null) {
149+
setSelectedEvent(null);
150+
}
151+
if (showEventModal) {
152+
setShowEventModal(false);
153+
}
154+
return;
155+
}
156+
157+
const hasSelectedEvent = eventsForDate.some(event => event.id === selectedEvent?.id);
158+
if (!hasSelectedEvent) {
159+
setSelectedEvent(eventsForDate[0]);
160+
if (showEventModal) {
161+
setShowEventModal(false);
162+
}
163+
}
164+
}, [getEventsForDate, selectedDate, selectedEvent, showEventModal]);
165+
110166
const statusMap = {
111167
New: 'statusNew',
112168
'Needs Attendees': 'statusNeedsAttendees',
@@ -158,9 +214,17 @@ function CommunityCalendar() {
158214
);
159215

160216
const tileClassName = useCallback(
161-
({ date, view }) =>
162-
view === 'month' && eventCountByDate.has(date.toDateString()) ? styles.hasEvents : null,
163-
[eventCountByDate],
217+
({ date, view }) => {
218+
const classNames = [];
219+
if (view === 'month' && eventCountByDate.has(date.toDateString())) {
220+
classNames.push(styles.hasEvents);
221+
}
222+
if (view === 'month' && selectedDate && date.toDateString() === selectedDate.toDateString()) {
223+
classNames.push(styles.selectedDate);
224+
}
225+
return classNames.join(' ') || null;
226+
},
227+
[eventCountByDate, selectedDate],
164228
);
165229

166230
const handleFilterChange = field => e =>
@@ -199,6 +263,57 @@ function CommunityCalendar() {
199263

200264
return (
201265
<div className={calendarClasses.container}>
266+
{/* Inline styles to ensure selected date number is visible in dark mode - force dark background */}
267+
{darkMode && (
268+
<style>
269+
{`
270+
/* CRITICAL: Force dark background on selected date in dark mode - override ALL react-calendar defaults */
271+
.react-calendar__tile.selectedDate,
272+
.react-calendar__tile.selectedDate.react-calendar__tile--active,
273+
.react-calendar__tile.react-calendar__tile--active.selectedDate {
274+
background-color: #1a2332 !important;
275+
background: #1a2332 !important;
276+
color: #ffffff !important;
277+
}
278+
.react-calendar__tile.selectedDate:hover,
279+
.react-calendar__tile.selectedDate.react-calendar__tile--active:hover,
280+
.react-calendar__tile.react-calendar__tile--active.selectedDate:hover {
281+
background-color: #1a2332 !important;
282+
background: #1a2332 !important;
283+
color: #ffffff !important;
284+
}
285+
/* Force white text on dark background */
286+
.react-calendar__tile.selectedDate abbr,
287+
.react-calendar__tile.selectedDate abbr[title],
288+
.react-calendar__tile.selectedDate > abbr,
289+
.react-calendar__tile.selectedDate.react-calendar__tile--active abbr,
290+
.react-calendar__tile.react-calendar__tile--active.selectedDate abbr {
291+
color: #ffffff !important;
292+
font-weight: 900 !important;
293+
font-size: 1.2em !important;
294+
text-shadow:
295+
0 0 8px rgba(255, 255, 255, 1),
296+
0 0 10px rgba(255, 255, 255, 0.9),
297+
0 2px 4px rgba(0, 0, 0, 1),
298+
0 4px 8px rgba(0, 0, 0, 0.9) !important;
299+
-webkit-text-stroke: 0.6px rgba(255, 255, 255, 1) !important;
300+
filter: brightness(1.8) contrast(1.5) !important;
301+
opacity: 1 !important;
302+
}
303+
.react-calendar__tile.selectedDate:hover abbr,
304+
.react-calendar__tile.selectedDate:hover abbr[title],
305+
.react-calendar__tile.selectedDate.react-calendar__tile--active:hover abbr {
306+
color: #ffffff !important;
307+
filter: brightness(1.8) contrast(1.5) !important;
308+
opacity: 1 !important;
309+
}
310+
/* But preserve event item colors */
311+
.react-calendar__tile.selectedDate .eventItem {
312+
color: inherit !important;
313+
}
314+
`}
315+
</style>
316+
)}
202317
<header className={calendarClasses.header}>
203318
<h1>Community Calendar</h1>
204319
<div className={calendarClasses.filters}>
@@ -235,14 +350,81 @@ function CommunityCalendar() {
235350
className={calendarClasses.reactCalendar}
236351
tileContent={tileContent}
237352
tileClassName={tileClassName}
353+
onClickDay={handleDateSelect}
354+
value={selectedDate}
238355
/>
356+
<section
357+
className={`${styles.selectedDatePanel} ${
358+
darkMode ? styles.selectedDatePanelDarkMode : ''
359+
}`}
360+
aria-live="polite"
361+
>
362+
<div className={styles.selectedDateHeader}>
363+
<div>
364+
<h2>{formattedSelectedDate || 'Select a date'}</h2>
365+
<p className={styles.selectedDateSummary}>
366+
{(() => {
367+
if (selectedDateEvents.length === 0) {
368+
return 'No events scheduled for this date';
369+
}
370+
const eventText = selectedDateEvents.length === 1 ? 'event' : 'events';
371+
return `${selectedDateEvents.length} ${eventText} scheduled`;
372+
})()}
373+
</p>
374+
</div>
375+
</div>
376+
377+
{selectedDateEvents.length > 0 ? (
378+
<ul className={styles.selectedEventList}>
379+
{selectedDateEvents.map(event => {
380+
const isActive = selectedEvent?.id === event.id;
381+
return (
382+
<li key={event.id}>
383+
<article
384+
className={`${styles.selectedEventCard} ${
385+
darkMode ? styles.selectedEventCardDarkMode : ''
386+
} ${isActive ? styles.selectedEventCardActive : ''}`}
387+
>
388+
<header className={styles.selectedEventHeader}>
389+
<div>
390+
<h3>{event.title}</h3>
391+
<div className={styles.selectedEventMeta}>
392+
<span>{event.time}</span>
393+
<span>{event.location}</span>
394+
<span>{event.type}</span>
395+
<span>{event.status}</span>
396+
</div>
397+
</div>
398+
<button
399+
type="button"
400+
className={styles.eventDetailButton}
401+
onClick={() => handleEventClick(event)}
402+
>
403+
View full details
404+
</button>
405+
</header>
406+
<p className={styles.selectedEventDescription}>{event.description}</p>
407+
</article>
408+
</li>
409+
);
410+
})}
411+
</ul>
412+
) : (
413+
<div className={styles.noEventsMessage}>
414+
<p>Select a different date or adjust the filters to see scheduled events.</p>
415+
</div>
416+
)}
417+
</section>
239418
</div>
240419
</div>
241420
</main>
242421

243422
{/* Overflow popup */}
244423
{overflowDate && (
245-
<div ref={popupRef} className={styles.overflowPopup}>
424+
<div
425+
ref={popupRef}
426+
className={`${styles.overflowPopup} ${darkMode ? styles.overflowPopupDark : ''}`}
427+
>
246428
<div className={styles.overflowPopupInner}>
247429
<h4>{overflowDate.toDateString()}</h4>
248430
{getEventsForDate(overflowDate).map(e => (

0 commit comments

Comments
 (0)