module View.Payment.Pages ( widget , PagesIn(..) , PagesOut(..) ) where import qualified Data.Text as T import Reflex.Dom (Dynamic, Event, MonadWidget) import qualified Reflex.Dom as R import Component (ButtonIn (..), ButtonOut (..)) import qualified Component as Component import qualified Util.Reflex as ReflexUtil import qualified View.Icon as Icon data PagesIn t = PagesIn { _pagesIn_total :: Dynamic t Int , _pagesIn_perPage :: Int , _pagesIn_reset :: Event t () } data PagesOut t = PagesOut { _pagesOut_currentPage :: Dynamic t Int } widget :: forall t m. MonadWidget t m => PagesIn t -> m (PagesOut t) widget pagesIn = do currentPage <- ReflexUtil.divVisibleIf ((> 0) <$> total) $ pageButtons total perPage reset return $ PagesOut { _pagesOut_currentPage = currentPage } where total = _pagesIn_total pagesIn perPage = _pagesIn_perPage pagesIn reset = _pagesIn_reset pagesIn pageButtons :: forall t m. MonadWidget t m => Dynamic t Int -> Int -> Event t () -> m (Dynamic t Int) pageButtons total perPage reset = do R.divClass "pages" $ do rec currentPage <- R.holdDyn 1 . R.leftmost $ [ firstPageClic , previousPageClic , pageClic , nextPageClic , lastPageClic , 1 <$ reset ] firstPageClic <- pageButton noCurrentPage (R.constDyn 1) Icon.doubleLeftBar previousPageClic <- pageButton noCurrentPage (fmap (\x -> max (x - 1) 1) currentPage) Icon.doubleLeft pageClic <- pageEvent <$> (R.simpleList (range <$> currentPage <*> maxPage) $ \p -> pageButton (Just <$> currentPage) p (R.dynText $ fmap (T.pack . show) p)) nextPageClic <- pageButton noCurrentPage ((\c m -> min (c + 1) m) <$> currentPage <*> maxPage) Icon.doubleRight lastPageClic <- pageButton noCurrentPage maxPage Icon.doubleRightBar return currentPage where maxPage = R.ffor total (\t -> ceiling $ toRational t / toRational perPage) pageEvent = R.switch . R.current . fmap R.leftmost noCurrentPage = R.constDyn Nothing range :: Int -> Int -> [Int] range currentPage maxPage = [start..end] where sidePages = 2 start = max 1 (min (currentPage - sidePages) (maxPage - sidePages * 2)) end = min maxPage (start + sidePages * 2) pageButton :: forall t m. MonadWidget t m => Dynamic t (Maybe Int) -> Dynamic t Int -> m () -> m (Event t Int) pageButton currentPage page content = do clic <- _buttonOut_clic <$> (Component.button $ ButtonIn { _buttonIn_class = do cp <- currentPage p <- page if cp == Just p then "page current" else "page" , _buttonIn_content = content , _buttonIn_waiting = R.never , _buttonIn_tabIndex = Nothing , _buttonIn_submit = False }) return . fmap fst $ R.attach (R.current page) clic