bornhack-website/schedule/src/Views/FilterView.elm

150 lines
4.5 KiB
Elm

module Views.FilterView exposing (filterSidebar, applyFilters)
-- Local modules
import Messages exposing (Msg(..))
import Models exposing (Model, EventInstance)
-- External modules
import Html exposing (Html, text, div, ul, li, span, i, h4)
import Html.Attributes exposing (class, classList, href)
import Html.Events exposing (onClick)
import Date.Extra exposing (Interval(..), equalBy)
applyFilters day model =
let
types =
List.map (\eventType -> eventType.slug)
(if List.isEmpty model.filter.eventTypes then
model.eventTypes
else
model.filter.eventTypes
)
locations =
List.map (\eventLocation -> eventLocation.slug)
(if List.isEmpty model.filter.eventLocations then
model.eventLocations
else
model.filter.eventLocations
)
videoFilters =
List.map (\filter -> filter.filter)
(if List.isEmpty model.filter.videoRecording then
videoRecordingFilters
else
model.filter.videoRecording
)
filteredEventInstances =
List.filter
(\eventInstance ->
(Date.Extra.equalBy Month eventInstance.from day.date)
&& (Date.Extra.equalBy Date.Extra.Day eventInstance.from day.date)
&& List.member eventInstance.location locations
&& List.member eventInstance.eventType types
&& applyVideoRecordingFilters videoFilters eventInstance
)
model.eventInstances
in
filteredEventInstances
filterSidebar : Model -> Html Msg
filterSidebar model =
div
[ classList
[ ( "col-sm-3", True )
, ( "col-sm-push-9", True )
, ( "schedule-sidebar", True )
, ( "schedule-filter", True )
, ( "sticky", True )
]
]
[ h4 [] [ text "Filter" ]
, div [ class "form-group" ]
[ filterView "Type" model.eventTypes model.filter.eventTypes ToggleEventTypeFilter
, filterView "Location" model.eventLocations model.filter.eventLocations ToggleEventLocationFilter
, filterView "Video" videoRecordingFilters model.filter.videoRecording ToggleVideoRecordingFilter
]
]
notRecordedFilter : EventInstance -> Bool
notRecordedFilter eventInstance =
eventInstance.videoRecording == False
recordedFilter : EventInstance -> Bool
recordedFilter eventInstance =
eventInstance.videoRecording == True
hasRecordingFilter : EventInstance -> Bool
hasRecordingFilter eventInstance =
eventInstance.videoUrl /= ""
videoRecordingFilters : List { name : String, filter : EventInstance -> Bool }
videoRecordingFilters =
[ { name = "Will not be recorded", filter = notRecordedFilter }
, { name = "Will recorded", filter = recordedFilter }
, { name = "Has recording", filter = hasRecordingFilter }
]
applyVideoRecordingFilters : List (EventInstance -> Bool) -> EventInstance -> Bool
applyVideoRecordingFilters filters eventInstance =
let
results =
List.map (\filter -> filter eventInstance) filters
in
List.member True results
filterView :
String
-> List { a | name : String }
-> List { a | name : String }
-> ({ a | name : String } -> Msg)
-> Html Msg
filterView name possibleFilters currentFilters action =
div []
[ text (name ++ ":")
, ul [] (List.map (\filter -> filterChoiceView filter currentFilters action) possibleFilters)
]
filterChoiceView :
{ a | name : String }
-> List { a | name : String }
-> ({ a | name : String } -> Msg)
-> Html Msg
filterChoiceView filter currentFilters action =
let
active =
List.member filter currentFilters
notActive =
not active
in
li []
[ div
[ classList
[ ( "btn", True )
, ( "btn-default", True )
, ( "filter-choice-active", active )
]
, onClick (action filter)
]
[ span []
[ i [ classList [ ( "fa", True ), ( "fa-minus", active ), ( "fa-plus", notActive ) ] ] []
, text (" " ++ filter.name)
]
]
]