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
14 changes: 3 additions & 11 deletions src/apps/profiles/src/member-profile/phones/Phones.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { UserProfile } from '~/libs/core'
import { CopyButton } from '~/apps/admin/src/lib/components/CopyButton'
import { IconSolid } from '~/libs/ui'

import { AddButton, EmptySection } from '../../components'
import { AddButton } from '../../components'

import { ModifyPhonesModal } from './ModifyPhonesModal'
import { PhoneCard } from './PhoneCard'
Expand Down Expand Up @@ -64,7 +64,7 @@ const Phones: FC<PhonesProps> = (props: PhonesProps) => {

<div className={styles.phonesContent}>
{phones.length > 0
? phones.map((phone, index: number) => (
&& phones.map((phone, index: number) => (
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ design]
The change from a ternary operator to a logical AND operator removes the EmptySection component when there are no phones. Ensure that this behavior is intentional and that the user experience is not negatively impacted by the absence of a message indicating no phone numbers are available.

<PhoneCard
key={`${phone.type}-${phone.number}`}
type={phone.type}
Expand All @@ -73,15 +73,7 @@ const Phones: FC<PhonesProps> = (props: PhonesProps) => {
phoneIndex={index}
onEdit={index === 0 ? handleEditPhonesClick : undefined}
/>
))
: (
<EmptySection
selfMessage='Adding contact information helps others reach you.'
isSelf={canEdit}
>
This member has not added contact phone numbers.
</EmptySection>
)}
))}
{canEdit && (
<AddButton
label='Add phone number'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@import "@libs/ui/styles/includes";

.badgeContainer {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 maintainability]
Consider using a more descriptive class name than .badgeContainer to improve maintainability and clarity, especially if there are multiple badge types in the application.

position: absolute;
top: 0px;
right: 20px;
z-index: 10;
cursor: pointer;
}

.badge {
position: relative;
width: 68px;
height: 68px;
display: flex;
align-items: center;
justify-content: center;

@include ltelg {
width: 56px;
height: 56px;
}

.icon {
width: 100%;
height: 100%;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
}
}

.tooltip {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The .tooltip class uses a hardcoded color $black-100 for the background. Ensure this variable is defined and consistent with the design system to avoid unexpected styling issues.

position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background-color: $black-100;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Ensure that $black-100 and $tc-white are defined in the imported styles and are consistent with the application's theme to prevent styling inconsistencies.

color: $tc-white;
padding: $sp-1 $sp-2;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease-in-out;
z-index: 20;

&::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: $black-100;
}
}

.badgeContainer:hover .tooltip {
opacity: 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FC } from 'react'

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

import styles from './IdentityVerifiedBadge.module.scss'

interface IdentityVerifiedBadgeProps {
identityVerified?: boolean
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ design]
Consider making identityVerified a required prop instead of optional. This would make the component's behavior more predictable and reduce the need for null checks.

}

const IdentityVerifiedBadge: FC<IdentityVerifiedBadgeProps> = (props: IdentityVerifiedBadgeProps) => {
if (!props.identityVerified) {
// eslint-disable-next-line unicorn/no-null
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 style]
Returning null is acceptable here, but consider using undefined to align with React's best practices for conditional rendering.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, this is good suggestion and practice to appy going forward @hentrymartin .

return null
}

return (
<div className={styles.badgeContainer}>
<div className={styles.badge}>
<IdentityVerifiedBadgeIcon />
</div>
<span className={styles.tooltip}>Identity Verified</span>
</div>
)
}

export default IdentityVerifiedBadge
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import IdentityVerifiedBadge from './IdentityVerifiedBadge'

export { IdentityVerifiedBadge }
export default IdentityVerifiedBadge
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { OpenForGigs } from './OpenForGigs'
import { ModifyMemberNameModal } from './ModifyMemberNameModal'
import { ModifyMemberPhotoModal } from './ModifyMemberPhotoModal'
import { HiringFormModal } from './HiringFormModal'
import IdentityVerifiedBadge from './IdentityVerifiedBadge'
import styles from './ProfileHeader.module.scss'

interface ProfileHeaderProps {
Expand Down Expand Up @@ -109,6 +110,7 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
return (
<div className={styles.photoWrap}>
<ProfilePicture member={props.profile} className={styles.profilePhoto} />
<IdentityVerifiedBadge identityVerified={props.profile.identityVerified} />
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Ensure that props.profile.identityVerified is always a boolean. If it can be undefined or null, it might cause the IdentityVerifiedBadge component to behave unexpectedly. Consider adding a default value or type check.

{canEdit && hasProfilePicture && (
<EditMemberPropertyBtn
className={styles.button}
Expand Down
1 change: 1 addition & 0 deletions src/libs/core/lib/profile/user-profile.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ export interface UserProfile {
updatedAt: number
userId: number
namesAndHandleAppearance: NamesAndHandleAppearance
identityVerified?: boolean
}
2 changes: 2 additions & 0 deletions src/libs/ui/lib/components/svgs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ReactComponent as GitlabIcon } from './gitlab.svg'
import { ReactComponent as ArrowIcon } from './icon-arrow.svg'
import { ReactComponent as BackArrowIcon } from './icon-back-arrow.svg'
import { ReactComponent as IconCheck } from './icon-check-thin.svg'
import { ReactComponent as IdentityVerifiedBadgeIcon } from './verified-badge.svg'
import { ReactComponent as LogoIcon } from './logo.svg'
import { ReactComponent as SaveForLaterIcon } from './save-for-later-icon.svg'
import { ReactComponent as SocialIconFacebook } from './social-fb-icon.svg'
Expand Down Expand Up @@ -37,6 +38,7 @@ export {
BackArrowIcon,
IconOutline,
IconSolid,
IdentityVerifiedBadgeIcon,
LogoIcon,
SocialIconFacebook,
SocialIconInstagram,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/ui/lib/components/svgs/verified-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading