From 5df99302c4df6cd1af862ae9775b2516229c6bd3 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 21 Dec 2021 10:46:37 +0000 Subject: [PATCH 01/13] update profile and skills to v5 --- .../Settings/Profile/BasicInfo/index.jsx | 311 ++++++++---------- src/shared/containers/Settings.jsx | 5 + src/shared/reducers/page/settings.js | 8 + 3 files changed, 143 insertions(+), 181 deletions(-) diff --git a/src/shared/components/Settings/Profile/BasicInfo/index.jsx b/src/shared/components/Settings/Profile/BasicInfo/index.jsx index 1818e9d80a..9d127fec49 100644 --- a/src/shared/components/Settings/Profile/BasicInfo/index.jsx +++ b/src/shared/components/Settings/Profile/BasicInfo/index.jsx @@ -38,41 +38,35 @@ export default class BasicInfo extends ConsentComponent { this.onSaveBasicInfo = this.onSaveBasicInfo.bind(this); this.onChange = this.onChange.bind(this); this.onCheckFormValue = this.onCheckFormValue.bind(this); + this.processBasicInfo = this.processBasicInfo.bind(this); const { userTraits } = props; this.state = { inputChanged: false, formInvalid: false, basicInfoTrait: this.loadBasicInfoTraits(userTraits), + profile: {}, personalizationTrait: this.loadPersonalizationTrait(userTraits), - newBasicInfo: { - handle: '', + newProfileInfo: { firstName: null, lastName: null, - gender: '', - ethnicBackground: null, - shortBio: '', - tshirtSize: '', - country: '', - primaryInterestInTopcoder: '', - currentLocation: '', - birthDate: null, - userId: '', + tracks: [], + status: null, + addresses: [], description: '', - otherLangName: null, - status: '', - email: '', - addresses: [{ - streetAddr1: '', - streetAddr2: '', - city: '', - stateCode: '', - zip: '', - type: 'Home', - }], + email: null, homeCountryCode: null, competitionCountryCode: null, - tracks: [], + photoURL: null, + }, + newBasicInfo: { + gender: null, + shortBio: '', + tshirtSize: null, + country: null, + primaryInterestInTopcoder: null, + currentLocation: null, + birthDate: null, }, }; } @@ -80,7 +74,8 @@ export default class BasicInfo extends ConsentComponent { componentDidMount() { const { basicInfoTrait } = this.state; const basicInfo = basicInfoTrait.traits ? basicInfoTrait.traits.data[0] : {}; - this.processBasicInfo(basicInfo); + this.processBasicInfo(basicInfo, this.props.profile); + this.setState({ profile: this.props.profile }); } componentWillReceiveProps(nextProps) { @@ -88,18 +83,22 @@ export default class BasicInfo extends ConsentComponent { const basicInfo = basicInfoTrait.traits ? basicInfoTrait.traits.data[0] : {}; const personalizationTrait = this.loadPersonalizationTrait(nextProps.userTraits); if (basicInfoTrait.updatedAt !== this.loadBasicInfoTraits(this.props.userTraits).updatedAt) { - this.processBasicInfo(basicInfo); + this.processBasicInfo(basicInfo, nextProps.profile); this.setState({ basicInfoTrait, personalizationTrait, inputChanged: false, }); } + if (this.state.profile.updatedAt !== nextProps.profile.updatedAt) { + this.processBasicInfo(basicInfo, nextProps.profile); + this.setState({ profile: nextProps.profile }); + } if (nextProps.lookupData) { const { countries } = nextProps.lookupData; - const { newBasicInfo } = this.state; + const { newBasicInfo, newProfileInfo } = this.state; if (!newBasicInfo.country) { - const code = newBasicInfo.homeCountryCode || newBasicInfo.competitionCountryCode; + const code = newProfileInfo.homeCountryCode || newProfileInfo.competitionCountryCode; const { country } = countries.find(c => c.countryCode === code) || {}; newBasicInfo.country = country; this.setState({ newBasicInfo }); @@ -107,14 +106,14 @@ export default class BasicInfo extends ConsentComponent { } } - onCheckFormValue(newBasicInfo) { + onCheckFormValue(newBasicInfo, newProfileInfo) { let invalid = false; - if (!_.trim(newBasicInfo.firstName).length) { + if (!_.trim(newProfileInfo.firstName).length) { invalid = true; } - if (!_.trim(newBasicInfo.lastName).length) { + if (!_.trim(newProfileInfo.lastName).length) { invalid = true; } @@ -135,7 +134,7 @@ export default class BasicInfo extends ConsentComponent { async onCheckUserTrait(traitId) { const { handle, tokenV3 } = this.props; let isExists = false; - await fetch(`${config.API.V3}/members/${handle}/traits?traitIds=${traitId}`, { + await fetch(`${config.API.V5}/members/${handle}/traits?traitIds=${traitId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -144,8 +143,8 @@ export default class BasicInfo extends ConsentComponent { }) .then(result => result.json()) .then((dataResponse) => { - if (dataResponse.result && dataResponse.result.content.length > 0) { - const trait = dataResponse.result.content[0]; + if (dataResponse.length > 0) { + const trait = dataResponse[0]; if (trait.createdAt) { isExists = true; } @@ -162,8 +161,8 @@ export default class BasicInfo extends ConsentComponent { onHandleSaveBasicInfo(e) { e.preventDefault(); this.setState({ isSaving: true, inputChange: true }); - const { newBasicInfo } = this.state; - if (this.onCheckFormValue(newBasicInfo)) { + const { newBasicInfo, newProfileInfo } = this.state; + if (this.onCheckFormValue(newBasicInfo, newProfileInfo)) { this.setState({ isSaving: false }); return; } @@ -175,12 +174,16 @@ export default class BasicInfo extends ConsentComponent { * @param answer user consent answer value */ async onSaveBasicInfo(answer) { - const { newBasicInfo, basicInfoTrait, personalizationTrait } = this.state; + const { + newBasicInfo, newProfileInfo, basicInfoTrait, personalizationTrait, + } = this.state; const { handle, tokenV3, addUserTrait, updateUserTrait, + updateProfileV5, + profile, } = this.props; try { const parsedDate = moment(newBasicInfo.birthDate).utc(); @@ -201,12 +204,15 @@ export default class BasicInfo extends ConsentComponent { newBasicInfo.tshirtSize = null; } - _.forEach(newBasicInfo.addresses[0], (value, key) => { - newBasicInfo.addresses[0][key] = _.trim(value); + _.forEach(newProfileInfo.addresses[0], (value, key) => { + newProfileInfo.addresses[0][key] = _.trim(value); }); - _.forEach(['currentLocation', 'primaryInterestInTopcoder', 'description'], (key) => { + _.forEach(['currentLocation', 'primaryInterestInTopcoder'], (key) => { newBasicInfo[key] = _.trim(newBasicInfo[key]); }); + _.forEach(['description'], (key) => { + newProfileInfo[key] = _.trim(newProfileInfo[key]); + }); // This is a hack to check if the user has an existing basic_info trait object const exists = await this.onCheckUserTrait('basic_info'); if (exists) { @@ -232,6 +238,25 @@ export default class BasicInfo extends ConsentComponent { } } + const updateProfileData = { + ...newProfileInfo, + }; + updateProfileData.addresses.forEach((address, idx) => { + if (!address.createdAt) { + updateProfileData.addresses[idx].createdAt = new Date(); + } + if (!address.updatedAt) { + updateProfileData.addresses[idx].updatedAt = new Date(); + } + if (!address.createdBy) { + updateProfileData.addresses[idx].createdBy = profile.handle; + } + if (!address.updatedBy) { + updateProfileData.addresses[idx].updatedBy = profile.handle; + } + }); + await updateProfileV5(updateProfileData, handle, tokenV3); + this.setState({ isSaving: false }); } @@ -245,25 +270,31 @@ export default class BasicInfo extends ConsentComponent { } onUpdateInput(e) { - const { newBasicInfo: oldBasicInfo } = this.state; + const { newBasicInfo: oldBasicInfo, newProfileInfo: oldProfileInfo } = this.state; const newBasicInfo = { ...oldBasicInfo }; - switch (e.target.name) { + const newProfileInfo = { ...oldProfileInfo }; + const { name, value } = e.target; + switch (name) { case 'stateCode': case 'zip': case 'city': case 'streetAddr1': case 'streetAddr2': - newBasicInfo.addresses[0][e.target.name] = e.target.value; + newProfileInfo.addresses[0][name] = value; break; case 'firstName': case 'lastName': - newBasicInfo[e.target.name] = e.target.value.replace(/[^a-zA-Z0-9,. -]/g, ''); + newProfileInfo[name] = value.replace(/[^a-zA-Z0-9,. -]/g, ''); break; default: - newBasicInfo[e.target.name] = e.target.value; + if (name in newProfileInfo) { + newProfileInfo[name] = value; + } else if (name in newBasicInfo) { + newBasicInfo[name] = value; + } } - this.setState({ newBasicInfo, inputChanged: true }); + this.setState({ newBasicInfo, newProfileInfo, inputChanged: true }); } onUpdateDate(date) { @@ -292,15 +323,15 @@ export default class BasicInfo extends ConsentComponent { * @param checked check value */ onChange(id, checked) { - const { newBasicInfo } = this.state; + const { newProfileInfo } = this.state; if (checked) { - newBasicInfo.tracks.push(id.toUpperCase()); + newProfileInfo.tracks.push(id.toUpperCase()); } else { - _.remove(newBasicInfo.tracks, track => ( + _.remove(newProfileInfo.tracks, track => ( track.toUpperCase() === id.toUpperCase() )); } - this.setState({ newBasicInfo, inputChanged: true }); + this.setState({ newProfileInfo, inputChanged: true }); } /** @@ -326,109 +357,23 @@ export default class BasicInfo extends ConsentComponent { /** * Process basic info state */ - processBasicInfo = (value) => { - const { newBasicInfo } = this.state; - const { handle, profile } = this.props; - if (_.has(value, 'handle')) { - newBasicInfo.handle = value.handle; - if (_.has(value, 'addresses') && value.addresses.length > 0) { - newBasicInfo.addresses[0].city = value.addresses[0].city ? value.addresses[0].city : ''; - newBasicInfo.addresses[0].stateCode = value.addresses[0].stateCode ? value.addresses[0].stateCode : ''; - newBasicInfo.addresses[0].streetAddr1 = value.addresses[0].streetAddr1 ? value.addresses[0].streetAddr1 : ''; - newBasicInfo.addresses[0].streetAddr2 = value.addresses[0].streetAddr2 ? value.addresses[0].streetAddr2 : ''; - newBasicInfo.addresses[0].zip = value.addresses[0].zip ? value.addresses[0].zip : ''; - if (newBasicInfo.addresses[0].streetAddr1 === '' && _.has(value, 'address')) { - newBasicInfo.addresses[0].streetAddr1 = value.address; + processBasicInfo = (value, profile) => { + const { newBasicInfo, newProfileInfo: profileInfo } = this.state; + if (_.has(profile, 'handle')) { + const newProfileInfo = Object.keys(profileInfo).reduce((acc, key) => { + if (_.has(profileInfo, key)) { + acc[key] = profile[key] || profileInfo[key]; } - } else { - newBasicInfo.addresses[0].city = _.has(value, 'city') ? value.city : ''; - newBasicInfo.addresses[0].stateCode = _.has(value, 'state') ? value.state : ''; - newBasicInfo.addresses[0].streetAddr1 = _.has(value, 'address') ? value.address : ''; - newBasicInfo.addresses[0].zip = _.has(value, 'zipCode') ? value.zipCode : ''; - } - if (_.has(value, 'birthDate')) { - const newDate = moment(value.birthDate).utc(); - if (newDate.isValid()) { - newBasicInfo.birthDate = newDate; + return acc; + }, {}); + const basicInfo = Object.keys(newBasicInfo).reduce((acc, key) => { + if (_.has(value, key)) { + acc[key] = value[key]; + newBasicInfo[key] = value[key]; } - } - if (_.has(value, 'competitionCountryCode')) { - newBasicInfo.competitionCountryCode = value.competitionCountryCode; - } else { - newBasicInfo.competitionCountryCode = profile.competitionCountryCode; - } - if (_.has(value, 'country')) { - newBasicInfo.country = value.country; - } - if (_.has(value, 'currentLocation')) { - newBasicInfo.currentLocation = value.currentLocation; - } - if (_.has(value, 'description')) { - if (_.trim(value.description).length) { - newBasicInfo.description = value.description; - } - } else { - newBasicInfo.description = profile.description ? profile.description : ''; - } - if (_.has(value, 'email')) { - newBasicInfo.email = value.email; - } else { - newBasicInfo.email = profile.email; - } - if (_.has(value, 'firstName')) { - newBasicInfo.firstName = value.firstName; - } else { - newBasicInfo.firstName = ''; - } - if (_.has(value, 'gender')) { - newBasicInfo.gender = value.gender; - } else { - newBasicInfo.gender = profile.gender; - } - if (_.has(value, 'homeCountryCode')) { - newBasicInfo.homeCountryCode = value.homeCountryCode; - } else { - newBasicInfo.homeCountryCode = profile.homeCountryCode; - } - if (_.has(value, 'lastName')) { - newBasicInfo.lastName = value.lastName; - } else { - newBasicInfo.lastName = ''; - } - if (_.has(value, 'primaryInterestInTopcoder')) { - newBasicInfo.primaryInterestInTopcoder = value.primaryInterestInTopcoder; - } - if (_.has(value, 'status')) { - newBasicInfo.status = value.status; - } else { - newBasicInfo.status = profile.status; - } - if (_.has(value, 'tracks')) { - newBasicInfo.tracks = value.tracks ? value.tracks : []; - } else { - newBasicInfo.tracks = profile.tracks ? profile.tracks : []; - } - if (_.has(value, 'tshirtSize')) { - newBasicInfo.tshirtSize = value.tshirtSize; - } - if (_.has(value, 'userId')) { - newBasicInfo.userId = value.userId; - } else { - newBasicInfo.userId = profile.userId; - } - this.setState({ newBasicInfo }); - } else { - newBasicInfo.handle = handle; - newBasicInfo.gender = ''; - newBasicInfo.tshirtSize = ''; - newBasicInfo.userId = profile.userId; - newBasicInfo.status = profile.status; - newBasicInfo.email = profile.email; - newBasicInfo.homeCountryCode = profile.homeCountryCode; - newBasicInfo.competitionCountryCode = profile.competitionCountryCode; - newBasicInfo.tracks = profile.tracks ? profile.tracks : []; - newBasicInfo.description = profile.description ? profile.description : ''; - this.setState({ newBasicInfo }); + return acc; + }, {}); + this.setState({ newBasicInfo: basicInfo, newProfileInfo }); } } @@ -437,21 +382,23 @@ export default class BasicInfo extends ConsentComponent { * @returns {boolean} */ shouldDisableSave() { - const { newBasicInfo, inputChanged } = this.state; + const { newBasicInfo, inputChanged, newProfileInfo } = this.state; + + const { addresses } = newProfileInfo; - const invalid = !_.trim(newBasicInfo.firstName).length - || !_.trim(newBasicInfo.lastName).length + const invalid = !_.trim(newProfileInfo.firstName).length + || !_.trim(newProfileInfo.lastName).length || !_.trim(newBasicInfo.gender).length || !_.trim(newBasicInfo.tshirtSize).length || !_.trim(newBasicInfo.country).length || !_.trim(newBasicInfo.primaryInterestInTopcoder).length || !_.trim(newBasicInfo.currentLocation).length || !_.trim(newBasicInfo.birthDate).length - || (newBasicInfo.addresses.length > 0 && !_.trim(newBasicInfo.addresses[0].city).length) - || (newBasicInfo.addresses.length > 0 && !_.trim(newBasicInfo.addresses[0].stateCode).length) - || (newBasicInfo.addresses.length > 0 && !_.trim(newBasicInfo.addresses[0].zip).length) - || (newBasicInfo.addresses.length > 0 - && !_.trim(newBasicInfo.addresses[0].streetAddr1).length); + || (addresses.length > 0 && !_.trim(addresses[0].city).length) + || (addresses.length > 0 && !_.trim(addresses[0].stateCode).length) + || (addresses.length > 0 && !_.trim(addresses[0].zip).length) + || (addresses.length > 0 + && !_.trim(addresses[0].streetAddr1).length); // Invalid value, can not save if (invalid) { return true; @@ -464,6 +411,7 @@ export default class BasicInfo extends ConsentComponent { render() { const { newBasicInfo, + newProfileInfo, inputChanged, } = this.state; @@ -504,8 +452,8 @@ export default class BasicInfo extends ConsentComponent {
* Required - - + +
@@ -517,8 +465,8 @@ export default class BasicInfo extends ConsentComponent {
* Required - - + +
@@ -550,7 +498,7 @@ export default class BasicInfo extends ConsentComponent {
- 0 ? newBasicInfo.addresses[0].streetAddr1 : ''}`} maxLength="64" required /> + 0 ? newProfileInfo.addresses[0].streetAddr1 : ''}`} maxLength="64" required />
@@ -561,7 +509,7 @@ export default class BasicInfo extends ConsentComponent {
- 0 ? newBasicInfo.addresses[0].streetAddr2 : ''}`} maxLength="64" /> + 0 ? newProfileInfo.addresses[0].streetAddr2 : ''}`} maxLength="64" />
@@ -572,7 +520,7 @@ export default class BasicInfo extends ConsentComponent {
- 0 ? newBasicInfo.addresses[0].city : ''}`} maxLength="64" required /> + 0 ? newProfileInfo.addresses[0].city : ''}`} maxLength="64" required />
@@ -583,7 +531,7 @@ export default class BasicInfo extends ConsentComponent {
- 0 ? newBasicInfo.addresses[0].stateCode : ''}`} maxLength="64" required /> + 0 ? newProfileInfo.addresses[0].stateCode : ''}`} maxLength="64" required />
@@ -594,7 +542,7 @@ export default class BasicInfo extends ConsentComponent {
- 0 ? newBasicInfo.addresses[0].zip : ''}`} maxLength="64" required /> + 0 ? newProfileInfo.addresses[0].zip : ''}`} maxLength="64" required />
@@ -703,10 +651,10 @@ export default class BasicInfo extends ConsentComponent {
- {newBasicInfo.description.length}/240 + {newProfileInfo.description.length}/240
-