[Pharo] Personal fitness tracker web app.
Rename "Tabs" to "Pages".
Changed files
- src/MyFitnessTracker/MFTLearnPage.class.st
- src/MyFitnessTracker/MFTLearnTab.class.st
- src/MyFitnessTracker/MFTLoginRegisterLogoutComponent.class.st
- src/MyFitnessTracker/MFTProfilePage.class.st
- src/MyFitnessTracker/MFTProfileTab.class.st
- src/MyFitnessTracker/MFTPublicHomepageTab.class.st
- src/MyFitnessTracker/MFTPublicLandingPage.class.st
- src/MyFitnessTracker/MFTSession.class.st
- src/MyFitnessTracker/MFTUserHomepageTab.class.st
- src/MyFitnessTracker/MFTUserLandingPage.class.st
- src/MyFitnessTracker/MFTWeightsListPage.class.st
- src/MyFitnessTracker/MFTWeightsListTab.class.st
- src/MyFitnessTracker/MFTWorkoutsListPage.class.st
- src/MyFitnessTracker/MFTWorkoutsListTab.class.st
src/MyFitnessTracker/MFTLearnPage.class.st
@@ -0,0 +1,22 @@
1
Added:
Class {
2
Added:
#name : #MFTLearnPage,
3
Added:
#superclass : #MFTPage,
4
Added:
#instVars : [
5
Added:
'articles'
6
Added:
],
7
Added:
#category : #'MyFitnessTracker-Components'
8
Added:
}
9
Added:
10
Added:
{ #category : #initialization }
11
Added:
MFTLearnPage >> initialize [
12
Added:
13
Added:
super initialize.
14
Added:
title := 'learn'.
15
Added:
articles := Array with: MFTMusclesArticle new
16
Added:
]
17
Added:
18
Added:
{ #category : #rendering }
19
Added:
MFTLearnPage >> renderContentOn: html [
20
Added:
21
Added:
articles do: [ :each | html render: each ]
22
Added:
]
src/MyFitnessTracker/MFTLearnTab.class.st
@@ -1,22 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : #MFTLearnTab,
3
Removed:
#superclass : #MFTPage,
4
Removed:
#instVars : [
5
Removed:
'articles'
6
Removed:
],
7
Removed:
#category : #'MyFitnessTracker-Components'
8
Removed:
}
9
Removed:
10
Removed:
{ #category : #initialization }
11
Removed:
MFTLearnTab >> initialize [
12
Removed:
13
Removed:
super initialize.
14
Removed:
title := 'learn'.
15
Removed:
articles := Array with: MFTMusclesArticle new
16
Removed:
]
17
Removed:
18
Removed:
{ #category : #rendering }
19
Removed:
MFTLearnTab >> renderContentOn: html [
20
Removed:
21
Removed:
articles do: [ :each | html render: each ]
22
Removed:
]
src/MyFitnessTracker/MFTLoginRegisterLogoutComponent.class.st
@@ -49,7 +49,7 @@
49
49
self session db updateLoginDateAndTime: aMFTUser.
50
50
self session user: aMFTUser.
51
51
self session user isLoggedIn: true.
52
Removed:
self session mainPages at: 1 put: MFTUserHomepageTab new
52
Added:
self session mainPages at: 1 put: MFTUserLandingPage new
53
53
]
54
54
55
55
{ #category : #'as yet unclassified' }
src/MyFitnessTracker/MFTProfilePage.class.st
@@ -0,0 +1,18 @@
1
Added:
Class {
2
Added:
#name : #MFTProfilePage,
3
Added:
#superclass : #MFTPage,
4
Added:
#category : #'MyFitnessTracker-Components'
5
Added:
}
6
Added:
7
Added:
{ #category : #initialization }
8
Added:
MFTProfilePage >> initialize [
9
Added:
10
Added:
super initialize.
11
Added:
title := 'profile'
12
Added:
]
13
Added:
14
Added:
{ #category : #rendering }
15
Added:
MFTProfilePage >> renderContentOn: html [
16
Added:
17
Added:
html container: [ html text: 'Welcome!' ]
18
Added:
]
src/MyFitnessTracker/MFTProfileTab.class.st
@@ -1,18 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : #MFTProfileTab,
3
Removed:
#superclass : #MFTPage,
4
Removed:
#category : #'MyFitnessTracker-Components'
5
Removed:
}
6
Removed:
7
Removed:
{ #category : #initialization }
8
Removed:
MFTProfileTab >> initialize [
9
Removed:
10
Removed:
super initialize.
11
Removed:
title := 'profile'
12
Removed:
]
13
Removed:
14
Removed:
{ #category : #rendering }
15
Removed:
MFTProfileTab >> renderContentOn: html [
16
Removed:
17
Removed:
html container: [ html text: 'Welcome!' ]
18
Removed:
]
src/MyFitnessTracker/MFTPublicHomepageTab.class.st
@@ -1,55 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : #MFTPublicHomepageTab,
3
Removed:
#superclass : #MFTPage,
4
Removed:
#category : #'MyFitnessTracker-Components'
5
Removed:
}
6
Removed:
7
Removed:
{ #category : #initialization }
8
Removed:
MFTPublicHomepageTab >> initialize [
9
Removed:
10
Removed:
super initialize.
11
Removed:
title := 'home'
12
Removed:
]
13
Removed:
14
Removed:
{ #category : #rendering }
15
Removed:
MFTPublicHomepageTab >> renderContentOn: html [
16
Removed:
17
Removed:
html container: [
18
Removed:
self renderMainCardOn: html.
19
Removed:
self renderPromisesCardOn: html ]
20
Removed:
]
21
Removed:
22
Removed:
{ #category : #rendering }
23
Removed:
MFTPublicHomepageTab >> renderMainCardOn: html [
24
Removed:
25
Removed:
html card: [
26
Removed:
html jumbotron
27
Removed:
class: 'p-3 bg-light';
28
Removed:
with: [
29
Removed:
html displayHeading
30
Removed:
level: 1;
31
Removed:
with: 'Welcome to My Fitness Tracker!'.
32
Removed:
html big textMuted with: 'Free Software never looked so fit.'.
33
Removed:
html form: [ "TODO"
34
Removed:
html formButton
35
Removed:
bePrimary;
36
Removed:
beLarge;
37
Removed:
class: 'mt-3';
38
Removed:
callback: [
39
Removed:
self session activePage: (self session mainPages at: 2) ];
40
Removed:
with: 'Log a workout' ] ] ]
41
Removed:
]
42
Removed:
43
Removed:
{ #category : #rendering }
44
Removed:
MFTPublicHomepageTab >> renderPromisesCardOn: html [
45
Removed:
46
Removed:
html card
47
Removed:
marginTopAndBottom: 3;
48
Removed:
with: [
49
Removed:
html cardHeader: 'We promise you...'.
50
Removed:
html cardBody: [
51
Removed:
html unorderedList: [
52
Removed:
html listItem: 'All features shall always be entirely free.'.
53
Removed:
html listItem: 'No user data shall ever be sold.'.
54
Removed:
html listItem: '.' ] ] ]
55
Removed:
]
src/MyFitnessTracker/MFTPublicLandingPage.class.st
@@ -0,0 +1,55 @@
1
Added:
Class {
2
Added:
#name : #MFTPublicLandingPage,
3
Added:
#superclass : #MFTPage,
4
Added:
#category : #'MyFitnessTracker-Components'
5
Added:
}
6
Added:
7
Added:
{ #category : #initialization }
8
Added:
MFTPublicLandingPage >> initialize [
9
Added:
10
Added:
super initialize.
11
Added:
title := 'home'
12
Added:
]
13
Added:
14
Added:
{ #category : #rendering }
15
Added:
MFTPublicLandingPage >> renderContentOn: html [
16
Added:
17
Added:
html container: [
18
Added:
self renderMainCardOn: html.
19
Added:
self renderPromisesCardOn: html ]
20
Added:
]
21
Added:
22
Added:
{ #category : #rendering }
23
Added:
MFTPublicLandingPage >> renderMainCardOn: html [
24
Added:
25
Added:
html card: [
26
Added:
html jumbotron
27
Added:
class: 'p-3 bg-light';
28
Added:
with: [
29
Added:
html displayHeading
30
Added:
level: 1;
31
Added:
with: 'Welcome to My Fitness Tracker!'.
32
Added:
html big textMuted with: 'Free Software never looked so fit.'.
33
Added:
html form: [ "TODO"
34
Added:
html formButton
35
Added:
bePrimary;
36
Added:
beLarge;
37
Added:
class: 'mt-3';
38
Added:
callback: [
39
Added:
self session activePage: (self session mainPages at: 2) ];
40
Added:
with: 'Log a workout' ] ] ]
41
Added:
]
42
Added:
43
Added:
{ #category : #rendering }
44
Added:
MFTPublicLandingPage >> renderPromisesCardOn: html [
45
Added:
46
Added:
html card
47
Added:
marginTopAndBottom: 3;
48
Added:
with: [
49
Added:
html cardHeader: 'We promise you...'.
50
Added:
html cardBody: [
51
Added:
html unorderedList: [
52
Added:
html listItem: 'All features shall always be entirely free.'.
53
Added:
html listItem: 'No user data shall ever be sold.'.
54
Added:
html listItem: '.' ] ] ]
55
Added:
]
src/MyFitnessTracker/MFTSession.class.st
@@ -42,11 +42,11 @@
42
42
user := MFTUser new.
43
43
mainNavigationBar := MFTMainNavigationBarComponent new.
44
44
mainPages := OrderedCollection newFromArray: {
45
Removed:
MFTPublicHomepageTab new.
46
Removed:
MFTWorkoutsListTab placeholder.
47
Removed:
MFTWeightsListTab new.
48
Removed:
MFTLearnTab new.
49
Removed:
MFTProfileTab new }.
45
Added:
MFTPublicLandingPage new.
46
Added:
MFTWorkoutsListPage placeholder.
47
Added:
MFTWeightsListPage new.
48
Added:
MFTLearnPage new.
49
Added:
MFTProfilePage new }.
50
50
activePage := mainPages first
51
51
]
52
52
src/MyFitnessTracker/MFTUserHomepageTab.class.st
@@ -1,25 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : #MFTUserHomepageTab,
3
Removed:
#superclass : #MFTPage,
4
Removed:
#category : #'MyFitnessTracker-Components'
5
Removed:
}
6
Removed:
7
Removed:
{ #category : #initialization }
8
Removed:
MFTUserHomepageTab >> initialize [
9
Removed:
10
Removed:
super initialize.
11
Removed:
title := self session user ifNotNil: [
12
Removed:
self session user username capitalized ]
13
Removed:
]
14
Removed:
15
Removed:
{ #category : #rendering }
16
Removed:
MFTUserHomepageTab >> renderContentOn: html [
17
Removed:
18
Removed:
html container: [
19
Removed:
html displayHeading
20
Removed:
level: 1;
21
Removed:
with: 'Welcome, ' , self session user username , '!'.
22
Removed:
html unorderedList: [
23
Removed:
(self session db selectAll: 'prospects') do: [ :prospect |
24
Removed:
html listItem: prospect ] ] ]
25
Removed:
]
src/MyFitnessTracker/MFTUserLandingPage.class.st
@@ -0,0 +1,25 @@
1
Added:
Class {
2
Added:
#name : #MFTUserLandingPage,
3
Added:
#superclass : #MFTPage,
4
Added:
#category : #'MyFitnessTracker-Components'
5
Added:
}
6
Added:
7
Added:
{ #category : #initialization }
8
Added:
MFTUserLandingPage >> initialize [
9
Added:
10
Added:
super initialize.
11
Added:
title := self session user ifNotNil: [
12
Added:
self session user username capitalized ]
13
Added:
]
14
Added:
15
Added:
{ #category : #rendering }
16
Added:
MFTUserLandingPage >> renderContentOn: html [
17
Added:
18
Added:
html container: [
19
Added:
html displayHeading
20
Added:
level: 1;
21
Added:
with: 'Welcome, ' , self session user username , '!'.
22
Added:
html unorderedList: [
23
Added:
(self session db selectAll: 'prospects') do: [ :prospect |
24
Added:
html listItem: prospect ] ] ]
25
Added:
]
src/MyFitnessTracker/MFTWeightsListPage.class.st
@@ -0,0 +1,58 @@
1
Added:
Class {
2
Added:
#name : #MFTWeightsListPage,
3
Added:
#superclass : #MFTPage,
4
Added:
#instVars : [
5
Added:
'weights'
6
Added:
],
7
Added:
#category : #'MyFitnessTracker-Components'
8
Added:
}
9
Added:
10
Added:
{ #category : #rendering }
11
Added:
MFTWeightsListPage class >> placeholder [
12
Added:
13
Added:
^ self new
14
Added:
weights: {
15
Added:
(MFTWeight value: 90).
16
Added:
(MFTWeight value: 100).
17
Added:
(MFTWeight value: 102).
18
Added:
(MFTWeight date: (Date fromString: '01/01/2024') value: 105) };
19
Added:
yourself
20
Added:
]
21
Added:
22
Added:
{ #category : #initialization }
23
Added:
MFTWeightsListPage >> initialize [
24
Added:
25
Added:
super initialize.
26
Added:
title := 'weight'.
27
Added:
weights := OrderedCollection new
28
Added:
]
29
Added:
30
Added:
{ #category : #rendering }
31
Added:
MFTWeightsListPage >> renderContentOn: html [
32
Added:
33
Added:
html container with: [
34
Added:
html table
35
Added:
class: 'table table-striped';
36
Added:
with: [
37
Added:
weights do: [ :each |
38
Added:
html tableRow: [
39
Added:
html
40
Added:
tableData: each date ddmmyyyy;
41
Added:
tableData: each value ] ] ].
42
Added:
html form: [
43
Added:
html buttonGroup: [
44
Added:
html formButton
45
Added:
bePrimary;
46
Added:
callback: [ "Edit the weight" ];
47
Added:
with: 'Edit'.
48
Added:
html formButton
49
Added:
beDanger;
50
Added:
callback: [ nil ];
51
Added:
with: 'Delete' ] ] ]
52
Added:
]
53
Added:
54
Added:
{ #category : #accessing }
55
Added:
MFTWeightsListPage >> weights: aWeight [
56
Added:
57
Added:
weights := aWeight
58
Added:
]
src/MyFitnessTracker/MFTWeightsListTab.class.st
@@ -1,58 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : #MFTWeightsListTab,
3
Removed:
#superclass : #MFTPage,
4
Removed:
#instVars : [
5
Removed:
'weights'
6
Removed:
],
7
Removed:
#category : #'MyFitnessTracker-Components'
8
Removed:
}
9
Removed:
10
Removed:
{ #category : #rendering }
11
Removed:
MFTWeightsListTab class >> placeholder [
12
Removed:
13
Removed:
^ self new
14
Removed:
weights: {
15
Removed:
(MFTWeight value: 90).
16
Removed:
(MFTWeight value: 100).
17
Removed:
(MFTWeight value: 102).
18
Removed:
(MFTWeight date: (Date fromString: '01/01/2024') value: 105) };
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : #initialization }
23
Removed:
MFTWeightsListTab >> initialize [
24
Removed:
25
Removed:
super initialize.
26
Removed:
title := 'weight'.
27
Removed:
weights := OrderedCollection new
28
Removed:
]
29
Removed:
30
Removed:
{ #category : #rendering }
31
Removed:
MFTWeightsListTab >> renderContentOn: html [
32
Removed:
33
Removed:
html container with: [
34
Removed:
html table
35
Removed:
class: 'table table-striped';
36
Removed:
with: [
37
Removed:
weights do: [ :each |
38
Removed:
html tableRow: [
39
Removed:
html
40
Removed:
tableData: each date ddmmyyyy;
41
Removed:
tableData: each value ] ] ].
42
Removed:
html form: [
43
Removed:
html buttonGroup: [
44
Removed:
html formButton
45
Removed:
bePrimary;
46
Removed:
callback: [ "Edit the weight" ];
47
Removed:
with: 'Edit'.
48
Removed:
html formButton
49
Removed:
beDanger;
50
Removed:
callback: [ nil ];
51
Removed:
with: 'Delete' ] ] ]
52
Removed:
]
53
Removed:
54
Removed:
{ #category : #accessing }
55
Removed:
MFTWeightsListTab >> weights: aWeight [
56
Removed:
57
Removed:
weights := aWeight
58
Removed:
]
src/MyFitnessTracker/MFTWorkoutsListPage.class.st
@@ -0,0 +1,199 @@
1
Added:
"
2
Added:
I represent the list of user workouts retrieved from the database.
3
Added:
4
Added:
I am rendered by `MFTRootComponent` when the user views their workouts. I know about user workouts retrieved from the database.
5
Added:
6
Added:
* Collaborators
7
Added:
8
Added:
- I work with lists of `MFTWorkout`s.
9
Added:
- I might work with `MFTExercise class`canonical exercises once the variable is implemented.
10
Added:
11
Added:
Public API and Key Messages
12
Added:
13
Added:
- message one
14
Added:
- message two
15
Added:
- (for bonus points) how to create instances.
16
Added:
17
Added:
One simple example is simply gorgeous.
18
Added:
19
Added:
Internal Representation and Key Implementation Points.
20
Added:
21
Added:
22
Added:
Implementation Points
23
Added:
"
24
Added:
Class {
25
Added:
#name : #MFTWorkoutsListPage,
26
Added:
#superclass : #MFTPage,
27
Added:
#instVars : [
28
Added:
'workouts'
29
Added:
],
30
Added:
#category : #'MyFitnessTracker-Components'
31
Added:
}
32
Added:
33
Added:
{ #category : #rendering }
34
Added:
MFTWorkoutsListPage class >> placeholder [
35
Added:
"Return a placeholder list of three workouts."
36
Added:
37
Added:
| placeholderWorkouts workout1 workout2 workout3 |
38
Added:
placeholderWorkouts := OrderedCollection new.
39
Added:
workout1 := MFTWorkout new
40
Added:
primaryMuscle: MFTMuscleGroup chest;
41
Added:
exercises: (OrderedCollection
42
Added:
with: (MFTExercise cableRow sets: {
43
Added:
(MFTSet reps: 8 rpe: 6).
44
Added:
(MFTSet reps: 6 rpe: 8).
45
Added:
(MFTSet reps: 6 rpe: 10).
46
Added:
(MFTSet reps: 15 rpe: 4) })
47
Added:
with: (MFTExercise shoulderPressDumbell sets: {
48
Added:
(MFTSet reps: 10 rpe: 6).
49
Added:
(MFTSet reps: 6 rpe: 8).
50
Added:
(MFTSet reps: 6 rpe: 10) })
51
Added:
with: (MFTExercise declineBenchPress sets: {
52
Added:
(MFTSet reps: 5 rpe: 6).
53
Added:
(MFTSet reps: 6 rpe: 8).
54
Added:
(MFTSet reps: 8 rpe: 10) })).
55
Added:
workout2 := MFTWorkout new
56
Added:
date: (Date fromString: '04/20/2023');
57
Added:
exercises: (OrderedCollection
58
Added:
with: (MFTExercise cableRow sets: {
59
Added:
(MFTSet reps: 8 rpe: 6).
60
Added:
(MFTSet reps: 6 rpe: 8).
61
Added:
(MFTSet reps: 6 rpe: 10).
62
Added:
(MFTSet reps: 15 rpe: 4) })
63
Added:
with: MFTExercise shoulderPressDumbell
64
Added:
with: MFTExercise declineBenchPress).
65
Added:
workout3 := MFTWorkout new
66
Added:
date: (Date fromString: '01/01/2023');
67
Added:
addExercise: MFTExercise cableRow;
68
Added:
addExercise: MFTExercise shoulderPressDumbell;
69
Added:
addExercise: MFTExercise declineBenchPress.
70
Added:
placeholderWorkouts
71
Added:
add: workout1;
72
Added:
add: workout2;
73
Added:
add: workout3.
74
Added:
75
Added:
^ self new
76
Added:
workouts: placeholderWorkouts;
77
Added:
yourself
78
Added:
]
79
Added:
80
Added:
{ #category : #adding }
81
Added:
MFTWorkoutsListPage >> addWorkout [
82
Added:
83
Added:
| newWorkout |
84
Added:
newWorkout := self call: MFTWorkoutDialog new.
85
Added:
newWorkout ifNotNil: [ workouts addFirst: newWorkout ]
86
Added:
]
87
Added:
88
Added:
{ #category : #hooks }
89
Added:
MFTWorkoutsListPage >> children [
90
Added:
91
Added:
^ workouts
92
Added:
]
93
Added:
94
Added:
{ #category : #accessing }
95
Added:
MFTWorkoutsListPage >> confirmDeleteAt: i [
96
Added:
97
Added:
| workout confirmed |
98
Added:
workout := workouts at: i.
99
Added:
confirmed := self call: (MFTConfirmDialog delete: workout).
100
Added:
confirmed ifTrue: [ workouts removeAt: i ]
101
Added:
]
102
Added:
103
Added:
{ #category : #'as yet unclassified' }
104
Added:
MFTWorkoutsListPage >> editWorkoutAt: i [
105
Added:
106
Added:
| oldWorkout newWorkout |
107
Added:
oldWorkout := workouts at: i.
108
Added:
newWorkout := self call: (MFTWorkoutDialog edit: oldWorkout).
109
Added:
newWorkout ifNotNil: [ workouts at: i put: newWorkout ]
110
Added:
]
111
Added:
112
Added:
{ #category : #initialization }
113
Added:
MFTWorkoutsListPage >> initialize [
114
Added:
115
Added:
super initialize.
116
Added:
title := 'workouts'.
117
Added:
workouts := OrderedCollection new
118
Added:
]
119
Added:
120
Added:
{ #category : #'as yet unclassified' }
121
Added:
MFTWorkoutsListPage >> randomWittyCTA [
122
Added:
123
Added:
| listOfStrings randomString |
124
Added:
listOfStrings := #( 'First time?' 'Get your sweat on!'
125
Added:
'Go go go!' 'Go get ''em, Tiger!' ).
126
Added:
randomString := listOfStrings atRandom.
127
Added:
^ randomString
128
Added:
]
129
Added:
130
Added:
{ #category : #rendering }
131
Added:
MFTWorkoutsListPage >> renderActionsButtonGroupOn: html [
132
Added:
133
Added:
html form: [
134
Added:
html buttonGroup: [
135
Added:
html formButton
136
Added:
bePrimary;
137
Added:
callback: [ self addWorkout ];
138
Added:
with: 'Add workout' ] ]
139
Added:
]
140
Added:
141
Added:
{ #category : #rendering }
142
Added:
MFTWorkoutsListPage >> renderContentOn: html [
143
Added:
144
Added:
workouts sort: [ :a :b | a date > b date ].
145
Added:
html container: [
146
Added:
workouts ifEmpty: [
147
Added:
html jumbotron: [ html heading: self randomWittyCTA ] ].
148
Added:
self renderActionsButtonGroupOn: html.
149
Added:
self renderWorkoutsAsAccordionOn: html ]
150
Added:
]
151
Added:
152
Added:
{ #category : #rendering }
153
Added:
MFTWorkoutsListPage >> renderWorkoutActionsButtonGroup: html at: i [
154
Added:
155
Added:
html form: [
156
Added:
html buttonGroup: [
157
Added:
html formButton
158
Added:
bePrimary;
159
Added:
callback: [ self editWorkoutAt: i ];
160
Added:
with: 'Edit'.
161
Added:
html formButton
162
Added:
beDanger;
163
Added:
callback: [ self confirmDeleteAt: i ];
164
Added:
with: 'Delete' ] ]
165
Added:
]
166
Added:
167
Added:
{ #category : #rendering }
168
Added:
MFTWorkoutsListPage >> renderWorkoutsAsAccordionOn: html [
169
Added:
170
Added:
html accordion
171
Added:
id: 'accordion';
172
Added:
class: 'mt-3';
173
Added:
with: [
174
Added:
workouts doWithIndex: [ :workout :i |
175
Added:
html accordionItem: [
176
Added:
html accordionHeading: [
177
Added:
html accordionButton
178
Added:
dataToggle: 'collapse';
179
Added:
dataTarget: '#collapse' , i asString;
180
Added:
with:
181
Added:
workout date yyyymmdd , (workout primaryMuscle englishName
182
Added:
ifNotEmpty: [
183
Added:
' | ' , workout primaryMuscle englishName asString ]
184
Added:
ifEmpty: [ '' ]) ].
185
Added:
html accordionCollapse
186
Added:
id: 'collapse' , i asString;
187
Added:
class: 'collapse';
188
Added:
dataAttributeAt: 'bs-parent' put: '#accordion';
189
Added:
with: [
190
Added:
html accordionBody with: [
191
Added:
html render: workout.
192
Added:
self renderWorkoutActionsButtonGroup: html at: i ] ] ] ] ]
193
Added:
]
194
Added:
195
Added:
{ #category : #accessing }
196
Added:
MFTWorkoutsListPage >> workouts: aListOfWorkouts [
197
Added:
198
Added:
workouts := aListOfWorkouts
199
Added:
]
src/MyFitnessTracker/MFTWorkoutsListTab.class.st
@@ -1,199 +0,0 @@
1
Removed:
"
2
Removed:
I represent the list of user workouts retrieved from the database.
3
Removed:
4
Removed:
I am rendered by `MFTRootComponent` when the user views their workouts. I know about user workouts retrieved from the database.
5
Removed:
6
Removed:
* Collaborators
7
Removed:
8
Removed:
- I work with lists of `MFTWorkout`s.
9
Removed:
- I might work with `MFTExercise class`canonical exercises once the variable is implemented.
10
Removed:
11
Removed:
Public API and Key Messages
12
Removed:
13
Removed:
- message one
14
Removed:
- message two
15
Removed:
- (for bonus points) how to create instances.
16
Removed:
17
Removed:
One simple example is simply gorgeous.
18
Removed:
19
Removed:
Internal Representation and Key Implementation Points.
20
Removed:
21
Removed:
22
Removed:
Implementation Points
23
Removed:
"
24
Removed:
Class {
25
Removed:
#name : #MFTWorkoutsListTab,
26
Removed:
#superclass : #MFTPage,
27
Removed:
#instVars : [
28
Removed:
'workouts'
29
Removed:
],
30
Removed:
#category : #'MyFitnessTracker-Components'
31
Removed:
}
32
Removed:
33
Removed:
{ #category : #rendering }
34
Removed:
MFTWorkoutsListTab class >> placeholder [
35
Removed:
"Return a placeholder list of three workouts."
36
Removed:
37
Removed:
| placeholderWorkouts workout1 workout2 workout3 |
38
Removed:
placeholderWorkouts := OrderedCollection new.
39
Removed:
workout1 := MFTWorkout new
40
Removed:
primaryMuscle: MFTMuscleGroup chest;
41
Removed:
exercises: (OrderedCollection
42
Removed:
with: (MFTExercise cableRow sets: {
43
Removed:
(MFTSet reps: 8 rpe: 6).
44
Removed:
(MFTSet reps: 6 rpe: 8).
45
Removed:
(MFTSet reps: 6 rpe: 10).
46
Removed:
(MFTSet reps: 15 rpe: 4) })
47
Removed:
with: (MFTExercise shoulderPressDumbell sets: {
48
Removed:
(MFTSet reps: 10 rpe: 6).
49
Removed:
(MFTSet reps: 6 rpe: 8).
50
Removed:
(MFTSet reps: 6 rpe: 10) })
51
Removed:
with: (MFTExercise declineBenchPress sets: {
52
Removed:
(MFTSet reps: 5 rpe: 6).
53
Removed:
(MFTSet reps: 6 rpe: 8).
54
Removed:
(MFTSet reps: 8 rpe: 10) })).
55
Removed:
workout2 := MFTWorkout new
56
Removed:
date: (Date fromString: '04/20/2023');
57
Removed:
exercises: (OrderedCollection
58
Removed:
with: (MFTExercise cableRow sets: {
59
Removed:
(MFTSet reps: 8 rpe: 6).
60
Removed:
(MFTSet reps: 6 rpe: 8).
61
Removed:
(MFTSet reps: 6 rpe: 10).
62
Removed:
(MFTSet reps: 15 rpe: 4) })
63
Removed:
with: MFTExercise shoulderPressDumbell
64
Removed:
with: MFTExercise declineBenchPress).
65
Removed:
workout3 := MFTWorkout new
66
Removed:
date: (Date fromString: '01/01/2023');
67
Removed:
addExercise: MFTExercise cableRow;
68
Removed:
addExercise: MFTExercise shoulderPressDumbell;
69
Removed:
addExercise: MFTExercise declineBenchPress.
70
Removed:
placeholderWorkouts
71
Removed:
add: workout1;
72
Removed:
add: workout2;
73
Removed:
add: workout3.
74
Removed:
75
Removed:
^ self new
76
Removed:
workouts: placeholderWorkouts;
77
Removed:
yourself
78
Removed:
]
79
Removed:
80
Removed:
{ #category : #adding }
81
Removed:
MFTWorkoutsListTab >> addWorkout [
82
Removed:
83
Removed:
| newWorkout |
84
Removed:
newWorkout := self call: MFTWorkoutDialog new.
85
Removed:
newWorkout ifNotNil: [ workouts addFirst: newWorkout ]
86
Removed:
]
87
Removed:
88
Removed:
{ #category : #hooks }
89
Removed:
MFTWorkoutsListTab >> children [
90
Removed:
91
Removed:
^ workouts
92
Removed:
]
93
Removed:
94
Removed:
{ #category : #accessing }
95
Removed:
MFTWorkoutsListTab >> confirmDeleteAt: i [
96
Removed:
97
Removed:
| workout confirmed |
98
Removed:
workout := workouts at: i.
99
Removed:
confirmed := self call: (MFTConfirmDialog delete: workout).
100
Removed:
confirmed ifTrue: [ workouts removeAt: i ]
101
Removed:
]
102
Removed:
103
Removed:
{ #category : #'as yet unclassified' }
104
Removed:
MFTWorkoutsListTab >> editWorkoutAt: i [
105
Removed:
106
Removed:
| oldWorkout newWorkout |
107
Removed:
oldWorkout := workouts at: i.
108
Removed:
newWorkout := self call: (MFTWorkoutDialog edit: oldWorkout).
109
Removed:
newWorkout ifNotNil: [ workouts at: i put: newWorkout ]
110
Removed:
]
111
Removed:
112
Removed:
{ #category : #initialization }
113
Removed:
MFTWorkoutsListTab >> initialize [
114
Removed:
115
Removed:
super initialize.
116
Removed:
title := 'workouts'.
117
Removed:
workouts := OrderedCollection new
118
Removed:
]
119
Removed:
120
Removed:
{ #category : #'as yet unclassified' }
121
Removed:
MFTWorkoutsListTab >> randomWittyCTA [
122
Removed:
123
Removed:
| listOfStrings randomString |
124
Removed:
listOfStrings := #( 'First time?' 'Get your sweat on!'
125
Removed:
'Go go go!' 'Go get ''em, Tiger!' ).
126
Removed:
randomString := listOfStrings atRandom.
127
Removed:
^ randomString
128
Removed:
]
129
Removed:
130
Removed:
{ #category : #rendering }
131
Removed:
MFTWorkoutsListTab >> renderActionsButtonGroupOn: html [
132
Removed:
133
Removed:
html form: [
134
Removed:
html buttonGroup: [
135
Removed:
html formButton
136
Removed:
bePrimary;
137
Removed:
callback: [ self addWorkout ];
138
Removed:
with: 'Add workout' ] ]
139
Removed:
]
140
Removed:
141
Removed:
{ #category : #rendering }
142
Removed:
MFTWorkoutsListTab >> renderContentOn: html [
143
Removed:
144
Removed:
workouts sort: [ :a :b | a date > b date ].
145
Removed:
html container: [
146
Removed:
workouts ifEmpty: [
147
Removed:
html jumbotron: [ html heading: self randomWittyCTA ] ].
148
Removed:
self renderActionsButtonGroupOn: html.
149
Removed:
self renderWorkoutsAsAccordionOn: html ]
150
Removed:
]
151
Removed:
152
Removed:
{ #category : #rendering }
153
Removed:
MFTWorkoutsListTab >> renderWorkoutActionsButtonGroup: html at: i [
154
Removed:
155
Removed:
html form: [
156
Removed:
html buttonGroup: [
157
Removed:
html formButton
158
Removed:
bePrimary;
159
Removed:
callback: [ self editWorkoutAt: i ];
160
Removed:
with: 'Edit'.
161
Removed:
html formButton
162
Removed:
beDanger;
163
Removed:
callback: [ self confirmDeleteAt: i ];
164
Removed:
with: 'Delete' ] ]
165
Removed:
]
166
Removed:
167
Removed:
{ #category : #rendering }
168
Removed:
MFTWorkoutsListTab >> renderWorkoutsAsAccordionOn: html [
169
Removed:
170
Removed:
html accordion
171
Removed:
id: 'accordion';
172
Removed:
class: 'mt-3';
173
Removed:
with: [
174
Removed:
workouts doWithIndex: [ :workout :i |
175
Removed:
html accordionItem: [
176
Removed:
html accordionHeading: [
177
Removed:
html accordionButton
178
Removed:
dataToggle: 'collapse';
179
Removed:
dataTarget: '#collapse' , i asString;
180
Removed:
with:
181
Removed:
workout date yyyymmdd , (workout primaryMuscle englishName
182
Removed:
ifNotEmpty: [
183
Removed:
' | ' , workout primaryMuscle englishName asString ]
184
Removed:
ifEmpty: [ '' ]) ].
185
Removed:
html accordionCollapse
186
Removed:
id: 'collapse' , i asString;
187
Removed:
class: 'collapse';
188
Removed:
dataAttributeAt: 'bs-parent' put: '#accordion';
189
Removed:
with: [
190
Removed:
html accordionBody with: [
191
Removed:
html render: workout.
192
Removed:
self renderWorkoutActionsButtonGroup: html at: i ] ] ] ] ]
193
Removed:
]
194
Removed:
195
Removed:
{ #category : #accessing }
196
Removed:
MFTWorkoutsListTab >> workouts: aListOfWorkouts [
197
Removed:
198
Removed:
workouts := aListOfWorkouts
199
Removed:
]