Skip to content

circadia-bio/ScoreMe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

133 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“‹ ScoreMe

A cross-platform research questionnaire scorer for Circadia Lab.

MIT License Expo React Native Platform


πŸ“– What is ScoreMe?

ScoreMe is a mobile and desktop app for administering and scoring validated clinical and sleep health questionnaires across multiple research participants. It is designed for lab-based or clinic-based research sessions where a researcher needs to collect structured self-report data from a cohort, track completion, and export results for analysis.

It is part of the Circadia Lab toolchain and shares its visual identity with SleepDiaries.


✨ Features

  • πŸ“‹ 25 built-in validated instruments across 5 clinical domains β€” Sleep (ESS, ISI, DBAS-16, MEQ, PSQI, RU-SATED, STOP-BANG, KSS), Mental Health (PHQ-2, PHQ-9, PHQ-15, GAD-7, GAD-2, BDI-II, BAI, DASS-21, PANSS, STAI-S, STAI-T), Wellbeing (WHOQOL-BREF, MacArthur SSS), Physical Activity (IPAQ-S, GPAQ), and Neurodevelopmental (GSQ, AQ-10)
  • πŸ‘₯ Rich participant profiles β€” mandatory participant code plus optional name, demographics (age, sex, BMI), study fields (group, site, session), clinical fields (diagnosis, medication, referral), and arbitrary custom key–value pairs
  • πŸ” Search and sort β€” filter participants by code, name, group, site, or session; sort by date added, A–Z, or completion %
  • 🎯 Step-by-step questionnaire runner β€” one item at a time, automatic scoring and interpretation on completion, coloured result badge with glow shadow
  • πŸ• Score history β€” re-scoring appends to a timestamped history array; no data is ever overwritten; attempt count shown in detail view; full history in JSON export
  • πŸ”€ Enable/disable instruments β€” per-questionnaire toggles persisted across sessions; animated pill toggle; group by clinical domain
  • πŸ“Š Analytics tab β€” score distributions (SVG box plots with whiskers, mean, median), descriptive statistics table (n, mean Β± SD, median, range), completion rates, switchable grouping by group/condition, sex, session, or site
  • πŸ“₯ Custom questionnaire import β€” import any instrument as a JSON file following the built-in schema
  • πŸ“€ CSV and JSON export β€” CSV includes all participant metadata fields and custom fields as dynamic columns, with latest score per questionnaire; JSON includes full timestamped score history with item-level answers; preview table in the export panel
  • πŸ–₯️ Desktop split-panel layout β€” left participant list, right detail/scoring/edit panel, glassmorphic sidebar with About modal
  • 🌐 Cross-platform β€” runs as a web app, iOS app, and Android app from the same codebase
  • 🌍 Localisation β€” English and Brazilian Portuguese (PT-BR) for both UI strings and instrument content (item text, response options, instructions, score band labels), detected automatically from the device locale
  • πŸŽ‰ First-run onboarding β€” 3-slide centred modal walkthrough, shown once; resettable from the About modal

πŸ—‚οΈ Project Structure

