module Handler.Help where import Import import Handler.Utils import Handler.Info (faqsWidget) import Jobs import qualified Data.Map as Map import qualified Data.Yaml as Yaml import qualified Control.Monad.State.Class as State data HelpIdentOptions = HIUser | HIEmail | HIAnonymous deriving (Eq, Ord, Bounded, Enum, Show, Read) instance Universe HelpIdentOptions instance Finite HelpIdentOptions nullaryPathPiece ''HelpIdentOptions (camelToPathPiece' 1) embedRenderMessage ''UniWorX ''HelpIdentOptions (("Help" <>) . dropPrefix "HI") data HelpForm = HelpForm { hfReferer :: Maybe (Route UniWorX) , hfUserId :: Either (Maybe Address) UserId , hfSubject :: Maybe Text , hfRequest :: Maybe Html , hfError :: Maybe ErrorResponse } helpForm :: Maybe (Route UniWorX) -> Maybe UserId -> Form HelpForm helpForm mReferer mUid = renderWForm FormStandard $ do MsgRenderer mr <- getMsgRenderer let defaultActions = [ ( HIEmail , Left . Just <$> (Address <$> aopt textField (fslpI MsgName $ mr MsgName) Nothing <*> apreq emailField (fslpI MsgEMail $ mr MsgEMail) Nothing) ) , ( HIAnonymous , pure $ Left Nothing ) ] identActions :: Map _ (AForm _ (Either (Maybe Address) UserId)) identActions = Map.fromList $ case mUid of (Just uid) -> (HIUser, pure $ Right uid):defaultActions Nothing -> defaultActions sessErr <- lookupSessionJson SessionError hfReferer' <- wopt routeField (fslI MsgHelpProblemPage & inputReadonly) (Just <$> mReferer) hfUserId' <- multiActionW identActions (fslI MsgHelpAnswer) (HIUser <$ mUid) hfSubject' <- wopt textField (fslpI MsgHelpSubject $ mr MsgHelpSubject) Nothing hfRequest' <- case sessErr of Nothing -> fmap Just <$> wreq htmlField (fslpI MsgHelpRequest $ mr MsgHelpRequest) Nothing Just _ -> wopt htmlField (fslpI MsgHelpRequest $ mr MsgHelpRequest) Nothing hfError' <- case sessErr of Nothing -> return $ pure Nothing Just err -> let prettyErr = decodeUtf8 $ Yaml.encode err in optionalActionW (err <$ aforced textareaField (fslI MsgHelpError) (Textarea prettyErr)) (fslI MsgHelpSendLastError) (Just True) return $ HelpForm <$> hfReferer' <*> hfUserId' <*> hfSubject' <*> (fmap markupOutput <$> hfRequest') <*> hfError' validateHelpForm :: FormValidator HelpForm Handler () validateHelpForm = do HelpForm{..} <- State.get guardValidation MsgHelpErrorOrRequestRequired $ is _Just hfRequest || is _Just hfError getHelpR, postHelpR :: Handler Html getHelpR = postHelpR postHelpR = do mUid <- maybeAuthId mReferer <- flip formResultMaybe return <=< runInputGetResult $ iopt routeField (toPathPiece GetReferer) isModal <- hasCustomHeader HeaderIsModal ((res,formWidget'),formEnctype) <- runFormPost . validateForm validateHelpForm $ helpForm mReferer mUid formResultModal res HelpR $ \HelpForm{..} -> do now <- liftIO getCurrentTime hfReferer' <- traverse toTextUrl hfReferer queueJob' JobHelpRequest { jHelpSender = hfUserId , jSubject = hfSubject , jHelpRequest = hfRequest , jRequestTime = now , jReferer = hfReferer' , jError = hfError } whenIsJust hfError $ \error' -> modifySessionJson SessionError $ assertM (/= error') tell . pure =<< messageI Success MsgHelpSent defaultLayout $ do setTitleI MsgHelpTitle let formWidget = wrapForm formWidget' def { formAction = Just $ SomeRoute HelpR , formEncoding = formEnctype , formAttrs = [ asyncSubmitAttr | isModal ] } mFaqs <- (>>= \(mWgt, truncated) -> (, truncated) <$> mWgt) <$> traverse (faqsWidget $ Just 5) (Just <$> mReferer) $(widgetFile "help")