[Racket] Ferti hydroponic nutrient solver, redux.
Update views to reflect model evolution.
views.rkt
@@ -6,10 +6,10 @@
6
6
ferti-recipe-page
7
7
ferti-fertilizers-page
8
8
new-measurement-page
9
Removed:
new-target-page
9
Added:
new-rotation-page
10
10
new-fertilizer-page
11
11
show-measurement-page
12
Removed:
show-target-page
12
Added:
show-rotation-page
13
13
show-fertilizer-page
14
14
fallback-page)
15
15
@@ -19,8 +19,8 @@
19
19
"models/user.rkt"
20
20
"models/nutrient.rkt"
21
21
"models/nutrient-measurement.rkt"
22
Removed:
"models/nutrient-target.rkt"
23
22
"models/crop-rotation.rkt"
23
Added:
"models/crop-requirement.rkt"
24
24
"models/fertilizer-product.rkt")
25
25
26
26
(define (page-template title body-xexpr)
@@ -73,6 +73,9 @@
73
73
(define (round n number)
74
74
(~r number #:precision `(= ,n)))
75
75
76
Added:
(define (normal-date date-string)
77
Added:
(~t (iso8601->date date-string) "dd/MM/yyyy"))
78
Added:
76
79
;; Pages
77
80
78
81
(define (ferti-template body-xexpr)
@@ -84,7 +87,7 @@
84
87
(a ((class "nav-link") (aria-current "page") (href "/ferti/index")) "Accueil"))
85
88
(li ((class "nav-item"))
86
89
(a ((class "nav-link") (aria-current "page") (href "/ferti/measurements-and-rotations"))
87
Removed:
"Relevés & Cibles"))
90
Added:
"Relevés & Assolements"))
88
91
(li ((class "nav-item"))
89
92
(a ((class "nav-link") (aria-current "page") (href "/ferti/fertilizers")) "Intrants"))
90
93
#;(li ((class "nav-item"))
@@ -95,13 +98,13 @@
95
98
`((p "La recette Ferti© est calculée en fonction d'un relevé de nutriments et d'une cible.")
96
99
(div ((class "btn-group-vertical"))
97
100
(a ((class "btn btn-outline-primary") [href "/ferti/measurement/new"]) "Ajouter un relevé")
98
Removed:
(a ((class "btn btn-outline-primary") [href "/ferti/target/new"]) "Créer une cible")
101
Added:
(a ((class "btn btn-outline-primary") [href "/ferti/rotation/new"]) "Ajouter un assolement")
99
102
(a ((class "btn btn-outline-primary") [href "/ferti/fertilizer/new"])
100
103
"Ajouter un intrant")))))
101
104
102
105
(define (ferti-measurements-and-rotations-page nutrients measurements rotations)
103
106
(define (maybe-rotation-for-measurement m)
104
Removed:
(findf (λ (r) (= (crop-rotation-measurement-id r) (nutrient-measurement-id m))) rotations))
107
Added:
(findf (λ (r) (equal? (crop-rotation-date r) (nutrient-measurement-date m))) rotations))
105
108
(define table
106
109
`(table
107
110
((class "table"))
@@ -109,8 +112,7 @@
109
112
(tbody
110
113
,@(for/list ([m measurements])
111
114
(define maybe-rotation (maybe-rotation-for-measurement m))
112
Removed:
`(tr (td ((class "font-monospace"))
113
Removed:
,(~t (iso8601->date (nutrient-measurement-date m)) "dd/MM/yyyy"))
115
Added:
`(tr (td ((class "font-monospace")) ,(normal-date (nutrient-measurement-date m)))
114
116
(td (a ((class "btn btn-outline-secondary btn-sm")
115
117
(href ,(format "/ferti/measurement/~a" (nutrient-measurement-id m))))
116
118
"Modifier"))
@@ -118,7 +120,8 @@
118
120
`(a ((class "btn btn-outline-secondary btn-sm")
119
121
(href ,(format "/ferti/rotation/~a" (crop-rotation-id maybe-rotation))))
120
122
"Modifier")
121
Removed:
`(a ((class "btn btn-outline-primary btn-sm") (href "/ferti/rotation/new"))
123
Added:
`(a ((class "btn btn-outline-primary btn-sm")
124
Added:
(href ,(format "/ferti/rotation/new/~a" (nutrient-measurement-date m))))
122
125
"Ajouter")))
123
126
(td ,(if maybe-rotation
124
127
`(a ((class "btn btn-outline-secondary btn-sm")
@@ -126,10 +129,9 @@
126
129
"Consulter")
127
130
"—")))))))
128
131
(ferti-template
129
Removed:
`((h2 () "Relevés")
132
Added:
`((h2 () "Relevés & Assolements")
130
133
(div ((class "btn-group mb-3"))
131
134
(a ((class "btn btn-primary") [href "/ferti/measurement/new"]) "Ajouter un relevé")
132
Removed:
#;(a ((class "btn btn-secondary") [href "/ferti/target/new"]) "Créer une cible"))
133
135
,table)))
134
136
135
137
#;
@@ -155,37 +157,32 @@
155
157
(a ((class "btn btn-primary mb-3") [href "/ferti/target/new"]) "Créer une cible")
156
158
,table)))
157
159
158
Removed:
(define (ferti-recipe-page fertilizer-recipe)
160
Added:
(define (ferti-recipe-page recipe-date fertilizer-recipe)
159
161
(define table
160
162
`(table ((class "table"))
161
Removed:
(thead (tr (th "Intrant") (th ((class "text-end")) "Quantité (g/L)")))
162
Removed:
(tbody ,@(for/list ([fertilizer-amount fertilizer-recipe]
163
Removed:
#:when (not (zero? (cdr fertilizer-amount))))
164
Removed:
(match-define (cons fertilizer amount) fertilizer-amount)
163
Added:
(thead (tr (th "Intrant") (th ((class "text-end")) "Quantité (g)")))
164
Added:
(tbody ,@(for/list ([(fertilizer quantity) (in-hash fertilizer-recipe)]
165
Added:
#:when (not (zero? quantity)))
165
166
`(tr (td ()
166
Removed:
,(let ([canonical-name (fertilizer-name fertilizer)]
167
Added:
,(let ([canonical-name (fertilizer-product-name fertilizer)]
167
168
[brand-name (fertilizer-brand-name fertilizer)])
168
169
(if brand-name
169
170
(format "~a (~a)" brand-name canonical-name)
170
171
canonical-name)))
171
Removed:
(td ((class "text-end font-monospace")) ,(round 2 amount)))))))
172
Removed:
(ferti-template `((h2 () "Recette")
173
Removed:
,(if (ormap (λ (pair) (not (zero? (cdr pair)))) fertilizer-recipe)
174
Removed:
table
175
Removed:
`(p "La recette Ferti requiert au moins un relevé et une cible.")))))
172
Added:
(td ((class "text-end font-monospace")) ,(round 2 (* 100 quantity))))))))
173
Added:
(ferti-template `((h2 () ,(format "Recette du ~a" (normal-date recipe-date)))
174
Added:
(p "Quantités calculées pour 100'000 L.")
175
Added:
,table)))
176
176
177
177
(define (ferti-fertilizers-page fertilizers)
178
Removed:
(define (delete-button-for fp)
179
Removed:
`(a ((class "btn btn-outline-danger btn-sm")
180
Removed:
[href ,(format "/ferti/fertilizer/destroy/~a" (fertilizer-product-id fp))])
181
Removed:
"Supprimer"))
182
178
(define table
183
179
`(table ((class "table table-striped"))
184
Removed:
(tr (th () "Nom de référence") (th () "Nom de marque") (th () "Actions"))
185
Removed:
,@(for/list ([fertilizer fertilizers])
186
Removed:
`(tr (td ,(fertilizer-name fertilizer))
187
Removed:
(td ,(or (fertilizer-brand-name fertilizer) "—"))
188
Removed:
(td ,(delete-button-for fertilizer))))))
180
Added:
(tr (th () "Nom de référence") (th () "Nom de marque"))
181
Added:
,@
182
Added:
(for/list ([fertilizer fertilizers])
183
Added:
`(tr (td (a ([href ,(format "/ferti/fertilizer/~a" (fertilizer-product-id fertilizer))])
184
Added:
,(fertilizer-product-name fertilizer)))
185
Added:
(td ,(or (fertilizer-brand-name fertilizer) "—"))))))
189
186
(ferti-template `((h2 () "Intrants") (a ((class "btn btn-primary mb-3") [href
190
187
"/ferti/fertilizer/new"])
191
188
"Ajouter un intrant")
@@ -198,12 +195,12 @@
198
195
(form ([action "/ferti/measurement/create"] [method "POST"])
199
196
,@(formlet-display (measurements-formlet)))))))
200
197
201
Removed:
(define (new-target-page)
202
Removed:
(page-template "Nouvelle cible"
203
Removed:
`((h1 ((class "display-1 mb-3")) "Nouvelle cible")
198
Added:
(define (new-rotation-page #:date [date-string #f])
199
Added:
(page-template "Nouvel assolement"
200
Added:
`((h1 ((class "display-1 mb-3")) "Nouvel assolement")
204
201
(div ((class "mb-3") [style "max-width: 30em"])
205
Removed:
(form ([action "/ferti/target/create"] [method "POST"])
206
Removed:
,@(formlet-display (targets-formlet)))))))
202
Added:
(form ([action "/ferti/rotation/create"] [method "POST"])
203
Added:
,@(formlet-display (rotation-formlet #:date date-string)))))))
207
204
208
205
(define (new-fertilizer-page)
209
206
(page-template "Nouvel intrant"
@@ -213,23 +210,55 @@
213
210
,@(formlet-display (fertilizer-formlet)))))))
214
211
215
212
(define (show-measurement-page nm)
216
Removed:
(define title (format "Relevé du ~a" (nutrient-measurement-date nm)))
213
Added:
(define title (format "Relevé du ~a" (normal-date (nutrient-measurement-date nm))))
217
214
(define table
218
215
`(table ((class "table"))
219
Removed:
(thead (tr (th "Nutriment") (th ((class "text-end")) "Valeur de ce relevé")))
216
Added:
(thead (tr (th "Nutriment") (th ((class "text-end")) "Valeur de ce relevé (mg/L)")))
220
217
(tbody ,@(for/list ([n (get-nutrients)])
221
218
(define nutrient-value (hash-ref (nutrient-measurement-values nm) n 0))
222
219
`(tr (td ,(nutrient-french-name n))
223
220
(td ((class "text-end font-monospace")) ,(round 2 nutrient-value)))))))
224
Removed:
(page-template title `((h1 ((class "display-1 mb-3")) ,title) ,table)))
221
Added:
(page-template title
222
Added:
`((h1 ((class "display-1 mb-3")) ,title)
223
Added:
(a ((class "btn btn-danger")
224
Added:
[href ,(format "/ferti/measurement/destroy/~a" (nutrient-measurement-id nm))])
225
Added:
"Supprimer relevé")
226
Added:
,table)))
225
227
226
Removed:
(define (show-target-page nt)
227
Removed:
(page-template (format "Cible ~a" (nutrient-target-id nt))
228
Removed:
'((h1 ((class "display-1 mb-3")) "Cible"))))
228
Added:
(define (show-rotation-page cr)
229
Added:
(define title (format "Assolement du ~a" (normal-date (crop-rotation-date cr))))
230
Added:
(define table
231
Added:
`(table ((class "table"))
232
Added:
(thead (tr (th "Type de culture") (th ((class "text-end")) "Proportion (%)")))
233
Added:
(tbody ,@(for/list ([requirement (get-crop-requirements)])
234
Added:
(define requirement-proportion
235
Added:
(hash-ref (crop-rotation-requirements cr) requirement 0))
236
Added:
`(tr (td ,(crop-requirement-profile requirement))
237
Added:
(td ((class "text-end font-monospace"))
238
Added:
,(round 2 requirement-proportion)))))))
239
Added:
(page-template
240
Added:
title
241
Added:
`((h1 ((class "display-1 mb-3")) ,title)
242
Added:
(a ((class "btn btn-danger") [href ,(format "/ferti/rotation/destroy/~a" (crop-rotation-id cr))])
243
Added:
"Supprimer assolement")
244
Added:
,table)))
229
245
230
246
(define (show-fertilizer-page fp)
231
Removed:
(page-template (format "Intrant ~a" (fertilizer-product-id fp))
232
Removed:
'((h1 ((class "display-1 mb-3")) "Intrant"))))
247
Added:
(define title (fertilizer-product-name fp))
248
Added:
(define table
249
Added:
`(table ((class "table"))
250
Added:
(thead (tr (th "Nutriment") (th ((class "text-end")) "Apport (mg/L)")))
251
Added:
(tbody ,@(for/list ([n (get-nutrients)])
252
Added:
(define nutrient-value (hash-ref (fertilizer-product-values fp) n 0))
253
Added:
`(tr (td ,(nutrient-french-name n))
254
Added:
(td ((class "text-end font-monospace")) ,(round 2 nutrient-value)))))))
255
Added:
256
Added:
(page-template title
257
Added:
`((h1 ((class "display-1 mb-3")) ,title)
258
Added:
(a ((class "btn btn-danger")
259
Added:
[href ,(format "/ferti/fertilizer/destroy/~a" (fertilizer-product-id fp))])
260
Added:
"Supprimer")
261
Added:
,table)))
233
262
234
263
(define (index-page user)
235
264
(page-template