diff --git a/src/apps/profiles/src/config/constants.ts b/src/apps/profiles/src/config/constants.ts index f5a2b1cf5..b8bd645a6 100644 --- a/src/apps/profiles/src/config/constants.ts +++ b/src/apps/profiles/src/config/constants.ts @@ -24,3 +24,5 @@ export enum profileEditModes { } export const CES_SURVEY_ID = EnvironmentConfig.USERFLOW_SURVEYS.PROFILES + +export const MAX_PRINCIPAL_SKILLS_COUNT = 10 diff --git a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.module.scss b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.module.scss index f07d5098f..22e6cacff 100644 --- a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.module.scss +++ b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.module.scss @@ -27,8 +27,28 @@ .skillsWrap { padding-bottom: $sp-8; + + :global(.large-subtitle) { + margin-bottom: $sp-4; + } + @include ltemd { padding-bottom: $sp-4; } } } + +.principalSkillsWrap { + background: $black-5; + border-radius: $sp-2; + padding: $sp-6; + + .additionalSkillsWrap { + margin-top: $sp-6; + } +} + +.principalSkills { + display: flex; + flex-wrap: wrap; + gap: $sp-2; +} diff --git a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx index db5c98949..738e3918e 100644 --- a/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx +++ b/src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx @@ -1,9 +1,9 @@ import { Dispatch, FC, SetStateAction, useEffect, useMemo, useState } from 'react' import { useSearchParams } from 'react-router-dom' -import { orderBy } from 'lodash' +import { filter, orderBy } from 'lodash' -import { UserProfile, UserSkill } from '~/libs/core' -import { GroupedSkillsUI, HowSkillsWorkModal, isSkillVerified } from '~/libs/shared' +import { UserProfile, UserSkill, UserSkillDisplayModes } from '~/libs/core' +import { GroupedSkillsUI, HowSkillsWorkModal, isSkillVerified, SkillPill, useLocalStorage } from '~/libs/shared' import { Button } from '~/libs/ui' import { AddButton, EditMemberPropertyBtn, EmptySection } from '../../components' @@ -11,6 +11,7 @@ import { EDIT_MODE_QUERY_PARAM, profileEditModes } from '../../config' import { MemberProfileContextValue, useMemberProfileContext } from '../MemberProfile.context' import { ModifySkillsModal } from './ModifySkillsModal' +import { PrincipalSkillsModal } from './PrincipalSkillsModal' import styles from './MemberSkillsInfo.module.scss' interface MemberSkillsInfoProps { @@ -24,6 +25,7 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp const editMode: string | null = queryParams.get(EDIT_MODE_QUERY_PARAM) const canEdit: boolean = props.authProfile?.handle === props.profile.handle + const [hasSeenPrincipalIntro, setHasSeenPrincipalIntro] = useLocalStorage('seen-principal-intro', {} as any) const { skillsRenderer, isTalentSearch }: MemberProfileContextValue = useMemberProfileContext() @@ -33,11 +35,19 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp ['desc', 'asc'], ) as UserSkill[], [props.profile.skills]) + const principalSkills = useMemo(() => ( + filter(memberSkills, s => s.displayMode?.name === UserSkillDisplayModes.principal) + ), [memberSkills]) + + const additionalSkills = useMemo(() => ( + filter(memberSkills, s => s.displayMode?.name !== UserSkillDisplayModes.principal) + ), [memberSkills]) + const groupedSkillsByCategory: { [key: string]: UserSkill[] } = useMemo(() => { const grouped: { [key: string]: UserSkill[] } = {} const sortedGroupedSkillsByCategory: { [key: string]: UserSkill[] } = {} - memberSkills.forEach((skill: UserSkill) => { + additionalSkills.forEach((skill: UserSkill) => { const categoryName = skill.category?.name ?? '' if (grouped[categoryName]) { grouped[categoryName].push(skill) @@ -53,7 +63,7 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp }) return sortedGroupedSkillsByCategory - }, [memberSkills]) + }, [additionalSkills]) const [isEditMode, setIsEditMode]: [boolean, Dispatch>] = useState(false) @@ -61,6 +71,9 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp const [howSkillsWorkVisible, setHowSkillsWorkVisible]: [boolean, Dispatch>] = useState(false) + const [principalIntroModalVisible, setPrincipalIntroModalVisible]: [boolean, Dispatch>] + = useState(false) + useEffect(() => { if (props.authProfile && editMode === profileEditModes.skills) { setIsEditMode(true) @@ -69,6 +82,19 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.authProfile]) + useEffect(() => { + if ( + !canEdit + || !props.authProfile + || hasSeenPrincipalIntro[props.authProfile.handle] + || isTalentSearch + ) { + return + } + + setPrincipalIntroModalVisible(true) + }, [hasSeenPrincipalIntro, canEdit, isTalentSearch, props.authProfile, setHasSeenPrincipalIntro]) + function handleEditSkillsClick(): void { setIsEditMode(true) } @@ -92,16 +118,21 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp setHowSkillsWorkVisible(false) } + function handlePrincipalIntroShow(): void { + setPrincipalIntroModalVisible(true) + } + + function handlePrincipalIntroClose(): void { + setHasSeenPrincipalIntro((prevValue: any) => ({ + ...prevValue, + [props.authProfile?.handle ?? '']: true, + })) + + setPrincipalIntroModalVisible(false) + } + return (
- { - skillsRenderer && memberSkills.length > 0 && ( -
- {skillsRenderer(memberSkills)} -
- ) - } -

Skills

@@ -123,11 +154,42 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp
+ { + skillsRenderer && memberSkills.length > 0 && ( +
+ {skillsRenderer(memberSkills)} +
+ ) + } +
- {memberSkills.length > 0 && ( - + {principalSkills.length > 0 && ( +
+
+ Principal Skills +
+
+ {principalSkills.map((skill: UserSkill) => ( + + ))} +
+
+ )} + {additionalSkills.length > 0 && ( +
+ {principalSkills.length > 0 && ( +
+ Additional Skills +
+ )} + +
)} {!memberSkills.length && ( = (props: MemberSkillsInfoProp ) } @@ -168,6 +231,14 @@ const MemberSkillsInfo: FC = (props: MemberSkillsInfoProp /> ) } + + { + principalIntroModalVisible && ( + + ) + }
) } diff --git a/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.module.scss b/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.module.scss index d07c19e93..672dc7024 100644 --- a/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.module.scss +++ b/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.module.scss @@ -1,16 +1,17 @@ @import '@libs/ui/styles/includes'; +.skillsModalHeader { + :global(.body-main-normal) { + margin-top: $sp-2; + } +} + .container { display: flex; flex-direction: column; - :global(.body-main-bold) { - font-size: 20px; - margin-bottom: $sp-2; - } - - .skillPicker { - margin-top: $sp-4; + :global(.input-wrapper) { + margin-top: $sp-2; } } @@ -29,3 +30,15 @@ .skillsModalBody { overflow: visible !important; } + +.principalIntroLink { + display: flex; + justify-content: flex-end; + > span { + color: $link-blue-dark; + cursor: pointer; + &:hover { + color: darken($link-blue-dark, 5); + } + } +} diff --git a/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.tsx b/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.tsx index 68a9204ec..6de75fc4e 100644 --- a/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.tsx +++ b/src/apps/profiles/src/member-profile/skills/ModifySkillsModal/ModifySkillsModal.tsx @@ -9,6 +9,7 @@ import styles from './ModifySkillsModal.module.scss' interface ModifySkillsModalProps { onClose: () => void onSave: () => void + showPrincipalIntroModal: () => void } const ModifySkillsModal: FC = (props: ModifySkillsModalProps) => { @@ -40,7 +41,14 @@ const ModifySkillsModal: FC = (props: ModifySkillsModalP onClose={props.onClose} open size='lg' - title='My Skills' + title={( +
+

Your skills

+

+ We use your skills to connect you to the best opportunities. +

+
+ )} buttons={(