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
1 change: 0 additions & 1 deletion craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ module.exports = {
'@learn': resolve('src/apps/learn/src'),
'@devCenter': resolve('src/apps/dev-center/src'),
'@gamificationAdmin': resolve('src/apps/gamification-admin/src'),
'@talentSearch': resolve('src/apps/talent-search/src'),
'@profiles': resolve('src/apps/profiles/src'),
'@wallet': resolve('src/apps/wallet/src'),
'@walletAdmin': resolve('src/apps/wallet-admin/src'),
Expand Down
2 changes: 1 addition & 1 deletion src/apps/customer-portal/src/config/routes.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export const rootRoute: string
? ''
: `/${AppSubdomain.customer}`

export const talentSearchRouteId = 'talent-search'
export const profileCompletionRouteId = 'profile-completion'
11 changes: 0 additions & 11 deletions src/apps/customer-portal/src/customer-portal.routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ import {
lazyLoad,
LazyLoadedComponent,
PlatformRoute,
Rewrite,
UserRole,
} from '~/libs/core'

import {
rootRoute,
talentSearchRouteId,
} from './config/routes.config'
import { customerPortalTalentSearchRoutes } from './pages/talent-search/talent-search.routes'

const CustomerPortalApp: LazyLoadedComponent = lazyLoad(() => import('./CustomerPortalApp'))

Expand All @@ -24,14 +21,6 @@ export const customerPortalRoutes: ReadonlyArray<PlatformRoute> = [
// Customer portal App Root
{
authRequired: true,
children: [
{
authRequired: true,
element: <Rewrite to={talentSearchRouteId} />,
route: '',
},
...customerPortalTalentSearchRoutes,
],
domain: AppSubdomain.customer,
element: <CustomerPortalApp />,
id: toolTitle,
Expand Down
28 changes: 3 additions & 25 deletions src/apps/customer-portal/src/lib/components/NavTabs/NavTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,16 @@ import {
MouseEvent,
SetStateAction,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import { NavigateFunction, useLocation, useNavigate } from 'react-router-dom'
import { isEmpty } from 'lodash'
import classNames from 'classnames'

import { useClickOutside } from '~/libs/shared/lib/hooks'
import { IconOutline } from '~/libs/ui'

import { CustomerPortalAppContext } from '../../contexts'
import { CustomerPortalAppContextModel } from '../../models'
import { PRIVILEGED_ROLES } from '../../../config/index.config'

import { getTabIdFromPathName, getTabsConfig } from './config'
import styles from './NavTabs.module.scss'

Expand All @@ -30,31 +23,16 @@ const NavTabs: FC = () => {
const triggerRef = useRef<HTMLDivElement>(null)
const { pathname }: { pathname: string } = useLocation()

const { loginUserInfo }: CustomerPortalAppContextModel = useContext(CustomerPortalAppContext)
const isAnonymous = isEmpty(loginUserInfo)
const userRoles = useMemo(() => loginUserInfo?.roles || [], [loginUserInfo?.roles])
const isUnprivilegedUser = useMemo(() => {
if (!loginUserInfo) return true

return !userRoles.some(role => PRIVILEGED_ROLES.includes(role))
}, [loginUserInfo, userRoles])
const tabs = useMemo(
() => getTabsConfig(userRoles, isAnonymous, isUnprivilegedUser),
[userRoles, isAnonymous, isUnprivilegedUser],
)

const activeTabPathName: string = useMemo<string>(
() => getTabIdFromPathName(pathname, userRoles, isAnonymous, isUnprivilegedUser),
[pathname, userRoles, isAnonymous, isUnprivilegedUser],
)
const tabs = getTabsConfig()
const activeTabPathName: string = getTabIdFromPathName(pathname)
const [activeTab, setActiveTab]: [
string,
Dispatch<SetStateAction<string>>
] = useState<string>(activeTabPathName)

useEffect(() => {
setActiveTab(activeTabPathName)
}, [activeTabPathName])
}, [pathname])

const triggerTab = useCallback(() => {
setIsOpen(!isOpen)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
import _ from 'lodash'

import { TabsNavItem } from '~/libs/ui'
import {
talentSearchRouteId,
} from '~/apps/customer-portal/src/config/routes.config'

export function getTabsConfig(userRoles: string[], isAnonymous: boolean, isUnprivilegedUser: boolean): TabsNavItem[] {

const tabs: TabsNavItem[] = [
...(!isUnprivilegedUser ? [{
id: talentSearchRouteId,
title: 'Talent Search',
}] : []),
]

return tabs
export function getTabsConfig(): TabsNavItem[] {
return []
}

export function getTabIdFromPathName(
pathname: string,
userRoles: string[],
isAnonymous: boolean,
isUnprivilegedUser: boolean,
): string {
const matchItem = _.find(getTabsConfig(
userRoles,
isAnonymous,
isUnprivilegedUser,
), item => pathname.includes(`/${item.id}`))
const matchItem = _.find(getTabsConfig(), item => pathname.includes(`/${item.id}`))

if (matchItem) {
return matchItem.id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { EnvironmentConfig } from '~/config'
import { UserSkill, xhrGetAsync } from '~/libs/core'

export type CompletedProfile = {
countryCode?: string
countryName?: string
city?: string
firstName?: string
handle: string
lastName?: string
photoURL?: string
skillCount?: number
userId?: number | string
isOpenToWork?: boolean | null
openToWork?: {
availability?: string
preferredRoles?: string[]
} | null
}

export type CompletedProfilesResponse = {
data: CompletedProfile[]
page: number
perPage: number
total: number
totalPages: number
}

export const DEFAULT_PAGE_SIZE = 50

function normalizeToList(raw: any): any[] {
if (Array.isArray(raw)) {
return raw
}

if (Array.isArray(raw?.data)) {
return raw.data
}

if (Array.isArray(raw?.result?.content)) {
return raw.result.content
}

if (Array.isArray(raw?.result)) {
return raw.result
}

return []
}

function normalizeCompletedProfilesResponse(
raw: any,
fallbackPage: number,
fallbackPerPage: number,
): CompletedProfilesResponse {
if (raw && Array.isArray(raw.data)) {
const total: number = Number(raw.total ?? raw.data.length)
const perPage: number = Number(raw.perPage ?? fallbackPerPage)
const page: number = Number(raw.page ?? fallbackPage)
const safePerPage = Number.isFinite(perPage) ? Math.max(perPage, 1) : fallbackPerPage
const safeTotal = Number.isFinite(total) ? Math.max(total, 0) : raw.data.length

return {
data: raw.data,
page: Number.isFinite(page) ? Math.max(page, 1) : fallbackPage,
perPage: safePerPage,
total: safeTotal,
totalPages: Number.isFinite(raw.totalPages)
? Math.max(Number(raw.totalPages), 1)
: Math.max(Math.ceil(safeTotal / safePerPage), 1),
}
}

const rows = normalizeToList(raw)
const total = Number(raw?.total ?? rows.length)
const safeTotal = Number.isFinite(total) ? Math.max(total, 0) : rows.length

return {
data: rows,
page: fallbackPage,
perPage: fallbackPerPage,
total: safeTotal,
totalPages: Math.max(Math.ceil(safeTotal / fallbackPerPage), 1),
}
}

export type OpenToWorkFilter = 'all' | 'yes' | 'no'

export async function fetchCompletedProfiles(
countryCode: string | undefined,
page: number,
perPage: number,
openToWorkFilter?: OpenToWorkFilter,
skillIds?: string[],
): Promise<CompletedProfilesResponse> {
const queryParams = new URLSearchParams({
page: String(page),
perPage: String(perPage),
})

if (countryCode) {
queryParams.set('countryCode', countryCode)
}

if (openToWorkFilter === 'yes') {
queryParams.set('openToWork', 'true')
}

if (openToWorkFilter === 'no') {
queryParams.set('openToWork', 'false')
}

if (Array.isArray(skillIds) && skillIds.length > 0) {
skillIds.forEach(id => {
if (id) {
queryParams.append('skillId', String(id))
}
})
}

const response = await xhrGetAsync<any>(
`${EnvironmentConfig.REPORTS_API}/topcoder/completed-profiles?${queryParams.toString()}`,
)

return normalizeCompletedProfilesResponse(response, page, perPage)
}

export async function fetchMemberSkillsData(userId: string | number | undefined): Promise<UserSkill[]> {
if (!userId) {
return []
}

const baseUrl = `${EnvironmentConfig.API.V5}/standardized-skills`
const url = `${baseUrl}/user-skills/${userId}?disablePagination=true`

try {
return await xhrGetAsync<UserSkill[]>(url)
} catch {
// If skills API fails, return empty array to not block the page
return []
}
}
Loading
Loading