# ⏱️ TimeToLeave > **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), calculates your bike route to the station, 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. 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. 5. **Leave Status:** You get a clear status: `Leave now`, `On time`, `Delayed +X min`, or `Departure missed`. ## 🧱 Project Structure This project uses a monorepo setup (npm workspaces) to manage multiple, interconnected parts: | Directory | Description | | :--- | :--- | | `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. | ## 🛠 Development & Running the Application ### Prerequisites * Node.js (version 20.x or higher) * npm (version 9.x or higher) ### Installation 1. **Clone the repository:** ```bash git clone cd TimeToLeave ``` 2. **Install dependencies:** ```bash npm install ``` 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. ### Available Scripts | Script | Command | Description | | :--- | :--- | :--- | | `dev` | `npm run dev` | Starts the Next.js development server for the Web dashboard. | | `dev:mobile` | `npm run dev:mobile` | Starts the Expo development server for the Mobile client. | | `build` | `npm run build` | Builds the production bundle for the Web application. | | `test` | `npm run test` | Runs Vitest for the Web app and Jest for the Mobile app. | | `lint` | `npm run lint` | Runs ESLint across both web and mobile clients. | | `typecheck` | `npm run typecheck` | Runs TypeScript type checking across all workspaces. | ## 📝 Key Features & Tech Stack ### Web Application (`apps/web`) * **Framework:** Next.js 16.2.6 (App Router) * **UI:** React 19.2.4 with Tailwind CSS 4 * **State Management:** Zustand (for events and station selection) * **Routing:** Next.js built-in routing for `/add-event`, `/calendar`, and `/event` views. ### Mobile Application (`apps/mobile`) * **Framework:** React Native 0.81 via Expo 54 * **Navigation:** React Navigation 7 (Native Stack) * **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. ### Core Logic (`packages/core`) * **Countdown Utilities:** Calculates time-deltas and assigns color codes (Red/Orange/Yellow/Green/Blue) based on urgency. * **HAFAS Time Parsing:** Highly accurate timezone-aware parsing for HAFAS timestamps, specifically handling `Europe/Vienna` (CET/CEST) and DST transitions. * **WienerLinien Support:** Native types and handling for Vienna public transport departures. * **Leave Status:** Derives human-readable statuses (`Leave now`, `Delayed +10 min`, etc.) by comparing the best non-cancelled journey's real departure time against the current time. ## 📄 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. ```typescript import { ApiClient } from "@timetoleave/api-client"; // Initialize with your backend URL const api = new ApiClient("http://localhost:3000"); // 1. Sync your calendar const events = await api.fetchCalendar("https://example.com/calendar.ics", 7); // 2. Search for a station by name const stations = await api.searchStation("Wien Mitte"); // 3. 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 const bikeRoute = await api.getBikeRoute( 48.2082, 16.3738, // From lat/lng stations[0].lat, stations[0].lng // To lat/lng ); ``` ## 🛡️ Testing & Quality Assurance The project provides comprehensive scripts for maintaining code quality: * **Linting:** Use `npm run lint` to catch stylistic and structural errors via ESLint 9. * **Type Checking:** Use `npm run typecheck` to ensure strict type safety across the codebase via TypeScript 5. * **Testing:** * The web application uses **Vitest** (v4.1.5) with **jsdom** and **@testing-library/react**. * The mobile application uses **Jest** (v29.7.0) with **jest-expo** and **react-test-renderer**. ## 📂 File Structure ```text ├── apps/ │ ├── 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 │ └── core/ # Shared domain types, countdowns, and HAFAS time utilities ├── node_modules/ # Third-party dependencies └── README.md # The file you're reading now ``` --- *Built for developers who bike to the train and hate missing their connections.*