import Html exposing (Html, Attribute, div, h1, input, p, text) import Html.App as App import Html.Attributes exposing (checked, style, type') import Html.Events exposing (onClick) import Html.Lazy exposing (lazy) import String import Table exposing (defaultCustomizations) import Time exposing (Time) main = App.program { init = init missionSights , update = update , view = view , subscriptions = \_ -> Sub.none } -- MODEL type alias Model = { sights : List Sight , tableState : Table.State } init : List Sight -> ( Model, Cmd Msg ) init sights = let model = { sights = sights , tableState = Table.initialSort "Year" } in ( model, Cmd.none ) -- UPDATE type Msg = ToggleSelected String | SetTableState Table.State update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ToggleSelected name -> ( { model | sights = List.map (toggle name) model.sights } , Cmd.none ) SetTableState newState -> ( { model | tableState = newState } , Cmd.none ) toggle : String -> Sight -> Sight toggle name sight = if sight.name == name then { sight | selected = not sight.selected } else sight -- VIEW view : Model -> Html Msg view { sights, tableState } = div [] [ h1 [] [ text "Trip Planner" ] , lazy viewSummary sights , Table.view config tableState sights ] viewSummary : List Sight -> Html msg viewSummary allSights = case List.filter .selected allSights of [] -> p [] [ text "Click the sights you want to see on your trip!" ] sights -> let time = List.sum (List.map .time sights) price = List.sum (List.map .price sights) summary = "That is " ++ toString (Time.inHours time) ++ " hours of fun, costing $" ++ toString price in p [] [ text summary ] -- TABLE CONFIGURATION config : Table.Config Sight Msg config = Table.customConfig { toId = .name , toMsg = SetTableState , columns = [ checkboxColumn , Table.stringColumn "Name" .name , timeColumn , Table.floatColumn "Price" .price , Table.floatColumn "Rating" .rating ] , customizations = { defaultCustomizations | rowAttrs = toRowAttrs } } toRowAttrs : Sight -> List (Attribute Msg) toRowAttrs sight = [ onClick (ToggleSelected sight.name) , style [ ("background", if sight.selected then "#CEFAF8" else "white") ] ] timeColumn : Table.Column Sight Msg timeColumn = Table.customColumn { name = "Time" , viewData = viewTime , sorter = Table.increasingOrDecreasingBy .time } viewTime : Sight -> String viewTime {time} = if time < Time.hour then toString (Time.inMinutes time) ++ "min" else toString (Time.inHours time) ++ "hr" checkboxColumn : Table.Column Sight Msg checkboxColumn = Table.veryCustomColumn { name = "" , viewData = viewCheckbox , sorter = Table.unsortable } viewCheckbox : Sight -> Table.HtmlDetails Msg viewCheckbox {selected} = Table.HtmlDetails [] [ input [ type' "checkbox", checked selected ] [] ] -- SIGHTS type alias Sight = { name : String , time : Time , price : Float , rating : Float , selected : Bool } missionSights : List Sight missionSights = [ Sight "Eat a Burrito" (Time.hour / 2) 7 4.6 False , Sight "Buy drugs in Delores park" Time.hour 20 4.9 False , Sight "Armory Tour" (1.5 * Time.hour) 27 4.5 False , Sight "Tartine Bakery" Time.hour 10 4.1 False , Sight "Have Brunch" (2 * Time.hour) 25 4.2 False ]