Render events in calendar grid from API
This commit is contained in:
+5
-40
@@ -1,42 +1,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import CalendarPage from "./CalendarPage";
|
||||||
import { getEvents } from "./lib/api";
|
|
||||||
|
|
||||||
type Event = {
|
function App() {
|
||||||
id: string;
|
return <CalendarPage />;
|
||||||
title: string;
|
}
|
||||||
starts_at: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function CalendarPage() {
|
export default App;
|
||||||
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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
|
|||||||
import MonthGrid from './components/MonthGrid'
|
import MonthGrid from './components/MonthGrid'
|
||||||
import { buildMonthGrid } from './utils/calendarMath'
|
import { buildMonthGrid } from './utils/calendarMath'
|
||||||
import type { CalendarEvent, GridLayout } from './types/calendar'
|
import type { CalendarEvent, GridLayout } from './types/calendar'
|
||||||
import { fetchPublicEvents } from './lib/api'
|
import { getEvents } from './lib/api'
|
||||||
|
|
||||||
export default function CalendarPage() {
|
export default function CalendarPage() {
|
||||||
const [visibleMonth, setVisibleMonth] = useState(new Date())
|
const [visibleMonth, setVisibleMonth] = useState(new Date())
|
||||||
@@ -14,20 +14,15 @@ export default function CalendarPage() {
|
|||||||
|
|
||||||
const days = useMemo(() => buildMonthGrid(visibleMonth), [visibleMonth])
|
const days = useMemo(() => buildMonthGrid(visibleMonth), [visibleMonth])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const from = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth(), 1)
|
getEvents()
|
||||||
const to = new Date(visibleMonth.getFullYear(), visibleMonth.getMonth() + 1, 0)
|
.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(() => {
|
useEffect(() => {
|
||||||
if (!gridWrapperRef.current) return
|
if (!gridWrapperRef.current) return
|
||||||
|
|||||||
@@ -23,14 +23,17 @@ export default function DayCell({
|
|||||||
const isSelected = selectedDate ? isSameDay(date, selectedDate) : false
|
const isSelected = selectedDate ? isSameDay(date, selectedDate) : false
|
||||||
const isCurrentMonth = isSameMonth(date, visibleMonth)
|
const isCurrentMonth = isSameMonth(date, visibleMonth)
|
||||||
|
|
||||||
const eventsForThisDay = events.filter((event) => {
|
const eventsForThisDay = events
|
||||||
const eventDate = new Date(event.start)
|
.filter((event) => {
|
||||||
return isSameDay(eventDate, date)
|
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 visibleEvents = eventsForThisDay.slice(0, layout.maxVisibleEvents)
|
||||||
const hiddenCount = eventsForThisDay.length - visibleEvents.length
|
const hiddenCount = eventsForThisDay.length - visibleEvents.length
|
||||||
const showCountOnly = layout.maxVisibleEvents === 0
|
const showCountOnly = layout.maxVisibleEvents === 0
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@@ -108,7 +111,10 @@ export default function DayCell({
|
|||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{event.title}
|
{new Date(event.starts_at).toLocaleTimeString([], {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: '2-digit',
|
||||||
|
})} - {event.title}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
@@ -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!
|
|
||||||
)
|
|
||||||
@@ -1,16 +1,9 @@
|
|||||||
export type CalendarEvent = {
|
export type CalendarEvent = {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
start: string
|
starts_at: string
|
||||||
end: string
|
created_at: string
|
||||||
calendarId: string
|
updated_at: string
|
||||||
resourceId?: string | null
|
|
||||||
description?: string | null
|
|
||||||
imageUrl?: string | null
|
|
||||||
isPublic: boolean
|
|
||||||
recurrence?: unknown | null
|
|
||||||
createdAt: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GridLayout = {
|
export type GridLayout = {
|
||||||
|
|||||||
Reference in New Issue
Block a user