Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/apps/profiles/src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ export enum profileEditModes {
}

export const CES_SURVEY_ID = EnvironmentConfig.USERFLOW_SURVEYS.PROFILES

export const MAX_PRINCIPAL_SKILLS_COUNT = 10
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
105 changes: 88 additions & 17 deletions src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
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'
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 {
Expand All @@ -24,6 +25,7 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (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()

Expand All @@ -33,11 +35,19 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (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)
Expand All @@ -53,14 +63,17 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
})

return sortedGroupedSkillsByCategory
}, [memberSkills])
}, [additionalSkills])

const [isEditMode, setIsEditMode]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(false)

const [howSkillsWorkVisible, setHowSkillsWorkVisible]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(false)

const [principalIntroModalVisible, setPrincipalIntroModalVisible]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(false)

useEffect(() => {
if (props.authProfile && editMode === profileEditModes.skills) {
setIsEditMode(true)
Expand All @@ -69,6 +82,19 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (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)
}
Expand All @@ -92,16 +118,21 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
setHowSkillsWorkVisible(false)
}

function handlePrincipalIntroShow(): void {
setPrincipalIntroModalVisible(true)
}

function handlePrincipalIntroClose(): void {
setHasSeenPrincipalIntro((prevValue: any) => ({
...prevValue,
[props.authProfile?.handle ?? '']: true,
}))

setPrincipalIntroModalVisible(false)
}

return (
<div className={styles.container}>
{
skillsRenderer && memberSkills.length > 0 && (
<div className={styles.skillsWrap}>
{skillsRenderer(memberSkills)}
</div>
)
}

<div className={styles.titleWrap}>
<div className={styles.headerWrap}>
<h3>Skills</h3>
Expand All @@ -123,11 +154,42 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
</div>
</div>

{
skillsRenderer && memberSkills.length > 0 && (
<div className={styles.skillsWrap}>
{skillsRenderer(memberSkills)}
</div>
)
}

<div className={styles.skillsWrap}>
{memberSkills.length > 0 && (
<GroupedSkillsUI
groupedSkillsByCategory={groupedSkillsByCategory}
/>
{principalSkills.length > 0 && (
<div className={styles.principalSkillsWrap}>
<div className='large-subtitle'>
Principal Skills
</div>
<div className={styles.principalSkills}>
{principalSkills.map((skill: UserSkill) => (
<SkillPill
skill={skill}
key={skill.id}
theme={isSkillVerified(skill) ? 'verified' : 'dark'}
/>
))}
</div>
</div>
)}
{additionalSkills.length > 0 && (
<div className={styles.additionalSkillsWrap}>
{principalSkills.length > 0 && (
<div className='large-subtitle'>
Additional Skills
</div>
)}
<GroupedSkillsUI
groupedSkillsByCategory={groupedSkillsByCategory}
/>
</div>
)}
{!memberSkills.length && (
<EmptySection
Expand Down Expand Up @@ -155,6 +217,7 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
<ModifySkillsModal
onClose={handleModyfSkillsModalClose}
onSave={handleModyfSkillsSave}
showPrincipalIntroModal={handlePrincipalIntroShow}
/>
)
}
Expand All @@ -168,6 +231,14 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
/>
)
}

{
principalIntroModalVisible && (
<PrincipalSkillsModal
onClose={handlePrincipalIntroClose}
/>
)
}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}

Expand All @@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import styles from './ModifySkillsModal.module.scss'
interface ModifySkillsModalProps {
onClose: () => void
onSave: () => void
showPrincipalIntroModal: () => void
}

const ModifySkillsModal: FC<ModifySkillsModalProps> = (props: ModifySkillsModalProps) => {
Expand Down Expand Up @@ -40,7 +41,14 @@ const ModifySkillsModal: FC<ModifySkillsModalProps> = (props: ModifySkillsModalP
onClose={props.onClose}
open
size='lg'
title='My Skills'
title={(
<div className={styles.skillsModalHeader}>
<h3>Your skills</h3>
<p className='body-main-normal'>
We use your skills to connect you to the best opportunities.
</p>
</div>
)}
buttons={(
<div className={styles.modalButtons}>
<Button
Expand All @@ -58,13 +66,17 @@ const ModifySkillsModal: FC<ModifySkillsModalProps> = (props: ModifySkillsModalP
)}
>
<div className={styles.container}>
<p className='body-main-bold'>What are your skills?</p>
<p>
Understanding your skills will allow us to connect you to the right opportunities.
</p>
<div className={styles.skillPicker}>
{editor.formInput}
</div>
<div
className={styles.principalIntroLink}
onClick={props.showPrincipalIntroModal}
>
<span className='body-main-link'>
See what Principal skills are
</span>
</div>
</div>
</BaseModal>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@import '@libs/ui/styles/includes';

.verified {
display: inline-flex;

svg {
margin: 0 $sp-2;
color: $turq-120;
}
}

.container {
strong {
font-weight: bold;
}
}

.mb1 {
margin-bottom: $sp-2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { FC } from 'react'

import { BaseModal } from '~/libs/ui'

import { MAX_PRINCIPAL_SKILLS_COUNT } from '../../../config'

import principalInputImg from './principal-input.png'
import principalSectionImg from './principal-section.png'
import styles from './PrincipalSkillsModal.module.scss'

interface PrincipalSkillsModalProps {
onClose: () => void
}

const PrincipalSkillsModal: FC<PrincipalSkillsModalProps> = (props: PrincipalSkillsModalProps) => (
<BaseModal
onClose={props.onClose}
open
title='Highlight your Principal Skills'
size='lg'
>
<div className={styles.container}>
<p>
<div className={styles.mb1}>
Now you can highlight your most important skills using the&nbsp;
<strong>Principal Skills</strong>
&nbsp;section!
</div>
<img src={principalSectionImg} alt='' />
</p>
<br />
<p>
<div className={styles.mb1}>
Just move the skills you want to highlight by typing them in the&nbsp;
<strong>Principal Skills input</strong>
&nbsp;when you edit your skills.
</div>
<img src={principalInputImg} alt='' />
</p>
<br />
<p>
<strong>NOTE:</strong>
&nbsp;You can add up to
{' '}
{MAX_PRINCIPAL_SKILLS_COUNT}
{' '}
skills to your Principal Skills section.
</p>
<br />
<p>
To move a skill back to the
{' '}
<strong>Additional Skills section</strong>
, just type it in the
{' '}
<strong>Additional Skills input</strong>
.
</p>
</div>
</BaseModal>
)

export default PrincipalSkillsModal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as PrincipalSkillsModal } from './PrincipalSkillsModal'
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading