Skip to content

Commit 6c6c9a8

Browse files
authored
Merge pull request #368 from topcoder-platform/feat/GAME-137
Feat/GAME-137 -> gamification
2 parents 257cf9c + 77370fa commit 6c6c9a8

20 files changed

+288
-32
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export interface InfinitePageDao<T> {
22
count: number
3+
limit: number
4+
offset: number
35
// TODO: rename this 'items' so it can be used in a grid/card view
46
rows: ReadonlyArray<T>
57
}
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
// TODO: add factory to convert snake case property names to camel case
2+
export interface MemberBadgeAward {
3+
awarded_at: string
4+
awarded_by: string
5+
user_handle: string
6+
user_id: string
7+
}
8+
29
export interface GameBadge {
3-
active: boolean
4-
badge_description: string
5-
badge_image_url: string
6-
badge_name: string
7-
badge_status: string
8-
id: string
9-
member_badges?: Array<{
10-
awarded_at: string,
11-
awarded_by: string,
12-
user_handle: string,
13-
user_id: string,
14-
}>
15-
organization_id: string
10+
active: boolean
11+
badge_description: string
12+
badge_image_url: string
13+
badge_name: string
14+
badge_status: string
15+
id: string
16+
member_badges?: Array<MemberBadgeAward>
17+
organization_id: string
1618
}

src-ts/tools/gamification-admin/game-lib/use-gamification-breadcrumb.hook.tsx renamed to src-ts/tools/gamification-admin/game-lib/hooks/use-gamification-breadcrumb.hook.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { BreadcrumbItemModel } from '../../../lib'
2-
import { basePath } from '../gamification-admin.routes'
3-
import { toolTitle } from '../GamificationAdmin'
1+
import { BreadcrumbItemModel } from '../../../../lib'
2+
import { basePath } from '../../gamification-admin.routes'
3+
import { toolTitle } from '../../GamificationAdmin'
44

