[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-2902":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":47,"readmeContent":48,"aiSummary":49,"trendingCount":16,"starSnapshotCount":16,"syncStatus":50,"lastSyncTime":51,"discoverSource":52},2902,"fit-dashboard","arpanghosh8453\u002Ffit-dashboard","arpanghosh8453","Standalone offline local desktop application to process, store, and visualize Garmin FIT file data in a comprehensive dashboard.","https:\u002F\u002Ffitdashboard.app",null,"TypeScript",166,12,120,15,0,8,18,37,24,3.34,"Other",false,"main",true,[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"analytics","dashboard","data-analysis","data-visualisation","dektop-app","desktop","file-file","fit","fitfile","fitfileviewer","fitness-app","fitness-tracker","garmin","linux","macos","rust","statistics","tauri-app","web-application","windows","2026-06-12 02:00:44","\u003Cp align=\"center\">\n  \u003Cimg src=\"src\u002Fassets\u002Fapp-icon.svg\" alt=\"FIT Dashboard\" width=\"80\" \u002F>\n\u003C\u002Fp>\n\n\u003CH1 align=\"center\">FIT Dashboard\u003C\u002FH1>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Farpanghosh8453\u002Ffit-dashboard\u002Freleases\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDownload-Latest%20Release-1a7f37?style=for-the-badge&logo=github\" alt=\"Download Latest Release\" height=\"48\"\u002F>\n  \u003C\u002Fa>\n  &nbsp;&nbsp;\n  \u003Ca href=\"https:\u002F\u002Ffitdashboard.app\u002F\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FWebsite-Visit%20Site-0ea5e9?style=for-the-badge&logo=googlechrome&logoColor=white\" alt=\"Website\" height=\"48\"\u002F>\n  \u003C\u002Fa>\n  &nbsp;&nbsp;\n  \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FxVu4gK75zG\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-Join%20Community-5865F2?style=for-the-badge&logo=discord&logoColor=white\" alt=\"Join Discord\" height=\"48\"\u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">A high-performance activity analytics dashboard for Garmin FIT files. Available as a Tauri v2 desktop app or a Docker-deployable web app. Built with Rust, DuckDB, and React.\u003C\u002Fp>\n\n---\n\n> [!IMPORTANT]\n> Garmin is a registered trademark of Garmin Ltd. or its subsidiaries. This project is an independent, open-source tool and is not affiliated with, endorsed by, sponsored by, or approved by Garmin Ltd.\n\n> [!NOTE]\n> This project repository is dynamically mirrored in [Codeberg](https:\u002F\u002Fcodeberg.org\u002Farpanghosh8453\u002Ffit-dashboard) as a backup. An alternative docker image is available at [codeberg.org\u002Farpanghosh8453\u002Ffit-dashboard](https:\u002F\u002Fcodeberg.org\u002Farpanghosh8453\u002F-\u002Fpackages\u002Fcontainer\u002Ffit-dashboard).\n\n## Contents\n\n- [Features](#features)\n- [Getting Started](#getting-started)\n  - [Prebuilt Binaries](#prebuilt-binaries)\n  - [Development](#development)\n  - [Docker Deployment (Self-hosted)](#docker-deployment-self-hosted)\n- [Getting FIT Files from Garmin](#getting-fit-files-from-garmin)\n- [Usage](#usage)\n- [Export Formats](#export-formats)\n- [Tech Stack](#tech-stack)\n- [Project Structure](#project-structure)\n- [API Reference](#api-reference)\n- [Configuration](#configuration)\n- [Security](#security)\n- [Acknowledgements](#acknowledgements)\n- [Love This Project?](#love-this-project)\n- [Declaration](#declaration)\n- [License](#license)\n\n## Screenshots\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"screenshots\u002Foverview_page.png\" alt=\"Overview Page\" width=\"90%\" \u002F>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"screenshots\u002Findividual_page.png\" alt=\"Individual Page\" width=\"90%\" \u002F>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"screenshots\u002Fcompare_page.png\" alt=\"Compare Page\" width=\"90%\" \u002F>\n\u003C\u002Fp>\n\n## Features\n\n- **FIT File Parsing**: Native Rust parser using the `fitparser` crate. Supports all standard Garmin FIT activity files with automatic field extraction.\n- **High-Performance Storage**: DuckDB-powered analytical database with automatic downsampling for fast time-series queries. Handles hundreds of activities with millions of data points.\n- **Interactive Telemetry Charts**: ECharts-powered visualization of speed, heart rate, cadence, altitude, power, and temperature. Synchronized zoom\u002Fpan with Ctrl+scroll guarding to prevent accidental navigation.\n- **Activity Map**: MapLibre GL map with dynamic path coloring by metric (speed, HR, cadence, altitude, power, temperature, time). Hover tooltips show telemetry details at each point. Supports multiple map styles.\n- **Overview Dashboard**: Aggregate statistics across all imported activities — total distance, total duration, activity count, and recent activity feed with interactive map overlay.\n- **Advanced Filtering**: Filter by sport type, date range, duration range, and full-text search. Collapsible filter panel with bordered container design.\n- **Bulk Export**: Export filtered activities as CSV, JSON, GPX, or KML. Uses the File System Access API to write directly to a chosen folder. Fallback to individual browser downloads when the API is unavailable.\n- **Single Export**: Right-click any activity to export it individually via the context menu with format submenu.\n- **Bulk Delete**: Delete all filtered activities at once with inline confirmation and progress overlay.\n- **Inline Management**: Rename and delete activities with inline UI — no browser dialogs. All destructive actions require explicit confirmation.\n- **Session Persistence**: Authentication tokens persist across browser refreshes with a configurable 72-hour TTL (web) or until logout (desktop).\n- **Dark & Light Themes**: Modern glassmorphism design with CSS custom properties. Theme toggles instantly across the entire interface.\n- **Responsive Layout**: Collapsible sidebar with a persistent expand strip. Works on desktop and tablet viewports.\n- **Import Queue**: Batch import multiple FIT files with sequential processing for stability. Duplicate detection prevents re-importing the same file.\n- **Password Protection**: Argon2-hashed credentials with session-based authentication. First-use onboarding flow for initial setup.\n- **Cross-Platform**: Desktop builds for Windows, macOS, and Linux. \n- **Multi-language Support**: Deutsch, English, Español, Français, Magyar, Italiano, Nederlands, Polski, Português, Turkce, 中文, 日本語, 한국어\n\n## Getting Started\n\n### Prebuilt Binaries (Windows\u002FMacOS\u002FLinux)\n\nDownload desktop binaries from the [Releases page](https:\u002F\u002Fgithub.com\u002Farpanghosh8453\u002Ffit-dashboard\u002Freleases) and install for your platform:\n\n- Linux: `.AppImage` \u002F `.deb` (depending on release artifacts)\n- macOS: `.dmg` (requires an additional De-Quarantine step, read below)\n- Windows: `.msi` and `exe` installers\n\nAfter installation, launch FIT Dashboard and complete onboarding on first run.\n\n#### macOS: \"App is damaged\" Fix\n\nIf you downloaded the macOS build and see \"FIT Dashboard is damaged and can't be opened\", macOS Gatekeeper is blocking an unsigned app (this is a security warning, not a corrupted file). Use one of the methods below to open the app:\n\n##### Method 1: Right-click to Open\n\n1. Locate the app in your Applications folder (or wherever you placed it).\n2. Right-click (or Control+click) on `FIT Dashboard.app`.\n3. Select **Open** from the context menu and confirm **Open** in the dialog.\n\n##### Method 2: Remove the quarantine attribute (Terminal)\n\nOpen Terminal and run the following. Type `xattr -cr `, then drag the `.app` bundle onto the Terminal window (it will paste the full path), then press Enter:\n\n```bash\nxattr -cr \u003Cdrag-and-drop-FIT-Dashboard.app-here>\n```\n\nAfter running this, try opening the app again.\n\n> **Note:** Apple charges for developer signing; unsigned releases may require these steps. This warning means Gatekeeper prevented launch, not that the file is corrupted.\n\n### Development\n\n#### Prerequisites\n\n- [Rust](https:\u002F\u002Frustup.rs\u002F) 1.70+\n- [Node.js](https:\u002F\u002Fnodejs.org\u002F) 18+\n- npm (bundled with Node.js)\n\n```bash\n# Clone the repository\ngit clone https:\u002F\u002Fgithub.com\u002Fyour-username\u002Ffit-dashboard\ncd fit-dashboard\n\n# Install frontend dependencies\nnpm install\n\n# Start the Rust backend (web server mode)\ncd src-tauri\ncargo run --features web\n# Backend starts at http:\u002F\u002Flocalhost:8080\n\n# In another terminal, start the frontend dev server\ncd fit-dashboard\nnpm run dev\n# Frontend starts at http:\u002F\u002Flocalhost:5173\n\n# Tauri desktop dev mode\nnpm run tauri:dev\n\n# Tauri production build\nnpm run tauri:build\n```\n\nOpen http:\u002F\u002Flocalhost:5173 in your browser. On first launch, the onboarding screen appears to set up your username and password.\n\n### Docker Deployment (Self-hosted)\n\nUse the prebuilt GHCR image:\n\n```bash\ncd docker\ndocker compose up -d\n```\n\nBuild locally from source instead:\n\n```bash\ncd docker\ndocker compose -f docker-compose-build.yml up --build -d\n```\n\nOpen http:\u002F\u002Flocalhost:8088 in your browser. The Nginx reverse proxy serves the frontend and proxies API requests to the Rust backend.\n\n#### Data Persistence\n\nAll data (DuckDB database, config) is stored in a Docker named volume mapped to `\u002Fdata\u002Ffit-dashboard` inside the container. Data persists across container restarts and image updates.\n\nThe desktop app runs the Rust backend natively with Tauri IPC — no web server needed.\n\n## Getting FIT Files from Garmin\n\nIf your activities are in Garmin Connect, you can export FIT files in two ways.\n\n### Option A: Bulk export all data (recommended)\n\nUse Garmin's data export portal:\n\n- URL: https:\u002F\u002Fwww.garmin.com\u002Fen-US\u002Faccount\u002Fdatamanagement\u002Fexportdata\u002F\n\nSteps:\n\n1. Sign in with your Garmin account.\n2. Go to Data Management and choose Export Your Data.\n3. Request the export and wait for Garmin to prepare the archive.\n4. Download the ZIP archive when it's ready from email\n5. Extract the ZIP on your computer.\n6. Find activity files (FIT\u002FTCX\u002FGPX) in the extracted folders - The exported zip contains a folder (DI_CONNECT\u002FDI-Connect-Fitness-Uploaded-Files) containing your raw FIT activity files.\n7. In FIT Dashboard, use Import to select or drag-and-drop those files.\n\nWhen to use this option:\n\n- You want a full history export.\n- You are migrating from Garmin Connect to local storage.\n\n### Option B: Export one activity at a time\n\nUse the activity page in Garmin Connect:\n\n- URL: https:\u002F\u002Fconnect.garmin.com\u002Fapp\u002Factivities\n\nSteps:\n\n1. Open the Activities page.\n2. Click an activity to open details.\n3. Open the gear menu (top-right on the activity page).\n4. Click Export Original (or Export TCX\u002FGPX depending on availability).\n5. Repeat for each activity you want.\n6. Import downloaded files into FIT Dashboard.\n\nWhen to use this option:\n\n- You only need a few activities.\n- You want to re-export specific workouts.\n\nTips:\n\n- FIT is the preferred format when available, because it usually includes the richest telemetry.\n- You can import `.fit`, `.tcx`, and `.gpx` files in FIT Dashboard.\n- If duplicate files are imported, FIT Dashboard will skip them automatically. But if you have the save activity file in different format, it may still cause duplicate. We de-duplicate them based on file hash and exact start and end timestamp match of an activity. \n\n### Option C: Use Garmin-CLI tool\n\nIf you prefer the command line, [Garmin-CLI](https:\u002F\u002Fgithub.com\u002Fvicentereig\u002Fgarmin-cli) can list your activities and download the original Garmin export for a specific activity. This can be easily automated to batch download multiple activities.\n\n**Steps:**\n\n1. Install Garmin-CLI (`cargo install garmin-cli`, or use the pre-built MacOS\u002Flinux binary).\n2. Sign in once with password and OTP (if applicable): `garmin auth login`.\n3. List your activities and copy the activity ID you want: `garmin activities list`. use `--limit 20` to limit the result to last 20 activities\n4. Download the original FIT export for that activity: `garmin activities download \u003Cactivity-id>`\n\n5. Unzip the downloaded archive to get the `.fit` file, then import that file into FIT Dashboard.\n\n> [!TIP]\n> You are automate the whole process with this one liner (update the limit to match your need, here it's set as 50) \n> ```bash\n> garmin activities list --limit 50 | awk 'NR>2 && $1 ~ \u002F^[0-9]+$\u002F {print $1}' | while read -r id; do garmin activities download \"$id\" && unzip \"activity_${id}.zip\" && rm \"activity_${id}.zip\"; done\n>``` \n\nWhen to use this option:\n\n- You want to batch pull individual activities without using the Garmin Connect web UI.\n- You want a repeatable way to fetch specific activity files by ID.\n\n\n## Usage\n\n1. **Import**: Open the sidebar Import section and select one or more `.fit` files\n2. **Browse**: Activities appear in the sidebar, sorted by date. Use filters to narrow down\n3. **Analyze**: Click an activity to view telemetry charts, map path, and performance insights\n4. **Export**: Right-click an activity for single export, or use \"Export filtered\" for bulk export\n5. **Overview**: Switch to the Overview tab for aggregate statistics across all activities\n\n## Export Formats\n\n| Format | Description |\n|--------|-------------|\n| **CSV** | Full time-series with all telemetry fields. Metadata JSON embedded in the first row. Speed in both m\u002Fs and km\u002Fh. |\n| **JSON** | Structured export with activity metadata and full records array. Pretty-printed for readability. |\n| **GPX** | Standard GPS Exchange Format with track segments. Extensions include heart rate, cadence, and power. |\n| **KML** | Google Earth format with 3D line path using absolute altitude mode. |\n\n**Single export**: Right-click → Export → choose format → browser download.\n\n**Bulk export**: Click \"Export filtered\" → choose format → select destination folder → files are written one by one with progress overlay.\n\n## Tech Stack\n\n### Backend (Rust)\n\n| Component | Purpose |\n|-----------|---------|\n| **Tauri v2** | Desktop application framework (feature-gated behind `tauri-app`) |\n| **Axum** | Web REST API server for Docker\u002Fweb deployment (feature-gated behind `web`) |\n| **DuckDB** | Embedded analytical database — fast aggregations over millions of records |\n| **fitparser** | Native FIT file parsing — no external tools required |\n| **Argon2** | Password hashing for authentication |\n\n### Frontend (React)\n\n| Component | Purpose |\n|-----------|---------|\n| **React 18 + TypeScript** | UI framework |\n| **Vite** | Build tool with HMR |\n| **Zustand** | Lightweight state management |\n| **ECharts** | Telemetry charts with synchronized zoom |\n| **MapLibre GL** | Interactive map with cooperative gestures |\n| **Vanilla CSS** | Custom design system with CSS variables, dark\u002Flight theming |\n\n## Project Structure\n\n```\nfit-dashboard\u002F\n├── src-tauri\u002F                   # RUST BACKEND\n│   └── src\u002F\n│       ├── main.rs              # Entry point (feature-gated: Tauri or Axum)\n│       ├── server.rs            # Axum REST API routes\n│       ├── database.rs          # DuckDB schema, queries, downsampling\n│       ├── fit_parser.rs        # FIT file parsing with fitparser crate\n│       ├── models.rs            # Shared data structures\n│       ├── auth.rs              # Password hashing & session management\n│       ├── state.rs             # Shared application state\n│       └── tauri_app.rs         # Tauri IPC command handlers\n│\n├── src\u002F                         # REACT FRONTEND\n│   ├── components\u002F\n│   │   ├── Dashboard.tsx        # Main layout — sidebar, header, content\n│   │   ├── ActivityChart.tsx    # ECharts telemetry visualization\n│   │   ├── ActivityMap.tsx      # MapLibre map with path coloring\n│   │   ├── ActivityInsights.tsx # Derived statistics & heatmaps\n│   │   ├── SettingsPanel.tsx    # Slide-over settings drawer\n│   │   ├── Onboarding.tsx      # First-use setup flow\n│   │   ├── UnlockScreen.tsx    # Password unlock screen\n│   │   └── DonationBanner.tsx  # Support banner\n│   ├── stores\u002F\n│   │   ├── activityStore.ts    # Activity data & selection state\n│   │   └── settingsStore.ts    # Theme, units, map style settings\n│   ├── lib\u002F\n│   │   ├── api.ts              # Backend adapter (Tauri IPC \u002F Axios)\n│   │   └── exportUtils.ts      # CSV\u002FJSON\u002FGPX\u002FKML export builders\n│   ├── types.ts                # TypeScript type definitions\n│   ├── styles.css              # Complete design system\n│   ├── App.tsx                 # Root component with auth flow\n│   └── main.tsx                # React entry point\n│\n├── docker\u002F                      # DOCKER CONFIG\n│   ├── Dockerfile              # Combined backend + frontend image build\n│   ├── docker-compose.yml      # Prebuilt GHCR image deployment\n│   ├── docker-compose-build.yml# Local source build deployment\n│   └── nginx.conf              # Reverse proxy config\n│\n├── index.html                   # HTML entry point\n├── vite.config.ts               # Vite configuration\n├── tsconfig.json                # TypeScript configuration\n└── package.json                 # Node.js dependencies\n```\n\n## API Reference\n\nAll endpoints require the `X-Session` header after authentication (except `\u002Fapi\u002Fstatus`, `\u002Fapi\u002Fonboard`, and `\u002Fapi\u002Funlock`).\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| `GET` | `\u002Fapi\u002Fstatus` | Server status and onboarding check |\n| `POST` | `\u002Fapi\u002Fonboard` | First-time user setup (username + password) |\n| `POST` | `\u002Fapi\u002Funlock` | Authenticate and receive session token |\n| `POST` | `\u002Fapi\u002Flogout` | Invalidate current session |\n| `POST` | `\u002Fapi\u002Fimport-fit` | Import FIT file (multipart form data) |\n| `GET` | `\u002Fapi\u002Factivities` | List all activities |\n| `GET` | `\u002Fapi\u002Foverview` | Aggregate statistics |\n| `GET` | `\u002Fapi\u002Frecords\u002F:id` | Telemetry records with `?resolution_ms=` downsampling |\n| `PATCH` | `\u002Fapi\u002Factivities\u002F:id` | Rename activity |\n| `DELETE` | `\u002Fapi\u002Factivities\u002F:id` | Delete activity |\n\n## Configuration\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| Session TTL | 72 hours | Web session token lifetime. Desktop tokens persist until logout. |\n| API Base | `http:\u002F\u002Flocalhost:8080` | Backend URL, configurable via `VITE_API_BASE` env var |\n| Resolution | 10,000 ms | Default telemetry downsampling interval for chart queries |\n| Export Resolution | 1,000 ms | Higher-resolution records used during export operations |\n\n## Security\n\n> **FIT Dashboard is designed as a local-first application.** The web\u002FDocker mode does NOT include TLS\u002FHTTPS.\n\n- Passwords are hashed with **Argon2** before storage\n- Session tokens are generated server-side and validated on every request\n- For internet-facing deployments, use a reverse proxy (Nginx, Caddy, Traefik) with TLS termination\n\n## Acknowledgements\n\n- [fitparser](https:\u002F\u002Fcrates.io\u002Fcrates\u002Ffitparser) for robust FIT decoding.\n- [DuckDB](https:\u002F\u002Fduckdb.org\u002F) for fast embedded analytics.\n- [MapLibre GL JS](https:\u002F\u002Fmaplibre.org\u002F) for rendering activity maps.\n- Tile\u002Fmap providers used by built-in styles:\n  - [OpenStreetMap](https:\u002F\u002Fwww.openstreetmap.org\u002Fcopyright)\n  - [CARTO](https:\u002F\u002Fcarto.com\u002Fattributions)\n  - [OpenTopoMap](https:\u002F\u002Fopentopomap.org\u002Fabout)\n  - [Esri World Imagery](https:\u002F\u002Fwww.esri.com\u002Fen-us\u002Flegal\u002Foverview)\n- [ECharts](https:\u002F\u002Fecharts.apache.org\u002F) for charting.\n- [Tauri](https:\u002F\u002Ftauri.app\u002F) and [Axum](https:\u002F\u002Fgithub.com\u002Ftokio-rs\u002Faxum) for desktop and web runtime foundations.\n\n## Love This Project?\n\nIf FIT Dashboard helps your training workflow, consider supporting ongoing development:\n\n- Give this repository a star.\n- Share it with other athletes, coaches, and data enthusiasts.\n- Get a supporter badge via [Ko-fi](https:\u002F\u002Fko-fi.com\u002Fs\u002Fec2c3036ee).\n\n## Declaration\n\nFIT Dashboard is a personal open-source project maintained in public. I started this project as an offline alternative to my other project [garmin-grafana](https:\u002F\u002Fgithub.com\u002Farpanghosh8453\u002Fgarmin-grafana)\n\n- It is not affiliated with Garmin, Strava, Golden Cheetah, or any map\u002Ftile provider.\n- All trademarks and product names are the property of their respective owners.\n- Map data and tiles remain subject to each provider's attribution and usage terms.\n- This project is AI assisted. Some feature implementations includes using Claude Opus 4.5 and Codex 5.3. Although design, artitecture, behaviour and implementation decisions are always made by myself. I test out features throughly before each release and try my best to address any reported issue within a reasonable timeline. \n\n## License\n\nCopyright &copy; 2025 Arpan Ghosh. Licensed under the [GNU Affero General Public License v3.0](LICENSE).\n\n## Star History\n\n[![Star History Chart](https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=arpanghosh8453\u002Ffit-dashboard&type=date&legend=top-left)](https:\u002F\u002Fwww.star-history.com\u002F#arpanghosh8453\u002Ffit-dashboard&type=date&legend=top-left)\n","FIT Dashboard 是一个独立的离线桌面应用程序，用于处理、存储和可视化Garmin FIT文件数据。它通过Rust编写的高性能解析器支持所有标准Garmin FIT活动文件，并利用DuckDB数据库实现快速的时间序列查询，能够处理包含数百万数据点的数百项活动。此外，该应用使用ECharts提供交互式的遥测图表，包括速度、心率、节奏、海拔、功率及温度等指标的展示。适用于需要对健身活动进行深入分析和个人健康管理的场景，无论是运动员还是普通健身爱好者都能从中受益。此项目提供了Tauri v2桌面版以及可自托管的Docker镜像版本。",2,"2026-06-11 02:51:37","CREATED_QUERY"]