Skip to content

Conversation

@vas3a
Copy link
Collaborator

@vas3a vas3a commented Jan 26, 2026

Related JIRA Ticket:

https://topcoder.atlassian.net/browse/PM-3329

What's in this PR?

Depending on how a skill was earned, hovering the skill "verified" icon will display activity info:

  • last activity date
  • up to 3 entries for each category (each linking to the specific activity eg challenge/course/etc)
image (note: in the image there are multiple entries for the same course - that's because I was testing earning that skill so I have multiple events for it, normally that wouldn't happen)

related PR: topcoder-platform/member-api-v6#41

skill={skill}
key={skill.id}
theme={isSkillVerified(skill) ? 'verified' : 'dark'}
fetchSkillDetails={canFetchSkillDetails ? fetchSkillDetails : undefined}

Choose a reason for hiding this comment

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

[⚠️ correctness]
Passing undefined to fetchSkillDetails when canFetchSkillDetails is false might lead to unexpected behavior if SkillPill or GroupedSkillsUI do not handle undefined properly. Consider ensuring these components can handle undefined gracefully.

return xhrGetBlobAsync<Blob>(`${profileUrl(handle)}/profileDownload`)
}

export function getMemberSkillDetails(handle: string, skillId: string): Promise<UserSkillWithActivity> {

Choose a reason for hiding this comment

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

[⚠️ maintainability]
Consider adding error handling for the xhrGetAsync call to manage potential network or API errors gracefully. This will improve the robustness of the function.

}

export type UserSkillWithActivity = {
lastUsedDate: string

Choose a reason for hiding this comment

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

[⚠️ correctness]
Consider using a more descriptive type for lastUsedDate such as Date instead of string to ensure date operations are type-safe and consistent.

}
}

.tootltipRow {

Choose a reason for hiding this comment

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

[❗❗ correctness]
The class name .tootltipRow appears to have a typo. It should likely be .tooltipRow for consistency and to avoid confusion.

@@ -1,8 +1,12 @@
import { FC, ReactNode, useCallback, useMemo } from 'react'
/* eslint-disable complexity */
import { FC, ReactNode, useCallback, useMemo, useState } from 'react'

Choose a reason for hiding this comment

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

[💡 maintainability]
Consider removing the complexity ESLint rule disable directive if it's not necessary. Disabling rules can hide potential issues.

<a
key={s.id}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.CHALLENGES_PAGE}/${s.id}`}

Choose a reason for hiding this comment

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

[❗❗ security]
The target='blank' attribute should be target='_blank' to correctly open links in a new tab. Additionally, consider adding rel='noopener noreferrer' for security reasons to prevent the new page from gaining access to the window.opener property.

Copy link
Collaborator

Choose a reason for hiding this comment

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

For fix.

<a
key={s.completionEventId}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_COURSE}/${s.certification}`}

Choose a reason for hiding this comment

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

[❗❗ security]
The target='blank' attribute should be target='_blank' to correctly open links in a new tab. Additionally, consider adding rel='noopener noreferrer' for security reasons to prevent the new page from gaining access to the window.opener property.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@vas3a let's fix.

<a
key={s.completionEventId}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_CERTIFICATION}/${s.dashedName}`}

Choose a reason for hiding this comment

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

[❗❗ security]
The target='blank' attribute should be target='_blank' to correctly open links in a new tab. Additionally, consider adding rel='noopener noreferrer' for security reasons to prevent the new page from gaining access to the window.opener property.

Copy link
Collaborator

Choose a reason for hiding this comment

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

To fix.


return (
<>
<div className={styles.tootltipRow}>

Choose a reason for hiding this comment

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

[⚠️ correctness]
There is a typo in the class name styles.tootltipRow. It should be styles.tooltipRow.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@vas3a let's fix it.


return (
<>
<div className={styles.tootltipRow}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

@vas3a let's fix it.

<a
key={s.completionEventId}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_COURSE}/${s.certification}`}
Copy link
Collaborator

Choose a reason for hiding this comment

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

@vas3a let's fix.

<a
key={s.id}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.CHALLENGES_PAGE}/${s.id}`}
Copy link
Collaborator

Choose a reason for hiding this comment

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

For fix.

<a
key={s.completionEventId}
className={classNames(styles.tootltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_CERTIFICATION}/${s.dashedName}`}
Copy link
Collaborator

Choose a reason for hiding this comment

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

To fix.

key={s.id}
className={classNames(styles.tooltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.CHALLENGES_PAGE}/${s.id}`}
target='_blank'

Choose a reason for hiding this comment

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

[❗❗ security]
The target='_blank' attribute should always be accompanied by rel='noopener noreferrer' to prevent security vulnerabilities such as reverse tabnabbing. This has been correctly added here.

key={s.completionEventId}
className={classNames(styles.tooltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_COURSE}/${s.certification}`}
target='_blank'

Choose a reason for hiding this comment

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

[❗❗ security]
The target='_blank' attribute should always be accompanied by rel='noopener noreferrer' to prevent security vulnerabilities such as reverse tabnabbing. This has been correctly added here.

key={s.completionEventId}
className={classNames(styles.tooltipRow, styles.padLeft)}
href={`${EnvironmentConfig.URLS.ACADEMY_CERTIFICATION}/${s.dashedName}`}
target='_blank'

Choose a reason for hiding this comment

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

[❗❗ security]
The target='_blank' attribute should always be accompanied by rel='noopener noreferrer' to prevent security vulnerabilities such as reverse tabnabbing. This has been correctly added here.

@vas3a vas3a merged commit 1214b18 into dev Jan 27, 2026
6 of 8 checks passed
@vas3a vas3a deleted the PM-3329_show-skills-activity-details branch January 27, 2026 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants