import { Ionicons } from "@expo/vector-icons"; import * as Calendar from "expo-calendar"; import * as SQLite from "expo-sqlite"; import React, { useEffect, useState } from "react"; import { Button, FlatList, Modal, SafeAreaView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from "react-native"; export interface EventItem { id: string; title: string; startDate: string; endDate: string; } const db = SQLite.openDatabaseSync("events.db"); export default function CalendarTab() { const [source, setSource] = useState<"sqlite" | "iphone">("sqlite"); const [events, setEvents] = useState([]); const [loading, setLoading] = useState(false); const [selectedYear, setSelectedYear] = useState( new Date().getFullYear() ); const [permissionError, setPermissionError] = useState(null); const [calendarType, setCalendarType] = useState<"calendar" | "reminder">( "calendar" ); const [modalVisible, setModalVisible] = useState(false); const [newTitle, setNewTitle] = useState(""); const [newStart, setNewStart] = useState(""); const [newEnd, setNewEnd] = useState(""); useEffect(() => { if (source === "sqlite") { loadEventsFromDB(); } else { loadEventsFromDevice(); } }, [source, selectedYear, calendarType]); const loadEventsFromDB = async () => { setLoading(true); try { const stmt = await db.prepareAsync("SELECT * FROM events;"); const loadedEvents: EventItem[] = []; const result = await stmt.executeAsync([]); for await (const row of result) { loadedEvents.push(row as EventItem); } setEvents(loadedEvents); await stmt.finalizeAsync(); } catch (e) { setEvents([]); } finally { setLoading(false); } }; const loadEventsFromDevice = async () => { setLoading(true); setPermissionError(null); try { let perm; if (calendarType === "reminder") { perm = await Calendar.requestRemindersPermissionsAsync(); } else { perm = await Calendar.requestCalendarPermissionsAsync(); } if (!perm.granted) { setEvents([]); setPermissionError( `Keine Berechtigung für ${ calendarType === "reminder" ? "Erinnerungen" : "Kalender" }-Zugriff. Bitte in den iOS-Einstellungen aktivieren.` ); return; } let calendars = await Calendar.getCalendarsAsync(); console.log( "Gefundene Kalender:", calendars.map((c) => ({ id: c.id, title: c.title, type: c.type })) ); if (calendarType === "calendar") { calendars = calendars.filter((c) => String(c.type) === "calendar"); } else { calendars = calendars.filter((c) => String(c.type) === "reminder"); } const start = new Date(selectedYear, 0, 1); const end = new Date(selectedYear, 11, 31, 23, 59, 59); let allEvents: EventItem[] = []; for (const cal of calendars) { const calEvents = await Calendar.getEventsAsync([cal.id], start, end); console.log( `Events für Kalender ${cal.title}:`, calEvents.map((e) => ({ id: e.id, title: e.title, start: e.startDate, end: e.endDate, })) ); allEvents = allEvents.concat( calEvents.map((e) => ({ id: e.id, title: e.title || "(Kein Titel)", startDate: typeof e.startDate === "string" ? e.startDate : new Date(e.startDate).toISOString(), endDate: typeof e.endDate === "string" ? e.endDate : new Date(e.endDate).toISOString(), })) ); } setEvents(allEvents); } catch (e: any) { setEvents([]); setPermissionError( "Fehler beim Zugriff auf " + (calendarType === "reminder" ? "Erinnerungen" : "Kalender") + ": " + (e?.message || JSON.stringify(e)) ); } finally { setLoading(false); } }; const addEventToDB = async () => { if (!newTitle || !newStart || !newEnd) return; await db.execAsync( `INSERT INTO events (id, title, startDate, endDate) VALUES ('${Date.now()}', '${newTitle.replace( /'/g, "''" )}', '${newStart}', '${newEnd}');` ); setModalVisible(false); setNewTitle(""); setNewStart(""); setNewEnd(""); await loadEventsFromDB(); }; const renderItem = ({ item }: { item: EventItem }) => ( {item.title} {new Date(item.startDate).toLocaleString()} -{" "} {new Date(item.endDate).toLocaleString()} ); return ( setModalVisible(true)} style={{ padding: 10 }} > setSource("sqlite")} > SQLite setSource("iphone")} > iPhone ({calendarType === "calendar" ? "Kalender" : "Erinnerungen"}) {source === "iphone" && ( setCalendarType("calendar")} > Kalender setCalendarType("reminder")} > Erinnerungen )} Kalender Events ({selectedYear}) item.id} renderItem={renderItem} ListEmptyComponent={ permissionError ? ( {permissionError} ) : ( Keine Events gefunden. ) } refreshing={loading} onRefresh={ source === "sqlite" ? loadEventsFromDB : loadEventsFromDevice } /> setModalVisible(false)} > Neuer SQLite-Eintrag