module View.Income.Form ( view , In(..) , Out(..) ) where import Data.Aeson (FromJSON, ToJSON) import Data.Text (Text) import qualified Data.Text as T import Data.Time.Calendar (Day) import qualified Data.Time.Calendar as Calendar import Data.Validation (Validation) import qualified Data.Validation as V import Reflex.Dom (Dynamic, Event, MonadWidget) import qualified Reflex.Dom as R import Common.Model (Income) import qualified Common.Msg as Msg import qualified Common.Validation.Income as IncomeValidation import qualified Component.Input as Input import qualified Component.ModalForm as ModalForm data In m t a = In { _in_cancel :: Event t () , _in_headerLabel :: Text , _in_amount :: Text , _in_date :: Day , _in_mkPayload :: Text -> Text -> a , _in_ajax :: Text -> Event t a -> m (Event t (Either Text Income)) } data Out t = Out { _out_hide :: Event t () , _out_addIncome :: Event t Income } view :: forall t m a. (MonadWidget t m, ToJSON a) => In m t a -> m (Out t) view input = do rec let reset = R.leftmost [ "" <$ ModalForm._out_cancel modalForm , "" <$ ModalForm._out_validate modalForm , "" <$ _in_cancel input ] modalForm <- ModalForm.view $ ModalForm.In { ModalForm._in_headerLabel = _in_headerLabel input , ModalForm._in_ajax = _in_ajax input "/api/income" , ModalForm._in_form = form reset (ModalForm._out_confirm modalForm) } return $ Out { _out_hide = ModalForm._out_hide modalForm , _out_addIncome = ModalForm._out_validate modalForm } where form :: Event t String -> Event t () -> m (Dynamic t (Validation Text a)) form reset confirm = do amount <- Input._out_raw <$> (Input.view (Input.defaultIn { Input._in_label = Msg.get Msg.Income_Amount , Input._in_initialValue = _in_amount input , Input._in_validation = IncomeValidation.amount }) (_in_amount input <$ reset) confirm) let initialDate = T.pack . Calendar.showGregorian . _in_date $ input date <- Input._out_raw <$> (Input.view (Input.defaultIn { Input._in_label = Msg.get Msg.Income_Date , Input._in_initialValue = initialDate , Input._in_inputType = "date" , Input._in_hasResetButton = False , Input._in_validation = IncomeValidation.date }) (initialDate <$ reset) confirm) return $ do a <- amount d <- date return . V.Success $ (_in_mkPayload input) a d