From 4313714c5deab57f53c54a10571167a5f115de03 Mon Sep 17 00:00:00 2001 From: Media Date: Tue, 14 Apr 2026 20:09:53 -0500 Subject: [PATCH] Connect frontend to API and display events --- apps/api/src/server.ts | 16 ++-- apps/web/src/App.tsx | 167 ++++++++-------------------------------- apps/web/src/lib/api.ts | 25 +----- 3 files changed, 46 insertions(+), 162 deletions(-) diff --git a/apps/api/src/server.ts b/apps/api/src/server.ts index cd410c3..b5b93cf 100644 --- a/apps/api/src/server.ts +++ b/apps/api/src/server.ts @@ -1,21 +1,25 @@ import Fastify from "fastify"; -import { pool } from "./db/index.js"; -import { calendarRoutes } from "./modules/calendar/routes.js"; +import cors from "@fastify/cors"; +import { pool } from "./db"; +import { calendarRoutes } from "./modules/calendar/routes"; const app = Fastify(); +await app.register(cors, { + origin: true, +}); + pool .query("SELECT NOW()") .then((res) => console.log("DB connected:", res.rows[0])) .catch((err) => console.error("DB connection failed:", err)); -app.register(calendarRoutes); - app.get("/health", async () => { return { ok: true }; }); +app.register(calendarRoutes); + app.listen({ port: 3000, host: "0.0.0.0" }).then(() => { console.log("API running on port 3000"); -}); - +}); \ No newline at end of file diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 4351a07..67eb447 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,145 +1,42 @@ -import { useEffect, useState } from 'react' -import { createClient } from '@supabase/supabase-js' +import { useEffect, useState } from "react"; +import { getEvents } from "./lib/api"; -const supabase = createClient( - import.meta.env.VITE_SUPABASE_URL, - import.meta.env.VITE_SUPABASE_ANON_KEY -) +type Event = { + id: string; + title: string; + starts_at: string; +}; -export default function App() { - const [email, setEmail] = useState('') - const [password, setPassword] = useState('') - const [events, setEvents] = useState([]) - const [user, setUser] = useState(null) - const [profile, setProfile] = useState(null) - const [status, setStatus] = useState('loading...') - const [error, setError] = useState(null) +export default function CalendarPage() { + const [events, setEvents] = useState([]); + const [error, setError] = useState(""); useEffect(() => { - void loadEvents() - void loadSession() - }, []) - - async function loadEvents() { - const { data, error } = await supabase - .from('events') - .select('*') - .order('created_at', { ascending: false }) - - if (error) { - setError(error.message) - setStatus('error loading events') - return - } - - setEvents(data || []) - setStatus('ready') - } - - async function loadSession() { - const { data, error } = await supabase.auth.getUser() - - if (error) { - setError(error.message) - return - } - - setUser(data.user ?? null) - - if (data.user) { - const { data: profileData, error: profileError } = await supabase - .from('profiles') - .select('*') - .eq('id', data.user.id) - .maybeSingle() - - if (profileError) { - setError(profileError.message) - return - } - - setProfile(profileData) - } - } - - async function signIn() { - setError(null) - - const { data, error } = await supabase.auth.signInWithPassword({ - email, - password, - }) - - if (error) { - setError(error.message) - console.error('signIn error:', error) - return - } - - console.log('signIn data:', data) - setUser(data.user ?? null) - - if (data.user) { - const { data: profileData, error: profileError } = await supabase - .from('profiles') - .select('*') - .eq('id', data.user.id) - .maybeSingle() - - if (profileError) { - setError(profileError.message) - console.error('profile error:', profileError) - return - } - - setProfile(profileData) - } - } - - async function signOut() { - await supabase.auth.signOut() - setUser(null) - setProfile(null) - } + getEvents() + .then((data) => { + console.log("Fetched events:", data); + setEvents(data); + }) + .catch((err) => { + console.error("Fetch failed:", err); + setError(String(err)); + }); + }, []); return ( -
-

Supabase Test

-

Status: {status}

+
+

Events

- {!user ? ( -
-

Sign In

- setEmail(e.target.value)} - style={{ display: 'block', marginBottom: 12 }} - /> - setPassword(e.target.value)} - style={{ display: 'block', marginBottom: 12 }} - /> - + {error &&

Error: {error}

} + +

Event count: {events.length}

+ + {events.map((event) => ( +
+ {event.title} +
{new Date(event.starts_at).toLocaleString()}
- ) : ( -
-

Signed In

-

{user.email}

- -
- )} - - {error &&

{error}

} - -

Profile

-
{JSON.stringify(profile, null, 2)}
- -

Events

-
{JSON.stringify(events, null, 2)}
+ ))}
- ) + ); } \ No newline at end of file diff --git a/apps/web/src/lib/api.ts b/apps/web/src/lib/api.ts index 9e940d6..04b0f73 100644 --- a/apps/web/src/lib/api.ts +++ b/apps/web/src/lib/api.ts @@ -1,26 +1,9 @@ -import type { CalendarEvent } from '../types/calendar' - -const API_BASE = 'http://localhost:8787' - -export async function fetchPublicEvents(params: { - from: string - to: string - calendarId?: string - resourceId?: string -}): Promise { - const search = new URLSearchParams({ - from: params.from, - to: params.to, - }) - - if (params.calendarId) search.set('calendarId', params.calendarId) - if (params.resourceId) search.set('resourceId', params.resourceId) - - const res = await fetch(`${API_BASE}/v1/public/events?${search.toString()}`) +export async function getEvents() { + const res = await fetch("http://localhost:3000/events"); if (!res.ok) { - throw new Error(`Failed to fetch events: ${res.status}`) + throw new Error("Failed to fetch events"); } - return res.json() as Promise + return res.json(); } \ No newline at end of file