From d359e1d6203728783c97ed1313e62088dd44f386 Mon Sep 17 00:00:00 2001 From: Joris Date: Fri, 21 Apr 2017 17:31:50 +0200 Subject: Sort table by clicking on the header --- public/main.css | 15 +++++++++++- src/Food.purs | 7 +++--- src/Main.purs | 2 +- src/Order.purs | 54 ++++++++++++++++++++++++++++++++++++++++++ src/Page.purs | 73 ++++++++++++++++++++++++++++++++++++++------------------- 5 files changed, 121 insertions(+), 30 deletions(-) create mode 100644 src/Order.purs diff --git a/public/main.css b/public/main.css index da0b04e..29f031c 100644 --- a/public/main.css +++ b/public/main.css @@ -33,10 +33,23 @@ body { margin: 0; } } .line.title { + height: 60px; +} + +.line.title > * { + border: 0; background-color: #333333; color: white; - font-size: 18px; + cursor: pointer; height: 60px; + font-size: 17px; + padding: 0 15px; + text-align: left; + transition: background-color 0.2s ease-in-out; +} + +.line.title > *.sorted { + background-color: #505050; } .line.search { 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 = -- cgit v1.2.3