Skip to content

Repository files navigation

Fremgang (Norwegian for "Progress")

A full-stack web application for tracking training activities, setting targets, visualizing progress, and managing events.

This application was inspired by Jason Gilmore's article "10,000 Pushups And Other Silly Exercise Quests That Changed My Life", available at https://wjgilmore.com/articles/10000-pushups.

Features

  • User Authentication: Secure registration and login with email and password.
  • Activity Tracking: Register various training activities (e.g., Push-ups, Sit-ups).
  • Event Logging: Log repetitions for activities with timestamps.
  • Target Counts: Set and track target repetition counts for each activity.
  • Progress Visualization: Interactive charts (volume over time, time of day patterns) for selected activities.
  • Event Management: View, edit, and delete past training events.
  • Data Export: Export all training data to CSV format.
  • Multi-language Support: English, Norwegian, and Spanish.
  • Theme Switching: Dark and Light mode.
  • Responsive Design: Works well on both mobile and desktop.

Screenshot

Screenshot of the Fremgang application dashboard, showing activity tracking, event logging, and progress visualization.

The dashboard view of the Fremgang application, showcasing the user interface for tracking activities, logging events, and visualizing progress with interactive charts.

Technologies Used

  • Frontend: Svelte, SvelteKit, TypeScript, Chart.js, i18next
  • Backend: Node.js, Express.js, SQLite3, bcrypt, jsonwebtoken

Getting Started

Follow these steps to set up and run the project locally.

Prerequisites

  • Node.js (LTS version recommended)
  • npm (Node Package Manager)

Environment Variables

  • JWT_SECRET (required in production): Secret used to sign authentication tokens. Generate a strong random string, e.g. node -e "console.log(require('crypto').randomBytes(32).toString('hex'))". In development, if unset, an ephemeral random secret is generated automatically (logins will not survive restarts).
  • DB_PATH (optional): Path to the SQLite database file. Defaults to db.sqlite.
  • PORT (optional): Server port. Defaults to 3010.

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd fremgang-wip-maal
  2. Install Dependencies:

    npm install

    This will install the dependencies for the root, server, and client-svelte projects.

Building for Production

To create a production-ready build of the application:

  1. Navigate to the root of the project.
  2. Run the build script:
    npm run build
    This command will:
    • Create an optimized static build of the Svelte frontend in the client-svelte/build directory.
    • Compile the TypeScript backend code into JavaScript in the server/dist directory.

Running the Application

Development

For a development environment with live reloading for both the frontend and backend:

  1. Navigate to the root of the project.
  2. Run the development start script:
    npm run start:dev
    This will start the Svelte development server and the Node.js server simultaneously. The application will be accessible at http://localhost:5173.

Production

After building the application (see "Building for Production"), you can run the production version:

  1. Navigate to the root of the project.
  2. Start the server:
    npm start
    This will start the Node.js server, which will serve the optimized frontend build. The application will be accessible at http://localhost:3010 (or the port specified in server/src/index.ts).

Podman

The application can be run in a container using Podman. The SQLite database is stored in a persistent volume, so data survives container restarts.

Prerequisites:

Build and run:

# Build the image
podman build -t fremgang .

# Set a strong JWT secret first
export JWT_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")

# Run using podman-compose (recommended, persists DB data)
podman-compose -f podman-compose.yml up -d

Or run manually:

podman run -d --name fremgang -p 3010:3010 \
  -v fremgang-data:/app/data \
  -e DB_PATH=/app/data/db.sqlite \
  -e JWT_SECRET=your-secret-here \
  fremgang

The application will be accessible at http://localhost:3010.

Stop and remove:

podman-compose -f podman-compose.yml down

Systemd Service with Podman Quadlet

Podman Quadlets are a simple, declarative way to define containers as systemd services. The Quadlet files are translated into proper systemd units automatically. This approach uses rootless podman — no sudo required.

1. Build the image:

podman build -t fremgang .

2. Create the Quadlet directory:

mkdir -p ~/.config/containers/systemd

3. Create the container Quadlet:

cat > ~/.config/containers/systemd/fremgang.container << 'EOF'
[Unit]
Description=Fremgang Training Tracker
After=network-online.target

[Container]
Image=localhost/fremgang:latest
PublishPort=3010:3010
Volume=fremgang-data:/app/data
Environment=DB_PATH=/app/data/db.sqlite
EnvironmentFile=/path/to/fremgang/.env

[Install]
WantedBy=default.target
EOF

Replace /path/to/fremgang/.env with the absolute path to your project's .env file. The JWT_SECRET from that file will be passed to the container automatically. The fremgang-data volume will be created on first run.

4. Enable lingering (so it starts at boot, not just at login):

loginctl enable-linger $USER

5. Start the service:

systemctl --user daemon-reexec
systemctl --user start fremgang.service

Note: The service name is fremgang.service (not fremgang.container.service). Generated Quadlet units cannot be enabled — the [Install] section in the Quadlet handles automatic starting.

6. Verify:

systemctl --user status fremgang.service

The container starts at boot and restarts on failure. The SQLite database persists in the fremgang-data volume.

Manage the service:

systemctl --user stop fremgang.service
systemctl --user start fremgang.service
systemctl --user restart fremgang.service
journalctl --user -u fremgang.service -f

CLI Password Change

To change a user's password via the command line:

  1. Navigate to the server directory.
  2. Run:
    npm run change-password -- <user-email> <new-password>
    (e.g., npm run change-password -- user@example.com newSecurePass123)

About

A web application for tracking training activities, setting targets, and visualizing progress.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages