-
Notifications
You must be signed in to change notification settings - Fork 20
PM-4198 add pagination & member details to custmer portal results #1514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| 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 | ||
| } | ||
|
|
||
| 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 async function fetchCompletedProfiles( | ||
| countryCode: string | undefined, | ||
| page: number, | ||
| perPage: number, | ||
| ): Promise<CompletedProfilesResponse> { | ||
| const queryParams = new URLSearchParams({ | ||
| page: String(page), | ||
| perPage: String(perPage), | ||
| }) | ||
|
|
||
| if (countryCode) { | ||
| queryParams.set('countryCode', countryCode) | ||
| } | ||
|
|
||
| const response = await xhrGetAsync<any>( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| `${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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [💡 |
||
| 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 [] | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,7 +86,7 @@ | |
| table { | ||
| width: 100%; | ||
| border-collapse: collapse; | ||
| min-width: 420px; | ||
| min-width: 1120px; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [ |
||
| } | ||
|
|
||
| th, | ||
|
|
@@ -106,9 +106,66 @@ | |
|
|
||
| td { | ||
| color: $black-100; | ||
| vertical-align: middle; | ||
| } | ||
|
|
||
| tr:last-child td { | ||
| border-bottom: 0; | ||
| } | ||
| } | ||
|
|
||
| .memberCell { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: $sp-2; | ||
| } | ||
|
|
||
| .avatar { | ||
| width: 28px; | ||
| height: 28px; | ||
| border-radius: 50%; | ||
| object-fit: cover; | ||
| border: 1px solid $black-20; | ||
| } | ||
|
|
||
| .paginationRow { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: space-between; | ||
| gap: $sp-3; | ||
|
|
||
| @include ltemd { | ||
| flex-direction: column; | ||
| align-items: flex-start; | ||
| } | ||
| } | ||
|
|
||
| .paginationInfo { | ||
| color: $black-60; | ||
| font-size: 14px; | ||
| line-height: 20px; | ||
| } | ||
|
|
||
| .paginationButtons { | ||
| display: flex; | ||
| align-items: center; | ||
| gap: $sp-2; | ||
| } | ||
|
|
||
| .skillsList { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: $sp-2; | ||
| } | ||
|
|
||
| .skillTag { | ||
| display: inline-block; | ||
| background: $black-5; | ||
| border: 1px solid $black-20; | ||
| border-radius: $sp-1; | ||
| padding: $sp-1 $sp-2; | ||
| font-size: 12px; | ||
| line-height: 16px; | ||
| color: $black-80; | ||
| white-space: nowrap; | ||
| } | ||
There was a problem hiding this comment.
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 specific type than
anyfor therawparameter to improve type safety and maintainability.