Added edit/update functionality for words
Getty Ritter
8 years ago
24 | 24 | conn <- getContext |
25 | 25 | liftIO (mote conn) |
26 | 26 | |
27 | unwrap :: Maybe a -> (a -> ActionCtxT ctx IO ()) -> ActionCtxT ctx IO () | |
28 | unwrap Nothing _ = setStatus status404 | |
29 | unwrap (Just x) f = f x | |
30 | ||
27 | 31 | main :: IO () |
28 | 32 | main = do |
29 | 33 | dbLoc <- maybe "test.db" id `fmap` lookupEnv "DB_LOC" |
31 | 35 | conn <- open dbLoc |
32 | 36 | runSpock port $ spockT id $ prehook (return conn) $ do |
33 | 37 | middleware $ staticPolicy (mempty <> hasPrefix "static") |
38 | ||
34 | 39 | get root $ do |
35 | 40 | html (rPage "welcome to the dictionary yo") |
41 | ||
36 | 42 | get "add" $ do |
37 | 43 | ls <- db allLanguages |
38 | 44 | html (rPage (rAdd ls)) |
45 | ||
39 | 46 | get "search" $ do |
40 | 47 | html (rPage rSearch) |
48 | ||
41 | 49 | get "word" $ do |
42 | 50 | es <- db getAllWords |
43 | 51 | respondWith es |
44 | 52 | post "word" $ do |
45 | ps <- params | |
46 | case paramsToEntry ps of | |
47 | Nothing -> setStatus status404 | |
48 | Just e -> do | |
49 | i <- db (addWord e) | |
50 | redirect (pack ("/word/" ++ show i)) | |
53 | ps <- paramsToEntry <$> params | |
54 | unwrap ps $ \ e -> do | |
55 | i <- db (addWord e) | |
56 | redirect (pack ("/word/" ++ show i)) | |
57 | ||
51 | 58 | get ("word" <//> var) $ \ w -> do |
52 | 59 | eM <- db (getWordById w) |
53 | case eM of | |
54 | Just e -> respondWith [e] | |
55 |
|
|
60 | unwrap eM $ \ e -> respondWith [e] | |
61 | post ("word" <//> var) $ \ w -> do | |
62 | ps <- paramsToEntry <$> params | |
63 | unwrap ps $ \ e -> do | |
64 | db (updateWord w e) | |
65 | redirect (pack ("/word/" ++ show w)) | |
66 | ||
67 | get ("word" <//> var <//> "edit") $ \ w -> do | |
68 | eM <- db (getWordById w) | |
69 | ls <- db allLanguages | |
70 | unwrap eM $ html . rPage . rEdit w ls | |
71 | ||
56 | 72 | get ("word" <//> "search" <//> var) $ \ t -> do |
57 | 73 | db (searchAll t) >>= respondWith |
74 | ||
58 | 75 | get ("word" <//> "search" <//> "by-word" <//> var) $ \ t -> do |
59 | 76 | db (searchWord t) >>= respondWith |
77 | ||
60 | 78 | get ("word" <//> "search" <//> "by-meaning" <//> var) $ \ t -> do |
61 | 79 | db (searchMeaning t) >>= respondWith |
45 | 45 | div_ [ class_ "meaning" ] $ toHtml (eMeaning e) |
46 | 46 | when (eNotes e /= "") $ |
47 | 47 | div_ [ class_ "notes" ] $ toHtml (eNotes e) |
48 | ul_ [ class_ "links" ] $ do | |
49 | li_ $ a_ [ href_ (pack ("/word/" ++ show (eID e) ++ "/edit")) ] "edit" | |
50 | li_ $ a_ [ href_ (pack ("/word/" ++ show (eID e))) ] "link" | |
48 | 51 | |
49 | 52 | rSearch :: Html () |
50 | 53 | rSearch = form_ [ name_ "search" ] $ do |
51 | 54 | input_ [ type_ "text", name_ "query" ] |
52 | 55 | |
53 | 56 | rAdd :: [Language] -> Html () |
54 |
rAdd ls = form_ [ name_ "add", action_ "/word |
|
57 | rAdd ls = form_ [ name_ "add", action_ "/word/", method_ "POST" ] $ do | |
55 | 58 | div_ $ do |
56 | 59 | label_ "Language: " |
57 | 60 | select_ [ name_ "lang" ] $ sequence_ |
71 | 74 | label_ "Notes: " |
72 | 75 | textarea_ [ rows_ "4", cols_ "100", name_ "notes" ] "" |
73 | 76 | div_ $ input_ [ type_ "submit" ] |
77 | ||
78 | ||
79 | rEdit :: Integer -> [Language] -> Entry -> Html () | |
80 | rEdit w ls e = form_ [ name_ "edit" | |
81 | , action_ (pack ("/word/" ++ show w)) | |
82 | , method_ "POST" | |
83 | ] $ do | |
84 | div_ $ do | |
85 | label_ "Language: " | |
86 | select_ [ name_ "lang" ] $ sequence_ | |
87 | [ option_ [ value_ (pack (show i)) | |
88 | , select_ (if i == langId (eLanguage e) | |
89 | then "true" | |
90 | else "false") | |
91 | ] $ toHtml n | |
92 | | Language { langId = i, langName = n } <- ls | |
93 | ] | |
94 | div_ $ do | |
95 | label_ "Word: " | |
96 | input_ [ type_ "text" | |
97 | , name_ "word" | |
98 | , value_ (eWord e) | |
99 | ] | |
100 | div_ $ do | |
101 | label_ "Transliteration: " | |
102 | input_ [ type_ "text" | |
103 | , name_ "translit" | |
104 | , value_ (eTranslit e) | |
105 | ] | |
106 | div_ $ do | |
107 | label_ "Meaning: " | |
108 | textarea_ [ rows_ "4", cols_ "100", name_ "meaning" ] $ | |
109 | toHtml (eMeaning e) | |
110 | div_ $ do | |
111 | label_ "Notes: " | |
112 | textarea_ [ rows_ "4", cols_ "100", name_ "notes" ] $ | |
113 | toHtml (eNotes e) | |
114 | div_ $ input_ [ type_ "submit" ] |
99 | 99 | execute conn q entry |
100 | 100 | fromIntegral <$> lastInsertRowId conn |
101 | 101 | |
102 | updateWord :: Integer -> Entry -> DB () | |
103 | updateWord i e conn = do | |
104 | let q = "UPDATE words \ | |
105 | \ SET word=?, trans=?, meaning=?, notes=? \ | |
106 | \ WHERE id=?" | |
107 | execute conn q ( eWord e | |
108 | , eTranslit e | |
109 | , eMeaning e | |
110 | , eNotes e | |
111 | , i | |
112 | ) | |
113 | ||
102 | 114 | getWordById :: Integer -> DB (Maybe Entry) |
103 | 115 | getWordById i conn = do |
104 | 116 | let q = "SELECT w.id, w.word, w.trans, w.meaning, w.notes, l.id, l.name \ |
63 | 63 | } |
64 | 64 | |
65 | 65 | .notes { |
66 | padding-top: 20px; | |
67 | padding-left: 40px; | |
66 | 68 | font-style: italic; |
67 | 69 | } |
68 | 70 | |
116 | 118 | |
117 | 119 | textarea { |
118 | 120 | float: right; |
121 | } | |
122 | ||
123 | .links { | |
124 | text-align: right; | |
125 | } | |
126 | ||
127 | .links li { | |
128 | display: inline; | |
129 | list-style-type: none; | |
130 | padding-left: 20px; | |
131 | padding-right: 20px; | |
119 | 132 | } |