2018-12-09 22:05:15 +00:00
|
|
|
import Browser exposing ( element)
|
2016-07-21 01:57:39 +00:00
|
|
|
import Html exposing (Html, Attribute, div, h1, input, p, text)
|
2016-12-07 06:40:58 +00:00
|
|
|
import Html.Attributes exposing (checked, style, type_)
|
2016-07-21 01:57:39 +00:00
|
|
|
import Html.Events exposing (onClick)
|
|
|
|
import Html.Lazy exposing (lazy)
|
|
|
|
import Table exposing (defaultCustomizations)
|
|
|
|
|
|
|
|
main =
|
2018-12-09 22:05:15 +00:00
|
|
|
Browser.element
|
2016-07-21 01:57:39 +00:00
|
|
|
{ init = init missionSights
|
|
|
|
, update = update
|
|
|
|
, view = view
|
|
|
|
, subscriptions = \_ -> Sub.none
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- MODEL
|
|
|
|
|
|
|
|
|
|
|
|
type alias Model =
|
|
|
|
{ sights : List Sight
|
|
|
|
, tableState : Table.State
|
|
|
|
}
|
|
|
|
|
2018-12-09 22:05:15 +00:00
|
|
|
type alias TimeSpan =
|
|
|
|
{ hours: Float
|
|
|
|
, minutes: Float
|
|
|
|
}
|
|
|
|
|
|
|
|
type alias Flags = {}
|
2016-07-21 01:57:39 +00:00
|
|
|
|
2018-12-09 22:05:15 +00:00
|
|
|
|
|
|
|
init : List Sight -> Flags -> ( Model, Cmd Msg )
|
|
|
|
init sights _ =
|
2016-07-21 01:57:39 +00:00
|
|
|
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 =
|
2018-12-09 22:05:15 +00:00
|
|
|
sumTimeSpan (List.map .time sights)
|
2016-07-21 01:57:39 +00:00
|
|
|
|
|
|
|
price =
|
|
|
|
List.sum (List.map .price sights)
|
|
|
|
|
|
|
|
summary =
|
2018-12-09 22:05:15 +00:00
|
|
|
"That is " ++ timeToString time ++ " of fun, costing $" ++ String.fromFloat price
|
2016-07-21 01:57:39 +00:00
|
|
|
in
|
|
|
|
p [] [ text summary ]
|
|
|
|
|
2018-12-09 22:05:15 +00:00
|
|
|
sumTimeSpan : List TimeSpan -> TimeSpan
|
|
|
|
sumTimeSpan spans =
|
|
|
|
{ hours = List.sum (List.map (.hours) spans)
|
|
|
|
, minutes = List.sum (List.map (.minutes) spans)
|
|
|
|
}
|
2016-07-21 01:57:39 +00:00
|
|
|
|
2018-12-09 22:05:15 +00:00
|
|
|
timeToString : TimeSpan -> String
|
2016-07-21 03:49:06 +00:00
|
|
|
timeToString time =
|
|
|
|
let
|
|
|
|
hours =
|
2018-12-09 22:05:15 +00:00
|
|
|
case floor (time.hours) of
|
2016-07-21 03:49:06 +00:00
|
|
|
0 -> ""
|
|
|
|
1 -> "1 hour"
|
2018-12-09 22:05:15 +00:00
|
|
|
n -> String.fromInt n ++ " hours"
|
2016-07-21 03:49:06 +00:00
|
|
|
|
|
|
|
minutes =
|
2018-12-09 22:05:15 +00:00
|
|
|
case modBy 60 (round (time.minutes)) of
|
2016-07-21 03:49:06 +00:00
|
|
|
0 -> ""
|
|
|
|
1 -> "1 minute"
|
2018-12-09 22:05:15 +00:00
|
|
|
n -> String.fromInt n ++ " minutes"
|
2016-07-21 03:49:06 +00:00
|
|
|
in
|
|
|
|
hours ++ " " ++ minutes
|
|
|
|
|
|
|
|
|
2016-07-21 01:57:39 +00:00
|
|
|
|
|
|
|
-- 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)
|
2018-12-09 22:05:15 +00:00
|
|
|
, style "backgroundColor" (if sight.selected then "#CEFAF8" else "white")
|
2016-07-21 01:57:39 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
timeColumn : Table.Column Sight Msg
|
|
|
|
timeColumn =
|
|
|
|
Table.customColumn
|
|
|
|
{ name = "Time"
|
2016-07-21 03:49:06 +00:00
|
|
|
, viewData = timeToString << .time
|
2018-12-09 22:05:15 +00:00
|
|
|
, sorter = Table.unsortable
|
2016-07-21 01:57:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
checkboxColumn : Table.Column Sight Msg
|
|
|
|
checkboxColumn =
|
|
|
|
Table.veryCustomColumn
|
|
|
|
{ name = ""
|
|
|
|
, viewData = viewCheckbox
|
|
|
|
, sorter = Table.unsortable
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
viewCheckbox : Sight -> Table.HtmlDetails Msg
|
|
|
|
viewCheckbox {selected} =
|
|
|
|
Table.HtmlDetails []
|
2016-12-07 06:40:58 +00:00
|
|
|
[ input [ type_ "checkbox", checked selected ] []
|
2016-07-21 01:57:39 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- SIGHTS
|
|
|
|
|
|
|
|
|
|
|
|
type alias Sight =
|
|
|
|
{ name : String
|
2018-12-09 22:05:15 +00:00
|
|
|
, time : TimeSpan
|
2016-07-21 01:57:39 +00:00
|
|
|
, price : Float
|
|
|
|
, rating : Float
|
|
|
|
, selected : Bool
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
missionSights : List Sight
|
|
|
|
missionSights =
|
2018-12-09 22:05:15 +00:00
|
|
|
[ Sight "Eat a Burrito" ( TimeSpan 0 30 ) 7 4.6 False
|
|
|
|
, Sight "Buy drugs in Dolores park" ( TimeSpan 1 0 ) 20 4.8 False
|
|
|
|
, Sight "Armory Tour" ( TimeSpan 1 30 ) 27 4.5 False
|
|
|
|
, Sight "Tartine Bakery" ( TimeSpan 1 0 ) 10 4.1 False
|
|
|
|
, Sight "Have Brunch" ( TimeSpan 2 0 ) 25 4.2 False
|
|
|
|
, Sight "Get catcalled at BART" ( TimeSpan 0 5 ) 0 1.6 False
|
|
|
|
, Sight "Buy a painting at \"Stuff\"" ( TimeSpan 0 45 ) 400 4.7 False
|
|
|
|
, Sight "McDonalds at 24th" ( TimeSpan 0 20 ) 5 2.8 False
|
2016-12-07 06:40:58 +00:00
|
|
|
]
|