diff --git a/packages/react-components/src/templates/ContactInfoModal.tsx b/packages/react-components/src/templates/ContactInfoModal.tsx index 32b60173c8..4e4d60a955 100644 --- a/packages/react-components/src/templates/ContactInfoModal.tsx +++ b/packages/react-components/src/templates/ContactInfoModal.tsx @@ -1,9 +1,5 @@ import { UserPatchRequest, UserResponse } from '@asap-hub/model'; -import { - urlExpression, - USER_SOCIAL_NOT_URL, - USER_SOCIAL_RESEARCHER_ID, -} from '@asap-hub/validation'; +import { urlExpression, USER_SOCIAL_RESEARCHER_ID } from '@asap-hub/validation'; import { css } from '@emotion/react'; import { FunctionComponent, useState } from 'react'; @@ -23,7 +19,7 @@ import { mailToSupport } from '../mail'; import { LabeledTextField } from '../molecules'; import { EditUserModal } from '../organisms'; import { rem } from '../pixels'; -import { noop } from '../utils'; +import { formatUserSocial, noop } from '../utils'; const iconStyles = css({ width: 24, @@ -93,12 +89,14 @@ const ContactInfoModal: React.FC = ({ onSave({ contactEmail: newEmail || undefined, social: { - twitter: newTwitter || undefined, + twitter: formatUserSocial(newTwitter, 'twitter') || undefined, researcherId: newResearcherId || undefined, - researchGate: newResearchGate || undefined, - github: newGithub || undefined, - googleScholar: newGoogleScholar || undefined, - linkedIn: newLinkedIn || undefined, + researchGate: + formatUserSocial(newResearchGate, 'researchGate') || undefined, + github: formatUserSocial(newGithub, 'github') || undefined, + googleScholar: + formatUserSocial(newGoogleScholar, 'googleScholar') || undefined, + linkedIn: formatUserSocial(newLinkedIn, 'linkedIn') || undefined, website1: newWebsite1 || undefined, website2: newWebsite2 || undefined, }, @@ -188,68 +186,52 @@ const ContactInfoModal: React.FC = ({ 'Please enter a valid Twitter handle'} + description="Type your X (formerly Twitter) profile URL." onChange={setNewTwitter} value={newTwitter} enabled={!isSaving} labelIndicator={wrapIcon(XIcon)} - placeholder="Username" + placeholder="https://twitter.com/yourprofilename" /> 'Please enter a valid Github username'} + description="Type your Github profile URL." onChange={setNewGithub} value={newGithub} enabled={!isSaving} labelIndicator={wrapIcon(GithubIcon, true)} - placeholder="Username" + placeholder="https://github.com/yourprofilename" /> - 'Please enter a valid LinkedIn username' - } + description="Type your LinkedIn profile URL." onChange={setNewLinkedIn} value={newLinkedIn} enabled={!isSaving} labelIndicator={wrapIcon(LinkedInIcon, true)} - placeholder="Username" + placeholder="https://www.linkedin.com/in/yourprofilename" /> - 'Please enter a valid Research Gate Profile ID' - } + description="Type your Research Gate profile URL." onChange={setNewResearchGate} value={newResearchGate} enabled={!isSaving} labelIndicator={wrapIcon(ResearchGateIcon, true)} - placeholder="Profile ID" + placeholder="https://www.researchgate.net/profile/profileID" /> - 'Please enter a valid Google Scholar Profile ID' - } + description="Type your Google Scholar profile URL." onChange={setNewGoogleScholar} value={newGoogleScholar} enabled={!isSaving} labelIndicator={wrapIcon(GoogleScholarIcon, true)} - placeholder="Profile ID" + placeholder="https://scholar.google.com/citations?user=profileID" /> )} diff --git a/packages/react-components/src/templates/__tests__/ContactInfoModal.test.tsx b/packages/react-components/src/templates/__tests__/ContactInfoModal.test.tsx index 1627292442..0f3cd8b3fe 100644 --- a/packages/react-components/src/templates/__tests__/ContactInfoModal.test.tsx +++ b/packages/react-components/src/templates/__tests__/ContactInfoModal.test.tsx @@ -159,15 +159,10 @@ it.each` }); it.each` - label | value | message - ${'Website 1'} | ${'not url'} | ${'valid URL'} - ${'Website 2'} | ${'not url'} | ${'valid URL'} - ${'Researcher ID'} | ${'http://'} | ${'valid Researcher ID'} - ${'X'} | ${'http://'} | ${'valid Twitter handle'} - ${'Github'} | ${'http://'} | ${'valid Github username'} - ${'LinkedIn'} | ${'http://'} | ${'valid LinkedIn username'} - ${'Research Gate'} | ${'http://'} | ${'valid Research Gate Profile ID'} - ${'Google Scholar'} | ${'http://'} | ${'valid Google Scholar Profile ID'} + label | value | message + ${'Website 1'} | ${'not url'} | ${'valid URL'} + ${'Website 2'} | ${'not url'} | ${'valid URL'} + ${'Researcher ID'} | ${'http://'} | ${'valid Researcher ID'} `( 'shows validation message "$message" for $label input', async ({ label, value, message }) => { diff --git a/packages/react-components/src/utils/__tests__/user.test.ts b/packages/react-components/src/utils/__tests__/user.test.ts index d4e9d0da84..4102a0871d 100644 --- a/packages/react-components/src/utils/__tests__/user.test.ts +++ b/packages/react-components/src/utils/__tests__/user.test.ts @@ -1,4 +1,4 @@ -import { formatUserLocation } from '../user'; +import { formatUserLocation, formatUserSocial } from '../user'; describe('formatUserLocation', () => { it.each` @@ -18,3 +18,17 @@ describe('formatUserLocation', () => { }, ); }); + +describe('formatUserSocial', () => { + it.each` + social | type | result + ${'https://twitter.com/username'} | ${'twitter'} | ${'username'} + ${'https://github.com/username'} | ${'linkedIn'} | ${'https://github.com/username'} + ${''} | ${'googleScholar'} | ${''} + `( + 'generates the correct result for "$type" type', + ({ social, type, result }) => { + expect(formatUserSocial(social, type)).toEqual(result); + }, + ); +}); diff --git a/packages/react-components/src/utils/user.ts b/packages/react-components/src/utils/user.ts index 107c7d3a7b..5afc1b1e32 100644 --- a/packages/react-components/src/utils/user.ts +++ b/packages/react-components/src/utils/user.ts @@ -19,3 +19,16 @@ export const formatUserLocation = ( return formattedLocation; }; + +const baseUrls = { + twitter: 'https://twitter.com/', + linkedIn: 'https://www.linkedin.com/in/', + github: 'https://github.com/', + googleScholar: 'https://scholar.google.com/citations?user=', + researchGate: 'https://www.researchgate.net/profile/', +}; + +export type UserSocialType = keyof typeof baseUrls; + +export const formatUserSocial = (social: string, type: UserSocialType) => + social.startsWith(baseUrls[type]) ? social.split(baseUrls[type])[1] : social;