aboutsummaryrefslogtreecommitdiff
path: root/client/src/View/Payment/Payment.hs
blob: 6bc1614f9347b9c8724148dfcc41c61a13b01f15 (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
module View.Payment.Payment
  ( view
  , In(..)
  ) where

import           Control.Monad.IO.Class   (liftIO)
import qualified Data.Maybe               as Maybe
import           Data.Text                (Text)
import qualified Data.Text                as T
import           Data.Time.Clock          (NominalDiffTime)
import           Prelude                  hiding (init)
import           Reflex.Dom               (Dynamic, Event, MonadWidget, Reflex)
import qualified Reflex.Dom               as R

import           Common.Model             (Currency, Frequency, Income (..),
                                           Payment (..), PaymentId,
                                           PaymentPage (..), User, UserId)
import qualified Common.Util.Text         as T

import qualified Component.Pages          as Pages
import           Loadable                 (Loadable (..))
import qualified Loadable
import qualified Util.Ajax                as AjaxUtil
import qualified Util.Reflex              as ReflexUtil
import qualified View.Payment.HeaderForm  as HeaderForm
import qualified View.Payment.HeaderInfos as HeaderInfos
import qualified View.Payment.Reducer     as Reducer
import qualified View.Payment.Table       as Table

data In t = In
  { _in_currentUser :: UserId
  , _in_users       :: [User]
  , _in_currency    :: Currency
  }

view :: forall t m. MonadWidget t m => In t -> m ()
view input = do

  categories <- AjaxUtil.getNow "api/categories"

  R.dyn . R.ffor categories . Loadable.view $ \categories -> do

    rec
      payments <- Reducer.reducer $ Reducer.In
        { Reducer._in_page          = page
        , Reducer._in_search        = HeaderForm._out_search form
        , Reducer._in_frequency     = HeaderForm._out_frequency form
        , Reducer._in_addPayment    = addPayment
        , Reducer._in_editPayment   = editPayment
        , Reducer._in_deletePayment = deletePayment
        }

      let eventFromResult :: forall a. (((), Table.Out t, Pages.Out t) -> Event t a) -> m (Event t a)
          eventFromResult op = ReflexUtil.flatten . fmap (Maybe.fromMaybe R.never . fmap op) $ result

      let addPayment =
            R.leftmost
              [ tableAddPayment
              , HeaderForm._out_addPayment form
              ]

      page <- eventFromResult $ Pages._out_newPage . (\(_, _, c) -> c)
      tableAddPayment <- eventFromResult $ Table._out_add . (\(_, b, _) -> b)
      editPayment <- eventFromResult $ Table._out_edit . (\(_, b, _) -> b)
      deletePayment <- eventFromResult $ Table._out_delete . (\(_, b, _) -> b)

      form <- HeaderForm.view $ HeaderForm.In
        { HeaderForm._in_reset             = () <$ addPayment
        , HeaderForm._in_categories        = categories
        }

      result <- R.dyn . R.ffor payments $
        Loadable.view $ \(PaymentPage page header payments count) -> do

          HeaderInfos.view $ HeaderInfos.In
            { HeaderInfos._in_users = _in_users input
            , HeaderInfos._in_currency = _in_currency input
            , HeaderInfos._in_header = header
            , HeaderInfos._in_paymentCount = count
            }

          table <- Table.view $ Table.In
            { Table._in_users = _in_users input
            , Table._in_currentUser = _in_currentUser input
            , Table._in_categories = categories
            , Table._in_currency = _in_currency input
            , Table._in_payments = payments
            }

          pages <- Pages.view $ Pages.In
            { Pages._in_total = R.constDyn count
            , Pages._in_perPage = Reducer.perPage
            , Pages._in_page = page
            }

          return ((), table, pages)

    return ()

  return ()