From 903fdd816d0184a1dfaad6452e258ccc4e7accb9 Mon Sep 17 00:00:00 2001 From: Artus Date: Sat, 7 Dec 2019 16:28:40 +0100 Subject: [PATCH] many styling tweaks, adds sourceName field --- css/lootalot.css | 11 ++- sass/lootalot.scss | 14 ++- src/Bulma.elm | 26 +++++- src/Chest.elm | 17 ++-- src/Chest/Selection.elm | 30 +++++- src/Main.elm | 17 +++- src/Page.elm | 89 +++++++++--------- src/Page/Dashboard.elm | 198 ++++++++++++++++++++++++---------------- src/Page/Shop.elm | 6 +- src/Table.elm | 2 +- src/Wealth.elm | 34 ++++++- 11 files changed, 294 insertions(+), 150 deletions(-) diff --git a/css/lootalot.css b/css/lootalot.css index be287be..236942e 100644 --- a/css/lootalot.css +++ b/css/lootalot.css @@ -1,4 +1,13 @@ @charset "UTF-8"; +.navbar.is-spaced a.navbar-item.is-active { + border-bottom: 1px solid #2e3440; + border-radius: 0; +} + +.hero.is-dark.is-bold { + background-image: linear-gradient(280deg, #191c22 0%, #2e3440 71%, #3b4252 100%) !important; +} + /*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */ @keyframes spinAround { from { @@ -1453,7 +1462,7 @@ a.has-text-danger:hover, a.has-text-danger:focus { .box { background-color: white; - border-radius: 0 0 2rem 2rem; + border-radius: 6px; box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02); color: #4a4a4a; display: block; diff --git a/sass/lootalot.scss b/sass/lootalot.scss index 03bbbba..000f0ad 100644 --- a/sass/lootalot.scss +++ b/sass/lootalot.scss @@ -8,8 +8,8 @@ $purple:#b48ead; $green:#a3be8c; $dark:#2e3440; -$dark-bis:#2e3440; -$dark-ter:#2e3440; +$dark-bis:#3b4252; +$dark-ter:#434c5e; $grey:#4c566a; $grey-light:#d8dee9; $grey-lighter:#e5e9f0; @@ -28,6 +28,14 @@ $navbar-background-color: $body-background-color; // Notifications $notification-padding: 0.8rem 2.5rem 0.8rem 1rem; -$box-radius: 0 0 2rem 2rem; +//$box-radius: 0 0 2rem 2rem; +.navbar.is-spaced a.navbar-item.is-active { + border-bottom: 1px solid $dark; + border-radius: 0; +} + +.hero.is-dark.is-bold { + background-image: linear-gradient(280deg, darken($dark, 10) 0%, $dark 71%, $dark-bis 100%) !important; +} @import "./bulma-0.8.0/bulma.sass"; diff --git a/src/Bulma.elm b/src/Bulma.elm index ed6c7b4..6d5384f 100644 --- a/src/Bulma.elm +++ b/src/Bulma.elm @@ -46,7 +46,7 @@ confirmButtons confirm cancel = confirmBtn msg = - btn msg { text = "Ok", icon = "fas fa-check", color = "is-primary" } + btn msg { text = "Ok", icon = "fas fa-check", color = "is-success" } cancelBtn msg = @@ -70,3 +70,27 @@ datatable headers rows = -- Section +-- TAGS +-- + + +tag attrs content = + span ([ class "tag" ] ++ attrs) content + + + +-- LEVELS +-- + + +levelItem = + class "level-item" + + + +-- COLORS +-- + + +isInfo = + class "is-info" diff --git a/src/Chest.elm b/src/Chest.elm index 888997f..427a017 100644 --- a/src/Chest.elm +++ b/src/Chest.elm @@ -170,16 +170,19 @@ update msg model = List.any (\claim_ -> claim_.loot_id == item.id) claims renderItem item = - [ if isClaimed item then - B.icon - { icon = "fas fa-praying-hands" - , size = Just "is-small" - , ratio = Just "fa-1x" - } + [ p [ B.levelItem ] [ text item.name ] + , if isClaimed item then + B.tag [ B.levelItem, B.isInfo ] + [ B.icon + { icon = "fas fa-praying-hands" + , size = Just "is-small" + , ratio = Just "fa-1x" + } + , text "time left..." + ] else text "" - , p [] [ text item.name ] ] in ( View <| Table.renderRowLevel renderItem (\_ -> []), Cmd.none ) diff --git a/src/Chest/Selection.elm b/src/Chest/Selection.elm index 7fe6cfc..91d6c9b 100644 --- a/src/Chest/Selection.elm +++ b/src/Chest/Selection.elm @@ -1,4 +1,4 @@ -module Chest.Selection exposing (Model, Msg, init, modifiers, selected, update, view) +module Chest.Selection exposing (Model, Msg, init, modifiers, selected, totalSelectedPrice, update, view) import Api exposing (Item, Loot) import Dict exposing (Dict) @@ -147,7 +147,7 @@ modifiers (Model selection data) items = List.map (\item -> Dict.get item.id inner - |> Maybe.map (\i -> toFloatingMod i) + |> Maybe.map toFloatingMod ) items @@ -155,6 +155,32 @@ modifiers (Model selection data) items = [] +totalSelectedPrice : Model -> Loot -> Maybe Float +totalSelectedPrice model loot = + case selected model loot of + [] -> + Nothing + + items -> + let + (Model selection data) = + model + + modifier item = + Maybe.withDefault 1.0 <| + Maybe.map toFloatingMod <| + case data of + Data inner -> + Dict.get item.id inner + + NoData -> + Nothing + in + Just <| + List.foldl (+) 0.0 <| + List.map (\item -> toFloat item.base_price * modifier item) items + + itemInSelection : Selection -> Item -> Bool itemInSelection selection item = Set.member item.id selection diff --git a/src/Main.elm b/src/Main.elm index 9914389..600b20f 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -101,8 +101,16 @@ viewHeaderBar navbarTitle navbarLinks navbar = nav [ class "navbar container is-transparent is-spaced " ] [ div [ class "navbar-brand" ] [ p [ class "navbar-item" ] - [ B.icon { icon = "fab fa-d-and-d", size = Just "is-medium", ratio = Just "fa-2x" } - , span [ class "title is-4", style "padding-left" "0.4em" ] [ text navbarTitle ] + [ B.icon + { icon = "fab fa-d-and-d" + , size = Just "is-medium" + , ratio = Just "fa-2x" + } + , span + [ class "title is-4" + , style "padding-left" "0.4em" + ] + [ text navbarTitle ] ] , a [ class "navbar-burger" @@ -114,7 +122,10 @@ viewHeaderBar navbarTitle navbarLinks navbar = , span [ attribute "aria-hidden" "true" ] [] ] ] - , div [ class "navbar-menu", classList [ ( "is-active", navbar.menuOpen ) ] ] + , div + [ class "navbar-menu" + , classList [ ( "is-active", navbar.menuOpen ) ] + ] [ div [ class "navbar-end" ] navbarLinks ] ] diff --git a/src/Page.elm b/src/Page.elm index bee9ef9..0cd3239 100644 --- a/src/Page.elm +++ b/src/Page.elm @@ -91,7 +91,7 @@ view page = case Session.user session of Session.Player data -> ( data.player.name - , [ navLink "fas fa-home" Route.Home page + , [ navLink "fas fa-dungeon" Route.Home page , navLink "fas fa-store-alt" Route.Merchant page , if data.player.id /= 0 then navLink "fas fa-gem" Route.GroupChest page @@ -103,7 +103,7 @@ view page = Session.Admin _ -> ( "Administration" - , [ navLink "fas fa-home" Route.Home page + , [ navLink "fas fa-users" Route.Home page , navLink "fas fa-store-alt" Route.Merchant page ] ) @@ -115,9 +115,9 @@ view page = in ( pageTitle , { title = navbarTitle, links = navbarLinks } - , [ div [ class "container" ] <| + , [ div [ class "container box is-paddingless" ] <| [ viewSessionBar (maybeSession page) pageTitle [ controls ] - , div [ class "section" ] + , section [ class "section" ] content ] ] @@ -139,7 +139,10 @@ viewNotification kind content = NotifyError -> "is-danger" in - div [ class ("level-item notification " ++ className) ] + div + [ class ("level-item notification " ++ className) + , style "margin-left" "1.5rem" + ] [ text content , a [ class "delete", onClick <| CloseNotification kind ] [] ] @@ -193,7 +196,7 @@ viewSessionBar session pageTitle pageControls = p [ class "title" ] [ text pageTitle ] in section [ class "hero is-dark is-bold" ] - [ div [ class "hero-body" ] + [ div [ class "hero-body", style "padding" "3rem 1.5rem 1.5rem 1.5rem" ] [ renderLevel notifications user , renderLevel [ title ] pageControls ] @@ -201,7 +204,7 @@ viewSessionBar session pageTitle pageControls = renderLevel left right = - div [ class "level container" ] + div [ class "level" ] [ div [ class "level-left" ] left , div [ class "level-right" ] right ] @@ -265,30 +268,6 @@ type PageMsg --- Maps the page session to a function, if any - - -map func page = - case maybeSession page of - Nothing -> - page - - Just session -> - case page of - Home model -> - Home <| Home.updateSession model (func session) - - GroupChest model -> - GroupChest { model | session = func session } - - Shop model -> - Shop { model | session = func session } - - _ -> - page - - - -- Restores the page after an action has be resolved (either success or error) @@ -349,7 +328,7 @@ update msg page = -- Notifications -- - ( CloseNotification kind, _, _ ) -> + ( CloseNotification kind, _, Just session ) -> ( map (case kind of NotifySuccess -> @@ -362,6 +341,9 @@ update msg page = , Cmd.none ) + ( CloseNotification _, _, _ ) -> + ( page, Cmd.none ) + -- Wealth viewer/editor ( Wealth wealthMsg, _, Just session ) -> let @@ -421,15 +403,15 @@ update msg page = Cmd.none ) - -- |> setNotification notification - -- |> setError errors - -- |> update (ModeSwitched View) - Err r -> + Err error -> let _ = - Debug.log "ERR: ActionResult:" r + Debug.log "ApiError" error in - ( page, Cmd.none ) + ( page + |> map (Session.setError (Just "Oups! Cela n'a pas fonctionné")) + , Cmd.none + ) ( ApiMsg apiMsg, _, Nothing ) -> let @@ -445,15 +427,32 @@ updatePage toPage toMsg ( subModel, subMsg ) = ) + +-- Maps the page session to a function, if any + + +map func page = + case maybeSession page of + Nothing -> + page + + Just session -> + case page of + Home model -> + Home <| Home.updateSession model (func session) + + GroupChest model -> + GroupChest { model | session = func session } + + Shop model -> + Shop { model | session = func session } + + _ -> + page + + applyUpdate : Api.Update -> Session.User -> Session.User applyUpdate u user = - let - _ = - Debug.log "applyUpdate" u - - _ = - Debug.log "on" user - in {- Note: DbUpdates always refer to the active player -} case user of Session.Player data -> diff --git a/src/Page/Dashboard.elm b/src/Page/Dashboard.elm index 7f70747..3721403 100644 --- a/src/Page/Dashboard.elm +++ b/src/Page/Dashboard.elm @@ -4,6 +4,7 @@ import Api import Api.Player as Player exposing (Player, Wealth) import Bulma as B import Chest exposing (Chest) +import Chest.Selection as Selection import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) @@ -12,20 +13,20 @@ import Session exposing (Session) getSession model = case model of - Admin (AdminConfig session _ _) -> - session + Admin config -> + config.session - Player (PlayerConfig session _) -> - session + Player config -> + config.session updateSession model session = case model of - Admin (AdminConfig _ a b) -> - Admin (AdminConfig session a b) + Admin config -> + Admin { config | session = session } - Player (PlayerConfig _ a) -> - Player (PlayerConfig session a) + Player config -> + Player { config | session = session } type Model @@ -39,12 +40,18 @@ type alias NewPlayerForm = } -type PlayerConfig - = PlayerConfig Session Chest +type alias ExtraData = + { sourceName : String + , players : List Player + } -type AdminConfig - = AdminConfig Session (List Player) (Maybe NewPlayerForm) +type alias PlayerConfig = + { session : Session, chest : Chest, extra : ExtraData } + + +type alias AdminConfig = + { session : Session, players : List Player, playerForm : Maybe NewPlayerForm } init : Session -> ( Model, Cmd Msg ) @@ -57,15 +64,17 @@ init session = Session.Player data -> ( Player <| - PlayerConfig session - (if data.player.id == 0 then + { session = session + , chest = + if data.player.id == 0 then -- TODO: render claimed items Chest.update (Chest.showWithClaims data.claims) Chest.init |> Tuple.first - else + else Chest.init - ) + , extra = ExtraData "" [] + } , Cmd.none ) @@ -74,16 +83,12 @@ 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 DASHBOARD - Player (PlayerConfig session chest) -> - case Session.user session of + Player config -> + case Session.user config.session of Session.Player data -> let toShow = @@ -95,11 +100,11 @@ view model = GotChestMsg Chest.show in ( Html.map PlayerViewer <| - case chest of + case config.chest of Chest.View _ -> case data.player.id of 0 -> - buttons + B.buttons [ B.btn (GotChestMsg Chest.sell) { text = "Vendre" @@ -122,15 +127,48 @@ view model = , color = "is-primary" } - Chest.Sell _ -> - B.confirmButtons ConfirmSell toShow + Chest.Sell selection -> + let + sellText = + case Selection.totalSelectedPrice selection data.loot of + Nothing -> + "Ok" + + Just amount -> + String.fromFloat amount ++ "po" + in + B.buttons + [ B.btn ConfirmSell + { text = sellText + , icon = "fas fa-coins" + , color = "is-success" + } + , B.cancelBtn toShow + ] Chest.New _ -> B.confirmButtons ConfirmAdd toShow _ -> text "" - , [ Html.map (PlayerViewer << GotChestMsg) <| Chest.view chest data.loot ] + , List.map (Html.map PlayerViewer) + [ case config.chest of + Chest.New _ -> + div [ class "field" ] + [ label [ class "label" ] [ text "Source" ] + , input + [ class "input" + , type_ "text" + , value config.extra.sourceName + , onInput SourceNameChanged + ] + [] + ] + + _ -> + text "" + , Html.map GotChestMsg <| Chest.view config.chest data.loot + ] ) _ -> @@ -141,8 +179,8 @@ view model = ( text "", [] ) -- ADMIN DASHBOARD - Admin (AdminConfig session players playerForm) -> - ( case playerForm of + Admin config -> + ( case config.playerForm of Nothing -> B.btn (AdminViewer EditPlayer) @@ -154,17 +192,14 @@ view model = Just _ -> B.confirmButtons ConfirmNewPlayer CloseEdit |> Html.map AdminViewer - , [ div [ class "section" ] - [ case playerForm of - Nothing -> - text "" + , [ case config.playerForm of + Nothing -> + B.datatable + [ "Joueurs" ] + (List.map viewPlayer config.players) - Just form -> - editNewPlayer form - , B.datatable - [ "Joueurs" ] - (List.map viewPlayer players) - ] + Just form -> + editNewPlayer form ] ) @@ -176,30 +211,27 @@ viewPlayer player = editNewPlayer : NewPlayerForm -> Html Msg editNewPlayer newPlayer = - div [ class "box" ] - [ div [ class "field is-horizontal" ] - [ div [ class "field-body" ] - [ div [ class "field" ] - [ label [ class "label" ] [ text "Nom" ] - , input - [ class "input" - , type_ "text" - , value newPlayer.name - , onInput <| NameChanged - ] - [] - ] - , div [ class "field" ] - [ label [ class "label" ] [ text "Argent de départ" ] - , input - [ class "input" - , type_ "text" - , value <| String.fromFloat newPlayer.wealth - , onInput <| WealthChanged - ] - [] - ] + div [ class "form" ] + [ p [ class "subtitle" ] [ text "Nouveau joueur" ] + , div [ class "field" ] + [ label [ class "label" ] [ text "Nom" ] + , input + [ class "input" + , type_ "text" + , value newPlayer.name + , onInput <| NameChanged ] + [] + ] + , div [ class "field" ] + [ label [ class "label" ] [ text "Argent de départ" ] + , input + [ class "input" + , type_ "text" + , value <| String.fromFloat newPlayer.wealth + , onInput <| WealthChanged + ] + [] ] ] |> Html.map (AdminViewer << GotFormMsg) @@ -226,19 +258,20 @@ type PlayerMsg = GotChestMsg Chest.Msg | ConfirmSell | ConfirmAdd + | SourceNameChanged String update msg model = case ( msg, model ) of - ( AdminViewer aMsg, Admin (AdminConfig session players form) ) -> - (case ( aMsg, form ) of + ( AdminViewer aMsg, Admin config ) -> + (case ( aMsg, config.playerForm ) of ( EditPlayer, Nothing ) -> - ( Admin (AdminConfig session players (Just <| NewPlayerForm "" 0.0)) + ( Admin { config | playerForm = Just <| NewPlayerForm "" 0.0 } , Cmd.none ) ( GotFormMsg subMsg, Just f ) -> - ( Admin (AdminConfig session players <| Just (updateForm subMsg f)) + ( Admin { config | playerForm = Just (updateForm subMsg f) } , Cmd.none ) @@ -246,22 +279,22 @@ update msg model = ( model, Cmd.none ) ( CloseEdit, _ ) -> - ( Admin (AdminConfig session players Nothing), Cmd.none ) + ( Admin { config | playerForm = Nothing }, Cmd.none ) _ -> ( model, Cmd.none ) ) |> Tuple.mapSecond (Cmd.map AdminViewer) - ( PlayerViewer ConfirmSell, Player (PlayerConfig session chest) ) -> + ( PlayerViewer ConfirmSell, Player config ) -> ( model , Cmd.map Api <| - case Session.user session of + case Session.user config.session of Session.Player data -> -- TODO: handle list of players when Viewer is group Chest.confirmSell data.player.id - chest + config.chest data.loot [] @@ -269,32 +302,35 @@ update msg model = Cmd.none ) - ( PlayerViewer ConfirmAdd, Player (PlayerConfig session chest) ) -> + ( PlayerViewer ConfirmAdd, Player config ) -> ( model , Cmd.map Api <| - case Session.user session of + case Session.user config.session of Session.Player _ -> - let - sourceName = - "nouveau loot #1" - in Chest.confirmAdd 0 - sourceName - chest + config.extra.sourceName + config.chest _ -> Cmd.none ) - ( PlayerViewer aMsg, Player (PlayerConfig session chest) ) -> + ( PlayerViewer aMsg, Player config ) -> (case aMsg of GotChestMsg chestMsg -> - Chest.update chestMsg chest + Chest.update chestMsg config.chest |> Tuple.mapBoth - (\chest_ -> Player (PlayerConfig session chest_)) + (\chest_ -> Player { config | chest = chest_ }) (Cmd.map GotChestMsg) + SourceNameChanged new -> + let + extra = + config.extra + in + ( Player { config | extra = { extra | sourceName = new } }, Cmd.none ) + _ -> ( model, Cmd.none ) ) diff --git a/src/Page/Shop.elm b/src/Page/Shop.elm index 8da455d..76631e1 100644 --- a/src/Page/Shop.elm +++ b/src/Page/Shop.elm @@ -37,7 +37,11 @@ view model = LoadError error -> ( text "" - , [ p [ class "has-text-danger" ] [ text <| "Error : " ++ error ] ] + , [ div [ class "notification is-error" ] + [ B.icon { icon = "fas fa-exclamation", size = Just "is-medium", ratio = Just "fa-2x" } + , p [ class "has-text-danger" ] [ text <| "Error : " ++ error ] + ] + ] ) Loaded loot -> diff --git a/src/Table.elm b/src/Table.elm index 75d1f8d..cfcbccd 100644 --- a/src/Table.elm +++ b/src/Table.elm @@ -28,7 +28,7 @@ view rowRenderer content = renderSelectableRow : ItemRenderer a msg -> ItemRenderer a msg -> (a -> Bool -> msg) -> (a -> Bool) -> RowRenderer a msg renderSelectableRow left right onCheckMsg isSelected item = tr [] - [ td [] + [ td [ classList [ ( "is-selected has-text-weight-bold", isSelected item ) ] ] [ label [ class "level checkbox" ] [ div [ class "level-left" ] <| left item , div [ class "level-right" ] <| diff --git a/src/Wealth.elm b/src/Wealth.elm index ef2de07..e5faa82 100644 --- a/src/Wealth.elm +++ b/src/Wealth.elm @@ -1,6 +1,7 @@ module Wealth exposing (Model, Msg(..), editValue, init, update, view) import Api.Player exposing (Wealth) +import Bulma as B import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) @@ -22,13 +23,22 @@ view wealth model = :: (case model of View -> viewWealth wealth + ++ [ div [ class "level-item button is-small is-dark" ] + [ span + [ class "icon is-small" + , onClick StartEdit + ] + [ i [ class "fas fa-tools" ] [] ] + ] + ] Edit amount -> viewUpdateWealth amount ) - ++ [ div [ class "level-item" ] - [ span [ class "icon", onClick StartEdit ] [ i [ class "fas fa-tools" ] [] ] ] - ] + + +inBarButton = + class "button is-small is-outlined " viewUpdateWealth amount = @@ -40,12 +50,26 @@ viewUpdateWealth amount = , ( "is-success", isValid amount ) ] , value amount - , placeholder "En pièces d'or..." , style "width" "8em" , onInput AmountChanged ] [] - , button [ class "level-item button", onClick ConfirmEdit ] [ text "Ok" ] + , button + [ inBarButton + , class "level-item is-primary" + , onClick ConfirmEdit + ] + [ B.icon + { icon = + if isValid amount then + "fas fa-check" + + else + "fas fa-times" + , ratio = Nothing + , size = Nothing + } + ] ]