>(({ className, ...props }, ref) => (
- ;
+}
+
+export const AccountRegistrationStatus = ({
+ methods,
+ settings,
+}: StatusProps) => {
+ const { t } = useTranslation();
+
+ const { setActiveStep } = useSignUpContext();
+ const { trigger } = methods;
+
+ const { data: registrationStatus, isError } = useRegistrationStatus(
+ settings.response.configs["status.request.limit"],
+ settings.response.configs["status.request.delay"]
+ );
+
+ useEffect(() => {
+ if (isError) {
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ }
+
+ if (
+ registrationStatus?.response.status ===
+ RegistrationWithFailedStatus.FAILED
+ ) {
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ }
+ if (
+ registrationStatus?.response.status ===
+ RegistrationWithFailedStatus.COMPLETED
+ ) {
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ }
+ }, [registrationStatus, settings.response.configs, isError, setActiveStep]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {t("setup_progress")}
+
+
+ {t("setup_progress_wait")}
+
+
+
+
+
+ );
+};
diff --git a/signup-ui/src/pages/SignUpPage/AccountRegistrationStatus/index.ts b/signup-ui/src/pages/SignUpPage/AccountRegistrationStatus/index.ts
new file mode 100644
index 00000000..f7496287
--- /dev/null
+++ b/signup-ui/src/pages/SignUpPage/AccountRegistrationStatus/index.ts
@@ -0,0 +1 @@
+export { AccountRegistrationStatus as default } from "./AccountRegistrationStatus";
diff --git a/signup-ui/src/pages/SignUpPage/AccountSetup/AccountSetup.tsx b/signup-ui/src/pages/SignUpPage/AccountSetup/AccountSetup.tsx
index 2af4abf8..87d5559a 100644
--- a/signup-ui/src/pages/SignUpPage/AccountSetup/AccountSetup.tsx
+++ b/signup-ui/src/pages/SignUpPage/AccountSetup/AccountSetup.tsx
@@ -23,12 +23,11 @@ import {
StepHeader,
StepTitle,
} from "~components/ui/step";
-import { RegisterRequestDto } from "~typings/types";
+import { RegistrationRequestDto, RegistrationStatus } from "~typings/types";
import { useRegister } from "../mutations";
import { useSignUpContext } from "../SignUpContext";
import { SignUpForm } from "../SignUpPage";
-import { AccountSetupProgress } from "./components/AccountSetupProgress";
import { TermsAndPrivacyModal } from "./components/TermsAndPrivacyModal";
interface AccountSetupProps {
@@ -50,7 +49,7 @@ export const AccountSetup = ({ methods }: AccountSetupProps) => {
const isStepValid = await trigger();
if (isStepValid) {
- const registerRequestDto: RegisterRequestDto = {
+ const RegistrationRequestDto: RegistrationRequestDto = {
requestTime: new Date().toISOString(),
request: {
username: `855${getValues("phone")}`,
@@ -66,10 +65,17 @@ export const AccountSetup = ({ methods }: AccountSetupProps) => {
},
};
- return registerMutation.mutate(registerRequestDto, {
- onSuccess: ({ errors }) => {
+ return registerMutation.mutate(RegistrationRequestDto, {
+ onSuccess: ({ response, errors }) => {
if (!errors) {
- setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ if (response.status === RegistrationStatus.PENDING) {
+ // direct user to status step when the account creation is pending
+ setActiveStep((prevActiveStep) => prevActiveStep + 1);
+ }
+ if (response.status === RegistrationStatus.COMPLETED) {
+ // direct user to the final (success) step when user successfully create the account
+ setActiveStep((prevActiveStep) => prevActiveStep + 2);
+ }
}
},
});
@@ -96,162 +102,167 @@ export const AccountSetup = ({ methods }: AccountSetupProps) => {
}
return (
- <>
- {registerMutation.isLoading && }
- {!registerMutation.isLoading && (
-
-
- Setup Account
-
- Please enter the requested details to complete your registration.
-
-
-
-
-
+
+
);
};
diff --git a/signup-ui/src/pages/SignUpPage/Otp/OTP.tsx b/signup-ui/src/pages/SignUpPage/Otp/OTP.tsx
index 1400fc0f..55044aef 100644
--- a/signup-ui/src/pages/SignUpPage/Otp/OTP.tsx
+++ b/signup-ui/src/pages/SignUpPage/Otp/OTP.tsx
@@ -32,24 +32,24 @@ import { convertTime } from "~utils/timer";
import {
Error,
GenerateChallengeRequestDto,
+ SettingsDto,
VerifyChallengeRequestDto,
} from "~typings/types";
import { useGenerateChallenge, useVerifyChallenge } from "../mutations";
-import { useSettings } from "../queries";
import { useSignUpContext } from "../SignUpContext";
import { SignUpForm } from "../SignUpPage";
import { ResendAttempt } from "./components/ResendAttempt";
import { useTimer } from "./hooks/useTimer";
interface OTPProps {
+ settings: SettingsDto;
methods: UseFormReturn;
}
-export const OTP = ({ methods }: OTPProps) => {
+export const OTP = ({ methods, settings }: OTPProps) => {
const { t } = useTranslation();
- const { data: settings, isLoading } = useSettings();
const [hasError, setHasError] = useState(false);
const pinInputRef = useRef(null);
const { control, getValues, setValue } = useFormContext();
@@ -65,11 +65,9 @@ export const OTP = ({ methods }: OTPProps) => {
const { hash: fromSingInHash } = useLocation();
useEffect(() => {
- if (settings?.response.configs) {
- setTimeLeft(settings.response.configs["resend.delay"]);
- setResendAttempts(settings.response.configs["resend.attempts"]);
- }
- }, [settings?.response.configs, setTimeLeft]);
+ setTimeLeft(settings.response.configs["resend.delay"]);
+ setResendAttempts(settings.response.configs["resend.attempts"]);
+ }, [settings.response.configs, setTimeLeft]);
useEffect(() => {
if (!hasError) return;
@@ -219,9 +217,9 @@ export const OTP = ({ methods }: OTPProps) => {
className="absolute left-0 ml-4 cursor-pointer"
onClick={handleBack}
/>
-
+
{t("otp_header")}
-
+
@@ -301,7 +299,7 @@ export const OTP = ({ methods }: OTPProps) => {
className="w-full p-4 font-semibold"
onClick={handleContinue}
disabled={!formState.isValid}
- isLoading={verifyChallengeMutation.isLoading}
+ isLoading={verifyChallengeMutation.isPending}
>
{t("continue")}
diff --git a/signup-ui/src/pages/SignUpPage/Otp/mutations.ts b/signup-ui/src/pages/SignUpPage/Otp/mutations.ts
deleted file mode 100644
index 1eb0f3cf..00000000
--- a/signup-ui/src/pages/SignUpPage/Otp/mutations.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// import { useMutation } from "react-query";
-
-// export const useGenerateChallenge = () => {
-
-// const handleSuccess = () => {};
-// // const handleError = () => {};
-
-// const generateChallengeMutation = useMutation(
-// ({
-// identifier,
-// captchaToken,
-// }: {
-// identifier: string;
-// captchaToken: string;
-// }) => generateChallengeMutation(identifier, captchaToken),
-// {
-// onSuccess: handleSuccess,
-// // onError: handleError,
-// }
-// );
-
-// return { generateChallengeMutation };
-// };
diff --git a/signup-ui/src/pages/SignUpPage/Phone/Phone.tsx b/signup-ui/src/pages/SignUpPage/Phone/Phone.tsx
index 6db3a643..e2509351 100644
--- a/signup-ui/src/pages/SignUpPage/Phone/Phone.tsx
+++ b/signup-ui/src/pages/SignUpPage/Phone/Phone.tsx
@@ -162,7 +162,7 @@ export const Phone = ({ methods }: PhoneProps) => {
diff --git a/signup-ui/src/pages/SignUpPage/RegistrationStatus/RegistrationStatus.tsx b/signup-ui/src/pages/SignUpPage/RegistrationStatus/RegistrationStatus.tsx
index 810075b0..58741c99 100644
--- a/signup-ui/src/pages/SignUpPage/RegistrationStatus/RegistrationStatus.tsx
+++ b/signup-ui/src/pages/SignUpPage/RegistrationStatus/RegistrationStatus.tsx
@@ -10,7 +10,7 @@ export const RegistrationStatus = () => {
const handleAction = () => {
window.location.href = getSignInRedirectURL(fromSingInHash);
- }
+ };
return (
{
case 0:
return ;
case 1:
- return ;
+ return ;
case 2:
return ;
case 3:
return ;
+ case 4:
+ return (
+
+ );
default:
return "unknown step";
}
diff --git a/signup-ui/src/pages/SignUpPage/mutations.ts b/signup-ui/src/pages/SignUpPage/mutations.ts
index e7b7678c..b945e5d6 100644
--- a/signup-ui/src/pages/SignUpPage/mutations.ts
+++ b/signup-ui/src/pages/SignUpPage/mutations.ts
@@ -1,11 +1,11 @@
-import { useMutation } from "react-query";
+import { useMutation } from "@tanstack/react-query";
import { ApiError } from "~typings/core";
import {
GenerateChallengeRequestDto,
GenerateChallengeResponseDto,
- RegisterRequestDto,
- RegisterResponseDto,
+ RegistrationRequestDto,
+ RegistrationResponseDto,
VerifyChallengeRequestDto,
VerifyChallengeResponseDto,
} from "~typings/types";
@@ -17,9 +17,10 @@ export const useGenerateChallenge = () => {
GenerateChallengeResponseDto,
ApiError,
GenerateChallengeRequestDto
- >((generateChallengeRequestDto: GenerateChallengeRequestDto) =>
- generateChallenge(generateChallengeRequestDto)
- );
+ >({
+ mutationFn: (generateChallengeRequestDto: GenerateChallengeRequestDto) =>
+ generateChallenge(generateChallengeRequestDto),
+ });
return { generateChallengeMutation };
};
@@ -29,19 +30,23 @@ export const useVerifyChallenge = () => {
VerifyChallengeResponseDto,
ApiError,
VerifyChallengeRequestDto
- >((verifyChallengeRequestDto: VerifyChallengeRequestDto) =>
- verifyChallenge(verifyChallengeRequestDto)
- );
+ >({
+ mutationFn: (verifyChallengeRequestDto: VerifyChallengeRequestDto) =>
+ verifyChallenge(verifyChallengeRequestDto),
+ });
return { verifyChallengeMutation };
};
export const useRegister = () => {
const registerMutation = useMutation<
- RegisterResponseDto,
+ RegistrationResponseDto,
ApiError,
- RegisterRequestDto
- >((registerRequestDto: RegisterRequestDto) => register(registerRequestDto));
+ RegistrationRequestDto
+ >({
+ mutationFn: (RegistrationRequestDto: RegistrationRequestDto) =>
+ register(RegistrationRequestDto),
+ });
return { registerMutation };
};
diff --git a/signup-ui/src/pages/SignUpPage/queries.ts b/signup-ui/src/pages/SignUpPage/queries.ts
index 084d4468..c71d3859 100644
--- a/signup-ui/src/pages/SignUpPage/queries.ts
+++ b/signup-ui/src/pages/SignUpPage/queries.ts
@@ -1,29 +1,30 @@
-import { useQuery, UseQueryResult } from "react-query";
+import { useQuery, UseQueryResult } from "@tanstack/react-query";
-import { RegisterStatusResponseDto, SettingsDto } from "~typings/types";
+import { RegistrationStatusResponseDto, SettingsDto } from "~typings/types";
-import { getRegisterStatus, getSettings } from "./service";
+import { getRegistrationStatus, getSettings } from "./service";
export const keys = {
settings: ["settings"] as const,
- registerStatus: ["registerStatus"] as const,
+ registrationStatus: ["registrationStatus"] as const,
};
export const useSettings = (): UseQueryResult => {
- return useQuery(keys.settings, () => getSettings(), {
+ return useQuery({
+ queryKey: keys.settings,
+ queryFn: () => getSettings(),
staleTime: Infinity,
});
};
-export const useRegisterStatus = (): UseQueryResult<
- RegisterStatusResponseDto,
- unknown
-> => {
- return useQuery(
- keys.registerStatus,
- () => getRegisterStatus(),
- {
- staleTime: Infinity,
- }
- );
+export const useRegistrationStatus = (
+ statusRequestAttempt: number,
+ statusRequestDelay: number
+): UseQueryResult => {
+ return useQuery({
+ queryKey: keys.registrationStatus,
+ queryFn: () => getRegistrationStatus(),
+ retry: statusRequestAttempt,
+ retryDelay: statusRequestDelay * 1000,
+ });
};
diff --git a/signup-ui/src/pages/SignUpPage/service.ts b/signup-ui/src/pages/SignUpPage/service.ts
index 49324ab5..c2a3977e 100644
--- a/signup-ui/src/pages/SignUpPage/service.ts
+++ b/signup-ui/src/pages/SignUpPage/service.ts
@@ -1,8 +1,9 @@
import { ApiService } from "~services/api.service";
import {
GenerateChallengeRequestDto,
- RegisterRequestDto,
- RegisterStatusResponseDto,
+ RegistrationRequestDto,
+ RegistrationStatusResponseDto,
+ RegistrationWithFailedStatus,
SettingsDto,
VerifyChallengeRequestDto,
} from "~typings/types";
@@ -29,15 +30,22 @@ export const verifyChallenge = async (
).then(({ data }) => data);
};
-export const register = async (register: RegisterRequestDto) => {
+export const register = async (register: RegistrationRequestDto) => {
return ApiService.post("/registration/register", register).then(
({ data }) => data
);
};
-export const getRegisterStatus =
- async (): Promise => {
- return ApiService.get(
+export const getRegistrationStatus =
+ async (): Promise => {
+ return ApiService.get(
"/registration/status"
- ).then(({ data }) => data);
+ ).then(({ data }) => {
+ // treat PENDING as an error so that react-query will auto retry
+ if (data.response.status === RegistrationWithFailedStatus.PENDING) {
+ throw new Error("Status pending");
+ }
+
+ return data;
+ });
};
diff --git a/signup-ui/src/templates/ResponsePageTemplate/StatusPageTemplate.tsx b/signup-ui/src/templates/ResponsePageTemplate/StatusPageTemplate.tsx
index 6826e04a..3088ade0 100644
--- a/signup-ui/src/templates/ResponsePageTemplate/StatusPageTemplate.tsx
+++ b/signup-ui/src/templates/ResponsePageTemplate/StatusPageTemplate.tsx
@@ -48,27 +48,3 @@ export const StatusPageTemplate = ({
);
};
-
-{
- /*
-
-
- {status === "success" ?
:
}
-
-
{title}
- {subtitle && (
-
{subtitle}
- )}
-
{description}
-
-
-
-
-
*/
-}
diff --git a/signup-ui/src/typings/types.ts b/signup-ui/src/typings/types.ts
index 59016fc8..911788b4 100644
--- a/signup-ui/src/typings/types.ts
+++ b/signup-ui/src/typings/types.ts
@@ -49,7 +49,6 @@ export interface Error {
export interface BaseResponseDto {
responseTime: string;
- response: any;
errors: Error[] | null;
}
@@ -70,6 +69,8 @@ interface SettingsConfig {
"fullname.pattern": string;
"status.deferred.response.timeout": number;
"status.check.limit": number;
+ "status.request.limit": number;
+ "status.request.delay": number;
}
export interface Settings {
@@ -120,7 +121,7 @@ export interface UserInfo {
preferredLang: string;
}
-export type RegisterRequestDto = BaseRequestDto & {
+export type RegistrationRequestDto = BaseRequestDto & {
request: {
username: string;
password: string;
@@ -129,14 +130,25 @@ export type RegisterRequestDto = BaseRequestDto & {
};
};
-export type RegisterResponseDto = BaseResponseDto & {
+export enum RegistrationStatus {
+ PENDING = "PENDING",
+ COMPLETED = "COMPLETED",
+}
+
+export type RegistrationResponseDto = BaseResponseDto & {
response: {
- status: string;
+ status: RegistrationStatus;
};
};
-export type RegisterStatusResponseDto = BaseResponseDto & {
+export enum RegistrationWithFailedStatus {
+ PENDING = "PENDING",
+ COMPLETED = "COMPLETED",
+ FAILED = "FAILED",
+}
+
+export type RegistrationStatusResponseDto = BaseResponseDto & {
response: {
- status: string;
+ status: RegistrationWithFailedStatus;
};
};