From d0e61ebdb0ff54675209a3df616572ffe6715788 Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Wed, 13 May 2026 09:54:58 +0200 Subject: [PATCH] Update documentation with new features --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ README.md | 37 ++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e57635..1e306a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,32 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### 🌙 Mobile Application + +- Default to dark theme across the mobile app +- Filter native calendar events by location to exclude empty ones +- Async station selection with error handling and alerts +- Improved notification settings UI + +### 📅 Calendar Integration + +- **Google Calendar sync** via full OAuth 2.0 flow (token exchange, refresh, and status checks) +- UI for connecting, syncing, and disconnecting Google accounts in the Calendar panel +- Batch edit panel for managing event destinations on the web calendar +- Edit support in AddEventModal for modifying existing events + +### 🚉 Public Transport + +- HAFAS LocMatch method in API client for finding nearest station to current location +- Improved station selection with async search and error handling +- WienerLinien departures hook improvements + +### 🔧 API Client + +- Added `fetchGoogleCalendarEvents` method for Google Calendar sync +- Added `findNearestStation` method for geolocation-based station lookup +- Enhanced HAFAS request handling + --- ## [1.0.0] — 2025-01-27 diff --git a/README.md b/README.md index e71f467..4af2505 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ ![TimeToLeave Logo](apps/web/public/timetoleave_logo.png) -> **TimeToLeave** is a smart departure planner that tells you exactly when to leave home to catch your public transport for upcoming appointments. It syncs with your personal calendar, checks real-time train/bus departures (HAFAS & WienerLinien), and provides a live "Leave Status" based on real-time delays. +> **TimeToLeave** is a smart departure planner that tells you exactly when to leave home to catch your public transport for upcoming appointments. It syncs with your personal calendar (`.ics` files or Google Calendar), checks real-time train/bus departures (HAFAS & WienerLinien), and provides a live "Leave Status" based on real-time delays. ![Platform](https://img.shields.io/badge/platform-Web_%26_Mobile-blue) ![Next.js](https://img.shields.io/badge/Next.js-16.2-green) ![React Native](https://img.shields.io/badge/React%20Native-0.81-blue) ![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue) ## 🚀 How It Works -1. **Sync Your Calendar:** Import your `.ics` file or provide a calendar URL. The app extracts your upcoming events and destinations. -2. **Set Your Origin:** Define your home station or let the app use your current geolocation. +1. **Sync Your Calendar:** Import your `.ics` file, provide a calendar URL, or connect your Google Calendar via OAuth 2.0. The app extracts your upcoming events and destinations. +2. **Set Your Origin:** Define your home station or let the app use your current geolocation. The app can also find the nearest station to your location via HAFAS LocMatch. 3. **Journey Calculation:** The app queries the HAFAS protocol and WienerLinien APIs to find the best public transport connections to your event destination. -4. **Real-Time Monitoring:** It monitors your train's real-time departure time, accounts for delays, and adds your local travel time (e.g., biking to the station) to calculate a dynamic countdown. +4. **Real-Time Monitoring:** It monitors your train's real-time departure time, accounts for delays, and adds your local travel time (e.g., biking or walking to the station) to calculate a dynamic countdown. 5. **Leave Status:** You get a clear status: `Leave now`, `On time`, `Delayed +X min`, or `Departure missed`. ## 🧱 Project Structure @@ -23,7 +23,7 @@ This project uses a monorepo setup (npm workspaces) to manage multiple, intercon | `apps/web/` | The main web dashboard built with **Next.js 16**, React 19, and Tailwind CSS 4. | | `apps/mobile/` | The on-the-go mobile client built with **React Native 0.81** and **Expo 54**. | | `packages/core/` | Shared domain logic, types (`Event`, `Journey`, `Station`), countdown utilities, and status calculators. | -| `packages/api-client/` | A lightweight client that handles API proxies for HAFAS requests, calendar parsing, geocoding, and bike routing. | +| `packages/api-client/` | A lightweight client that handles API proxies for HAFAS requests, calendar parsing, geocoding, bike routing, and Google Calendar sync. | ## 🛠 Development & Running the Application @@ -47,6 +47,7 @@ This project uses a monorepo setup (npm workspaces) to manage multiple, intercon 3. **Environment variables:** * For `apps/web` and `apps/mobile`, copy `.env.example` to `.env` in each app directory and update the backend API URL and any required keys. + * Google Calendar integration requires `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, and `GOOGLE_REDIRECT_URI` environment variables. ### Available Scripts @@ -66,15 +67,23 @@ This project uses a monorepo setup (npm workspaces) to manage multiple, intercon * **UI:** React 19.2.4 with Tailwind CSS 4 * **State Management:** React Context (via `EventsProvider` and `ReminderSettingsProvider`) * **Routing:** Next.js built-in routing for `/` (event list) and `/calendar` views. +* **Calendar Integration:** + * Import `.ics` files or provide calendar URLs + * **Google Calendar sync** via full OAuth 2.0 flow (token exchange, refresh, and status checks) + * Batch edit panel for managing event destinations + * Edit support in the AddEventModal for modifying existing events +* **Dark/Light Theme:** Built-in theme toggle ### Mobile Application (`apps/mobile`) * **Framework:** React Native 0.81 via Expo 54 * **Navigation:** React Navigation 7 (Native Stack) +* **Theme:** Dark theme by default * **Device APIs:** * `expo-location`: For geocoding your current position. * `expo-calendar`: For native calendar event integration. * `expo-notifications`: For native push notifications when it's time to leave. * `@react-native-async-storage/async-storage`: For persisting settings and local state. +* **Station Selection:** Async station search with error handling and nearest-station detection via HAFAS LocMatch. ### Core Logic (`packages/core`) * **Countdown Utilities:** Calculates time-deltas and assigns color codes (Red/Orange/Yellow/Green/Blue) based on urgency. @@ -84,7 +93,7 @@ This project uses a monorepo setup (npm workspaces) to manage multiple, intercon ## 📄 API Client Usage -The `@timetoleave/api-client` package provides a clean interface to interact with your backend proxy, which handles the heavy lifting of HAFAS protocol communication and calendar parsing. +The `@timetoleave/api-client` package provides a clean interface to interact with your backend proxy, which handles the heavy lifting of HAFAS protocol communication, calendar parsing, and Google Calendar sync. ```typescript import { ApiClient } from "@timetoleave/api-client"; @@ -92,10 +101,13 @@ import { ApiClient } from "@timetoleave/api-client"; // Initialize with your backend URL const api = new ApiClient("http://localhost:3000"); -// 1. Sync your calendar +// 1. Sync your calendar (via .ics URL) const events = await api.fetchCalendar("https://example.com/calendar.ics", 7); -// 2. Search for a station via the HAFAS LocMatch endpoint +// 2. Sync Google Calendar (after OAuth flow) +const googleEvents = await api.fetchGoogleCalendarEvents(); + +// 3. Search for a station via the HAFAS LocMatch endpoint const stationResult = await api.hafasRequest({ svcReqL: [ { @@ -106,14 +118,17 @@ const stationResult = await api.hafasRequest({ }); const stations = stationResult?.svcReqL?.[0]?.res?.locL ?? []; -// 3. Find journeys between stations for a specific date +// 4. Find the nearest station to your current location +const nearestStation = await api.findNearestStation(48.2082, 16.3738); + +// 5. Find journeys between stations for a specific date const journeys = await api.searchJourneys( stations[0].extId, // From "dest:extId", // To new Date() // Date ); -// 4. Get a bike route from your current location to the station +// 6. Get a bike route from your current location to the station const bikeRoute = await api.getBikeRoute( 48.2082, 16.3738, // From lat/lng 48.1850, 16.3780 // To lat/lng @@ -137,7 +152,7 @@ The project provides comprehensive scripts for maintaining code quality: │ ├── mobile/ # Mobile application using React Native and Expo │ └── web/ # Web application using Next.js and Tailwind CSS ├── packages/ -│ ├── api-client/ # API client for HAFAS, Calendar, and Routing proxies +│ ├── api-client/ # API client for HAFAS, Calendar, Google Calendar, and Routing proxies │ └── core/ # Shared domain types, countdowns, and HAFAS time utilities ├── node_modules/ # Third-party dependencies └── README.md # The file you're reading now