You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

80 lines
2.3 KiB

  1. module Component.LoginAff where
  2. import Prelude
  3. import Data.Maybe ( Maybe(..), fromMaybe )
  4. import Data.Argonaut.Encode.Class ( encodeJson )
  5. import Data.Argonaut.Core ( Json )
  6. import Data.Either ( Either )
  7. -- Effect
  8. import Effect ( Effect )
  9. -- Aff
  10. import Affjax as AX
  11. import Affjax.ResponseFormat as ResponseFormat
  12. import Affjax.RequestBody as RequestBody
  13. import Effect.Aff ( Aff, never )
  14. -- React
  15. import React.Basic.Hooks as React
  16. import React.Basic.Hooks ( ReactComponent, component, Hook, UseState, useState, (/\) )
  17. import React.Basic.Hooks.Aff ( useAff )
  18. import React.Basic.DOM as R
  19. import React.Basic.Events ( handler, EventHandler )
  20. import React.Basic.DOM.Events ( preventDefault, stopPropagation, targetValue )
  21. mkLoginAff :: Effect ( ReactComponent {} )
  22. mkLoginAff = do
  23. component "LoginAff" $ const React.do
  24. isSubmitting/\setSubmitting <- useState false
  25. email <- useInput ""
  26. password <- useInput ""
  27. login/\setLogin <- useState { email: "", password: "" }
  28. useAff login $ do
  29. void $ submitLogin isSubmitting { email: login.email, password: login.password }
  30. pure $ setSubmitting \_ -> false
  31. pure
  32. $ R.form_
  33. [ R.input
  34. { placeholder: "email"
  35. , onChange: email.onChange
  36. }
  37. , R.input
  38. { placeholder: "password"
  39. , onChange: password.onChange
  40. }
  41. , R.button
  42. { onClick: handler ( preventDefault >>> stopPropagation >>> targetValue ) \_ -> do
  43. setSubmitting \_ -> true
  44. setLogin \_ -> login { email = email.value, password = password.value }
  45. , children: [ R.text "Sign-In" ]
  46. }
  47. ]
  48. type Login =
  49. { email :: String
  50. , password :: String
  51. }
  52. submitLogin :: Boolean -> Login -> Aff ( Either AX.Error Json )
  53. submitLogin isSubmitting login = do
  54. if not isSubmitting
  55. then never
  56. else do
  57. result <- AX.post ResponseFormat.json "http://localhost:8080/login"
  58. ( Just $ RequestBody.json $ encodeJson login )
  59. pure $ _.body <$> result
  60. useInput
  61. :: String
  62. -> Hook
  63. ( UseState String )
  64. { onChange :: EventHandler
  65. , value :: String
  66. }
  67. useInput initialValue = React.do
  68. value /\ replaceValue <- useState initialValue
  69. pure
  70. { onChange: handler
  71. ( preventDefault >>> stopPropagation >>> targetValue ) \val -> do
  72. replaceValue \_ -> fromMaybe "" val
  73. , value
  74. }