ScoreMe/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ _layout.jsx              Root layout β€” fonts, WebShell, Stack
β”‚   β”œβ”€β”€ index.jsx                Redirects to tabs
β”‚   β”œβ”€β”€ export.jsx               Export screen + DesktopExportModal
β”‚   β”œβ”€β”€ score/[pid]/[qid].jsx   Mobile scoring route
β”‚   β”œβ”€β”€ participant/[id].jsx     Mobile participant detail + inline edit
β”‚   └── (tabs)/
β”‚       β”œβ”€β”€ _layout.jsx          Desktop shell; onboarding modal
β”‚       β”œβ”€β”€ index.jsx            Dashboard
β”‚       β”œβ”€β”€ participants.jsx     Participant list + search/sort + FAB + detail panel
β”‚       β”œβ”€β”€ questionnaires.jsx   Questionnaire library + toggles + domain grouping
β”‚       └── analytics.jsx        Score distributions, stats table, completion rates
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ QuestionnaireRunner.jsx  Step-by-step runner (desktop + mobile); applies localise()
β”‚   β”œβ”€β”€ OnboardingModal.jsx      First-run centred square modal
β”‚   β”œβ”€β”€ ScreenBackground.jsx     SVG gradient background (mobile)
β”‚   β”œβ”€β”€ DesktopBackground.jsx    Dot-grid pattern background (desktop)
β”‚   β”œβ”€β”€ DesktopSidebar.jsx       Sidebar nav + About modal + onboarding reset
β”‚   └── charts/
β”‚       β”œβ”€β”€ BoxPlot.jsx          SVG box-and-whisker plot with group support
β”‚       β”œβ”€β”€ CompletionBar.jsx    Horizontal completion rate bars
β”‚       └── chartUtils.js        Descriptive stats, grouping, palette helpers
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ questionnaires.js        Compatibility shim β€” re-exports from questionnaires/index.js
β”‚   └── questionnaires/
β”‚       β”œβ”€β”€ index.js             Central registry β€” QUESTIONNAIRES, getQuestionnaire,
β”‚       β”‚                        compileQuestionnaire; imports all domain files
β”‚       β”œβ”€β”€ sleep.js             ESS, ISI, DBAS-16, MEQ, PSQI, RU-SATED, STOP-BANG, KSS
β”‚       β”œβ”€β”€ mental_health.js     PHQ-2, PHQ-9, PHQ-15, GAD-7, GAD-2, BDI-II, BAI,
β”‚       β”‚                        DASS-21, PANSS, STAI-S, STAI-T
β”‚       β”œβ”€β”€ wellbeing.js         WHOQOL-BREF, MacArthur SSS
β”‚       β”œβ”€β”€ physical_activity.js IPAQ-S, GPAQ
β”‚       β”œβ”€β”€ neurodevelopmental.js GSQ, AQ-10
β”‚       └── utils.js             localise(questionnaire, locale) β€” merges pt-BR translations
β”‚                                over the base EN instrument object at runtime
β”œβ”€β”€ i18n/
β”‚   β”œβ”€β”€ index.js                 Locale detection + t() helper
β”‚   β”œβ”€β”€ en.js                    English UI strings
β”‚   └── pt-BR.js                 Brazilian Portuguese UI strings
β”œβ”€β”€ storage/
β”‚   └── storage.js               AsyncStorage CRUD, score history, export helpers,
β”‚                                 disabled-Qs, onboarding flag
β”‚                                 Exports: getLatestResult, getAllResults
β”œβ”€β”€ theme/
β”‚   β”œβ”€β”€ typography.js            FONTS, SIZES, COLOURS
β”‚   └── responsive.js            useLayout(), SIDEBAR_W, SIDEBAR_TOTAL
β”œβ”€β”€ docs/
β”‚   └── questionnaire-schema.md  Full schema reference + LLM prompt template
└── scripts/
    └── setup.js                 Copies fonts from SleepDiaries sibling repo

πŸš€ Getting Started

Prerequisites

  • Node.js β‰₯ 18
  • Expo CLI
  • The SleepDiaries repo cloned as a sibling directory (for fonts and logo)

Installation

git clone https://github.com/circadia-bio/ScoreMe
cd ScoreMe
npm install
node scripts/setup.js     # copies fonts from SleepDiaries

If SleepDiaries is not present, setup.js will skip missing files gracefully and the app will fall back to system fonts.

Run

# Web (recommended for development)
npx expo start --web

# iOS simulator
npx expo start --ios

# Android emulator
npx expo start --android

πŸ‘€ Participant Data Model

Each participant stores a mandatory code and a set of optional fields exported in both CSV and JSON:

Field Type Notes
code string Required. Unique participant identifier (e.g. P001)
name string Full name (optional)
age string Age in years
sex string Male / Female / Non-binary / Prefer not to say
bmi string Body mass index
group string Group or condition label (e.g. Control, Treatment A)
site string Recruitment or testing site
session string Session label (e.g. Baseline, Week 4)
diagnosis string Clinical diagnosis
medication string Current medication
referral string Referral source
customFields {label, value}[] Arbitrary researcher-defined key–value pairs; each becomes its own CSV column
notes string Free-text notes

Metadata chips in the detail panel are colour-coded by category (demographics, study, clinical).

Score history

Each questionnaire result is stored as a timestamped array. Re-scoring appends a new entry rather than overwriting. getLatestResult(participant, qid) and getAllResults(participant, qid) are exported from storage.js for use across screens. Legacy single-object results are migrated automatically on next save.


πŸ“₯ Custom Questionnaire Import

Any validated questionnaire can be imported as a .json file. ScoreMe compiles scoring and interpretation logic from declarative fields β€” no code required.

To import: Questionnaires tab β†’ Import JSON.

The minimum required fields are id, title, and items. A complete example:

