Skip to content

Commit 437de8c

Browse files
committed
initial commit for jsx
1 parent 4aea423 commit 437de8c

1 file changed

Lines changed: 128 additions & 11 deletions

File tree

src/components/CommunityPortal/Calendar/CommunityCalendar.jsx

Lines changed: 128 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function CommunityCalendar() {
1717
const [showEventModal, setShowEventModal] = useState(false);
1818
const [overflowDate, setOverflowDate] = useState(null);
1919
const popupRef = useRef(null);
20+
const [calendarView, setCalendarView] = useState('month');
2021

2122
const currentDate = new Date();
2223
const currentMonth = currentDate.getMonth();
@@ -170,6 +171,96 @@ function CommunityCalendar() {
170171
'Full Event': 'statusFull',
171172
};
172173

174+
function WeeklyTimeGrid({ events, selectedDate, onEventClick, darkMode }) {
175+
const hours = Array.from({ length: 24 }, (_, i) => i);
176+
177+
// Find the Sunday of the currently selected week
178+
const startOfWeek = useMemo(() => {
179+
const d = new Date(selectedDate);
180+
const day = d.getDay(); // 0 (Sun) to 6 (Sat)
181+
d.setDate(d.getDate() - day);
182+
return d;
183+
}, [selectedDate]);
184+
185+
// Create an array of 7 Date objects for the header
186+
const weekDays = useMemo(() => {
187+
return Array.from({ length: 7 }, (_, i) => {
188+
const day = new Date(startOfWeek);
189+
day.setDate(startOfWeek.getDate() + i);
190+
return day;
191+
});
192+
}, [startOfWeek]);
193+
194+
return (
195+
<div className={`${styles.weekGridContainer} ${darkMode ? styles.weekGridDark : ''}`}>
196+
{/* HEADER: Day Names and Numbers */}
197+
<div className={styles.weekGridHeader}>
198+
<div className={styles.timeGutter}></div>
199+
{weekDays.map(date => (
200+
<div key={date.toString()} className={styles.dayColumnHeader}>
201+
<div className={styles.dayLabel}>
202+
{date.toLocaleDateString('en-US', { weekday: 'short' })}
203+
</div>
204+
<div className={styles.dateLabel}>{date.getDate()}</div>
205+
</div>
206+
))}
207+
</div>
208+
209+
{/* BODY: Time Rows */}
210+
<div className={styles.weekGridBody}>
211+
{hours.map(hour => (
212+
<div key={hour} className={styles.hourRow}>
213+
<div className={styles.timeLabel}>
214+
{hour === 0
215+
? '12 AM'
216+
: hour > 12
217+
? `${hour - 12} PM`
218+
: hour === 12
219+
? '12 PM'
220+
: `${hour} AM`}
221+
</div>
222+
{weekDays.map(date => {
223+
// Filter events that happen on THIS day at THIS hour
224+
const cellEvents = events.filter(e => {
225+
const eventDate = new Date(e.date);
226+
// Check if date matches and if the hour in "10:00 AM" matches our current row
227+
const eventHour = parseInt(e.time.split(':')[0]);
228+
const isPM = e.time.toLowerCase().includes('pm');
229+
const normalizedEventHour =
230+
isPM && eventHour !== 12
231+
? eventHour + 12
232+
: !isPM && eventHour === 12
233+
? 0
234+
: eventHour;
235+
236+
return (
237+
eventDate.toDateString() === date.toDateString() && normalizedEventHour === hour
238+
);
239+
});
240+
241+
return (
242+
<div key={date.toString()} className={styles.gridCell}>
243+
{cellEvents.map(event => (
244+
<button
245+
key={event.id}
246+
type="button"
247+
className={styles.gridEvent}
248+
onClick={() => onEventClick(event)}
249+
>
250+
<div className={styles.gridEventTime}>{event.time}</div>
251+
<div className={styles.gridEventTitle}>{event.title}</div>
252+
</button>
253+
))}
254+
</div>
255+
);
256+
})}
257+
</div>
258+
))}
259+
</div>
260+
</div>
261+
);
262+
}
263+
173264
// Render event tiles
174265
const tileContent = useCallback(
175266
({ date, view }) => {
@@ -189,20 +280,24 @@ function CommunityCalendar() {
189280
key={e.id}
190281
type="button"
191282
className={`${styles.eventItem} ${styles[statusKey] || ''}`}
192-
onClick={() => handleEventClick(e)}
283+
onClick={e_obj => {
284+
e_obj.stopPropagation();
285+
handleEventClick(e);
286+
}}
193287
title={e.title}
194288
>
195289
{e.title}
196290
</button>
197291
);
198292
})}
199-
200293
{hiddenCount > 0 && (
201294
<button
202295
type="button"
203296
className={styles.moreEvents}
204-
onClick={() => setOverflowDate(date)}
205-
title="View all events"
297+
onClick={e_obj => {
298+
e_obj.stopPropagation();
299+
setOverflowDate(date);
300+
}}
206301
>
207302
+{hiddenCount} more
208303
</button>
@@ -317,6 +412,16 @@ function CommunityCalendar() {
317412
<header className={calendarClasses.header}>
318413
<h1>Community Calendar</h1>
319414
<div className={calendarClasses.filters}>
415+
<select
416+
value={calendarView}
417+
onChange={e => setCalendarView(e.target.value)}
418+
className={styles.viewSelector}
419+
>
420+
<option value="month">Day View (Month)</option>
421+
<option value="week">Week View (Time Grid)</option>
422+
<option value="year">Month View (Year)</option>
423+
<option value="decade">Year View (Decade)</option>
424+
</select>
320425
<select value={filter.type} onChange={handleFilterChange('type')}>
321426
<option value="all">All Types</option>
322427
{uniqueFilterValues.types.map(t => (
@@ -346,13 +451,25 @@ function CommunityCalendar() {
346451
<CalendarActivitySection />
347452
</div>
348453
<div className={calendarClasses.calendarSection}>
349-
<ReactCalendar
350-
className={calendarClasses.reactCalendar}
351-
tileContent={tileContent}
352-
tileClassName={tileClassName}
353-
onClickDay={handleDateSelect}
354-
value={selectedDate}
355-
/>
454+
{calendarView === 'week' ? (
455+
<WeeklyTimeGrid
456+
events={filteredEvents}
457+
selectedDate={selectedDate}
458+
onEventClick={handleEventClick}
459+
darkMode={darkMode}
460+
/>
461+
) : (
462+
<ReactCalendar
463+
className={calendarClasses.reactCalendar}
464+
tileContent={tileContent}
465+
tileClassName={tileClassName}
466+
onClickDay={handleDateSelect}
467+
value={selectedDate}
468+
view={calendarView}
469+
onViewChange={({ view }) => setCalendarView(view)}
470+
/>
471+
)}
472+
356473
<section
357474
className={`${styles.selectedDatePanel} ${
358475
darkMode ? styles.selectedDatePanelDarkMode : ''

0 commit comments

Comments
 (0)