gdritter repos profile-site / master
Working HTML; needs edit capability Getty Ritter 9 years ago
3 changed file(s) with 62 addition(s) and 15 deletion(s). Collapse all Expand all
33
44 module Main where
55
6 import Control.Monad.IO.Class (liftIO)
7 import Data.Text (Text)
8 import qualified Data.Text as T
9 import Data.HashMap.Strict (toList)
10 import Lucid (renderBS)
6 import Control.Monad.IO.Class (MonadIO, liftIO)
7 import Lucid (Html, renderBS)
118 import qualified Storage as S
129 import qualified Templates as T
1310 import Web.Spock.Safe
3229 loginR :: Path '[]
3330 loginR = "login"
3431
32 imageR :: Path '[String]
33 imageR = "imgs" <//> var
34
3535 editR :: Path '[]
3636 editR = "edit"
3737
3838 editProjectR :: Path '[String]
3939 editProjectR = "edit" <//> "project" <//> var
4040
41 lucid :: MonadIO m => Html () -> ActionT m a
42 lucid = lazyBytes . renderBS
43
4144 main :: IO ()
4245 main = runSpock 8080 $ spockT id $ do
4346 get root $ do
4447 projects <- liftIO S.getAllProjects
45 lazyBytes (renderBS $ T.projectList projects)
48 lucid (T.projectList projects)
4649 get projectR $ \ p -> do
47 project <- liftIO (S.getProject p)
48 text (T.pack $ show project)
50 Just project <- liftIO (S.getProject p)
51 lucid (T.project project)
52 get loginR $ do
53 lucid T.loginPage
54 get imageR $ \ i -> do
55 setHeader "Content-Type" (S.getType i)
56 d <- liftIO (S.getImage i)
57 lazyBytes d
58 get "css" $ do
59 setHeader "Content-Type" "text/css"
60 liftIO S.getCSS >>= lazyBytes
4961 {-
5062 post root $ do
5163 fs <- files
11 {-# LANGUAGE OverloadedStrings #-}
22 {-# LANGUAGE FlexibleInstances #-}
33 {-# LANGUAGE DeriveGeneric #-}
4 {-# LANGUAGE DeriveAnyClass #-}
54 {-# LANGUAGE ViewPatterns #-}
65 {-# LANGUAGE ScopedTypeVariables #-}
76
1110 import Data.Aeson
1211 import Data.ByteString.Lazy (ByteString)
1312 import Data.FileStore
13 import Data.List (isSuffixOf)
1414 import Data.Maybe (catMaybes)
15 import Data.Monoid ((<>))
15 import Data.Monoid (Monoid, (<>))
1616 import Data.String (IsString)
1717 import Data.Text (Text)
1818 --import Data.UUID.V4
3232 , projectName :: Text
3333 , projectDescr :: Text
3434 , projectImgs :: [String]
35 } deriving (Eq, Show, Generic, FromJSON, ToJSON)
35 } deriving (Eq, Show, Generic)
36
37 instance FromJSON Project where
38 instance ToJSON Project where
3639
3740 recover :: forall a. IO (Maybe a) -> IO (Maybe a)
3841 recover action = action `catch` go
6265 getImage :: String -> IO ByteString
6366 getImage name = retrieve portfolioStore ("images" </> name) Nothing
6467
68 getType :: String -> Text
69 getType s
70 | ".png" `isSuffixOf` s = "image/png"
71 | ".jpg" `isSuffixOf` s = "image/jpeg"
72 | ".gif" `isSuffixOf` s = "image/gif"
73 | otherwise = error "unrecognized image type requested"
74
75 getCSS :: IO ByteString
76 getCSS = retrieve portfolioStore ("css") Nothing
77
6578 {-
6679 imageType :: String -> ImageType
6780 imageType "image/gif" = ItGIF
33
44 module Templates where
55
6 import Control.Monad (forM_)
7 import Data.Char (toLower)
68 import Data.Monoid ((<>))
79 import Data.Text (Text, pack)
10 import qualified Data.Text as T
811 import Lucid
912 import qualified Storage as S
1013
1114 footer :: Html ()
12 footer = "© Empress Cortana 2015"
15 footer = "copyright 2015 Empress Cortana"
1316
1417 page :: Html () -> Html () -> Html ()
1518 page name contents = html_ $ do
1619 head_ $ do
1720 title_ name
21 link_ [rel_ "stylesheet", type_ "text/css", href_ "/css"]
1822 body_ $ do
1923 div_ [id_ "header"] $ h1_ name
2024 div_ [id_ "main"] $ contents
2125 div_ [id_ "footer"] $ footer
2226
27 title :: Text -> Html ()
28 title t = toHtml ("empress cortana // " <> T.map toLower t)
29
2330 projectList :: [S.Project] -> Html ()
24 projectList = page "empress cortana // portfolio" . mapM_ shortProj
31 projectList = page (title "portfolio") . mapM_ shortProj
32
33 project :: S.Project -> Html ()
34 project p = page (title (S.projectName p)) (fullProj p)
35
36 loginPage :: Html ()
37 loginPage = page (title "login") $ do
38 form_ [name_ "login", action_ "/login"] $ do
39 input_ [type_ "password", name_ "password"]
40 input_ [type_ "submit", value_ "login"]
2541
2642 imgUrl :: String -> Text
27 imgUrl s = pack ("imgs/" <> s)
43 imgUrl s = pack ("/imgs/" <> s)
2844
2945 projUrl :: Text -> Text
30 projUrl s = "project/" <> s
46 projUrl s = "/project/" <> s
3147
3248 shortProj :: S.Project -> Html ()
3349 shortProj (S.Project { .. }) = div_ [class_ "project"] $ do
3551 case projectImgs of
3652 (img:_) -> div_ [id_ "tile"] $ img_ [src_ (imgUrl img)]
3753 [] -> return ()
54
55 fullProj :: S.Project -> Html ()
56 fullProj (S.Project { .. }) = div_ [class_ "project"] $ do
57 div_ [id_ "descr"] $ toHtml projectDescr
58 forM_ projectImgs $ \img ->
59 div_ [id_ "tile"] $ img_ [src_ (imgUrl img)]