summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Peter <dev@marius-peter.com>2025-12-14 15:30:37 +0100
committerMarius Peter <dev@marius-peter.com>2025-12-14 15:30:37 +0100
commitad966bf35d1a6d5761d186c40c3dcd8a661aa69b (patch)
tree5491001cc9b3f67bcfa958559238cf84fd15e2f4
parent2a1c552c44411e7f044bbd1585390cde31239043 (diff)
Add active state to Ferti tab bar + make views more orthogonal.
-rw-r--r--views.rkt149
1 files changed, 82 insertions, 67 deletions
diff --git a/views.rkt b/views.rkt
index ccafb99..2e32851 100644
--- a/views.rkt
+++ b/views.rkt
@@ -86,24 +86,28 @@
;; Ferti
-(define (ferti-template body-xexpr)
- (page-template "Ferti" `((h1 ((class "display-1 mb-3")) "Ferti") ,ferti-tabs ,@body-xexpr)))
+(define (ferti-template active-tab body-xexpr)
+ (page-template (format "Ferti — ~a" active-tab) `(,(ferti-tabs-bar active-tab) ,@body-xexpr)))
+
+(define (ferti-tabs-bar active-tab)
+ `(ul ((class "nav nav-tabs my-3"))
+ ,@
+ (for/list ([tab ferti-tabs])
+ (match-define (cons tab-title tab-action) tab)
+ `(li ((class "nav-item"))
+ (a ((class ,(string-append "nav-link" (if (equal? tab-title active-tab) " active" "")))
+ (aria-current "page")
+ (href ,tab-action))
+ ,tab-title)))))
(define ferti-tabs
- '(ul ((class "nav nav-tabs mb-3"))
- (li ((class "nav-item"))
- (a ((class "nav-link") (aria-current "page") (href "/ferti/index")) "Accueil"))
- (li ((class "nav-item"))
- (a ((class "nav-link") (aria-current "page") (href "/ferti/measurements-and-rotations"))
- "Relevés & Assolements"))
- (li ((class "nav-item"))
- (a ((class "nav-link") (aria-current "page") (href "/ferti/fertilizers")) "Intrants"))
- (li ((class "nav-item"))
- (a ((class "nav-link") (aria-current "page") (href "/ferti/crop-requirements"))
- "Cultures"))))
+ '(("Accueil" . "/ferti/index") ("Relevés et Assolements" . "/ferti/measurements-and-rotations")
+ ("Intrants" . "/ferti/fertilizers")
+ ("Cultures" . "/ferti/crop-requirements")))
(define (ferti-index-page)
(ferti-template
+ "Accueil"
`((p "La recette Ferti© est calculée en fonction d'un relevé de nutriments et d'un assolement.")
(div
((class "btn-group-vertical"))
@@ -119,47 +123,31 @@
((class "table"))
(thead (tr (th "Date du relevé") (th "Relevé") (th "Assolement") (th "Recette")))
(tbody
- ,@
- (for/list ([m measurements])
- (define maybe-rotation (maybe-rotation-for-measurement m))
- `(tr (td ((class "font-monospace align-middle")) ,(normal-date (nutrient-measurement-date m)))
- (td (a ((class "btn btn-outline-secondary btn-sm")
- (href ,(format "/ferti/measurements/~a" (nutrient-measurement-id m))))
- "Voir"))
- (td ,(if maybe-rotation
- `(a ((class "btn btn-outline-secondary btn-sm")
- (href ,(format "/ferti/rotations/~a" (crop-rotation-id maybe-rotation))))
- "Voir")
- `(a ((class "btn btn-outline-primary btn-sm")
- (href ,(format "/ferti/rotations/new/~a" (nutrient-measurement-date m))))
- "Ajouter")))
- (td ,(if maybe-rotation
- `(a ((class "btn btn-outline-secondary btn-sm")
- (href ,(format "/ferti/recipes/~a" (crop-rotation-date maybe-rotation))))
- "Voir")
- "—")))))))
- (ferti-template `((h2 () "Relevés et Assolements")
- (div ((class "btn-group mb-3"))
+ ,@(for/list ([m measurements])
+ (define maybe-rotation (maybe-rotation-for-measurement m))
+ `(tr
+ (td ((class "font-monospace align-middle")) ,(normal-date (nutrient-measurement-date m)))
+ (td (a ((class "btn btn-outline-secondary btn-sm")
+ (href ,(format "/ferti/measurements/~a" (nutrient-measurement-id m))))
+ "Consulter"))
+ (td ,(if maybe-rotation
+ `(a ((class "btn btn-outline-secondary btn-sm")
+ (href ,(format "/ferti/rotations/~a" (crop-rotation-id maybe-rotation))))
+ "Consulter")
+ `(a ((class "btn btn-outline-primary btn-sm")
+ (href ,(format "/ferti/rotations/new/~a" (nutrient-measurement-date m))))
+ "Ajouter")))
+ (td ,(if maybe-rotation
+ `(a ((class "btn btn-outline-secondary btn-sm")
+ (href ,(format "/ferti/recipes/~a" (crop-rotation-date maybe-rotation))))
+ "Consulter")
+ "—")))))))
+ (ferti-template "Relevés et Assolements"
+ `((div ((class "btn-group mb-3"))
(a ((class "btn btn-primary") [href "/ferti/measurements/new"])
"Ajouter un relevé"))
,table)))
-;; TODO: add bar chart for comparing to target concentrations
-(define (ferti-recipe-page recipe-date fertilizer-recipe)
- (define table
- `(table ((class "table"))
- (thead (tr (th "Intrant") (th "Marque") (th ((class "text-end")) "Quantité (g)")))
- (tbody ,@(for/list ([(fertilizer quantity) (in-hash fertilizer-recipe)]
- #:when (not (zero? quantity)))
- (define canonical-name (fertilizer-product-name fertilizer))
- (define brand-name (fertilizer-brand-name fertilizer))
- `(tr (td ,canonical-name)
- (td ,(if (non-empty-string? brand-name) brand-name "—"))
- (td ((class "text-end font-monospace")) ,(round 2 (* 100 quantity))))))))
- (ferti-template `((h2 () ,(format "Recette du ~a" (normal-date recipe-date)))
- (p "Quantités calculées pour 100'000 L.")
- ,table)))
-
(define (ferti-fertilizers-page fertilizers)
(define table
`(table ((class "table table-striped"))
@@ -169,10 +157,10 @@
`(tr (td (a ([href ,(format "/ferti/fertilizers/~a" (fertilizer-product-id fp))])
,(fertilizer-product-name fp)))
(td ,(if (and brand-name (non-empty-string? brand-name)) brand-name "—"))))))
- (ferti-template `((h2 () "Intrants") (a ((class "btn btn-primary mb-3") [href
- "/ferti/fertilizers/new"])
- "Ajouter un intrant")
- ,table)))
+ (ferti-template "Intrants"
+ `((a ((class "btn btn-primary mb-3") [href "/ferti/fertilizers/new"])
+ "Ajouter un intrant")
+ ,table)))
(define (ferti-crop-requirements-page crop-requirements)
(define table
@@ -185,10 +173,31 @@
(td ,(if crop-id
(string-titlecase (crop-name (get-crop #:id crop-id)))
"—"))))))
- (ferti-template `((h2 () "Profils de culture")
- (a ((class "btn btn-primary mb-3") [href "/ferti/crop-requirements/new"])
- "Ajouter un profil")
- ,table)))
+ (define button-group
+ '(div ((class "btn-group mb-3"))
+ (a ((class "btn btn-primary") [href "/ferti/crop-requirements/new"]) "Ajouter un profil")
+ (a ((class "btn btn-secondary") [href "/ferti/crop/new"]) "Ajouter une culture")))
+ (ferti-template "Cultures" `(,button-group ,table)))
+
+;; TODO: add bar chart for comparing to target concentrations
+(define (ferti-recipe-page recipe-date fertilizer-recipe)
+ (define normal-recipe-date (normal-date recipe-date))
+ (define title (format "Recette du ~a" normal-recipe-date))
+ (define table
+ `(table ((class "table"))
+ (thead (tr (th "Intrant") (th "Marque") (th ((class "text-end")) "Quantité (g)")))
+ (tbody ,@(for/list ([(fertilizer quantity) (in-hash fertilizer-recipe)]
+ #:when (not (zero? quantity)))
+ (define canonical-name (fertilizer-product-name fertilizer))
+ (define brand-name (fertilizer-brand-name fertilizer))
+ `(tr (td ,canonical-name)
+ (td ,(if (non-empty-string? brand-name) brand-name "—"))
+ (td ((class "text-end font-monospace")) ,(round 2 (* 100 quantity))))))))
+ (page-template title
+ `((h1 ((class "display-1 mb-3")) "Recette Ferti")
+ (h5 ((class "display-5 mb-3")) ,normal-recipe-date)
+ (p "Quantités calculées pour 100'000 L.")
+ ,table)))
;; New
@@ -230,7 +239,8 @@
;; Show
(define (show-measurement-page nm)
- (define title (format "Relevé du ~a" (normal-date (nutrient-measurement-date nm))))
+ (define id (nutrient-measurement-id nm))
+ (define measurement-date (normal-date (nutrient-measurement-date nm)))
(define table
`(table ((class "table") (style "max-width: 30em"))
(thead (tr (th "Nutriment") (th ((class "text-end")) "Concentration (mg/L)")))
@@ -240,17 +250,18 @@
(td ((class "text-end font-monospace")) ,(round 2 nutrient-value)))))))
(define button-group
`(div ((class "btn-group mb-3"))
- (a ((class "btn btn-primary")
- [href ,(format "/ferti/measurements/~a/edit" (nutrient-measurement-id nm))])
- "Modifier")
- (a ((class "btn btn-danger")
- [href ,(format "/ferti/measurements/~a/destroy" (nutrient-measurement-id nm))])
+ (a ((class "btn btn-primary") [href ,(format "/ferti/measurements/~a/edit" id)]) "Modifier")
+ (a ((class "btn btn-danger") [href ,(format "/ferti/measurements/~a/destroy" id)])
"Supprimer")))
- (page-template title `((h1 ((class "display-1 mb-3")) ,title) ,button-group ,table)))
+ (page-template (format "Relevé du ~a" measurement-date)
+ `((h1 ((class "display-1 mb-3")) "Relevé") (h5 ((class "display-5 mb-3"))
+ ,measurement-date)
+ ,button-group
+ ,table)))
(define (show-rotation-page cr)
(define id (crop-rotation-id cr))
- (define title (format "Assolement du ~a" (normal-date (crop-rotation-date cr))))
+ (define rotation-date (normal-date (crop-rotation-date cr)))
(define table
`(table ((class "table") (style "max-width: 30em"))
(thead (tr (th "Type de culture") (th ((class "text-end")) "Proportion (%)")))
@@ -266,7 +277,11 @@
(a ((class "btn btn-danger")
[href ,(format "/ferti/rotations/~a/destroy" (crop-rotation-id cr))])
"Supprimer")))
- (page-template title `((h1 ((class "display-1 mb-3")) ,title) ,button-group ,table)))
+ (page-template (format "Assolement du ~a" rotation-date)
+ `((h1 ((class "display-1 mb-3")) ,"Assolement") (h5 ((class "display-5 mb-3"))
+ ,rotation-date)
+ ,button-group
+ ,table)))
(define (show-fertilizer-page fp)
(define id (fertilizer-product-id fp))
Copyright 2019--2026 Marius PETER