module Screen.Leaderboard exposing (..) {-| Widget module for a leaderboard page. -} import Api.Elo exposing (EloStat, Leaderboard, Players) import Color import Element exposing (Element) import Element.Background import Element.Border import Element.Events import Element.Font import Layout import Pixels exposing (Pixels) import Program exposing (ViewBox) import Quantity exposing (Quantity) import Theme view : ViewBox { board : Leaderboard, onSelect : String -> msg, selectedName : String } -> Element msg view data = Element.column [] [ selectBoard { flavor = data.flavor , leaderboard = data.model.board , onSelect = data.model.onSelect , selectedName = data.model.selectedName , width = data.size.width } , data.model.board |> List.map (\l -> if l.name == data.model.selectedName then viewSingleBoard { flavor = data.flavor , model = l , size = data.size } else Element.none ) |> Element.column [] ] selectBoard : { flavor : Theme.Flavor , leaderboard : Leaderboard , onSelect : String -> msg , selectedName : String , width : Quantity Int Pixels } -> Element msg selectBoard data = data.leaderboard |> List.map .name |> List.map (\s -> Element.el [ if data.selectedName == s then Element.Background.color (Theme.subtext0UI data.flavor) else Element.Background.color (Theme.surface1UI data.flavor) , Element.Border.rounded 25 , Element.centerX , Element.Events.onClick (data.onSelect s) , Element.padding 10 ] (Element.text s) ) |> Element.wrappedRow [ Element.padding 20 , Element.spacing 10 , Element.width <| Element.px <| Pixels.inPixels data.width ] viewSingleBoard : ViewBox { name : String, players : Players } -> Element msg viewSingleBoard data = let boardWidth = data.size.width |> Quantity.toFloatQuantity |> Quantity.multiplyBy (2 / 3) |> Quantity.floor |> Quantity.clamp (Pixels.pixels 600) (Pixels.pixels 1800) |> Pixels.inPixels |> Element.px |> Element.width in data.model.players |> List.map (viewEloStat { flavor = data.flavor }) |> Element.column [ Element.centerX, boardWidth ] |> List.singleton |> (::) (Element.text data.model.name |> Element.el [ Element.centerX, Element.Font.size 50 ] ) |> Element.column [ Element.padding 15 , Element.spacing 30 , Element.width <| Element.px <| Pixels.inPixels data.size.width ] viewEloStat : { flavor : Theme.Flavor } -> EloStat -> Element msg viewEloStat data stat = Element.row [ Element.Background.color (Theme.mantleUI data.flavor) , Element.Border.rounded 5 , Element.padding 10 , Element.spacing 5 , Element.width Element.fill ] [ Element.column [ Element.centerY, Element.spacing 5, Element.width Element.fill ] [ Element.text stat.name |> Element.el [ Element.Font.size 30 ] , Element.el [ Element.Font.color (Theme.subtext0UI data.flavor) , Element.Font.size 15 ] (case stat.version of Nothing -> Element.text stat.url Just v -> Element.text (stat.url ++ " | " ++ v) ) ] -- Bar to push the rest to the right , Element.column [ Element.width Element.fill ] [] , field { text = "ELO", value = stat.elo, color = Theme.lavenderUI data.flavor } |> Element.el [ Element.paddingEach { top = 0, bottom = 0, left = 0, right = 15 } ] , field { text = "WINS", value = stat.wins, color = Theme.greenUI data.flavor } , field { text = "DRAWS", value = stat.draws, color = Theme.subtext0UI data.flavor } , field { text = "LOSSES", value = stat.losses, color = Theme.redUI data.flavor } ] field : { text : String, value : Int, color : Element.Color } -> Element msg field { text, value, color } = Element.column [ Element.Font.color color , Element.spacing 3 , Element.width (Element.px 70) ] [ String.fromInt value |> Element.text |> Element.el [ Element.centerX, Element.Font.size 25 ] , text |> Element.text |> Element.el [ Element.centerX, Element.Font.size 15 ] ]