module Pages.Blog exposing (Model, Msg, page) import Config.Data.Identity exposing (pageNames) import Config.Helpers.CardFormat exposing ( cardContentSpacing , cardFormatter , cardMaker , cardTitleMaker , desktopCardMaker , desktopImageBoxSize , desktopImageSize , fieldSpacer , mobileCardMaker , mobileImageBoxSize , mobileImageSize , topLevelBox , underConstructionMaker ) import Config.Helpers.Converters exposing ( formatName , wordCount ) import Config.Helpers.Format exposing ( paragraphFontSize , paragraphSpacing ) import Config.Helpers.Header exposing (..) import Config.Helpers.Response exposing ( pageList , topLevelContainer ) import Config.Helpers.Viewport exposing (resetViewport) import Config.Pages.Blog.Records.EverettVegans exposing (articleEverettVegans) import Config.Pages.Blog.Records.HunterGatherers exposing (articleHunterGatherers) import Config.Pages.Blog.Records.MeatApologetics exposing (articleMeatApologetics) import Config.Pages.Blog.Records.NagraGoodrich exposing (articleNagraGoodrich) import Config.Pages.Blog.Records.QuackSmashing exposing (articleQuackSmashing) import Config.Pages.Blog.Records.SapienDiet exposing (articleSapienDiet) import Config.Pages.Blog.Records.SeedOils exposing (articleSeedOils) import Config.Pages.Blog.Types exposing (..) import Config.Style.Colour as T exposing (..) import Config.Style.Icons.Icons exposing (construction) import Effect exposing (Effect) import Element as E exposing (..) import Element.Background as B import Element.Border as D import Element.Font as F import Html.Attributes as H exposing (style) import Layouts import Page exposing (Page) import Route exposing (Route) import Route.Path as Path import Shared exposing (..) import View exposing (View) page : Shared.Model -> Route () -> Page Model Msg page shared route = Page.new { init = init , update = update , subscriptions = subscriptions , view = view shared } |> Page.withLayout toLayout toLayout : Model -> Layouts.Layout Msg toLayout model = Layouts.Navbar {} -- INIT type alias Model = {} init : () -> ( Model, Effect Msg ) init () = ( {} , Effect.map (\_ -> NoOp) (Effect.sendCmd resetViewport) ) -- UPDATE type Msg = NoOp update : Msg -> Model -> ( Model, Effect Msg ) update msg model = case msg of NoOp -> ( model , Effect.none ) -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions model = Sub.none -- VIEW view : Shared.Model -> Model -> View Msg view shared model = { title = pageNames.pageHyperBlog , attributes = [] , element = blogContainer shared.device } blogContainer : Device -> Element msg blogContainer device = topLevelContainer (blogList device) blogList : Device -> Element msg blogList device = column (case ( device.class, device.orientation ) of _ -> pageList ) <| List.concat [ List.map headerMaker [ blogHeader ] , (case ( device.class, device.orientation ) of ( Phone, Portrait ) -> List.map mobileBlogMaker ( Tablet, Portrait ) -> List.map mobileBlogMaker _ -> List.map desktopBlogMaker ) [ articleEverettVegans , articleQuackSmashing , articleSapienDiet , articleNagraGoodrich , articleMeatApologetics , articleSeedOils , articleHunterGatherers ] ] blogHeader : Header blogHeader = let name = "Blog" in { headerTitle = String.toUpper name , headerBody = "This page features blog articles written by me, along with contributions from guest authors, covering topics primarily related to nutrition science, health science, and debate." } desktopBlogMaker : BlogArticle -> Element msg desktopBlogMaker article = row topLevelBox [ desktopCardMaker desktopImageBoxSize desktopImageSize (articleImage article) article.articleLink , cardMaker [ cardTitleMaker article.articleName , cardFormatter [ cardContentSpacing [ column fieldSpacer [ articleMaker article ] ] ] ] ] mobileBlogMaker : BlogArticle -> Element msg mobileBlogMaker article = row topLevelBox [ column [] [] , cardMaker [ cardTitleMaker article.articleName , cardFormatter [ cardContentSpacing [ column fieldSpacer [ row [ width fill, spacing 10 ] [ mobileCardMaker mobileImageBoxSize mobileImageSize (articleImage article) article.articleLink , column [ width fill ] [ articleMaker article ] ] ] ] ] ] ] articleImage : BlogArticle -> { src : String , description : String } articleImage article = { src = "blog/" ++ article.articleImage ++ "thumb.png" , description = article.articleName } articleMaker : BlogArticle -> Element msg articleMaker article = column [ E.width fill , centerX ] [ column [ width fill ] (articleRows article ++ [ row [] [ paragraph [ F.color colourTheme.textLightGrey , paragraphSpacing , paragraphFontSize , spacing 3 , F.regular , F.alignLeft , F.size 16 , paddingEach { top = 8 , bottom = 0 , left = 0 , right = 0 } ] [ text article.articleDescription ] ] ] ) ] infoRow : String -> String -> Element msg infoRow label value = row [ width fill ] [ el [ width <| px 85 ] <| paragraph [ F.color colourTheme.textLightOrange , paragraphSpacing , paragraphFontSize , F.bold , F.size 18 , E.width fill ] [ text label ] , el [ width fill ] <| paragraph [ F.color colourTheme.textLightGrey , F.regular , paragraphFontSize , width fill ] [ text value ] ] articleRows : BlogArticle -> List (Element msg) articleRows article = [ infoRow "Author:" article.articleAuthor , infoRow "Published:" article.articlePublished , infoRow "Duration:" (String.fromInt (wordCount article.articleBody // 225) ++ " minutes") , infoRow "Words:" (String.fromInt (wordCount article.articleBody)) ]