feat: implemented restricted countires

This commit is contained in:
sundasnoreen12
2025-02-22 15:34:54 +05:00
parent 30980242a3
commit ffe306b60f
9 changed files with 72 additions and 6 deletions

View File

@@ -13,9 +13,15 @@ export const getThirdPartyAuthContextBegin = () => ({
type: THIRD_PARTY_AUTH_CONTEXT.BEGIN,
});
export const getThirdPartyAuthContextSuccess = (fieldDescriptions, optionalFields, thirdPartyAuthContext) => ({
export const getThirdPartyAuthContextSuccess = (
fieldDescriptions,
optionalFields,
thirdPartyAuthContext,
countries) => ({
type: THIRD_PARTY_AUTH_CONTEXT.SUCCESS,
payload: { fieldDescriptions, optionalFields, thirdPartyAuthContext },
payload: {
fieldDescriptions, optionalFields, thirdPartyAuthContext, countries,
},
});
export const getThirdPartyAuthContextFailure = () => ({

View File

@@ -0,0 +1,3 @@
export const FIELD_LABELS = {
COUNTRY: 'country',
};

View File

@@ -35,6 +35,7 @@ const reducer = (state = defaultState, action = {}) => {
optionalFields: action.payload.optionalFields,
thirdPartyAuthContext: action.payload.thirdPartyAuthContext,
thirdPartyAuthApiStatus: COMPLETE_STATE,
countries: action.payload.countries,
};
}
case THIRD_PARTY_AUTH_CONTEXT.FAILURE:

View File

@@ -8,6 +8,7 @@ import {
THIRD_PARTY_AUTH_CONTEXT,
} from './actions';
import {
getCountryList,
getThirdPartyAuthContext,
} from './service';
import { setCountryFromThirdPartyAuthContext } from '../../register/data/actions';
@@ -19,8 +20,10 @@ export function* fetchThirdPartyAuthContext(action) {
fieldDescriptions, optionalFields, thirdPartyAuthContext,
} = yield call(getThirdPartyAuthContext, action.payload.urlParams);
const countries = (yield call(getCountryList)) || [];
yield put(setCountryFromThirdPartyAuthContext(thirdPartyAuthContext.countryCode));
yield put(getThirdPartyAuthContextSuccess(fieldDescriptions, optionalFields, thirdPartyAuthContext));
yield put(getThirdPartyAuthContextSuccess(fieldDescriptions, optionalFields, thirdPartyAuthContext, countries));
} catch (e) {
yield put(getThirdPartyAuthContextFailure());
logError(e);

View File

@@ -1,5 +1,8 @@
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { logError } from '@edx/frontend-platform/logging';
import { FIELD_LABELS } from './constants';
// eslint-disable-next-line import/prefer-default-export
export async function getThirdPartyAuthContext(urlParams) {
@@ -23,3 +26,28 @@ export async function getThirdPartyAuthContext(urlParams) {
thirdPartyAuthContext: data.contextData || {},
};
}
function extractCountryList(data) {
return data?.fields
.find(({ name }) => name === FIELD_LABELS.COUNTRY)
?.options?.map(({ value, name }) => ({ code: value, name })) || [];
}
export async function getCountryList() {
try {
const requestConfig = {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
isPublic: true,
};
const { data } = await getAuthenticatedHttpClient()
.get(
`${getConfig().LMS_BASE_URL}/user_api/v1/account/registration/`,
requestConfig,
);
return extractCountryList(data);
} catch (e) {
logError(e);
return [];
}
}

View File

@@ -8,6 +8,11 @@ import * as api from '../service';
const { loggingService } = initializeMockLogging();
jest.mock('../service', () => ({
getCountryList: jest.fn(),
getThirdPartyAuthContext: jest.fn(),
}));
describe('fetchThirdPartyAuthContext', () => {
const params = {
payload: { urlParams: {} },
@@ -31,6 +36,7 @@ describe('fetchThirdPartyAuthContext', () => {
thirdPartyAuthContext: data,
fieldDescriptions: {},
optionalFields: {},
countries: [],
}));
const dispatched = [];
@@ -44,7 +50,7 @@ describe('fetchThirdPartyAuthContext', () => {
expect(dispatched).toEqual([
actions.getThirdPartyAuthContextBegin(),
setCountryFromThirdPartyAuthContext(),
actions.getThirdPartyAuthContextSuccess({}, {}, data),
actions.getThirdPartyAuthContextSuccess({}, {}, data, []),
]);
getThirdPartyAuthContext.mockClear();
});

View File

@@ -95,6 +95,7 @@ const RegistrationPage = (props) => {
const [errors, setErrors] = useState({ ...backedUpFormData.errors });
const [errorCode, setErrorCode] = useState({ type: '', count: 0 });
const [formStartTime, setFormStartTime] = useState(null);
const countries = useSelector(state => state.commonComponents.countries);
// temporary error state for embedded experience because we don't want to show errors on blur
const [temporaryErrors, setTemporaryErrors] = useState({ ...backedUpFormData.errors });
@@ -358,6 +359,7 @@ const RegistrationPage = (props) => {
setFormFields={setConfigurableFormFields}
autoSubmitRegisterForm={autoSubmitRegForm}
fieldDescriptions={fieldDescriptions}
countries={countries}
/>
<StatefulButton
id="register-user"

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from 'react';
import React, { useCallback, useEffect, useMemo } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { getCountryList, getLocale, useIntl } from '@edx/frontend-platform/i18n';
@@ -31,13 +31,13 @@ const ConfigurableRegistrationForm = (props) => {
setFieldErrors,
setFormFields,
autoSubmitRegistrationForm,
countries,
} = props;
/** The reason for adding the entry 'United States' is that Chrome browser aut-fill the form with the 'Unites
States' instead of 'United States of America' which does not exist in country dropdown list and gets the user
confused and unable to create an account. So we added the United States entry in the dropdown list.
*/
const countryList = useMemo(() => getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }]), []);
let showTermsOfServiceAndHonorCode = false;
let showCountryField = false;
@@ -70,6 +70,17 @@ const ConfigurableRegistrationForm = (props) => {
}
}, [autoSubmitRegistrationForm]); // eslint-disable-line react-hooks/exhaustive-deps
const removeDisabledCountries = useCallback((countryList) => {
if (!countries.length) {
return countryList;
}
const allowedCountries = new Set(countries.map(({ code }) => code));
return countryList.filter(({ code }) => allowedCountries.has(code));
}, [countries]);
const countryList = useMemo(() => removeDisabledCountries(
getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }])), [removeDisabledCountries]);
const handleErrorChange = (fieldName, error) => {
if (fieldName) {
setFieldErrors(prevErrors => ({
@@ -231,11 +242,16 @@ ConfigurableRegistrationForm.propTypes = {
setFieldErrors: PropTypes.func.isRequired,
setFormFields: PropTypes.func.isRequired,
autoSubmitRegistrationForm: PropTypes.bool,
countries: PropTypes.arrayOf(PropTypes.shape({
code: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
})),
};
ConfigurableRegistrationForm.defaultProps = {
fieldDescriptions: {},
autoSubmitRegistrationForm: false,
countries: [],
};
export default ConfigurableRegistrationForm;

View File

@@ -185,6 +185,7 @@ describe('ConfigurableRegistrationForm', () => {
},
},
autoSubmitRegistrationForm: true,
countries: [{ code: 'AX', name: 'Åland Islands' }, { code: 'AL', name: 'Albania' }],
};
render(routerWrapper(reduxWrapper(