aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoris2017-04-21 17:31:50 +0200
committerJoris2017-04-21 17:31:50 +0200
commitd359e1d6203728783c97ed1313e62088dd44f386 (patch)
tree1841f31f6c97cdf3ae453c803915083dab37460d /src
parentb7a00a27d50353f53bd5e74a0c67f1a238518cb7 (diff)
Sort table by clicking on the header
Diffstat (limited to 'src')
-rw-r--r--src/Food.purs7
-rw-r--r--src/Main.purs2
-rw-r--r--src/Order.purs54
-rw-r--r--src/Page.purs73
4 files changed, 107 insertions, 29 deletions
diff --git a/src/Food.purs b/src/Food.purs
index 8a6bb57..2ced271 100644
--- a/src/Food.purs
+++ b/src/Food.purs
@@ -13,8 +13,6 @@ type Aliment =
, carbohydrates :: Int -- for 100 grams
}
--- let @a = 'I , { name: "A", glycemicIndex: TDTf Xdf i, carbohydrates: f XL }t^'
-
glycemicLoad :: Aliment -> Number
glycemicLoad aliment = toNumber aliment.glycemicIndex * toNumber aliment.carbohydrates / 100.0
@@ -63,7 +61,7 @@ all =
, { name: "Choux romanesco", glycemicIndex: 15, carbohydrates: 2 }
, { name: "Choux rouge", glycemicIndex: 15, carbohydrates: 7 }
, { name: "Choux vert", glycemicIndex: 15, carbohydrates: 1 }
- , { name: "citron", glycemicIndex: 20, carbohydrates: 3 }
+ , { name: "Citron", glycemicIndex: 20, carbohydrates: 3 }
, { name: "Citron vert", glycemicIndex: 20, carbohydrates: 7 }
, { name: "Citrouille", glycemicIndex: 80, carbohydrates: 6 }
, { name: "Clémentine", glycemicIndex: 30, carbohydrates: 9 }
@@ -164,6 +162,7 @@ all =
, { name: "Nectar de mangue", glycemicIndex: 50, carbohydrates: 12 }
, { name: "Nectarine", glycemicIndex: 35, carbohydrates: 13 }
+ , { name: "Noisette", glycemicIndex: 25, carbohydrates: 17 }
, { name: "Noix de cajou", glycemicIndex: 15, carbohydrates: 21 }
, { name: "Noix de coco", glycemicIndex: 35, carbohydrates: 10 }
, { name: "Noix de coco râpée", glycemicIndex: 35, carbohydrates: 12 }
@@ -181,7 +180,7 @@ all =
, { name: "Pain aux raisins", glycemicIndex: 70, carbohydrates: 46 }
, { name: "Pain au chocolat", glycemicIndex: 65, carbohydrates: 49 }
, { name: "Pain complet", glycemicIndex: 65, carbohydrates: 44 }
- , { name: "pain hamburger complet", glycemicIndex: 48, carbohydrates: 48 }
+ , { name: "Pain hamburger complet", glycemicIndex: 48, carbohydrates: 48 }
, { name: "Pastèque", glycemicIndex: 75, carbohydrates: 7 }
, { name: "Pâte", glycemicIndex: 70, carbohydrates: 20 }
, { name: "Pâte de fruit", glycemicIndex: 70, carbohydrates: 53 }
diff --git a/src/Main.purs b/src/Main.purs
index 85346b3..6c7fe42 100644
--- a/src/Main.purs
+++ b/src/Main.purs
@@ -12,4 +12,4 @@ import Page as Page
main :: Eff (HA.HalogenEffects ()) Unit
main = HA.runHalogenAff do
body <- HA.awaitBody
- runUI Page.component "" body
+ runUI Page.component Page.init body
diff --git a/src/Order.purs b/src/Order.purs
new file mode 100644
index 0000000..33c2be9
--- /dev/null
+++ b/src/Order.purs
@@ -0,0 +1,54 @@
+module Order
+ ( Order
+ , OrderKind(..)
+ , OrderDirection(..)
+ , init
+ , select
+ ) where
+
+import Prelude (class Eq, (==))
+import Data.Generic (class Generic, gEq)
+
+type Order =
+ { kind :: OrderKind
+ , direction :: OrderDirection
+ }
+
+data OrderKind =
+ Name
+ | GlycemicIndex
+ | Carbohydrates
+ | GlycemicLoad
+
+derive instance genericOrderKind :: Generic OrderKind
+
+instance eqOrderKind :: Eq OrderKind where
+ eq = gEq
+
+data OrderDirection =
+ Ascending
+ | Descending
+
+derive instance genericOrderDirection :: Generic OrderDirection
+
+instance eqOrderDirection :: Eq OrderDirection where
+ eq = gEq
+
+init :: Order
+init =
+ { kind: Name
+ , direction: initDirection
+ }
+
+select :: OrderKind -> Order -> Order
+select kind order =
+ if order.kind == kind
+ then order { direction = otherDirection order.direction }
+ else order { kind = kind, direction = initDirection }
+
+otherDirection :: OrderDirection -> OrderDirection
+otherDirection Ascending = Descending
+otherDirection Descending = Ascending
+
+initDirection :: OrderDirection
+initDirection = Ascending
diff --git a/src/Page.purs b/src/Page.purs
index f7c04c2..40c8ddc 100644
--- a/src/Page.purs
+++ b/src/Page.purs
@@ -1,10 +1,11 @@
module Page
( component
, Query
+ , init
) where
import Control.Monad.Aff (Aff)
-import Data.Array (sortBy, filter)
+import Data.Array (sortBy, filter, reverse)
import Data.Maybe (Maybe(..))
import Data.String (contains, Pattern(..))
import DOM (DOM)
@@ -18,19 +19,30 @@ import Food (Aliment)
import Food as Food
import Format as Format
import Indicator as Indicator
+import Order (Order, OrderKind)
+import Order as Order
data Query a =
- NoOp a
- | UpdateSearch String a
+ UpdateSearch String a
+ | SelectOrder OrderKind a
-type State = String
+type State =
+ { search :: String
+ , order :: Order
+ }
+
+init :: State
+init =
+ { search: ""
+ , order: Order.init
+ }
type Message = Unit
component :: forall eff. H.Component HH.HTML Query State Message (Aff (dom :: DOM | eff))
component =
H.component
- { initialState: const ""
+ { initialState: const init
, render
, eval
, receiver: const Nothing
@@ -40,41 +52,46 @@ component =
render state =
HH.div
[ HP.class_ $ HH.ClassName "page" ]
- [ renderHeader state
+ [ renderHeader state.order.kind state.search
, HH.div
[ HP.class_ $ HH.ClassName "aliments" ]
( Food.all
- # filter (\a -> contains (Pattern $ Format.string state) (Format.string a.name))
- # sortBy (\a b -> compare (Format.string a.name) (Format.string b.name))
+ # filter (\a -> contains (Pattern $ Format.string state.search) (Format.string a.name))
+ # sortBy compareAliments
+ # (if state.order.direction == Order.Ascending then id else reverse)
# map renderAliment
)
]
+ where
+ compareAliments :: Aliment -> Aliment -> Ordering
+ compareAliments a b =
+ case state.order.kind of
+ Order.Name -> compare (Format.string a.name) (Format.string b.name)
+ Order.GlycemicIndex -> compare a.glycemicIndex b.glycemicIndex
+ Order.Carbohydrates -> compare a.carbohydrates b.carbohydrates
+ Order.GlycemicLoad -> compare (Food.glycemicLoad a) (Food.glycemicLoad b)
eval :: Query ~> H.ComponentDSL State Query Message (Aff (dom :: DOM | eff))
eval = case _ of
- NoOp next -> pure next
UpdateSearch search next -> do
- H.put search
+ state <- H.get
+ H.put $ state { search = search }
+ pure next
+ SelectOrder kind next -> do
+ state <- H.get
+ H.put $ state { order = Order.select kind state.order }
pure next
-renderHeader :: String -> H.ComponentHTML Query
-renderHeader search =
+renderHeader :: OrderKind -> String -> H.ComponentHTML Query
+renderHeader orderKind search =
HH.div
[ HP.class_ $ HH.ClassName "header" ]
[ HH.div
[ HP.class_ $ HH.ClassName "title line" ]
- [ HH.div
- []
- [ HH.text "Aliment" ]
- , HH.div
- []
- [ HH.text "Index glycémique" ]
- , HH.div
- []
- [ HH.text "Glucides pour 100 g" ]
- , HH.div
- []
- [ HH.text "Charge glycémique" ]
+ [ button Order.Name "Aliment"
+ , button Order.GlycemicIndex "Index glycémique"
+ , button Order.Carbohydrates "Glucides pour 100 g"
+ , button Order.GlycemicLoad "Charge glycémique"
]
, HH.input
[ HP.class_ $ HH.ClassName "search line"
@@ -83,6 +100,14 @@ renderHeader search =
, HP.value search
]
]
+ where
+ button :: OrderKind -> String -> H.ComponentHTML Query
+ button kind label =
+ HH.button
+ [ HE.onClick (HE.input_ (SelectOrder kind))
+ , HP.class_ $ HH.ClassName (if orderKind == kind then "sorted" else "")
+ ]
+ [ HH.text label ]
renderAliment :: Aliment -> H.ComponentHTML Query
renderAliment aliment =