Nuke components.

Let's stop using Bootstrap.

Commit
41778d3019396a7ba0c755c4742d5fcd94440a5d
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
src/MyFitnessTracker-Components/MFTAboutPage.class.st
index 95172b24..00000000 100644..000000
@@ -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
index 33c7d013..00000000 100644..000000
@@ -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
index e444af04..00000000 100644..000000
@@ -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
index 30882210..00000000 100644..000000
@@ -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
index 1d8f17ce..00000000 100644..000000
@@ -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
index 1a220df5..00000000 100644..000000
@@ -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
index ce916f9d..00000000 100644..000000
@@ -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
index 58f4de1d..00000000 100644..000000
@@ -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
index a2d6306f..00000000 100644..000000
@@ -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
index 5e599f2c..00000000 100644..000000
@@ -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
index 2ec20a0b..00000000 100644..000000
@@ -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
index 9639106d..00000000 100644..000000
@@ -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
index 8f0d2ff0..85ad3dc6 100644..100644
@@ -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
index 2da294f8..00000000 100644..000000
@@ -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
index 1ddca7ff..00000000 100644..000000
@@ -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
index 0615e206..00000000 100644..000000
@@ -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
index 00000000..64b2fad6 000000..100644
@@ -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
index 53ede556..00000000 100644..000000
@@ -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
index a82f4ab8..00000000 100644..000000
@@ -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
index d789a8e9..00000000 100644..000000
@@ -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
index 73eb5bc3..00000000 100644..000000
@@ -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
index a59216f0..00000000 100644..000000
@@ -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
index b3ec3518..00000000 100644..000000
@@ -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
index fdd3b19e..00000000 100644..000000
@@ -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
index f89a7aff..00000000 100644..000000
@@ -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
index fc6b7f20..00000000 100644..000000
@@ -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
index ec189190..00000000 100644..000000
@@ -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
index db996cb3..00000000 100644..000000
@@ -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
index 33f6a340..00000000 100644..000000
@@ -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
index d2ad4f2e..1d778289 100644..100644
@@ -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
index d4060316..00000000 100644..000000
@@ -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
index 17f7b5d1..00000000 100644..000000
@@ -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
index a2c2e1ff..00000000 100644..000000
@@ -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
index ba6f30a9..00000000 100644..000000
@@ -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
index 597489c3..00000000 100644..000000
@@ -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
index a7c27e54..00000000 100644..000000
@@ -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
index 831f58c8..4a9d1c84 100644..100644
@@ -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
index 8458e230..00000000 100644..000000
@@ -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
index 3d522760..00000000 100644..000000
@@ -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
index ce2ef60b..00000000 100644..000000
@@ -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
index 41dcb03a..00000000 100644..000000
@@ -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
index e8e70e0f..00000000 100644..000000
@@ -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
index 0c4d0706..00000000 100644..000000
@@ -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
index 49fa648b..00000000 100644..000000
@@ -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
index 7c0f8efb..00000000 100644..000000
@@ -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
index 7640969a..00000000 100644..000000
@@ -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
index e50b64d0..00000000 100644..000000
@@ -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
index 15cd6186..00000000 100644..000000
@@ -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
index 046225df..00000000 100644..000000
@@ -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
index c4a7fe87..00000000 100644..000000
@@ -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
index 6aa2850c..00000000 100644..000000
@@ -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
index c69fc930..00000000 100644..000000
@@ -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
index a73e87eb..00000000 100644..000000
@@ -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
index ce232af0..00000000 100644..000000
@@ -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
index 88f953b3..00000000 100644..000000
@@ -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
index b0661216..00000000 100644..000000
@@ -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
index c4618229..00000000 100644..000000
@@ -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
index 289b3aa2..00000000 100644..000000
@@ -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
index cf78adff..00000000 100644..000000
@@ -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
index 9d959d0d..00000000 100644..000000
@@ -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
index d97c5b93..00000000 100644..000000
@@ -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
index c9fef163..00000000 100644..000000
@@ -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: }