55
export function useGamificationBreadcrumb(items: Array<BreadcrumbItemModel>): Array<BreadcrumbItemModel> {
66

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { EnvironmentConfig } from '../../../../config'
2+
import { InfinitePageDao, InfinitePageHandler, Sort, useGetInfinitePage } from '../../../../lib'
3+
import { GamificationConfig } from '../../game-config'
4+
import { GameBadge, MemberBadgeAward } from '../game-badge.model'
5+
6+
export function useGetGameBadgeAssigneesPage(badge: GameBadge, sort: Sort): InfinitePageHandler<MemberBadgeAward> {
7+
8+
function getKey(index: number, previousPageData: InfinitePageDao<MemberBadgeAward>): string | undefined {
9+
10+
// reached the end
11+
if (!!previousPageData && !previousPageData.rows.length) {
12+
return undefined
13+
}
14+
15+
const params: Record<string, string> = {
16+
limit: `${GamificationConfig.PAGE_SIZE}`,
17+
offset: `${index * GamificationConfig.PAGE_SIZE}`,
18+
order_by: sort.fieldName,
19+
order_type: sort.direction,
20+
}
21+
22+
const badgeEndpointUrl: URL = new URL(`${EnvironmentConfig.API.V5}/gamification/badges/${badge.id}/assignees?${new URLSearchParams(params)}`)
23+
24+
return badgeEndpointUrl.toString()
25+
}
26+
27+
return useGetInfinitePage(getKey)
28+
}

src-ts/tools/gamification-admin/game-lib/use-get-game-badge-details.hook.ts renamed to src-ts/tools/gamification-admin/game-lib/hooks/use-get-game-badge-details.hook.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import useSWR, { KeyedMutator, SWRResponse } from 'swr'
22

3-
import { EnvironmentConfig } from '../../../config'
4-
5-
import { GameBadge } from './game-badge.model'
3+
import { EnvironmentConfig } from '../../../../config'
4+
import { GameBadge } from '../game-badge.model'
65

76
export interface BadgeDetailPageHandler<T> {
87
data?: Readonly<T>

src-ts/tools/gamification-admin/game-lib/use-get-game-badges-page.hook.ts renamed to src-ts/tools/gamification-admin/game-lib/hooks/use-get-game-badges-page.hook.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { EnvironmentConfig } from '../../../config'
2-
import { InfinitePageDao, InfinitePageHandler, Sort, useGetInfinitePage } from '../../../lib'
3-
import { GamificationConfig } from '../game-config'
4-
5-
import { GameBadge } from './game-badge.model'
1+
import { EnvironmentConfig } from '../../../../config'
2+
import { InfinitePageDao, InfinitePageHandler, Sort, useGetInfinitePage } from '../../../../lib'
3+
import { GamificationConfig } from '../../game-config'
4+
import { GameBadge } from '../game-badge.model'
65

76
export function useGetGameBadgesPage(sort: Sort): InfinitePageHandler<GameBadge> {
87

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './game-badge.model'
2-
export * from './use-get-game-badges-page.hook'
3-
export * from './use-gamification-breadcrumb.hook'
4-
export * from './use-get-game-badge-details.hook'
2+
export * from './hooks/use-get-game-badges-page.hook'
3+
export * from './hooks/use-gamification-breadcrumb.hook'
4+
export * from './hooks/use-get-game-badge-details.hook'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
@import "../../../../../lib/styles/variables/spacing";
2+
13
.tabWrap {
24
display: flex;
5+
padding-bottom: $space-xxxxl;
36
}

src-ts/tools/gamification-admin/pages/badge-detail/AwardedMembersTab/AwardedMembersTab.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,54 @@
1-
import { FC } from 'react'
1+
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
22

3-
import { GameBadge } from '../../../game-lib'
3+
import { InfinitePageHandler, Sort, Table, TableColumn, tableGetDefaultSort } from '../../../../../lib'
4+
import { GameBadge, MemberBadgeAward } from '../../../game-lib'
5+
import { useGetGameBadgeAssigneesPage } from '../../../game-lib/hooks/use-get-game-badge-assignees-page.hook'
46

7+
import { awardedMembersColumns } from './awarded-members-table/awarded-members-table.config'
58
import styles from './AwardedMembersTab.module.scss'
69

710
export interface AwardedMembersTabProps {
811
badge: GameBadge
12+
forceRefresh?: boolean
913
}
1014

1115
const AwardedMembersTab: FC<AwardedMembersTabProps> = (props: AwardedMembersTabProps) => {
16+
const [sort, setSort]: [Sort, Dispatch<SetStateAction<Sort>>] = useState<Sort>(tableGetDefaultSort(awardedMembersColumns))
17+
18+
const [columns]: [
19+
ReadonlyArray<TableColumn<MemberBadgeAward>>,
20+
Dispatch<SetStateAction<ReadonlyArray<TableColumn<MemberBadgeAward>>>>,
21+
]
22+
= useState<ReadonlyArray<TableColumn<MemberBadgeAward>>>([...awardedMembersColumns])
23+
24+
const pageHandler: InfinitePageHandler<MemberBadgeAward> = useGetGameBadgeAssigneesPage(props.badge, sort)
25+
26+
useEffect(() => {
27+
if (props.forceRefresh && pageHandler) {
28+
pageHandler.mutate()
29+
}
30+
}, [
31+
props.forceRefresh,
32+
pageHandler,
33+
])
34+
35+
function onSortClick(newSort: Sort): void {
36+
setSort({ ...newSort })
37+
}
38+
1239
return (
1340
<div className={styles.tabWrap}>
14-
41+
{
42+
pageHandler.data?.length ? (
43+
<Table
44+
columns={columns}
45+
data={pageHandler.data}
46+
onLoadMoreClick={pageHandler.getAndSetNext}
47+
moreToLoad={pageHandler.hasMore}
48+
onToggleSort={onSortClick}
49+
/>
50+
) : undefined
51+
}
1552
</div>
1653
)
1754
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { TableColumn } from '../../../../../../lib'
2+
import { MemberBadgeAward } from '../../../../game-lib'
3+
4+
import { MemberActionRenderer } from './member-action-renderer'
5+
import { MemberAwaredAtRenderer } from './member-awardedAt-renderer'
6+
import { MemberHandleRenderer } from './member-handle-renderer'
7+
8+
export const awardedMembersColumns: ReadonlyArray<TableColumn<MemberBadgeAward>> = [
9+
{
10+
defaultSortDirection: 'asc',
11+
isDefaultSort: true,
12+
label: 'Handle',
13+
propertyName: 'user_handle',
14+
renderer: MemberHandleRenderer,
15+
type: 'element',
16+
},
17+
{
18+
defaultSortDirection: 'asc',
19+
label: 'Awarded at',
20+
propertyName: 'awarded_at',
21+
renderer: MemberAwaredAtRenderer,
22+
type: 'element',
23+
},
24+
{
25+
renderer: MemberActionRenderer,
26+
type: 'action',
27+
},
28+
]

0 commit comments

Comments
 (0)