module Layouts.Navbar exposing (Model, Msg, Props, layout) import Config.Data.Identity exposing (..) import Config.Helpers.Format exposing ( paragraphFontSize , paragraphSpacing ) import Config.Style.Colour exposing (colourTheme) import Config.Style.Fonts exposing (spartanFont) import Config.Style.Glow exposing (glowDeepDarkGreyNavbar) import Config.Style.Icons.Icons exposing ( contact , debate , discord , donate , gitlab , home , hyperBlog , interviews , mastodon , nutriDex , services , twitter , upRootLarge , upRootMedium , upRootSmall ) import Config.Style.Transitions exposing ( hoverFontLightOrange , transitionStyleMedium ) import Effect exposing (Effect) import Element as E exposing (..) import Element.Background as B import Element.Border as D import Element.Events as Events import Element.Font as F import Element.Region exposing (description) import Html exposing (Html) import Html.Attributes as H exposing ( class , style ) import Layout exposing (Layout) import Route exposing (Route) import Route.Path as Path import Shared import View exposing (View) type alias Props = {} layout : Props -> Shared.Model -> Route () -> Layout () Model Msg contentMsg layout props shared route = Layout.new { init = init , update = update , view = \layoutArgs -> view route shared { props = props , content = layoutArgs.content , model = layoutArgs.model , toContentMsg = layoutArgs.toContentMsg } , subscriptions = subscriptions } -- MODEL type alias Model = {} init : () -> ( Model, Effect Msg ) init _ = ( {} , Effect.none ) -- UPDATE type Msg = ReplaceMe update : Msg -> Model -> ( Model, Effect Msg ) update msg model = case msg of ReplaceMe -> ( model , Effect.none ) subscriptions : Model -> Sub Msg subscriptions model = Sub.none -- VIEW view : Route () -> Shared.Model -> { content : View contentMsg , model : Model , toContentMsg : Msg -> contentMsg , props : Props } -> View contentMsg view route shared { content, model, toContentMsg, props } = { title = "uRN :: " ++ content.title , attributes = [ F.family [ spartanFont ] ] , element = navbarContainer route shared.device content.element } navbarContainer : Route () -> Device -> Element msg -> Element msg navbarContainer route device content = row [ E.width fill , height fill , B.color colourTheme.backgroundDarkGrey , E.height E.fill ] [ column [ htmlAttribute (H.style "position" "fixed") , htmlAttribute (H.style "left" "0") , htmlAttribute (H.style "top" "0") , htmlAttribute (H.style "height" "100vh") , htmlAttribute (H.style "z-index" "10") , htmlAttribute (H.style "transform-style" "preserve-3d") , D.widthEach { top = 0, bottom = 0, left = 0, right = 3 } , D.color colourTheme.textDarkOrange , B.color colourTheme.backgroundDarkGrey , glowDeepDarkGreyNavbar , spacing 3 ] (case ( device.class, device.orientation ) of ( Phone, Portrait ) -> [ mobileIconMaker, mobileNavbar, mobileFooterIcons ] ( Phone, Landscape ) -> [ mobileIconMaker, mobileNavbar, mobileFooterIcons ] ( Tablet, Portrait ) -> [ mobileIconMaker, mobileNavbar, mobileFooterIcons ] _ -> [ desktopIconMaker, desktopNavbar route, desktopFooterIcons ] ) , el [ E.width fill , height fill , paddingEach { top = 0 , right = 0 , bottom = 0 , left = case ( device.class, device.orientation ) of ( Phone, _ ) -> mobileBarWidth ( Tablet, Portrait ) -> mobileBarWidth _ -> desktopBarWidth } ] content ] desktopBarWidth : Int desktopBarWidth = 200 mobileBarWidth : Int mobileBarWidth = 50 localhostUrl : String localhostUrl = url desktopNavbar : Route () -> Element msg desktopNavbar route = column [ alignLeft , height fill , F.color colourTheme.textLightGrey , scrollbarY ] [ column [ padding 20, alignTop, alignLeft ] [ column [ F.bold , F.color colourTheme.textLightGrey , F.size 17 , spacing 10 , paddingEach { top = 0 , right = 0 , bottom = 0 , left = 10 } ] (List.map2 (desktopButtonMaker route) pageList iconList ) ] ] desktopIconMaker : Element msg desktopIconMaker = column [ centerX , E.width <| px desktopBarWidth ] [ row [ centerX , spacing 2 , E.width <| px 140 , centerX , paddingEach { top = 20 , right = 0 , bottom = 20 , left = 0 } ] [ html upRootMedium ] , el [ E.width <| px 140 , alignTop , centerX , D.widthEach { bottom = 1 , top = 0 , left = 0 , right = 0 } , D.color colourTheme.textDarkGrey ] none ] mobileIconMaker : Element msg mobileIconMaker = column [ centerX , E.width <| px mobileBarWidth ] [ row [ centerX , spacing 2 , E.width <| px 35 , centerX , paddingEach { top = 10 , right = 0 , bottom = 10 , left = 0 } ] [ html upRootSmall ] , el [ E.width <| px 20 , alignTop , centerX , D.widthEach { bottom = 1 , top = 0 , left = 0 , right = 0 } , D.color colourTheme.textDarkGrey ] none ] mobileNavbar : Element msg mobileNavbar = column [ height fill , E.width fill , F.color colourTheme.textLightGrey , scrollbarY ] [ column [ padding 5 , alignTop , centerX ] [ column [ spacing 8 , centerX ] (List.map2 mobileButtonMaker pageList iconList ) ] ] desktopBackground : Element msg -> Element msg desktopBackground = el [ E.width fill , height fill , paddingEach { top = 0 , right = 0 , bottom = 0 , left = desktopBarWidth } ] mobileBackground : Element msg -> Element msg mobileBackground = el [ E.width fill , height fill , paddingEach { top = 0 , right = 0 , bottom = 0 , left = mobileBarWidth } ] desktopButtonMaker : Route () -> String -> Html msg -> Element msg desktopButtonMaker route name icon = link [ E.width fill ] { url = if name == "Home" then localhostUrl else localhostUrl ++ String.toLower name , label = row [ spacing 0, height <| px 30 ] [ el [ E.width <| px 35 , paddingEach { top = 0 , right = 10 , bottom = 0 , left = 0 } ] <| html icon , el ((if route.path == Path.Blog then F.color colourTheme.textLightOrange else F.color colourTheme.textLightGrey ) :: [ transitionStyleMedium , alignBottom ] ) <| text <| String.toUpper name ] } mobileButtonMaker : String -> Html msg -> Element msg mobileButtonMaker name icon = link [] { url = localhostUrl ++ String.toLower name , label = row [ spacing 10 ] [ column [ E.width <| px 20 ] [ html icon ] ] } iconList : List (Html msg) iconList = [ home , services , hyperBlog , debate , nutriDex , interviews , donate , contact ] pageList : List String pageList = [ "Home" , "Services" , "HyperBlog" , "Debate" , "NutriDex" , "Interviews" , "Donate" , "Contact" ] desktopFooterIcons : Element msg desktopFooterIcons = column [ E.width <| px 140 , alignTop , centerX , D.widthEach { bottom = 0 , top = 1 , left = 0 , right = 0 } , D.color colourTheme.textDarkGrey ] [ row [ alignBottom , E.width fill , centerX ] [ row [ centerX , centerY , E.width fill , E.height fill , spacing 20 , paddingEach { top = 25 , bottom = 25 , left = 0 , right = 0 } ] (List.map2 desktopFooterImageMaker [ gitlabDetails , twitterDetails , mastodonDetails , discordDetails ] footerIconList ) ] ] mobileFooterIcons : Element msg mobileFooterIcons = column [ E.width <| px 20 , alignTop , centerX , D.widthEach { bottom = 0 , top = 1 , left = 0 , right = 0 } , D.color colourTheme.textDarkGrey ] [ column [ alignBottom , E.width fill ] [ column [ centerX , centerY , E.width fill , E.height fill , spacing 10 , paddingEach { top = 10 , bottom = 10 , left = 0 , right = 0 } ] (List.map2 mobileFooterImageMaker [ gitlabDetails , twitterDetails , mastodonDetails , discordDetails ] footerIconList ) ] ] desktopFooterImageMaker : { name : String , url : String } -> Html msg -> Element msg desktopFooterImageMaker config icon = column [ centerX ] [ newTabLink [] { url = config.url , label = row [ E.width <| px 20 ] [ html icon ] } ] mobileFooterImageMaker : { name : String , url : String } -> Html msg -> Element msg mobileFooterImageMaker config icon = column [ centerX ] [ newTabLink [] { url = config.url , label = row [ E.width <| px 15 ] [ html icon ] } ] gitlabDetails : { name : String, url : String } gitlabDetails = { name = "gitlab" , url = "https://gitlab.com/upRootNutrition/website" } twitterDetails : { name : String, url : String } twitterDetails = { name = "twitter" , url = "https://x.com/upRootNutrition" } mastodonDetails : { name : String, url : String } mastodonDetails = { name = "mastodon" , url = "https://social.uprootnutrition.com/@nick" } discordDetails : { name : String, url : String } discordDetails = { name = "discord" , url = "https://discord.com/invite/YrcEvgRTqy" } footerIconList = [ gitlab , twitter , mastodon , discord ]