feat: add api to connect user completion form to backend
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||
import { LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||
@@ -12,7 +12,6 @@ interface DateOfBirthProps {
|
||||
export function DateOfBirth({ value, onChange }: DateOfBirthProps) {
|
||||
const { t, i18n } = useTranslation('completionForm');
|
||||
const isFarsi = i18n.language === 'fa' || i18n.language === 'fa-IR';
|
||||
// const [birthDate, setBirthDate] = useState<Date | null>(null);
|
||||
|
||||
const Adapter = useMemo(() => {
|
||||
return isFarsi ? AdapterDateFnsJalali : AdapterDateFns;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Logo from '@/components/Logo';
|
||||
import { PersonalInfoFields } from './PersonalInfoFields';
|
||||
import { PasswordSection } from './PasswordSection';
|
||||
import { EmailSection } from './EmailSection';
|
||||
import { SubmitSection } from './SubmitSection';
|
||||
import Logo from '@/components/Logo';
|
||||
import apiClient from '@/lib/apiClient';
|
||||
import { loginWithPassword } from '@/lib/authToken';
|
||||
|
||||
export function UserCompletionForm() {
|
||||
const { t } = useTranslation('completionForm');
|
||||
const USERNAME = '+989353989651';
|
||||
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
@@ -61,11 +63,9 @@ export function UserCompletionForm() {
|
||||
}, [password, validPassword]);
|
||||
|
||||
useEffect(() => {
|
||||
let timer: ReturnType<typeof setInterval>;
|
||||
let timer: NodeJS.Timeout;
|
||||
if (buttonState === 'counting' && countdown > 0) {
|
||||
timer = setInterval(() => {
|
||||
setCountdown((prev) => prev - 1);
|
||||
}, 1000);
|
||||
timer = setInterval(() => setCountdown((prev) => prev - 1), 1000);
|
||||
}
|
||||
if (countdown === 0) {
|
||||
setButtonState('default');
|
||||
@@ -74,7 +74,7 @@ export function UserCompletionForm() {
|
||||
}, [buttonState, countdown]);
|
||||
|
||||
const toPersianDigits = (str: string) =>
|
||||
str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]);
|
||||
str.replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d, 10)]);
|
||||
|
||||
const getButtonLabel = () => {
|
||||
if (buttonState === 'sent') return t('completion.sent');
|
||||
@@ -108,40 +108,39 @@ export function UserCompletionForm() {
|
||||
setCodeSent(false);
|
||||
setEmailVerified(false);
|
||||
};
|
||||
const STATICTOKEN = 'Bearer abcdef1234567890';
|
||||
|
||||
const handleSubmit = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setSuccess(false);
|
||||
|
||||
try {
|
||||
await loginWithPassword(USERNAME, password);
|
||||
|
||||
const { data } = await apiClient.post<{
|
||||
success: boolean;
|
||||
errorCode: number;
|
||||
message: string;
|
||||
validations: { property: string; message: string }[];
|
||||
}>(
|
||||
'/User/CompleteUserInformation',
|
||||
{
|
||||
firstName,
|
||||
lastName,
|
||||
gender: sex === 'female' ? 2 : 1,
|
||||
nationalId,
|
||||
savePassword: showPasswordSection,
|
||||
password: showPasswordSection ? password : undefined,
|
||||
saveEmail: showEmail,
|
||||
email: showEmail ? email : undefined,
|
||||
birthDate,
|
||||
},
|
||||
{ headers: { Authorization: STATICTOKEN } },
|
||||
);
|
||||
}>('/User/CompleteUserInformation', {
|
||||
firstName,
|
||||
lastName,
|
||||
gender: sex === 'female' ? 2 : 1,
|
||||
nationalId,
|
||||
savePassword: showPasswordSection,
|
||||
password: showPasswordSection ? password : undefined,
|
||||
saveEmail: showEmail,
|
||||
email: showEmail ? email : undefined,
|
||||
birthDate,
|
||||
});
|
||||
|
||||
if (data.success) {
|
||||
setSuccess(true);
|
||||
} else {
|
||||
setError(data.message || 'Validation error');
|
||||
}
|
||||
} catch (err) {
|
||||
setError((err as Error).message || 'An error occurred');
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'An error occurred');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -152,8 +151,8 @@ export function UserCompletionForm() {
|
||||
sx={{
|
||||
backgroundColor: 'background.default',
|
||||
minHeight: '100vh',
|
||||
flexDirection: 'column',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
p: { xs: 1, sm: 2, md: 3 },
|
||||
@@ -165,7 +164,7 @@ export function UserCompletionForm() {
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
maxWidth: '730px',
|
||||
maxWidth: 730,
|
||||
backgroundColor: 'background.paper',
|
||||
border: '1px solid #ccc',
|
||||
display: 'flex',
|
||||
@@ -175,14 +174,7 @@ export function UserCompletionForm() {
|
||||
py: { xs: 3, sm: 4 },
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
gap: 1,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
<Typography variant="h5" color="text.primary">
|
||||
{t('completion.title')}
|
||||
</Typography>
|
||||
@@ -190,6 +182,7 @@ export function UserCompletionForm() {
|
||||
{t('completion.description')}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<PersonalInfoFields
|
||||
firstName={firstName}
|
||||
setFirstName={setFirstName}
|
||||
@@ -204,6 +197,7 @@ export function UserCompletionForm() {
|
||||
country={country}
|
||||
setCountry={setCountry}
|
||||
/>
|
||||
|
||||
<PasswordSection
|
||||
showPasswordSection={showPasswordSection}
|
||||
setShowPasswordSection={setShowPasswordSection}
|
||||
@@ -219,6 +213,7 @@ export function UserCompletionForm() {
|
||||
validPassword={validPassword}
|
||||
showValidations={showPasswordValidations}
|
||||
/>
|
||||
|
||||
<EmailSection
|
||||
showEmail={showEmail}
|
||||
setShowEmail={setShowEmail}
|
||||
@@ -236,6 +231,7 @@ export function UserCompletionForm() {
|
||||
isVerifyingCode={isVerifyingCode}
|
||||
handleEditEmail={handleEditEmail}
|
||||
/>
|
||||
|
||||
<SubmitSection
|
||||
onSubmit={handleSubmit}
|
||||
loading={loading}
|
||||
|
||||
34
src/lib/authToken.ts
Normal file
34
src/lib/authToken.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// src/lib/authService.ts
|
||||
import axios from 'axios';
|
||||
|
||||
export interface TokenResponse {
|
||||
access_token: string;
|
||||
expires_in: number;
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
const authClient = axios.create({
|
||||
baseURL: 'https://account.business-harmony.com',
|
||||
timeout: 10000,
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
|
||||
export async function loginWithPassword(
|
||||
username: string,
|
||||
password: string,
|
||||
): Promise<TokenResponse> {
|
||||
const body = new URLSearchParams();
|
||||
body.set('grant_type', 'password');
|
||||
body.set('username', username);
|
||||
body.set('password', password);
|
||||
body.set('client_id', 'harmony_identity');
|
||||
body.set('scope', 'openid harmony_identity profile offline_access');
|
||||
|
||||
const { data } = await authClient.post<TokenResponse>(
|
||||
'/connect/token',
|
||||
body.toString(),
|
||||
);
|
||||
|
||||
localStorage.setItem('authToken', data.access_token);
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user