Added new pages and components, and made lots of miscellaneous enhancements.

- Added MFTAthlete, MFTAthletesArticle, and MFTPrize. - Heavily improved MFTLearnPage. - Removed instance variables for pages (workouts and weights). Instead, the MFTUser instance will store its own workouts and weights. - Started work on the MFTWorkoutTask component.

Commit
ea4403923a281c78b46d2d684df3b5a440cb4433
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
src/MyFitnessTracker/MFTAboutPage.class.st
index a7f9ff1b..15aa67d1 100644..100644
@@ -14,12 +14,8 @@
14 14 { #category : #rendering }
15 15 MFTAboutPage >> renderBackgroundOn: html [
16 16
17 Removed: html heading
18 Removed: level: 1;
19 Removed: with: 'Background'.
20 Removed: html heading
21 Removed: level: 2;
22 Removed: with: 'Why I built this web app'.
17 Added: html heading level1 with: 'Background'.
18 Added: html heading level2 with: 'Why I built this web app'.
23 19 html
24 20 paragraph:
25 21 'I wanted a convenient way to record, perform data analysis, and create visualizations for my workouts.';
@@ -41,23 +37,28 @@
41 37 { #category : #rendering }
42 38 MFTAboutPage >> renderCatchOn: html [
43 39
44 Removed: html heading
45 Removed: dangerText;
46 Removed: with: 'The catch'.
40 Added: html heading level1 dangerText with: 'The catch'.
47 41 html
48 42 paragraph:
49 43 'I''ve made some debatable compromises when it comes to My Fitness Tracker:';
50 44 unorderedList: [
51 45 html
52 Removed: listItem: 'No external advertisements,';
46 Added: listItem: 'No external advertisement,';
53 47 listItem:
54 48 'No cookies or personally identifying information stored,';
55 49 listItem:
56 50 'No paid feature, except for the storage of your training data beyond ten workouts.' ];
57 51 paragraph:
58 Removed: 'I know these design choices might frustrate and maybe even anger certain users; thankfully, all previously existing fitness tracking services do not abide by these design principles.';
52 Added: 'I know these design choices might frustrate and maybe even anger certain users; '
53 Added: ,
54 Added: 'thankfully, all previously existing fitness tracking services do not abide by these design principles.';
59 55 paragraph:
60 Removed: 'I am developing My Fitness Tracker for my own personal use case, first and foremost; secondly, for the benefit of as many fitness enthusiasts as possible; thirdly, because I''ve found to be a fun experience. I''m already rich of the joy this project has brought me, and the paid '
56 Added: 'I am developing My Fitness Tracker for my own personal use case, first and foremost; '
57 Added: ,
58 Added: 'secondly, for the benefit of as many fitness enthusiasts as possible; '
59 Added: , 'thirdly, because I''ve found to be a fun experience. '
60 Added: ,
61 Added: 'I''m already rich of the joy this project has brought me, and the paid '
61 62 ]
62 63
63 64 { #category : #rendering }
@@ -66,7 +67,7 @@
66 67 self renderPageOn: html with: [
67 68 self renderVisionOn: html.
68 69 self renderBackgroundOn: html.
69 Removed: self renderCatchOn: html]
70 Added: self renderCatchOn: html ]
70 71 ]
71 72
72 73 { #category : #rendering }
src/MyFitnessTracker/MFTAthlete.class.st
index 00000000..a582a22a 000000..100644
@@ -0,0 +1,145 @@
1 Added: Class {
2 Added: #name : #MFTAthlete,
3 Added: #superclass : #SBSComponent,
4 Added: #instVars : [
5 Added: 'name',
6 Added: 'nickname',
7 Added: 'born',
8 Added: 'died',
9 Added: 'bio',
10 Added: 'workouts'
11 Added: ],
12 Added: #category : #'MyFitnessTracker-Model'
13 Added: }
14 Added:
15 Added: { #category : #'as yet unclassified' }
16 Added: MFTAthlete class >> allAthletes [
17 Added:
18 Added: ^ { #'Arnold Alois Schwarzenneger'. #'Michael John Mentzer'.
19 Added: #'Thomas Steven Platz' }
20 Added: ]
21 Added:
22 Added: { #category : #'instance creation' }
23 Added: MFTAthlete class >> newFromDictionary: aDictionary [
24 Added:
25 Added: ^ self new
26 Added: date: (Date fromString: (aDictionary at: 'date'));
27 Added: primaryMuscle:
28 Added: (MFTMuscle new latinName: (aDictionary at: 'primary_muscle'));
29 Added: secondaryMuscles:
30 Added: (MFTMuscle new latinName: (aDictionary at: 'secondary_muscles'));
31 Added: yourself
32 Added: ]
33 Added:
34 Added: { #category : #accessing }
35 Added: MFTAthlete class >> primaryMuscle: aMFTMuscle [
36 Added:
37 Added: ^ self new
38 Added: primaryMuscle: aMFTMuscle;
39 Added: yourself
40 Added: ]
41 Added:
42 Added: { #category : #accessing }
43 Added: MFTAthlete class >> primaryMuscle: aMFTMuscle1 secondaryMuscles: aMFTMuscle2 [
44 Added: ^ self new
45 Added: primaryMuscle: aMFTMuscle1;
46 Added: secondaryMuscles: aMFTMuscle2;
47 Added: yourself
48 Added: ]
49 Added:
50 Added: { #category : #accessing }
51 Added: MFTAthlete >> bio [
52 Added:
53 Added: ^ bio
54 Added: ]
55 Added:
56 Added: { #category : #accessing }
57 Added: MFTAthlete >> born [
58 Added:
59 Added: ^ born
60 Added: ]
61 Added:
62 Added: { #category : #accessing }
63 Added: MFTAthlete >> died [
64 Added:
65 Added: ^ died
66 Added: ]
67 Added:
68 Added: { #category : #initialization }
69 Added: MFTAthlete >> initialize [
70 Added:
71 Added: super initialize.
72 Added: name := 'John Default'.
73 Added: nickname := 'Johnny D.'.
74 Added: born := Date fromString: '01/01/2000'.
75 Added: died := Date fromString: '01/01/2000'.
76 Added: bio := 'John Default is still today regarded as one of the most default bodybuilders ever.'
77 Added: ]
78 Added:
79 Added: { #category : #accessing }
80 Added: MFTAthlete >> name [
81 Added:
82 Added: ^ name
83 Added: ]
84 Added:
85 Added: { #category : #accessing }
86 Added: MFTAthlete >> nickname [
87 Added:
88 Added: ^ nickname
89 Added: ]
90 Added:
91 Added: { #category : #accessing }
92 Added: MFTAthlete >> prizes [
93 Added:
94 Added: ^ {
95 Added: (MFTPrize year: 1989 competition: 'Default Prize' place: 1).
96 Added: (MFTPrize year: 1988 competition: 'Default Prize' place: 2) }
97 Added: ]
98 Added:
99 Added: { #category : #rendering }
100 Added: MFTAthlete >> renderContentOn: html [
101 Added:
102 Added: html heading level2 with: name.
103 Added: html heading level3 textMuted with:
104 Added: nickname , ' (' , born year asString , '–' , died year asString
105 Added: , ')'.
106 Added: html outlineButton bePrimary
107 Added: dataToggle: 'collapse';
108 Added: dataTarget: '#collapsePrizes';
109 Added: with: 'Prizes'.
110 Added: html collapse
111 Added: id: 'collapsePrizes';
112 Added: with: [
113 Added: html div
114 Added: marginTopAndBottom: 3;
115 Added: style: 'height: 14em; overflow: scroll';
116 Added: with: [ self renderPrizesTableOn: html ] ].
117 Added: html paragraph: bio
118 Added: ]
119 Added:
120 Added: { #category : #rendering }
121 Added: MFTAthlete >> renderPrizesTableOn: html [
122 Added:
123 Added: html table
124 Added: class: 'table table-striped table-bordered';
125 Added: with: [
126 Added: html tableHead: [
127 Added: html tableRow: [
128 Added: html tableHeading: 'Year'.
129 Added: html tableHeading: 'Competition'.
130 Added: html tableHeading: 'Place'.
131 Added: html tableHeading: 'Category' ] ].
132 Added: html tableBody: [
133 Added: self prizes do: [ :prize |
134 Added: html tableRow: [
135 Added: html tableData: prize year.
136 Added: html tableData: prize competition.
137 Added: html tableData: prize place.
138 Added: html tableData: prize category ] ] ] ]
139 Added: ]
140 Added:
141 Added: { #category : #accessing }
142 Added: MFTAthlete >> workouts [
143 Added:
144 Added: ^ workouts
145 Added: ]
src/MyFitnessTracker/MFTAthletesArticle.class.st
index 00000000..4a48bc53 000000..100644
@@ -0,0 +1,23 @@
1 Added: Class {
2 Added: #name : #MFTAthletesArticle,
3 Added: #superclass : #MFTArticle,
4 Added: #instVars : [
5 Added: 'athletes'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Components'
8 Added: }
9 Added:
10 Added: { #category : #initialization }
11 Added: MFTAthletesArticle >> initialize [
12 Added:
13 Added: super initialize.
14 Added: title := 'Athletes'.
15 Added: athletes := { MFTMikeMentzer new}
16 Added: ]
17 Added:
18 Added: { #category : #rendering }
19 Added: MFTAthletesArticle >> renderContentOn: html [
20 Added:
21 Added: html heading: title.
22 Added: athletes do: [ :athlete | athlete renderContentOn: html ]
23 Added: ]
src/MyFitnessTracker/MFTDefaultFooter.class.st
index 00000000..db253280 000000..100644
@@ -0,0 +1,16 @@
1 Added: Class {
2 Added: #name : #MFTDefaultFooter,
3 Added: #superclass : #MFTFooter,
4 Added: #category : #'MyFitnessTracker-Components'
5 Added: }
6 Added:
7 Added: { #category : #rendering }
8 Added: MFTDefaultFooter >> renderContentOn: html [
9 Added:
10 Added: html card
11 Added: marginTop: 3;
12 Added: class: 'align-items-center';
13 Added: with: [
14 Added: html cardHeader:
15 Added: 'Copyright 2023–' , Date today year asString , ' Marius PETER' ]
16 Added: ]
src/MyFitnessTracker/MFTFooter.class.st
index 00000000..361daf46 000000..100644
@@ -0,0 +1,13 @@
1 Added: Class {
2 Added: #name : #MFTFooter,
3 Added: #superclass : #SBSComponent,
4 Added: #category : #'MyFitnessTracker-Components'
5 Added: }
6 Added:
7 Added: { #category : #rendering }
8 Added: MFTFooter >> renderContentOn: html [
9 Added:
10 Added: html card
11 Added: marginTop: 3;
12 Added: with: [ html cardHeader: 'I am the default footer' ]
13 Added: ]
src/MyFitnessTracker/MFTFooterComponent.class.st
index a08234dd..00000000 100644..000000
@@ -1,15 +0,0 @@
1 Removed: Class {
2 Removed: #name : #MFTFooterComponent,
3 Removed: #superclass : #SBSComponent,
4 Removed: #category : #'MyFitnessTracker-Components'
5 Removed: }
6 Removed:
7 Removed: { #category : #rendering }
8 Removed: MFTFooterComponent >> renderContentOn: html [
9 Removed:
10 Removed: html card
11 Removed: marginTop: 3;
12 Removed: with: [
13 Removed: html cardHeader:
14 Removed: 'Copyright 2023-' , Date today year asString , ' Marius PETER' ]
15 Removed: ]
src/MyFitnessTracker/MFTLandingPage.class.st
index 00000000..2c481471 000000..100644
@@ -0,0 +1,41 @@
1 Added: Class {
2 Added: #name : #MFTLandingPage,
3 Added: #superclass : #MFTPage,
4 Added: #instVars : [
5 Added: 'cards'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Components'
8 Added: }
9 Added:
10 Added: { #category : #hooks }
11 Added: MFTLandingPage >> children [
12 Added:
13 Added: ^ cards
14 Added: ]
15 Added:
16 Added: { #category : #'as yet unclassified' }
17 Added: MFTLandingPage >> defaultCards [
18 Added:
19 Added: ^ {
20 Added: MFTCard new.
21 Added: MFTCard new.
22 Added: MFTCard new }
23 Added: ]
24 Added:
25 Added: { #category : #'as yet unclassified' }
26 Added: MFTLandingPage >> initialize [
27 Added:
28 Added: super initialize.
29 Added: title := 'landingPage'.
30 Added: cards := self defaultCards
31 Added: ]
32 Added:
33 Added: { #category : #rendering }
34 Added: MFTLandingPage >> renderContentOn: html [
35 Added:
36 Added: self renderPageOn: html with: [
37 Added: html div
38 Added: style:
39 Added: 'display: flex; flex-wrap: wrap; justify-content: space-around; gap: 1em';
40 Added: with: [ cards do: [ :card | html render: card ] ] ]
41 Added: ]
src/MyFitnessTracker/MFTLearnPage.class.st
index c114fb60..54132bc1 100644..100644
@@ -2,7 +2,8 @@
2 2 #name : #MFTLearnPage,
3 3 #superclass : #MFTPage,
4 4 #instVars : [
5 Removed: 'articles'
5 Added: 'articles',
6 Added: 'activeArticle'
6 7 ],
7 8 #category : #'MyFitnessTracker-Components'
8 9 }
@@ -12,13 +13,36 @@
12 13
13 14 super initialize.
14 15 title := 'learn'.
15 Removed: articles := Array with: MFTMusclesArticle new
16 Added: articles := {
17 Added: MFTAthletesArticle new.
18 Added: MFTMusclesArticle new }.
19 Added: activeArticle := articles first
16 20 ]
17 21
18 22 { #category : #rendering }
19 23 MFTLearnPage >> renderContentOn: html [
20 24
21 Removed: self
22 Removed: renderPageOn: html
23 Removed: with: [ articles do: [ :each | html render: each ] ]
25 Added: self renderPageOn: html with: [
26 Added: html breadcrumb: [
27 Added: html breadcrumbItem: [
28 Added: html anchor
29 Added: callback: [ self session pageManager activePage: #learn ];
30 Added: with: 'Home' ].
31 Added: html breadcrumbItem: [
32 Added: html anchor
33 Added: url: '#';
34 Added: with: activeArticle title ].
35 Added: html breadcrumbItem
36 Added: beActive;
37 Added: with: 'Data' ].
38 Added: html div
39 Added: class: 'table-of-contents';
40 Added: with: [
41 Added: html navigation flexColumn with: [
42 Added: articles do: [ :article |
43 Added: html navigationLink
44 Added: beActiveIf: [ activeArticle = article ];
45 Added: callback: [ activeArticle := article ];
46 Added: with: article title ] ] ].
47 Added: html render: activeArticle ]
24 48 ]
src/MyFitnessTracker/MFTLoginRegisterLogoutComponent.class.st
index 45f88a8e..bf680707 100644..100644
@@ -11,7 +11,7 @@
11 11 MFTLoginRegisterLogoutComponent >> attemptLogin: aMFTUser [
12 12 "Attempt to match aMFTUser passwordHash against an existing user password_hash in the database.
13 13
14 Removed: If a matching user is found, hydrate a MFTUser from the existingUser, and keep track of the database connection used to authenticate.
14 Added: If a matching user is found, hydrate a MFTUser from the existingUser.
15 15 If no matching user is found, kill the connection."
16 16
17 17 | connection existingUser passwordHash |
src/MyFitnessTracker/MFTMainNavigationBarComponent.class.st
index c38f823f..9c482c85 100644..100644
@@ -22,7 +22,6 @@
22 22
23 23 { #category : #rendering }
24 24 MFTMainNavigationBarComponent >> renderContentOn: html [
25 Removed: "FIXME: NavigationBar Bootstrap class cannot be sticky-top, otherwise login modals are hidden by a shadow..."
26 25
27 26 html navigationBar
28 27 beLight;
@@ -30,6 +29,7 @@
30 29 expandLarge;
31 30 marginBottom: 3;
32 31 paddingLeftAndRight: 3;
32 Added: style: 'position: sticky; top: 0; z-index: 1051';
33 33 with: [ self renderNavigationBarItemsOn: html ]
34 34 ]
35 35
@@ -38,27 +38,25 @@
38 38
39 39 | pm |
40 40 pm := self session pageManager.
41 Removed: html navigationBarBrand
42 Removed: callback: [ pm activePage: 1 ];
43 Removed: with: 'MyFitnessTracker'.
44 41 "The toggler that is only visible when reducing the width of screen"
45 42 html navigationBarToggler
46 43 beButtonType;
47 44 collapse;
48 45 dataTarget: '#navbarCollapsed';
49 46 with: [ html navigationBarTogglerIcon ].
47 Added: html navigationBarBrand
48 Added: callback: [ pm activePage: 1 ];
49 Added: with: 'MyFitnessTracker'.
50 50 html navigationBarCollapse collapse
51 51 id: 'navbarCollapsed';
52 52 with: [
53 53 html navigationBarNavigation: [
54 Removed: pm mainPages doWithIndex: [ :page :i |
54 Added: pm mainPages keysAndValuesDo: [ :key :value |
55 55 html navigationItem
56 Removed: beActiveIf: [ pm activePage = page ];
56 Added: beActiveIf: [ pm activePage = value ];
57 57 with: [
58 58 html navigationLink
59 Removed: callback: [ pm activePage: i ];
60 Removed: with: page title asCapitalizedPhrase ] ] ].
61 Removed: html div
62 Removed: class: 'ms-auto';
63 Removed: with: [ html render: loginRegisterLogout ] ]
59 Added: callback: [ pm activePage: key ];
60 Added: with: value title asCapitalizedPhrase ] ] ] ].
61 Added: html div: [ html render: loginRegisterLogout ]
64 62 ]
src/MyFitnessTracker/MFTMainPublicCard.class.st
index 6322d342..82b6d126 100644..100644
@@ -20,7 +20,10 @@
20 20 html displayHeading
21 21 level: 1;
22 22 with: 'Welcome to My Fitness Tracker!'.
23 Removed: html big textMuted with: 'Free Software never looked so fit.'.
23 Added: html heading
24 Added: level: 2;
25 Added: textMuted;
26 Added: with: 'Free Software never looked so fit.'.
24 27 html form: [
25 28 html formButton
26 29 bePrimary;
src/MyFitnessTracker/MFTMikeMentzer.class.st
index 00000000..2e7ddea9 000000..100644
@@ -0,0 +1,101 @@
1 Added: Class {
2 Added: #name : #MFTMikeMentzer,
3 Added: #superclass : #MFTAthlete,
4 Added: #category : #'MyFitnessTracker-Model'
5 Added: }
6 Added:
7 Added: { #category : #initialization }
8 Added: MFTMikeMentzer >> initialize [
9 Added:
10 Added: super initialize.
11 Added: name := 'Michael John Mentzer'.
12 Added: nickname := 'Mike Mentzer'.
13 Added: born := Date fromString: '11/15/1951'.
14 Added: died := Date fromString: '06/10/2001'.
15 Added: bio := 'Mike Mentzer is most famous for his Heavy Duty training regimen.'.
16 Added: ]
17 Added:
18 Added: { #category : #accessing }
19 Added: MFTMikeMentzer >> prizes [
20 Added:
21 Added: ^ {
22 Added: (MFTPrize year: 1971 competition: 'Mr. Lancaster' place: 1).
23 Added: (MFTPrize year: 1971 competition: 'AAU Mr. America' place: 10).
24 Added: (MFTPrize year: 1971 competition: 'AAU Teen Mr America' place: 2).
25 Added: (MFTPrize
26 Added: year: 1975
27 Added: competition: 'IFBB Mr. America'
28 Added: place: 3
29 Added: category: 'Medium').
30 Added: (MFTPrize
31 Added: year: 1975
32 Added: competition: 'ABBA Mr. USA'
33 Added: place: 2
34 Added: category: 'Medium').
35 Added: (MFTPrize
36 Added: year: 1976
37 Added: competition: 'IFBB Mr. America'
38 Added: place: 1
39 Added: category: 'Overall').
40 Added: (MFTPrize
41 Added: year: 1976
42 Added: competition: 'IFBB Mr. America'
43 Added: place: 1
44 Added: category: 'Medium').
45 Added: (MFTPrize
46 Added: year: 1976
47 Added: competition: 'IFBB Mr. Universe'
48 Added: place: 2
49 Added: category: 'MW').
50 Added: (MFTPrize
51 Added: year: 1977
52 Added: competition: 'IFBB North American Championships'
53 Added: place: 1
54 Added: category: 'Overall').
55 Added: (MFTPrize
56 Added: year: 1977
57 Added: competition: 'IFBB North American Championships'
58 Added: place: 1
59 Added: category: 'MW').
60 Added: (MFTPrize
61 Added: year: 1977
62 Added: competition: 'IFBB Mr. Universe'
63 Added: place: 2
64 Added: category: 'HW').
65 Added: (MFTPrize
66 Added: year: 1978
67 Added: competition: 'IFBB USA vs the World'
68 Added: place: 1
69 Added: category: 'HW').
70 Added: (MFTPrize
71 Added: year: 1978
72 Added: competition: 'IFBB World Amateur Championships'
73 Added: place: 1
74 Added: category: 'HW').
75 Added: (MFTPrize year: 1978 competition: 'IFBB Mr. Universe' place: 1).
76 Added: (MFTPrize year: 1979 competition: 'IFBB Canada Pro Cup' place: 2).
77 Added: (MFTPrize
78 Added: year: 1979
79 Added: competition: 'IFBB Florida Pro Invitational'
80 Added: place: 1).
81 Added: (MFTPrize
82 Added: year: 1979
83 Added: competition: 'IFBB Night of Champions'
84 Added: place: 3).
85 Added: (MFTPrize
86 Added: year: 1979
87 Added: competition: 'IFBB Mr. Olympia'
88 Added: place: 2
89 Added: category: 'Overall').
90 Added: (MFTPrize
91 Added: year: 1979
92 Added: competition: 'IFBB Mr. Olympia'
93 Added: place: 1
94 Added: category: 'Heavyweight Division').
95 Added: (MFTPrize
96 Added: year: 1979
97 Added: competition: 'IFBB Pittsburgh Pro Invitational'
98 Added: place: 2).
99 Added: (MFTPrize year: 1979 competition: 'IFBB Southern Pro Cup' place: 1).
100 Added: (MFTPrize year: 1980 competition: 'IFBB Mr. Olympia' place: 5) }
101 Added: ]
src/MyFitnessTracker/MFTMuscleGroup.class.st
index d2726cbb..75354d4e 100644..100644
@@ -1,6 +1,6 @@
1 1 Class {
2 2 #name : #MFTMuscleGroup,
3 Removed: #superclass : #Object,
3 Added: #superclass : #SBSComponent,
4 4 #instVars : [
5 5 'englishName',
6 6 'latinName',
@@ -182,26 +182,25 @@
182 182 { #category : #rendering }
183 183 MFTMuscleGroup >> renderContentOn: html [
184 184
185 Removed: html container: [
186 Removed: html heading level2 with: englishName capitalized.
187 Removed: description ifNotEmpty: [
188 Removed: html
189 Removed: text: description;
190 Removed: break ].
191 Removed: muscles ifNotEmpty: [
192 Removed: html
193 Removed: text: 'This group is comprised of:';
194 Removed: definitionList: [
195 Removed: muscles do: [ :muscle |
196 Removed: html definitionTerm: [
197 Removed: html text: muscle englishName capitalized.
198 Removed: muscle latinName ifNotEmpty: [
199 Removed: html space.
200 Removed: html text: '('.
201 Removed: html anchor
202 Removed: url: muscle linkTerminologiaAnatomica;
203 Removed: with: muscle latinName.
204 Removed: html text: ')' ] ].
205 Removed: html definitionData: muscle description.
206 Removed: muscle renderContentOn: html ] ] ] ]
185 Added: html heading level2 with: englishName capitalized.
186 Added: description ifNotEmpty: [
187 Added: html
188 Added: text: description;
189 Added: break ].
190 Added: muscles ifNotEmpty: [
191 Added: html
192 Added: text: 'This group is comprised of:';
193 Added: definitionList: [
194 Added: muscles do: [ :muscle |
195 Added: html definitionTerm: [
196 Added: html text: muscle englishName capitalized.
197 Added: muscle latinName ifNotEmpty: [
198 Added: html space.
199 Added: html text: '('.
200 Added: html anchor
201 Added: url: muscle linkTerminologiaAnatomica;
202 Added: with: muscle latinName.
203 Added: html text: ')' ] ].
204 Added: html definitionData: muscle description.
205 Added: muscle renderContentOn: html ] ] ]
207 206 ]
src/MyFitnessTracker/MFTMusclesArticle.class.st
index 885ff81e..ef493044 100644..100644
@@ -7,6 +7,12 @@
7 7 #category : #'MyFitnessTracker-Components'
8 8 }
9 9
10 Added: { #category : #hooks }
11 Added: MFTMusclesArticle >> children [
12 Added:
13 Added: ^ muscleGroups
14 Added: ]
15 Added:
10 16 { #category : #initialization }
11 17 MFTMusclesArticle >> initialize [
12 18
@@ -24,5 +30,5 @@
24 30 MFTMusclesArticle >> renderContentOn: html [
25 31
26 32 html heading: title.
27 Removed: muscleGroups do: [ :muscleGroup | muscleGroup renderContentOn: html ]
33 Added: muscleGroups do: [ :muscleGroup | html render: muscleGroup ]
28 34 ]
src/MyFitnessTracker/MFTPage.class.st
index 07330d7d..689433c2 100644..100644
@@ -7,11 +7,17 @@
7 7 #category : #'MyFitnessTracker-Components'
8 8 }
9 9
10 Added: { #category : #'as yet unclassified' }
11 Added: MFTPage >> loadUserData [
12 Added:
13 Added: ^ nil
14 Added: ]
15 Added:
10 16 { #category : #rendering }
11 17 MFTPage >> renderPageOn: html with: aBlock [
12 18
13 19 html container
14 Removed: style: 'max-width: 60vw';
20 Added: style: 'max-width: 60rem';
15 21 with: aBlock
16 22 ]
17 23
src/MyFitnessTracker/MFTPageManager.class.st
index 4647489e..45ae13b7 100644..100644
@@ -4,6 +4,8 @@
4 4 #instVars : [
5 5 'mainNavigationBar',
6 6 'mainPages',
7 Added: 'header',
8 Added: 'footer',
7 9 'activePage'
8 10 ],
9 11 #category : #MyFitnessTracker
@@ -16,61 +18,70 @@
16 18 ]
17 19
18 20 { #category : #accessing }
19 Removed: MFTPageManager >> activePage: anIndex [
21 Added: MFTPageManager >> activePage: aKey [
20 22
21 Removed: activePage := mainPages at: anIndex
23 Added: activePage := mainPages at: aKey
22 24 ]
23 25
24 26 { #category : #'as yet unclassified' }
25 Removed: MFTPageManager >> defaultFooter [
27 Added: MFTPageManager >> defaultPublicPages [
26 28
27 Removed: ^ MFTFooterComponent new
29 Added: ^ OrderedDictionary newFrom: {
30 Added: (#landing -> MFTPublicLandingPage new).
31 Added: (#workouts -> MFTWorkoutsListPage new).
32 Added: (#weights -> MFTWeightsListPage new).
33 Added: (#learn -> MFTLearnPage new).
34 Added: (#about -> MFTAboutPage new).
35 Added: (#profile -> MFTProfilePage new) }
28 36 ]
29 37
30 Removed: { #category : #'as yet unclassified' }
31 Removed: MFTPageManager >> defaultPublicPages [
38 Added: { #category : #accessing }
39 Added: MFTPageManager >> footer [
32 40
33 Removed: ^ {
34 Removed: MFTPublicLandingPage new.
35 Removed: MFTWorkoutsListPage placeholder.
36 Removed: MFTWeightsListPage placeholder.
37 Removed: MFTLearnPage new.
38 Removed: MFTAboutPage new.
39 Removed: MFTProfilePage new }
41 Added: ^ footer
40 42 ]
41 43
42 Removed: { #category : #initialization }
43 Removed: MFTPageManager >> initialize [
44 Added: { #category : #accessing }
45 Added: MFTPageManager >> footer: anObject [
44 46
45 Removed: mainNavigationBar := MFTMainNavigationBarComponent new.
46 Removed: mainPages := self defaultPublicPages.
47 Removed: activePage := mainPages at: 1
47 Added: footer := anObject
48 48 ]
49 49
50 Removed: { #category : #'as yet unclassified' }
51 Removed: MFTPageManager >> loadUserLandingPage [
50 Added: { #category : #accessing }
51 Added: MFTPageManager >> header [
52 52
53 Removed: mainPages at: 1 put: MFTUserLandingPage new
53 Added: ^ header
54 54 ]
55 55
56 Removed: { #category : #'as yet unclassified' }
57 Removed: MFTPageManager >> loadUserPages [
56 Added: { #category : #accessing }
57 Added: MFTPageManager >> header: anObject [
58 58
59 Removed: self loadUserLandingPage.
60 Removed: self loadUserWorkouts.
61 Removed: self loadUserWeights.
59 Added: header := anObject
62 60 ]
63 61
62 Added: { #category : #initialization }
63 Added: MFTPageManager >> initialize [
64 Added:
65 Added: mainPages := self defaultPublicPages.
66 Added: activePage := mainPages at: #landing.
67 Added:
68 Added: mainNavigationBar := MFTMainNavigationBarComponent new.
69 Added: header := MFTRegisterProspectEmailHeader new.
70 Added: footer := MFTDefaultFooter new
71 Added: ]
72 Added:
64 73 { #category : #'as yet unclassified' }
65 Removed: MFTPageManager >> loadUserWeights [
74 Added: MFTPageManager >> loadPublicPages [
66 75
67 Removed: (mainPages at: 3) loadUserWeights
76 Added: mainPages at: 1 put: MFTPublicLandingPage new.
77 Added: self activePage: 1
68 78 ]
69 79
70 80 { #category : #'as yet unclassified' }
71 Removed: MFTPageManager >> loadUserWorkouts [
81 Added: MFTPageManager >> loadUserPages [
72 82
73 Removed: (mainPages at: 2) loadUserWorkouts
83 Added: mainPages do: [ :page | page loadUserData ].
84 Added: self activePage: 1
74 85 ]
75 86
76 87 { #category : #accessing }
@@ -95,10 +106,4 @@
95 106 MFTPageManager >> mainPages: aCollection [
96 107
97 108 mainPages := aCollection
98 Removed: ]
99 Removed:
100 Removed: { #category : #'as yet unclassified' }
101 Removed: MFTPageManager >> registerProspectEmailHeader [
102 Removed:
103 Removed: ^ MFTRegisterProspectEmailHeader new
104 109 ]
src/MyFitnessTracker/MFTPrize.class.st
index 00000000..22547f41 000000..100644
@@ -0,0 +1,80 @@
1 Added: Class {
2 Added: #name : #MFTPrize,
3 Added: #superclass : #Object,
4 Added: #instVars : [
5 Added: 'year',
6 Added: 'competition',
7 Added: 'place',
8 Added: 'category'
9 Added: ],
10 Added: #category : #'MyFitnessTracker-Model'
11 Added: }
12 Added:
13 Added: { #category : #'as yet unclassified' }
14 Added: MFTPrize class >> year: aDate competition: aCompetition place: anInteger [
15 Added:
16 Added: ^ self new
17 Added: year: aDate;
18 Added: competition: aCompetition;
19 Added: place: anInteger;
20 Added: yourself
21 Added: ]
22 Added:
23 Added: { #category : #'as yet unclassified' }
24 Added: MFTPrize class >> year: aDate competition: aCompetition place: anInteger category: aCategory [
25 Added:
26 Added: ^ self new
27 Added: year: aDate;
28 Added: competition: aCompetition;
29 Added: place: anInteger;
30 Added: category: aCategory;
31 Added: yourself
32 Added: ]
33 Added:
34 Added: { #category : #accessing }
35 Added: MFTPrize >> category [
36 Added:
37 Added: ^ category
38 Added: ]
39 Added:
40 Added: { #category : #accessing }
41 Added: MFTPrize >> category: anObject [
42 Added:
43 Added: category := anObject
44 Added: ]
45 Added:
46 Added: { #category : #accessing }
47 Added: MFTPrize >> competition [
48 Added:
49 Added: ^ competition
50 Added: ]
51 Added:
52 Added: { #category : #accessing }
53 Added: MFTPrize >> competition: anObject [
54 Added:
55 Added: competition := anObject
56 Added: ]
57 Added:
58 Added: { #category : #accessing }
59 Added: MFTPrize >> place [
60 Added:
61 Added: ^ place
62 Added: ]
63 Added:
64 Added: { #category : #accessing }
65 Added: MFTPrize >> place: anObject [
66 Added:
67 Added: place := anObject
68 Added: ]
69 Added:
70 Added: { #category : #accessing }
71 Added: MFTPrize >> year [
72 Added:
73 Added: ^ year
74 Added: ]
75 Added:
76 Added: { #category : #accessing }
77 Added: MFTPrize >> year: anObject [
78 Added:
79 Added: year := anObject
80 Added: ]
src/MyFitnessTracker/MFTProfilePage.class.st
index 2f60928a..4298e255 100644..100644
@@ -14,5 +14,47 @@
14 14 { #category : #rendering }
15 15 MFTProfilePage >> renderContentOn: html [
16 16
17 Removed: self renderPageOn: html with: [ html text: 'Welcome!' ]
17 Added: | user |
18 Added: user := self session user.
19 Added:
20 Added: self renderPageOn: html with: [
21 Added: html heading level1 with: [
22 Added: html
23 Added: code: self session user username;
24 Added: text: '''s profile' ].
25 Added: user isLoggedIn ifFalse: [
26 Added: html paragraph: [
27 Added: html
28 Added: text:
29 Added: 'You aren''t logged in. To create an account, only two things are required: a unique username, and a password.';
30 Added: break.
31 Added: html anchor
32 Added: callback: [ self error: 'TODO' ];
33 Added: with: 'Why not collect more user data?' ].
34 Added: html table
35 Added: class: 'table';
36 Added: with: [
37 Added: user dataDictionary keysAndValuesDo: [ :key :value |
38 Added: html tableRow: [
39 Added: html tableData: key.
40 Added: html tableData: value ] ] ] ] ]
41 Added: ]
42 Added:
43 Added: { #category : #rendering }
44 Added: MFTProfilePage >> renderProfileActionsButtonGroupOn: html at: i [
45 Added:
46 Added: html form: [
47 Added: html buttonGroup
48 Added: beSmall;
49 Added: with: [
50 Added: html formButton
51 Added: beSecondary;
52 Added: formControl;
53 Added: callback: [ self editWeightAt: i ];
54 Added: with: 'Edit'.
55 Added: html formButton
56 Added: beDanger;
57 Added: formControl;
58 Added: callback: [ self removeWeightAt: i ];
59 Added: with: 'Delete' ] ]
18 60 ]
src/MyFitnessTracker/MFTPublicLandingPage.class.st
index bf765025..8dd711e2 100644..100644
@@ -1,18 +1,9 @@
1 1 Class {
2 2 #name : #MFTPublicLandingPage,
3 Removed: #superclass : #MFTPage,
4 Removed: #instVars : [
5 Removed: 'cards'
6 Removed: ],
3 Added: #superclass : #MFTLandingPage,
7 4 #category : #'MyFitnessTracker-Components'
8 5 }
9 6
10 Removed: { #category : #hooks }
11 Removed: MFTPublicLandingPage >> children [
12 Removed:
13 Removed: ^ cards
14 Removed: ]
15 Removed:
16 7 { #category : #'as yet unclassified' }
17 8 MFTPublicLandingPage >> defaultCards [
18 9
@@ -31,12 +22,8 @@
31 22 cards := self defaultCards.
32 23 ]
33 24
34 Removed: { #category : #rendering }
35 Removed: MFTPublicLandingPage >> renderContentOn: html [
25 Added: { #category : #'as yet unclassified' }
26 Added: MFTPublicLandingPage >> loadUserData [
36 27
37 Removed: self renderPageOn: html with: [
38 Removed: html div
39 Removed: style:
40 Removed: 'display: flex; flex-wrap: wrap; justify-content: space-around; gap: 1em';
41 Removed: with: [ cards do: [ :card | html render: card ] ] ]
28 Added: self session pageManager mainPages at: #landing put: MFTUserLandingPage new
42 29 ]
src/MyFitnessTracker/MFTScreenComponent.class.st
index d7d08bdf..94d8cfc1 100644..100644
@@ -2,7 +2,6 @@
2 2 #name : #MFTScreenComponent,
3 3 #superclass : #SBSComponent,
4 4 #instVars : [
5 Removed: 'footer',
6 5 'pm'
7 6 ],
8 7 #category : #'MyFitnessTracker-Components'
@@ -12,27 +11,25 @@
12 11 MFTScreenComponent >> children [
13 12
14 13 ^ {
15 Removed: pm registerProspectEmailHeader.
14 Added: pm header.
16 15 pm mainNavigationBar.
17 16 pm activePage.
18 Removed: footer }
17 Added: pm footer }
19 18 ]
20 19
21 20 { #category : #initialization }
22 21 MFTScreenComponent >> initialize [
23 22
24 23 super initialize.
25 Removed: pm := self session pageManager.
26 Removed: footer := pm defaultFooter
24 Added: pm := self session pageManager
27 25 ]
28 26
29 27 { #category : #rendering }
30 28 MFTScreenComponent >> renderContentOn: html [
31 29
32 Removed: self session user isLoggedIn ifFalse: [
33 Removed: html render: pm registerProspectEmailHeader ].
30 Added: self session user isLoggedIn ifFalse: [ html render: pm header ].
34 31 html
35 32 render: pm mainNavigationBar;
36 33 render: pm activePage;
37 Removed: render: footer
34 Added: render: pm footer
38 35 ]
src/MyFitnessTracker/MFTSession.class.st
index 242b9370..2ef52037 100644..100644
@@ -61,7 +61,8 @@
61 61 MFTSession >> unregistered [
62 62
63 63 db connection close.
64 Removed: user := MFTUser new
64 Added: user := MFTUser new.
65 Added: pageManager loadPublicPages
65 66 ]
66 67
67 68 { #category : #accessing }
src/MyFitnessTracker/MFTUser.class.st
index 86c5931c..45cd945d 100644..100644
@@ -34,10 +34,10 @@
34 34 username: 'mrs_default';
35 35 realFirstName: 'Deborah';
36 36 realLastName: 'Default';
37 Removed: dateOfBirth: Date today;
37 Added: dateOfBirth: (Date fromString: '01/01/2000');
38 38 isLoggedIn: false;
39 Removed: workouts: MFTWorkoutsListPage placeholder workouts;
40 Removed: weights: MFTWeightsListPage placeholder weights
39 Added: workouts: self placeholderWorkouts;
40 Added: weights: self placeholderWeights
41 41 ]
42 42
43 43 { #category : #'instance creation' }
@@ -61,6 +61,72 @@
61 61 yourself
62 62 ]
63 63
64 Added: { #category : #'as yet unclassified' }
65 Added: MFTUser class >> placeholderWeights [
66 Added:
67 Added: ^ OrderedCollection withAll: {
68 Added: (MFTWeight date: (Date fromString: '01/01/2024') value: 90).
69 Added: (MFTWeight date: (Date fromString: '01/02/2024') value: 91).
70 Added: (MFTWeight date: (Date fromString: '01/03/2024') value: 92).
71 Added: (MFTWeight date: (Date fromString: '01/04/2024') value: 93) }
72 Added: ]
73 Added:
74 Added: { #category : #'as yet unclassified' }
75 Added: MFTUser class >> placeholderWorkouts [
76 Added:
77 Added: | placeholderWorkouts workout1 workout2 workout3 |
78 Added: placeholderWorkouts := OrderedCollection new.
79 Added: workout1 := MFTWorkout new
80 Added: date: (Date fromString: '01/03/2023');
81 Added: primaryMuscle: MFTMuscleGroup chest;
82 Added: exercises: (OrderedCollection
83 Added: with: (MFTExercise cableRow sets: {
84 Added: (MFTSet reps: 8 rpe: 6).
85 Added: (MFTSet reps: 6 rpe: 8).
86 Added: (MFTSet reps: 6 rpe: 10).
87 Added: (MFTSet reps: 15 rpe: 4) })
88 Added: with: (MFTExercise shoulderPressDumbell sets: {
89 Added: (MFTSet reps: 10 rpe: 6).
90 Added: (MFTSet reps: 6 rpe: 8).
91 Added: (MFTSet reps: 6 rpe: 10) })
92 Added: with: (MFTExercise declineBenchPress sets: {
93 Added: (MFTSet reps: 5 rpe: 6).
94 Added: (MFTSet reps: 6 rpe: 8).
95 Added: (MFTSet reps: 8 rpe: 10) })).
96 Added: workout2 := MFTWorkout new
97 Added: date: (Date fromString: '01/02/2023');
98 Added: exercises: (OrderedCollection
99 Added: with: (MFTExercise cableRow sets: {
100 Added: (MFTSet reps: 8 rpe: 6).
101 Added: (MFTSet reps: 6 rpe: 8).
102 Added: (MFTSet reps: 6 rpe: 10).
103 Added: (MFTSet reps: 15 rpe: 4) })
104 Added: with: MFTExercise shoulderPressDumbell
105 Added: with: MFTExercise declineBenchPress).
106 Added: workout3 := MFTWorkout new
107 Added: date: (Date fromString: '01/01/2023');
108 Added: addExercise: MFTExercise cableRow;
109 Added: addExercise: MFTExercise shoulderPressDumbell;
110 Added: addExercise: MFTExercise declineBenchPress.
111 Added: placeholderWorkouts
112 Added: add: workout1;
113 Added: add: workout2;
114 Added: add: workout3.
115 Added:
116 Added: ^ placeholderWorkouts
117 Added: ]
118 Added:
119 Added: { #category : #'as yet unclassified' }
120 Added: MFTUser >> dataDictionary [
121 Added:
122 Added: ^ OrderedDictionary newFrom: {
123 Added: (#username -> username).
124 Added: (#'date of birth' -> dateOfBirth).
125 Added: (#'first name' -> realFirstName).
126 Added: (#'last name' -> realLastName).
127 Added: (#'last login date and time' -> lastLoginDateAndTime) }
128 Added: ]
129 Added:
64 130 { #category : #accessing }
65 131 MFTUser >> dateOfBirth [
66 132
@@ -83,6 +149,7 @@
83 149 realLastName := String new.
84 150 dateOfBirth := Date new.
85 151 isLoggedIn := false.
152 Added: lastLoginDateAndTime := DateAndTime now asUTC rounded asString.
86 153 workouts := OrderedCollection new.
87 154 weights := OrderedCollection new
88 155 ]
@@ -172,9 +239,9 @@
172 239 ]
173 240
174 241 { #category : #accessing }
175 Removed: MFTUser >> weights: anObject [
242 Added: MFTUser >> weights: aCollection [
176 243
177 Removed: weights := anObject
244 Added: weights := aCollection
178 245 ]
179 246
180 247 { #category : #accessing }
src/MyFitnessTracker/MFTUserLandingPage.class.st
index 7c8b789c..3611b2cd 100644..100644
@@ -1,27 +1,22 @@
1 1 Class {
2 2 #name : #MFTUserLandingPage,
3 Removed: #superclass : #MFTPage,
3 Added: #superclass : #MFTLandingPage,
4 4 #category : #'MyFitnessTracker-Components'
5 5 }
6 6
7 Removed: { #category : #initialization }
8 Removed: MFTUserLandingPage >> initialize [
7 Added: { #category : #'as yet unclassified' }
8 Added: MFTUserLandingPage >> defaultCards [
9 9
10 Removed: super initialize.
11 Removed: title := self session user username
10 Added: ^ {
11 Added: MFTMainUserCard new.
12 Added: MFTWorkoutsCard new.
13 Added: MFTCard new }
12 14 ]
13 15
14 Removed: { #category : #rendering }
15 Removed: MFTUserLandingPage >> renderContentOn: html [
16 Added: { #category : #initialization }
17 Added: MFTUserLandingPage >> initialize [
16 18
17 Removed: self renderPageOn: html with: [
18 Removed: html render: MFTMainUserCard new.
19 Removed: html render: MFTWorkoutsCard new.
20 Removed: html render: MFTCard new ]
21 Removed: ]
22 Removed:
23 Removed: { #category : #rendering }
24 Removed: MFTUserLandingPage >> renderWorkoutsSummaryCardOn: html [
25 Removed:
26 Removed: html card: [ html text: self session user username. ]
19 Added: super initialize.
20 Added: title := self session user username.
21 Added: cards := self defaultCards
27 22 ]
src/MyFitnessTracker/MFTWeightVsTimeGraph.class.st
index 602ace78..e56a8caf 100644..100644
@@ -29,9 +29,6 @@
29 29 datasets: [{
30 30 label: "weight",
31 31 data: ' , data asJavascript , ',
32 Removed: backgroundColor: "rgba(255, 99, 132, 0.2)",
33 Removed: borderColor: "rgba(255, 99, 132, 1)",
34 Removed: borderWidth: 1
35 32 }]
36 33 },
37 34 options: {
src/MyFitnessTracker/MFTWeightsListPage.class.st
index d03451d0..21c8a2de 100644..100644
@@ -1,9 +1,6 @@
1 1 Class {
2 2 #name : #MFTWeightsListPage,
3 3 #superclass : #MFTPage,
4 Removed: #instVars : [
5 Removed: 'weights'
6 Removed: ],
7 4 #category : #'MyFitnessTracker-Components'
8 5 }
9 6
@@ -30,7 +27,7 @@
30 27 { #category : #accessing }
31 28 MFTWeightsListPage >> editWeightAt: i [
32 29
33 Removed: self call: (MFTWeightDialog edit: (weights at: i))
30 Added: self call: (MFTWeightDialog edit: (self session user weights at: i))
34 31 ]
35 32
36 33 { #category : #initialization }
@@ -38,14 +35,14 @@
38 35
39 36 super initialize.
40 37 title := 'weights'.
41 Removed: weights := OrderedCollection new
38 Added:
42 39 ]
43 40
44 41 { #category : #'as yet unclassified' }
45 Removed: MFTWeightsListPage >> loadUserWeights [
42 Added: MFTWeightsListPage >> loadUserData [
46 43
47 Removed: weights := self session db selectWeightsWhereUser:
48 Removed: self session user
44 Added: self session user weights:
45 Added: (self session db selectWeightsWhereUser: self session user)
49 46 ]
50 47
51 48 { #category : #'as yet unclassified' }
@@ -61,7 +58,7 @@
61 58 { #category : #accessing }
62 59 MFTWeightsListPage >> removeWeightAt: i [
63 60
64 Removed: weights removeAt: i
61 Added: self session user weights removeAt: i
65 62 ]
66 63
67 64 { #category : #rendering }
@@ -82,6 +79,8 @@
82 79 { #category : #rendering }
83 80 MFTWeightsListPage >> renderContentOn: html [
84 81
82 Added: | weights |
83 Added: weights := self session user weights.
85 84 weights sort: [ :a :b | a date > b date ].
86 85
87 86 self renderPageOn: html with: [
@@ -121,7 +120,7 @@
121 120 tableHeading;
122 121 tableHeading: 'Date';
123 122 tableHeading: 'Value' ].
124 Removed: weights doWithIndex: [ :weight :i |
123 Added: self session user weights doWithIndex: [ :weight :i |
125 124 html tableRow: [
126 125 html tableData: [
127 126 self renderWeightActionsButtonGroupOn: html at: i ].
@@ -133,16 +132,4 @@
133 132 MFTWeightsListPage >> viewAnalytics [
134 133
135 134 self call: (MFTAnalyticsPage for: #weights)
136 Removed: ]
137 Removed:
138 Removed: { #category : #accessing }
139 Removed: MFTWeightsListPage >> weights [
140 Removed:
141 Removed: ^ weights
142 Removed: ]
143 Removed:
144 Removed: { #category : #accessing }
145 Removed: MFTWeightsListPage >> weights: aMFTWeightCollection [
146 Removed:
147 Removed: weights := aMFTWeightCollection
148 135 ]
src/MyFitnessTracker/MFTWorkout.class.st
index 380132af..fd80ea20 100644..100644
@@ -10,6 +10,13 @@
10 10 #category : #'MyFitnessTracker-Model'
11 11 }
12 12
13 Added: { #category : #'as yet unclassified' }
14 Added: MFTWorkout class >> allAthletes [
15 Added:
16 Added: ^ { #'Arnold Alois Schwarzenneger'. #'Michael John Mentzer'.
17 Added: #'Thomas Steven Platz' }
18 Added: ]
19 Added:
13 20 { #category : #'instance creation' }
14 21 MFTWorkout class >> newFromDictionary: aDictionary [
15 22
@@ -132,7 +139,7 @@
132 139 | grandTotal |
133 140 grandTotal := 0.
134 141 html table
135 Removed: class: 'table table-striped';
142 Added: class: 'table table-striped table-bordered';
136 143 with: [
137 144 self renderTableHeaderOn: html.
138 145 exercises do: [ :exercise |
src/MyFitnessTracker/MFTWorkoutTask.class.st
index 00000000..9e6aa184 000000..100644
@@ -0,0 +1,29 @@
1 Added: Class {
2 Added: #name : #MFTWorkoutTask,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'workout',
6 Added: 'exercises',
7 Added: 'date'
8 Added: ],
9 Added: #category : #'MyFitnessTracker-Dialogs'
10 Added: }
11 Added:
12 Added: { #category : #running }
13 Added: MFTWorkoutTask >> go [
14 Added:
15 Added: workout := MFTWorkout new.
16 Added: self setDate.
17 Added: self setPrimaryMuscle.
18 Added: self addExercises.
19 Added: self confirmAndSaveWorkout
20 Added: ]
21 Added:
22 Added: { #category : #initialization }
23 Added: MFTWorkoutTask >> setDate [
24 Added:
25 Added: | dateComponent |
26 Added: dateComponent := Date new.
27 Added: date := self call: dateComponent.
28 Added: workout date: date
29 Added: ]
src/MyFitnessTracker/MFTWorkoutsListPage.class.st
index d750ced5..3c65b34d 100644..100644
@@ -24,9 +24,6 @@
24 24 Class {
25 25 #name : #MFTWorkoutsListPage,
26 26 #superclass : #MFTPage,
27 Removed: #instVars : [
28 Removed: 'workouts'
29 Removed: ],
30 27 #category : #'MyFitnessTracker-Components'
31 28 }
32 29
@@ -83,31 +80,32 @@
83 80
84 81 | newWorkout |
85 82 newWorkout := self call: MFTWorkoutDialog new.
86 Removed: newWorkout ifNotNil: [ workouts add: newWorkout ]
83 Added: newWorkout ifNotNil: [ self session user workouts add: newWorkout ]
87 84 ]
88 85
89 86 { #category : #hooks }
90 87 MFTWorkoutsListPage >> children [
91 88
92 Removed: ^ workouts
89 Added: ^ self session user workouts
93 90 ]
94 91
95 92 { #category : #accessing }
96 93 MFTWorkoutsListPage >> confirmDeleteAt: i [
97 94
98 95 | workout confirmed |
99 Removed: workout := workouts at: i.
96 Added: workout := self session user workouts at: i.
100 97 confirmed := self call: (MFTConfirmDialog delete: workout).
101 Removed: confirmed ifTrue: [ workouts removeAt: i ]
98 Added: confirmed ifTrue: [ self session user workouts removeAt: i ]
102 99 ]
103 100
104 101 { #category : #'as yet unclassified' }
105 102 MFTWorkoutsListPage >> editWorkoutAt: i [
106 103
107 104 | oldWorkout newWorkout |
108 Removed: oldWorkout := workouts at: i.
105 Added: oldWorkout := self session user workouts at: i.
109 106 newWorkout := self call: (MFTWorkoutDialog edit: oldWorkout).
110 Removed: newWorkout ifNotNil: [ workouts at: i put: newWorkout ]
107 Added: newWorkout ifNotNil: [
108 Added: self session user workouts at: i put: newWorkout ]
111 109 ]
112 110
113 111 { #category : #initialization }
@@ -115,14 +113,14 @@
115 113
116 114 super initialize.
117 115 title := 'workouts'.
118 Removed: workouts := OrderedCollection new
116 Added:
119 117 ]
120 118
121 119 { #category : #'as yet unclassified' }
122 Removed: MFTWorkoutsListPage >> loadUserWorkouts [
120 Added: MFTWorkoutsListPage >> loadUserData [
123 121
124 Removed: workouts := self session db selectWorkoutsWhereUser:
125 Removed: self session user
122 Added: self session user workouts:
123 Added: (self session db selectWorkoutsWhereUser: self session user)
126 124 ]
127 125
128 126 { #category : #'as yet unclassified' }
@@ -153,6 +151,8 @@
153 151 { #category : #rendering }
154 152 MFTWorkoutsListPage >> renderContentOn: html [
155 153
154 Added: | workouts |
155 Added: workouts := self session user workouts.
156 156 workouts sort: [ :a :b | a date > b date ].
157 157
158 158 self renderPageOn: html with: [
@@ -184,7 +184,7 @@
184 184 id: 'accordion';
185 185 class: 'mt-3';
186 186 with: [
187 Removed: workouts doWithIndex: [ :workout :i |
187 Added: self session user workouts doWithIndex: [ :workout :i |
188 188 html accordionItem: [
189 189 html accordionHeading: [
190 190 html accordionButton
@@ -218,16 +218,4 @@
218 218 MFTWorkoutsListPage >> viewAnalytics [
219 219
220 220 self call: (MFTAnalyticsPage for: #workouts)
221 Removed: ]
222 Removed:
223 Removed: { #category : #accessing }
224 Removed: MFTWorkoutsListPage >> workouts [
225 Removed:
226 Removed: ^ workouts
227 Removed: ]
228 Removed:
229 Removed: { #category : #accessing }
230 Removed: MFTWorkoutsListPage >> workouts: aMFTWorkoutCollection [
231 Removed:
232 Removed: workouts := aMFTWorkoutCollection
233 221 ]