{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} module Main where import Data.ByteString.Lazy (ByteString) import Data.Text.Lazy (Text) import Data.Text.Lazy.Encoding (encodeUtf8) import Text.Blaze (Markup) import Text.Blaze.Html (Html) import Text.Blaze.Html.Renderer.Text (renderHtml) import Text.Hamlet (shamlet) import Text.Lucius (lucius, renderCss) import Web.Scotty (ActionM, scotty, get, html, raw, setHeader) render :: Html -> ActionM () render = html . renderHtml css :: ByteString -> ActionM () css src = setHeader "content-type" "text/css" >> raw src main :: IO () main = scotty 3000 $ do get "/" $ render homepage get "/custom.css" $ css stylesheet data Person = Person { _name :: Text , _pic :: Text , _twitter :: Text , _twitterLink :: Text , _website :: Text , _books :: [Book] } data Book = Book { _title :: Text , _author :: Text , _amznref :: Text } allPeople :: [Person] allPeople = [ Person { _name = "Joe Rogan" , _pic = "https://pbs.twimg.com/profile_images/552307347851210752/vrXDcTFC_400x400.jpeg" , _twitter = "joerogan" , _twitterLink ="https://twitter.com/joerogan" , _website = "http://joerogan.com" , _books = [ Book {_title = "Food of the Gods" , _author = "Terence McKenna" , _amznref = "0553371304" } , Book { _title = "The War of Art" , _author ="Steven Pressfield" , _amznref ="B007A4SDCG" } ] } , Person { _name = "Beyoncé" , _pic = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTxT84sF19lxdnSiblIXAp-Y4wAigpQn8sZ2GtAerIR_ApiiEJfFQ" , _twitter = "Beyonce" , _twitterLink = "https://twitter.com/beyonce" , _website = "http://beyonce.com" , _books = [ Book { _title = "What Will It Take To Make A Woman President?" , _author = "Marianne Schnall" , _amznref = "B00E257Y7G"} ] } , Person { _name = "Barrack Obama" , _pic = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQeLzftR36p0hYI-EKNa5fm7CYDuN-vyz23_R48ocqa8X1nPr6C" , _twitter = "BarackObama" , _twitterLink = "https://twitter.com/BarackObama" , _website = "http://barackobama.com" , _books = [ Book { _title = "An American Marriage" , _author = "Tayari Jones" , _amznref = "B01NCUXEFR"} , Book { _title = "Americanah" , _author = "Chimamanda Ngozi Adichie" , _amznref = "B00A9ET4MC"} ] } , Person { _name = "Warren Buffet" , _pic = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQbmnUykS6zqgzaf44tsq1RAsnHe6H7fapEoSqUwAoJGSFKbAPSw" , _twitter = "WarrenBuffett" , _twitterLink = "https://twitter.com/WarrenBuffett" , _website = "http://berkshirehathaway.com" , _books = [ Book { _title = "The Intelligent Investor" , _author = "Benjamin Graham" , _amznref = "B000FC12C8"} , Book { _title = "Security Analysis" , _author = "Benjamin Graham" , _amznref = "B0037JO5J8"} ] } , Person { _name = "Bill Gates" , _pic = "https://pbs.twimg.com/profile_images/988775660163252226/XpgonN0X_400x400.jpg" , _twitter = "BillGates" , _twitterLink = "https://twitter.com/billgates" , _website = "https://www.gatesnotes.com" , _books = [ Book { _title = "Leonardo da Vinci" , _author = "Walter Isaacson" , _amznref = "1501139169" } , Book { _title = "Educated" , _author = "Tara Wetsover" , _amznref = "B072BLVM83" } ] } ] displayPerson :: Person -> Markup displayPerson person = [shamlet| <div .card .mx-3 .my-5 .w-25 .h-25> <img .card-img .img-fluid src=#{_pic person}> <div .card-body> <h4 .card-title> #{_name person} <h6> <a href=#{_twitterLink person} class="fab fa-twitter"> <a target=_blank href=#{_website person} class="fas fa-globe"> <p .card-text> <ul> $forall book <- (_books person) <li> <a target=_blank .text-dark href="https://www.amazon.com/dp/#{_amznref book}"> #{_title book} |] title, subtitle :: Text title = "Influenced by books" subtitle = "Influential people and the books that made them." homepage :: Markup homepage = [shamlet| <!doctype html> <head> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> <link href="/custom.css" rel="stylesheet"> <title>#{title} | #{subtitle} <body> <div .container.mt-5> <div .jumbotron> <h1 .display-4> #{title} <p .lead> #{subtitle} <div .d-flex .flex-wrap .justify-content-around> $forall person <- allPeople #{displayPerson person} |] stylesheet :: ByteString stylesheet = encodeUtf8 . renderCss $ [lucius| .jumbotron { background: #fff ; text-align: center } |] undefined