[Racket] Ferti hydroponic nutrient solver, redux.
Add a metric ton's worth of routes.
For now, let's emulate Rails routing, before we identify a more elegant architecture.
Changed files
handlers.rkt
@@ -47,18 +47,29 @@
47
47
void))
48
48
49
49
(define-values (fapg-dispatch fapg-url)
50
Removed:
(dispatch-rules [("ferti" "index") #:method "get" ferti-index]
50
Added:
(dispatch-rules [("index") #:method "get" index]
51
Added:
;; Ferti
52
Added:
[("ferti" "index") #:method "get" ferti-index]
51
53
[("ferti" "measurements") #:method "get" ferti-measurements]
52
54
[("ferti" "targets") #:method "get" ferti-targets]
53
55
[("ferti" "recipe") #:method "get" ferti-recipe]
54
56
[("ferti" "fertilizers") #:method "get" ferti-fertilizers]
55
Removed:
[("measurement" "new") #:method "get" new-measurement]
56
Removed:
[("measurement" "create") #:method "post" create-measurement]
57
Removed:
[("measurement" "destroy") #:method "post" destroy-measurement]
58
Removed:
[("target" "new") #:method "get" new-target]
59
Removed:
[("target" "create") #:method "post" create-target]
60
Removed:
[("fertilizer" "new") #:method "get" new-fertilizer]
61
Removed:
[("fertilizer" "create") #:method "post" create-fertilizer]
57
Added:
;; Nutrient measurements
58
Added:
[("ferti" "measurement" "new") #:method "get" new-measurement]
59
Added:
[("ferti" "measurement" "create") #:method "post" create-measurement]
60
Added:
[("ferti" "measurement" (integer-arg)) #:method "get" show-measurement]
61
Added:
[("ferti" "measurement" (integer-arg)) #:method "delete" destroy-measurement]
62
Added:
;; Nutrient targets
63
Added:
[("ferti" "target" "new") #:method "get" new-target]
64
Added:
[("ferti" "target" "create") #:method "post" create-target]
65
Added:
[("ferti" "target" (integer-arg)) #:method "get" show-target]
66
Added:
[("ferti" "target" (integer-arg)) #:method "delete" destroy-target]
67
Added:
;; Fertilizer products
68
Added:
[("ferti" "fertilizer" "new") #:method "get" new-fertilizer]
69
Added:
[("ferti" "fertilizer" "create") #:method "post" create-fertilizer]
70
Added:
[("ferti" "fertilizer" (integer-arg)) #:method "get" show-fertilizer]
71
Added:
[("ferti" "fertilizer" (integer-arg)) #:method "delete" destroy-fertilizer]
72
Added:
;; Default
62
73
[("") #:method "get" index]
63
74
[else fallback]))
64
75
@@ -104,8 +115,12 @@
104
115
(create-nutrient-measurement! measured-on nutrient-values)
105
116
(redirect-to "/ferti/measurements"))
106
117
107
Removed:
(define (destroy-measurement req)
108
Removed:
(delete-nutrient-measurement! req)
118
Added:
(define (show-measurement _ id)
119
Added:
(define nm (get-nutrient-measurement #:id id))
120
Added:
(render-page (show-measurement-page nm)))
121
Added:
122
Added:
(define (destroy-measurement _ id)
123
Added:
(delete-nutrient-measurement! id)
109
124
(redirect-to "/ferti/index"))
110
125
111
126
;; Nutrient targets
@@ -118,6 +133,14 @@
118
133
(create-nutrient-target! effective-on nutrient-values)
119
134
(redirect-to "/ferti/targets"))
120
135
136
Added:
(define (show-target _ id)
137
Added:
(define nt (get-nutrient-target #:id id))
138
Added:
(render-page (show-target-page nt)))
139
Added:
140
Added:
(define (destroy-target _ id)
141
Added:
(delete-nutrient-target! id)
142
Added:
(redirect-to "/ferti/targets"))
143
Added:
121
144
;; Fertilizer products
122
145
123
146
(define (new-fertilizer _)
@@ -127,6 +150,14 @@
127
150
(define-values (canonical-name brand-name nutrient-values)
128
151
(formlet-process (fertilizer-formlet) req))
129
152
(create-fertilizer-product! canonical-name brand-name nutrient-values)
153
Added:
(redirect-to "/ferti/fertilizers"))
154
Added:
155
Added:
(define (show-fertilizer _ id)
156
Added:
(define fp (get-fertilizer-product #:id id))
157
Added:
(render-page (show-fertilizer-page fp)))
158
Added:
159
Added:
(define (destroy-fertilizer _ id)
160
Added:
(delete-fertilizer-product! id)
130
161
(redirect-to "/ferti/fertilizers"))
131
162
132
163
;; Fallback
views.rkt
@@ -9,6 +9,9 @@
9
9
new-measurement-page
10
10
new-target-page
11
11
new-fertilizer-page
12
Added:
show-measurement-page
13
Added:
show-target-page
14
Added:
show-fertilizer-page
12
15
fallback-page)
13
16
14
17
(require gregor
@@ -17,6 +20,7 @@
17
20
"models/user.rkt"
18
21
"models/nutrient.rkt"
19
22
"models/nutrient-measurement.rkt"
23
Added:
"models/nutrient-target.rkt"
20
24
"models/fertilizer-product.rkt")
21
25
22
26
(define (page-template title body-xexpr)
@@ -89,28 +93,23 @@
89
93
90
94
(define (ferti-index-page)
91
95
(ferti-template
92
Removed:
'((p "La recette Ferti© est calculée en fonction d'un relevé de nutriments et d'une cible.")
96
Added:
`((p "La recette Ferti© est calculée en fonction d'un relevé de nutriments et d'une cible.")
93
97
(div ((class "btn-group-vertical"))
94
Removed:
(a ((class "btn btn-outline-primary") [href "/measurement/new"]) "Ajouter un relevé")
95
Removed:
(a ((class "btn btn-outline-primary") [href "/target/new"]) "Créer une cible")
96
Removed:
(a ((class "btn btn-outline-primary") [href "/fertilizer/new"]) "Ajouter un intrant")))))
98
Added:
(a ((class "btn btn-outline-primary") [href "/ferti/measurement/new"]) "Ajouter un relevé")
99
Added:
(a ((class "btn btn-outline-primary") [href "/ferti/target/new"]) "Créer une cible")
100
Added:
(a ((class "btn btn-outline-primary") [href "/ferti/fertilizer/new"])
101
Added:
"Ajouter un intrant")))))
97
102
98
103
(define (ferti-measurements-page nutrients measurements)
99
104
(define table
100
Removed:
`(table ((class "table table-striped"))
101
Removed:
(thead (tr (th "Date")
102
Removed:
,@(for/list ([n nutrients])
103
Removed:
`(th ((class "text-end")) ,(nutrient-formula n)))))
104
Removed:
(tbody ,@
105
Removed:
(for/list ([m measurements])
106
Removed:
`(tr (td ,(nutrient-measurement-date m))
107
Removed:
,@(for/list ([n nutrients])
108
Removed:
(define nutrient-value (hash-ref (nutrient-measurement-values m) n #f))
109
Removed:
`(td ((class "text-end"))
110
Removed:
,(if nutrient-value
111
Removed:
(round 2 nutrient-value)
112
Removed:
"—"))))))))
113
Removed:
(ferti-template `((h2 () "Relevés") (a ((class "btn btn-primary mb-3") [href "/measurement/new"])
105
Added:
`(table ((class "table"))
106
Added:
(thead (tr (th "Date")))
107
Added:
(tbody ,@(for/list ([m measurements])
108
Added:
`(tr (td (a ((href ,(format "/ferti/measurement/~a"
109
Added:
(nutrient-measurement-id m))))
110
Added:
,(nutrient-measurement-date m))))))))
111
Added:
(ferti-template `((h2 () "Relevés") (a ((class "btn btn-primary mb-3") [href
112
Added:
"/ferti/measurement/new"])
114
113
"Ajouter un relevé")
115
114
,table)))
116
115
@@ -132,9 +131,9 @@
132
131
,(if latest-target
133
132
(round 2 latest-target)
134
133
"—")))))))
135
Removed:
(ferti-template `((h2 () "Dernière Cible") (a ((class "btn btn-primary mb-3") [href "/target/new"])
136
Removed:
"Créer une cible")
137
Removed:
,table)))
134
Added:
(ferti-template `((h2 () "Dernière Cible")
135
Added:
(a ((class "btn btn-primary mb-3") [href "/ferti/target/new"]) "Créer une cible")
136
Added:
,table)))
138
137
139
138
(define (ferti-recipe-page fertilizer-recipe)
140
139
(define table
@@ -162,7 +161,8 @@
162
161
,@(for/list ([fertilizer fertilizers])
163
162
`(tr (td ,(fertilizer-name fertilizer))
164
163
(td ,(or (fertilizer-brand-name fertilizer) "—"))))))
165
Removed:
(ferti-template `((h2 () "Intrants") (a ((class "btn btn-primary mb-3") [href "/fertilizer/new"])
164
Added:
(ferti-template `((h2 () "Intrants") (a ((class "btn btn-primary mb-3") [href
165
Added:
"/ferti/fertilizer/new"])
166
166
"Ajouter un intrant")
167
167
,table)))
168
168
@@ -170,32 +170,48 @@
170
170
(page-template "Nouveau relevé"
171
171
`((h1 ((class "display-1 mb-3")) "Nouveau relevé")
172
172
(div ((class "mb-3") [style "max-width: 30em"])
173
Removed:
(form ([action "/measurement/create"] [method "POST"])
173
Added:
(form ([action "/ferti/measurement/create"] [method "POST"])
174
174
,@(formlet-display (measurements-formlet)))))))
175
175
176
176
(define (new-target-page)
177
177
(page-template "Nouvelle cible"
178
178
`((h1 ((class "display-1 mb-3")) "Nouvelle cible")
179
179
(div ((class "mb-3") [style "max-width: 30em"])
180
Removed:
(form ([action "/target/create"] [method "POST"])
180
Added:
(form ([action "/ferti/target/create"] [method "POST"])
181
181
,@(formlet-display (targets-formlet)))))))
182
182
183
183
(define (new-fertilizer-page)
184
184
(page-template "Nouvel intrant"
185
185
`((h1 ((class "display-1 mb-3")) "Nouvel intrant")
186
186
(div ((class "mb-3") [style "max-width: 30em"])
187
Removed:
(form ([action "/fertilizer/create"] [method "POST"])
187
Added:
(form ([action "/ferti/fertilizer/create"] [method "POST"])
188
188
,@(formlet-display (fertilizer-formlet)))))))
189
189
190
Added:
(define (show-measurement-page nm)
191
Added:
(page-template (format "Relevé du ~a" (nutrient-measurement-date nm))
192
Added:
'((h1 ((class "display-1 mb-3")) "Relevé"))))
193
Added:
194
Added:
(define (show-target-page nt)
195
Added:
(page-template (format "Cible ~a" (nutrient-target-id nt))
196
Added:
'((h1 ((class "display-1 mb-3")) "Cible"))))
197
Added:
198
Added:
(define (show-fertilizer-page fp)
199
Added:
(page-template (format "Intrant ~a" (fertilizer-product-id fp))
200
Added:
'((h1 ((class "display-1 mb-3")) "Intrant"))))
201
Added:
190
202
(define (index-page user)
191
Removed:
(page-template "Bienvenue à la FAPG"
192
Removed:
`((h1 ((class "display-1 mb-3"))
193
Removed:
,(string-join (list (if (<= (->hours (current-time)) 17) "Bonjour" "Bonsoir")
194
Removed:
(if user
195
Removed:
(user-name user)
196
Removed:
"et bienvenue"))))
197
Removed:
(p ,(~t (now) "'Dernière connexion à' HH:mm, 'le' EEEE d MMMM yyyy"))
198
Removed:
(a ((class "btn btn-primary mb-3") [href "/ferti/index"]) "Accéder à Ferti"))))
203
Added:
(page-template
204
Added:
"Bienvenue à la FAPG"
205
Added:
`((div ((class "jumbotron"))
206
Added:
(h1 ((class "display-1 mb-3"))
207
Added:
,(string-join (list (if (<= (->hours (current-time)) 17) "Bonjour" "Bonsoir")
208
Added:
(if user
209
Added:
(user-name user)
210
Added:
"et bienvenue"))))
211
Added:
(hr ((class "my-3")))
212
Added:
(p ((class "lead")) ,(~t (now) "'Dernière connexion à' HH:mm, 'le' EEEE d MMMM yyyy"))
213
Added:
(p ((class "lead"))
214
Added:
(a ((class "btn btn-primary mb-3") [href "/ferti/index"]) "Accéder à Ferti"))))))
199
215
200
216
(define (fallback-page request-code)
201
217
(page-template (format "Réponse: ~a" request-code)