Skip to content

Commit

Permalink
[SDP-899] feat: patch receivers' verification info (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
CaioTeixeira95 authored Mar 1, 2024
2 parents a962e20 + b4cc657 commit 128959f
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 44 deletions.
17 changes: 7 additions & 10 deletions src/apiQueries/useReceiversReceiverId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { API_URL } from "constants/envVariables";
import { fetchApi } from "helpers/fetchApi";
import { formatPaymentReceiver } from "helpers/formatPaymentReceiver";
import { formatReceiver } from "helpers/formatReceiver";
import { ApiReceiver, AppError } from "types";
import { AppError, PaymentDetailsReceiver, ReceiverDetails } from "types";

export const useReceiversReceiverId = <T>({
receiverId,
Expand All @@ -14,22 +14,19 @@ export const useReceiversReceiverId = <T>({
dataFormat: "receiver" | "paymentReceiver";
receiverWalletId?: string;
}) => {
const query = useQuery<ApiReceiver, AppError>({
const query = useQuery<ReceiverDetails | PaymentDetailsReceiver, AppError>({
queryKey: ["receivers", dataFormat, receiverId, { receiverWalletId }],
queryFn: async () => {
return await fetchApi(`${API_URL}/receivers/${receiverId}`);
const response = await fetchApi(`${API_URL}/receivers/${receiverId}`);
return dataFormat === "receiver"
? formatReceiver(response)
: formatPaymentReceiver(response, receiverWalletId);
},
enabled: !!receiverId,
});

const formatData = (data: ApiReceiver) => {
return dataFormat === "receiver"
? formatReceiver(data)
: formatPaymentReceiver(data, receiverWalletId);
};

return {
...query,
data: query.data ? (formatData(query.data) as T) : undefined,
data: query.data as T,
};
};
13 changes: 12 additions & 1 deletion src/apiQueries/useUpdateReceiverDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,23 @@ import { fetchApi } from "helpers/fetchApi";
import { sanitizeObject } from "helpers/sanitizeObject";
import { AppError } from "types";

interface ReceiverDetailsUpdate {
email: string;
externalId: string;
dataOfBirth: string;
pin: string;
nationalId: string;
}

export const useUpdateReceiverDetails = (receiverId: string | undefined) => {
const mutation = useMutation({
mutationFn: (fields: { email: string; externalId: string }) => {
mutationFn: (fields: ReceiverDetailsUpdate) => {
const fieldsToSubmit = sanitizeObject({
email: fields.email,
external_id: fields.externalId,
date_of_birth: fields.dataOfBirth,
pin: fields.pin,
national_id: fields.nationalId,
});

if (Object.keys(fieldsToSubmit).length === 0) {
Expand Down
5 changes: 3 additions & 2 deletions src/helpers/formatReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const formatReceiver = (receiver: ApiReceiver): ReceiverDetails => ({
withdrawnAmount: "",
})),
verifications: receiver.verifications.map((v) => ({
verificationField: v.VerificationField,
value: v.HashedValue,
verificationField: v.verification_field,
value: v.hashed_value,
confirmedAt: v.confirmed_at,
})),
});
102 changes: 73 additions & 29 deletions src/pages/ReceiverDetailsEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import {
Card,
Expand All @@ -19,9 +19,15 @@ import { InfoTooltip } from "components/InfoTooltip";
import { LoadingContent } from "components/LoadingContent";
import { ErrorWithExtras } from "components/ErrorWithExtras";

import { ReceiverDetails, ReceiverEditFields } from "types";
import {
ReceiverDetails,
ReceiverEditFields,
ReceiverVerification,
} from "types";
import { useUpdateReceiverDetails } from "apiQueries/useUpdateReceiverDetails";

type VerificationFieldType = "DATE_OF_BIRTH" | "PIN" | "NATIONAL_ID_NUMBER";

export const ReceiverDetailsEdit = () => {
const { id: receiverId } = useParams();

Expand All @@ -31,6 +37,9 @@ export const ReceiverDetailsEdit = () => {
useState<ReceiverEditFields>({
email: "",
externalId: "",
dateOfBirth: "",
pin: "",
nationalId: "",
});

const {
Expand All @@ -52,17 +61,40 @@ export const ReceiverDetailsEdit = () => {
reset,
} = useUpdateReceiverDetails(receiverId);

const getReadyOnlyValue = useCallback(
(field: VerificationFieldType) => {
return (
receiverDetails?.verifications.find(
(v) => v.verificationField === field,
)?.value ?? ""
);
},
[receiverDetails?.verifications],
);

const isVerificationFieldConfirmed = (
field: VerificationFieldType,
): boolean => {
const verification: ReceiverVerification | undefined =
receiverDetails?.verifications.find((v) => v.verificationField === field);
return !verification ? false : verification.confirmedAt !== null;
};

useEffect(() => {
if (isReceiverDetailsSuccess) {
setReceiverEditFields({
email: receiverDetails?.email || "",
externalId: receiverDetails?.orgId || "",
email: receiverDetails?.email ?? "",
externalId: receiverDetails?.orgId ?? "",
dateOfBirth: getReadyOnlyValue("DATE_OF_BIRTH"),
pin: getReadyOnlyValue("PIN"),
nationalId: getReadyOnlyValue("NATIONAL_ID_NUMBER"),
});
}
}, [
isReceiverDetailsSuccess,
receiverDetails?.email,
receiverDetails?.orgId,
getReadyOnlyValue,
]);

useEffect(() => {
Expand All @@ -81,15 +113,6 @@ export const ReceiverDetailsEdit = () => {
};
}, [updateError, reset]);

const getReadyOnlyValue = (
field: "DATE_OF_BIRTH" | "PIN" | "NATIONAL_ID_NUMBER",
) => {
return (
receiverDetails?.verifications.find((v) => v.verificationField === field)
?.value || ""
);
};

const emptyValueIfNotChanged = (newValue: string, oldValue: string) => {
return newValue === oldValue ? "" : newValue;
};
Expand All @@ -99,15 +122,25 @@ export const ReceiverDetailsEdit = () => {
) => {
e.preventDefault();

const { email, externalId } = receiverEditFields;
const { email, externalId, dateOfBirth, pin, nationalId } =
receiverEditFields;

if (receiverId) {
try {
await mutateAsync({
email: emptyValueIfNotChanged(email, receiverDetails?.email || ""),
email: emptyValueIfNotChanged(email, receiverDetails?.email ?? ""),
externalId: emptyValueIfNotChanged(
externalId,
receiverDetails?.orgId || "",
receiverDetails?.orgId ?? "",
),
dataOfBirth: emptyValueIfNotChanged(
dateOfBirth,
getReadyOnlyValue("DATE_OF_BIRTH"),
),
pin: emptyValueIfNotChanged(pin, getReadyOnlyValue("PIN")),
nationalId: emptyValueIfNotChanged(
nationalId,
getReadyOnlyValue("NATIONAL_ID_NUMBER"),
),
});
} catch (e) {
Expand All @@ -119,8 +152,11 @@ export const ReceiverDetailsEdit = () => {
const handleReceiverEditCancel = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setReceiverEditFields({
email: receiverDetails?.email || "",
externalId: receiverDetails?.orgId || "",
email: receiverDetails?.email ?? "",
externalId: receiverDetails?.orgId ?? "",
dateOfBirth: getReadyOnlyValue("DATE_OF_BIRTH"),
pin: getReadyOnlyValue("PIN"),
nationalId: getReadyOnlyValue("NATIONAL_ID_NUMBER"),
});
navigate(`${Routes.RECEIVERS}/${receiverId}`);
};
Expand Down Expand Up @@ -155,7 +191,10 @@ export const ReceiverDetailsEdit = () => {

const isSubmitDisabled =
receiverEditFields.email === receiverDetails?.email &&
receiverEditFields.externalId === receiverDetails.orgId;
receiverEditFields.externalId === receiverDetails.orgId &&
receiverEditFields.dateOfBirth === getReadyOnlyValue("DATE_OF_BIRTH") &&
receiverEditFields.pin === getReadyOnlyValue("PIN") &&
receiverEditFields.nationalId === getReadyOnlyValue("NATIONAL_ID_NUMBER");

return (
<>
Expand Down Expand Up @@ -213,28 +252,33 @@ export const ReceiverDetailsEdit = () => {
onChange={handleDetailsChange}
/>
<Input
id="personalPIN"
name="personalPIN"
id="pin"
name="pin"
label="Personal PIN"
fieldSize="sm"
value={getReadyOnlyValue("PIN")}
disabled
value={receiverEditFields.pin}
onChange={handleDetailsChange}
disabled={isVerificationFieldConfirmed("PIN")}
/>
<Input
id="nationalIDNumber"
name="nationalIDNumber"
id="nationalId"
name="nationalId"
label="National ID Number"
fieldSize="sm"
value={getReadyOnlyValue("NATIONAL_ID_NUMBER")}
disabled
value={receiverEditFields.nationalId}
onChange={handleDetailsChange}
disabled={isVerificationFieldConfirmed(
"NATIONAL_ID_NUMBER",
)}
/>
<Input
id="dateOfBirth"
name="dateOfBirth"
label="Date of Birth"
fieldSize="sm"
value={getReadyOnlyValue("DATE_OF_BIRTH")}
disabled
value={receiverEditFields.dateOfBirth}
onChange={handleDetailsChange}
disabled={isVerificationFieldConfirmed("DATE_OF_BIRTH")}
/>
</div>
</div>
Expand Down
9 changes: 7 additions & 2 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ export type ReceiverWallet = {
export type ReceiverVerification = {
verificationField: string;
value: string;
confirmedAt?: string;
};

export type ReceiverWalletBalance = {
Expand Down Expand Up @@ -407,6 +408,9 @@ export type ReceiverDetails = {
export type ReceiverEditFields = {
email: string;
externalId: string;
dateOfBirth: string;
pin: string;
nationalId: string;
};

// =============================================================================
Expand Down Expand Up @@ -715,8 +719,9 @@ export type ApiReceiverWallet = {
};

export type ApiReceiverVerification = {
VerificationField: string;
HashedValue: string;
verification_field: string;
hashed_value: string;
confirmed_at: string;
};

export type ApiReceiver = {
Expand Down

0 comments on commit 128959f

Please sign in to comment.