This project provides a client-side web application for analyzing patient visit data from an XLSX file and applying predefined loyalty rules. It generates a dynamic report table with robust filtering and sorting capabilities to help manage patient statuses and discounts. The XLSX file should be exported from Medfile system, which stores information about patient visits.
This project was developed for FizjoActive – Rehabilitacja i Fizjoterapia Gdańsk, a modern physiotherapy and rehabilitation clinic based in Gdańsk, Poland. FizjoActive specializes in providing personalized therapeutic care to support patient recovery and long-term well-being. The loyalty system helps the clinic efficiently track visit history and reward returning patients, enhancing both engagement and continuity of care.
The app is hosted using GitHub Pages: Link.
The FizjoActive Loyalty System helps you:
-
Upload XLSX Data
Easily import patient visit data from a XLSX file using the Medfile format. -
Process Patient Information
Automatically parse patient names, surnames, and visit details. -
Apply Loyalty Rules
Calculate loyalty statuses and discounts based on configurable rules (e.g., "30+ Wizyt", "Roczni Lojalni"). -
Determine Status Expiration
Track when a patient’s loyalty status is set to expire. -
Generate Dynamic Report Table
Display processed patient data in an interactive table. -
Flexible Filtering:
- Patient Search: Quickly find patients by name and surname using an input field.
- Multi-Select Status Filter: Filter patients by their "Obecny status" using a custom dropdown with "Select All" and "Deselect All" options.
- Multi-Select Threshold Filter: Filter patients by "Wizyt do zmiany statusu" similarly using a custom dropdown.
-
Persistent Sorting
The table intelligently remembers and reapplies your chosen sorting preferences even after filtering. -
Configurable Highlight Threshold
Highlight patients who are a set number of visits away from reaching the next loyalty threshold.
This demo briefly presents the key functionalities of the system.
The example XLSX file used in the demo can be found in the demo folder.
The loyalty rules are defined in js/config.js and can be customized as needed.
The system applies loyalty discounts based on the number of visits within a defined period.
The rules are as follows:
| Rule Name | Visit Range | Discount | Validity Period |
|---|---|---|---|
| 30+ Wizyt | 30 or more | 10% | 365 days |
| Roczni Lojalni - Grupa 1 | 10–19 visits | 5% | 90 days |
| Roczni Lojalni - Grupa 2 | 20–29 visits | 10% | 180 days |
- Default dates:
- Start: One year prior to today.
- End: Today.
- Used to filter visits within this period.
- Users upload an XLSX file with patient records.
XLSX.readparses the file into a worksheet object.- Data is extracted: name, surname, visit info.
-
Visits are grouped by unique patients.
-
For each patient:
visitsInPeriod: Number of visits in selected range.lastVisit: Most recent visit date.status,discount,nextThreshold,expires: Evaluated byevaluateLoyalty.
-
Expiration Logic:
IflastVisit + validityDaysis past, the status is set to"Brak statusu", and discount to0.
populateThresholdDropdown,populateStatusDropdowndynamically fill filter dropdowns with unique values.- Dropdowns include:
- Select All
- Deselect All
- Bootstrap Table is (re)initialized via:
$('#reportTable').bootstrapTable('destroy').bootstrapTable({ ... });
- Applies:
- Initial sorting (
sortPriority) rowStylehighlighting
- Initial sorting (
-
Triggered on:
- Name input
- Checkbox changes (status, threshold)
-
Collects filter state and calls:
$reportTable.bootstrapTable('filterBy', filters, { filterAlgorithm: customAlgorithm });
Where:
filters: active criteriacustomAlgorithm:- AND logic across filters (name, status, threshold)
- OR logic within each (multiple statuses/thresholds)
- Handles “Deselect All” → no match behavior
-
After filtering:
$reportTable.bootstrapTable('refresh');
to apply sorting again.
| File | Responsibility |
|---|---|
js/config.js |
Global constants (e.g., LOYALTY_RULES, column mappings) |
js/utils.js |
Utilities for date math, UI toggles, etc. |
js/loyalty-engine.js |
Core logic: evaluateLoyalty(), rowStyle() |
js/table-filters.js |
Manages filter UI and applyAllFilters() logic |
js/main.js |
Entry point: DOM ready, event binding, file handling, table orchestration |
- Clone or Download the project files.
- Set up the loyalty rules in
js/config.jsas needed. - Open
index.htmlin your browser (no server required). - Upload XLSX Data Click “Wgraj plik XLSX” and select your file (ensure it follows expected column format).
- Explore the Report Use filters and search to interactively explore patient data.
- XLSX File Format
The uploaded file must match the column mapping defined in:The example XLSX file used in the demo can be found in theSOURCE_XLSX_FILE_COLUMN_TO_INDEX_MAPdemofolder.