Skip to content

Commit

Permalink
feat: add new user (#237)
Browse files Browse the repository at this point in the history
Co-authored-by: Riddhi Agrawal <[email protected]>
Co-authored-by: Jeeva Ramachandran <[email protected]>
  • Loading branch information
3 people authored Jan 18, 2024
1 parent 1b75528 commit 3749e32
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 29 deletions.
13 changes: 3 additions & 10 deletions src/screens/HyperSwitch/SwitchMerchant/SwitchMerchant.res
Original file line number Diff line number Diff line change
Expand Up @@ -318,16 +318,9 @@ let make = (~userRole, ~isAddMerchantEnabled=false) => {
} else {
<>
<ExternalUser switchMerchant isAddMerchantEnabled />
<Modal
showModal=successModal
setShowModal=setSuccessModal
modalClass="w-80 !h-48 flex items-center justify-center m-auto"
paddingClass=""
childClass="flex items-center justify-center h-full w-full">
{<div className="flex items-center gap-2">
<p className="text-xl font-semibold"> {"Switching merchant..."->React.string} </p>
</div>}
</Modal>
<LoaderModal
showModal={successModal} setShowModal={setSuccessModal} text="Switching merchant..."
/>
</>
}
}
82 changes: 63 additions & 19 deletions src/screens/HyperSwitch/UserManagement/InviteUsers.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module InviteEmailForm = {
open LogicUtils
open APIUtils
let fetchDetails = useGetMethod()
let {magicLink} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let (roleListData, setRoleListData) = React.useState(_ => [])

let emailList =
Expand Down Expand Up @@ -53,7 +54,7 @@ module InviteEmailForm = {
<div className="text-sm text-grey-500"> {emailList->React.string} </div>
</div>
<div className="absolute top-10 right-5">
<FormRenderer.SubmitButton text="Send Invite" />
<FormRenderer.SubmitButton text={magicLink ? "Send Invite" : "Add User"} />
</div>
</div>
<FormRenderer.FieldRenderer
Expand All @@ -74,47 +75,83 @@ let make = () => {
let fetchDetails = useGetMethod()
let updateDetails = useUpdateMethod()
let showToast = ToastState.useShowToast()
let {magicLink} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let {permissionInfo, setPermissionInfo} = React.useContext(GlobalProvider.defaultContext)
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
let (roleTypeValue, setRoleTypeValue) = React.useState(_ => "merchant_view_only")
let (roleDict, setRoleDict) = React.useState(_ => Dict.make())
let (loaderForInviteUsers, setLoaderForInviteUsers) = React.useState(_ => false)

let initialValues = React.useMemo0(() => {
[("roleType", ["merchant_view_only"->Js.Json.string]->Js.Json.array)]
->Dict.fromArray
->Js.Json.object_
})

let inviteUserReq = async (body, index) => {
try {
let url = getURL(~entityName=USERS, ~userType=#INVITE, ~methodType=Post, ())
let _ = await updateDetails(url, body, Post)
if index === 0 {
showToast(~message=`Invite(s) sent successfully via Email`, ~toastType=ToastSuccess, ())
}
} catch {
| _ => ()
}
let inviteUserReq = body => {
let url = getURL(~entityName=USERS, ~userType=#INVITE, ~methodType=Post, ())
let response = updateDetails(url, body, Post)
response
}

let inviteListOfUsers = async values => {
if !magicLink {
setLoaderForInviteUsers(_ => true)
}
let valDict = values->getDictFromJsonObject
let role = valDict->getStrArray("roleType")->LogicUtils.getValueFromArray(0, "")
let emailList = valDict->getStrArray("emailList")
let emailPasswordsArray = []

valDict
->getStrArray("emailList")
->Array.forEachWithIndex((ele, index) => {
let arrayOfPromises = emailList->Array.map(ele => {
let body =
[
("email", ele->String.toLowerCase->Js.Json.string),
("name", ele->getNameFromEmail->Js.Json.string),
("role_id", role->Js.Json.string),
]
->Dict.fromArray
->Js.Json.object_
let _ = inviteUserReq(body, index)
]->LogicUtils.getJsonFromArrayOfJson
inviteUserReq(body)
})
await HyperSwitchUtils.delay(400)

let response = await PromiseUtils.allSettledPolyfill(arrayOfPromises)
if !magicLink {
response->Array.forEachWithIndex((ele, index) => {
switch Js.Json.classify(ele) {
| Js.Json.JSONObject(jsonDict) => {
let passwordFromResponse = jsonDict->getString("password", "")
emailPasswordsArray->Array.push(
[
("email", emailList[index]->Option.getWithDefault("")->Js.Json.string),
("password", passwordFromResponse->Js.Json.string),
]->LogicUtils.getJsonFromArrayOfJson,
)
}
| _ => ()
}
})
}

showToast(
~message=magicLink
? `Invite(s) sent successfully via Email`
: `The user accounts have been successfully created. The file with their credentials has been downloaded.`,
~toastType=ToastSuccess,
(),
)

if !magicLink && emailPasswordsArray->Array.length > 0 {
DownloadUtils.download(
~fileName=`invited-users.txt`,
~content=emailPasswordsArray->Js.Json.array->Js.Json.stringifyWithSpace(3),
~fileType="application/json",
)
}

if !magicLink {
setLoaderForInviteUsers(_ => false)
} else {
await HyperSwitchUtils.delay(400)
}
RescriptReactRouter.push("/users")
Js.Nullable.null
}
Expand Down Expand Up @@ -222,5 +259,12 @@ let make = () => {
</div>
</PageLoaderWrapper>
</div>
<UIUtils.RenderIf condition={!magicLink}>
<LoaderModal
showModal={loaderForInviteUsers}
setShowModal={setLoaderForInviteUsers}
text="Inviting Users"
/>
</UIUtils.RenderIf>
</div>
}
16 changes: 16 additions & 0 deletions src/utils/LoaderModal.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@react.component
let make = (~showModal, ~setShowModal, ~text) => {
<UIUtils.RenderIf condition={showModal}>
<Modal
showModal
setShowModal
modalClass="w-80 !h-56 flex items-center justify-center m-auto"
paddingClass=""
childClass="flex items-center justify-center h-full w-full">
<div className="flex flex-col items-center gap-2">
<Loader />
<div className="text-xl font-semibold mb-4"> {text->React.string} </div>
</div>
</Modal>
</UIUtils.RenderIf>
}
21 changes: 21 additions & 0 deletions src/utils/PromiseUtils.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Pollyfill for Promise.allSettled()
// Promise.allSettled() takes an iterable of promises and returns a single promise that is fulfilled with an array of promise settlement result

let allSettledPolyfill = (arr: array<promise<Js.Json.t>>) => {
arr
->Array.map(promise =>
promise
->Promise.then(val => {
Promise.resolve(val)
})
->Promise.catch(err => {
switch err {
| Js.Exn.Error(e) =>
let err = Js.Exn.message(e)->Belt.Option.getWithDefault("Failed to Fetch!")
err->Js.Json.string
| _ => Js.Json.null
}->Promise.resolve
})
)
->Promise.all
}

0 comments on commit 3749e32

Please sign in to comment.