aboutsummaryrefslogtreecommitdiff
path: root/client/src/View/Payment/Reducer.hs
blob: d221ff0f7e509e30d765cd791bf468f90a33674d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
module View.Payment.Reducer
  ( perPage
  , reducer
  , In(..)
  , Params(..)
  ) where

import           Data.Text    (Text)
import qualified Data.Text    as T
import           Data.Time    (NominalDiffTime)
import           Reflex.Dom   (Dynamic, Event, MonadWidget)
import qualified Reflex.Dom   as R

import           Common.Model (Frequency (..), PaymentPage)

import           Loadable     (Loadable2 (..))
import qualified Util.Ajax    as AjaxUtil
import qualified Util.Either  as EitherUtil

perPage :: Int
perPage = 7

data In t a b c = In
  { _in_page          :: Event t Int
  , _in_search        :: Event t Text
  , _in_frequency     :: Event t Frequency
  , _in_addPayment    :: Event t a
  , _in_editPayment   :: Event t b
  , _in_deletePayment :: Event t c
  }

data Params = Params
  { _params_page      :: Int
  , _params_search    :: Text
  , _params_frequency :: Frequency
  } deriving (Show)

initParams = Params 1 "" Punctual

data Msg
  = Page Int
  | Search Text
  | Frequency Common.Model.Frequency
  | ResetSearch
  deriving Show

reducer :: forall t m a b c. MonadWidget t m => In t a b c -> m (Loadable2 t PaymentPage)
reducer input = do

  postBuild <- R.getPostBuild

  debouncedSearch <- R.debounce (1 :: NominalDiffTime) (_in_search input)

  params <- R.foldDynMaybe
    (\msg params -> case msg of
      Page page     ->
        Just $ params { _params_page = page }

      Search ""     ->
        if _params_search params == "" then
          Nothing

        else
          Just $ initParams { _params_frequency = _params_frequency params }

      Search search ->
        Just $ params { _params_search = search, _params_page = _params_page initParams }

      Frequency frequency ->
        Just $ params { _params_frequency = frequency }

      ResetSearch   ->
        Just $ initParams { _params_frequency = _params_frequency params }
    )
    initParams
    (R.leftmost
      [ Page <$> _in_page input
      , Search <$> debouncedSearch
      , Frequency <$> _in_frequency input
      , ResetSearch <$ _in_addPayment input
      ])

  let paramsEvent =
        R.leftmost
          [ initParams <$ postBuild
          , R.updated params
          , R.tag (R.current params) (_in_editPayment input)
          , R.tag (R.current params) (_in_deletePayment input)
          ]

  getResult <- AjaxUtil.get (pageUrl <$> paramsEvent)

  isLoading <- R.holdDyn
    True
    (R.leftmost
      [ True <$ paramsEvent
      , False <$ getResult
      ])

  paymentPage <- R.holdDyn
    Nothing
    (fmap EitherUtil.eitherToMaybe getResult)

  return $ Loadable2 isLoading paymentPage

  where
    pageUrl (Params page search frequency) =
      "api/payments?page="
      <> (T.pack . show $ page)
      <> "&perPage="
      <> (T.pack . show $ perPage)
      <> "&search="
      <> search
      <> "&frequency="
      <> (T.pack $ show frequency)