diff --git a/README.md b/README.md index e54808e3..7ad77d7b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -A workout tracking web application for personal use (or family, friends), geared towards running and other GPX-based -activities +A workout tracking web application for personal use (or family, friends), geared +towards running and other GPX-based activities Self-hosted, everything included. @@ -9,7 +9,8 @@ Heavily inspired by [FitTrackee](https://github.com/SamR1/FitTrackee) :heart:. ### Docker -Run the latest master image from GitHub Container Registry (master and release images are available for amd64 and arm64): +Run the latest master image from GitHub Container Registry (master and release +images are available for amd64 and arm64): ```bash # Latest master build @@ -51,7 +52,9 @@ docker compose up -d ### Natively -Download a [pre-built binary](https://github.com/jovandeginste/workout-tracker/releases) or build it yourself (see [Development](#development) below). +Download a [pre-built +binary](https://github.com/jovandeginste/workout-tracker/releases) or build it +yourself (see [Development](#development) below). Eg. for v0.11.3 on Linux x86_64: @@ -68,13 +71,15 @@ export WT_JWT_ENCRYPTION_KEY=my-secret-key ./workout-tracker ``` -This will create a new database file in the current directory and start the web server at `http://localhost:8080`. +This will create a new database file in the current directory and start the web +server at `http://localhost:8080`. ## Screenshots ### Login page ![](docs/login.png) + Login / registration form - new users have to be activated by an admin @@ -83,6 +88,7 @@ Login / registration form ### Dashboard ![](docs/dashboard.png) + Dashboard view with: - personal totals @@ -93,17 +99,20 @@ Dashboard view with: ### Overview of workouts ![](docs/workout_overview.png) + Overview of all your activities, with summaries. The columns are sortable. ### Details of a single workout ![](docs/single_workout-dark.png) + Details of a workout, with: - a zoomable, dragable map of the GPX track with more details per point - many summarized statistics -- a breakdown per kilometer +- a breakdown per kilometer or per mile - track color based on elevation of the segment +- graph of average speed and elevation per minute ### Tooltips for even more information @@ -118,8 +127,10 @@ Details of a workout, with: ![](docs/upload_workouts.png) - Upload one or multiple GPX files. -- Pick the type (running, cycling, ...) or let the application guess based on average speed -- The files are parsed when uploaded: statistics and other information are calculated and stored in the database (serialized). +- Pick the type (running, cycling, ...) or let the application guess based on + average speed +- The files are parsed when uploaded: statistics and other information are + calculated and stored in the database (serialized). ### Statistics to follow your progress @@ -150,9 +161,11 @@ Details of a workout, with: ## Configuration -The web server looks for a file `workout-tracker.yaml` (or `json` or `toml`) in the current directory, or takes it's -configuration from environment variables. The most important variable is the JWT encryption key. If you don't provide -it, the key is randomly generated every time the server starts, invalidating all current sessions. +The web server looks for a file `workout-tracker.yaml` (or `json` or `toml`) in +the current directory, or takes it's configuration from environment variables. +The most important variable is the JWT encryption key. If you don't provide it, +the key is randomly generated every time the server starts, invalidating all +current sessions. Generate a secure key and write it to `workout-tracker.yaml`: @@ -180,10 +193,12 @@ WT_REGISTRATION_DISABLED="false" WT_SOCIALS_DISABLED="false" ``` -After starting the server, you can access it at (the default port). A login form is shown. +After starting the server, you can access it at (the +default port). A login form is shown. -If no users are in the database (eg. when starting with an empty database), a default `admin` user is created with -password `admin`. You should change this password in a production environment. +If no users are in the database (eg. when starting with an empty database), a +default `admin` user is created with password `admin`. You should change this +password in a production environment. ## Development @@ -197,7 +212,8 @@ go build ./ ./workout-tracker ``` -This does not require npm or Tailwind, since the compiled css is included in the repository. +This does not require npm or Tailwind, since the compiled css is included in the +repository. ### Do some development @@ -235,10 +251,12 @@ make clean # Removes build artifacts A single binary that runs on any platform, with no dependencies. -The binary contains all assets to serve a web interface, through which you can upload your GPX files, visualize -your tracks and see their statistics and graphs. The web application is multi-user, with a simple registration and -authentication form, session cookies and JWT tokens). New accounts are inactive by default. An admin user can activate -(or edit, delete) accounts. The default database storage is a single SQLite file. +The binary contains all assets to serve a web interface, through which you can +upload your GPX files, visualize your tracks and see their statistics and +graphs. The web application is multi-user, with a simple registration and +authentication form, session cookies and JWT tokens). New accounts are inactive +by default. An admin user can activate (or edit, delete) accounts. The default +database storage is a single SQLite file. ## What technologies are used @@ -256,12 +274,13 @@ authentication form, session cookies and JWT tokens). New accounts are inactive - [Chart.js](https://cdn.jsdelivr.net/npm/chart.js) - Docker -The application uses OpenStreetMap as its map provider and for geocoding a GPS coordinate to a location. +The application uses OpenStreetMap as its map provider and for geocoding a GPS +coordinate to a location. ## Compatiblity -This is a work in progress. If you find any problems, please let us know. The application is tested with GPX files from -these sources: +This is a work in progress. If you find any problems, please let us know. The +application is tested with GPX files from these sources: - Garmin Connect (export to GPX) - FitoTrack (automatic export to GPX) @@ -276,7 +295,8 @@ these sources: - added support for MySQL, but untested so far - added support for Postgres by @icewind1991 - add support for other types of import files (eg. Garmin fit files) - - importing fit files works, kinda: there seems to be an issue with the elevation + - importing fit files works, kinda: there seems to be an issue with the + elevation - see https://github.com/tormoder/fit/issues/87 - https://www.fitfileviewer.com/ gives the same elevation issue - see if htmx is worth using diff --git a/assets/output.css b/assets/output.css index e413a510..aacc3300 100644 --- a/assets/output.css +++ b/assets/output.css @@ -1819,6 +1819,10 @@ table { height: 300px; } +.h-\[400px\] { + height: 400px; +} + .min-h-\[450px\] { min-height: 450px; } @@ -1835,10 +1839,6 @@ table { flex-basis: 50%; } -.basis-1\/3 { - flex-basis: 33.333333%; -} - .basis-1\/4 { flex-basis: 25%; } @@ -1921,6 +1921,10 @@ table { overflow: hidden; } +.overflow-y-auto { + overflow-y: auto; +} + .overflow-y-hidden { overflow-y: hidden; } @@ -2820,6 +2824,10 @@ table { .xl\:hidden { display: none; } + + .xl\:h-\[600px\] { + height: 600px; + } } @media (min-width: 1536px) { @@ -2834,6 +2842,10 @@ table { .\32xl\:hidden { display: none; } + + .\32xl\:basis-1\/3 { + flex-basis: 33.333333%; + } } @media (prefers-color-scheme: dark) { diff --git a/docs/dashboard-responsive.png b/docs/dashboard-responsive.png index 6367d8f8..2fa8950d 100644 Binary files a/docs/dashboard-responsive.png and b/docs/dashboard-responsive.png differ diff --git a/docs/dashboard.png b/docs/dashboard.png index 83586e31..65112dc5 100644 Binary files a/docs/dashboard.png and b/docs/dashboard.png differ diff --git a/docs/login.png b/docs/login.png index 5ff432af..39e0acfe 100644 Binary files a/docs/login.png and b/docs/login.png differ diff --git a/docs/responsive.png b/docs/responsive.png index 58e5d987..708f4d99 100644 Binary files a/docs/responsive.png and b/docs/responsive.png differ diff --git a/docs/single_workout-dark.png b/docs/single_workout-dark.png index edc375e9..179fb7ca 100644 Binary files a/docs/single_workout-dark.png and b/docs/single_workout-dark.png differ diff --git a/docs/single_workout-light.png b/docs/single_workout-light.png index f60cd8dd..42e3c29b 100644 Binary files a/docs/single_workout-light.png and b/docs/single_workout-light.png differ diff --git a/docs/single_workout-responsive.png b/docs/single_workout-responsive.png index 319696a6..275044d0 100644 Binary files a/docs/single_workout-responsive.png and b/docs/single_workout-responsive.png differ diff --git a/docs/single_workout-theme.jpg b/docs/single_workout-theme.jpg index b7693830..a6ff0e1b 100644 Binary files a/docs/single_workout-theme.jpg and b/docs/single_workout-theme.jpg differ diff --git a/docs/statistics-responsive.png b/docs/statistics-responsive.png index 3217088c..45e13c0d 100644 Binary files a/docs/statistics-responsive.png and b/docs/statistics-responsive.png differ diff --git a/docs/statistics.png b/docs/statistics.png index a334b6bd..aae2424c 100644 Binary files a/docs/statistics.png and b/docs/statistics.png differ diff --git a/docs/upload_workouts.png b/docs/upload_workouts.png index 731cca84..f67e72d2 100644 Binary files a/docs/upload_workouts.png and b/docs/upload_workouts.png differ diff --git a/docs/workout_overview.png b/docs/workout_overview.png index 7fbe9082..e5629f0b 100644 Binary files a/docs/workout_overview.png and b/docs/workout_overview.png differ diff --git a/screenshots.js b/screenshots.js index 4171fb4f..eb5e3ccf 100644 --- a/screenshots.js +++ b/screenshots.js @@ -81,7 +81,7 @@ export default async function () { // Create screenshots for responsive view page.setViewportSize({ - width: 400, + width: 600, height: 2000, }); page.emulateMedia({ diff --git a/translations/de.json b/translations/de.json index 7d3c7c5a..76575aca 100644 --- a/translations/de.json +++ b/translations/de.json @@ -33,8 +33,6 @@ "I completed a workout: %s.": "Ich habe die Trainingseinheit %s absolviert.", "It took me %s to go %s. I averaged %s.": "Es hat mich %s gekostet, um %s zu gehen. Ich habe im Durchschnitt %s.", "Language": "Sprache", - "Lap": "Lap", - "Last distance": "Letzte Distanz", "Leave blank to keep current password": "Leer lassen, um das aktuelle Passwort beizubehalten.", "Location": "Standort", "Logout": "Abmelden", diff --git a/translations/messages.json b/translations/messages.json index 6a303119..30601109 100644 --- a/translations/messages.json +++ b/translations/messages.json @@ -33,8 +33,6 @@ "I completed a workout: %s.": "I completed a workout: %s.", "It took me %s to go %s. I averaged %s.": "It took me %s to go %s. I averaged %s.", "Language": "Language", - "Lap": "Lap", - "Last distance": "Last distance", "Leave blank to keep current password": "Leave blank to keep current password", "Location": "Location", "Logout": "Logout", diff --git a/translations/nl.json b/translations/nl.json index 2efe97be..d1112613 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -33,8 +33,6 @@ "I completed a workout: %s.": "Ik heb een workout voltooid: %s.", "It took me %s to go %s. I averaged %s.": "Het duurde %s om %s te bereiken. Ik haalde gemiddeld %s.", "Language": "Taal", - "Lap": "Ronde", - "Last distance": "Laatste afstand", "Leave blank to keep current password": "Laat leeg om het huidige wachtwoord te behouden", "Location": "Locatie", "Logout": "Afmelden", diff --git a/views/partials/workout_breakdown.html b/views/partials/workout_breakdown.html index ce6bcedb..d513b99d 100644 --- a/views/partials/workout_breakdown.html +++ b/views/partials/workout_breakdown.html @@ -3,14 +3,13 @@ - {{ i18n "Lap" }} {{ i18n "Distance" }} - {{ i18n "Duration" }} + {{ i18n "Duration" }} {{ i18n "Speed" }} {{ i18n "Tempo" }} - + {{ range .Items }} - - {{ if .IsWorst }} - {{ end }} {{ - if .IsBest }} - {{ end }} + + {{- if .IsWorst -}} + + {{- end -}} {{- if .IsBest -}} + + {{- end -}} {{ .Counter }} - {{ .Counter }} {{ .TotalDistance | HumanDistance }} {{ CurrentUser.PreferredUnits.Distance }} - {{ .Duration | HumanDuration }} - - {{ .Speed | HumanSpeed }} {{ CurrentUser.PreferredUnits.Speed }} - - - {{ .Speed | HumanTempo }} {{ CurrentUser.PreferredUnits.Tempo }} + + {{ .TotalDuration | HumanDuration }} + {{ .Speed | HumanSpeed }} {{ CurrentUser.PreferredUnits.Speed }} + {{ .Speed | HumanTempo }} {{ CurrentUser.PreferredUnits.Tempo }} {{ end }} diff --git a/views/workouts/workouts_show.html b/views/workouts/workouts_show.html index d712ce1c..5aa2a34c 100644 --- a/views/workouts/workouts_show.html +++ b/views/workouts/workouts_show.html @@ -31,8 +31,8 @@

{{ .Name }} {{ with .Filename }}({{ . }}){{ end }}

-
-
+
+
.}} {{ end }}
-
+
{{ template "workout_details" . }}
-
+
- {{ template "workout_breakdown" (.StatisticsPer 1 - CurrentUser.PreferredUnits.Distance) }} +
+ {{ template "workout_breakdown" (.StatisticsPer 1 + CurrentUser.PreferredUnits.Distance) }} +