Random Pick: Go to the Gym
Loaded SRC_URL
https://producingtechnology.com/65-apps/bhanushalidivya_158081_15200333_gym-reminder-app.html
JSON source: bhanushalidivya_158081_14904013_dkb86.json
Summary of Behavior
A one-screen, dark-mode, mobile-sized gym-reminder mock. It actually performs a real
fetch() against a remote JSON file and renders four stacked cards:
- You — displays the user’s reminderMessage (for this JSON: the profane “Go to the f*cking gym.” in large type), plus a “signed in as You” row and a pill with the user id.
-
Settings — a working “Reminders enabled” toggle,
read-only timezone (
America/New_York), and reminder-time chips (06:00,17:30). - Reminders — a list of scheduled reminder items with a “Dismiss (mock)” button per row. Dismissing fades the row and disables the button.
-
Workout streak — a big green streak counter, a “Log workout
today” button that bumps the counter and sets
lastWorkoutto now, and a timestamp of the last workout.
A Reload from server button re-fetches the JSON. Errors show a red error state with a Retry button. State is mutated in memory only.
Things That Didn’t Work As Expected
-
No persistence. Every local change (toggle off, dismissed reminder,
logged workout, incremented streak) is wiped on reload or on clicking
“Reload from server.” There is no
localStoragewriteback. - The toggle does nothing observable. Turning “Reminders enabled” off does not remove the reminder times, hide upcoming reminders, or change any behavior — the reminder-times chips still render.
-
“Dismiss” admits it is a mock. The button label literally
says
Dismiss (mock). There is no scheduler, notification API hookup, or reappearance logic. - Streak can only go up. The “Log workout today” button can be clicked multiple times in one day and will keep incrementing. There is no once-per-day guard and no rule that an idle day resets the streak.
- Stale reminder timestamps. The JSON ships with a 2025-02-25 reminder time. Rendered in 2026 that reads as a long-past event, not an upcoming one.
- Reminder message is NSFW by default. No profanity filter or softer alternative, which may be intended as a tone choice but is the first thing rendered in 1.15rem bold.
- No add/edit affordances. You can’t create a new reminder, edit the message, change reminder times, or switch timezone.
Prompt to Improve the App
Level up this gym-reminder single-file app so it behaves like a real accountability tool, not a screenshot with buttons:
- Persist state to
localStorage. On load, merge the fetched JSON with a local overlay (gym.state.v1) keyed by user id. Write back on every mutation (toggle, dismiss, log workout). Add a “Reset to server state” button that clears the overlay.- Make the streak honest. Store logged workouts as an array of ISO dates. The streak is derived: count consecutive days up to today that appear in the array. Logging twice in one day is a no-op. If the user misses a day, the displayed streak resets automatically on the next render.
- Wire the reminder toggle. When off, grey out the reminder-times section, hide the upcoming reminders list, and show copy like “Reminders are paused — you won’t be nudged today.” When on (and the browser supports it), request the Notification API and fire a real local notification at the next reminder time using
setTimeoutscheduled against the user’s timezone.- Add edit affordances. Inline-edit the reminder message (with a “keep it PG” softer default), add/remove reminder times via a time input, and let the user pick their timezone from
Intl.supportedValuesOf('timeZone').- Treat reminders as recurring, not one-off. Instead of one
scheduledAttimestamp, generate the next occurrence from each reminder time daily. Dismissing a reminder only dismisses today’s instance; tomorrow it comes back.- Show the future, not the past. The “when” row should say “in 3h 12m” / “tomorrow at 6:00 AM” rather than a raw date string, and items whose time has passed should be marked missed rather than labeled as if they were scheduled.