Skip to content

Commit d4a04cd

Browse files
committed
GAME-147 #comment render badge assignees
1 parent f8eda78 commit d4a04cd

File tree

14 files changed

+222
-17
lines changed

14 files changed

+222
-17
lines changed
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
}
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: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
1-
import { FC } from 'react'
1+
import { Dispatch, FC, SetStateAction, 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'
45

6+
import { awardedMembersColumns } from './awarded-members-table/awarded-members-table.config'
57
import styles from './AwardedMembersTab.module.scss'
68

79
export interface AwardedMembersTabProps {
810
badge: GameBadge
911
}
1012

1113
const AwardedMembersTab: FC<AwardedMembersTabProps> = (props: AwardedMembersTabProps) => {
14+
const [sort, setSort]: [Sort, Dispatch<SetStateAction<Sort>>] = useState<Sort>(tableGetDefaultSort(awardedMembersColumns))
15+
16+
const [columns]: [
17+
ReadonlyArray<TableColumn<MemberBadgeAward>>,
18+
Dispatch<SetStateAction<ReadonlyArray<TableColumn<MemberBadgeAward>>>>,
19+
]
20+
= useState<ReadonlyArray<TableColumn<MemberBadgeAward>>>([...awardedMembersColumns])
21+
22+
function onSortClick(newSort: Sort): void {
23+
setSort({ ...newSort })
24+
}
25+
1226
return (
1327
<div className={styles.tabWrap}>
14-
28+
{
29+
props.badge.member_badges?.length ? (
30+
<Table
31+
columns={columns}
32+
data={props.badge.member_badges}
33+
// onLoadMoreClick={pageHandler.getAndSetNext}
34+
// moreToLoad={pageHandler.hasMore}
35+
// onToggleSort={onSortClick}
36+
/>
37+
) : undefined
38+
}
1539
</div>
1640
)
1741
}
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+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@import "../../../../../../../lib/styles/includes";
2+
@import "../../../../../../../lib/styles/variables";
3+
4+
.badge-actions {
5+
display: flex;
6+
align-items: center;
7+
justify-content: flex-end;
8+
padding-top: $space-lg;
9+
padding-right: $space-sm;
10+
11+
@include ltemd {
12+
flex-direction: column;
13+
align-items: flex-end;
14+
}
15+
16+
a {
17+
margin-right: $space-sm;
18+
19+
@include ltemd {
20+
margin-right: 0;
21+
margin-bottom: $space-sm;
22+
}
23+
24+
&:last-child {
25+
margin-right: 0;
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Button, ButtonProps, useCheckIsMobile } from '../../../../../../../lib'
2+
import { MemberBadgeAward } from '../../../../../game-lib'
3+
4+
import styles from './MemberActionRenderer.module.scss'
5+
6+
function MemberActionRenderer(memberAward: MemberBadgeAward): JSX.Element {
7+
8+
const isMobile: boolean = useCheckIsMobile()
9+
10+
const buttonProps: ButtonProps = {
11+
buttonStyle: 'secondary',
12+
size: isMobile ? 'xs' : 'sm',
13+
}
14+
15+
const actionButtons: Array<{
16+
label: string
17+
}> = [
18+
{
19+
label: 'Unassign',
20+
},
21+
]
22+
23+
function onUnassign(): void {
24+
// TODO: unassign feature
25+
}
26+
27+
return (
28+
<div className={styles['badge-actions']}>
29+
{actionButtons.map((button, index) => {
30+
return (
31+
<Button
32+
{...buttonProps}
33+
key={index}
34+
label={button.label}
35+
onClick={onUnassign}
36+
/>
37+
)
38+
})}
39+
</div>
40+
)
41+
}
42+
43+
export default MemberActionRenderer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as MemberActionRenderer } from './MemberActionRenderer'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@import "../../../../../../../lib/styles/variables";
2+
@import "../../../../../../../lib/styles/includes";
3+
4+
.memberAwardedAt {
5+
font-size: 16px;
6+
font-weight: $font-weight-normal;
7+
text-align: left;
8+
9+
@include ltemd {
10+
font-size: 14px;
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { MemberBadgeAward } from '../../../../../game-lib'
2+
3+
import styles from './MemberAwaredAtRenderer.module.scss'
4+
5+
function MemberAwaredAtRenderer(memberAward: MemberBadgeAward): JSX.Element {
6+
const dateFormat: Record<string, string> = {
7+
day: 'numeric',
8+
hour: 'numeric',
9+
minute: 'numeric',
10+
month: 'short',
11+
year: 'numeric',
12+
}
13+
14+
return (
15+
<div className={styles.memberAwardedAt}>{new Date(memberAward.awarded_at).toLocaleString(undefined, dateFormat)}</div>
16+
)
17+
}
18+
19+
export default MemberAwaredAtRenderer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as MemberAwaredAtRenderer } from './MemberAwaredAtRenderer'

0 commit comments

Comments
 (0)