# Map Journal

**Authors:** Tomas Horsky, Haeri Kim
**Student IDs:** 20256426, <ID>
**Emails:** tomashorsky@kaist.ac.kr , <Email> 

**Repository:** <https://git.prototyping.id/20256426/Map-Jurnal.git>  
**Video Demo:** _[YouTube URL]_

---

## Overview

Journi is a web application for journaling and visualizing travel experiences. Users log trips by country, pinning cities, dates, transport modes, and photos. Then user can explore their journey on an interactive world map, timeline view or can play short animations overviewing his trips.

### How It Works

1. **Sign in** with a Google account.
2. **Select your home country** — it is automatically marked as visited on the map.
3. **Add journal entries**:
    - **Step 0** — Click on country in map you visited or click add trip in timeline.
   - **Step 1** — Choose country, cities, arrival date, days stayed, trip type (solo/friends/family), and transport (flight/train/bus/car/ship/walk).
   - **Step 2** — Upload photos (stored in Firebase Storage).
   - **Step 3** — Answer three random reflective questions about the trip (e.g., *"What was the most unexpected thing that happened?"*).
4. **Edit entries** through the same form, pre-filled with existing data.
5. **View your journey** on a D3-powered world map where visited countries are highlighted and animated flight paths connect entries in chronological order.
6. **Browse a timeline** sorted by date, country, or recency.
7. **Share** a generated summary card to show off your stats.

---

## Code Organization

```
src/
├── App.svelte              Root component — mode switching & replay button
├── main.js                 Vite entry point
├── app.css                 Global CSS variables and resets
├── assets/                 14 static images (transport icons, profile, defaults)
│
└── lib/
    ├── firebase.js         Firebase init (auth, Firestore, Storage)
    │
    ├── auth/
    │   ├── LoginOverlay.svelte    Google sign-in dialog
    │   ├── CountryPicker.svelte   Home-country selection step
    │   └── userStore.svelte.js    Auth state & user profile store
    │
    ├── layout/
    │   ├── Layout.svelte          App shell (auth guard + sidebar)
    │   ├── TopBar.svelte          Segmented nav (Map / Journal)
    │   └── selection.svelte.js    Reactive set of visited countries
    │
    ├── stores/
    │   └── entriesStore.svelte.js  Firestore CRUD & reactive list
    │
    ├── shared/
    │   ├── cities.js              Country→cities map
    │   ├── countries.js           Country names, IDs, flag emoji helpers
    │   ├── SearchInput.svelte     Autocomplete text input
    │   └── types.js               JSDoc type definitions
    │
    ├── world-map/
    │   ├── WorldMap.svelte        D3 globe — visited countries, home marker, tooltips
    │   ├── JourneyView.svelte     Animated flight-path overlay + stats
    │   ├── StatsPanel.svelte      Trip statistics panel
    │   └── continents.js          Continent classification data
    │
    └── timeline/
        ├── detail/
        │   ├── NewEntryForm.svelte     Multi-step entry creation (3 steps)
        │   ├── EditForm.svelte         Multi-step entry editing (3 steps)
        │   ├── StepNavbar.svelte       Shared step-navigation top bar
        │   ├── TripBasicInfo.svelte    Step 1 form (country, cities, dates, transport)
        │   ├── PhotoEditor.svelte      Step 2 — upload & manage photos
        │   ├── JournalDetail.svelte    Full entry view with lightbox
        │   └── DeleteConfirm.svelte    Delete confirmation dialog
        └── view/
            ├── TimelineView.svelte     Sorted entry list with year groups
            ├── TimelineCard.svelte     Entry card thumbnail
            ├── ShareCard.svelte        Generated share image
            └── SharePreview.svelte     Share card preview modal
```

### Architecture

**Component tree** (simplified):

```
App.svelte
└── Layout.svelte
    ├── LoginOverlay.svelte
    ├── TopBar.svelte
    ├── CountryPicker.svelte
    ├── WorldMap.svelte
    │   └── JourneyView.svelte
    │       └── StatsPanel.svelte
    └── TimelineView.svelte
        ├── TimelineCard.svelte
        ├── JournalDetail.svelte
        │   ├── DeleteConfirm.svelte
        │   └── EditForm.svelte
        │       ├── StepNavbar.svelte
        │       ├── TripBasicInfo.svelte
        │       └── PhotoEditor.svelte
        ├── NewEntryForm.svelte
        │   ├── StepNavbar.svelte
        │   ├── PhotoEditor.svelte
        │   └── ...
        ├── ShareCard.svelte
        └── SharePreview.svelte
```

### Data Flow

```
Firebase Auth          ──→  userStore.svelte.js  ──→  Layout (auth guard)
Firebase Firestore     ──→  entriesStore.svelte.js ──→  Timeline, Map (via $state/$derived)
Firebase Storage       ──→  PhotoEditor.svelte (upload)
selection.svelte.js    ──→  visited set (derived from entries + home country)
```

### Key Patterns

- **Svelte 5 runes** — `$state`, `$derived`, `$effect`, `$bindable`, `$props` replace the old Svelte store/reactivity model.
- **$bindable props** — `TripBasicInfo` uses `$bindable()` for two-way binding with its parent form, keeping form state in the parent while delegating UI rendering.
- **Firebase listeners** — `entriesStore` uses `onSnapshot` for real-time Firestore sync; `userStore` uses `onAuthStateChanged`.
- **D3.js** — `WorldMap` renders a GeoJSON world map with centered zoom via `d3-geo`; `JourneyView` animates SVG flight paths.
- **No framework router** — the app uses a simple `mode` state variable (`'map' | 'journal'`) in `App.svelte` to switch between views.

---


## Setup & Run

```bash
# Install
npm install

# Environment — create .env with your Firebase config:
#   VITE_FIREBASE_API_KEY=...
#   VITE_FIREBASE_AUTH_DOMAIN=...
#   VITE_FIREBASE_PROJECT_ID=...
#   VITE_FIREBASE_STORAGE_BUCKET=...
#   VITE_FIREBASE_MESSAGING_SENDER_ID=...
#   VITE_FIREBASE_APP_ID=...

# Run server
npm run dev

```

---

## Acknowledgments

- **D3.js** — [Mike Bostock](https://d3js.org/) for the visualization library.
- **world-atlas** — [Topojson world data](https://github.com/topojson/world-atlas) by Mike Bostock.
- **Firebase** — Google for the backend suite (Auth, Firestore, Storage).
- **Svelte** — [Svelte team](https://svelte.dev/) for the frontend framework.
- **html-to-image** — [tsayen](https://github.com/bubkoo/html-to-image) for DOM-to-image capture.
- **Cursor icon** — Derived from the SVG airplane asset used in the app.
