Equipment picker
Let people say what their gym has, using filters you never have to hard-code or update.
“What do you have access to?” is the question that makes everything after it useful — home gym, hotel rack, commercial floor. Answering it needs a taxonomy, and the taxonomy is the part you do not want to own.
Build filters from vocabularies
Each filter’s accepted values are published, with a label where the id is not presentable on its own:
curl 'https://api.gymassets.dev/v1/equipment-categories' \
-H "Authorization: Bearer $GA_SECRET_KEY"
Render those as your options and your picker keeps working as the catalogue grows — no release on your side when a value is added. See equipment vocabularies.
Filter equipment
curl 'https://api.gymassets.dev/v1/equipment?category=free-weight' \
-H "Authorization: Bearer $GA_SECRET_KEY"
Filters combine, and the collection carries whole records — so the list you draw has the label and the artwork already in it, with no second request per row.
Draw a row and show what is chosen
At row height the line icon reads where the photographic render does not, and both hang off the id you already have. Draw every row in a neutral theme and the chosen one in a highlight — same URL, one parameter apart:
/v1/{key}/equipment/icon/leg-press-45.png?theme=thm_neutral_dark
/v1/{key}/equipment/icon/leg-press-45.png?theme=thm_highlight_dark_sky
The selected state is a colour you did not have to apply yourself, and the resting rows stay quieter than your own controls. See render an equipment icon and theming.
Distinguish unknown from none
A count of zero is still an option. It means the value is accepted but nothing
uses it today. Show it or hide it as you prefer, but expect it to fill later rather
than appear from nowhere.
An empty loading is not ["none"]. An empty value means nobody has classified
the entry. ["none"] is a deliberate “takes no load” — a pull-up bar, a balance
board. Treat them as different, and see
get equipment for the detail.
Store ids, not labels
Store the ids, not the labels. Ids are stable and are what every later request takes; labels are for people and can be reworded.