diff options
Diffstat (limited to 'src/main/scala/reading/component/index/Menu.scala')
-rw-r--r-- | src/main/scala/reading/component/index/Menu.scala | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/main/scala/reading/component/index/Menu.scala b/src/main/scala/reading/component/index/Menu.scala new file mode 100644 index 0000000..5ffbd25 --- /dev/null +++ b/src/main/scala/reading/component/index/Menu.scala @@ -0,0 +1,104 @@ +package reading.component.index + +import org.scalajs.dom + +import rx._ +import Ctx.Owner.Unsafe._ + +import scalatags.JsDom.all._ +import scalacss.Defaults._ +import scalacss.ScalatagsCss._ + +import reading.component.index.style.{ Menu => MenuStyle } +import reading.models._ +import reading.utils.{ RxTag, RxAttr } +import reading.Route + +object Menu { + def apply(books: Rx[Seq[Book]], filters: Var[Seq[Filter]], showFiltersMenu: Var[Boolean]): Frag = + RxTag { implicit context => + div( + MenuStyle.render, + if (showFiltersMenu()) MenuStyle.show else "", + MenuStyle.menu, + + header(showFiltersMenu, filters().length), + + filters().find(_.kind == FilterKind.Grade) match { + case None => group(books, filters, "Classe", Grade.values.map(Filter.apply(_))) + case Some(grade) => group(books, filters, grade.name, Program.values.map(Filter.apply(_)), Some(grade)) + }, + group(books, filters, "Theme", Theme.values.map(Filter.apply(_))), + group(books, filters, "Genre", Genre.values.map(Filter.apply(_))), + group(books, filters, "Niveau", Level.values.map(Filter.apply(_))), + group(books, filters, "PĂ©riode", Period.values.map(Filter.apply(_))) + ) + } + + def header(showFiltersMenu: Var[Boolean], count: Int): HtmlTag = + div( + MenuStyle.header, + span( + MenuStyle.close, + RxAttr(onclick, Rx(() => { + showFiltersMenu() = false + dom.document.body.style.overflowY = "scroll" + })) + ), + "Filtrer", + if (count > 0) span(MenuStyle.count, count) else span("") + ) + + def group( + books: Rx[Seq[Book]], + filters: Var[Seq[Filter]], + name: String, + groupFilters: Seq[Filter], + parentFilter: Option[Filter] = None + )( + implicit + context: Ctx.Data + ): Frag = { + val filtersWithCount = Rx { + groupFilters + .map(filter => (filter, Book.filter(books(), Seq(filter)).length)) + .filter(_._2 > 0) + } + + if (filtersWithCount().isEmpty) + span("") + else + div( + MenuStyle.filterGroup, + div( + MenuStyle.filterTitle, + parentFilter.map(filter => + RxAttr(onclick, Rx(() => updateFilters(filters, Filter.remove(filters(), filter))))).getOrElse(""), + if (parentFilter.isDefined) MenuStyle.activeFilter else "", + name + ), + div( + filtersWithCount().map { + case (filter, count) => { + val isActive = Filter.contains(filters(), filter) + + button( + MenuStyle.filter, + if (isActive) MenuStyle.activeFilter else "", + RxAttr(onclick, Rx(() => updateFilters( + filters, + if (isActive) Filter.remove(filters(), filter) else filter +: filters() + ))), + span(s"${filter.name.capitalize} ($count)") + ) + } + } + ) + ) + } + + private def updateFilters(filters: Var[Seq[Filter]], newFilters: Seq[Filter]): Unit = { + filters() = newFilters + Route.push(Route.Books(newFilters)) + } +} |