diff --git a/src/App/Container.purs b/src/App/Container.purs index 6795452..fa6cd9b 100644 --- a/src/App/Container.purs +++ b/src/App/Container.purs @@ -164,6 +164,14 @@ data Action -- | Currently, this handles the navigation bar. | ToggleAuthenticated (Maybe Token) + -- | Add a main notification, at the top of the page. + | AddNotif Notification + + -- | Close the main notification, at the top of the page. + | CloseNotif + +data Notification = NoNotification | GoodNotification String | BadNotification String + -- | The component's state is composed of: -- | a potential authentication token, -- | the current page, @@ -173,6 +181,7 @@ type State = { token :: Maybe String , current_page :: Page , store_DomainListInterface_state :: Maybe DomainListInterface.State , store_AuthenticationDaemonAdmin_state :: Maybe AdminInterface.State + , notif :: Notification } -- | The list of child components: log, `WS` twice (once for each ws connection), @@ -222,6 +231,7 @@ initialState _ = { token: Nothing , current_page: Home , store_DomainListInterface_state: Nothing , store_AuthenticationDaemonAdmin_state: Nothing + , notif: NoNotification } render :: forall m. MonadAff m => State -> H.ComponentHTML Action ChildSlots m @@ -229,6 +239,10 @@ render state = HH.div_ $ [ render_header , render_nav + , case state.notif of + NoNotification -> HH.div_ [] + GoodNotification v -> Bulma.box [Bulma.notification_primary v CloseNotif] + BadNotification v -> Bulma.box [Bulma.notification_danger v CloseNotif] , case state.current_page of Home -> render_home Authentication -> render_auth_form @@ -491,9 +505,11 @@ handleAction = case _ of { current_page } <- H.get case current_page of Registration -> do - handleAction $ Log $ SuccessLog """ - You are now registered, copy the token we sent you by email to finish your registration. + let successlog = """ + You are now registered, copy the token we sent you by email to finish your registration. """ + handleAction $ Log $ SuccessLog successlog + handleAction $ AddNotif $ GoodNotification successlog handleAction $ Routing MailValidation _ -> handleAction $ DispatchAuthDaemonMessage m (AuthD.GotUserEdited u) -> do @@ -501,6 +517,7 @@ handleAction = case _ of (AuthD.GotUserValidated _) -> do handleAction $ Log $ SuccessLog "User got validated! You can now log in!" handleAction $ Routing Authentication + handleAction $ AddNotif $ GoodNotification "User got validated! You can now log in!" (AuthD.GotUsersList _) -> do handleAction $ Log $ ErrorLog "TODO: received a GotUsersList message." (AuthD.GotPermissionCheck _) -> do @@ -510,6 +527,7 @@ handleAction = case _ of m@(AuthD.GotPasswordRecovered _) -> do handleAction $ Log $ SuccessLog "your new password is now valid!" handleAction $ DispatchAuthDaemonMessage m + handleAction $ AddNotif $ GoodNotification "Your new password is now valid!" m@(AuthD.GotMatchingUsers _) -> do { current_page } <- H.get case current_page of @@ -524,56 +542,73 @@ handleAction = case _ of "received a GotUserDeleted message while not on authd admin page." (AuthD.GotErrorMustBeAuthenticated _) -> do handleAction $ Log $ ErrorLog "received a GotErrorMustBeAuthenticated message." + handleAction $ AddNotif $ BadNotification "Sorry, you must be authenticated to perform this action." (AuthD.GotErrorAlreadyUsedLogin _) -> do handleAction $ Log $ ErrorLog "received a GotErrorAlreadyUsedLogin message." + handleAction $ AddNotif $ BadNotification "Sorry, your login is already taken." (AuthD.GotErrorUserNotFound _) -> do handleAction $ Log $ ErrorLog "received a GotErrorUserNotFound message." + handleAction $ AddNotif $ BadNotification "User hasn't been found." -- The authentication failed. (AuthD.GotError errmsg) -> do handleAction $ Log $ ErrorLog $ " generic error message: " <> maybe "server didn't tell why" (\v -> v) errmsg.reason + handleAction $ AddNotif $ BadNotification $ "Sorry, authd sent an error message." + <> maybe "The server didn't tell why." (\v -> "Message was: " <> v) errmsg.reason m@(AuthD.GotPasswordRecoverySent _) -> do handleAction $ Log $ SuccessLog $ "Password recovery: email sent!" + handleAction $ AddNotif $ GoodNotification "Your password recovery mail has been sent!" handleAction $ DispatchAuthDaemonMessage m (AuthD.GotErrorPasswordTooShort _) -> do handleAction $ Log $ ErrorLog "Password too short!" + handleAction $ AddNotif $ BadNotification "The server told that your password is too short." (AuthD.GotErrorMailRequired _) -> do handleAction $ Log $ ErrorLog "Email required!" + handleAction $ AddNotif $ BadNotification "An email is required." (AuthD.GotErrorInvalidCredentials _) -> do handleAction $ Log $ ErrorLog "Invalid credentials!" handleAction $ ToggleAuthenticated Nothing + handleAction $ AddNotif $ BadNotification "Invalid credentials!" (AuthD.GotErrorRegistrationsClosed _) -> do handleAction $ Log $ ErrorLog "Registration closed! Try another time or contact an administrator." + handleAction $ AddNotif $ BadNotification "Registration are closed at the moment." (AuthD.GotErrorInvalidLoginFormat _) -> do handleAction $ Log $ ErrorLog "Invalid login format!" + handleAction $ AddNotif $ BadNotification "Invalid login format." (AuthD.GotErrorInvalidEmailFormat _) -> do handleAction $ Log $ ErrorLog "Invalid email format!" + handleAction $ AddNotif $ BadNotification "Invalid email format." (AuthD.GotErrorAlreadyUsersInDB _) -> do - handleAction $ Log $ ErrorLog "Login already taken!" + handleAction $ Log $ ErrorLog "GotErrorAlreadyUsersInDB" + handleAction $ AddNotif $ BadNotification "Login already taken!" (AuthD.GotErrorReadOnlyProfileKeys _) -> do handleAction $ Log $ ErrorLog "Trying to add a profile with some invalid (read-only) keys!" + handleAction $ AddNotif $ BadNotification "Trying to add a profile with some invalid (read-only) keys!" (AuthD.GotErrorInvalidActivationKey _) -> do handleAction $ Log $ ErrorLog "Invalid activation key!" + handleAction $ AddNotif $ BadNotification "Invalid activation key!" (AuthD.GotErrorUserAlreadyValidated _) -> do handleAction $ Log $ ErrorLog "User already validated!" + handleAction $ AddNotif $ BadNotification "User already validated!" (AuthD.GotErrorCannotContactUser _) -> do handleAction $ Log $ ErrorLog "User cannot be contacted. Email address may be invalid." + handleAction $ AddNotif $ BadNotification "User cannot be contacted. Email address may be invalid." (AuthD.GotErrorInvalidRenewKey _) -> do handleAction $ Log $ ErrorLog "Invalid renew key!" + handleAction $ AddNotif $ BadNotification "Invalid renew key!" -- The authentication was a success! (AuthD.GotToken msg) -> do handleAction $ Log $ SuccessLog $ "Authenticated to authd!" H.modify_ _ { token = Just msg.token } + handleAction $ AddNotif $ GoodNotification "Authenticated!" handleAction $ ToggleAuthenticated (Just msg.token) sessionstorage <- H.liftEffect $ Window.sessionStorage =<< HTML.window _ <- H.liftEffect $ Storage.setItem "user-authd-token" msg.token sessionstorage handleAction AuthenticateToDNSManager - (AuthD.GotKeepAlive _) -> do - -- handleAction $ Log $ SystemLog $ "KeepAlive!" - pure unit + (AuthD.GotKeepAlive _) -> pure unit pure unit -- | Send a received authentication daemon message `AuthD.AnswerMessage` to a component. @@ -585,6 +620,12 @@ handleAction = case _ of _ -> handleAction $ Log $ SystemLog "unexpected message from authd" pure unit + AddNotif n -> do + H.modify_ _ { notif = n } + + CloseNotif -> do + H.modify_ _ { notif = NoNotification } + Disconnection -> do H.put $ initialState unit diff --git a/src/Bulma.purs b/src/Bulma.purs index 5ec7123..84fc9e2 100644 --- a/src/Bulma.purs +++ b/src/Bulma.purs @@ -506,3 +506,19 @@ tab_entry :: forall w i. Boolean -> String -> i -> HH.HTML w i tab_entry active name action = HH.li (if active then [HP.classes C.is_active] else []) [ HH.a [HE.onClick \_ -> action] [HH.text name] ] + +delete_btn :: forall w i. i -> HH.HTML w i +delete_btn action = HH.button [HE.onClick \_ -> action, HP.classes C.delete] [] + +notification :: forall w i. Array HH.ClassName -> String -> i -> HH.HTML w i +notification classes value deleteaction = + HH.div [HP.classes (C.notification <> classes)] + [ delete_btn deleteaction + , HH.text value + ] + +notification_primary :: forall w i. String -> i -> HH.HTML w i +notification_primary value deleteaction = notification C.is_primary value deleteaction + +notification_danger :: forall w i. String -> i -> HH.HTML w i +notification_danger value deleteaction = notification C.is_danger value deleteaction