From dfc81b448589e51ed038f5e3fc45b6213cfc36f9 Mon Sep 17 00:00:00 2001 From: Cipher Vance Date: Wed, 18 Feb 2026 09:56:14 -0600 Subject: [PATCH] more work --- BUILD.md | 108 +++++++++++++++++++++++++++++++ src/hooks/useCalendarWorkouts.ts | 8 ++- src/services/api/workouts.ts | 9 ++- src/types/api.ts | 12 ++++ 4 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 BUILD.md diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..81d4eaf --- /dev/null +++ b/BUILD.md @@ -0,0 +1,108 @@ +# Building RideAware Trainer + +## Quick Start + +### Local Development Build +```bash +npm run electron:dev +``` + +### Production Builds + +#### Linux (from Linux) +```bash +npm run electron:build:linux +``` +Builds: AppImage, deb, rpm (requires Ubuntu/Debian for deb/rpm) + +#### Windows (from Windows) +```bash +npm run electron:build:win +``` +Builds: NSIS installer (.exe) + +#### macOS (from macOS) +```bash +npm run electron:build:mac +``` +Builds: DMG, ZIP + +## Cross-Platform Builds with GitHub Actions + +The easiest way to build for all platforms is using GitHub Actions: + +### Automatic Release Build +```bash +git tag v1.0.1 +git push origin v1.0.1 +``` + +This triggers the workflow which: +1. Builds on Windows, macOS, and Linux runners +2. Creates a GitHub Release +3. Uploads all installers (exe, dmg, AppImage, deb, rpm) + +### Manual Build +Go to: GitHub → Actions → Build and Release → Run workflow + +## Build Artifacts + +After building, files are in the `release/` directory: + +- **Windows**: `RideAware Trainer Setup 1.0.0.exe` +- **macOS**: `RideAware Trainer-1.0.0-arm64.dmg`, `RideAware Trainer-1.0.0-arm64-mac.zip` +- **Linux**: + - `RideAware Trainer-1.0.0.AppImage` (universal) + - `rideaware-trainer_1.0.0_amd64.deb` (Debian/Ubuntu) + - `rideaware-trainer-1.0.0.x86_64.rpm` (Fedora/RHEL) + +## Platform Limitations + +### Building from Linux +- ✅ Linux packages (AppImage always works, deb/rpm need Ubuntu) +- ❌ macOS DMG (requires macOS-specific dependencies) +- ❌ Windows EXE (requires Windows or Wine) + +### Building from macOS +- ✅ macOS packages (DMG, ZIP) +- ✅ Linux packages (with Docker) +- ❌ Windows EXE (requires Windows or Wine) + +### Building from Windows +- ✅ Windows packages (EXE) +- ✅ Linux packages (with WSL/Docker) +- ❌ macOS DMG (requires macOS) + +**Recommendation**: Use GitHub Actions for cross-platform builds. + +## Icon Requirements + +Place app icons in the `build/` directory: +- `build/icon.ico` - Windows (256x256) +- `build/icon.icns` - macOS (1024x1024) +- `build/icon.png` - Linux (512x512) + +## Troubleshooting + +### "dmg-license not found" on Linux +This is expected. Build macOS packages on macOS or use GitHub Actions. + +### "libcrypt.so.1 not found" on Fedora +Install compatibility package or use GitHub Actions (runs on Ubuntu). + +### Build hangs on "packaging" +Check available disk space. Electron builds can use 500MB+ per platform. + +## GitHub Actions Workflow + +The workflow file is at `.github/workflows/build.yml`. + +**Triggers:** +- Push to `main` branch (builds but doesn't release) +- Push tag starting with `v` (builds and creates release) +- Manual workflow dispatch +- Pull requests (builds but doesn't release) + +**Permissions needed:** +- Repository Settings → Actions → General → Workflow permissions +- Enable "Read and write permissions" diff --git a/src/hooks/useCalendarWorkouts.ts b/src/hooks/useCalendarWorkouts.ts index 18982b7..a86be60 100644 --- a/src/hooks/useCalendarWorkouts.ts +++ b/src/hooks/useCalendarWorkouts.ts @@ -3,7 +3,7 @@ import { getWorkoutsByMonth, getTodaysWorkouts, getWeeksWorkouts, - markWorkoutComplete, + completeWorkout as apiCompleteWorkout, } from '../services/api'; import type { ApiWorkout } from '../types/api'; import type { Workout, WorkoutInterval } from '../types/workout'; @@ -166,17 +166,19 @@ export function useCalendarWorkouts(): UseCalendarWorkoutsReturn { maxPower?: number; maxHr?: number; caloriesBurned?: number; + syncToStrava?: boolean; } ) => { try { - await markWorkoutComplete(workoutId, { - duration: Math.round(metrics.duration / 60), + await apiCompleteWorkout(workoutId, { + duration: Math.round(metrics.duration), distance: metrics.distance, avg_power: metrics.avgPower, avg_hr: metrics.avgHr, max_power: metrics.maxPower, max_hr: metrics.maxHr, calories_burned: metrics.caloriesBurned, + sync_to_strava: metrics.syncToStrava ?? true, }); await refresh(); } catch (err) { diff --git a/src/services/api/workouts.ts b/src/services/api/workouts.ts index 2f08b20..70914b2 100644 --- a/src/services/api/workouts.ts +++ b/src/services/api/workouts.ts @@ -1,5 +1,5 @@ import { api } from './client'; -import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload } from '../../types/api'; +import type { ApiWorkout, WorkoutTemplate, WorkoutUpdatePayload, WorkoutCompletionPayload } from '../../types/api'; export async function getWorkouts(): Promise { return api.get('/protected/workouts'); @@ -35,6 +35,13 @@ export async function markWorkoutComplete( }); } +export async function completeWorkout( + id: number, + completionData: WorkoutCompletionPayload +): Promise { + return api.post(`/protected/workouts/complete?id=${id}`, completionData); +} + export async function skipWorkout(id: number, notes?: string): Promise { return api.put(`/protected/workouts?id=${id}`, { status: 'skipped', diff --git a/src/types/api.ts b/src/types/api.ts index f28b236..2eb6039 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -151,3 +151,15 @@ export interface WorkoutUpdatePayload { calories_burned?: number; notes?: string; } + +export interface WorkoutCompletionPayload { + duration: number; + distance?: number; + avg_power?: number; + avg_hr?: number; + max_power?: number; + max_hr?: number; + calories_burned?: number; + notes?: string; + sync_to_strava?: boolean; +}