No description
Find a file
2026-05-15 22:58:33 +02:00
data med: fix 'Delete Demo Data' — real error reporting, robust detection 2026-04-21 20:22:27 +00:00
favicon favicon: add Med Tracker app icons and manifest 2026-04-22 07:44:57 +00:00
lang Actual State 20260515-220047 2026-05-15 22:00:47 +02:00
.gitignore Actual State 20260515-220047 2026-05-15 22:00:47 +02:00
.htaccess Initial Version of code 20260421-1917 2026-04-21 19:17:02 +02:00
api.php Actual State 20260515-225833 2026-05-15 22:58:33 +02:00
config.php.sample med: update today's history meta_times when schedule times change (v1.23.1) 2026-04-22 12:13:11 +00:00
favicon.ico favicon: add Med Tracker app icons and manifest 2026-04-22 07:44:57 +00:00
index.php Actual State 20260515-225833 2026-05-15 22:58:33 +02:00
README.de.md Actual State 20260515-220047 2026-05-15 22:00:47 +02:00
README.md Actual State 20260515-220047 2026-05-15 22:00:47 +02:00

MedTracker

A simple, self-hosted, mobile-first, multi-user medication tracker. Runs on any stock PHP web server. All data is stored in plain, human-readable text files — no database required.

Features

  • Multi-User with secure password hashing. Each user has their own login, data directory, schedule and history. Passwords are stored as bcrypt hashes in data/users.json.
  • Persistent Login. "Stay logged in" checkbox on the login form. Uses a secure, HttpOnly remember-me cookie (30 days). Sessions persist across browser restarts until explicit logout.
  • Lowercase Usernames. Usernames are always normalised to lowercase on login and user creation.
  • Admin Panel. Users flagged as admin get an extra tab to add, edit, rename, and delete other users. One user is designated as super admin in config.php and cannot be demoted or deleted from the UI.
  • Admin User Switching. Admins see a global user picker below the tab bar to view and manage any user's data — Today, Schedule, Meds, and History all switch to the selected user.
  • Per-User Settings. Admins can configure per-user defaults in the user edit form:
    • Default Startup User — which user is pre-selected when the admin logs in.
    • Default History View — Day / Week / Month / Year (default: Week). Also saved automatically when the user clicks a period button in the History tab.
  • Read-Only Users. Users with the isReadOnly flag see only the History and Meds tabs (read-only). A configurable viewUsers list controls which other users' data a read-only user can see.
  • Self-Service Password Change. Any logged-in user can change their own password from the user dropdown in the top-right.
  • Multi-Language UI. English, German, and French (EN / DE / FR). Auto-detects the browser's Accept-Language on first visit; manual switcher in the header overrides.
  • Mobile-First Design. The interface is optimised for a smartphone in portrait orientation.
  • Medication Management. Add, edit, and delete medications. Two types:
    • unit (pills / pieces) — supports fractional doses (1/4, 1/2, 3/4, 1 1/2, …).
    • liquid — free-text amounts like 15ml, 20 drops.
  • Visual Weekly Schedule Editor. Set per-day, per-slot dosages. Each slot has its own time-of-day picker. A per-slot "every day" checkbox propagates the slot's meds to every weekday when saving.
  • Schedule Versioning. When the schedule is changed, the old line is archived with a trailing date in schedule.txt. This preserves what was scheduled on each day for accurate history display and backfill. Note: The schedule can only be changed once per day (per weekday); a second change on the same day overwrites the first.
  • Configurable Time Format. Auto / 24-hour / 12-hour (AM/PM), stored per user.
  • Daily "Today" View. Lists everything scheduled for the current day, grouped by time slot, with one-tap Mark as Taken / Revert buttons.
  • History with Period Selection. History view offers Day / Week / Month / Year periods with prev/next navigation.
    • Day view: full detail with per-slot taken/missing breakdown.
    • Week / Month / Year: collapsed date lines with colour coding — green (all taken), yellow (incomplete), red (none taken). Click any date to expand its detail.
    • CSV Export: download the currently displayed period as a CSV file.
  • Automatic History Backfill. When a user logs in, any missing days between their earliest history entry and today are automatically filled with "not taken" entries using the schedule that was active on each day. This means days without login still appear correctly in the history.
  • File-Based. Everything lives under data/ as plain text — no database required.

Roles

Role Today Schedule Meds History Admin
Super admin edit (protected)
Admin edit
Regular user edit (own)
Read-only view (allowed users)

Server Requirements

  • A web server with PHP support (PHP 7.4 or newer). Apache, Nginx, Caddy, or lighttpd all work.
  • Not compatible with static-only servers — all backend logic runs in PHP.

Installation

  1. Copy files to a directory served by your web server, e.g. /var/www/html/med/.

  2. Permissions. The PHP process must be able to write to data/:

    chown -R www-data:www-data /path/to/med/data
    chmod -R u+rwX,go+rX       /path/to/med/data
    
  3. Create your configuration.

    cp config.php.sample config.php
    

    Then edit config.php:

    • Set 'super_admin' => 'your_login'
    • Optionally edit the default seed users inside load_users()
  4. First login. Open the app URL. On the first request, data/users.json is created from the seed users. Log in as the super admin, then use the Admin tab to add real users.

Install on Android (Hermit WebApp)

MedTracker exposes a Web App Manifest and a full set of icons (16 512 px). Install via Hermit — Lite Apps Browser.

Data File Format

meds.txt

One med per line: id;short;full;type or id;short;full;type;YYYY-MM-DD for archived meds. The trailing date means the med was deactivated on that date. Archived meds still appear in history but not in the active med list. IDs are never reused.

schedule.txt

One row per weekday: day;<slot1>;<slot2>;… where each slot is 0 or medId:amount[,medId:amount,…].

Historical lines have a trailing date: day;<slot1>;…;2026-05-19. This means the line was replaced starting on that date. The schedule can only be changed once per day (per weekday); changing it archives the old active line with the next occurrence of that weekday as the archive date.

history.txt

One row per day: date;day;<slot1>;<slot2>;…;meta_times. Slot-item suffix is o (taken) or n (missed).

users.json

{
  "admin": {
    "realname": "Administrator",
    "password": "$2y$...hashed...",
    "isAdmin": true,
    "isReadOnly": false,
    "viewUsers": ["*"]
  }
}

prefs.json

Per-user preferences stored in each user's data directory:

{
  "lang": "de",
  "time_format": "de",
  "default_startup_user": "",
  "default_history_view": "week"
}

tokens.json

Remember-me tokens stored in data/tokens.json (auto-managed, protected by data/.htaccess).

Security notes

  • Passwords: bcrypt hashes, never plaintext.
  • config.php is in .gitignore — don't commit secrets.
  • Use HTTPS (required for remember-me cookies).
  • data/ should not be web-browsable — keep the provided data/.htaccess.

Versioning & updates

  • Version is shown top-right as v<major>.<minor>.<patch>.
  • Update = pull + deploy; no migrations required.
  • The current version is v1.25.0.