module Page.Dashboard exposing (Model, Msg(..), getSession, init, update, updateSession, view) import Api import Api.Player as Player exposing (Player, Wealth) import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) import Page.Chest as Chest exposing (Chest) import Session exposing (Session) getSession model = case model of Admin (AdminConfig session _ _) -> session Player (PlayerConfig session _) -> session updateSession model session = case model of Admin (AdminConfig _ a b) -> Admin (AdminConfig session a b) Player (PlayerConfig _ a) -> Player (PlayerConfig session a) type Model = Admin AdminConfig | Player PlayerConfig type alias NewPlayerForm = { name : String , wealth : Float } type PlayerConfig = PlayerConfig Session Mode type AdminConfig = AdminConfig Session (List Player) NewPlayerForm type Mode = PlayerChest Chest | GroupChest Chest | Sell Chest | Add Chest init : Session -> ( Model, Cmd Msg ) init session = case Session.user session of Session.Admin -> ( Admin <| AdminConfig session [] initForm , Player.list (AdminViewer << GotPlayers) ) Session.Player player wealth loot -> ( Player <| PlayerConfig session (if player.id == 0 then -- TODO: render claimed items GroupChest Chest.init else PlayerChest Chest.init ) , Cmd.none ) initForm = NewPlayerForm "" 0.0 modeButton t msg = button [ class "button", onClick msg ] [ text t ] buttons bs = div [ class "buttons" ] bs view : Model -> ( Html Msg, List (Html Msg) ) view model = case model of Player (PlayerConfig session mode) -> case Session.user session of Session.Player player _ loot -> Tuple.mapBoth (Html.map PlayerViewer) (List.map (Html.map PlayerViewer)) <| case mode of PlayerChest chest -> ( modeButton "Vendre" IntoSell , [ Html.map GotChestMsg <| Chest.view chest loot ] ) GroupChest chest -> ( buttons [ modeButton "Vendre" IntoSell, modeButton "Ajouter" IntoAdd ] , [ Html.map GotChestMsg <| Chest.view chest loot ] ) Sell chest -> ( buttons [ modeButton "Ok" ConfirmSell, modeButton "Annuler" IntoView ] , [ Html.map GotChestMsg <| Chest.view chest loot ] ) Add chest -> ( buttons [ modeButton "Ok" ConfirmAdd, modeButton "Annuler" IntoView ] , [ Html.map GotChestMsg <| Chest.view chest [] ] ) _ -> let _ = Debug.log "Admin in PlayerDashboard !!" () in ( text "", [] ) Admin (AdminConfig session players newPlayer) -> ( text "" , [ div [ class "container" ] [ p [ class "title" ] [ text "Administration" ] , div [ class "section" ] [ table [ class "table is-fullwidth is-striped" ] [ thead [ class "table-header" ] [ th [] [ text "Joueurs" ] ] , tbody [] <| editNewPlayer newPlayer :: List.map viewPlayer players ] ] , div [ class "section" ] [ p [] [ text "Campagnes" ] ] ] ] ) viewPlayer : Player -> Html Msg viewPlayer player = tr [] [ td [] [ p [] [ text (player.name ++ " (" ++ String.fromInt player.id ++ ")") ] ] ] editNewPlayer : NewPlayerForm -> Html Msg editNewPlayer newPlayer = tr [] [ td [] [ div [ class "field is-horizontal" ] [ div [ class "field-body" ] [ div [ class "field" ] [ input [ class "input" , type_ "text" , value newPlayer.name , onInput <| NameChanged ] [] ] , div [ class "field" ] [ input [ class "input" , type_ "text" , value <| String.fromFloat newPlayer.wealth , onInput <| WealthChanged ] [] ] ] ] ] ] |> Html.map (AdminViewer << GotFormMsg) type Msg = Api Api.Msg | AdminViewer AdminMsg | PlayerViewer PlayerMsg type AdminMsg = GotPlayers (List Player) | GotFormMsg FormMsg -- Player type PlayerMsg = GotChestMsg Chest.Msg | IntoSell | IntoAdd | ConfirmSell | ConfirmAdd | IntoView mapChest : (Chest -> a) -> Mode -> a mapChest fn mode = case mode of PlayerChest chest -> fn chest GroupChest chest -> fn chest Add chest -> fn chest Sell chest -> fn chest updateChest : Model -> Chest -> Model updateChest model new = case model of Admin _ -> model Player (PlayerConfig s mode) -> case mode of PlayerChest _ -> Player (PlayerConfig s (PlayerChest new)) GroupChest _ -> Player (PlayerConfig s (GroupChest new)) Add _ -> Player (PlayerConfig s (Add new)) Sell _ -> Player (PlayerConfig s (Sell new)) update msg model = case ( msg, model ) of ( AdminViewer aMsg, Admin (AdminConfig session players form) ) -> (case aMsg of GotPlayers newPlayers -> ( Admin (AdminConfig session newPlayers form) , Cmd.none ) GotFormMsg subMsg -> ( Admin (AdminConfig session players (updateForm subMsg form)) , Cmd.none ) ) |> Tuple.mapSecond (Cmd.map AdminViewer) ( PlayerViewer ConfirmSell, Player (PlayerConfig session mode) ) -> ( model , Cmd.map Api <| case Session.user session of Session.Player player _ loot -> -- TODO: handle list of players when Viewer is group mapChest (\chest -> Chest.confirmSell player.id chest loot []) mode _ -> Cmd.none ) ( PlayerViewer ConfirmAdd, Player (PlayerConfig session mode) ) -> ( model , Cmd.map Api <| case Session.user session of Session.Player player _ _ -> let sourceName = "nouveau loot #1" in mapChest (\chest -> Chest.confirmAdd 0 sourceName chest) mode _ -> Cmd.none ) ( PlayerViewer aMsg, Player (PlayerConfig session mode) ) -> (case aMsg of GotChestMsg chestMsg -> mapChest (Chest.update chestMsg) mode |> Tuple.mapBoth (updateChest model) (Cmd.map GotChestMsg) IntoSell -> ( Player (PlayerConfig session (Sell Chest.initSelection)), Cmd.none ) IntoAdd -> ( Player (PlayerConfig session (Add Chest.initCreate)), Cmd.none ) IntoView -> let userChest = case Session.user session of Session.Player player _ _ -> if player.id == 0 then GroupChest else PlayerChest -- TODO: this seems not right -- there should be a better way -- to handle this _ -> PlayerChest in ( Player (PlayerConfig session (userChest Chest.init)), Cmd.none ) _ -> ( model, Cmd.none ) ) |> Tuple.mapSecond (Cmd.map PlayerViewer) ( _, _ ) -> let _ = Debug.log "unhandled msg" msg in ( model, Cmd.none ) -- Player form type FormMsg = NameChanged String | WealthChanged String updateForm : FormMsg -> NewPlayerForm -> NewPlayerForm updateForm msg form = case msg of NameChanged newName -> { form | name = newName } WealthChanged newWealth -> { form | wealth = Maybe.withDefault 0.0 <| String.toFloat newWealth }