[Pharo] Personal fitness tracker web app.
Collapse workout prescription and logging components into one.
Changed files
- src/MyFitnessTracker-Core/MFTPlan.class.st
- src/MyFitnessTracker-Core/MFTRoutine.class.st
- src/MyFitnessTracker-Core/MFTSetPrescription.class.st
- src/MyFitnessTracker-Core/MFTTrainee.class.st
- src/MyFitnessTracker-Core/MFTWorkoutLog.class.st
- src/MyFitnessTracker-Core/MFTWorkoutLogBook.class.st
- src/MyFitnessTracker-Core/MFTWorkoutPrescription.class.st
- src/MyFitnessTracker-Web/MFTHomePage.class.st
- src/MyFitnessTracker-Web/MFTLogWorkoutPage.class.st
- src/MyFitnessTracker-Web/MFTNavbarComponent.class.st
- src/MyFitnessTracker-Web/MFTPage.class.st
- src/MyFitnessTracker-Web/MFTPageManager.class.st
- src/MyFitnessTracker-Web/MFTPlanPage.class.st
- src/MyFitnessTracker-Web/MFTRoutineComponent.class.st
- src/MyFitnessTracker-Web/MFTStatusComponent.class.st
- src/MyFitnessTracker-Web/MFTWorkoutComponent.class.st
- src/MyFitnessTracker-Web/MFTWorkoutLogBookComponent.class.st
- src/MyFitnessTracker-Web/MFTWorkoutLogComponent.class.st
- src/MyFitnessTracker-Web/MFTWorkoutPrescriptionComponent.class.st
src/MyFitnessTracker-Core/MFTPlan.class.st
@@ -1,94 +0,0 @@
1
Removed:
"
2
Removed:
I represent a training routine for a trainee.
3
Removed:
"
4
Removed:
Class {
5
Removed:
#name : 'MFTPlan',
6
Removed:
#superclass : 'MFTObject',
7
Removed:
#instVars : [
8
Removed:
'trainee',
9
Removed:
'routine',
10
Removed:
'start'
11
Removed:
],
12
Removed:
#category : 'MyFitnessTracker-Core-Logging',
13
Removed:
#package : 'MyFitnessTracker-Core',
14
Removed:
#tag : 'Logging'
15
Removed:
}
16
Removed:
17
Removed:
{ #category : 'instance creation' }
18
Removed:
MFTPlan class >> forRoutine: aMFTRoutine [
19
Removed:
20
Removed:
^ self new
21
Removed:
routine: aMFTRoutine;
22
Removed:
yourself
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'instance creation' }
26
Removed:
MFTPlan class >> forRoutine: aMFTRoutine start: aDate [
27
Removed:
28
Removed:
^ self new
29
Removed:
routine: aMFTRoutine;
30
Removed:
start: aDate;
31
Removed:
yourself
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'accessing' }
35
Removed:
MFTPlan >> canonicalName [
36
Removed:
37
Removed:
^ start
38
Removed:
ifNotNil: [ 'plan started ' , start asDate asString ]
39
Removed:
ifNil: [ 'plan not started' ]
40
Removed:
]
41
Removed:
42
Removed:
{ #category : 'as yet unclassified' }
43
Removed:
MFTPlan >> nextWorkout [
44
Removed:
45
Removed:
^ routine workouts first
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'accessing' }
49
Removed:
MFTPlan >> routine [
50
Removed:
51
Removed:
^ routine
52
Removed:
]
53
Removed:
54
Removed:
{ #category : 'accessing' }
55
Removed:
MFTPlan >> routine: aMFTRoutine [
56
Removed:
57
Removed:
routine := aMFTRoutine
58
Removed:
]
59
Removed:
60
Removed:
{ #category : 'accessing' }
61
Removed:
MFTPlan >> start [
62
Removed:
63
Removed:
^ start
64
Removed:
]
65
Removed:
66
Removed:
{ #category : 'accessing' }
67
Removed:
MFTPlan >> start: aDateAndTime [
68
Removed:
69
Removed:
start := aDateAndTime asDateAndTime
70
Removed:
]
71
Removed:
72
Removed:
{ #category : 'accessing' }
73
Removed:
MFTPlan >> startNow [
74
Removed:
75
Removed:
start := DateAndTime now
76
Removed:
]
77
Removed:
78
Removed:
{ #category : 'accessing' }
79
Removed:
MFTPlan >> trainee [
80
Removed:
81
Removed:
^ trainee
82
Removed:
]
83
Removed:
84
Removed:
{ #category : 'accessing' }
85
Removed:
MFTPlan >> trainee: aMFTTrainee [
86
Removed:
87
Removed:
trainee := aMFTTrainee
88
Removed:
]
89
Removed:
90
Removed:
{ #category : 'accessing' }
91
Removed:
MFTPlan >> workouts [
92
Removed:
93
Removed:
^ routine workouts
94
Removed:
]
src/MyFitnessTracker-Core/MFTRoutine.class.st
@@ -50,6 +50,18 @@
50
50
title := aString
51
51
]
52
52
53
Added:
{ #category : 'as yet unclassified' }
54
Added:
MFTRoutine >> workoutAfter: aMFTWorkoutPrescription [
55
Added:
56
Added:
| index |
57
Added:
workouts ifEmpty: [ ^ nil ].
58
Added:
59
Added:
index := workouts
60
Added:
indexOf: aMFTWorkoutPrescription
61
Added:
ifAbsent: [ ^ workouts first ].
62
Added:
^ workouts at: index % workouts size + 1
63
Added:
]
64
Added:
53
65
{ #category : 'accessing' }
54
66
MFTRoutine >> workouts [
55
67
src/MyFitnessTracker-Core/MFTSetPrescription.class.st
@@ -32,7 +32,6 @@
32
32
33
33
{ #category : 'comparing' }
34
34
MFTSetPrescription >> = anObject [
35
Removed:
"Answer whether the receiver and anObject represent the same object."
36
35
37
36
self == anObject ifTrue: [ ^ true ].
38
37
self class = anObject class ifFalse: [ ^ false ].
src/MyFitnessTracker-Core/MFTTrainee.class.st
@@ -55,6 +55,20 @@
55
55
logBook := aMFTWorkoutLogBook
56
56
]
57
57
58
Added:
{ #category : 'adding' }
59
Added:
MFTTrainee >> logWorkout: aMFTWorkoutLog [
60
Added:
61
Added:
logBook logWorkout: aMFTWorkoutLog
62
Added:
]
63
Added:
64
Added:
{ #category : 'testing' }
65
Added:
MFTTrainee >> nextWorkoutPrescription [
66
Added:
67
Added:
routine workouts ifEmpty: [ ^ nil ].
68
Added:
logBook workoutLogs ifEmpty: [ ^ routine workouts first ].
69
Added:
^ routine workoutAfter: logBook workoutLogs last prescription
70
Added:
]
71
Added:
58
72
{ #category : 'accessing' }
59
73
MFTTrainee >> routine [
60
74
@@ -62,7 +76,7 @@
62
76
]
63
77
64
78
{ #category : 'accessing' }
65
Removed:
MFTTrainee >> routine: anObject [
79
Added:
MFTTrainee >> routine: aMFTRoutine [
66
80
67
Removed:
routine := anObject
81
Added:
routine := aMFTRoutine
68
82
]
src/MyFitnessTracker-Core/MFTWorkoutLog.class.st
@@ -8,8 +8,7 @@
8
8
'prescription',
9
9
'start',
10
10
'finish',
11
Removed:
'sets',
12
Removed:
'trainee'
11
Added:
'sets'
13
12
],
14
13
#category : 'MyFitnessTracker-Core-Logging',
15
14
#package : 'MyFitnessTracker-Core',
@@ -33,12 +32,15 @@
33
32
{ #category : 'initialization' }
34
33
MFTWorkoutLog >> canonicalName [
35
34
35
Added:
prescription ifNil: [ ^ 'no prescription' ].
36
36
^ prescription canonicalName , ' log'
37
37
]
38
38
39
39
{ #category : 'as yet unclassified' }
40
40
MFTWorkoutLog >> duration [
41
41
42
Added:
start ifNil: [ ^ Duration zero ].
43
Added:
finish ifNil: [ ^ DateAndTime now - start ].
42
44
^ finish - start
43
45
]
44
46
@@ -61,6 +63,12 @@
61
63
]
62
64
63
65
{ #category : 'accessing' }
66
Added:
MFTWorkoutLog >> finishNow [
67
Added:
68
Added:
finish := DateAndTime now
69
Added:
]
70
Added:
71
Added:
{ #category : 'initialization' }
64
72
MFTWorkoutLog >> initialize [
65
73
66
74
super initialize.
@@ -121,16 +129,4 @@
121
129
MFTWorkoutLog >> startNow [
122
130
123
131
start := DateAndTime now
124
Removed:
]
125
Removed:
126
Removed:
{ #category : 'accessing' }
127
Removed:
MFTWorkoutLog >> trainee [
128
Removed:
129
Removed:
^ trainee
130
Removed:
]
131
Removed:
132
Removed:
{ #category : 'accessing' }
133
Removed:
MFTWorkoutLog >> trainee: aMFTTrainee [
134
Removed:
135
Removed:
trainee := aMFTTrainee
136
132
]
src/MyFitnessTracker-Core/MFTWorkoutLogBook.class.st
@@ -5,7 +5,7 @@
5
5
#name : 'MFTWorkoutLogBook',
6
6
#superclass : 'MFTObject',
7
7
#instVars : [
8
Removed:
'workouts'
8
Added:
'workoutLogs'
9
9
],
10
10
#category : 'MyFitnessTracker-Core-Logging',
11
11
#package : 'MyFitnessTracker-Core',
@@ -15,22 +15,22 @@
15
15
{ #category : 'initialization' }
16
16
MFTWorkoutLogBook >> canonicalName [
17
17
18
Removed:
^ workouts
18
Added:
^ workoutLogs
19
19
]
20
20
21
21
{ #category : 'adding' }
22
22
MFTWorkoutLogBook >> durationSinceLastWorkout [
23
23
24
Removed:
^ workouts
24
Added:
^ workoutLogs
25
25
ifEmpty: [ nil ]
26
Removed:
ifNotEmpty: [ DateAndTime now - workouts last finish ]
26
Added:
ifNotEmpty: [ DateAndTime now - workoutLogs last finish ]
27
27
]
28
28
29
29
{ #category : 'initialization' }
30
30
MFTWorkoutLogBook >> initialize [
31
31
32
32
super initialize.
33
Removed:
workouts := OrderedCollection new
33
Added:
workoutLogs := OrderedCollection new
34
34
]
35
35
36
36
{ #category : 'adding' }
@@ -38,7 +38,7 @@
38
38
"Answer the most recent workout log during which this exercise was performed."
39
39
40
40
| lastLog |
41
Removed:
lastLog := (workouts select: [ :workout |
41
Added:
lastLog := (workoutLogs select: [ :workout |
42
42
workout exercises includes: aMFTExercise ])
43
43
ifEmpty: [ ^ nil ]
44
44
ifNotEmpty: [ :logs | logs detectMax: #finish ].
@@ -50,8 +50,8 @@
50
50
"Answer the most recent workout log for this workout prescription."
51
51
52
52
| lastLog |
53
Removed:
lastLog := (workouts select: [ :workout |
54
Removed:
workout prescription = aMFTWorkoutPrescription ])
53
Added:
lastLog := (workoutLogs select: [ :log |
54
Added:
log prescription = aMFTWorkoutPrescription ])
55
55
ifEmpty: [ ^ nil ]
56
56
ifNotEmpty: [ :logs | logs detectMax: #finish ].
57
57
^ lastLog
@@ -60,17 +60,23 @@
60
60
{ #category : 'adding' }
61
61
MFTWorkoutLogBook >> logWorkout: aMFTWorkoutLog [
62
62
63
Removed:
workouts addLast: aMFTWorkoutLog
63
Added:
workoutLogs addLast: aMFTWorkoutLog
64
64
]
65
65
66
Added:
{ #category : 'removing' }
67
Added:
MFTWorkoutLogBook >> removeWorkoutLog: aMFTWorkoutLog [
68
Added:
69
Added:
workoutLogs remove: aMFTWorkoutLog
70
Added:
]
71
Added:
66
72
{ #category : 'as yet unclassified' }
67
73
MFTWorkoutLogBook >> workoutLogIsInProgress [
68
74
69
Removed:
^ workouts last finish isNil
75
Added:
^ workoutLogs last finish isNil
70
76
]
71
77
72
78
{ #category : 'initialization' }
73
Removed:
MFTWorkoutLogBook >> workouts [
79
Added:
MFTWorkoutLogBook >> workoutLogs [
74
80
75
Removed:
^ workouts
81
Added:
^ workoutLogs
76
82
]
src/MyFitnessTracker-Core/MFTWorkoutPrescription.class.st
@@ -77,7 +77,7 @@
77
77
^ Duration zero
78
78
]
79
79
80
Removed:
{ #category : 'as yet unclassified' }
80
Added:
{ #category : 'initialization' }
81
81
MFTWorkoutPrescription >> initialize [
82
82
83
83
super initialize.
src/MyFitnessTracker-Web/MFTHomePage.class.st
@@ -2,54 +2,56 @@
2
2
#name : 'MFTHomePage',
3
3
#superclass : 'MFTPage',
4
4
#instVars : [
5
Removed:
'plan',
6
5
'statusComponent',
7
Removed:
'nextWorkoutComponent',
8
Removed:
'mainActionsComponent'
6
Added:
'nextWorkoutPrescriptionComponent',
7
Added:
'workoutLogBookComponent'
9
8
],
10
9
#category : 'MyFitnessTracker-Web-Components',
11
10
#package : 'MyFitnessTracker-Web',
12
11
#tag : 'Components'
13
12
}
14
13
15
Removed:
{ #category : 'rendering' }
14
Added:
{ #category : 'hooks' }
16
15
MFTHomePage >> children [
17
16
18
Removed:
^ {
19
Removed:
statusComponent.
20
Removed:
nextWorkoutComponent }
17
Added:
^ { statusComponent }
21
18
]
22
19
23
20
{ #category : 'initialization' }
24
21
MFTHomePage >> initialize [
25
22
26
Removed:
| nextWorkout |
27
23
super initialize.
28
Removed:
plan := (MFTPlan forRoutine: MFTRoutine heavyDutyOneIdealRoutine)
29
Removed:
startNow.
30
Removed:
statusComponent := MFTStatusComponent forPlan: plan.
31
Removed:
32
Removed:
nextWorkout := plan nextWorkout.
33
Removed:
nextWorkoutComponent := (MFTWorkoutPrescriptionComponent
34
Removed:
forPrescription: plan workouts first)
35
Removed:
title:
36
Removed:
'Next Workout: ' , nextWorkout asString;
37
Removed:
isLoggable
24
Added:
statusComponent := MFTStatusComponent new.
25
Added:
nextWorkoutPrescriptionComponent := MFTWorkoutComponent new
26
Added:
beLoggable.
27
Added:
workoutLogBookComponent := MFTWorkoutLogBookComponent new
38
28
]
39
29
40
30
{ #category : 'rendering' }
41
31
MFTHomePage >> renderContentOn: html [
42
32
33
Added:
| trainee |
34
Added:
trainee := self session user.
35
Added:
43
36
self renderPageOn: html with: [
44
37
html heading
45
38
level: 1;
46
Removed:
with: plan routine canonicalName capitalized.
39
Added:
with: trainee routine canonicalName capitalized.
40
Added:
trainee logBook workoutLogs ifNotEmpty: [
41
Added:
html heading
42
Added:
level: 2;
43
Added:
with: 'Plan started '
44
Added:
, trainee logBook workoutLogs first start asDate asString ].
45
Added:
html render: statusComponent.
47
46
html heading
48
47
level: 2;
49
Removed:
with: plan canonicalName capitalized.
50
Removed:
html render: statusComponent.
51
Removed:
html render: mainActionsComponent.
52
Removed:
html render: nextWorkoutComponent ]
48
Added:
with: 'Next workout'.
49
Added:
html
50
Added:
render: (nextWorkoutPrescriptionComponent
51
Added:
workoutPrescription: trainee nextWorkoutPrescription;
52
Added:
workoutLog:
53
Added:
(MFTWorkoutLog forPrescription: trainee nextWorkoutPrescription));
54
Added:
render: (workoutLogBookComponent workoutLogBook: trainee logBook) ]
53
55
]
54
56
55
57
{ #category : 'accessing' }
src/MyFitnessTracker-Web/MFTLogWorkoutPage.class.st
@@ -0,0 +1,44 @@
1
Added:
Class {
2
Added:
#name : 'MFTLogWorkoutPage',
3
Added:
#superclass : 'MFTPage',
4
Added:
#instVars : [
5
Added:
'workoutComponent'
6
Added:
],
7
Added:
#category : 'MyFitnessTracker-Web-Components',
8
Added:
#package : 'MyFitnessTracker-Web',
9
Added:
#tag : 'Components'
10
Added:
}
11
Added:
12
Added:
{ #category : 'as yet unclassified' }
13
Added:
MFTLogWorkoutPage >> children [
14
Added:
15
Added:
^ { workoutComponent }
16
Added:
]
17
Added:
18
Added:
{ #category : 'rendering' }
19
Added:
MFTLogWorkoutPage >> renderContentOn: html [
20
Added:
21
Added:
self renderPageOn: html with: [
22
Added:
html heading
23
Added:
level: 1;
24
Added:
with: 'Log Workout'.
25
Added:
html render: workoutComponent ]
26
Added:
]
27
Added:
28
Added:
{ #category : 'accessing' }
29
Added:
MFTLogWorkoutPage >> title [
30
Added:
31
Added:
^ 'Log workout'
32
Added:
]
33
Added:
34
Added:
{ #category : 'accessing' }
35
Added:
MFTLogWorkoutPage >> workoutComponent [
36
Added:
37
Added:
^ workoutComponent
38
Added:
]
39
Added:
40
Added:
{ #category : 'accessing' }
41
Added:
MFTLogWorkoutPage >> workoutComponent: aMFTWorkoutComponent [
42
Added:
43
Added:
workoutComponent := aMFTWorkoutComponent
44
Added:
]
src/MyFitnessTracker-Web/MFTNavbarComponent.class.st
@@ -17,6 +17,6 @@
17
17
pm mainPages collect: [ :page |
18
18
html listItem: [
19
19
html anchor
20
Removed:
callback: [ pm setActivePage: page class ];
20
Added:
callback: [ pm setActivePage: page ];
21
21
with: page title ] ] ] ]
22
22
]
src/MyFitnessTracker-Web/MFTPage.class.st
@@ -1,3 +1,6 @@
1
Added:
"
2
Added:
I represent a MFT activity.
3
Added:
"
1
4
Class {
2
5
#name : 'MFTPage',
3
6
#superclass : 'WAComponent',
@@ -11,7 +14,10 @@
11
14
12
15
html div
13
16
id: 'content';
14
Removed:
with: aBlock
17
Added:
with: [
18
Added:
html div
19
Added:
id: 'notebook-paper';
20
Added:
with: aBlock ]
15
21
]
16
22
17
23
{ #category : 'accessing' }
src/MyFitnessTracker-Web/MFTPageManager.class.st
@@ -2,7 +2,6 @@
2
2
#name : 'MFTPageManager',
3
3
#superclass : 'Object',
4
4
#instVars : [
5
Removed:
'mainPages',
6
5
'activePage',
7
6
'navbar',
8
7
'footer'
@@ -24,14 +23,6 @@
24
23
activePage := aMFTPage
25
24
]
26
25
27
Removed:
{ #category : 'as yet unclassified' }
28
Removed:
MFTPageManager >> defaultPublicPages [
29
Removed:
30
Removed:
^ {
31
Removed:
MFTHomePage new.
32
Removed:
MFTPlanPage new }
33
Removed:
]
34
Removed:
35
26
{ #category : 'accessing' }
36
27
MFTPageManager >> footer [
37
28
@@ -47,32 +38,20 @@
47
38
{ #category : 'initialization' }
48
39
MFTPageManager >> initialize [
49
40
50
Removed:
mainPages := self defaultPublicPages.
51
Removed:
activePage := mainPages first.
41
Added:
activePage := MFTHomePage new.
52
42
navbar := MFTNavbarComponent new.
53
43
footer := MFTFooterComponent new
54
44
]
55
45
56
Removed:
{ #category : 'as yet unclassified' }
57
Removed:
MFTPageManager >> loadPublicPages [
58
Removed:
59
Removed:
mainPages := self defaultPublicPages.
60
Removed:
self setActivePageAt: #home
61
Removed:
]
62
Removed:
63
46
{ #category : 'accessing' }
64
47
MFTPageManager >> mainPages [
65
48
66
Removed:
^ mainPages
49
Added:
^ {
50
Added:
MFTHomePage new.
51
Added:
MFTPlanPage new }
67
52
]
68
53
69
54
{ #category : 'accessing' }
70
Removed:
MFTPageManager >> mainPages: aCollection [
71
Removed:
72
Removed:
mainPages := aCollection
73
Removed:
]
74
Removed:
75
Removed:
{ #category : 'accessing' }
76
55
MFTPageManager >> navbar [
77
56
78
57
^ navbar
@@ -85,9 +64,7 @@
85
64
]
86
65
87
66
{ #category : 'accessing' }
88
Removed:
MFTPageManager >> setActivePage: aMFTPageClass [
67
Added:
MFTPageManager >> setActivePage: aMFTPage [
89
68
90
Removed:
activePage := mainPages
91
Removed:
detect: [ :page | page class = aMFTPageClass ]
92
Removed:
ifNone: [ MFTHomePage ]
69
Added:
activePage := aMFTPage
93
70
]
src/MyFitnessTracker-Web/MFTPlanPage.class.st
@@ -10,7 +10,7 @@
10
10
#tag : 'Components'
11
11
}
12
12
13
Removed:
{ #category : 'rendering' }
13
Added:
{ #category : 'as yet unclassified' }
14
14
MFTPlanPage >> children [
15
15
16
16
^ { routineComponent }
src/MyFitnessTracker-Web/MFTRoutineComponent.class.st
@@ -18,13 +18,6 @@
18
18
yourself
19
19
]
20
20
21
Removed:
{ #category : 'accessing' }
22
Removed:
MFTRoutineComponent >> buildWorkoutComponents [
23
Removed:
24
Removed:
workoutComponents := routine workouts collect: [ :each |
25
Removed:
MFTWorkoutPrescriptionComponent forPrescription: each ]
26
Removed:
]
27
Removed:
28
21
{ #category : 'hooks' }
29
22
MFTRoutineComponent >> children [
30
23
@@ -55,5 +48,7 @@
55
48
MFTRoutineComponent >> routine: aMFTRoutine [
56
49
57
50
routine := aMFTRoutine.
58
Removed:
self buildWorkoutComponents
51
Added:
workoutComponents := routine workouts collect: [ :each |
52
Added:
MFTWorkoutComponent forWorkoutPrescription:
53
Added:
each ]
59
54
]
src/MyFitnessTracker-Web/MFTStatusComponent.class.st
@@ -6,40 +6,17 @@
6
6
Class {
7
7
#name : 'MFTStatusComponent',
8
8
#superclass : 'WAComponent',
9
Removed:
#instVars : [
10
Removed:
'plan'
11
Removed:
],
12
9
#category : 'MyFitnessTracker-Web-Components',
13
10
#package : 'MyFitnessTracker-Web',
14
11
#tag : 'Components'
15
12
}
16
13
17
Removed:
{ #category : 'as yet unclassified' }
18
Removed:
MFTStatusComponent class >> forPlan: aMFTPlan [
19
Removed:
20
Removed:
^ self new
21
Removed:
plan: aMFTPlan;
22
Removed:
yourself
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'accessing' }
26
Removed:
MFTStatusComponent >> plan [
27
Removed:
28
Removed:
^ plan
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'accessing' }
32
Removed:
MFTStatusComponent >> plan: aMFTPlan [
33
Removed:
34
Removed:
plan := aMFTPlan
35
Removed:
]
36
Removed:
37
14
{ #category : 'rendering' }
38
15
MFTStatusComponent >> renderContentOn: html [
39
16
40
17
html definitionList: [
41
18
html definitionTerm: 'Last workout'.
42
Removed:
html definitionData: (self session user logBook workouts
19
Added:
html definitionData: (self session user logBook workoutLogs
43
20
ifNotEmpty: [ :workoutLogs |
44
21
| lastLog |
45
22
lastLog := workoutLogs last.
src/MyFitnessTracker-Web/MFTWorkoutComponent.class.st
@@ -0,0 +1,197 @@
1
Added:
Class {
2
Added:
#name : 'MFTWorkoutComponent',
3
Added:
#superclass : 'WAComponent',
4
Added:
#instVars : [
5
Added:
'isLoggable',
6
Added:
'workoutPrescription',
7
Added:
'workoutLog',
8
Added:
'isLogging'
9
Added:
],
10
Added:
#category : 'MyFitnessTracker-Web-Components',
11
Added:
#package : 'MyFitnessTracker-Web',
12
Added:
#tag : 'Components'
13
Added:
}
14
Added:
15
Added:
{ #category : 'as yet unclassified' }
16
Added:
MFTWorkoutComponent class >> forWorkoutLog: aMFTWorkoutLog [
17
Added:
18
Added:
^ self new
19
Added:
workoutLog: aMFTWorkoutLog;
20
Added:
workoutPrescription: aMFTWorkoutLog prescription;
21
Added:
yourself
22
Added:
]
23
Added:
24
Added:
{ #category : 'as yet unclassified' }
25
Added:
MFTWorkoutComponent class >> forWorkoutPrescription: aMFTWorkoutPrescription [
26
Added:
27
Added:
^ self new
28
Added:
workoutLog:
29
Added:
(MFTWorkoutLog forPrescription: aMFTWorkoutPrescription);
30
Added:
workoutPrescription: aMFTWorkoutPrescription;
31
Added:
yourself
32
Added:
]
33
Added:
34
Added:
{ #category : 'accessing' }
35
Added:
MFTWorkoutComponent >> beLoggable [
36
Added:
37
Added:
isLoggable := true
38
Added:
]
39
Added:
40
Added:
{ #category : 'as yet unclassified' }
41
Added:
MFTWorkoutComponent >> initialize [
42
Added:
43
Added:
super initialize.
44
Added:
isLoggable := false.
45
Added:
isLogging := false
46
Added:
]
47
Added:
48
Added:
{ #category : 'accessing' }
49
Added:
MFTWorkoutComponent >> isLoggable [
50
Added:
51
Added:
^ isLoggable
52
Added:
]
53
Added:
54
Added:
{ #category : 'as yet unclassified' }
55
Added:
MFTWorkoutComponent >> isLogging [
56
Added:
57
Added:
isLogging := true
58
Added:
]
59
Added:
60
Added:
{ #category : 'as yet unclassified' }
61
Added:
MFTWorkoutComponent >> isNotLogging [
62
Added:
63
Added:
isLogging := false
64
Added:
]
65
Added:
66
Added:
{ #category : 'as yet unclassified' }
67
Added:
MFTWorkoutComponent >> renderActionsOn: html [
68
Added:
69
Added:
isLoggable ifTrue: [
70
Added:
html form: [
71
Added:
isLogging
72
Added:
ifTrue: [
73
Added:
html submitButton
74
Added:
callback: [
75
Added:
self isNotLogging.
76
Added:
workoutLog finishNow.
77
Added:
self session user logWorkout: workoutLog.
78
Added:
self session pageManager setActivePage: MFTHomePage new ];
79
Added:
with: 'Save Workout' ]
80
Added:
ifFalse: [
81
Added:
html submitButton
82
Added:
callback: [
83
Added:
self isLogging.
84
Added:
workoutLog startNow.
85
Added:
self session pageManager setActivePage:
86
Added:
(MFTLogWorkoutPage new workoutComponent: self) ];
87
Added:
with: 'Log Workout' ] ] ]
88
Added:
]
89
Added:
90
Added:
{ #category : 'rendering' }
91
Added:
MFTWorkoutComponent >> renderContentOn: html [
92
Added:
93
Added:
html div
94
Added:
class: 'workout-card';
95
Added:
with: [
96
Added:
html heading
97
Added:
level: 3;
98
Added:
with: workoutPrescription canonicalName.
99
Added:
workoutLog ifNotNil: [ self renderWorkoutLogDetailsOn: html ].
100
Added:
isLogging
101
Added:
ifTrue: [ self renderWorkoutSetsAsFormOn: html ]
102
Added:
ifFalse: [ self renderWorkoutSetsAsTableOn: html ].
103
Added:
self renderActionsOn: html ]
104
Added:
]
105
Added:
106
Added:
{ #category : 'rendering' }
107
Added:
MFTWorkoutComponent >> renderWorkoutLogDetailsOn: html [
108
Added:
109
Added:
workoutLog start ifNotNil: [
110
Added:
html definitionList: [
111
Added:
html
112
Added:
definitionTerm: 'Started:';
113
Added:
definitionData: workoutLog start asDate asString , ' at '
114
Added:
, workoutLog start asTime print24;
115
Added:
definitionTerm: 'Duration:';
116
Added:
definitionData:
117
Added:
(Duration seconds: workoutLog duration asSeconds rounded)
118
Added:
humanReadablePrintString ] ]
119
Added:
]
120
Added:
121
Added:
{ #category : 'as yet unclassified' }
122
Added:
MFTWorkoutComponent >> renderWorkoutSetsAsFormOn: html [
123
Added:
124
Added:
html form: [
125
Added:
workoutPrescription setGroups doWithIndex: [ :setGroupPrescription :i |
126
Added:
html fieldSet: [
127
Added:
html legend: setGroupPrescription.
128
Added:
setGroupPrescription sets doWithIndex: [ :setPrescription :j |
129
Added:
| uid setLog |
130
Added:
uid := i asString , '.' , j asString.
131
Added:
"setLog := workoutLog setForPrescription: setPrescription."
132
Added:
setLog := MFTSetLog forPrescription: setPrescription.
133
Added:
html heading
134
Added:
level: 4;
135
Added:
with: setPrescription exercise.
136
Added:
html div
137
Added:
class: 'exercise-log-container';
138
Added:
with: [
139
Added:
html label
140
Added:
for: 'reps-' , uid;
141
Added:
with: 'Reps'.
142
Added:
html numberInput
143
Added:
id: 'reps-' , uid;
144
Added:
callback: [ :value | setLog reps: value asNumber ].
145
Added:
html label
146
Added:
for: 'load-' , uid;
147
Added:
with: 'Load'.
148
Added:
html numberInput
149
Added:
id: 'load-' , uid;
150
Added:
callback: [ :value | setLog reps: value asNumber ].
151
Added:
html label
152
Added:
for: 'failure-' , uid;
153
Added:
with: 'Failure reached'.
154
Added:
html checkbox
155
Added:
id: 'failure-' , uid;
156
Added:
callback: [ :value | setLog failureAchieved: value ] ] ] ] ] ]
157
Added:
]
158
Added:
159
Added:
{ #category : 'as yet unclassified' }
160
Added:
MFTWorkoutComponent >> renderWorkoutSetsAsTableOn: html [
161
Added:
162
Added:
html table: [
163
Added:
html tableHead: [
164
Added:
html
165
Added:
tableHeading: 'Set';
166
Added:
tableHeading: 'Exercise' ].
167
Added:
html tableBody: [
168
Added:
workoutPrescription setGroups do: [ :setGroupPrescription |
169
Added:
html tableRow: [
170
Added:
html tableData: setGroupPrescription canonicalName.
171
Added:
html tableData:
172
Added:
((setGroupPrescription sets collect: #exercise) joinUsing: ', ') ] ] ] ]
173
Added:
]
174
Added:
175
Added:
{ #category : 'accessing' }
176
Added:
MFTWorkoutComponent >> workoutLog [
177
Added:
178
Added:
^ workoutLog
179
Added:
]
180
Added:
181
Added:
{ #category : 'accessing' }
182
Added:
MFTWorkoutComponent >> workoutLog: aMFTWorkoutLog [
183
Added:
184
Added:
workoutLog := aMFTWorkoutLog
185
Added:
]
186
Added:
187
Added:
{ #category : 'accessing' }
188
Added:
MFTWorkoutComponent >> workoutPrescription [
189
Added:
190
Added:
^ workoutPrescription
191
Added:
]
192
Added:
193
Added:
{ #category : 'accessing' }
194
Added:
MFTWorkoutComponent >> workoutPrescription: aMFTWorkoutPrescription [
195
Added:
196
Added:
workoutPrescription := aMFTWorkoutPrescription
197
Added:
]
src/MyFitnessTracker-Web/MFTWorkoutLogBookComponent.class.st
@@ -0,0 +1,32 @@
1
Added:
Class {
2
Added:
#name : 'MFTWorkoutLogBookComponent',
3
Added:
#superclass : 'WAComponent',
4
Added:
#instVars : [
5
Added:
'workoutLogBook'
6
Added:
],
7
Added:
#category : 'MyFitnessTracker-Web-Components',
8
Added:
#package : 'MyFitnessTracker-Web',
9
Added:
#tag : 'Components'
10
Added:
}
11
Added:
12
Added:
{ #category : 'rendering' }
13
Added:
MFTWorkoutLogBookComponent >> renderContentOn: html [
14
Added:
15
Added:
workoutLogBook workoutLogs reverseDo: [ :workoutLog |
16
Added:
html heading
17
Added:
level: 2;
18
Added:
with: 'Workout Logbook'.
19
Added:
html render: (MFTWorkoutComponent forWorkoutLog: workoutLog) ]
20
Added:
]
21
Added:
22
Added:
{ #category : 'accessing' }
23
Added:
MFTWorkoutLogBookComponent >> workoutLogBook [
24
Added:
25
Added:
^ workoutLogBook
26
Added:
]
27
Added:
28
Added:
{ #category : 'accessing' }
29
Added:
MFTWorkoutLogBookComponent >> workoutLogBook: aMFTWorkoutLogBook [
30
Added:
31
Added:
workoutLogBook := aMFTWorkoutLogBook
32
Added:
]
src/MyFitnessTracker-Web/MFTWorkoutLogComponent.class.st
@@ -1,66 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutLogComponent',
3
Removed:
#superclass : 'WAComponent',
4
Removed:
#instVars : [
5
Removed:
'workoutLog',
6
Removed:
'setGroupComponents'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Web-Components',
9
Removed:
#package : 'MyFitnessTracker-Web',
10
Removed:
#tag : 'Components'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'accessing' }
14
Removed:
MFTWorkoutLogComponent class >> forPrescription: aMFTWorkoutPrescription [
15
Removed:
16
Removed:
^ self new
17
Removed:
workoutLog:
18
Removed:
(MFTWorkoutLog forPrescription: aMFTWorkoutPrescription) startNow;
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'rendering' }
23
Removed:
MFTWorkoutLogComponent >> renderContentOn: html [
24
Removed:
25
Removed:
html div
26
Removed:
class: 'workout-card';
27
Removed:
with: [
28
Removed:
html heading
29
Removed:
level: 3;
30
Removed:
with: workoutLog asString.
31
Removed:
self renderLogsOn: html ]
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'rendering' }
35
Removed:
MFTWorkoutLogComponent >> renderLogsOn: html [
36
Removed:
37
Removed:
workoutLog prescription setGroups do: [ :setGroup |
38
Removed:
html heading
39
Removed:
level: 4;
40
Removed:
with: setGroup asString.
41
Removed:
html form: [
42
Removed:
html orderedList: [
43
Removed:
setGroup sets do: [ :setPrescription |
44
Removed:
html listItem: setPrescription exercise ] ].
45
Removed:
html submitButton
46
Removed:
callback: [ self answer: (workoutLog finish: DateAndTime now) ];
47
Removed:
with: 'Log' ] ]
48
Removed:
]
49
Removed:
50
Removed:
{ #category : 'accessing' }
51
Removed:
MFTWorkoutLogComponent >> title [
52
Removed:
53
Removed:
^ 'Log'
54
Removed:
]
55
Removed:
56
Removed:
{ #category : 'accessing' }
57
Removed:
MFTWorkoutLogComponent >> workoutLog [
58
Removed:
59
Removed:
^ workoutLog
60
Removed:
]
61
Removed:
62
Removed:
{ #category : 'accessing' }
63
Removed:
MFTWorkoutLogComponent >> workoutLog: aMFTWorkoutLog [
64
Removed:
65
Removed:
workoutLog := aMFTWorkoutLog
66
Removed:
]
src/MyFitnessTracker-Web/MFTWorkoutPrescriptionComponent.class.st
@@ -1,108 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutPrescriptionComponent',
3
Removed:
#superclass : 'WAComponent',
4
Removed:
#instVars : [
5
Removed:
'title',
6
Removed:
'isLoggable',
7
Removed:
'workoutPrescription'
8
Removed:
],
9
Removed:
#category : 'MyFitnessTracker-Web-Components',
10
Removed:
#package : 'MyFitnessTracker-Web',
11
Removed:
#tag : 'Components'
12
Removed:
}
13
Removed:
14
Removed:
{ #category : 'as yet unclassified' }
15
Removed:
MFTWorkoutPrescriptionComponent class >> forPrescription: aMFTWorkoutPrescription [
16
Removed:
17
Removed:
^ self new
18
Removed:
workoutPrescription: aMFTWorkoutPrescription;
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'rendering' }
23
Removed:
MFTWorkoutPrescriptionComponent >> initialize [
24
Removed:
25
Removed:
super initialize.
26
Removed:
isLoggable := false
27
Removed:
]
28
Removed:
29
Removed:
{ #category : 'accessing' }
30
Removed:
MFTWorkoutPrescriptionComponent >> isLoggable [
31
Removed:
32
Removed:
isLoggable := true
33
Removed:
]
34
Removed:
35
Removed:
{ #category : 'as yet unclassified' }
36
Removed:
MFTWorkoutPrescriptionComponent >> renderActionsOn: html [
37
Removed:
38
Removed:
html form: [
39
Removed:
html submitButton
40
Removed:
callback: [
41
Removed:
| workoutLog |
42
Removed:
workoutLog := self call:
43
Removed:
(MFTWorkoutLogComponent forPrescription:
44
Removed:
workoutPrescription).
45
Removed:
self session user logBook logWorkout: workoutLog ];
46
Removed:
with: 'Log Workout' ]
47
Removed:
]
48
Removed:
49
Removed:
{ #category : 'rendering' }
50
Removed:
MFTWorkoutPrescriptionComponent >> renderContentOn: html [
51
Removed:
52
Removed:
html div
53
Removed:
class: 'workout-card';
54
Removed:
with: [
55
Removed:
html heading
56
Removed:
level: 3;
57
Removed:
with: title.
58
Removed:
isLoggable ifTrue: [ self renderActionsOn: html ].
59
Removed:
self renderWorkoutSetsAsTableOn: html ]
60
Removed:
]
61
Removed:
62
Removed:
{ #category : 'as yet unclassified' }
63
Removed:
MFTWorkoutPrescriptionComponent >> renderWorkoutSetsAsTableOn: html [
64
Removed:
65
Removed:
html table: [
66
Removed:
html tableHead: [
67
Removed:
html
68
Removed:
tableHeading: 'Set';
69
Removed:
tableHeading: 'Muscle';
70
Removed:
tableHeading: 'Exercise' ].
71
Removed:
html tableBody: [
72
Removed:
workoutPrescription setGroups do: [ :setGroupPrescription |
73
Removed:
setGroupPrescription sets doWithIndex: [ :setPrescription :j |
74
Removed:
html tableRow: [
75
Removed:
j = 1 ifTrue: [
76
Removed:
html tableData
77
Removed:
rowSpan: setGroupPrescription setCount;
78
Removed:
with: setGroupPrescription ].
79
Removed:
html
80
Removed:
tableData:
81
Removed:
(setPrescription exercise mainActivatedMuscleGroups ifNotNil: [
82
Removed:
:groups | groups joinUsing: $/ ]);
83
Removed:
tableData: setPrescription exercise ] ] ] ] ]
84
Removed:
]
85
Removed:
86
Removed:
{ #category : 'accessing' }
87
Removed:
MFTWorkoutPrescriptionComponent >> title [
88
Removed:
89
Removed:
^ title
90
Removed:
]
91
Removed:
92
Removed:
{ #category : 'accessing' }
93
Removed:
MFTWorkoutPrescriptionComponent >> title: aString [
94
Removed:
95
Removed:
title := aString
96
Removed:
]
97
Removed:
98
Removed:
{ #category : 'accessing' }
99
Removed:
MFTWorkoutPrescriptionComponent >> workoutPrescription [
100
Removed:
101
Removed:
^ workoutPrescription
102
Removed:
]
103
Removed:
104
Removed:
{ #category : 'accessing' }
105
Removed:
MFTWorkoutPrescriptionComponent >> workoutPrescription: aMFTWorkoutPrescription [
106
Removed:
107
Removed:
workoutPrescription := aMFTWorkoutPrescription
108
Removed:
]