{
  "id": "pss10",
  "title": "Perceived Stress Scale β€” 10 items",
  "shortTitle": "PSS-10",
  "domain": "Mental Health",
  "construct": "Perceived stress",
  "timeframe": "Past month",
  "maxScore": 40,
  "scoringMethod": { "type": "sum", "items": ["pss1","pss2","pss3","pss4","pss5","pss6","pss7","pss8","pss9","pss10"] },
  "scoreBands": [
    { "min": 0,  "max": 13, "label": "Low stress",      "color": "#2E7D32", "description": "Low perceived stress." },
    { "min": 14, "max": 26, "label": "Moderate stress",  "color": "#F59E0B", "description": "Moderate perceived stress." },
    { "min": 27, "max": 40, "label": "High stress",      "color": "#DC2626", "description": "High perceived stress." }
  ],
  "items": [
    {
      "id": "pss1", "number": 1,
      "text": "In the last month, how often have you been upset because of something that happened unexpectedly?",
      "type": "frequency_4",
      "options": [
        { "value": 0, "label": "Never" },
        { "value": 1, "label": "Almost never" },
        { "value": 2, "label": "Sometimes" },
        { "value": 3, "label": "Fairly often" },
        { "value": 4, "label": "Very often" }
      ]
    }
  ]
}

See docs/questionnaire-schema.md for the full schema reference, all supported item types, and a ready-to-paste LLM prompt for generating new questionnaire files.


🌍 Localisation

ScoreMe detects the device locale at startup using expo-localization and selects the matching translation bundle, falling back to English for unsupported locales.

Supported languages:

Code Language Status
en English βœ… Default
pt-BR Portuguese (Brazil) βœ… Complete

UI strings

All interface strings are keyed in i18n/en.js and i18n/pt-BR.js. To add a new language, duplicate either file and register the new locale tag in i18n/index.js.

The t() helper supports {{variable}} interpolation and _one / _other pluralisation:

import t from '../i18n';

t('dashboard.title')                          // "Dashboard" / "Painel"
t('export.participants', { count: 3 })        // "3 participants" / "3 participantes"

Instrument content translations

Item text, response option labels, instructions, hints, and score band labels for all 25 built-in instruments are translated inside a translations block on each instrument definition. The localise(questionnaire, locale) helper in data/questionnaires/utils.js merges the requested locale over the base English object at runtime, with per-key English fallback for any missing keys.

// Applied automatically in QuestionnaireRunner before rendering:
import { localise } from '../data/questionnaires/utils';
import { locale }   from '../i18n';

const q = localise(questionnaire, locale);
// q.instructions, q.items[n].text, q.items[n].options[n].label
// are now in the device locale where translations exist

Fields intentionally left in English: title, shortTitle, version, reference, credit, copyright, construct, constructDescription β€” these are proper names and citations.


πŸ“¦ Dependencies

Package Version Purpose
expo ~55 App framework and build toolchain
expo-router ~55 File-based navigation
expo-blur ~14 Glassmorphic BlurView components
expo-document-picker ~55 JSON import from device
expo-file-system ~18 File write for CSV/JSON export
expo-font ~55 Custom font loading
expo-localization ~55 Device locale detection for i18n
expo-sharing ~55 Share sheet for export
@react-native-async-storage/async-storage 2.2 Persistent storage
react-native-safe-area-context 5.6 Safe area insets
react-native-svg 15.15 SVG charts in analytics tab
@expo/vector-icons ~15 Ionicons icon set

πŸ‘₯ Authors

Role Name Affiliation
Developer / Researcher Lucas FranΓ§a Circadia Lab
Researcher Mario Leocadio-Miguel Circadia Lab

🀝 Related Tools

  • πŸŒ™ SleepDiaries β€” participant-facing sleep diary app; shares visual identity and font assets with ScoreMe
  • πŸ”¬ tallieR β€” companion R package for importing ScoreMe JSON exports, rescoring questionnaires, and returning tidy data frames
  • πŸ”¬ circadia-bio β€” the Circadia Lab GitHub organisation

πŸ“„ Licence

Copyright Β© Lucas FranΓ§a, Mario Leocadio-Miguel, 2026

Released under the MIT License.

Note on third-party questionnaire instruments: The validated questionnaires included in this app are the intellectual property of their respective authors and institutions. Their inclusion in this open-source repository does not grant any rights to use them beyond what is permitted by each instrument's licence. See the credit and copyright fields in data/questionnaires/ for per-instrument details.

About

πŸ“‹ Research questionnaire scorer: administer and score validated sleep health instruments across multiple participants, with CSV/JSON export.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages