[Pharo] Personal fitness tracker web app.
Nuke components.
Let's stop using Bootstrap.
Changed files
- src/MyFitnessTracker-Components/MFTAboutPage.class.st
- src/MyFitnessTracker-Components/MFTActionsCard.class.st
- src/MyFitnessTracker-Components/MFTAnalyticsPage.class.st
- src/MyFitnessTracker-Components/MFTArticle.class.st
- src/MyFitnessTracker-Components/MFTAthletesArticle.class.st
- src/MyFitnessTracker-Components/MFTCard.class.st
- src/MyFitnessTracker-Components/MFTConfirmDialog.class.st
- src/MyFitnessTracker-Components/MFTConfirmForm.class.st
- src/MyFitnessTracker-Components/MFTDateDialog.class.st
- src/MyFitnessTracker-Components/MFTDefaultFooter.class.st
- src/MyFitnessTracker-Components/MFTDialog.class.st
- src/MyFitnessTracker-Components/MFTExercisesForm.class.st
- src/MyFitnessTracker-Components/MFTFooter.class.st
- src/MyFitnessTracker-Components/MFTForm.class.st
- src/MyFitnessTracker-Components/MFTGraph.class.st
- src/MyFitnessTracker-Components/MFTHeaderComponent.class.st
- src/MyFitnessTracker-Components/MFTHomepage.class.st
- src/MyFitnessTracker-Components/MFTLandingPage.class.st
- src/MyFitnessTracker-Components/MFTLearnPage.class.st
- src/MyFitnessTracker-Components/MFTLog.class.st
- src/MyFitnessTracker-Components/MFTLoginRegisterLogoutComponent.class.st
- src/MyFitnessTracker-Components/MFTLogsPage.class.st
- src/MyFitnessTracker-Components/MFTMainNavigationBar.class.st
- src/MyFitnessTracker-Components/MFTMainPublicCard.class.st
- src/MyFitnessTracker-Components/MFTMainUserCard.class.st
- src/MyFitnessTracker-Components/MFTMuscleComponent.class.st
- src/MyFitnessTracker-Components/MFTMuscleGroupComponent.class.st
- src/MyFitnessTracker-Components/MFTMusclesArticle.class.st
- src/MyFitnessTracker-Components/MFTPage.class.st
- src/MyFitnessTracker-Components/MFTPageManager.class.st
- src/MyFitnessTracker-Components/MFTPrimaryMuscleGroupDialog.class.st
- src/MyFitnessTracker-Components/MFTProfilePage.class.st
- src/MyFitnessTracker-Components/MFTPromisesCard.class.st
- src/MyFitnessTracker-Components/MFTPublicLandingPage.class.st
- src/MyFitnessTracker-Components/MFTRegisterProspectEmailHeader.class.st
- src/MyFitnessTracker-Components/MFTRepsDistributionGraph.class.st
- src/MyFitnessTracker-Components/MFTRootComponent.class.st
- src/MyFitnessTracker-Components/MFTSandboxPage.class.st
- src/MyFitnessTracker-Components/MFTSecondaryMuscleGroupsDialog.class.st
- src/MyFitnessTracker-Components/MFTSetGroupDialog.class.st
- src/MyFitnessTracker-Components/MFTSetGroupForm.class.st
- src/MyFitnessTracker-Components/MFTSetGroupTask.class.st
- src/MyFitnessTracker-Components/MFTSetGroupsDialog.class.st
- src/MyFitnessTracker-Components/MFTStringDialog.class.st
- src/MyFitnessTracker-Components/MFTUserComponent.class.st
- src/MyFitnessTracker-Components/MFTUserForm.class.st
- src/MyFitnessTracker-Components/MFTUserLandingPage.class.st
- src/MyFitnessTracker-Components/MFTUserTask.class.st
- src/MyFitnessTracker-Components/MFTWeightDialog.class.st
- src/MyFitnessTracker-Components/MFTWeightForm.class.st
- src/MyFitnessTracker-Components/MFTWeightVsTimeGraph.class.st
- src/MyFitnessTracker-Components/MFTWeightsCard.class.st
- src/MyFitnessTracker-Components/MFTWeightsLog.class.st
- src/MyFitnessTracker-Components/MFTWidget.class.st
- src/MyFitnessTracker-Components/MFTWorkoutComponent.class.st
- src/MyFitnessTracker-Components/MFTWorkoutForm.class.st
- src/MyFitnessTracker-Components/MFTWorkoutTask.class.st
- src/MyFitnessTracker-Components/MFTWorkoutVolumePerWeekGraph.class.st
- src/MyFitnessTracker-Components/MFTWorkoutVolumeVsTimeGraph.class.st
- src/MyFitnessTracker-Components/MFTWorkoutsCard.class.st
- src/MyFitnessTracker-Components/MFTWorkoutsLog.class.st
- src/MyFitnessTracker-Components/ManifestMyFitnessTrackerComponents.class.st
src/MyFitnessTracker-Components/MFTAboutPage.class.st
@@ -1,87 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTAboutPage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#category : 'MyFitnessTracker-Components-Pages',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Pages'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'initialization' }
10
Removed:
MFTAboutPage >> initialize [
11
Removed:
12
Removed:
super initialize.
13
Removed:
title := 'about'
14
Removed:
]
15
Removed:
16
Removed:
{ #category : 'rendering' }
17
Removed:
MFTAboutPage >> renderBackgroundOn: html [
18
Removed:
19
Removed:
html heading level1 with: 'Background'.
20
Removed:
html heading level2 with: 'Why I built this web app'.
21
Removed:
html
22
Removed:
paragraph:
23
Removed:
'I wanted a convenient way to record, perform data analysis, and create visualizations for my workouts.';
24
Removed:
paragraph:
25
Removed:
'The following features were, and still are, essential for me:';
26
Removed:
unorderedList: [
27
Removed:
html
28
Removed:
listItem: 'Free access to all app features,';
29
Removed:
listItem: 'Easy import and export of my training data,';
30
Removed:
listItem:
31
Removed:
'An extensible interface to suit a wide range of training routines.' ];
32
Removed:
paragraph:
33
Removed:
'What better way than to build my own Personal Fitness Tracker?!'.
34
Removed:
html heading level2 with: 'Who I am'.
35
Removed:
html paragraph:
36
Removed:
'I am an engineer working in Europe, with a deep passion for health and fitness. Publishing My Fitness Tracker is a way for me to give thanks to everyone who has inspired me throughtout my fitness journey.'
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'rendering' }
40
Removed:
MFTAboutPage >> renderCatchOn: html [
41
Removed:
42
Removed:
html heading level1 dangerText with: 'The catch'.
43
Removed:
html
44
Removed:
paragraph:
45
Removed:
'I''ve made some debatable compromises when it comes to My Fitness Tracker:';
46
Removed:
unorderedList: [
47
Removed:
html
48
Removed:
listItem: 'No external advertisement,';
49
Removed:
listItem:
50
Removed:
'No cookies or personally identifying information stored,';
51
Removed:
listItem:
52
Removed:
'No paid feature, except for the storage of your training data beyond ten workouts.' ];
53
Removed:
paragraph:
54
Removed:
'I know these design choices might frustrate and maybe even anger certain users; '
55
Removed:
,
56
Removed:
'thankfully, all previously existing fitness tracking services do not abide by these design principles.';
57
Removed:
paragraph:
58
Removed:
'I am developing My Fitness Tracker for my own personal use case, first and foremost; '
59
Removed:
,
60
Removed:
'secondly, for the benefit of as many other fitness enthusiasts as possible; '
61
Removed:
,
62
Removed:
'thirdly, for the enjoyment that developing this web application brings me. '
63
Removed:
,
64
Removed:
'The paid feature enables me to increase the amount of fitness enthusiasts I can cater to.'
65
Removed:
]
66
Removed:
67
Removed:
{ #category : 'rendering' }
68
Removed:
MFTAboutPage >> renderContentOn: html [
69
Removed:
70
Removed:
self renderPageOn: html with: [
71
Removed:
self renderVisionOn: html.
72
Removed:
self renderBackgroundOn: html.
73
Removed:
self renderCatchOn: html ]
74
Removed:
]
75
Removed:
76
Removed:
{ #category : 'rendering' }
77
Removed:
MFTAboutPage >> renderVisionOn: html [
78
Removed:
79
Removed:
html heading level1 with: 'The Vision'.
80
Removed:
html paragraph: [
81
Removed:
html text: 'Free, and eventually '.
82
Removed:
html anchor
83
Removed:
url: 'https://fsfe.org/index.en.html';
84
Removed:
with: 'libre'.
85
Removed:
html text:
86
Removed:
' fitness tracking for all to enjoy. No user data tracking and reselling; no features blocked for any reason.' ]
87
Removed:
]
src/MyFitnessTracker-Components/MFTActionsCard.class.st
@@ -1,26 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTActionsCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTActionsCard >> renderContentOn: html [
11
Removed:
12
Removed:
self renderCardOn: html with: [
13
Removed:
html cardBody: [
14
Removed:
html form: [
15
Removed:
html buttonGroupVertical: [
16
Removed:
html outlineButton
17
Removed:
beSecondary;
18
Removed:
formControl;
19
Removed:
callback: [ self addWorkout ];
20
Removed:
with: 'Log Workout'.
21
Removed:
html outlineButton
22
Removed:
beSecondary;
23
Removed:
formControl;
24
Removed:
callback: [ self addWeight ];
25
Removed:
with: 'Log weight' ] ] ] ]
26
Removed:
]
src/MyFitnessTracker-Components/MFTAnalyticsPage.class.st
@@ -1,70 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTAnalyticsPage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#instVars : [
5
Removed:
'type'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Pages',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Pages'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'instance creation' }
13
Removed:
MFTAnalyticsPage class >> for: aSymbol [
14
Removed:
15
Removed:
^ self new
16
Removed:
type: aSymbol;
17
Removed:
yourself
18
Removed:
]
19
Removed:
20
Removed:
{ #category : 'accessing' }
21
Removed:
MFTAnalyticsPage >> analytics [
22
Removed:
23
Removed:
^ Dictionary newFrom: {
24
Removed:
(#workouts -> {
25
Removed:
MFTRepsDistributionGraph new.
26
Removed:
MFTWorkoutVolumeVsTimeGraph new
27
Removed:
"MFTWorkoutVolumePerWeekGraph new" }).
28
Removed:
(#weights -> { MFTWeightVsTimeGraph new }) }
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'rendering' }
32
Removed:
MFTAnalyticsPage >> renderActionsButtonGroupOn: html [
33
Removed:
34
Removed:
html form class: 'my-3'; with: [
35
Removed:
html buttonGroup: [
36
Removed:
html formButton
37
Removed:
bePrimary;
38
Removed:
callback: [ self answer ];
39
Removed:
with: 'Return' ] ]
40
Removed:
]
41
Removed:
42
Removed:
{ #category : 'rendering' }
43
Removed:
MFTAnalyticsPage >> renderContentOn: html [
44
Removed:
45
Removed:
| components |
46
Removed:
components := self analytics at: type.
47
Removed:
48
Removed:
self renderPageOn: html with: [
49
Removed:
self renderActionsButtonGroupOn: html.
50
Removed:
html div
51
Removed:
style:
52
Removed:
'display: flex; flex-wrap: wrap; justify-content: space-around; gap: 1em';
53
Removed:
with: [
54
Removed:
components do: [ :each |
55
Removed:
html card: [
56
Removed:
html cardHeader: each title.
57
Removed:
html render: each ] ] ] ]
58
Removed:
]
59
Removed:
60
Removed:
{ #category : 'accessing' }
61
Removed:
MFTAnalyticsPage >> type [
62
Removed:
63
Removed:
^ type
64
Removed:
]
65
Removed:
66
Removed:
{ #category : 'accessing' }
67
Removed:
MFTAnalyticsPage >> type: anObject [
68
Removed:
69
Removed:
type := anObject
70
Removed:
]
src/MyFitnessTracker-Components/MFTArticle.class.st
@@ -1,28 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTArticle',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'title'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'rendering' }
12
Removed:
MFTArticle >> renderArticleOn: html with: aBlock [
13
Removed:
14
Removed:
html heading: title capitalized.
15
Removed:
html render: aBlock
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'accessing' }
19
Removed:
MFTArticle >> title [
20
Removed:
21
Removed:
^ title
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'accessing' }
25
Removed:
MFTArticle >> title: aString [
26
Removed:
27
Removed:
title := aString
28
Removed:
]
src/MyFitnessTracker-Components/MFTAthletesArticle.class.st
@@ -1,25 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTAthletesArticle',
3
Removed:
#superclass : 'MFTArticle',
4
Removed:
#instVars : [
5
Removed:
'athletes'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'initialization' }
12
Removed:
MFTAthletesArticle >> initialize [
13
Removed:
14
Removed:
super initialize.
15
Removed:
title := 'athletes'.
16
Removed:
athletes := { MFTMikeMentzer new }
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'rendering' }
20
Removed:
MFTAthletesArticle >> renderContentOn: html [
21
Removed:
22
Removed:
self
23
Removed:
renderArticleOn: html
24
Removed:
with: [ athletes do: [ :athlete | athlete renderContentOn: html ] ]
25
Removed:
]
src/MyFitnessTracker-Components/MFTCard.class.st
@@ -1,60 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTCard',
3
Removed:
#superclass : 'MFTWidget',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'adding' }
10
Removed:
MFTCard >> addWeight [
11
Removed:
12
Removed:
| newWeight newWeightMatchesOldWeight |
13
Removed:
newWeight := self session pageManager activePage call:
14
Removed:
MFTWeightDialog new.
15
Removed:
16
Removed:
newWeight ifNil: [ ^ self ] ifNotNil: [
17
Removed:
self session pageManager setActivePageAt: #logs.
18
Removed:
(self session pageManager mainPages at: #logs) setActiveLogAt:
19
Removed:
#weights ].
20
Removed:
21
Removed:
newWeightMatchesOldWeight := self session user weights anySatisfy: [
22
Removed:
:existingWeight |
23
Removed:
newWeight date = existingWeight date
24
Removed:
and: [
25
Removed:
newWeight value = existingWeight value ] ].
26
Removed:
newWeightMatchesOldWeight ifTrue: [ ^ self ].
27
Removed:
28
Removed:
self session user isLoggedIn
29
Removed:
ifTrue: [ self session db insert: newWeight ]
30
Removed:
ifFalse: [ self session user weights add: newWeight ]
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'adding' }
34
Removed:
MFTCard >> addWorkout [
35
Removed:
36
Removed:
| newWorkout |
37
Removed:
newWorkout := self session pageManager activePage call:
38
Removed:
MFTWorkoutForm new.
39
Removed:
newWorkout
40
Removed:
ifNil: [ ^ self ]
41
Removed:
ifNotNil: [ self session pageManager setActivePageAt: #logs ].
42
Removed:
43
Removed:
self session user isLoggedIn
44
Removed:
ifTrue: [ self session db insert: newWorkout ]
45
Removed:
ifFalse: [ self session user workouts add: newWorkout ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'rendering' }
49
Removed:
MFTCard >> renderCardOn: html with: aBlock [
50
Removed:
51
Removed:
html card: aBlock
52
Removed:
]
53
Removed:
54
Removed:
{ #category : 'rendering' }
55
Removed:
MFTCard >> renderContentOn: html [
56
Removed:
57
Removed:
self
58
Removed:
renderCardOn: html
59
Removed:
with: [ html cardBody: [ html paragraph: self defaultDescription ] ]
60
Removed:
]
src/MyFitnessTracker-Components/MFTConfirmDialog.class.st
@@ -1,28 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTConfirmDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Dialogs'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTConfirmDialog >> heading [
11
Removed:
12
Removed:
^ 'You are about to {1} a {2}:' format: {
13
Removed:
action.
14
Removed:
component class }
15
Removed:
]
16
Removed:
17
Removed:
{ #category : 'as yet unclassified' }
18
Removed:
MFTConfirmDialog >> renderContentOn: html [
19
Removed:
20
Removed:
self renderDialogOn: html with: [
21
Removed:
html render: component.
22
Removed:
html label: [
23
Removed:
html text: 'Are you sure?'.
24
Removed:
action = #delete ifTrue: [
25
Removed:
html
26
Removed:
space;
27
Removed:
strong: 'This action cannot be undone.' ] ] ]
28
Removed:
]
src/MyFitnessTracker-Components/MFTConfirmForm.class.st
@@ -1,61 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTConfirmForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'message'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Forms',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Forms'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'as yet unclassified' }
13
Removed:
MFTConfirmForm >> cancelForm [
14
Removed:
15
Removed:
self answer: false
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'initialization' }
19
Removed:
MFTConfirmForm >> initialize [
20
Removed:
21
Removed:
super initialize .
22
Removed:
heading := 'Heads up!'
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'accessing' }
26
Removed:
MFTConfirmForm >> message: anObject [
27
Removed:
28
Removed:
message := anObject
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'rendering' }
32
Removed:
MFTConfirmForm >> renderContentOn: html [
33
Removed:
34
Removed:
self renderFormOn: html with: [
35
Removed:
html
36
Removed:
text: message;
37
Removed:
break;
38
Removed:
text: 'To avoid this warning, go back and fix this issue.' ]
39
Removed:
]
40
Removed:
41
Removed:
{ #category : 'as yet unclassified' }
42
Removed:
MFTConfirmForm >> renderSubmitOn: html [
43
Removed:
44
Removed:
html buttonGroup: [
45
Removed:
html formButton
46
Removed:
beSubmit;
47
Removed:
bePrimary;
48
Removed:
callback: [ self submitForm ];
49
Removed:
with: 'Confirm'.
50
Removed:
html formButton
51
Removed:
beSubmit;
52
Removed:
beSecondary;
53
Removed:
callback: [ self cancelForm ];
54
Removed:
with: 'Cancel' ]
55
Removed:
]
56
Removed:
57
Removed:
{ #category : 'as yet unclassified' }
58
Removed:
MFTConfirmForm >> submitForm [
59
Removed:
60
Removed:
self answer: true
61
Removed:
]
src/MyFitnessTracker-Components/MFTDateDialog.class.st
@@ -1,50 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTDateDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'date'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'accessing' }
13
Removed:
MFTDateDialog >> date [
14
Removed:
15
Removed:
^ date
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'accessing' }
19
Removed:
MFTDateDialog >> date: anObject [
20
Removed:
21
Removed:
date := anObject
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'initialization' }
25
Removed:
MFTDateDialog >> initialize [
26
Removed:
27
Removed:
super initialize.
28
Removed:
date := Date today
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'rendering' }
32
Removed:
MFTDateDialog >> renderContentOn: html [
33
Removed:
34
Removed:
self renderDialogOn: html with: [
35
Removed:
html dateInput5 formControl
36
Removed:
value: date yyyymmdd;
37
Removed:
callback: [ :value |
38
Removed:
date := Date readFrom: value pattern: 'yyyy-mm-dd' ] ]
39
Removed:
]
40
Removed:
41
Removed:
{ #category : 'as yet unclassified' }
42
Removed:
MFTDateDialog >> renderSubmitOn: html [
43
Removed:
44
Removed:
html buttonGroup: [
45
Removed:
html formButton
46
Removed:
beSubmit;
47
Removed:
bePrimary;
48
Removed:
callback: [ self answer: date ];
49
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]) ]
50
Removed:
]
src/MyFitnessTracker-Components/MFTDefaultFooter.class.st
@@ -1,18 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTDefaultFooter',
3
Removed:
#superclass : 'MFTFooter',
4
Removed:
#category : 'MyFitnessTracker-Components',
5
Removed:
#package : 'MyFitnessTracker-Components'
6
Removed:
}
7
Removed:
8
Removed:
{ #category : 'rendering' }
9
Removed:
MFTDefaultFooter >> renderContentOn: html [
10
Removed:
11
Removed:
self renderFooterOn: html with: [
12
Removed:
html paragraph: [
13
Removed:
html text:
14
Removed:
'Copyright 2023–' , Date today year asString , ' Marius PETER '.
15
Removed:
html badge beSecondary with: (MFTUtils version
16
Removed:
ifNil: [ 'DEVELOP' ]
17
Removed:
ifNotNil: [ 'v' , MFTUtils version ]) ] ]
18
Removed:
]
src/MyFitnessTracker-Components/MFTDialog.class.st
@@ -1,174 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTDialog',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'heading',
6
Removed:
'subheading',
7
Removed:
'component',
8
Removed:
'action',
9
Removed:
'completion'
10
Removed:
],
11
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
12
Removed:
#package : 'MyFitnessTracker-Components',
13
Removed:
#tag : 'Dialogs'
14
Removed:
}
15
Removed:
16
Removed:
{ #category : 'actions' }
17
Removed:
MFTDialog class >> add: anObject [
18
Removed:
19
Removed:
^ self new
20
Removed:
action: #add;
21
Removed:
component: anObject;
22
Removed:
yourself
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'actions' }
26
Removed:
MFTDialog class >> delete: anObject [
27
Removed:
28
Removed:
^ self new
29
Removed:
action: #delete;
30
Removed:
component: anObject;
31
Removed:
yourself
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'actions' }
35
Removed:
MFTDialog class >> edit: anObject [
36
Removed:
37
Removed:
^ self new
38
Removed:
action: #edit;
39
Removed:
component: anObject;
40
Removed:
yourself
41
Removed:
]
42
Removed:
43
Removed:
{ #category : 'accessing' }
44
Removed:
MFTDialog >> action [
45
Removed:
46
Removed:
^ action
47
Removed:
]
48
Removed:
49
Removed:
{ #category : 'accessing' }
50
Removed:
MFTDialog >> action: anObject [
51
Removed:
52
Removed:
action := anObject
53
Removed:
]
54
Removed:
55
Removed:
{ #category : 'delegation' }
56
Removed:
MFTDialog >> answer [
57
Removed:
58
Removed:
self answer: component
59
Removed:
]
60
Removed:
61
Removed:
{ #category : 'accessing' }
62
Removed:
MFTDialog >> completion [
63
Removed:
64
Removed:
^ completion
65
Removed:
]
66
Removed:
67
Removed:
{ #category : 'accessing' }
68
Removed:
MFTDialog >> completion: anObject [
69
Removed:
70
Removed:
completion := anObject
71
Removed:
]
72
Removed:
73
Removed:
{ #category : 'accessing' }
74
Removed:
MFTDialog >> component [
75
Removed:
76
Removed:
^ component
77
Removed:
]
78
Removed:
79
Removed:
{ #category : 'accessing' }
80
Removed:
MFTDialog >> component: anObject [
81
Removed:
82
Removed:
component := anObject
83
Removed:
]
84
Removed:
85
Removed:
{ #category : 't - rotating' }
86
Removed:
MFTDialog >> heading [
87
Removed:
88
Removed:
^ action capitalized , ' ' , (heading ifNil: [
89
Removed:
('^MFT(.*)Dialog$' asRegex
90
Removed:
search: self class name;
91
Removed:
subexpression: 2) asCapitalizedPhrase ifNil: [
92
Removed:
'Default Component' ] ])
93
Removed:
]
94
Removed:
95
Removed:
{ #category : 'accessing' }
96
Removed:
MFTDialog >> heading: aString [
97
Removed:
98
Removed:
heading := aString
99
Removed:
]
100
Removed:
101
Removed:
{ #category : 'initialization' }
102
Removed:
MFTDialog >> initialize [
103
Removed:
104
Removed:
super initialize.
105
Removed:
action := #add
106
Removed:
]
107
Removed:
108
Removed:
{ #category : 'rendering' }
109
Removed:
MFTDialog >> renderCompletionOn: html [
110
Removed:
111
Removed:
completion ifNotNil: [
112
Removed:
html progress
113
Removed:
class: 'my-3';
114
Removed:
with: [
115
Removed:
html progressBar
116
Removed:
beStriped;
117
Removed:
beAnimated;
118
Removed:
successBackground;
119
Removed:
valueNow: completion;
120
Removed:
with: completion percent ] ]
121
Removed:
]
122
Removed:
123
Removed:
{ #category : 'rendering' }
124
Removed:
MFTDialog >> renderContentOn: html [
125
Removed:
126
Removed:
self renderDialogOn: html with: [
127
Removed:
html text:
128
Removed:
'By default, ' , self class name , ' doesn''t do anything.' ]
129
Removed:
]
130
Removed:
131
Removed:
{ #category : 'rendering' }
132
Removed:
MFTDialog >> renderDialogOn: html with: aBlock [
133
Removed:
134
Removed:
html container
135
Removed:
style: 'max-width: 40rem';
136
Removed:
with: [
137
Removed:
html heading level1 with: self heading.
138
Removed:
subheading ifNotNil: [
139
Removed:
html heading level3 textMuted with: subheading ].
140
Removed:
html form: [
141
Removed:
aBlock value.
142
Removed:
html horizontalRule.
143
Removed:
self renderSubmitOn: html ].
144
Removed:
self renderCompletionOn: html ]
145
Removed:
]
146
Removed:
147
Removed:
{ #category : 'rendering' }
148
Removed:
MFTDialog >> renderSubmitOn: html [
149
Removed:
150
Removed:
html buttonGroup: [
151
Removed:
html formButton
152
Removed:
beSubmit;
153
Removed:
bePrimary;
154
Removed:
beDangerIf: action = #delete;
155
Removed:
callback: [ self answer: true ];
156
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
157
Removed:
html formButton
158
Removed:
beSubmit;
159
Removed:
beSecondary;
160
Removed:
callback: [ self answer: false ];
161
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
162
Removed:
]
163
Removed:
164
Removed:
{ #category : 'accessing' }
165
Removed:
MFTDialog >> subheading [
166
Removed:
167
Removed:
^ subheading
168
Removed:
]
169
Removed:
170
Removed:
{ #category : 'accessing' }
171
Removed:
MFTDialog >> subheading: aString [
172
Removed:
173
Removed:
subheading := aString
174
Removed:
]
src/MyFitnessTracker-Components/MFTExercisesForm.class.st
@@ -1,59 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTExercisesForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'exercises'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Forms',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Forms'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'as yet unclassified' }
13
Removed:
MFTExercisesForm class >> forExerciseCount: anInteger [
14
Removed:
15
Removed:
| exercises |
16
Removed:
exercises := OrderedCollection new: anInteger.
17
Removed:
1 to: anInteger do: [ :i |
18
Removed:
exercises add: (MFTSQLite3Database allExercises at: i) ].
19
Removed:
^ self new
20
Removed:
exercises: exercises;
21
Removed:
yourself
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'accessing' }
25
Removed:
MFTExercisesForm >> exercises: anObject [
26
Removed:
27
Removed:
exercises := anObject
28
Removed:
]
29
Removed:
30
Removed:
{ #category : 'initialization' }
31
Removed:
MFTExercisesForm >> initialize [
32
Removed:
33
Removed:
super initialize.
34
Removed:
heading := 'Exercises'.
35
Removed:
exercises := OrderedCollection new
36
Removed:
]
37
Removed:
38
Removed:
{ #category : 'rendering' }
39
Removed:
MFTExercisesForm >> renderContentOn: html [
40
Removed:
41
Removed:
self renderFormOn: html with: [
42
Removed:
exercises doWithIndex: [ :selectedExercise :i |
43
Removed:
html div
44
Removed:
class: 'form-floating';
45
Removed:
marginBottom: 3;
46
Removed:
with: [
47
Removed:
html formSelect formControl
48
Removed:
list: MFTSQLite3Database allExercises;
49
Removed:
selected: selectedExercise;
50
Removed:
callback: [ :exercise | exercises at: i put: exercise ];
51
Removed:
labels: #englishName.
52
Removed:
html label: 'Exercise ' , i asString ] ] ]
53
Removed:
]
54
Removed:
55
Removed:
{ #category : 'as yet unclassified' }
56
Removed:
MFTExercisesForm >> submitForm [
57
Removed:
58
Removed:
self answer: exercises
59
Removed:
]
src/MyFitnessTracker-Components/MFTFooter.class.st
@@ -1,6 +1,6 @@
1
1
Class {
2
2
#name : 'MFTFooter',
3
Removed:
#superclass : 'SBSComponent',
3
Added:
#superclass : 'WAComponent',
4
4
#category : 'MyFitnessTracker-Components',
5
5
#package : 'MyFitnessTracker-Components'
6
6
}
@@ -8,20 +8,8 @@
8
8
{ #category : 'rendering' }
9
9
MFTFooter >> renderContentOn: html [
10
10
11
Removed:
self
12
Removed:
renderFooterOn: html
13
Removed:
with: [ html text: 'I am the default footer' ]
14
Removed:
]
15
Removed:
16
Removed:
{ #category : 'rendering' }
17
Removed:
MFTFooter >> renderFooterOn: html with: aBlock [
18
Removed:
19
Removed:
html div
20
Removed:
marginTop: 3;
21
Removed:
paddingTopAndBottom: 3;
22
Removed:
class: 'bg-light';
23
Removed:
with: [
24
Removed:
html container
25
Removed:
class: 'd-flex justify-content-center';
26
Removed:
with: [ aBlock value ] ]
11
Added:
html div with: [
12
Added:
html paragraph: [
13
Added:
html text:
14
Added:
'Copyright 2023–' , Date today year asString , ' Marius PETER ' ] ]
27
15
]
src/MyFitnessTracker-Components/MFTForm.class.st
@@ -1,84 +0,0 @@
1
Removed:
"
2
Removed:
I represent a user-fillable form.
3
Removed:
4
Removed:
Upon submitting the form (""submit"" button), I return (`WAComponent>>#answer:`) the `#modelObject` with its attributes populated by the appropriate `MFTFormComponent` subclasses.
5
Removed:
Upon canceling the form (""cancel"" button), I return `nil`.
6
Removed:
"
7
Removed:
Class {
8
Removed:
#name : 'MFTForm',
9
Removed:
#superclass : 'SBSComponent',
10
Removed:
#instVars : [
11
Removed:
'heading',
12
Removed:
'errors'
13
Removed:
],
14
Removed:
#category : 'MyFitnessTracker-Components-Forms',
15
Removed:
#package : 'MyFitnessTracker-Components',
16
Removed:
#tag : 'Forms'
17
Removed:
}
18
Removed:
19
Removed:
{ #category : 'as yet unclassified' }
20
Removed:
MFTForm >> cancelForm [
21
Removed:
22
Removed:
self answer: nil
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'initialization' }
26
Removed:
MFTForm >> initialize [
27
Removed:
28
Removed:
super initialize.
29
Removed:
heading := 'Form heading'.
30
Removed:
errors := OrderedCollection new
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'rendering' }
34
Removed:
MFTForm >> renderContentOn: html [
35
Removed:
36
Removed:
self subclassResponsibility
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'rendering' }
40
Removed:
MFTForm >> renderErrorsOn: html [
41
Removed:
42
Removed:
html listGroup
43
Removed:
marginBottom: 3;
44
Removed:
with: [
45
Removed:
errors do: [ :error | html listGroupItem beDanger with: error ] ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'as yet unclassified' }
49
Removed:
MFTForm >> renderFormOn: html with: aBlock [
50
Removed:
51
Removed:
html container
52
Removed:
style: 'max-width: 40rem';
53
Removed:
with: [
54
Removed:
html displayHeading
55
Removed:
level: 3;
56
Removed:
with: heading.
57
Removed:
self renderErrorsOn: html.
58
Removed:
html form: [
59
Removed:
aBlock value.
60
Removed:
html horizontalRule.
61
Removed:
self renderSubmitOn: html ] ]
62
Removed:
]
63
Removed:
64
Removed:
{ #category : 'as yet unclassified' }
65
Removed:
MFTForm >> renderSubmitOn: html [
66
Removed:
67
Removed:
html buttonGroup: [
68
Removed:
html formButton
69
Removed:
beSubmit;
70
Removed:
bePrimary;
71
Removed:
callback: [ self submitForm ];
72
Removed:
with: 'Submit'.
73
Removed:
html formButton
74
Removed:
beSubmit;
75
Removed:
beSecondary;
76
Removed:
callback: [ self cancelForm ];
77
Removed:
with: 'Cancel' ]
78
Removed:
]
79
Removed:
80
Removed:
{ #category : 'as yet unclassified' }
81
Removed:
MFTForm >> submitForm [
82
Removed:
83
Removed:
self subclassResponsibility
84
Removed:
]
src/MyFitnessTracker-Components/MFTGraph.class.st
@@ -1,72 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTGraph',
3
Removed:
#superclass : 'MFTWidget',
4
Removed:
#instVars : [
5
Removed:
'labels',
6
Removed:
'data'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Widgets'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'accessing' }
14
Removed:
MFTGraph >> data [
15
Removed:
16
Removed:
^ data
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'accessing' }
20
Removed:
MFTGraph >> data: anObject [
21
Removed:
22
Removed:
data := anObject
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'initialization' }
26
Removed:
MFTGraph >> initialize [
27
Removed:
28
Removed:
super initialize.
29
Removed:
labels := #( Monday Tuesday Wednesday Thursday Friday ).
30
Removed:
data := #( 5 1 6 2 7 )
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'accessing' }
34
Removed:
MFTGraph >> labels [
35
Removed:
36
Removed:
^ labels
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'accessing' }
40
Removed:
MFTGraph >> labels: anObject [
41
Removed:
42
Removed:
labels := anObject
43
Removed:
]
44
Removed:
45
Removed:
{ #category : 'rendering' }
46
Removed:
MFTGraph >> renderContentOn: html [
47
Removed:
48
Removed:
html heading level5 with: self defaultDescription.
49
Removed:
html canvas id: 'defaultGraph'.
50
Removed:
html script:
51
Removed:
'var ctx = document.getElementById("defaultGraph").getContext("2d");
52
Removed:
var defaultChart = new Chart(ctx, {
53
Removed:
type: "line",
54
Removed:
data: {
55
Removed:
labels: ' , labels asJavascript , ',
56
Removed:
datasets: [{
57
Removed:
label: "default data",
58
Removed:
data: ' , data asJavascript , ',
59
Removed:
borderWidth: 1
60
Removed:
}]
61
Removed:
}
62
Removed:
});'
63
Removed:
]
64
Removed:
65
Removed:
{ #category : 'accessing' }
66
Removed:
MFTGraph >> title [
67
Removed:
68
Removed:
^ ('^MFT(.*)Graph$' asRegex
69
Removed:
search: self class name;
70
Removed:
subexpression: 2) asCapitalizedPhrase ifNil: [
71
Removed:
'Default Graph' ]
72
Removed:
]
src/MyFitnessTracker-Components/MFTHeaderComponent.class.st
@@ -1,6 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTHeaderComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#category : 'MyFitnessTracker-Components',
5
Removed:
#package : 'MyFitnessTracker-Components'
6
Removed:
}
src/MyFitnessTracker-Components/MFTHomepage.class.st
@@ -0,0 +1,12 @@
1
Added:
Class {
2
Added:
#name : 'MFTHomepage',
3
Added:
#superclass : 'WAComponent',
4
Added:
#category : 'MyFitnessTracker-Components',
5
Added:
#package : 'MyFitnessTracker-Components'
6
Added:
}
7
Added:
8
Added:
{ #category : 'rendering' }
9
Added:
MFTHomepage >> renderContentOn: html [
10
Added:
11
Added:
html paragraph: 'foo'
12
Added:
]
src/MyFitnessTracker-Components/MFTLandingPage.class.st
@@ -1,58 +0,0 @@
1
Removed:
"
2
Removed:
I am the main landing page, I act as a dashboard for user information.
3
Removed:
"
4
Removed:
Class {
5
Removed:
#name : 'MFTLandingPage',
6
Removed:
#superclass : 'MFTPage',
7
Removed:
#instVars : [
8
Removed:
'cards'
9
Removed:
],
10
Removed:
#category : 'MyFitnessTracker-Components-Pages',
11
Removed:
#package : 'MyFitnessTracker-Components',
12
Removed:
#tag : 'Pages'
13
Removed:
}
14
Removed:
15
Removed:
{ #category : 'accessing' }
16
Removed:
MFTLandingPage >> cards [
17
Removed:
18
Removed:
^ cards
19
Removed:
]
20
Removed:
21
Removed:
{ #category : 'accessing' }
22
Removed:
MFTLandingPage >> cards: aMFTCardCollection [
23
Removed:
24
Removed:
cards := aMFTCardCollection
25
Removed:
]
26
Removed:
27
Removed:
{ #category : 'hooks' }
28
Removed:
MFTLandingPage >> children [
29
Removed:
30
Removed:
^ cards
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'as yet unclassified' }
34
Removed:
MFTLandingPage >> defaultCards [
35
Removed:
36
Removed:
^ {
37
Removed:
MFTCard new.
38
Removed:
MFTCard new.
39
Removed:
MFTCard new }
40
Removed:
]
41
Removed:
42
Removed:
{ #category : 'initialization' }
43
Removed:
MFTLandingPage >> initialize [
44
Removed:
45
Removed:
super initialize.
46
Removed:
title := 'home'.
47
Removed:
cards := self defaultCards
48
Removed:
]
49
Removed:
50
Removed:
{ #category : 'rendering' }
51
Removed:
MFTLandingPage >> renderContentOn: html [
52
Removed:
53
Removed:
self renderPageOn: html with: [
54
Removed:
html div
55
Removed:
style:
56
Removed:
'display: flex; flex-wrap: wrap; justify-content: space-around; gap: 1em';
57
Removed:
with: [ self cards do: [ :card | html render: card ] ] ]
58
Removed:
]
src/MyFitnessTracker-Components/MFTLearnPage.class.st
@@ -1,35 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTLearnPage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#instVars : [
5
Removed:
'articles',
6
Removed:
'activeArticle'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Pages',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Pages'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'initialization' }
14
Removed:
MFTLearnPage >> initialize [
15
Removed:
16
Removed:
super initialize.
17
Removed:
title := 'learn'.
18
Removed:
articles := {
19
Removed:
MFTAthletesArticle new.
20
Removed:
MFTMusclesArticle new }.
21
Removed:
activeArticle := articles first
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'rendering' }
25
Removed:
MFTLearnPage >> renderContentOn: html [
26
Removed:
27
Removed:
self renderPageOn: html with: [
28
Removed:
html navigation flexColumn with: [
29
Removed:
articles do: [ :article |
30
Removed:
html navigationLink
31
Removed:
beActiveIf: [ activeArticle = article ];
32
Removed:
callback: [ activeArticle := article ];
33
Removed:
with: article title capitalized ] ].
34
Removed:
html render: activeArticle ]
35
Removed:
]
src/MyFitnessTracker-Components/MFTLog.class.st
@@ -1,28 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTLog',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'title'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Logs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Logs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'rendering' }
13
Removed:
MFTLog >> renderLogOn: html with: aBlock [
14
Removed:
15
Removed:
html div: aBlock
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'accessing' }
19
Removed:
MFTLog >> title [
20
Removed:
21
Removed:
^ title
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'accessing' }
25
Removed:
MFTLog >> title: anObject [
26
Removed:
27
Removed:
title := anObject
28
Removed:
]
src/MyFitnessTracker-Components/MFTLoginRegisterLogoutComponent.class.st
@@ -1,154 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTLoginRegisterLogoutComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'user'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'as yet unclassified' }
12
Removed:
MFTLoginRegisterLogoutComponent >> attemptLogin: aMFTUser [
13
Removed:
"Attempt to match aMFTUser passwordHash against an existing user password_hash in the database."
14
Removed:
15
Removed:
| existingUser |
16
Removed:
aMFTUser username = 'testMFT' ifTrue: [
17
Removed:
^ self session login: MFTSQLite3Database getTestUser ].
18
Removed:
existingUser := MFTSQLite3Database getExistingUser: aMFTUser.
19
Removed:
aMFTUser passwordHash = existingUser passwordHash
20
Removed:
ifTrue: [ self session login: existingUser ]
21
Removed:
ifFalse: [ self inform: 'Login failed' ]
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'initialization' }
25
Removed:
MFTLoginRegisterLogoutComponent >> initialize [
26
Removed:
27
Removed:
super initialize.
28
Removed:
user := MFTUser new
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'as yet unclassified' }
32
Removed:
MFTLoginRegisterLogoutComponent >> logout [
33
Removed:
34
Removed:
self session logout
35
Removed:
]
36
Removed:
37
Removed:
{ #category : 'rendering' }
38
Removed:
MFTLoginRegisterLogoutComponent >> renderContentOn: html [
39
Removed:
40
Removed:
self session user isLoggedIn
41
Removed:
ifFalse: [ self renderLoginAndRegisterModalsOn: html ]
42
Removed:
ifTrue: [ self renderLogoutButtonOn: html ]
43
Removed:
]
44
Removed:
45
Removed:
{ #category : 'rendering' }
46
Removed:
MFTLoginRegisterLogoutComponent >> renderLoginAndRegisterModalsOn: html [
47
Removed:
"Logging in and registering display modal components; they are not in a form."
48
Removed:
49
Removed:
html buttonGroup: [
50
Removed:
html outlineButton
51
Removed:
beSecondary;
52
Removed:
beSmall;
53
Removed:
dataToggle: 'modal';
54
Removed:
dataTarget: '#loginModal';
55
Removed:
with: 'Login'.
56
Removed:
html outlineButton
57
Removed:
bePrimary;
58
Removed:
beSmall;
59
Removed:
dataToggle: 'modal';
60
Removed:
dataTarget: '#registerModal';
61
Removed:
with: 'Register' ].
62
Removed:
self renderLoginModalOn: html.
63
Removed:
self renderRegisterModalOn: html
64
Removed:
]
65
Removed:
66
Removed:
{ #category : 'rendering' }
67
Removed:
MFTLoginRegisterLogoutComponent >> renderLoginModalOn: html [
68
Removed:
69
Removed:
html modal
70
Removed:
id: 'loginModal';
71
Removed:
fade;
72
Removed:
with: [
73
Removed:
html modalDialog
74
Removed:
beCentered;
75
Removed:
with: [
76
Removed:
html modalContent: [
77
Removed:
html form: [
78
Removed:
html modalHeader: [
79
Removed:
html modalTitle
80
Removed:
level5;
81
Removed:
with: 'Welcome back!'.
82
Removed:
html modalCloseButton ].
83
Removed:
html modalBody with: [
84
Removed:
html formGroup: [
85
Removed:
html label: 'Username'.
86
Removed:
html textInput formControl callback: [ :value |
87
Removed:
user username: value ] ].
88
Removed:
html formGroup: [
89
Removed:
html label: 'Password'.
90
Removed:
html passwordInput formControl callback: [ :value |
91
Removed:
user passwordHashFromString: value ] ] ].
92
Removed:
html modalFooter: [
93
Removed:
html buttonGroup: [
94
Removed:
html formButton
95
Removed:
bePrimary;
96
Removed:
callback: [ self attemptLogin: user ];
97
Removed:
with: 'Login'.
98
Removed:
html formButton
99
Removed:
beSecondary;
100
Removed:
dataDismiss: 'modal';
101
Removed:
with: 'Cancel' ] ] ] ] ] ]
102
Removed:
]
103
Removed:
104
Removed:
{ #category : 'rendering' }
105
Removed:
MFTLoginRegisterLogoutComponent >> renderLogoutButtonOn: html [
106
Removed:
"Logging out is an action; the button is in a form."
107
Removed:
108
Removed:
html form: [
109
Removed:
html outlineButton
110
Removed:
beSecondary;
111
Removed:
beSmall;
112
Removed:
callback: [ self logout ];
113
Removed:
with: 'Logout' ]
114
Removed:
]
115
Removed:
116
Removed:
{ #category : 'rendering' }
117
Removed:
MFTLoginRegisterLogoutComponent >> renderRegisterModalOn: html [
118
Removed:
119
Removed:
html modal
120
Removed:
id: 'registerModal';
121
Removed:
fade;
122
Removed:
with: [
123
Removed:
html modalDialog
124
Removed:
beCentered;
125
Removed:
with: [
126
Removed:
html modalContent: [
127
Removed:
html form: [
128
Removed:
html modalHeader: [
129
Removed:
html modalTitle
130
Removed:
level5;
131
Removed:
with: 'Welcome aboard!'.
132
Removed:
html modalCloseButton ].
133
Removed:
html modalBody with: [
134
Removed:
html formGroup: [
135
Removed:
html label: 'Username'.
136
Removed:
html textInput formControl callback: [ :value |
137
Removed:
user username: value ] ].
138
Removed:
html formGroup: [
139
Removed:
html label: 'Password'.
140
Removed:
html passwordInput formControl callback: [ :value |
141
Removed:
user passwordHashFromString: value ] ] ].
142
Removed:
html modalFooter: [
143
Removed:
html buttonGroup: [
144
Removed:
html formButton
145
Removed:
bePrimary;
146
Removed:
callback: [
147
Removed:
MFTSQLite3Database registerNewUser: user.
148
Removed:
self attemptLogin: user ];
149
Removed:
with: 'Register'.
150
Removed:
html formButton
151
Removed:
beSecondary;
152
Removed:
dataDismiss: 'modal';
153
Removed:
with: 'Cancel' ] ] ] ] ] ]
154
Removed:
]
src/MyFitnessTracker-Components/MFTLogsPage.class.st
@@ -1,65 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTLogsPage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#instVars : [
5
Removed:
'logs',
6
Removed:
'activeLog'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Pages',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Pages'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'hooks' }
14
Removed:
MFTLogsPage >> children [
15
Removed:
16
Removed:
^ logs
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'initialization' }
20
Removed:
MFTLogsPage >> initialize [
21
Removed:
22
Removed:
super initialize.
23
Removed:
title := 'logs'.
24
Removed:
logs := OrderedDictionary withAll: {
25
Removed:
(#workouts -> MFTWorkoutsLog new).
26
Removed:
(#weights -> MFTWeightsLog new) }.
27
Removed:
activeLog := logs at: #workouts
28
Removed:
]
29
Removed:
30
Removed:
{ #category : 'rendering' }
31
Removed:
MFTLogsPage >> renderContentOn: html [
32
Removed:
33
Removed:
self renderPageOn: html with: [
34
Removed:
self renderLogsDropdownOn: html.
35
Removed:
html render: activeLog ]
36
Removed:
]
37
Removed:
38
Removed:
{ #category : 'rendering' }
39
Removed:
MFTLogsPage >> renderLogsDropdownOn: html [
40
Removed:
41
Removed:
html dropdown
42
Removed:
class: 'my-3';
43
Removed:
with: [
44
Removed:
html formButton
45
Removed:
id: 'dropdownMenuButton';
46
Removed:
beLarge;
47
Removed:
dropdown;
48
Removed:
dataToggle: 'dropdown';
49
Removed:
with: activeLog title capitalized.
50
Removed:
html dropdownMenu
51
Removed:
attributeAt: 'aria-labelledby' put: '"dropdownMenuButton"';
52
Removed:
with: [
53
Removed:
| inactiveLogs |
54
Removed:
inactiveLogs := logs reject: [ :log | log = activeLog ].
55
Removed:
inactiveLogs keysAndValuesDo: [ :name :log |
56
Removed:
html dropdownItem
57
Removed:
callback: [ self setActiveLogAt: name ];
58
Removed:
with: log title capitalized ] ] ]
59
Removed:
]
60
Removed:
61
Removed:
{ #category : 'accessing' }
62
Removed:
MFTLogsPage >> setActiveLogAt: aKey [
63
Removed:
64
Removed:
activeLog := logs at: aKey
65
Removed:
]
src/MyFitnessTracker-Components/MFTMainNavigationBar.class.st
@@ -1,65 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMainNavigationBar',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'loginRegisterLogout'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Navigation',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Navigation'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'as yet unclassified' }
13
Removed:
MFTMainNavigationBar >> children [
14
Removed:
15
Removed:
^ { }
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'initialization' }
19
Removed:
MFTMainNavigationBar >> initialize [
20
Removed:
21
Removed:
super initialize.
22
Removed:
loginRegisterLogout := MFTLoginRegisterLogoutComponent new
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'rendering' }
26
Removed:
MFTMainNavigationBar >> renderContentOn: html [
27
Removed:
28
Removed:
html navigationBar
29
Removed:
beLight;
30
Removed:
lightBackground;
31
Removed:
expandLarge;
32
Removed:
marginBottom: 3;
33
Removed:
paddingLeftAndRight: 3;
34
Removed:
style: 'position: sticky; top: 0; z-index: 1051';
35
Removed:
with: [ self renderNavigationBarItemsOn: html ]
36
Removed:
]
37
Removed:
38
Removed:
{ #category : 'as yet unclassified' }
39
Removed:
MFTMainNavigationBar >> renderNavigationBarItemsOn: html [
40
Removed:
41
Removed:
| pm |
42
Removed:
pm := self session pageManager.
43
Removed:
html navigationBarBrand
44
Removed:
callback: [ pm setActivePageAt: #home ];
45
Removed:
with: 'MyFitnessTracker'.
46
Removed:
"The toggler is only visible when the screen width is reduced."
47
Removed:
html navigationBarToggler
48
Removed:
beButtonType;
49
Removed:
collapse;
50
Removed:
dataTarget: '#navbarCollapsed';
51
Removed:
with: [ html navigationBarTogglerIcon ].
52
Removed:
html navigationBarCollapse collapse
53
Removed:
id: 'navbarCollapsed';
54
Removed:
class: 'justify-content-between';
55
Removed:
with: [
56
Removed:
html navigationBarNavigation: [
57
Removed:
pm mainPages keysAndValuesDo: [ :name :page |
58
Removed:
html navigationItem
59
Removed:
beActiveIf: [ pm activePage = page ];
60
Removed:
with: [
61
Removed:
html navigationLink
62
Removed:
callback: [ pm setActivePageAt: name ];
63
Removed:
with: page title capitalized ] ] ].
64
Removed:
html render: loginRegisterLogout ]
65
Removed:
]
src/MyFitnessTracker-Components/MFTMainPublicCard.class.st
@@ -1,30 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMainPublicCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTMainPublicCard >> renderContentOn: html [
11
Removed:
12
Removed:
self renderCardOn: html with: [
13
Removed:
html jumbotron
14
Removed:
class: 'p-3 bg-light h-100';
15
Removed:
with: [
16
Removed:
html displayHeading
17
Removed:
level: 1;
18
Removed:
with: 'Log, plan, share your workouts.'.
19
Removed:
html heading
20
Removed:
level: 2;
21
Removed:
textMuted;
22
Removed:
with: 'Free Software never looked so fit!'.
23
Removed:
html form: [
24
Removed:
html formButton
25
Removed:
bePrimary;
26
Removed:
beLarge;
27
Removed:
class: 'mt-3';
28
Removed:
callback: [ self addWorkout ];
29
Removed:
with: 'Log a workout' ] ] ]
30
Removed:
]
src/MyFitnessTracker-Components/MFTMainUserCard.class.st
@@ -1,41 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMainUserCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#instVars : [
5
Removed:
'lastLoginDate',
6
Removed:
'subtitle'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Widgets'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'initialization' }
14
Removed:
MFTMainUserCard >> initialize [
15
Removed:
16
Removed:
super initialize.
17
Removed:
lastLoginDate := self session user lastLoginDateAndTime.
18
Removed:
subtitle := 'Last logged in {1}, {2} at {3} UTC' format: {
19
Removed:
lastLoginDate dayOfWeekName.
20
Removed:
lastLoginDate asDate asString.
21
Removed:
lastLoginDate asTimeUTC asString }
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'rendering' }
25
Removed:
MFTMainUserCard >> renderContentOn: html [
26
Removed:
27
Removed:
| user |
28
Removed:
user := self session user.
29
Removed:
self renderCardOn: html with: [
30
Removed:
html jumbotron
31
Removed:
class: 'p-3 bg-light';
32
Removed:
with: [
33
Removed:
html displayHeading
34
Removed:
level: 1;
35
Removed:
with: [
36
Removed:
html
37
Removed:
text: 'Welcome, ';
38
Removed:
code: (user realFirstName ifEmpty: [ user username ]);
39
Removed:
text: '!' ].
40
Removed:
html big textMuted with: subtitle ] ]
41
Removed:
]
src/MyFitnessTracker-Components/MFTMuscleComponent.class.st
@@ -1,42 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMuscleComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'muscle'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'as yet unclassified' }
12
Removed:
MFTMuscleComponent class >> muscle: aMFTMuscle [
13
Removed:
14
Removed:
^ self new
15
Removed:
muscle: aMFTMuscle;
16
Removed:
yourself
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'accessing' }
20
Removed:
MFTMuscleComponent >> muscle [
21
Removed:
22
Removed:
^ muscle
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'as yet unclassified' }
26
Removed:
MFTMuscleComponent >> renderContentOn: html [
27
Removed:
28
Removed:
html table
29
Removed:
class: 'table table-striped';
30
Removed:
with: [
31
Removed:
html tableHead: [
32
Removed:
html
33
Removed:
tableHeading: 'Property';
34
Removed:
tableHeading: 'Value' ].
35
Removed:
html tableRow: [
36
Removed:
html tableData: 'Latin name'.
37
Removed:
html tableData: muscle latinName ].
38
Removed:
muscle function ifNotNil: [
39
Removed:
html tableRow: [
40
Removed:
html tableData: 'Function'.
41
Removed:
html tableData: ('This muscle {1}.' format: { muscle function }) ] ] ]
42
Removed:
]
src/MyFitnessTracker-Components/MFTMuscleGroupComponent.class.st
@@ -1,63 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMuscleGroupComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'muscleGroup'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'as yet unclassified' }
12
Removed:
MFTMuscleGroupComponent class >> antagonistIds [
13
Removed:
"TODO: is this sufficiently robust ?"
14
Removed:
15
Removed:
^ {
16
Removed:
{ 2. 4 } asSet.
17
Removed:
{ 5. 6 } asSet.
18
Removed:
{ 8. 9 } asSet.
19
Removed:
{ 8. 11 } asSet.
20
Removed:
{ 12. 13 } asSet }
21
Removed:
]
22
Removed:
23
Removed:
{ #category : 'instance creation' }
24
Removed:
MFTMuscleGroupComponent class >> newFromDictionary: aDictionary [
25
Removed:
26
Removed:
| id |
27
Removed:
id := aDictionary at: 'id'.
28
Removed:
29
Removed:
^ self new
30
Removed:
id: id;
31
Removed:
englishName: (aDictionary at: 'english_name');
32
Removed:
frenchName: (aDictionary at: 'french_name');
33
Removed:
function: (aDictionary at: 'function');
34
Removed:
muscles: (MFTSQLite3Database allMuscles select: [ :each |
35
Removed:
each primaryMuscleGroupId = id ]);
36
Removed:
yourself
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'initialization' }
40
Removed:
MFTMuscleGroupComponent >> initialize [
41
Removed:
42
Removed:
super initialize.
43
Removed:
muscleGroup := MFTMuscleGroup new
44
Removed:
]
45
Removed:
46
Removed:
{ #category : 'as yet unclassified' }
47
Removed:
MFTMuscleGroupComponent >> renderContentOn: html [
48
Removed:
49
Removed:
html heading level2 with: muscleGroup englishName capitalized.
50
Removed:
muscleGroup function ifNotNil: [
51
Removed:
html
52
Removed:
text: ('This muscle group {1}.' format: { muscleGroup function });
53
Removed:
break ].
54
Removed:
muscleGroup muscles ifNotEmpty: [
55
Removed:
html listGroup: [
56
Removed:
muscleGroup muscles do: [ :muscle |
57
Removed:
html listGroupItem: [
58
Removed:
html anchor
59
Removed:
url: muscle linkTerminologiaAnatomica;
60
Removed:
with: muscle latinName.
61
Removed:
muscle function ifNotNil: [
62
Removed:
html text: (': {1}.' format: { muscle function }) ] ] ] ] ]
63
Removed:
]
src/MyFitnessTracker-Components/MFTMusclesArticle.class.st
@@ -1,30 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTMusclesArticle',
3
Removed:
#superclass : 'MFTArticle',
4
Removed:
#instVars : [
5
Removed:
'muscleGroups'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'hooks' }
12
Removed:
MFTMusclesArticle >> children [
13
Removed:
14
Removed:
^ muscleGroups
15
Removed:
]
16
Removed:
17
Removed:
{ #category : 'initialization' }
18
Removed:
MFTMusclesArticle >> initialize [
19
Removed:
20
Removed:
super initialize.
21
Removed:
title := 'muscles'
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'rendering' }
25
Removed:
MFTMusclesArticle >> renderContentOn: html [
26
Removed:
27
Removed:
self renderArticleOn: html with: [
28
Removed:
MFTSQLite3Database allMuscleGroups do: [ :muscleGroup |
29
Removed:
html render: muscleGroup ] ]
30
Removed:
]
src/MyFitnessTracker-Components/MFTPage.class.st
@@ -1,24 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTPage',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'title'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Pages',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Pages'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'rendering' }
13
Removed:
MFTPage >> renderPageOn: html with: aBlock [
14
Removed:
15
Removed:
html container
16
Removed:
style: 'max-width: 50rem';
17
Removed:
with: aBlock
18
Removed:
]
19
Removed:
20
Removed:
{ #category : 'accessing' }
21
Removed:
MFTPage >> title [
22
Removed:
23
Removed:
^ title
24
Removed:
]
src/MyFitnessTracker-Components/MFTPageManager.class.st
@@ -2,9 +2,7 @@
2
2
#name : 'MFTPageManager',
3
3
#superclass : 'Object',
4
4
#instVars : [
5
Removed:
'mainNavigationBar',
6
5
'mainPages',
7
Removed:
'header',
8
6
'footer',
9
7
'activePage'
10
8
],
@@ -27,12 +25,7 @@
27
25
{ #category : 'as yet unclassified' }
28
26
MFTPageManager >> defaultPublicPages [
29
27
30
Removed:
^ OrderedDictionary newFrom: {
31
Removed:
(#home -> MFTPublicLandingPage new).
32
Removed:
(#logs -> MFTLogsPage new).
33
Removed:
"(#learn -> MFTLearnPage new).
34
Removed:
(#about -> MFTAboutPage new).
35
Removed:
(#profile -> MFTProfilePage new)" }
28
Added:
^ OrderedDictionary newFrom: { (#home -> MFTHomepage new) }
36
29
]
37
30
38
31
{ #category : 'accessing' }
@@ -47,26 +40,12 @@
47
40
footer := anObject
48
41
]
49
42
50
Removed:
{ #category : 'accessing' }
51
Removed:
MFTPageManager >> header [
52
Removed:
53
Removed:
^ header
54
Removed:
]
55
Removed:
56
Removed:
{ #category : 'accessing' }
57
Removed:
MFTPageManager >> header: anObject [
58
Removed:
59
Removed:
header := anObject
60
Removed:
]
61
Removed:
62
43
{ #category : 'initialization' }
63
44
MFTPageManager >> initialize [
64
45
65
46
mainPages := self defaultPublicPages.
66
47
activePage := mainPages at: #home.
67
Removed:
mainNavigationBar := MFTMainNavigationBar new.
68
Removed:
header := MFTRegisterProspectEmailHeader new.
69
Removed:
footer := MFTDefaultFooter new
48
Added:
footer := MFTFooter new
70
49
]
71
50
72
51
{ #category : 'as yet unclassified' }
@@ -74,25 +53,6 @@
74
53
75
54
mainPages := self defaultPublicPages.
76
55
self setActivePageAt: #home
77
Removed:
]
78
Removed:
79
Removed:
{ #category : 'as yet unclassified' }
80
Removed:
MFTPageManager >> loadUserPages [
81
Removed:
82
Removed:
mainPages at: #home put: MFTUserLandingPage new.
83
Removed:
self setActivePageAt: #home
84
Removed:
]
85
Removed:
86
Removed:
{ #category : 'accessing' }
87
Removed:
MFTPageManager >> mainNavigationBar [
88
Removed:
89
Removed:
^ mainNavigationBar
90
Removed:
]
91
Removed:
92
Removed:
{ #category : 'accessing' }
93
Removed:
MFTPageManager >> mainNavigationBar: anObject [
94
Removed:
95
Removed:
mainNavigationBar := anObject
96
56
]
97
57
98
58
{ #category : 'accessing' }
src/MyFitnessTracker-Components/MFTPrimaryMuscleGroupDialog.class.st
@@ -1,63 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTPrimaryMuscleGroupDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'primaryMuscleGroup'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'initialization' }
13
Removed:
MFTPrimaryMuscleGroupDialog >> initialize [
14
Removed:
15
Removed:
super initialize.
16
Removed:
primaryMuscleGroup := MFTMuscleGroup new
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'accessing' }
20
Removed:
MFTPrimaryMuscleGroupDialog >> primaryMuscleGroup [
21
Removed:
22
Removed:
^ primaryMuscleGroup
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'accessing' }
26
Removed:
MFTPrimaryMuscleGroupDialog >> primaryMuscleGroup: anObject [
27
Removed:
28
Removed:
primaryMuscleGroup := anObject
29
Removed:
]
30
Removed:
31
Removed:
{ #category : 'rendering' }
32
Removed:
MFTPrimaryMuscleGroupDialog >> renderContentOn: html [
33
Removed:
34
Removed:
| allMuscleGroups selectedMuscleGroup |
35
Removed:
allMuscleGroups := MFTSQLite3Database allMuscleGroups.
36
Removed:
selectedMuscleGroup := primaryMuscleGroup ifNotNil: [
37
Removed:
allMuscleGroups detect: [ :muscleGroup |
38
Removed:
muscleGroup englishName
39
Removed:
= primaryMuscleGroup englishName ] ].
40
Removed:
self renderDialogOn: html with: [
41
Removed:
html formGroup: [
42
Removed:
html select formControl
43
Removed:
list: allMuscleGroups;
44
Removed:
selected: selectedMuscleGroup;
45
Removed:
labels: [ :muscleGroup | muscleGroup englishName ];
46
Removed:
callback: [ :group | primaryMuscleGroup := group ] ] ]
47
Removed:
]
48
Removed:
49
Removed:
{ #category : 'rendering' }
50
Removed:
MFTPrimaryMuscleGroupDialog >> renderSubmitOn: html [
51
Removed:
52
Removed:
html buttonGroup: [
53
Removed:
html formButton
54
Removed:
beSubmit;
55
Removed:
bePrimary;
56
Removed:
callback: [ self answer: primaryMuscleGroup ];
57
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
58
Removed:
html formButton
59
Removed:
beSubmit;
60
Removed:
beSecondary;
61
Removed:
callback: [ self answer: nil ];
62
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
63
Removed:
]
src/MyFitnessTracker-Components/MFTProfilePage.class.st
@@ -1,47 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTProfilePage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#category : 'MyFitnessTracker-Components-Pages',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Pages'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTProfilePage >> editProfile [
11
Removed:
12
Removed:
| updatedUser |
13
Removed:
updatedUser := self session pageManager activePage call:
14
Removed:
(MFTUserForm new user: self session user).
15
Removed:
updatedUser ifNil: [ ^ self ].
16
Removed:
self session user: updatedUser.
17
Removed:
self session user isLoggedIn ifTrue: [
18
Removed:
self session db updateUserWith: updatedUser ]
19
Removed:
]
20
Removed:
21
Removed:
{ #category : 'initialization' }
22
Removed:
MFTProfilePage >> initialize [
23
Removed:
24
Removed:
super initialize.
25
Removed:
title := 'profile'
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'rendering' }
29
Removed:
MFTProfilePage >> renderContentOn: html [
30
Removed:
31
Removed:
| user |
32
Removed:
user := self session user.
33
Removed:
34
Removed:
self renderPageOn: html with: [
35
Removed:
self renderProfileActionsOn: html.
36
Removed:
html render: user ]
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'rendering' }
40
Removed:
MFTProfilePage >> renderProfileActionsOn: html [
41
Removed:
42
Removed:
html form: [
43
Removed:
html formButton
44
Removed:
bePrimary;
45
Removed:
callback: [ self editProfile ];
46
Removed:
with: 'Edit profile' ]
47
Removed:
]
src/MyFitnessTracker-Components/MFTPromisesCard.class.st
@@ -1,30 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTPromisesCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTPromisesCard >> renderContentOn: html [
11
Removed:
12
Removed:
self renderCardOn: html with: [
13
Removed:
html cardHeader: 'My promises to all users:'.
14
Removed:
html cardBody: [
15
Removed:
html listGroup: [
16
Removed:
html
17
Removed:
listGroupItem:
18
Removed:
'Every single feature shall always be free of charge.';
19
Removed:
listGroupItem:
20
Removed:
'No personal user data shall ever be sold, under any circumstances.';
21
Removed:
listGroupItem:
22
Removed:
'No external advertisements shall ever be displayed.' ].
23
Removed:
html form
24
Removed:
class: 'mt-3';
25
Removed:
with: [
26
Removed:
html outlineButton
27
Removed:
bePrimary;
28
Removed:
callback: [ self session pageManager setActivePageAt: #about ];
29
Removed:
with: 'Why did I create this web app?' ] ] ]
30
Removed:
]
src/MyFitnessTracker-Components/MFTPublicLandingPage.class.st
@@ -1,17 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTPublicLandingPage',
3
Removed:
#superclass : 'MFTLandingPage',
4
Removed:
#category : 'MyFitnessTracker-Components-Pages',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Pages'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTPublicLandingPage >> defaultCards [
11
Removed:
12
Removed:
^ {
13
Removed:
MFTMainPublicCard new.
14
Removed:
"MFTWorkoutsCard new."
15
Removed:
"MFTWeightsCard new."
16
Removed:
MFTPromisesCard new }
17
Removed:
]
src/MyFitnessTracker-Components/MFTRegisterProspectEmailHeader.class.st
@@ -1,137 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTRegisterProspectEmailHeader',
3
Removed:
#superclass : 'MFTHeaderComponent',
4
Removed:
#instVars : [
5
Removed:
'email',
6
Removed:
'localPart',
7
Removed:
'domain',
8
Removed:
'isDismissed'
9
Removed:
],
10
Removed:
#category : 'MyFitnessTracker-Components',
11
Removed:
#package : 'MyFitnessTracker-Components'
12
Removed:
}
13
Removed:
14
Removed:
{ #category : 'adding' }
15
Removed:
MFTRegisterProspectEmailHeader >> addUserEmail [
16
Removed:
17
Removed:
| emailToCheck emailPattern |
18
Removed:
emailToCheck := self call: MFTEmailSignupDialog new.
19
Removed:
emailPattern := '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]{3,}\.[a-zA-Z]{2,}$'
20
Removed:
asRegex.
21
Removed:
(emailToCheck isNil or: [ (emailPattern matches: emailToCheck) not ])
22
Removed:
ifTrue: [ ^ nil ].
23
Removed:
email := emailToCheck.
24
Removed:
MFTSQLite3Database storeProspectEmail: email
25
Removed:
]
26
Removed:
27
Removed:
{ #category : 'initialization' }
28
Removed:
MFTRegisterProspectEmailHeader >> initialize [
29
Removed:
30
Removed:
super initialize.
31
Removed:
isDismissed := false
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'accessing' }
35
Removed:
MFTRegisterProspectEmailHeader >> isDismissed [
36
Removed:
37
Removed:
^ isDismissed
38
Removed:
]
39
Removed:
40
Removed:
{ #category : 'accessing' }
41
Removed:
MFTRegisterProspectEmailHeader >> isDismissed: anObject [
42
Removed:
43
Removed:
isDismissed := anObject
44
Removed:
]
45
Removed:
46
Removed:
{ #category : 'rendering' }
47
Removed:
MFTRegisterProspectEmailHeader >> renderContentOn: html [
48
Removed:
49
Removed:
isDismissed ifTrue: [ ^ self ].
50
Removed:
email
51
Removed:
ifNil: [
52
Removed:
html alert
53
Removed:
beWarning;
54
Removed:
marginBottom: 0;
55
Removed:
with: [
56
Removed:
html alertHeading: 'This app is still in beta.'.
57
Removed:
html paragraph: [
58
Removed:
html
59
Removed:
text:
60
Removed:
'My Fitness Tracker is still under heavy development, with improvements being made daily.';
61
Removed:
space;
62
Removed:
text: 'I can''t wait to share the finished product with you!' ].
63
Removed:
html form with: [
64
Removed:
html label
65
Removed:
style: 'margin-right: 1em';
66
Removed:
with: [ html strong: 'Want to know when version 1.0 is out?' ].
67
Removed:
html buttonGroup: [
68
Removed:
html formButton
69
Removed:
beInfo;
70
Removed:
callback: [ self addUserEmail ];
71
Removed:
with: 'E-mail me!'.
72
Removed:
html formButton
73
Removed:
beSecondary;
74
Removed:
callback: [ isDismissed := true ];
75
Removed:
with: 'I''m not interested' ] ] ] ]
76
Removed:
ifNotNil: [
77
Removed:
html alert
78
Removed:
beSuccess;
79
Removed:
beDismissible;
80
Removed:
marginBottom: 0;
81
Removed:
with: [
82
Removed:
html closeButton dataDismiss: 'alert'.
83
Removed:
html
84
Removed:
text: 'You''ll be notified at ';
85
Removed:
strong: email;
86
Removed:
text: ' when My Fitness Tracker is ready for you!' ] ]
87
Removed:
]
88
Removed:
89
Removed:
{ #category : 'rendering' }
90
Removed:
MFTRegisterProspectEmailHeader >> renderEmailInputModalButtonOn: html [
91
Removed:
92
Removed:
html formButton
93
Removed:
bePrimary;
94
Removed:
beSmall;
95
Removed:
dataToggle: 'modal';
96
Removed:
dataTarget: '#emailInputModal';
97
Removed:
with: 'E-mail me!'
98
Removed:
]
99
Removed:
100
Removed:
{ #category : 'rendering' }
101
Removed:
MFTRegisterProspectEmailHeader >> renderEmailInputModalOn: html [
102
Removed:
103
Removed:
html modal
104
Removed:
id: 'emailInputModal';
105
Removed:
fade;
106
Removed:
with: [
107
Removed:
html modalDialog
108
Removed:
beCentered;
109
Removed:
with: [
110
Removed:
html modalContent: [
111
Removed:
html form: [
112
Removed:
html modalHeader: [
113
Removed:
html modalTitle
114
Removed:
level5;
115
Removed:
with:
116
Removed:
'You''ll be the first to know when My Fitness Tracker is ready to use.'.
117
Removed:
html modalCloseButton ].
118
Removed:
119
Removed:
html modalBody: [
120
Removed:
html inputGroup: [
121
Removed:
html formTextInput
122
Removed:
callback: [ :value | localPart := value ];
123
Removed:
placeholder: 'my-user'.
124
Removed:
html inputGroupAppend: [ html inputGroupText: '@' ].
125
Removed:
html formTextInput
126
Removed:
callback: [ :value | domain := value ];
127
Removed:
placeholder: 'example.com' ] ].
128
Removed:
129
Removed:
html modalFooter: [
130
Removed:
html paragraph:
131
Removed:
'You will receive a single e-mail when the app is ready to use. Your e-mail address shall not be used in any other way.'.
132
Removed:
html formButton
133
Removed:
bePrimary;
134
Removed:
beSubmit;
135
Removed:
callback: [ email := localPart , '@' , domain ];
136
Removed:
with: 'Confirm' ] ] ] ] ]
137
Removed:
]
src/MyFitnessTracker-Components/MFTRepsDistributionGraph.class.st
@@ -1,54 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTRepsDistributionGraph',
3
Removed:
#superclass : 'MFTGraph',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTRepsDistributionGraph >> crunchTheNumbers [
11
Removed:
"TODO: This looks ugly."
12
Removed:
13
Removed:
| sets repTally |
14
Removed:
sets := self session user workouts flatCollect: #sets.
15
Removed:
repTally := Dictionary new.
16
Removed:
sets do: [ :set |
17
Removed:
repTally at: set exercise englishName ifAbsentPut: [ 0 ].
18
Removed:
repTally
19
Removed:
at: set exercise englishName
20
Removed:
put: (repTally at: set exercise englishName) + set reps ].
21
Removed:
22
Removed:
labels := repTally keys.
23
Removed:
data := repTally values
24
Removed:
]
25
Removed:
26
Removed:
{ #category : 'initialization' }
27
Removed:
MFTRepsDistributionGraph >> initialize [
28
Removed:
29
Removed:
super initialize.
30
Removed:
self crunchTheNumbers
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'rendering' }
34
Removed:
MFTRepsDistributionGraph >> renderContentOn: html [
35
Removed:
36
Removed:
html canvas id: 'repsVsTimeChart'.
37
Removed:
html script:
38
Removed:
'var ctx = document.getElementById("repsVsTimeChart").getContext("2d");
39
Removed:
var workoutChart = new Chart(ctx, {
40
Removed:
type: "doughnut",
41
Removed:
data: {
42
Removed:
labels: ' , labels asJavascript , ',
43
Removed:
datasets: [{
44
Removed:
data: ' , data asJavascript , '
45
Removed:
}]
46
Removed:
},
47
Removed:
options: {
48
Removed:
title: {
49
Removed:
display: true,
50
Removed:
text: "Reps by exercise"
51
Removed:
}
52
Removed:
}
53
Removed:
});'
54
Removed:
]
src/MyFitnessTracker-Components/MFTRootComponent.class.st
@@ -1,6 +1,6 @@
1
1
Class {
2
2
#name : 'MFTRootComponent',
3
Removed:
#superclass : 'SBSRootComponent',
3
Added:
#superclass : 'WAComponent',
4
4
#instVars : [
5
5
'pageManager'
6
6
],
@@ -17,47 +17,16 @@
17
17
{ #category : 'class initialization' }
18
18
MFTRootComponent class >> initialize [
19
19
20
Removed:
| application libraries |
20
Added:
| application |
21
21
application := WAAdmin register: self asApplicationAt: 'mft'.
22
22
application preferenceAt: #sessionClass put: MFTSession.
23
Removed:
libraries := MFTUtils isDevelopmentImage
24
Removed:
ifTrue: [ self libraries at: #development ]
25
Removed:
ifFalse: [ self libraries at: #deployment ].
26
Removed:
libraries do: [ :library | application addLibrary: library ].
27
23
^ application
28
24
]
29
25
30
Removed:
{ #category : 'class initialization' }
31
Removed:
MFTRootComponent class >> libraries [
32
Removed:
33
Removed:
^ Dictionary new
34
Removed:
at: #development put: {
35
Removed:
JQDevelopmentLibrary.
36
Removed:
JQUiDevelopmentLibrary.
37
Removed:
SBSDevelopmentLibrary };
38
Removed:
at: #deployment put: {
39
Removed:
JQGoogleLibrary.
40
Removed:
JQUiGoogleLibrary.
41
Removed:
SBSCDNDeploymentLibrary };
42
Removed:
yourself
43
Removed:
]
44
Removed:
45
Removed:
{ #category : 'adding' }
46
Removed:
MFTRootComponent >> addBootstrapJSScriptTo: html [
47
Removed:
48
Removed:
| library |
49
Removed:
library := MFTUtils isDevelopmentImage
50
Removed:
ifTrue: [ SBSDeploymentLibrary ]
51
Removed:
ifFalse: [ SBSCDNDeploymentLibrary ].
52
Removed:
library addLoadScriptTo: html
53
Removed:
]
54
Removed:
55
26
{ #category : 'hooks' }
56
27
MFTRootComponent >> children [
57
28
58
29
^ {
59
Removed:
pageManager header.
60
Removed:
pageManager mainNavigationBar.
61
30
pageManager activePage.
62
31
pageManager footer }
63
32
]
@@ -72,14 +41,9 @@
72
41
{ #category : 'rendering' }
73
42
MFTRootComponent >> renderContentOn: html [
74
43
75
Removed:
(self session user isLoggedIn not and: [
76
Removed:
MFTUtils isDevelopmentImage not ]) ifTrue: [
77
Removed:
html render: pageManager header ].
78
44
html
79
Removed:
render: pageManager mainNavigationBar;
80
45
render: pageManager activePage;
81
Removed:
render: pageManager footer.
82
Removed:
self addBootstrapJSScriptTo: html
46
Added:
render: pageManager footer
83
47
]
84
48
85
49
{ #category : 'updating' }
@@ -94,10 +58,4 @@
94
58
anHtmlRoot link
95
59
beShortcutIcon;
96
60
url: MFTFileLibrary / #faviconPng
97
Removed:
]
98
Removed:
99
Removed:
{ #category : 'versions' }
100
Removed:
MFTRootComponent >> version [
101
Removed:
102
Removed:
^ MFTUtils version ifNil: [ '[DEVELOP]' ]
103
61
]
src/MyFitnessTracker-Components/MFTSandboxPage.class.st
@@ -1,22 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSandboxPage',
3
Removed:
#superclass : 'MFTPage',
4
Removed:
#category : 'MyFitnessTracker-Components-Pages',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Pages'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'initialization' }
10
Removed:
MFTSandboxPage >> initialize [
11
Removed:
12
Removed:
super initialize.
13
Removed:
title := 'sandbox'
14
Removed:
]
15
Removed:
16
Removed:
{ #category : 'rendering' }
17
Removed:
MFTSandboxPage >> renderContentOn: html [
18
Removed:
19
Removed:
self renderPageOn: html with: [
20
Removed:
html text: 'Welcome to the sandbox page.'.
21
Removed:
MFTSQLite3Database allMuscleGroups do: [ :each | html render: each ] ]
22
Removed:
]
src/MyFitnessTracker-Components/MFTSecondaryMuscleGroupsDialog.class.st
@@ -1,65 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSecondaryMuscleGroupsDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'secondaryMuscleGroups'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'initialization' }
13
Removed:
MFTSecondaryMuscleGroupsDialog >> initialize [
14
Removed:
15
Removed:
super initialize.
16
Removed:
secondaryMuscleGroups := OrderedCollection new
17
Removed:
]
18
Removed:
19
Removed:
{ #category : 'rendering' }
20
Removed:
MFTSecondaryMuscleGroupsDialog >> renderContentOn: html [
21
Removed:
22
Removed:
| allMuscleGroups selectedMuscles |
23
Removed:
allMuscleGroups := MFTSQLite3Database allMuscleGroups.
24
Removed:
"selectedMuscles := allMuscles
25
Removed:
detect: [ :each |
26
Removed:
each englishName
27
Removed:
= (secondaryMuscles collect: #englishName) ]
28
Removed:
ifNone: [ nil ]."
29
Removed:
30
Removed:
self renderDialogOn: html with: [
31
Removed:
html multiSelect formControl
32
Removed:
list: allMuscleGroups;
33
Removed:
"selected: selectedMuscles;"labels: [ :muscleGroup |
34
Removed:
muscleGroup englishName ];
35
Removed:
callback: [ :groups |
36
Removed:
groups ifNotEmpty: [ secondaryMuscleGroups := groups ] ] ]
37
Removed:
]
38
Removed:
39
Removed:
{ #category : 'rendering' }
40
Removed:
MFTSecondaryMuscleGroupsDialog >> renderSubmitOn: html [
41
Removed:
42
Removed:
html buttonGroup: [
43
Removed:
html formButton
44
Removed:
beSubmit;
45
Removed:
bePrimary;
46
Removed:
callback: [ self answer: secondaryMuscleGroups ];
47
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
48
Removed:
html formButton
49
Removed:
beSubmit;
50
Removed:
beSecondary;
51
Removed:
callback: [ self answer: OrderedCollection new ];
52
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
53
Removed:
]
54
Removed:
55
Removed:
{ #category : 'accessing' }
56
Removed:
MFTSecondaryMuscleGroupsDialog >> secondaryMuscleGroups [
57
Removed:
58
Removed:
^ secondaryMuscleGroups
59
Removed:
]
60
Removed:
61
Removed:
{ #category : 'accessing' }
62
Removed:
MFTSecondaryMuscleGroupsDialog >> secondaryMuscleGroups: anObject [
63
Removed:
64
Removed:
secondaryMuscleGroups := anObject
65
Removed:
]
src/MyFitnessTracker-Components/MFTSetGroupDialog.class.st
@@ -1,319 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSetGroupDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'allExercises',
6
Removed:
'selectedExercises',
7
Removed:
'setGroup'
8
Removed:
],
9
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
10
Removed:
#package : 'MyFitnessTracker-Components',
11
Removed:
#tag : 'Dialogs'
12
Removed:
}
13
Removed:
14
Removed:
{ #category : 'as yet unclassified' }
15
Removed:
MFTSetGroupDialog >> addSet [
16
Removed:
17
Removed:
| set |
18
Removed:
set := self call:
19
Removed:
(MFTSetDialog newForExercise: selectedExercises first).
20
Removed:
set ifNil: [ ^ self ].
21
Removed:
setGroup sets ifEmpty: [ setGroup := MFTSetGroup new ].
22
Removed:
setGroup addSet: (set exercise: selectedExercises first)
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'as yet unclassified' }
26
Removed:
MFTSetGroupDialog >> addSets: aMFTExerciseCollection [
27
Removed:
28
Removed:
| sets |
29
Removed:
sets := self call:
30
Removed:
((MFTSetsDialog newForExercises:
31
Removed:
aMFTExerciseCollection) subheading:
32
Removed:
((selectedExercises collect: #englishName) joinUsing: '/')).
33
Removed:
sets ifNotEmpty: [ setGroup addSets: sets ]
34
Removed:
]
35
Removed:
36
Removed:
{ #category : 'as yet unclassified' }
37
Removed:
MFTSetGroupDialog >> editSet: aMFTSet [
38
Removed:
39
Removed:
| oldSet newSet |
40
Removed:
oldSet := aMFTSet.
41
Removed:
newSet := self call:
42
Removed:
(MFTSetDialog
43
Removed:
edit: oldSet copy
44
Removed:
withExercise: selectedExercises first).
45
Removed:
newSet ifNotNil: [ setGroup updateSet: oldSet with: newSet ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'as yet unclassified' }
49
Removed:
MFTSetGroupDialog >> editSets: aMFTSetCollection [
50
Removed:
51
Removed:
| oldSets newSets |
52
Removed:
oldSets := aMFTSetCollection.
53
Removed:
newSets := self call:
54
Removed:
(MFTSetsDialog
55
Removed:
edit: oldSets copy
56
Removed:
withExercises: selectedExercises).
57
Removed:
newSets ifNotEmpty: [ setGroup updateSets: oldSets with: newSets ]
58
Removed:
]
59
Removed:
60
Removed:
{ #category : 'initialization' }
61
Removed:
MFTSetGroupDialog >> initialize [
62
Removed:
63
Removed:
super initialize.
64
Removed:
setGroup := MFTSetGroup new sets:
65
Removed:
(OrderedCollection with: (MFTSet new reps: 8)).
66
Removed:
allExercises := MFTSQLite3Database allExercises.
67
Removed:
selectedExercises := OrderedCollection with: allExercises first
68
Removed:
]
69
Removed:
70
Removed:
{ #category : 'as yet unclassified' }
71
Removed:
MFTSetGroupDialog >> makeGiantSet [
72
Removed:
73
Removed:
self heading: 'Giant Sets'.
74
Removed:
selectedExercises := OrderedCollection withAll:
75
Removed:
(allExercises copyFrom: 1 to: 5).
76
Removed:
self populateSetsForExercises: selectedExercises
77
Removed:
]
78
Removed:
79
Removed:
{ #category : 'as yet unclassified' }
80
Removed:
MFTSetGroupDialog >> makeRegularExercise [
81
Removed:
82
Removed:
self heading: 'Sets'.
83
Removed:
selectedExercises := OrderedCollection with: allExercises first.
84
Removed:
self populateSetsForExercises: selectedExercises
85
Removed:
]
86
Removed:
87
Removed:
{ #category : 'as yet unclassified' }
88
Removed:
MFTSetGroupDialog >> makeSuperset [
89
Removed:
90
Removed:
self heading: 'Supersets'.
91
Removed:
selectedExercises := OrderedCollection
92
Removed:
with: allExercises first
93
Removed:
with: allExercises second.
94
Removed:
self populateSetsForExercises: selectedExercises
95
Removed:
]
96
Removed:
97
Removed:
{ #category : 'as yet unclassified' }
98
Removed:
MFTSetGroupDialog >> makeTriset [
99
Removed:
100
Removed:
self heading: 'Tri-sets'.
101
Removed:
selectedExercises := OrderedCollection
102
Removed:
with: allExercises first
103
Removed:
with: allExercises second
104
Removed:
with: allExercises third.
105
Removed:
self populateSetsForExercises: selectedExercises
106
Removed:
]
107
Removed:
108
Removed:
{ #category : 'as yet unclassified' }
109
Removed:
MFTSetGroupDialog >> populateSetsForExercises: aMFTExerciseCollection [
110
Removed:
111
Removed:
setGroup := MFTSetGroup new sets:
112
Removed:
(aMFTExerciseCollection collect: [ :exercise |
113
Removed:
MFTSet new
114
Removed:
reps: 8;
115
Removed:
exercise: exercise ])
116
Removed:
]
117
Removed:
118
Removed:
{ #category : 'as yet unclassified' }
119
Removed:
MFTSetGroupDialog >> renderConfigureSetGroupButtonsOn: html [
120
Removed:
121
Removed:
selectedExercises size = 1
122
Removed:
ifTrue: [
123
Removed:
html outlineButton bePrimary beSmall
124
Removed:
class: 'me-2';
125
Removed:
callback: [ self addSet ];
126
Removed:
with: 'Add set' ]
127
Removed:
ifFalse: [
128
Removed:
html outlineButton bePrimary beSmall
129
Removed:
class: 'me-2';
130
Removed:
callback: [ self addSets: selectedExercises ];
131
Removed:
with: 'Add set group' ].
132
Removed:
html buttonGroup: [
133
Removed:
selectedExercises size ~~ 1 ifTrue: [
134
Removed:
html outlineButton beSecondary beSmall
135
Removed:
callback: [ self makeRegularExercise ];
136
Removed:
with: 'Regular exercise' ].
137
Removed:
selectedExercises size ~~ 2 ifTrue: [
138
Removed:
html outlineButton beSecondary beSmall
139
Removed:
callback: [ self makeSuperset ];
140
Removed:
with: 'Superset' ].
141
Removed:
selectedExercises size ~~ 3 ifTrue: [
142
Removed:
html outlineButton beSecondary beSmall
143
Removed:
callback: [ self makeTriset ];
144
Removed:
with: 'Tri-set' ].
145
Removed:
selectedExercises size < 4 ifTrue: [
146
Removed:
html outlineButton beSecondary beSmall
147
Removed:
callback: [ self makeGiantSet ];
148
Removed:
with: 'Giant set' ] ]
149
Removed:
]
150
Removed:
151
Removed:
{ #category : 'rendering' }
152
Removed:
MFTSetGroupDialog >> renderContentOn: html [
153
Removed:
154
Removed:
self renderDialogOn: html with: [
155
Removed:
self renderSelectExercisesOn: html.
156
Removed:
html horizontalRule.
157
Removed:
setGroup sets ifNotEmpty: [ self renderSetGroupTableOn: html ].
158
Removed:
self renderConfigureSetGroupButtonsOn: html ]
159
Removed:
]
160
Removed:
161
Removed:
{ #category : 'as yet unclassified' }
162
Removed:
MFTSetGroupDialog >> renderSelectExercisesOn: html [
163
Removed:
164
Removed:
| allSets |
165
Removed:
allSets := setGroup sets.
166
Removed:
selectedExercises doWithIndex: [ :selectedExercise :i |
167
Removed:
html formGroup: [
168
Removed:
html label: 'Exercise ' , (selectedExercises size > 1
169
Removed:
ifTrue: [ i asString ]
170
Removed:
ifFalse: [ '' ]).
171
Removed:
html select formControl
172
Removed:
list: allExercises;
173
Removed:
selected: selectedExercise;
174
Removed:
callback: [ :exercise |
175
Removed:
selectedExercises at: i put: exercise.
176
Removed:
self updateAllSelectedExercises ];
177
Removed:
labels: [ :each | each englishName ] ] ]
178
Removed:
]
179
Removed:
180
Removed:
{ #category : 'rendering' }
181
Removed:
MFTSetGroupDialog >> renderSetGroupRowsOn: html [
182
Removed:
183
Removed:
setGroup sets doWithIndex: [ :set :i |
184
Removed:
(i - 1 isDivisibleBy: selectedExercises size) ifTrue: [
185
Removed:
| selectedSets |
186
Removed:
selectedSets := setGroup sets atAll:
187
Removed:
(i to: i + selectedExercises size - 1).
188
Removed:
html tableRow with: [
189
Removed:
html tableData
190
Removed:
attributeAt: 'rowspan' put: selectedExercises size + 1;
191
Removed:
style: 'vertical-align: middle';
192
Removed:
with: [
193
Removed:
html buttonGroup: [
194
Removed:
html outlineButton
195
Removed:
beDanger;
196
Removed:
beSmall;
197
Removed:
callback: [ setGroup removeSets: selectedSets ];
198
Removed:
with: 'Remove'.
199
Removed:
html outlineButton
200
Removed:
beSecondary;
201
Removed:
beSmall;
202
Removed:
callback: [
203
Removed:
selectedSets size = 1
204
Removed:
ifTrue: [ self editSet: selectedSets first ]
205
Removed:
ifFalse: [ self editSets: selectedSets ] ];
206
Removed:
with: 'Edit'.
207
Removed:
selectedExercises size = 1 ifTrue: [
208
Removed:
html outlineButton
209
Removed:
beSecondary;
210
Removed:
beSmall;
211
Removed:
callback: [ setGroup duplicateSet: selectedSets first ];
212
Removed:
with: 'Duplicate' ] ] ] ] ].
213
Removed:
214
Removed:
html tableRow: [ "This row spans the amount of sets for a given exercise."
215
Removed:
setGroup isIrregularSetGroup ifTrue: [
216
Removed:
html tableData with: set exercise englishName capitalized ].
217
Removed:
html tableData
218
Removed:
style: 'text-align: right';
219
Removed:
with: set reps.
220
Removed:
setGroup hasLoad ifTrue: [
221
Removed:
html tableData
222
Removed:
style: 'text-align: right';
223
Removed:
with: set load ].
224
Removed:
setGroup hasRpe ifTrue: [
225
Removed:
html tableData
226
Removed:
style: 'text-align: right';
227
Removed:
with: set rpe ].
228
Removed:
setGroup hasRestAfter ifTrue: [
229
Removed:
html tableData
230
Removed:
style: 'text-align: right';
231
Removed:
with: set restAfter ] ] ]
232
Removed:
]
233
Removed:
234
Removed:
{ #category : 'rendering' }
235
Removed:
MFTSetGroupDialog >> renderSetGroupTableHeaderOn: html [
236
Removed:
237
Removed:
html tableHead: [
238
Removed:
html tableHeading.
239
Removed:
setGroup isIrregularSetGroup ifTrue: [
240
Removed:
html tableHeading with: 'Exercise' ].
241
Removed:
html tableHeading
242
Removed:
style: 'text-align: right';
243
Removed:
with: 'Reps'.
244
Removed:
setGroup hasLoad ifTrue: [
245
Removed:
html tableHeading
246
Removed:
style: 'text-align: right';
247
Removed:
with: 'Load' ].
248
Removed:
setGroup hasRpe ifTrue: [
249
Removed:
html tableHeading
250
Removed:
style: 'text-align: right';
251
Removed:
with: 'RPE' ].
252
Removed:
setGroup hasRestAfter ifTrue: [
253
Removed:
html tableHeading
254
Removed:
style: 'text-align: right';
255
Removed:
with: 'Rest After (s)' ] ]
256
Removed:
]
257
Removed:
258
Removed:
{ #category : 'rendering' }
259
Removed:
MFTSetGroupDialog >> renderSetGroupTableOn: html [
260
Removed:
261
Removed:
html table
262
Removed:
class: 'table table-bordered';
263
Removed:
with: [
264
Removed:
self renderSetGroupTableHeaderOn: html.
265
Removed:
self renderSetGroupRowsOn: html ]
266
Removed:
]
267
Removed:
268
Removed:
{ #category : 'as yet unclassified' }
269
Removed:
MFTSetGroupDialog >> renderSubmitOn: html [
270
Removed:
271
Removed:
html buttonGroup: [
272
Removed:
html formButton
273
Removed:
beSubmit;
274
Removed:
bePrimary;
275
Removed:
callback: [ self answer: setGroup ];
276
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
277
Removed:
html formButton
278
Removed:
beSubmit;
279
Removed:
beSecondary;
280
Removed:
callback: [ self answer: nil ];
281
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
282
Removed:
]
283
Removed:
284
Removed:
{ #category : 'as yet unclassified' }
285
Removed:
MFTSetGroupDialog >> selectedExercises [
286
Removed:
287
Removed:
^ selectedExercises
288
Removed:
]
289
Removed:
290
Removed:
{ #category : 'as yet unclassified' }
291
Removed:
MFTSetGroupDialog >> selectedExercises: aMFTExerciseCollection [
292
Removed:
293
Removed:
selectedExercises := aMFTExerciseCollection
294
Removed:
]
295
Removed:
296
Removed:
{ #category : 'as yet unclassified' }
297
Removed:
MFTSetGroupDialog >> setGroup [
298
Removed:
299
Removed:
^ setGroup
300
Removed:
]
301
Removed:
302
Removed:
{ #category : 'as yet unclassified' }
303
Removed:
MFTSetGroupDialog >> setGroup: anObject [
304
Removed:
305
Removed:
setGroup := anObject
306
Removed:
]
307
Removed:
308
Removed:
{ #category : 'as yet unclassified' }
309
Removed:
MFTSetGroupDialog >> updateAllSelectedExercises [
310
Removed:
311
Removed:
| allSets |
312
Removed:
allSets := setGroup sets.
313
Removed:
selectedExercises doWithIndex: [ :selectedExercise :i |
314
Removed:
i to: allSets size by: selectedExercises size do: [ :j |
315
Removed:
| set |
316
Removed:
"Update every nth set to reflect the newly selected exercise selectedExercises at: i."
317
Removed:
set := allSets at: j.
318
Removed:
set exercise: selectedExercise ] ]
319
Removed:
]
src/MyFitnessTracker-Components/MFTSetGroupForm.class.st
@@ -1,158 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSetGroupForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'setGroup',
6
Removed:
'exerciseCount',
7
Removed:
'renderRpe',
8
Removed:
'renderRestAfter'
9
Removed:
],
10
Removed:
#category : 'MyFitnessTracker-Components-Forms',
11
Removed:
#package : 'MyFitnessTracker-Components',
12
Removed:
#tag : 'Forms'
13
Removed:
}
14
Removed:
15
Removed:
{ #category : 'as yet unclassified' }
16
Removed:
MFTSetGroupForm class >> forExercises: anMFTExerciseCollection [
17
Removed:
18
Removed:
| setGroup |
19
Removed:
setGroup := MFTSetGroup new addSets:
20
Removed:
(anMFTExerciseCollection collect: [ :exercise |
21
Removed:
MFTSet new
22
Removed:
exercise: exercise;
23
Removed:
reps: 8 ]).
24
Removed:
^ self new
25
Removed:
setGroup: setGroup;
26
Removed:
exerciseCount: anMFTExerciseCollection size;
27
Removed:
yourself
28
Removed:
]
29
Removed:
30
Removed:
{ #category : 'accessing' }
31
Removed:
MFTSetGroupForm >> exerciseCount: anInteger [
32
Removed:
33
Removed:
exerciseCount := anInteger
34
Removed:
]
35
Removed:
36
Removed:
{ #category : 'initialization' }
37
Removed:
MFTSetGroupForm >> initialize [
38
Removed:
39
Removed:
super initialize.
40
Removed:
heading := 'Sets'.
41
Removed:
setGroup := MFTSetGroup new addSet: (MFTSet new reps: 8).
42
Removed:
renderRpe := false.
43
Removed:
renderRestAfter := false
44
Removed:
]
45
Removed:
46
Removed:
{ #category : 'rendering' }
47
Removed:
MFTSetGroupForm >> renderContentOn: html [
48
Removed:
49
Removed:
self renderFormOn: html with: [
50
Removed:
self renderSetsButtonGroupOn: html.
51
Removed:
self renderSetGroupTableOn: html ]
52
Removed:
]
53
Removed:
54
Removed:
{ #category : 'rendering' }
55
Removed:
MFTSetGroupForm >> renderSetGroupRowsOn: html [
56
Removed:
57
Removed:
| selectedExercises renderSetGroupExercisesName |
58
Removed:
selectedExercises := setGroup sets collect: #exercise.
59
Removed:
renderSetGroupExercisesName := setGroup isIrregularSetGroup.
60
Removed:
61
Removed:
setGroup sets do: [ :set |
62
Removed:
html tableRow: [
63
Removed:
renderSetGroupExercisesName ifTrue: [
64
Removed:
html tableData with: set exercise englishName capitalized ].
65
Removed:
html tableData: [
66
Removed:
html numberInput formControl
67
Removed:
value: set reps;
68
Removed:
callback: [ :value | set reps: value asInteger ] ].
69
Removed:
html tableData: [
70
Removed:
html numberInput formControl
71
Removed:
value: set load;
72
Removed:
callback: [ :value |
73
Removed:
set load:
74
Removed:
(value ifNotEmpty: [ value asNumber ] ifEmpty: [ nil ]) ] ].
75
Removed:
renderRpe ifTrue: [
76
Removed:
html tableData: [
77
Removed:
html numberInput formControl
78
Removed:
value: set rpe;
79
Removed:
callback: [ :value |
80
Removed:
set rpe:
81
Removed:
(value ifNotEmpty: [ value asInteger ] ifEmpty: [ nil ]) ] ] ].
82
Removed:
renderRestAfter ifTrue: [
83
Removed:
html tableData: [
84
Removed:
html numberInput formControl
85
Removed:
value: set restAfter;
86
Removed:
callback: [ :value |
87
Removed:
set restAfter:
88
Removed:
(value ifNotEmpty: [ value asNumber ] ifEmpty: [ nil ]) ] ] ] ] ]
89
Removed:
]
90
Removed:
91
Removed:
{ #category : 'rendering' }
92
Removed:
MFTSetGroupForm >> renderSetGroupTableHeaderOn: html [
93
Removed:
94
Removed:
html tableHead: [
95
Removed:
setGroup isIrregularSetGroup ifTrue: [
96
Removed:
html tableHeading with: 'Exercise' ].
97
Removed:
html tableHeading with: 'Reps'.
98
Removed:
html tableHeading with: 'Load'.
99
Removed:
renderRpe ifTrue: [ html tableHeading with: 'RPE' ].
100
Removed:
renderRestAfter ifTrue: [ html tableHeading with: 'Rest After (s)' ] ]
101
Removed:
]
102
Removed:
103
Removed:
{ #category : 'rendering' }
104
Removed:
MFTSetGroupForm >> renderSetGroupTableOn: html [
105
Removed:
106
Removed:
html table
107
Removed:
class: 'table table-bordered';
108
Removed:
with: [
109
Removed:
self renderSetGroupTableHeaderOn: html.
110
Removed:
self renderSetGroupRowsOn: html ]
111
Removed:
]
112
Removed:
113
Removed:
{ #category : 'rendering' }
114
Removed:
MFTSetGroupForm >> renderSetsButtonGroupOn: html [
115
Removed:
116
Removed:
html buttonGroup
117
Removed:
marginTopAndBottom: 3;
118
Removed:
with: [
119
Removed:
html outlineButton
120
Removed:
bePrimary;
121
Removed:
beSmall;
122
Removed:
callback: [
123
Removed:
setGroup addSets: (setGroup sets first: exerciseCount) ];
124
Removed:
with: 'Add set'.
125
Removed:
renderRpe ifFalse: [
126
Removed:
html outlineButton
127
Removed:
beSecondary;
128
Removed:
beSmall;
129
Removed:
callback: [ renderRpe := true ];
130
Removed:
with: 'Add RPE' ].
131
Removed:
renderRestAfter ifFalse: [
132
Removed:
html outlineButton
133
Removed:
beSecondary;
134
Removed:
beSmall;
135
Removed:
callback: [ renderRestAfter := true ];
136
Removed:
with: 'Add rest' ].
137
Removed:
html outlineButton
138
Removed:
beDanger;
139
Removed:
beSmall;
140
Removed:
callback: [
141
Removed:
| firstSets |
142
Removed:
firstSets := setGroup sets first: exerciseCount.
143
Removed:
setGroup := MFTSetGroup new addSets: firstSets.
144
Removed:
renderRpe := renderRestAfter := false ];
145
Removed:
with: 'Reset' ]
146
Removed:
]
147
Removed:
148
Removed:
{ #category : 'accessing' }
149
Removed:
MFTSetGroupForm >> setGroup: anObject [
150
Removed:
151
Removed:
setGroup := anObject
152
Removed:
]
153
Removed:
154
Removed:
{ #category : 'as yet unclassified' }
155
Removed:
MFTSetGroupForm >> submitForm [
156
Removed:
157
Removed:
self answer: setGroup
158
Removed:
]
src/MyFitnessTracker-Components/MFTSetGroupTask.class.st
@@ -1,51 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSetGroupTask',
3
Removed:
#superclass : 'WATask',
4
Removed:
#instVars : [
5
Removed:
'exercises',
6
Removed:
'exerciseCount',
7
Removed:
'setGroup'
8
Removed:
],
9
Removed:
#category : 'MyFitnessTracker-Components-Tasks',
10
Removed:
#package : 'MyFitnessTracker-Components',
11
Removed:
#tag : 'Tasks'
12
Removed:
}
13
Removed:
14
Removed:
{ #category : 'as yet unclassified' }
15
Removed:
MFTSetGroupTask class >> forExerciseCount: anInteger [
16
Removed:
17
Removed:
^ self new
18
Removed:
exerciseCount: anInteger;
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'accessing' }
23
Removed:
MFTSetGroupTask >> exerciseCount: anObject [
24
Removed:
25
Removed:
exerciseCount := anObject
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'accessing' }
29
Removed:
MFTSetGroupTask >> exercises [
30
Removed:
31
Removed:
^ exercises
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'accessing' }
35
Removed:
MFTSetGroupTask >> exercises: anObject [
36
Removed:
37
Removed:
exercises := anObject
38
Removed:
]
39
Removed:
40
Removed:
{ #category : 'running' }
41
Removed:
MFTSetGroupTask >> go [
42
Removed:
43
Removed:
exercises := self call:
44
Removed:
(MFTExercisesForm forExerciseCount: exerciseCount).
45
Removed:
exercises ifNil: [ self answer: nil ].
46
Removed:
47
Removed:
setGroup := self call: (MFTSetGroupForm forExercises: exercises).
48
Removed:
setGroup ifNil: [ self answer: nil ].
49
Removed:
50
Removed:
self answer: setGroup
51
Removed:
]
src/MyFitnessTracker-Components/MFTSetGroupsDialog.class.st
@@ -1,179 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTSetGroupsDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'setGroups'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'as yet unclassified' }
13
Removed:
MFTSetGroupsDialog >> addExercise [
14
Removed:
15
Removed:
| setGroup |
16
Removed:
setGroup := self call: (MFTSetGroupDialog new heading: 'Exercise').
17
Removed:
setGroup ifNotNil: [ setGroups add: setGroup ]
18
Removed:
]
19
Removed:
20
Removed:
{ #category : 'as yet unclassified' }
21
Removed:
MFTSetGroupsDialog >> editSetGroup: aMFTSetGroup [
22
Removed:
23
Removed:
| oldSetGroup newSetGroup |
24
Removed:
oldSetGroup := aMFTSetGroup.
25
Removed:
newSetGroup := self call: (MFTSetGroupDialog edit: aMFTSetGroup copy).
26
Removed:
newSetGroup ifNotNil: [
27
Removed:
setGroups at: (setGroups indexOf: oldSetGroup) put: newSetGroup ]
28
Removed:
]
29
Removed:
30
Removed:
{ #category : 'initialization' }
31
Removed:
MFTSetGroupsDialog >> initialize [
32
Removed:
33
Removed:
super initialize.
34
Removed:
setGroups := OrderedCollection new
35
Removed:
]
36
Removed:
37
Removed:
{ #category : 'as yet unclassified' }
38
Removed:
MFTSetGroupsDialog >> renderAddSetGroupButtonsOn: html [
39
Removed:
40
Removed:
html outlineButton
41
Removed:
bePrimary;
42
Removed:
beSmall;
43
Removed:
callback: [ self addExercise ];
44
Removed:
with: 'Add exercise'
45
Removed:
]
46
Removed:
47
Removed:
{ #category : 'as yet unclassified' }
48
Removed:
MFTSetGroupsDialog >> renderContentOn: html [
49
Removed:
50
Removed:
self renderDialogOn: html with: [
51
Removed:
setGroups ifNotEmpty: [ self renderSetsTableOn: html ].
52
Removed:
self renderAddSetGroupButtonsOn: html ]
53
Removed:
]
54
Removed:
55
Removed:
{ #category : 'as yet unclassified' }
56
Removed:
MFTSetGroupsDialog >> renderLoad [
57
Removed:
58
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasLoad
59
Removed:
]
60
Removed:
61
Removed:
{ #category : 'as yet unclassified' }
62
Removed:
MFTSetGroupsDialog >> renderRestAfter [
63
Removed:
64
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasRestAfter
65
Removed:
]
66
Removed:
67
Removed:
{ #category : 'as yet unclassified' }
68
Removed:
MFTSetGroupsDialog >> renderRpe [
69
Removed:
70
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasRpe
71
Removed:
]
72
Removed:
73
Removed:
{ #category : 'as yet unclassified' }
74
Removed:
MFTSetGroupsDialog >> renderSetGroupButtonsOn: html for: setGroup [
75
Removed:
76
Removed:
html buttonGroup: [
77
Removed:
html outlineButton
78
Removed:
beDanger;
79
Removed:
beSmall;
80
Removed:
callback: [ setGroups remove: setGroup ];
81
Removed:
with: 'Remove'.
82
Removed:
html outlineButton
83
Removed:
beSecondary;
84
Removed:
beSmall;
85
Removed:
callback: [ self editSetGroup: setGroup ];
86
Removed:
with: 'Edit'.
87
Removed:
html outlineButton
88
Removed:
beSecondary;
89
Removed:
beSmall;
90
Removed:
callback: [
91
Removed:
setGroups add: setGroup afterIndex: (setGroups indexOf: setGroup) ];
92
Removed:
with: 'Duplicate' ]
93
Removed:
]
94
Removed:
95
Removed:
{ #category : 'as yet unclassified' }
96
Removed:
MFTSetGroupsDialog >> renderSetGroupsRowsOn: html [
97
Removed:
98
Removed:
| renderLoad renderRpe renderRestAfter |
99
Removed:
renderLoad := self renderLoad.
100
Removed:
renderRpe := self renderRpe.
101
Removed:
renderRestAfter := self renderRestAfter.
102
Removed:
setGroups do: [ :setGroup |
103
Removed:
html tableRow with: [
104
Removed:
html tableData
105
Removed:
attributeAt: 'rowspan' put: setGroup sets size + 1;
106
Removed:
style: 'vertical-align: middle';
107
Removed:
with: [ self renderSetGroupButtonsOn: html for: setGroup ] ].
108
Removed:
setGroup sets do: [ :set |
109
Removed:
html tableRow: [
110
Removed:
html tableData: set exercise englishName.
111
Removed:
html tableData: set reps.
112
Removed:
setGroup hasLoad ifTrue: [ html tableData: set load ].
113
Removed:
setGroup hasRpe ifTrue: [ html tableData: set rpe ].
114
Removed:
setGroup hasRestAfter ifTrue: [ html tableData: set restAfter ] ] ] ]
115
Removed:
]
116
Removed:
117
Removed:
{ #category : 'as yet unclassified' }
118
Removed:
MFTSetGroupsDialog >> renderSetGroupsTableHeaderOn: html [
119
Removed:
120
Removed:
html tableHead: [
121
Removed:
html
122
Removed:
tableHeading;
123
Removed:
tableHeading: 'Exercise';
124
Removed:
tableHeading: 'Reps'.
125
Removed:
self renderLoad ifTrue: [ html tableHeading: 'Load' ].
126
Removed:
self renderRpe ifTrue: [ html tableHeading: 'RPE' ].
127
Removed:
self renderRestAfter ifTrue: [ html tableHeading: 'Rest after (s) ' ] ]
128
Removed:
]
129
Removed:
130
Removed:
{ #category : 'as yet unclassified' }
131
Removed:
MFTSetGroupsDialog >> renderSetsTableHeaderOn: html [
132
Removed:
133
Removed:
html tableHead: [
134
Removed:
html
135
Removed:
tableHeading;
136
Removed:
tableHeading: 'Exercise';
137
Removed:
tableHeading: 'Reps'.
138
Removed:
self renderLoad ifTrue: [ html tableHeading: 'Load' ].
139
Removed:
self renderRpe ifTrue: [ html tableHeading: 'RPE' ].
140
Removed:
self renderRestAfter ifTrue: [ html tableHeading: 'Rest after (s) ' ] ]
141
Removed:
]
142
Removed:
143
Removed:
{ #category : 'as yet unclassified' }
144
Removed:
MFTSetGroupsDialog >> renderSetsTableOn: html [
145
Removed:
146
Removed:
html table
147
Removed:
class: 'table table-bordered';
148
Removed:
with: [
149
Removed:
self renderSetGroupsTableHeaderOn: html.
150
Removed:
self renderSetGroupsRowsOn: html ]
151
Removed:
]
152
Removed:
153
Removed:
{ #category : 'as yet unclassified' }
154
Removed:
MFTSetGroupsDialog >> renderSubmitOn: html [
155
Removed:
156
Removed:
html buttonGroup: [
157
Removed:
html formButton
158
Removed:
beSubmit;
159
Removed:
bePrimary;
160
Removed:
callback: [ self answer: setGroups ];
161
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
162
Removed:
html formButton
163
Removed:
beSubmit;
164
Removed:
beSecondary;
165
Removed:
callback: [ self answer: OrderedCollection new ];
166
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
167
Removed:
]
168
Removed:
169
Removed:
{ #category : 'as yet unclassified' }
170
Removed:
MFTSetGroupsDialog >> setGroups [
171
Removed:
172
Removed:
^ setGroups
173
Removed:
]
174
Removed:
175
Removed:
{ #category : 'as yet unclassified' }
176
Removed:
MFTSetGroupsDialog >> setGroups: anObject [
177
Removed:
178
Removed:
setGroups := anObject
179
Removed:
]
src/MyFitnessTracker-Components/MFTStringDialog.class.st
@@ -1,58 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTStringDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'string'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'as yet unclassified' }
13
Removed:
MFTStringDialog class >> edit: aString [
14
Removed:
15
Removed:
^ self new
16
Removed:
action: #edit;
17
Removed:
string: aString;
18
Removed:
yourself
19
Removed:
]
20
Removed:
21
Removed:
{ #category : 'initialization' }
22
Removed:
MFTStringDialog >> initialize [
23
Removed:
24
Removed:
super initialize.
25
Removed:
string := String new
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'as yet unclassified' }
29
Removed:
MFTStringDialog >> renderContentOn: html [
30
Removed:
31
Removed:
self renderDialogOn: html with: [
32
Removed:
html textInput formControl
33
Removed:
value: string;
34
Removed:
callback: [ :value | string := value ] ]
35
Removed:
]
36
Removed:
37
Removed:
{ #category : 'as yet unclassified' }
38
Removed:
MFTStringDialog >> renderSubmitOn: html [
39
Removed:
40
Removed:
html buttonGroup: [
41
Removed:
html formButton
42
Removed:
beSubmit;
43
Removed:
bePrimary;
44
Removed:
callback: [ self answer: string ];
45
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]) ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'as yet unclassified' }
49
Removed:
MFTStringDialog >> string [
50
Removed:
51
Removed:
^ string
52
Removed:
]
53
Removed:
54
Removed:
{ #category : 'as yet unclassified' }
55
Removed:
MFTStringDialog >> string: anObject [
56
Removed:
57
Removed:
string := anObject
58
Removed:
]
src/MyFitnessTracker-Components/MFTUserComponent.class.st
@@ -1,41 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTUserComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'user'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'initialization' }
12
Removed:
MFTUserComponent >> initialize [
13
Removed:
14
Removed:
super initialize.
15
Removed:
user := MFTUser new
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'rendering' }
19
Removed:
MFTUserComponent >> renderContentOn: html [
20
Removed:
21
Removed:
html table
22
Removed:
class: 'table table-bordered my-3';
23
Removed:
with: [
24
Removed:
html tableRow: [
25
Removed:
html tableData: 'username'.
26
Removed:
html tableData: user username ].
27
Removed:
html tableRow: [
28
Removed:
html tableData: 'date of birth'.
29
Removed:
html tableData: user dateOfBirth ].
30
Removed:
user realFirstName ifNotEmpty: [
31
Removed:
html tableRow: [
32
Removed:
html tableData: 'real first name'.
33
Removed:
html tableData: user realFirstName ] ].
34
Removed:
user realLastName ifNotEmpty: [
35
Removed:
html tableRow: [
36
Removed:
html tableData: 'real last name'.
37
Removed:
html tableData: user realLastName ] ].
38
Removed:
html tableRow: [
39
Removed:
html tableData: 'last login date and time'.
40
Removed:
html tableData: user lastLoginDateAndTime ] ]
41
Removed:
]
src/MyFitnessTracker-Components/MFTUserForm.class.st
@@ -1,136 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTUserForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'user',
6
Removed:
'password',
7
Removed:
'passwordConfirmation'
8
Removed:
],
9
Removed:
#category : 'MyFitnessTracker-Components-Forms',
10
Removed:
#package : 'MyFitnessTracker-Components',
11
Removed:
#tag : 'Forms'
12
Removed:
}
13
Removed:
14
Removed:
{ #category : 'initialization' }
15
Removed:
MFTUserForm >> initialize [
16
Removed:
17
Removed:
super initialize.
18
Removed:
heading := 'Profile'.
19
Removed:
user := MFTUser new
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'rendering' }
23
Removed:
MFTUserForm >> renderContentOn: html [
24
Removed:
25
Removed:
self renderFormOn: html with: [
26
Removed:
self renderUsernamePickerOn: html.
27
Removed:
self renderPasswordPickerOn: html.
28
Removed:
self renderDateOfBirthPickerOn: html.
29
Removed:
self renderRealFirstNamePickerOn: html.
30
Removed:
self renderRealLastNamePickerOn: html ]
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'as yet unclassified' }
34
Removed:
MFTUserForm >> renderDateOfBirthPickerOn: html [
35
Removed:
36
Removed:
html formGroup: [
37
Removed:
html div
38
Removed:
class: 'form-floating';
39
Removed:
marginBottom: 3;
40
Removed:
with: [
41
Removed:
html dateInput5 formControl
42
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
43
Removed:
callback: [ :input |
44
Removed:
input
45
Removed:
ifNotEmpty: [
46
Removed:
user dateOfBirth: (Date readFrom: input pattern: 'yyyy-mm-dd') ]
47
Removed:
ifEmpty: [ user dateOfBirth: nil ] ];
48
Removed:
value: user dateOfBirth yyyymmdd.
49
Removed:
html label: 'Date of birth' ] ]
50
Removed:
]
51
Removed:
52
Removed:
{ #category : 'as yet unclassified' }
53
Removed:
MFTUserForm >> renderPasswordPickerOn: html [
54
Removed:
55
Removed:
html formGroup: [
56
Removed:
html div
57
Removed:
class: 'form-floating';
58
Removed:
with: [
59
Removed:
html formPasswordInput
60
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
61
Removed:
callback: [ :input | input ifNotEmpty: [ password := input ] ].
62
Removed:
html label: 'Change password' ] ].
63
Removed:
html formGroup: [
64
Removed:
html div
65
Removed:
class: 'form-floating';
66
Removed:
marginBottom: 3;
67
Removed:
with: [
68
Removed:
html formPasswordInput
69
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
70
Removed:
callback: [ :input |
71
Removed:
input ifNotEmpty: [ passwordConfirmation := input ] ].
72
Removed:
html label: 'Confirm new password' ] ]
73
Removed:
]
74
Removed:
75
Removed:
{ #category : 'as yet unclassified' }
76
Removed:
MFTUserForm >> renderRealFirstNamePickerOn: html [
77
Removed:
78
Removed:
html formGroup: [
79
Removed:
html div
80
Removed:
class: 'form-floating';
81
Removed:
marginBottom: 3;
82
Removed:
with: [
83
Removed:
html formTextInput
84
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
85
Removed:
callback: [ :input | user realFirstName: input ];
86
Removed:
value: user realFirstName.
87
Removed:
html label: 'Real first name' ] ]
88
Removed:
]
89
Removed:
90
Removed:
{ #category : 'as yet unclassified' }
91
Removed:
MFTUserForm >> renderRealLastNamePickerOn: html [
92
Removed:
93
Removed:
^ html formGroup: [
94
Removed:
html div
95
Removed:
class: 'form-floating';
96
Removed:
marginBottom: 3;
97
Removed:
with: [
98
Removed:
html formTextInput
99
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
100
Removed:
callback: [ :input | user realLastName: input ];
101
Removed:
value: user realLastName.
102
Removed:
html label: 'Real last name' ] ]
103
Removed:
]
104
Removed:
105
Removed:
{ #category : 'as yet unclassified' }
106
Removed:
MFTUserForm >> renderUsernamePickerOn: html [
107
Removed:
108
Removed:
html formGroup: [
109
Removed:
html div
110
Removed:
class: 'form-floating';
111
Removed:
marginBottom: 3;
112
Removed:
with: [
113
Removed:
html formTextInput
114
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
115
Removed:
callback: [ :input | user username: input ];
116
Removed:
value: user username.
117
Removed:
html label: 'Username' ] ]
118
Removed:
]
119
Removed:
120
Removed:
{ #category : 'as yet unclassified' }
121
Removed:
MFTUserForm >> submitForm [
122
Removed:
123
Removed:
errors removeAll.
124
Removed:
user username ifEmpty: [ errors add: 'Username is empty.' ].
125
Removed:
password = passwordConfirmation ifFalse: [
126
Removed:
errors add: 'Password and confirmation don''t match.' ].
127
Removed:
errors ifNotEmpty: [ ^ self ].
128
Removed:
password ifNotNil: [ user passwordHashFromString: password ].
129
Removed:
self answer: user
130
Removed:
]
131
Removed:
132
Removed:
{ #category : 'accessing' }
133
Removed:
MFTUserForm >> user: aMFTUser [
134
Removed:
135
Removed:
user := aMFTUser
136
Removed:
]
src/MyFitnessTracker-Components/MFTUserLandingPage.class.st
@@ -1,16 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTUserLandingPage',
3
Removed:
#superclass : 'MFTLandingPage',
4
Removed:
#category : 'MyFitnessTracker-Components-Pages',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Pages'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTUserLandingPage >> defaultCards [
11
Removed:
12
Removed:
^ {
13
Removed:
MFTMainUserCard new.
14
Removed:
MFTActionsCard new.
15
Removed:
MFTWorkoutsCard new }
16
Removed:
]
src/MyFitnessTracker-Components/MFTUserTask.class.st
@@ -1,85 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTUserTask',
3
Removed:
#superclass : 'WATask',
4
Removed:
#instVars : [
5
Removed:
'user',
6
Removed:
'action'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Tasks',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Tasks'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'actions' }
14
Removed:
MFTUserTask class >> edit: aMFTUser [
15
Removed:
16
Removed:
^ self new
17
Removed:
user: aMFTUser;
18
Removed:
action: #edit;
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'accessing' }
23
Removed:
MFTUserTask >> action [
24
Removed:
25
Removed:
^ action
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'accessing' }
29
Removed:
MFTUserTask >> action: anObject [
30
Removed:
31
Removed:
action := anObject
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'running' }
35
Removed:
MFTUserTask >> go [
36
Removed:
37
Removed:
user username: (self call: (MFTStringDialog new
38
Removed:
action: action;
39
Removed:
heading: 'username';
40
Removed:
string: user username;
41
Removed:
completion: 20)).
42
Removed:
user passwordHashFromString: (self call: (MFTStringDialog new
43
Removed:
action: action;
44
Removed:
heading: 'password';
45
Removed:
completion: 40)).
46
Removed:
user dateOfBirth: (self call: (MFTDateDialog new
47
Removed:
action: action;
48
Removed:
heading: 'date of birth';
49
Removed:
date: user dateOfBirth;
50
Removed:
completion: 60)).
51
Removed:
user realFirstName: (self call: (MFTStringDialog new
52
Removed:
action: action;
53
Removed:
heading: 'real first name';
54
Removed:
string: user realFirstName;
55
Removed:
completion: 80)).
56
Removed:
user realLastName: (self call: (MFTStringDialog new
57
Removed:
heading: 'real last name';
58
Removed:
string: user realLastName;
59
Removed:
completion: 100)).
60
Removed:
61
Removed:
(self call: (MFTConfirmDialog new
62
Removed:
action: action;
63
Removed:
component: user))
64
Removed:
ifTrue: [ self answer: user ]
65
Removed:
ifFalse: [ self answer: nil ]
66
Removed:
]
67
Removed:
68
Removed:
{ #category : 'initialization' }
69
Removed:
MFTUserTask >> initialize [
70
Removed:
71
Removed:
super initialize.
72
Removed:
user := MFTUser new
73
Removed:
]
74
Removed:
75
Removed:
{ #category : 'accessing' }
76
Removed:
MFTUserTask >> user [
77
Removed:
78
Removed:
^ user
79
Removed:
]
80
Removed:
81
Removed:
{ #category : 'accessing' }
82
Removed:
MFTUserTask >> user: anObject [
83
Removed:
84
Removed:
user := anObject
85
Removed:
]
src/MyFitnessTracker-Components/MFTWeightDialog.class.st
@@ -1,76 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWeightDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'weight'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Dialogs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Dialogs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'actions' }
13
Removed:
MFTWeightDialog class >> edit: aMFTWeight [
14
Removed:
15
Removed:
^ self new
16
Removed:
action: #edit;
17
Removed:
weight: aMFTWeight;
18
Removed:
yourself
19
Removed:
]
20
Removed:
21
Removed:
{ #category : 'initialization' }
22
Removed:
MFTWeightDialog >> initialize [
23
Removed:
24
Removed:
super initialize.
25
Removed:
weight := MFTWeight new
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'rendering' }
29
Removed:
MFTWeightDialog >> renderContentOn: html [
30
Removed:
31
Removed:
self renderDialogOn: html with: [
32
Removed:
html formGroup: [
33
Removed:
html label: 'Date'.
34
Removed:
html dateInput5 formControl
35
Removed:
value: weight date yyyymmdd;
36
Removed:
callback: [ :value |
37
Removed:
weight date: (Date readFrom: value pattern: 'yyyy-mm-dd') ] ].
38
Removed:
html formGroup: [
39
Removed:
html label: 'Weight'.
40
Removed:
html numberInput formControl
41
Removed:
value: (weight value = 0
42
Removed:
ifTrue: [ nil ]
43
Removed:
ifFalse: [ weight value ]);
44
Removed:
placeholder: weight value;
45
Removed:
callback: [ :value |
46
Removed:
value ifNotEmpty: [ weight value: value asNumber ] ] ] ]
47
Removed:
]
48
Removed:
49
Removed:
{ #category : 'rendering' }
50
Removed:
MFTWeightDialog >> renderSubmitOn: html [
51
Removed:
52
Removed:
html buttonGroup: [
53
Removed:
html formButton
54
Removed:
beSubmit;
55
Removed:
bePrimary;
56
Removed:
callback: [
57
Removed:
self answer: (weight value ifNotNil: [ weight ] ifNil: [ nil ]) ];
58
Removed:
with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
59
Removed:
html formButton
60
Removed:
beSubmit;
61
Removed:
beSecondary;
62
Removed:
callback: [ self answer: nil ];
63
Removed:
with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
64
Removed:
]
65
Removed:
66
Removed:
{ #category : 'accessing' }
67
Removed:
MFTWeightDialog >> weight [
68
Removed:
69
Removed:
^ weight
70
Removed:
]
71
Removed:
72
Removed:
{ #category : 'accessing' }
73
Removed:
MFTWeightDialog >> weight: aMFTWeight [
74
Removed:
75
Removed:
weight := aMFTWeight
76
Removed:
]
src/MyFitnessTracker-Components/MFTWeightForm.class.st
@@ -1,60 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWeightForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'weight'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Forms',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Forms'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'initialization' }
13
Removed:
MFTWeightForm >> initialize [
14
Removed:
15
Removed:
super initialize.
16
Removed:
heading := 'Weight'.
17
Removed:
weight := MFTWeight new
18
Removed:
]
19
Removed:
20
Removed:
{ #category : 'rendering' }
21
Removed:
MFTWeightForm >> renderContentOn: html [
22
Removed:
23
Removed:
self renderFormOn: html with: [
24
Removed:
html formGroup: [
25
Removed:
html div
26
Removed:
class: 'form-floating';
27
Removed:
marginBottom: 3;
28
Removed:
with: [
29
Removed:
html dateInput5 formControl
30
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
31
Removed:
callback: [ :input |
32
Removed:
weight date: (Date readFrom: input pattern: 'yyyy-mm-dd') ];
33
Removed:
value: weight date yyyymmdd.
34
Removed:
html label: 'Date' ] ].
35
Removed:
36
Removed:
html formGroup: [
37
Removed:
html div
38
Removed:
class: 'form-floating';
39
Removed:
marginBottom: 3;
40
Removed:
with: [
41
Removed:
html numberInput formControl
42
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
43
Removed:
callback: [ :input | input ifNotEmpty: [ weight value: input ] ];
44
Removed:
value: weight value.
45
Removed:
html label: 'Weight' ] ] ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'as yet unclassified' }
49
Removed:
MFTWeightForm >> submitForm [
50
Removed:
51
Removed:
(weight value isNotNil and: [ weight value ~= 0 ])
52
Removed:
ifTrue: [ self answer: weight ]
53
Removed:
ifFalse: [ self answer: nil ]
54
Removed:
]
55
Removed:
56
Removed:
{ #category : 'accessing' }
57
Removed:
MFTWeightForm >> weight: anObject [
58
Removed:
59
Removed:
weight := anObject
60
Removed:
]
src/MyFitnessTracker-Components/MFTWeightVsTimeGraph.class.st
@@ -1,29 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWeightVsTimeGraph',
3
Removed:
#superclass : 'MFTGraph',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTWeightVsTimeGraph >> renderContentOn: html [
11
Removed:
12
Removed:
labels := self session user weights collect: [ :weight |
13
Removed:
weight date yyyymmdd ].
14
Removed:
data := self session user weights collect: #value.
15
Removed:
16
Removed:
html canvas id: 'weightVsTimeChart'.
17
Removed:
html script:
18
Removed:
'var ctx = document.getElementById("weightVsTimeChart").getContext("2d");
19
Removed:
var weightChart = new Chart(ctx, {
20
Removed:
type: "line",
21
Removed:
data: {
22
Removed:
labels: ' , labels asJavascript , ',
23
Removed:
datasets: [{
24
Removed:
label: "weight",
25
Removed:
data: ' , data asJavascript , ',
26
Removed:
}]
27
Removed:
},
28
Removed:
});'
29
Removed:
]
src/MyFitnessTracker-Components/MFTWeightsCard.class.st
@@ -1,39 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWeightsCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTWeightsCard >> renderContentOn: html [
11
Removed:
12
Removed:
self renderCardOn: html with: [
13
Removed:
html cardHeader: 'Weights'.
14
Removed:
html cardBody: [
15
Removed:
html paragraph: 'Great job logging your weight '
16
Removed:
, self session user weights size asString , ' times!'.
17
Removed:
html form
18
Removed:
class: 'mb-3';
19
Removed:
with: [
20
Removed:
html buttonGroup
21
Removed:
beSmall;
22
Removed:
with: [
23
Removed:
html outlineButton
24
Removed:
bePrimary;
25
Removed:
callback: [ self addWeight ];
26
Removed:
with: 'Log weight'.
27
Removed:
html outlineButton
28
Removed:
beSecondary;
29
Removed:
callback: [ self viewAnalytics ];
30
Removed:
with: 'View progress' ] ].
31
Removed:
html render: MFTWeightVsTimeGraph new ] ]
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'as yet unclassified' }
35
Removed:
MFTWeightsCard >> viewAnalytics [
36
Removed:
37
Removed:
self session pageManager activePage call:
38
Removed:
(MFTAnalyticsPage for: #weights)
39
Removed:
]
src/MyFitnessTracker-Components/MFTWeightsLog.class.st
@@ -1,142 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWeightsLog',
3
Removed:
#superclass : 'MFTLog',
4
Removed:
#instVars : [
5
Removed:
'weights'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Logs',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Logs'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'adding' }
13
Removed:
MFTWeightsLog >> addWeight [
14
Removed:
15
Removed:
| newWeight |
16
Removed:
newWeight := self session pageManager activePage call:
17
Removed:
MFTWeightForm new.
18
Removed:
newWeight ifNil: [ ^ self ].
19
Removed:
(weights anySatisfy: [ :existingWeight |
20
Removed:
existingWeight date = newWeight date and: [
21
Removed:
existingWeight value = newWeight value ] ]) ifTrue: [ ^ self ].
22
Removed:
23
Removed:
self session user isLoggedIn
24
Removed:
ifTrue: [ self session db insert: newWeight ]
25
Removed:
ifFalse: [ weights add: newWeight ]
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'accessing' }
29
Removed:
MFTWeightsLog >> editWeight: oldWeight [
30
Removed:
31
Removed:
| newWeight |
32
Removed:
newWeight := self call: (MFTWeightForm new weight: oldWeight copy).
33
Removed:
(oldWeight value = newWeight value and: [
34
Removed:
oldWeight date = newWeight date ]) ifTrue: [ ^ self ].
35
Removed:
36
Removed:
self session user isLoggedIn
37
Removed:
ifTrue: [ self session db update: oldWeight with: newWeight ]
38
Removed:
ifFalse: [
39
Removed:
weights
40
Removed:
remove: oldWeight;
41
Removed:
add: newWeight ]
42
Removed:
]
43
Removed:
44
Removed:
{ #category : 'initialization' }
45
Removed:
MFTWeightsLog >> initialize [
46
Removed:
47
Removed:
super initialize.
48
Removed:
title := 'weights'.
49
Removed:
weights := OrderedCollection new
50
Removed:
]
51
Removed:
52
Removed:
{ #category : 'as yet unclassified' }
53
Removed:
MFTWeightsLog >> randomWittyCTA [
54
Removed:
55
Removed:
| listOfStrings randomString |
56
Removed:
listOfStrings := #( 'First time?' 'Get your sweat on!'
57
Removed:
'Go go go!' 'Go get ''em, Tiger!' ).
58
Removed:
randomString := listOfStrings atRandom.
59
Removed:
^ randomString
60
Removed:
]
61
Removed:
62
Removed:
{ #category : 'accessing' }
63
Removed:
MFTWeightsLog >> removeWeight: aMFTWeight [
64
Removed:
65
Removed:
self session user isLoggedIn
66
Removed:
ifTrue: [ self session db delete: aMFTWeight ]
67
Removed:
ifFalse: [ weights remove: aMFTWeight ]
68
Removed:
]
69
Removed:
70
Removed:
{ #category : 'rendering' }
71
Removed:
MFTWeightsLog >> renderActionsButtonGroupOn: html [
72
Removed:
73
Removed:
html form: [
74
Removed:
html buttonGroup: [
75
Removed:
html formButton
76
Removed:
bePrimary;
77
Removed:
callback: [ self addWeight ];
78
Removed:
with: 'Log weight'.
79
Removed:
html formButton
80
Removed:
beSecondary;
81
Removed:
callback: [ self viewAnalytics ];
82
Removed:
with: 'View progress' ] ]
83
Removed:
]
84
Removed:
85
Removed:
{ #category : 'rendering' }
86
Removed:
MFTWeightsLog >> renderContentOn: html [
87
Removed:
88
Removed:
weights := self session user weights sort: [ :a :b | a date > b date ].
89
Removed:
self renderLogOn: html with: [
90
Removed:
weights ifEmpty: [
91
Removed:
html jumbotron: [ html heading: self randomWittyCTA ] ].
92
Removed:
self renderActionsButtonGroupOn: html.
93
Removed:
weights ifNotEmpty: [ self renderWeightsAsTableOn: html ] ]
94
Removed:
]
95
Removed:
96
Removed:
{ #category : 'rendering' }
97
Removed:
MFTWeightsLog >> renderWeightActionsButtonGroupOn: html for: aMFTWeight [
98
Removed:
99
Removed:
html form: [
100
Removed:
html buttonGroup
101
Removed:
beSmall;
102
Removed:
with: [
103
Removed:
html outlineButton
104
Removed:
beSecondary;
105
Removed:
formControl;
106
Removed:
callback: [ self editWeight: aMFTWeight ];
107
Removed:
with: 'Edit'.
108
Removed:
html outlineButton
109
Removed:
beDanger;
110
Removed:
formControl;
111
Removed:
callback: [ self removeWeight: aMFTWeight ];
112
Removed:
with: 'Delete' ] ]
113
Removed:
]
114
Removed:
115
Removed:
{ #category : 'rendering' }
116
Removed:
MFTWeightsLog >> renderWeightsAsTableOn: html [
117
Removed:
118
Removed:
html table
119
Removed:
class: 'table table-striped';
120
Removed:
with: [
121
Removed:
html tableHead: [
122
Removed:
html
123
Removed:
tableHeading;
124
Removed:
tableHeading: 'Date'.
125
Removed:
html tableHeading
126
Removed:
style: 'text-align: right';
127
Removed:
with: 'Value' ].
128
Removed:
weights do: [ :weight |
129
Removed:
html tableRow: [
130
Removed:
html tableData: [
131
Removed:
self renderWeightActionsButtonGroupOn: html for: weight ].
132
Removed:
html tableData: weight date yyyymmdd.
133
Removed:
html tableData
134
Removed:
style: 'text-align: right';
135
Removed:
with: weight value ] ] ]
136
Removed:
]
137
Removed:
138
Removed:
{ #category : 'adding' }
139
Removed:
MFTWeightsLog >> viewAnalytics [
140
Removed:
141
Removed:
self call: (MFTAnalyticsPage for: #weights)
142
Removed:
]
src/MyFitnessTracker-Components/MFTWidget.class.st
@@ -1,46 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWidget',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'title'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Widgets'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'accessing' }
13
Removed:
MFTWidget >> defaultDescription [
14
Removed:
15
Removed:
^ 'I am a ' , self class name
16
Removed:
]
17
Removed:
18
Removed:
{ #category : 'initialization' }
19
Removed:
MFTWidget >> initialize [
20
Removed:
21
Removed:
super initialize.
22
Removed:
title := String new
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'rendering' }
26
Removed:
MFTWidget >> renderContentOn: html [
27
Removed:
28
Removed:
html div: [
29
Removed:
title ifNotEmpty: [
30
Removed:
html heading
31
Removed:
level5;
32
Removed:
with: self title ].
33
Removed:
html paragraph: self defaultDescription ]
34
Removed:
]
35
Removed:
36
Removed:
{ #category : 'accessing' }
37
Removed:
MFTWidget >> title [
38
Removed:
39
Removed:
^ title
40
Removed:
]
41
Removed:
42
Removed:
{ #category : 'accessing' }
43
Removed:
MFTWidget >> title: aString [
44
Removed:
45
Removed:
title := aString
46
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutComponent.class.st
@@ -1,146 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutComponent',
3
Removed:
#superclass : 'SBSComponent',
4
Removed:
#instVars : [
5
Removed:
'workout'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components',
8
Removed:
#package : 'MyFitnessTracker-Components'
9
Removed:
}
10
Removed:
11
Removed:
{ #category : 'instance creation' }
12
Removed:
MFTWorkoutComponent class >> with: aMFTWorkout [
13
Removed:
14
Removed:
^ self new workout: aMFTWorkout
15
Removed:
]
16
Removed:
17
Removed:
{ #category : 'initialization' }
18
Removed:
MFTWorkoutComponent >> initialize [
19
Removed:
20
Removed:
super initialize.
21
Removed:
workout := MFTWorkout new
22
Removed:
]
23
Removed:
24
Removed:
{ #category : 'as yet unclassified' }
25
Removed:
MFTWorkoutComponent >> renderContentOn: html [
26
Removed:
27
Removed:
html definitionList: [
28
Removed:
html
29
Removed:
definitionTerm: 'Date Planned';
30
Removed:
definitionData: workout datePlanned.
31
Removed:
html
32
Removed:
definitionTerm: 'Date Completed';
33
Removed:
definitionData: workout dateCompleted.
34
Removed:
workout primaryMuscleGroup ifNotNil: [
35
Removed:
html
36
Removed:
definitionTerm: 'Primary Muscle Group';
37
Removed:
definitionData: workout primaryMuscleGroup englishName ].
38
Removed:
workout secondaryMuscleGroups ifNotEmpty: [
39
Removed:
html
40
Removed:
definitionTerm: 'Secondary Muscle Group';
41
Removed:
definitionData:
42
Removed:
(workout secondaryMuscleGroups collect: #englishName)
43
Removed:
asCommaString ] ].
44
Removed:
self renderSetGroupsTableOn: html
45
Removed:
]
46
Removed:
47
Removed:
{ #category : 'as yet unclassified' }
48
Removed:
MFTWorkoutComponent >> renderSetGroupRowsOn: html [
49
Removed:
50
Removed:
| renderSetGroupsType renderLoad renderVolume |
51
Removed:
"No need to render the type of set group, if it is regular."
52
Removed:
renderSetGroupsType := workout allSetGroupsAreRegular not.
53
Removed:
renderLoad := workout anySetHasLoad.
54
Removed:
renderVolume := workout anySetHasVolume.
55
Removed:
56
Removed:
workout setGroups do: [ :group |
57
Removed:
| setsGroupedByExercise |
58
Removed:
setsGroupedByExercise := group sets groupedBy: #exercise.
59
Removed:
renderSetGroupsType ifTrue: [
60
Removed:
html tableRow: [ "This heading spans the amount of sets for this group + the amount of exercises + 1."
61
Removed:
html tableHeading
62
Removed:
attributeAt: 'rowspan'
63
Removed:
put: group sets size + setsGroupedByExercise keys size + 1;
64
Removed:
style: 'vertical-align: middle';
65
Removed:
with: [ html text: group description capitalized ] ] ].
66
Removed:
setsGroupedByExercise keysAndValuesDo: [ :exercise :sets |
67
Removed:
html tableRow: [ "This cell spans the amount of sets for a given exercise."
68
Removed:
html tableData
69
Removed:
attributeAt: 'rowspan' put: sets size + 1;
70
Removed:
style: 'vertical-align: middle';
71
Removed:
with: exercise englishName capitalized ].
72
Removed:
sets do: [ :set |
73
Removed:
html tableRow: [
74
Removed:
html tableData
75
Removed:
style: 'text-align: right';
76
Removed:
with: set reps asString. ", ' number: ', set number asString, ' groupId: ', set groupId asString"
77
Removed:
renderLoad ifTrue: [
78
Removed:
html tableData
79
Removed:
style: 'text-align: right';
80
Removed:
with: set load ].
81
Removed:
renderVolume ifTrue: [
82
Removed:
html tableData
83
Removed:
style: 'text-align: right';
84
Removed:
with: set volume ] ] ] ] ]
85
Removed:
]
86
Removed:
87
Removed:
{ #category : 'as yet unclassified' }
88
Removed:
MFTWorkoutComponent >> renderSetGroupsTableFooterOn: html [
89
Removed:
90
Removed:
| totalReps |
91
Removed:
totalReps := (workout sets collect: #reps) sum.
92
Removed:
html tableFoot: [
93
Removed:
workout anySetGroupIsIrregular ifTrue: [ html tableHeading ].
94
Removed:
html tableData: 'Total'.
95
Removed:
html tableData
96
Removed:
style: 'text-align: right';
97
Removed:
with: totalReps.
98
Removed:
workout anySetHasLoad ifTrue: [ html tableData ].
99
Removed:
workout volume ~~ 0 ifTrue: [
100
Removed:
html tableData
101
Removed:
style: 'text-align: right';
102
Removed:
with: workout volume ] ]
103
Removed:
]
104
Removed:
105
Removed:
{ #category : 'as yet unclassified' }
106
Removed:
MFTWorkoutComponent >> renderSetGroupsTableHeaderOn: html [
107
Removed:
108
Removed:
html tableHead: [
109
Removed:
workout allSetGroupsAreRegular ifFalse: [ html tableHeading ].
110
Removed:
html tableHeading: 'Exercise'.
111
Removed:
html tableHeading
112
Removed:
style: 'text-align: right';
113
Removed:
with: 'Reps'.
114
Removed:
workout anySetHasLoad ifTrue: [
115
Removed:
html tableHeading
116
Removed:
style: 'text-align: right';
117
Removed:
with: 'Load' ].
118
Removed:
workout anySetHasVolume ifTrue: [
119
Removed:
html tableHeading
120
Removed:
style: 'text-align: right';
121
Removed:
with: 'Volume' ] ]
122
Removed:
]
123
Removed:
124
Removed:
{ #category : 'as yet unclassified' }
125
Removed:
MFTWorkoutComponent >> renderSetGroupsTableOn: html [
126
Removed:
127
Removed:
workout setGroups ifNotEmpty: [
128
Removed:
html table
129
Removed:
class: 'table table-bordered';
130
Removed:
with: [
131
Removed:
self renderSetGroupsTableHeaderOn: html.
132
Removed:
self renderSetGroupRowsOn: html.
133
Removed:
self renderSetGroupsTableFooterOn: html ] ]
134
Removed:
]
135
Removed:
136
Removed:
{ #category : 'accessing' }
137
Removed:
MFTWorkoutComponent >> workout [
138
Removed:
139
Removed:
^ workout
140
Removed:
]
141
Removed:
142
Removed:
{ #category : 'accessing' }
143
Removed:
MFTWorkoutComponent >> workout: anObject [
144
Removed:
145
Removed:
workout := anObject
146
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutForm.class.st
@@ -1,155 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutForm',
3
Removed:
#superclass : 'MFTForm',
4
Removed:
#instVars : [
5
Removed:
'workout'
6
Removed:
],
7
Removed:
#category : 'MyFitnessTracker-Components-Forms',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Forms'
10
Removed:
}
11
Removed:
12
Removed:
{ #category : 'adding' }
13
Removed:
MFTWorkoutForm >> addSetGroupsForExerciseCount: anInteger [
14
Removed:
15
Removed:
| setGroup |
16
Removed:
setGroup := self session pageManager activePage call:
17
Removed:
(MFTSetGroupTask forExerciseCount: anInteger).
18
Removed:
setGroup ifNotNil: [ workout addSetGroup: setGroup ]
19
Removed:
]
20
Removed:
21
Removed:
{ #category : 'as yet unclassified' }
22
Removed:
MFTWorkoutForm >> getSelectedMuscleGroups [
23
Removed:
24
Removed:
| selectedMuscleGroups |
25
Removed:
selectedMuscleGroups := MFTSQLite3Database allMuscleGroups select: [
26
Removed:
:muscleGroup |
27
Removed:
workout secondaryMuscleGroups includes:
28
Removed:
muscleGroup ].
29
Removed:
^ selectedMuscleGroups
30
Removed:
]
31
Removed:
32
Removed:
{ #category : 'initialization' }
33
Removed:
MFTWorkoutForm >> initialize [
34
Removed:
35
Removed:
super initialize.
36
Removed:
heading := 'Workout'.
37
Removed:
workout := MFTWorkout new
38
Removed:
]
39
Removed:
40
Removed:
{ #category : 'rendering' }
41
Removed:
MFTWorkoutForm >> renderContentOn: html [
42
Removed:
43
Removed:
self renderFormOn: html with: [
44
Removed:
self renderDatePickerOn: html.
45
Removed:
self renderExercisesPickerOn: html.
46
Removed:
self renderPrimaryMuscleGroupPickerOn: html.
47
Removed:
self renderSecondaryMuscleGroupsPickerOn: html ]
48
Removed:
]
49
Removed:
50
Removed:
{ #category : 'as yet unclassified' }
51
Removed:
MFTWorkoutForm >> renderDatePickerOn: html [
52
Removed:
53
Removed:
html formGroup: [
54
Removed:
html div
55
Removed:
class: 'form-floating';
56
Removed:
marginBottom: 3;
57
Removed:
with: [
58
Removed:
html dateInput5 formControl
59
Removed:
placeholder: 'RequiredEntry-PutItAndDoNotUse';
60
Removed:
callback: [ :input |
61
Removed:
input ifEmpty: [ self error: 'Workout date required.' ].
62
Removed:
workout date: (Date readFrom: input pattern: 'yyyy-mm-dd') ];
63
Removed:
value: workout date yyyymmdd.
64
Removed:
html label: 'Date' ] ]
65
Removed:
]
66
Removed:
67
Removed:
{ #category : 'as yet unclassified' }
68
Removed:
MFTWorkoutForm >> renderExercisesPickerOn: html [
69
Removed:
70
Removed:
workout renderSetGroupsTableOn: html.
71
Removed:
html buttonGroup
72
Removed:
marginBottom: 3;
73
Removed:
with: [
74
Removed:
html outlineButton
75
Removed:
bePrimary;
76
Removed:
beSmall;
77
Removed:
callback: [ self addSetGroupsForExerciseCount: 1 ];
78
Removed:
with: 'Add exercise'.
79
Removed:
html outlineButton
80
Removed:
beSecondary;
81
Removed:
beSmall;
82
Removed:
callback: [ self addSetGroupsForExerciseCount: 2 ];
83
Removed:
with: 'Add superset'.
84
Removed:
html outlineButton
85
Removed:
beSecondary;
86
Removed:
beSmall;
87
Removed:
callback: [ self addSetGroupsForExerciseCount: 3 ];
88
Removed:
with: 'Add tri-set'.
89
Removed:
html outlineButton
90
Removed:
beSecondary;
91
Removed:
beSmall;
92
Removed:
callback: [ self addSetGroupsForExerciseCount: 4 ];
93
Removed:
with: 'Add giant set'.
94
Removed:
html outlineButton
95
Removed:
beDanger;
96
Removed:
beSmall;
97
Removed:
callback: [ workout setGroups removeAll ];
98
Removed:
with: 'Remove all' ]
99
Removed:
]
100
Removed:
101
Removed:
{ #category : 'as yet unclassified' }
102
Removed:
MFTWorkoutForm >> renderPrimaryMuscleGroupPickerOn: html [
103
Removed:
104
Removed:
| selectedMuscleGroup |
105
Removed:
selectedMuscleGroup := workout primaryMuscleGroup ifNotNil: [
106
Removed:
MFTSQLite3Database allMuscleGroups detect: [
107
Removed:
:muscleGroup |
108
Removed:
muscleGroup englishName
109
Removed:
= workout primaryMuscleGroup englishName ] ].
110
Removed:
111
Removed:
html formGroup: [
112
Removed:
html div
113
Removed:
class: 'form-floating';
114
Removed:
marginBottom: 3;
115
Removed:
with: [
116
Removed:
html formSelect
117
Removed:
list: MFTSQLite3Database allMuscleGroups;
118
Removed:
callback: [ :group | workout primaryMuscleGroup: group ];
119
Removed:
selected: selectedMuscleGroup;
120
Removed:
labels: [ :muscleGroup | muscleGroup englishName ].
121
Removed:
html label: 'Primary Muscle Group' ] ]
122
Removed:
]
123
Removed:
124
Removed:
{ #category : 'as yet unclassified' }
125
Removed:
MFTWorkoutForm >> renderSecondaryMuscleGroupsPickerOn: html [
126
Removed:
127
Removed:
html formGroup: [
128
Removed:
html div
129
Removed:
class: 'form-floating';
130
Removed:
marginBottom: 3;
131
Removed:
with: [
132
Removed:
html multiSelect formControl class: 'h-25';
133
Removed:
list: MFTSQLite3Database allMuscleGroups;
134
Removed:
callback: [ :muscleGroups |
135
Removed:
workout secondaryMuscleGroups: muscleGroups ];
136
Removed:
selected: self getSelectedMuscleGroups;
137
Removed:
labels: [ :muscleGroup | muscleGroup englishName ].
138
Removed:
html label: 'Secondary Muscle Groups' ] ]
139
Removed:
]
140
Removed:
141
Removed:
{ #category : 'as yet unclassified' }
142
Removed:
MFTWorkoutForm >> submitForm [
143
Removed:
144
Removed:
errors removeAll.
145
Removed:
workout setGroups ifEmpty: [
146
Removed:
errors add: 'Workout contains no exercises.'.
147
Removed:
^ self ].
148
Removed:
self answer: workout
149
Removed:
]
150
Removed:
151
Removed:
{ #category : 'accessing' }
152
Removed:
MFTWorkoutForm >> workout: anObject [
153
Removed:
154
Removed:
workout := anObject
155
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutTask.class.st
@@ -1,101 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutTask',
3
Removed:
#superclass : 'WATask',
4
Removed:
#instVars : [
5
Removed:
'workout',
6
Removed:
'action'
7
Removed:
],
8
Removed:
#category : 'MyFitnessTracker-Components-Tasks',
9
Removed:
#package : 'MyFitnessTracker-Components',
10
Removed:
#tag : 'Tasks'
11
Removed:
}
12
Removed:
13
Removed:
{ #category : 'actions' }
14
Removed:
MFTWorkoutTask class >> edit: aMFTWorkout [
15
Removed:
16
Removed:
^ self new
17
Removed:
workout: aMFTWorkout;
18
Removed:
action: #edit;
19
Removed:
yourself
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'accessing' }
23
Removed:
MFTWorkoutTask >> action [
24
Removed:
25
Removed:
^ action
26
Removed:
]
27
Removed:
28
Removed:
{ #category : 'accessing' }
29
Removed:
MFTWorkoutTask >> action: anObject [
30
Removed:
31
Removed:
action := anObject
32
Removed:
]
33
Removed:
34
Removed:
{ #category : 'running' }
35
Removed:
MFTWorkoutTask >> go [
36
Removed:
37
Removed:
| primaryMuscleGroup secondaryMuscleGroups |
38
Removed:
workout userId: self session user id.
39
Removed:
workout date: (self call: (MFTDateDialog new
40
Removed:
action: action;
41
Removed:
date: workout date;
42
Removed:
completion: 20)).
43
Removed:
workout setGroups: (self call: (MFTSetGroupsDialog new
44
Removed:
action: action;
45
Removed:
heading: 'Exercises';
46
Removed:
setGroups: workout setGroups;
47
Removed:
completion: 40)).
48
Removed:
primaryMuscleGroup := self call: (MFTPrimaryMuscleGroupDialog new
49
Removed:
action: action;
50
Removed:
primaryMuscleGroup:
51
Removed:
workout primaryMuscleGroup;
52
Removed:
completion: 60).
53
Removed:
primaryMuscleGroup ifNotNil: [
54
Removed:
workout primaryMuscleGroupId: primaryMuscleGroup id.
55
Removed:
secondaryMuscleGroups := self call:
56
Removed:
(MFTSecondaryMuscleGroupsDialog new
57
Removed:
action: action;
58
Removed:
secondaryMuscleGroups:
59
Removed:
workout secondaryMuscleGroups;
60
Removed:
completion: 80).
61
Removed:
workout secondaryMuscleGroupIds:
62
Removed:
(secondaryMuscleGroups collect: #id) ].
63
Removed:
64
Removed:
(self call: (MFTConfirmDialog new
65
Removed:
action: action;
66
Removed:
component: workout))
67
Removed:
ifTrue: [
68
Removed:
self updateSetsAttributes.
69
Removed:
self answer: workout ]
70
Removed:
ifFalse: [ self answer: nil ]
71
Removed:
]
72
Removed:
73
Removed:
{ #category : 'initialization' }
74
Removed:
MFTWorkoutTask >> initialize [
75
Removed:
76
Removed:
super initialize.
77
Removed:
workout := MFTWorkout new.
78
Removed:
action := #add
79
Removed:
]
80
Removed:
81
Removed:
{ #category : 'as yet unclassified' }
82
Removed:
MFTWorkoutTask >> updateSetsAttributes [
83
Removed:
84
Removed:
workout setGroups doWithIndex: [ :setGroup :i |
85
Removed:
setGroup sets doWithIndex: [ :set :j |
86
Removed:
set
87
Removed:
groupId: i;
88
Removed:
number: j ] ]
89
Removed:
]
90
Removed:
91
Removed:
{ #category : 'accessing' }
92
Removed:
MFTWorkoutTask >> workout [
93
Removed:
94
Removed:
^ workout
95
Removed:
]
96
Removed:
97
Removed:
{ #category : 'accessing' }
98
Removed:
MFTWorkoutTask >> workout: anObject [
99
Removed:
100
Removed:
workout := anObject
101
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutVolumePerWeekGraph.class.st
@@ -1,46 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutVolumePerWeekGraph',
3
Removed:
#superclass : 'MFTGraph',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'as yet unclassified' }
10
Removed:
MFTWorkoutVolumePerWeekGraph >> crunchTheNumbers [
11
Removed:
"TODO: not working at all!"
12
Removed:
13
Removed:
| datasets datasetsAsJs |
14
Removed:
labels := Week dayNames.
15
Removed:
data := self session user workouts groupedBy: [ :each |
16
Removed:
each date dayOfYear // 7 ].
17
Removed:
"datasets := {
18
Removed:
{ 1. 2. 0. 0. 3. 5. 3 }.
19
Removed:
{ 3. 4. 3. 0. 0. 0. 6 } }."
20
Removed:
datasetsAsJs := data keysAndValuesDo: [ :k :v |
21
Removed:
'{ label: ' , (#w , k asString) asJavascript
22
Removed:
, ', data: ' , (v collect: #volume) asJavascript
23
Removed:
, '},' ]
24
Removed:
]
25
Removed:
26
Removed:
{ #category : 'initialization' }
27
Removed:
MFTWorkoutVolumePerWeekGraph >> initialize [
28
Removed:
29
Removed:
super initialize.
30
Removed:
self crunchTheNumbers
31
Removed:
]
32
Removed:
33
Removed:
{ #category : 'rendering' }
34
Removed:
MFTWorkoutVolumePerWeekGraph >> renderContentOn: html [
35
Removed:
36
Removed:
html canvas id: 'workoutVolumePerWeekChart'.
37
Removed:
html script:
38
Removed:
'var ctx = document.getElementById("workoutVolumePerWeekChart").getContext("2d");
39
Removed:
var weightChart = new Chart(ctx, {
40
Removed:
type: "line",
41
Removed:
data: {
42
Removed:
labels: ' , labels asJavascript , ',
43
Removed:
datasets: [ ' , data asJavascript , ' ]
44
Removed:
},
45
Removed:
});'
46
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutVolumeVsTimeGraph.class.st
@@ -1,31 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutVolumeVsTimeGraph',
3
Removed:
#superclass : 'MFTGraph',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'rendering' }
10
Removed:
MFTWorkoutVolumeVsTimeGraph >> renderContentOn: html [
11
Removed:
12
Removed:
| workouts |
13
Removed:
workouts := self session user workouts sort: [ :a :b |
14
Removed:
a date < b date ].
15
Removed:
labels := workouts collect: [ :workout | workout date yyyymmdd ].
16
Removed:
data := workouts collect: #volume.
17
Removed:
18
Removed:
html canvas id: 'workoutVolumeVsTimeChart'.
19
Removed:
html script:
20
Removed:
'var ctx = document.getElementById("workoutVolumeVsTimeChart").getContext("2d");
21
Removed:
var weightChart = new Chart(ctx, {
22
Removed:
type: "line",
23
Removed:
data: {
24
Removed:
labels: ' , labels asJavascript , ',
25
Removed:
datasets: [{
26
Removed:
label: "total workout volume",
27
Removed:
data: ' , data asJavascript , ',
28
Removed:
}]
29
Removed:
},
30
Removed:
});'
31
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutsCard.class.st
@@ -1,53 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutsCard',
3
Removed:
#superclass : 'MFTCard',
4
Removed:
#category : 'MyFitnessTracker-Components-Widgets',
5
Removed:
#package : 'MyFitnessTracker-Components',
6
Removed:
#tag : 'Widgets'
7
Removed:
}
8
Removed:
9
Removed:
{ #category : 'adding' }
10
Removed:
MFTWorkoutsCard >> addWorkout [
11
Removed:
12
Removed:
| newWorkout |
13
Removed:
newWorkout := self session pageManager activePage call:
14
Removed:
MFTWorkoutTask new.
15
Removed:
newWorkout ifNil: [ ^ self ].
16
Removed:
17
Removed:
self session user isLoggedIn
18
Removed:
ifTrue: [ self session db insert: newWorkout ]
19
Removed:
ifFalse: [ self session user workouts add: newWorkout ]
20
Removed:
]
21
Removed:
22
Removed:
{ #category : 'rendering' }
23
Removed:
MFTWorkoutsCard >> renderContentOn: html [
24
Removed:
25
Removed:
self renderCardOn: html with: [
26
Removed:
html cardHeader: 'Workouts'.
27
Removed:
html cardBody: [
28
Removed:
html paragraph:
29
Removed:
'Great job logging ' , self session user workouts size asString
30
Removed:
, ' workouts!'.
31
Removed:
html form
32
Removed:
class: 'my-3';
33
Removed:
with: [
34
Removed:
html buttonGroup
35
Removed:
beSmall;
36
Removed:
with: [
37
Removed:
html outlineButton
38
Removed:
bePrimary;
39
Removed:
callback: [ self addWorkout ];
40
Removed:
with: 'Log workout'.
41
Removed:
html outlineButton
42
Removed:
beSecondary;
43
Removed:
callback: [ self viewAnalytics ];
44
Removed:
with: 'View progress' ] ].
45
Removed:
html render: MFTRepsDistributionGraph new ] ]
46
Removed:
]
47
Removed:
48
Removed:
{ #category : 'adding' }
49
Removed:
MFTWorkoutsCard >> viewAnalytics [
50
Removed:
51
Removed:
self session pageManager activePage call:
52
Removed:
(MFTAnalyticsPage for: #workouts)
53
Removed:
]
src/MyFitnessTracker-Components/MFTWorkoutsLog.class.st
@@ -1,173 +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:
Class {
12
Removed:
#name : 'MFTWorkoutsLog',
13
Removed:
#superclass : 'MFTLog',
14
Removed:
#instVars : [
15
Removed:
'workouts'
16
Removed:
],
17
Removed:
#category : 'MyFitnessTracker-Components-Logs',
18
Removed:
#package : 'MyFitnessTracker-Components',
19
Removed:
#tag : 'Logs'
20
Removed:
}
21
Removed:
22
Removed:
{ #category : 'adding' }
23
Removed:
MFTWorkoutsLog >> addWorkout [
24
Removed:
25
Removed:
| newWorkout |
26
Removed:
newWorkout := self session pageManager activePage call:
27
Removed:
MFTWorkoutForm new.
28
Removed:
newWorkout ifNil: [ ^ self ].
29
Removed:
30
Removed:
self session user isLoggedIn
31
Removed:
ifTrue: [ self session db insert: newWorkout ]
32
Removed:
ifFalse: [ workouts add: newWorkout ]
33
Removed:
]
34
Removed:
35
Removed:
{ #category : 'accessing' }
36
Removed:
MFTWorkoutsLog >> confirmDelete: workout [
37
Removed:
38
Removed:
(self call: (MFTConfirmForm new message:
39
Removed:
'Are you sure you want to delete this workout?')) ifFalse: [
40
Removed:
^ self ].
41
Removed:
self session user isLoggedIn
42
Removed:
ifTrue: [ self session db delete: workout ]
43
Removed:
ifFalse: [ workouts remove: workout ]
44
Removed:
]
45
Removed:
46
Removed:
{ #category : 'as yet unclassified' }
47
Removed:
MFTWorkoutsLog >> editWorkout: oldWorkout [
48
Removed:
49
Removed:
| newWorkout |
50
Removed:
newWorkout := self call:
51
Removed:
(MFTWorkoutForm new workout: oldWorkout copy).
52
Removed:
newWorkout ifNil: [ ^ self ].
53
Removed:
54
Removed:
self session user isLoggedIn
55
Removed:
ifTrue: [ self session db update: oldWorkout with: newWorkout ]
56
Removed:
ifFalse: [
57
Removed:
workouts
58
Removed:
remove: oldWorkout;
59
Removed:
add: newWorkout ]
60
Removed:
]
61
Removed:
62
Removed:
{ #category : 'initialization' }
63
Removed:
MFTWorkoutsLog >> initialize [
64
Removed:
65
Removed:
super initialize.
66
Removed:
title := 'workouts'.
67
Removed:
workouts := OrderedCollection new
68
Removed:
]
69
Removed:
70
Removed:
{ #category : 'as yet unclassified' }
71
Removed:
MFTWorkoutsLog >> randomWittyCTA [
72
Removed:
73
Removed:
| listOfStrings randomString |
74
Removed:
listOfStrings := #( 'First time?' 'Get your sweat on!'
75
Removed:
'Go go go!' 'Go get ''em, Tiger!' ).
76
Removed:
randomString := listOfStrings atRandom.
77
Removed:
^ randomString
78
Removed:
]
79
Removed:
80
Removed:
{ #category : 'rendering' }
81
Removed:
MFTWorkoutsLog >> renderAccordionItemOn: html for: workout index: i [
82
Removed:
83
Removed:
html accordionItem: [
84
Removed:
html accordionHeading: [
85
Removed:
html accordionButton
86
Removed:
dataToggle: 'collapse';
87
Removed:
dataTarget: '#collapse' , i asString;
88
Removed:
with: [
89
Removed:
html space.
90
Removed:
workout isCompleted
91
Removed:
ifTrue: [
92
Removed:
html badge beSuccess with: 'done'.
93
Removed:
html space.
94
Removed:
html text: workout dateCompleted yyyymmdd , ', '
95
Removed:
, workout dateCompleted dayOfWeekName ]
96
Removed:
ifFalse: [
97
Removed:
html badge beWarning with: 'planned'.
98
Removed:
html space.
99
Removed:
html text: workout datePlanned yyyymmdd , ', '
100
Removed:
, workout datePlanned dayOfWeekName ].
101
Removed:
workout primaryMuscleGroup ifNotNil: [
102
Removed:
html
103
Removed:
text: ':';
104
Removed:
space;
105
Removed:
emphasis: workout primaryMuscleGroup englishName ] ] ].
106
Removed:
html accordionCollapse
107
Removed:
id: 'collapse' , i asString;
108
Removed:
class: 'collapse';
109
Removed:
dataAttributeAt: 'bs-parent' put: '#accordion';
110
Removed:
with: [
111
Removed:
html accordionBody with: [
112
Removed:
html render: (MFTWorkoutComponent with: workout).
113
Removed:
self renderWorkoutActionsButtonGroupOn: html for: workout ] ] ]
114
Removed:
]
115
Removed:
116
Removed:
{ #category : 'rendering' }
117
Removed:
MFTWorkoutsLog >> renderActionsButtonGroupOn: html [
118
Removed:
119
Removed:
html form: [
120
Removed:
html buttonGroup: [
121
Removed:
html formButton
122
Removed:
bePrimary;
123
Removed:
callback: [ self addWorkout ];
124
Removed:
with: 'Log workout'.
125
Removed:
html formButton
126
Removed:
beSecondary;
127
Removed:
callback: [ self viewAnalytics ];
128
Removed:
with: 'View progress' ] ]
129
Removed:
]
130
Removed:
131
Removed:
{ #category : 'rendering' }
132
Removed:
MFTWorkoutsLog >> renderContentOn: html [
133
Removed:
134
Removed:
workouts := self session user workouts sort: [ :a :b |
135
Removed:
a datePlanned > b datePlanned ].
136
Removed:
self renderLogOn: html with: [
137
Removed:
workouts ifEmpty: [
138
Removed:
html jumbotron: [ html heading: self randomWittyCTA ] ].
139
Removed:
self renderActionsButtonGroupOn: html.
140
Removed:
workouts ifNotEmpty: [ self renderWorkoutsAsAccordionOn: html ] ]
141
Removed:
]
142
Removed:
143
Removed:
{ #category : 'rendering' }
144
Removed:
MFTWorkoutsLog >> renderWorkoutActionsButtonGroupOn: html for: workout [
145
Removed:
146
Removed:
html form: [
147
Removed:
html buttonGroup: [
148
Removed:
html formButton
149
Removed:
bePrimary;
150
Removed:
callback: [ self editWorkout: workout ];
151
Removed:
with: 'Edit'.
152
Removed:
html formButton
153
Removed:
beDanger;
154
Removed:
callback: [ self confirmDelete: workout ];
155
Removed:
with: 'Delete' ] ]
156
Removed:
]
157
Removed:
158
Removed:
{ #category : 'rendering' }
159
Removed:
MFTWorkoutsLog >> renderWorkoutsAsAccordionOn: html [
160
Removed:
161
Removed:
html accordion
162
Removed:
id: 'accordion';
163
Removed:
class: 'my-3';
164
Removed:
with: [
165
Removed:
workouts doWithIndex: [ :workout :i |
166
Removed:
self renderAccordionItemOn: html for: workout index: i ] ]
167
Removed:
]
168
Removed:
169
Removed:
{ #category : 'adding' }
170
Removed:
MFTWorkoutsLog >> viewAnalytics [
171
Removed:
172
Removed:
self call: (MFTAnalyticsPage for: #workouts)
173
Removed:
]
src/MyFitnessTracker-Components/ManifestMyFitnessTrackerComponents.class.st
@@ -1,10 +0,0 @@
1
Removed:
"
2
Removed:
Please describe the package using the class comment of the included manifest class. The manifest class also includes other additional metadata for the package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
3
Removed:
"
4
Removed:
Class {
5
Removed:
#name : 'ManifestMyFitnessTrackerComponents',
6
Removed:
#superclass : 'PackageManifest',
7
Removed:
#category : 'MyFitnessTracker-Components-Manifest',
8
Removed:
#package : 'MyFitnessTracker-Components',
9
Removed:
#tag : 'Manifest'
10
Removed:
}