From 703eb47fd2908ecd1d2a9eb999c88fdf4ccebcc3 Mon Sep 17 00:00:00 2001 From: Boxel Submission Bot Date: Wed, 8 Apr 2026 17:22:55 +0800 Subject: [PATCH] add Workout Listing changes [boxel-content-hash:dff0310fd5c6] --- .../1aa22e58-a6c4-4632-b686-f3a183a2e5a9.json | 84 ++++++++ Exercise/bench-press.json | 31 +++ Exercise/pull-up.json | 31 +++ Exercise/squat.json | 31 +++ .../05ef1d53-7fdc-4fbb-819a-b8f9eac8d307.json | 40 ++++ .../599e05ef-1d53-4fdc-9fbb-019ab8f9eac8.json | 40 ++++ .../84599e05-ef1d-437f-9c1f-bb019ab8f9ea.json | 40 ++++ .../9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3.json | 40 ++++ .../ca84599e-05ef-4d53-bfdc-1fbb019ab8f9.json | 40 ++++ .../81914141-a017-4470-9e9a-c14216fbf0e6.json | 57 ++++++ WorkoutSession/leg-day.json | 55 ++++++ WorkoutSession/pull-day.json | 55 ++++++ WorkoutSession/push-day.json | 55 ++++++ exercise.gts | 115 +++++++++++ workout-log.gts | 179 ++++++++++++++++++ workout-session.gts | 137 ++++++++++++++ 16 files changed, 1030 insertions(+) create mode 100644 CardListing/1aa22e58-a6c4-4632-b686-f3a183a2e5a9.json create mode 100644 Exercise/bench-press.json create mode 100644 Exercise/pull-up.json create mode 100644 Exercise/squat.json create mode 100644 Spec/05ef1d53-7fdc-4fbb-819a-b8f9eac8d307.json create mode 100644 Spec/599e05ef-1d53-4fdc-9fbb-019ab8f9eac8.json create mode 100644 Spec/84599e05-ef1d-437f-9c1f-bb019ab8f9ea.json create mode 100644 Spec/9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3.json create mode 100644 Spec/ca84599e-05ef-4d53-bfdc-1fbb019ab8f9.json create mode 100644 WorkoutLog/81914141-a017-4470-9e9a-c14216fbf0e6.json create mode 100644 WorkoutSession/leg-day.json create mode 100644 WorkoutSession/pull-day.json create mode 100644 WorkoutSession/push-day.json create mode 100644 exercise.gts create mode 100644 workout-log.gts create mode 100644 workout-session.gts diff --git a/CardListing/1aa22e58-a6c4-4632-b686-f3a183a2e5a9.json b/CardListing/1aa22e58-a6c4-4632-b686-f3a183a2e5a9.json new file mode 100644 index 0000000..ce3f6eb --- /dev/null +++ b/CardListing/1aa22e58-a6c4-4632-b686-f3a183a2e5a9.json @@ -0,0 +1,84 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "CardListing", + "module": "https://app.boxel.ai/catalog/catalog-app/listing/listing" + } + }, + "type": "card", + "attributes": { + "name": "Workout Listing", + "images": [], + "summary": "A simple yet easy workout log app", + "cardInfo": { + "name": "", + "notes": null, + "summary": null, + "cardThumbnailURL": null + } + }, + "relationships": { + "tags": { + "links": { + "self": null + } + }, + "skills": { + "links": { + "self": null + } + }, + "license": { + "links": { + "self": null + } + }, + "specs.0": { + "links": { + "self": "../Spec/84599e05-ef1d-437f-9c1f-bb019ab8f9ea" + } + }, + "specs.1": { + "links": { + "self": "../Spec/9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3" + } + }, + "specs.2": { + "links": { + "self": "../Spec/05ef1d53-7fdc-4fbb-819a-b8f9eac8d307" + } + }, + "specs.3": { + "links": { + "self": "../Spec/ca84599e-05ef-4d53-bfdc-1fbb019ab8f9" + } + }, + "specs.4": { + "links": { + "self": "../Spec/599e05ef-1d53-4fdc-9fbb-019ab8f9eac8" + } + }, + "publisher": { + "links": { + "self": null + } + }, + "categories": { + "links": { + "self": null + } + }, + "examples.0": { + "links": { + "self": "../WorkoutLog/81914141-a017-4470-9e9a-c14216fbf0e6" + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + } + } +} \ No newline at end of file diff --git a/Exercise/bench-press.json b/Exercise/bench-press.json new file mode 100644 index 0000000..ea480db --- /dev/null +++ b/Exercise/bench-press.json @@ -0,0 +1,31 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "Exercise", + "module": "../exercise" + } + }, + "type": "card", + "attributes": { + "name": "Bench Press", + "notes": "Keep back flat on bench. Control the descent.", + "cardInfo": { + "name": "Bench Press", + "notes": null, + "summary": "Classic chest exercise with barbell", + "cardThumbnailURL": null + }, + "equipment": "Barbell", + "muscleGroup": "Chest", + "personalRecord": 100 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + } + } + } +} \ No newline at end of file diff --git a/Exercise/pull-up.json b/Exercise/pull-up.json new file mode 100644 index 0000000..dade3ea --- /dev/null +++ b/Exercise/pull-up.json @@ -0,0 +1,31 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "Exercise", + "module": "../exercise" + } + }, + "type": "card", + "attributes": { + "name": "Pull-Up", + "notes": "Full range of motion. Dead hang to chin over bar.", + "cardInfo": { + "name": "Pull-Up", + "notes": null, + "summary": "Bodyweight back and bicep exercise", + "cardThumbnailURL": null + }, + "equipment": "Pull-up Bar", + "muscleGroup": "Back", + "personalRecord": 0 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + } + } + } +} \ No newline at end of file diff --git a/Exercise/squat.json b/Exercise/squat.json new file mode 100644 index 0000000..f422636 --- /dev/null +++ b/Exercise/squat.json @@ -0,0 +1,31 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "Exercise", + "module": "../exercise" + } + }, + "type": "card", + "attributes": { + "name": "Back Squat", + "notes": "Keep chest up and knees tracking over toes.", + "cardInfo": { + "name": "Back Squat", + "notes": null, + "summary": "Compound leg movement with barbell", + "cardThumbnailURL": null + }, + "equipment": "Barbell", + "muscleGroup": "Legs", + "personalRecord": 130 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + } + } + } +} \ No newline at end of file diff --git a/Spec/05ef1d53-7fdc-4fbb-819a-b8f9eac8d307.json b/Spec/05ef1d53-7fdc-4fbb-819a-b8f9eac8d307.json new file mode 100644 index 0000000..7c5224e --- /dev/null +++ b/Spec/05ef1d53-7fdc-4fbb-819a-b8f9eac8d307.json @@ -0,0 +1,40 @@ +{ + "data": { + "type": "card", + "attributes": { + "readMe": null, + "ref": { + "module": "../exercise", + "name": "Exercise" + }, + "specType": "card", + "containedExamples": [], + "cardTitle": "Exercise", + "cardDescription": null, + "cardInfo": { + "name": null, + "summary": null, + "cardThumbnailURL": null, + "notes": null + } + }, + "relationships": { + "linkedExamples": { + "links": { + "self": null + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + }, + "meta": { + "adoptsFrom": { + "module": "https://cardstack.com/base/spec", + "name": "Spec" + } + } + } +} \ No newline at end of file diff --git a/Spec/599e05ef-1d53-4fdc-9fbb-019ab8f9eac8.json b/Spec/599e05ef-1d53-4fdc-9fbb-019ab8f9eac8.json new file mode 100644 index 0000000..4ff5fef --- /dev/null +++ b/Spec/599e05ef-1d53-4fdc-9fbb-019ab8f9eac8.json @@ -0,0 +1,40 @@ +{ + "data": { + "type": "card", + "attributes": { + "readMe": null, + "ref": { + "module": "../workout-session", + "name": "WorkoutSession" + }, + "specType": "card", + "containedExamples": [], + "cardTitle": "Workout Session", + "cardDescription": null, + "cardInfo": { + "name": null, + "summary": null, + "cardThumbnailURL": null, + "notes": null + } + }, + "relationships": { + "linkedExamples": { + "links": { + "self": null + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + }, + "meta": { + "adoptsFrom": { + "module": "https://cardstack.com/base/spec", + "name": "Spec" + } + } + } +} \ No newline at end of file diff --git a/Spec/84599e05-ef1d-437f-9c1f-bb019ab8f9ea.json b/Spec/84599e05-ef1d-437f-9c1f-bb019ab8f9ea.json new file mode 100644 index 0000000..11834fb --- /dev/null +++ b/Spec/84599e05-ef1d-437f-9c1f-bb019ab8f9ea.json @@ -0,0 +1,40 @@ +{ + "data": { + "type": "card", + "attributes": { + "readMe": null, + "ref": { + "module": "../exercise", + "name": "MuscleGroupField" + }, + "specType": "field", + "containedExamples": [], + "cardTitle": "Muscle Group", + "cardDescription": null, + "cardInfo": { + "name": null, + "summary": null, + "cardThumbnailURL": null, + "notes": null + } + }, + "relationships": { + "linkedExamples": { + "links": { + "self": null + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + }, + "meta": { + "adoptsFrom": { + "module": "https://cardstack.com/base/spec", + "name": "Spec" + } + } + } +} \ No newline at end of file diff --git a/Spec/9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3.json b/Spec/9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3.json new file mode 100644 index 0000000..c2b27c8 --- /dev/null +++ b/Spec/9e05ef1d-537f-4c1f-bb01-9ab8f9eac8d3.json @@ -0,0 +1,40 @@ +{ + "data": { + "type": "card", + "attributes": { + "readMe": null, + "ref": { + "module": "../exercise", + "name": "ExerciseSetField" + }, + "specType": "field", + "containedExamples": [], + "cardTitle": "Exercise Set", + "cardDescription": null, + "cardInfo": { + "name": null, + "summary": null, + "cardThumbnailURL": null, + "notes": null + } + }, + "relationships": { + "linkedExamples": { + "links": { + "self": null + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + }, + "meta": { + "adoptsFrom": { + "module": "https://cardstack.com/base/spec", + "name": "Spec" + } + } + } +} \ No newline at end of file diff --git a/Spec/ca84599e-05ef-4d53-bfdc-1fbb019ab8f9.json b/Spec/ca84599e-05ef-4d53-bfdc-1fbb019ab8f9.json new file mode 100644 index 0000000..65ce867 --- /dev/null +++ b/Spec/ca84599e-05ef-4d53-bfdc-1fbb019ab8f9.json @@ -0,0 +1,40 @@ +{ + "data": { + "type": "card", + "attributes": { + "readMe": null, + "ref": { + "module": "../workout-session", + "name": "WorkoutExerciseField" + }, + "specType": "field", + "containedExamples": [], + "cardTitle": "Workout Exercise", + "cardDescription": null, + "cardInfo": { + "name": null, + "summary": null, + "cardThumbnailURL": null, + "notes": null + } + }, + "relationships": { + "linkedExamples": { + "links": { + "self": null + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + } + }, + "meta": { + "adoptsFrom": { + "module": "https://cardstack.com/base/spec", + "name": "Spec" + } + } + } +} \ No newline at end of file diff --git a/WorkoutLog/81914141-a017-4470-9e9a-c14216fbf0e6.json b/WorkoutLog/81914141-a017-4470-9e9a-c14216fbf0e6.json new file mode 100644 index 0000000..9209c78 --- /dev/null +++ b/WorkoutLog/81914141-a017-4470-9e9a-c14216fbf0e6.json @@ -0,0 +1,57 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "WorkoutLog", + "module": "../workout-log" + } + }, + "type": "card", + "attributes": { + "logName": "Richard's Workout Log", + "cardInfo": { + "name": "Richard's Workout Log", + "notes": null, + "summary": "Tracking push, pull and leg sessions", + "cardThumbnailURL": null + } + }, + "relationships": { + "sessions.0": { + "links": { + "self": "../WorkoutSession/push-day" + } + }, + "sessions.1": { + "links": { + "self": "../WorkoutSession/leg-day" + } + }, + "sessions.2": { + "links": { + "self": "../WorkoutSession/pull-day" + } + }, + "cardInfo.theme": { + "links": { + "self": null + } + }, + "exerciseLibrary.0": { + "links": { + "self": "../Exercise/bench-press" + } + }, + "exerciseLibrary.1": { + "links": { + "self": "../Exercise/squat" + } + }, + "exerciseLibrary.2": { + "links": { + "self": "../Exercise/pull-up" + } + } + } + } +} \ No newline at end of file diff --git a/WorkoutSession/leg-day.json b/WorkoutSession/leg-day.json new file mode 100644 index 0000000..fc32763 --- /dev/null +++ b/WorkoutSession/leg-day.json @@ -0,0 +1,55 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "WorkoutSession", + "module": "../workout-session" + } + }, + "type": "card", + "attributes": { + "date": "2026-04-03", + "title": "Leg Day", + "rating": 4, + "cardInfo": { + "name": "Leg Day", + "notes": null, + "summary": "Squat focused lower body session", + "cardThumbnailURL": null + }, + "exercises": [ + { + "sets": 5, + "reps": 5, + "weight": 120, + "notes": "New PR attempt" + }, + { + "sets": 3, + "reps": 10, + "weight": 80, + "notes": "Pause at bottom" + } + ], + "overallNotes": "Legs were on fire. Squats felt heavy but form was solid.", + "durationMinutes": 75 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + }, + "exercises.0.exercise": { + "links": { + "self": "../Exercise/squat" + } + }, + "exercises.1.exercise": { + "links": { + "self": "../Exercise/squat" + } + } + } + } +} \ No newline at end of file diff --git a/WorkoutSession/pull-day.json b/WorkoutSession/pull-day.json new file mode 100644 index 0000000..589aeff --- /dev/null +++ b/WorkoutSession/pull-day.json @@ -0,0 +1,55 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "WorkoutSession", + "module": "../workout-session" + } + }, + "type": "card", + "attributes": { + "date": "2026-04-05", + "title": "Pull Day", + "rating": 4, + "cardInfo": { + "name": "Pull Day", + "notes": null, + "summary": "Back and biceps session with pull-ups", + "cardThumbnailURL": null + }, + "exercises": [ + { + "sets": 4, + "reps": 8, + "weight": 0, + "notes": "Bodyweight only" + }, + { + "sets": 3, + "reps": 10, + "weight": 0, + "notes": "Wide grip" + } + ], + "overallNotes": "Back pump was intense. Need to work on grip strength.", + "durationMinutes": 55 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + }, + "exercises.0.exercise": { + "links": { + "self": "../Exercise/pull-up" + } + }, + "exercises.1.exercise": { + "links": { + "self": "../Exercise/pull-up" + } + } + } + } +} \ No newline at end of file diff --git a/WorkoutSession/push-day.json b/WorkoutSession/push-day.json new file mode 100644 index 0000000..814cd77 --- /dev/null +++ b/WorkoutSession/push-day.json @@ -0,0 +1,55 @@ +{ + "data": { + "meta": { + "adoptsFrom": { + "name": "WorkoutSession", + "module": "../workout-session" + } + }, + "type": "card", + "attributes": { + "date": "2026-04-01", + "title": "Push Day", + "rating": 5, + "cardInfo": { + "name": "Push Day", + "notes": null, + "summary": "Chest and triceps session", + "cardThumbnailURL": null + }, + "exercises": [ + { + "sets": 4, + "reps": 8, + "weight": 90, + "notes": "Felt strong today" + }, + { + "sets": 3, + "reps": 12, + "weight": 20, + "notes": "Superset with tricep dips" + } + ], + "overallNotes": "Great energy today. Increased bench press weight by 5kg.", + "durationMinutes": 60 + }, + "relationships": { + "cardInfo.theme": { + "links": { + "self": null + } + }, + "exercises.0.exercise": { + "links": { + "self": "../Exercise/bench-press" + } + }, + "exercises.1.exercise": { + "links": { + "self": "../Exercise/bench-press" + } + } + } + } +} \ No newline at end of file diff --git a/exercise.gts b/exercise.gts new file mode 100644 index 0000000..79a4049 --- /dev/null +++ b/exercise.gts @@ -0,0 +1,115 @@ +// ═══ [EDIT TRACKING: ON] Mark all changes with ⁿ ═══ +import { + CardDef, + FieldDef, + field, + contains, + Component, +} from 'https://cardstack.com/base/card-api'; +import StringField from 'https://cardstack.com/base/string'; +import NumberField from 'https://cardstack.com/base/number'; +import TextAreaField from 'https://cardstack.com/base/text-area'; + +export class MuscleGroupField extends FieldDef { + static displayName = 'Muscle Group'; + @field name = contains(StringField); + + static embedded = class Embedded extends Component { + + }; +} + +export class ExerciseSetField extends FieldDef { + static displayName = 'Exercise Set'; + @field sets = contains(NumberField); + @field reps = contains(NumberField); + @field weight = contains(NumberField); + @field notes = contains(StringField); + + static embedded = class Embedded extends Component { + + }; +} + +export class Exercise extends CardDef { + static displayName = 'Exercise'; + @field name = contains(StringField); + @field muscleGroup = contains(StringField); + @field equipment = contains(StringField); + @field personalRecord = contains(NumberField); + @field notes = contains(TextAreaField); + + static isolated = class Isolated extends Component { + + }; + + static embedded = class Embedded extends Component { + + }; + + static fitted = class Fitted extends Component { + + }; +} diff --git a/workout-log.gts b/workout-log.gts new file mode 100644 index 0000000..4876fc8 --- /dev/null +++ b/workout-log.gts @@ -0,0 +1,179 @@ +// ═══ [EDIT TRACKING: ON] Mark all changes with ⁿ ═══ +import { + CardDef, + field, + contains, + linksToMany, + Component, +} from 'https://cardstack.com/base/card-api'; +import StringField from 'https://cardstack.com/base/string'; +import { Exercise } from './exercise'; +import { WorkoutSession } from './workout-session'; + +export class WorkoutLog extends CardDef { + static displayName = 'Workout Log'; + @field logName = contains(StringField); + @field sessions = linksToMany(() => WorkoutSession); + @field exerciseLibrary = linksToMany(Exercise); + + static isolated = class Isolated extends Component { + + }; + + static embedded = class Embedded extends Component { + + }; + + static fitted = class Fitted extends Component { + + }; +} diff --git a/workout-session.gts b/workout-session.gts new file mode 100644 index 0000000..0471544 --- /dev/null +++ b/workout-session.gts @@ -0,0 +1,137 @@ +// ═══ [EDIT TRACKING: ON] Mark all changes with ⁿ ═══ +import { + CardDef, + FieldDef, + field, + contains, + containsMany, + linksTo, + Component, +} from 'https://cardstack.com/base/card-api'; +import StringField from 'https://cardstack.com/base/string'; +import NumberField from 'https://cardstack.com/base/number'; +import DateField from 'https://cardstack.com/base/date'; +import TextAreaField from 'https://cardstack.com/base/text-area'; +import { Exercise } from './exercise'; + +export class WorkoutExerciseField extends FieldDef { + static displayName = 'Workout Exercise'; + @field exercise = linksTo(Exercise); + @field sets = contains(NumberField); + @field reps = contains(NumberField); + @field weight = contains(NumberField); + @field notes = contains(StringField); + + static embedded = class Embedded extends Component { + + }; +} + +export class WorkoutSession extends CardDef { + static displayName = 'Workout Session'; + @field title = contains(StringField); + @field date = contains(DateField); + @field durationMinutes = contains(NumberField); + @field exercises = containsMany(WorkoutExerciseField); + @field overallNotes = contains(TextAreaField); + @field rating = contains(NumberField); + + static isolated = class Isolated extends Component { + + }; + + static embedded = class Embedded extends Component { + + }; + + static fitted = class Fitted extends Component { + + }; +}