Render events in calendar grid from API

This commit is contained in:
Media
2026-04-14 20:40:16 -05:00
parent 4313714c5d
commit 525022228a
9 changed files with 28 additions and 75 deletions
+5 -40
View File
@@ -1,42 +1,7 @@
import { useEffect, useState } from "react";
import { getEvents } from "./lib/api";
import CalendarPage from "./CalendarPage";
type Event = {
id: string;
title: string;
starts_at: string;
};
function App() {
return <CalendarPage />;
}
export default function CalendarPage() {
const [events, setEvents] = useState<Event[]>([]);
const [error, setError] = useState("");
useEffect(() => {
getEvents()
.then((data) => {
console.log("Fetched events:", data);
setEvents(data);
})
.catch((err) => {
console.error("Fetch failed:", err);
setError(String(err));
});
}, []);
return (
<div style={{ padding: "20px" }}>
<h1>Events</h1>
{error && <p>Error: {error}</p>}
<p>Event count: {events.length}</p>
{events.map((event) => (
<div key={event.id}>
<strong>{event.title}</strong>
<div>{new Date(event.starts_at).toLocaleString()}</div>
</div>
))}
</div>
);
}
export default App;
+9 -14
View File
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
import MonthGrid from './components/MonthGrid'
import { buildMonthGrid } from './utils/calendarMath'
import type { CalendarEvent, GridLayout } from './types/calendar'
import { fetchPublicEvents } from './lib/api'
import { getEvents } from './lib/api'
export default function CalendarPage() {
const [visibleMonth, setVisibleMonth] = useState(new Date())
@@ -14,20 +14,15 @@ export default function CalendarPage() {
const days = useMemo(() => buildMonthGrid(visibleMonth), [visibleMonth])
useEffect(() => {
const from = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth(), 1)
const to = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth() + 1, 0)
useEffect(() => {
getEvents()
.then(setEvents)
.catch((err) => {
console.error('Failed to load events:', err)
setEvents([])
})
}, [])
fetchPublicEvents({
from: from.toISOString(),
to: to.toISOString(),
})
.then(setEvents)
.catch((err) => {
console.error('Failed to load events:', err)
setEvents([])
})
}, [visibleMonth])
useEffect(() => {
if (!gridWrapperRef.current) return
+11 -5
View File
@@ -23,14 +23,17 @@ export default function DayCell({
const isSelected = selectedDate ? isSameDay(date, selectedDate) : false
const isCurrentMonth = isSameMonth(date, visibleMonth)
const eventsForThisDay = events.filter((event) => {
const eventDate = new Date(event.start)
return isSameDay(eventDate, date)
})
const eventsForThisDay = events
.filter((event) => {
const eventDate = new Date(event.starts_at)
return isSameDay(eventDate, date)
})
.sort((a, b) => new Date(a.starts_at).getTime() - new Date(b.starts_at).getTime())
const visibleEvents = eventsForThisDay.slice(0, layout.maxVisibleEvents)
const hiddenCount = eventsForThisDay.length - visibleEvents.length
const showCountOnly = layout.maxVisibleEvents === 0
return (
<button
@@ -108,7 +111,10 @@ export default function DayCell({
lineHeight: 1.2,
}}
>
{event.title}
{new Date(event.starts_at).toLocaleTimeString([], {
hour: 'numeric',
minute: '2-digit',
})} - {event.title}
</div>
))}
-6
View File
@@ -1,6 +0,0 @@
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL!,
import.meta.env.VITE_SUPABASE_ANON_KEY!
)
+3 -10
View File
@@ -1,16 +1,9 @@
export type CalendarEvent = {
id: string
title: string
start: string
end: string
calendarId: string
resourceId?: string | null
description?: string | null
imageUrl?: string | null
isPublic: boolean
recurrence?: unknown | null
createdAt: string
updatedAt: string
starts_at: string
created_at: string
updated_at: string
}
export type GridLayout = {
View File