[Pharo] Personal fitness tracker web app.
Clean-up.
Changed files
- src/MyFitnessTracker/MFTExercise.class.st
- src/MyFitnessTracker/MFTLoginRegisterLogoutComponent.class.st
- src/MyFitnessTracker/MFTMuscle.class.st
- src/MyFitnessTracker/MFTPageManager.class.st
- src/MyFitnessTracker/MFTSQLite3Database.class.st
- src/MyFitnessTracker/MFTUser.class.st
- src/MyFitnessTracker/MFTWeightVsTimeGraph.class.st
- src/MyFitnessTracker/MFTWorkout.class.st
src/MyFitnessTracker/MFTExercise.class.st
@@ -114,6 +114,15 @@
114
114
]
115
115
116
116
{ #category : #exercise }
117
Added:
MFTExercise class >> hammerCurl [
118
Added:
119
Added:
^ self newWithEnglishName
120
Added:
primaryMuscle: MFTMuscle bicepsBrachii;
121
Added:
secondaryMuscles: { MFTMuscleGroup forearm };
122
Added:
yourself
123
Added:
]
124
Added:
125
Added:
{ #category : #exercise }
117
126
MFTExercise class >> latPulldown [
118
127
119
128
^ self newWithEnglishName
@@ -142,17 +151,25 @@
142
151
143
152
{ #category : #'instance creation' }
144
153
MFTExercise class >> newWithEnglishName [
145
Removed:
"I return a MFTMuscle instance for which latinName is set to the calling method selector, as a space-separated string."
154
Added:
"I return a MFTExercise instance for which englishName is set to the calling method selector, as a space-separated string."
146
155
147
156
| exerciseNameFromSender |
148
157
exerciseNameFromSender := (thisContext sender selector splitCamelCase
149
Removed:
collect: [ :word | word asLowercase ])
150
Removed:
joinUsing: ' '.
158
Added:
collect: #asLowercase) joinUsing:
159
Added:
Character space.
151
160
^ self new
152
161
englishName: exerciseNameFromSender;
153
162
yourself
154
163
]
155
164
165
Added:
{ #category : #'instance creation' }
166
Added:
MFTExercise class >> sets: aMFTSetCollection [
167
Added:
168
Added:
^ self new
169
Added:
sets: aMFTSetCollection;
170
Added:
yourself
171
Added:
]
172
Added:
156
173
{ #category : #exercise }
157
174
MFTExercise class >> shoulderPressDumbell [
158
175
@@ -237,9 +254,7 @@
237
254
{ #category : #'as yet unclassified' }
238
255
MFTExercise >> repsBySet [
239
256
240
Removed:
^ (sets collect: #reps)
241
Removed:
ifNotEmpty: [ ^ sets collect: #reps ]
242
Removed:
ifEmpty: [ ^ { 0 } ]
257
Added:
^ (sets collect: #reps) ifEmpty: [ Array with: 0 ]
243
258
]
244
259
245
260
{ #category : #accessing }
src/MyFitnessTracker/MFTLoginRegisterLogoutComponent.class.st
@@ -28,7 +28,8 @@
28
28
aMFTUser passwordHash = passwordHash
29
29
ifTrue: [
30
30
self session login: (MFTUser newFromDictionary: existingUser) ]
31
Removed:
ifFalse: [ self inform: 'Login failed' ]
31
Added:
ifFalse: [
32
Added:
self session pageManager activePage inform: 'Login failed' ]
32
33
]
33
34
34
35
{ #category : #initialization }
@@ -100,14 +101,15 @@
100
101
html passwordInput formControl callback: [ :value |
101
102
user passwordHashFromString: value ] ] ].
102
103
html modalFooter: [
103
Removed:
html formButton
104
Removed:
beSecondary;
105
Removed:
dataDismiss: 'modal';
106
Removed:
with: 'Cancel'.
107
Removed:
html formButton
108
Removed:
bePrimary;
109
Removed:
callback: [ self attemptLogin: user ];
110
Removed:
with: 'Login' ] ] ] ] ]
104
Added:
html buttonGroup: [
105
Added:
html formButton
106
Added:
bePrimary;
107
Added:
callback: [ self attemptLogin: user ];
108
Added:
with: 'Login'.
109
Added:
html formButton
110
Added:
beSecondary;
111
Added:
dataDismiss: 'modal';
112
Added:
with: 'Cancel' ] ] ] ] ] ]
111
113
]
112
114
113
115
{ #category : #rendering }
@@ -149,12 +151,13 @@
149
151
html passwordInput formControl callback: [ :value |
150
152
user passwordHashFromString: value ] ] ].
151
153
html modalFooter: [
152
Removed:
html formButton
153
Removed:
beSecondary;
154
Removed:
dataDismiss: 'modal';
155
Removed:
with: 'Cancel'.
156
Removed:
html formButton
157
Removed:
bePrimary;
158
Removed:
callback: [ MFTSQLite3Database registerNewUser: user ];
159
Removed:
with: 'Register' ] ] ] ] ]
154
Added:
html buttonGroup: [
155
Added:
html formButton
156
Added:
bePrimary;
157
Added:
callback: [ MFTSQLite3Database registerNewUser: user ];
158
Added:
with: 'Register'.
159
Added:
html formButton
160
Added:
beSecondary;
161
Added:
dataDismiss: 'modal';
162
Added:
with: 'Cancel' ] ] ] ] ] ]
160
163
]
src/MyFitnessTracker/MFTMuscle.class.st
@@ -165,7 +165,7 @@
165
165
MFTMuscle class >> latissimusDorsi [
166
166
167
167
^ self newWithLatinName
168
Removed:
englishName: 'Lats';
168
Added:
englishName: 'lats';
169
169
description:
170
170
'Also known as the "lats," these muscles are located in the upper back and are responsible for shoulder adduction and extension.';
171
171
yourself
@@ -177,7 +177,8 @@
177
177
178
178
| muscleNameFromSender |
179
179
muscleNameFromSender := (thisContext sender selector splitCamelCase
180
Removed:
collect: #asLowercase) joinUsing: Character space.
180
Added:
collect: #asLowercase) joinUsing:
181
Added:
Character space.
181
182
^ self new
182
183
latinName: muscleNameFromSender;
183
184
yourself
@@ -205,7 +206,7 @@
205
206
MFTMuscle class >> pectoralisMajor [
206
207
207
208
^ self newWithLatinName
208
Removed:
englishName: 'Pec';
209
Added:
englishName: 'pectoral';
209
210
description:
210
211
'Commonly known as the "pecs," these muscles are in the chest and are responsible for shoulder flexion and adduction.';
211
212
yourself
@@ -317,8 +318,8 @@
317
318
MFTMuscle >> initialize [
318
319
319
320
super initialize.
320
Removed:
englishName := String new.
321
321
latinName := String new.
322
Added:
englishName := String new.
322
323
description := String new
323
324
]
324
325
src/MyFitnessTracker/MFTPageManager.class.st
@@ -81,7 +81,7 @@
81
81
MFTPageManager >> loadUserPages [
82
82
83
83
mainPages do: [ :page | page loadUserData ].
84
Removed:
self activePage: 1
84
Added:
self activePage: #landing
85
85
]
86
86
87
87
{ #category : #accessing }
src/MyFitnessTracker/MFTSQLite3Database.class.st
@@ -144,15 +144,16 @@
144
144
{ #category : #'as yet unclassified' }
145
145
MFTSQLite3Database class >> registerNewUser: aMFTUser [
146
146
147
Removed:
self defaultConnection
148
Removed:
open;
149
Removed:
execute:
150
Removed:
'INSERT INTO users(username,password_hash,account_creation_date_time) VALUES (?, ?, ?);'
151
Removed:
with: {
152
Removed:
aMFTUser username.
153
Removed:
aMFTUser passwordHash.
154
Removed:
DateAndTime now asUTC rounded };
155
Removed:
close
147
Added:
aMFTUser username ifNotEmpty: [
148
Added:
self defaultConnection
149
Added:
open;
150
Added:
execute:
151
Added:
'INSERT INTO users(username,password_hash,account_creation_date_time) VALUES (?, ?, ?);'
152
Added:
with: {
153
Added:
aMFTUser username.
154
Added:
aMFTUser passwordHash.
155
Added:
DateAndTime now asUTC rounded };
156
Added:
close ]
156
157
]
157
158
158
159
{ #category : #'as yet unclassified' }
src/MyFitnessTracker/MFTUser.class.st
@@ -1,6 +1,6 @@
1
1
Class {
2
2
#name : #MFTUser,
3
Removed:
#superclass : #Object,
3
Added:
#superclass : #SBSComponent,
4
4
#instVars : [
5
5
'username',
6
6
'passwordHash',
@@ -42,22 +42,25 @@
42
42
43
43
{ #category : #'instance creation' }
44
44
MFTUser class >> newFromDictionary: aDictionary [
45
Added:
"Dictionary keys are the SQLite3 column names."
45
46
46
47
^ self new
47
Removed:
username: (aDictionary at: 'username');
48
Removed:
dateOfBirth: (aDictionary at: 'date_of_birth');
49
Removed:
realFirstName: (aDictionary at: 'real_first_name');
50
Removed:
realLastName: (aDictionary at: 'real_last_name');
48
Added:
username: (aDictionary at: 'username' ifAbsent: [ String new ]);
49
Added:
dateOfBirth:
50
Added:
(aDictionary at: 'date_of_birth' ifAbsent: [ Date new ]);
51
Added:
realFirstName:
52
Added:
(aDictionary at: 'real_first_name' ifAbsent: [ String new ]);
53
Added:
realLastName:
54
Added:
(aDictionary at: 'real_last_name' ifAbsent: [ String new ]);
51
55
yourself
52
56
]
53
57
54
58
{ #category : #'instance creation' }
55
59
MFTUser class >> newFromID: id [
56
60
57
Removed:
| dictionary |
58
Removed:
dictionary := (MFTSQLite3Database selectUser: id) asDictionary.
59
61
^ self
60
Removed:
newFromDictionary: dictionary;
62
Added:
newFromDictionary:
63
Added:
(MFTSQLite3Database selectUser: id) asDictionary;
61
64
yourself
62
65
]
63
66
@@ -120,11 +123,11 @@
120
123
MFTUser >> dataDictionary [
121
124
122
125
^ OrderedDictionary newFrom: {
123
Removed:
(#username -> username).
124
Removed:
(#'date of birth' -> dateOfBirth).
125
Removed:
(#'first name' -> realFirstName).
126
Removed:
(#'last name' -> realLastName).
127
Removed:
(#'last login date and time' -> lastLoginDateAndTime) }
126
Added:
('username' -> username).
127
Added:
('date of birth' -> dateOfBirth).
128
Added:
('first name' -> realFirstName).
129
Added:
('last name' -> realLastName).
130
Added:
('last login date and time' -> lastLoginDateAndTime) }
128
131
]
129
132
130
133
{ #category : #accessing }
@@ -218,6 +221,29 @@
218
221
MFTUser >> realLastName: anObject [
219
222
220
223
realLastName := anObject
224
Added:
]
225
Added:
226
Added:
{ #category : #rendering }
227
Added:
MFTUser >> renderContentOn: html [
228
Added:
229
Added:
html table
230
Added:
class: 'table table-bordered my-3';
231
Added:
with: [
232
Added:
html tableRow: [
233
Added:
html tableData: 'username'.
234
Added:
html tableData: username ].
235
Added:
html tableRow: [
236
Added:
html tableData: 'date of birth'.
237
Added:
html tableData: dateOfBirth ].
238
Added:
html tableRow: [
239
Added:
html tableData: 'real first name'.
240
Added:
html tableData: realFirstName ].
241
Added:
html tableRow: [
242
Added:
html tableData: 'real last name'.
243
Added:
html tableData: realLastName ].
244
Added:
html tableRow: [
245
Added:
html tableData: 'last login date and time'.
246
Added:
html tableData: lastLoginDateAndTime ] ]
221
247
]
222
248
223
249
{ #category : #accessing }
src/MyFitnessTracker/MFTWeightVsTimeGraph.class.st
@@ -4,18 +4,13 @@
4
4
#category : #'MyFitnessTracker-Components'
5
5
}
6
6
7
Removed:
{ #category : #initialization }
8
Removed:
MFTWeightVsTimeGraph >> initialize [
7
Added:
{ #category : #rendering }
8
Added:
MFTWeightVsTimeGraph >> renderContentOn: html [
9
9
10
Removed:
super initialize.
11
10
labels := self session user weights collect: [ :weight |
12
11
weight date yyyymmdd ].
13
Removed:
data := self session user weights collect: #value
14
Removed:
]
12
Added:
data := self session user weights collect: #value.
15
13
16
Removed:
{ #category : #rendering }
17
Removed:
MFTWeightVsTimeGraph >> renderContentOn: html [
18
Removed:
19
14
html canvas
20
15
id: 'weightChart';
21
16
height: 1;
@@ -31,14 +26,5 @@
31
26
data: ' , data asJavascript , ',
32
27
}]
33
28
},
34
Removed:
options: {
35
Removed:
scales: {
36
Removed:
yAxes: [{
37
Removed:
ticks: {
38
Removed:
beginAtZero: true
39
Removed:
}
40
Removed:
}]
41
Removed:
}
42
Removed:
}
43
Removed:
});'
29
Added:
});'
44
30
]
src/MyFitnessTracker/MFTWorkout.class.st
@@ -88,8 +88,8 @@
88
88
MFTWorkout >> initialize [
89
89
90
90
super initialize.
91
Removed:
exercises := OrderedCollection new.
92
91
date := Date today.
92
Added:
exercises := OrderedCollection new.
93
93
primaryMuscle := MFTMuscle new.
94
94
secondaryMuscles := OrderedCollection new
95
95
]
@@ -138,25 +138,40 @@
138
138
139
139
| grandTotal |
140
140
grandTotal := 0.
141
Removed:
html table
142
Removed:
class: 'table table-striped table-bordered';
143
Removed:
with: [
144
Removed:
self renderTableHeaderOn: html.
145
Removed:
exercises do: [ :exercise |
146
Removed:
html tableRow: [
147
Removed:
html tableData: [
148
Removed:
html
149
Removed:
text: exercise englishName;
150
Removed:
text: ': '.
151
Removed:
exercise sets
152
Removed:
ifNotEmpty: [
153
Removed:
html text: exercise repsBySet asCommaString.
154
Removed:
html tableData: exercise repsBySet sum.
155
Removed:
grandTotal := grandTotal + exercise repsBySet sum ]
156
Removed:
ifEmpty: [
157
Removed:
html text: 0.
158
Removed:
html tableData: 0 ] ] ] ].
159
Removed:
self renderTableFooterTotal: grandTotal on: html ]
141
Added:
html definitionList: [
142
Added:
date ifNotNil: [
143
Added:
html
144
Added:
definitionTerm: 'Date';
145
Added:
definitionData: date "dayOfWeekName , ', ' , date asString" ].
146
Added:
primaryMuscle englishName ifNotEmpty: [
147
Added:
html
148
Added:
definitionTerm: 'Primary Muscle';
149
Added:
definitionData: primaryMuscle englishName ].
150
Added:
secondaryMuscles ifNotEmpty: [
151
Added:
html
152
Added:
definitionTerm: 'Secondary Muscles';
153
Added:
definitionData:
154
Added:
(secondaryMuscles collect: #englishName) asCommaString ] ].
155
Added:
exercises ifNotEmpty: [
156
Added:
html table
157
Added:
class: 'table table-striped table-bordered';
158
Added:
with: [
159
Added:
self renderTableHeaderOn: html.
160
Added:
exercises do: [ :exercise |
161
Added:
html tableRow: [
162
Added:
html tableData: [
163
Added:
html
164
Added:
text: exercise englishName;
165
Added:
text: ': '.
166
Added:
exercise sets
167
Added:
ifNotEmpty: [
168
Added:
html text: exercise repsBySet asCommaString.
169
Added:
html tableData: exercise repsBySet sum.
170
Added:
grandTotal := grandTotal + exercise repsBySet sum ]
171
Added:
ifEmpty: [
172
Added:
html text: 0.
173
Added:
html tableData: 0 ] ] ] ].
174
Added:
self renderTableFooterTotal: grandTotal on: html ] ]
160
175
]
161
176
162
177
{ #category : #rendering }