module View.Income.Form ( view , In(..) , Operation(..) ) where import Control.Monad.IO.Class (liftIO) import Data.Aeson (ToJSON) import qualified Data.Maybe as Maybe import Data.Text (Text) import qualified Data.Text as T import qualified Data.Time.Calendar as Calendar import qualified Data.Time.Clock as Time 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 (EditIncomeForm (..), Income (..)) import qualified Common.Msg as Msg import qualified Common.Util.Time as TimeUtil import qualified Common.Validation.Income as IncomeValidation import qualified Component.Input as Input import qualified Component.Modal as Modal import qualified Component.ModalForm as ModalForm import qualified Util.Ajax as Ajax data In t a = In { _in_operation :: Operation a } data Operation a = New (Text -> Text -> a) | Clone (Text -> Text -> a) Income | Edit (Text -> Text -> a) Income view :: forall t m a. (MonadWidget t m, ToJSON a) => In t a -> Modal.Content t m Income view input cancel = do rec let reset = R.leftmost [ "" <$ ModalForm._out_cancel modalForm , "" <$ ModalForm._out_validate modalForm , "" <$ cancel ] modalForm <- ModalForm.view $ ModalForm.In { ModalForm._in_headerLabel = headerLabel , ModalForm._in_ajax = ajax "/api/income" , ModalForm._in_form = form reset (ModalForm._out_confirm modalForm) } return (ModalForm._out_hide modalForm, 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 = amount , Input._in_validation = IncomeValidation.amount }) (amount <$ reset) confirm) currentDay <- liftIO $ Time.getCurrentTime >>= TimeUtil.timeToDay let initialDate = T.pack . Calendar.showGregorian $ date currentDay 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 $ mkPayload a d op = _in_operation input amount = case op of New _ -> "" Clone _ income -> T.pack . show . _income_amount $ income Edit _ income -> T.pack . show . _income_amount $ income date currentDay = case op of New _ -> currentDay Clone _ _ -> currentDay Edit _ income -> _income_date income ajax = case op of New _ -> Ajax.post Clone _ _ -> Ajax.post Edit _ _ -> Ajax.put headerLabel = case op of New _ -> Msg.get Msg.Income_AddLong Clone _ _ -> Msg.get Msg.Income_AddLong Edit _ _ -> Msg.get Msg.Income_Edit mkPayload = case op of New f -> f Clone f _ -> f Edit f _ -> f