Add part4
This commit is contained in:
21
intro/part4/src/Article.elm
Normal file
21
intro/part4/src/Article.elm
Normal file
@@ -0,0 +1,21 @@
|
||||
module Article exposing (feed, tags)
|
||||
|
||||
-- For now, this module only holds hardcoded data.
|
||||
--
|
||||
-- In future exercises, it will read data from the server!
|
||||
|
||||
|
||||
tags =
|
||||
[ "elm"
|
||||
, "fun"
|
||||
, "programming"
|
||||
, "dragons"
|
||||
]
|
||||
|
||||
|
||||
feed =
|
||||
[ { title = "Elm is fun!", description = "Elm", body = "I've really been enjoying it!", tags = [ "elm", "fun" ], slug = "elm-is-fun--zb6nba" }
|
||||
, { title = "Who says undefined isn't a function anyway?", description = "Functions", body = "Quite frankly I think undefined can be anything it wants to be,if it believes in itself.", slug = "who-says-undefined-isnt-a-function-anyway-t39ope", tags = [ "programming" ] }
|
||||
, { title = "This compiler is pretty neat", description = "Elm", body = "It tells me about problems in my code. How neat is that?", tags = [ "compilers", "elm" ], slug = "this-compiler-is-pretty-neat-9ycui8" }
|
||||
, { title = "Are dragons real?", description = "dragons", body = "Do Komodo Dragons count? I think they should. It's right there in the name!", tags = [ "dragons" ], slug = "are-dragons-real-467lsh" }
|
||||
]
|
||||
148
intro/part4/src/Main.elm
Normal file
148
intro/part4/src/Main.elm
Normal file
@@ -0,0 +1,148 @@
|
||||
module Main exposing (main)
|
||||
|
||||
import Article
|
||||
import Browser
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ tags : List String
|
||||
, selectedTag : String
|
||||
|
||||
{- 👉 TODO: change this `allArticles` annotation to the following:
|
||||
|
||||
allArticles : List Article
|
||||
|
||||
|
||||
💡 HINT: You'll need to move the existing annotation to a `type alias`.
|
||||
-}
|
||||
, allArticles :
|
||||
List
|
||||
{ title : String
|
||||
, description : String
|
||||
, body : String
|
||||
, tags : List String
|
||||
, slug : String
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `initialModel`
|
||||
-}
|
||||
initialModel =
|
||||
{ tags = Article.tags
|
||||
, selectedTag = "elm"
|
||||
, allArticles = Article.feed
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type alias Msg =
|
||||
{ description : String
|
||||
, data : String
|
||||
}
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `update`
|
||||
-}
|
||||
update msg model =
|
||||
if msg.description == "ClickedTag" then
|
||||
{ model | selectedTag = msg.data }
|
||||
else
|
||||
model
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `view`
|
||||
-}
|
||||
view model =
|
||||
let
|
||||
articles =
|
||||
List.filter (\article -> List.member model.selectedTag article.tags)
|
||||
model.allArticles
|
||||
|
||||
feed =
|
||||
List.map viewArticle articles
|
||||
in
|
||||
div [ class "home-page" ]
|
||||
[ viewBanner
|
||||
, div [ class "container page" ]
|
||||
[ div [ class "row" ]
|
||||
[ div [ class "col-md-9" ] feed
|
||||
, div [ class "col-md-3" ]
|
||||
[ div [ class "sidebar" ]
|
||||
[ p [] [ text "Popular Tags" ]
|
||||
, viewTags model
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `view`
|
||||
-}
|
||||
viewArticle article =
|
||||
div [ class "article-preview" ]
|
||||
[ h1 [] [ text article.title ]
|
||||
, p [] [ text article.description ]
|
||||
, span [] [ text "Read more..." ]
|
||||
]
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `view`
|
||||
-}
|
||||
viewBanner : Html Msg
|
||||
viewBanner =
|
||||
div [ class "banner" ]
|
||||
[ div [ class "container" ]
|
||||
[ h1 [ class "logo-font" ] [ text "conduit" ]
|
||||
, p [] [ text "A place to share your knowledge." ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
{-| 👉 TODO: Replace this comment with a type annotation for `view`
|
||||
-}
|
||||
viewTag selectedTagName tagName =
|
||||
let
|
||||
otherClass =
|
||||
if tagName == selectedTagName then
|
||||
"tag-selected"
|
||||
else
|
||||
"tag-default"
|
||||
in
|
||||
button
|
||||
[ class ("tag-pill " ++ otherClass)
|
||||
, onClick { description = "ClickedTag", data = tagName }
|
||||
]
|
||||
[ text tagName ]
|
||||
|
||||
|
||||
viewTags : Model -> Html Msg
|
||||
viewTags model =
|
||||
div [ class "tag-list" ] (List.map (viewTag model.selectedTag) model.tags)
|
||||
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
|
||||
main : Program () Model Msg
|
||||
main =
|
||||
Browser.sandbox
|
||||
{ init = initialModel
|
||||
, view = view
|
||||
, update = update
|
||||
}
|
||||
Reference in New Issue
Block a user