1
1
/* eslint-disable import/no-unresolved */
2
2
import { noop , trim } from 'lodash'
3
- import { ChangeEvent , createRef , Dispatch , FC , KeyboardEvent , RefObject , SetStateAction , useEffect , useState } from 'react'
3
+ import {
4
+ ChangeEvent ,
5
+ createRef ,
6
+ Dispatch ,
7
+ FC ,
8
+ KeyboardEvent ,
9
+ RefObject ,
10
+ SetStateAction ,
11
+ useEffect ,
12
+ useState ,
13
+ } from 'react'
4
14
import { Params , useLocation , useParams } from 'react-router-dom'
5
15
import { toast } from 'react-toastify'
6
16
import { KeyedMutator , useSWRConfig } from 'swr'
@@ -9,9 +19,29 @@ import ContentEditable from 'react-contenteditable'
9
19
import MarkdownIt from 'markdown-it'
10
20
import sanitizeHtml from 'sanitize-html'
11
21
12
- import { Breadcrumb , BreadcrumbItemModel , Button , ButtonProps , ContentLayout , IconOutline , IconSolid , LoadingSpinner , PageDivider , Sort , tableGetDefaultSort , TabsNavbar , TabsNavItem } from '../../../../lib'
22
+ import {
23
+ Breadcrumb ,
24
+ BreadcrumbItemModel ,
25
+ Button ,
26
+ ButtonProps ,
27
+ ContentLayout ,
28
+ IconOutline ,
29
+ IconSolid ,
30
+ LoadingSpinner ,
31
+ PageDivider ,
32
+ Sort ,
33
+ tableGetDefaultSort ,
34
+ TabsNavbar ,
35
+ TabsNavItem ,
36
+ } from '../../../../lib'
13
37
import { GamificationConfig } from '../../game-config'
14
- import { BadgeDetailPageHandler , GameBadge , useGamificationBreadcrumb , useGetGameBadgeDetails , useGetGameBadgesPage } from '../../game-lib'
38
+ import {
39
+ BadgeDetailPageHandler ,
40
+ GameBadge ,
41
+ useGamificationBreadcrumb ,
42
+ useGetGameBadgeDetails ,
43
+ useGetGameBadgesPage ,
44
+ } from '../../game-lib'
15
45
import { BadgeActivatedModal } from '../../game-lib/modals/badge-activated-modal'
16
46
import { badgeListingColumns } from '../badge-listing/badge-listing-table'
17
47
@@ -65,20 +95,26 @@ const BadgeDetailPage: FC = () => {
65
95
66
96
const fileInputRef : RefObject < HTMLInputElement > = createRef < HTMLInputElement > ( )
67
97
68
- // eslint-disable-next-line no-null/no-null
69
- const [ newImageFile , setNewImageFile ] : [ FileList | null , Dispatch < SetStateAction < FileList | null > > ] = useState < FileList | null > ( null )
98
+ const [ newImageFile , setNewImageFile ] : [ FileList | undefined , Dispatch < SetStateAction < FileList | undefined > > ]
99
+ = useState < FileList | undefined > ( undefined )
70
100
71
- const [ fileDataURL , setFileDataURL ] : [ string | undefined , Dispatch < SetStateAction < string | undefined > > ] = useState < string | undefined > ( )
101
+ const [ fileDataURL , setFileDataURL ] : [ string | undefined , Dispatch < SetStateAction < string | undefined > > ]
102
+ = useState < string | undefined > ( )
72
103
73
- const [ isBadgeDescEditingMode , setIsBadgeDescEditingMode ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState < boolean > ( false )
104
+ const [ isBadgeDescEditingMode , setIsBadgeDescEditingMode ] : [ boolean , Dispatch < SetStateAction < boolean > > ]
105
+ = useState < boolean > ( false )
74
106
75
107
// badgeListingMutate will reset badge listing page cache when called
76
108
const sort : Sort = tableGetDefaultSort ( badgeListingColumns )
77
109
const { mutate : badgeListingMutate } : { mutate : KeyedMutator < any > } = useGetGameBadgesPage ( sort )
78
110
79
- const [ badgeNameErrorText , setBadgeNameErrorText ] : [ string | undefined , Dispatch < SetStateAction < string | undefined > > ] = useState < string | undefined > ( )
111
+ const [ badgeNameErrorText , setBadgeNameErrorText ] : [
112
+ string | undefined ,
113
+ Dispatch < SetStateAction < string | undefined > >
114
+ ] = useState < string | undefined > ( )
80
115
81
- const [ showActivatedModal , setShowActivatedModal ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState < boolean > ( false )
116
+ const [ showActivatedModal , setShowActivatedModal ] : [ boolean , Dispatch < SetStateAction < boolean > > ]
117
+ = useState < boolean > ( false )
82
118
83
119
const { cache, mutate } : FullConfiguration = useSWRConfig ( )
84
120
@@ -135,6 +171,7 @@ const BadgeDetailPage: FC = () => {
135
171
onClick : onActivateBadge ,
136
172
} )
137
173
break
174
+ default : break
138
175
}
139
176
}
140
177
} , [
@@ -256,6 +293,28 @@ const BadgeDetailPage: FC = () => {
256
293
badgeListingMutate ( )
257
294
}
258
295
296
+ function handleBadgeEditClick ( ) : void {
297
+ fileInputRef . current ?. click ( )
298
+ }
299
+
300
+ function cancelEditBadge ( ) : void {
301
+ setIsBadgeDescEditingMode ( false )
302
+ }
303
+
304
+ function hideActivateModal ( ) : void {
305
+ setShowActivatedModal ( false )
306
+ }
307
+
308
+ function handleContentEditFocus ( ) : void {
309
+ setIsBadgeDescEditingMode ( true )
310
+ }
311
+
312
+ function handleContentChange ( ) : void {
313
+ if ( badgeNameErrorText ) {
314
+ setBadgeNameErrorText ( undefined )
315
+ }
316
+ }
317
+
259
318
function validateFilePicked ( e : ChangeEvent < HTMLInputElement > ) : void {
260
319
if ( e . target . files ?. length ) {
261
320
if ( GamificationConfig . ACCEPTED_BADGE_MIME_TYPES . includes ( e . target . files [ 0 ] . type ) ) {
@@ -327,9 +386,12 @@ const BadgeDetailPage: FC = () => {
327
386
buttonStyle = 'icon'
328
387
icon = { IconOutline . PencilIcon }
329
388
className = { styles . filePickerPencil }
330
- onClick = { ( ) => fileInputRef . current ?. click ( ) }
389
+ onClick = { handleBadgeEditClick }
390
+ />
391
+ < img
392
+ src = { fileDataURL || badgeDetailsHandler . data ?. badge_image_url }
393
+ alt = 'badge media preview'
331
394
/>
332
- < img src = { fileDataURL || badgeDetailsHandler . data ?. badge_image_url } alt = 'badge media preview' />
333
395
< input
334
396
type = 'file'
335
397
ref = { fileInputRef }
@@ -343,7 +405,7 @@ const BadgeDetailPage: FC = () => {
343
405
< ContentEditable
344
406
innerRef = { badgeNameRef }
345
407
html = { badgeDetailsHandler . data ?. badge_name as string }
346
- onChange = { ( ) => ( badgeNameErrorText ? setBadgeNameErrorText ( undefined ) : '' ) }
408
+ onChange = { handleContentChange }
347
409
onKeyDown = { onNameEditKeyDown }
348
410
onBlur = { onSaveBadgeName }
349
411
onFocus = { onBadgeNameEditFocus }
@@ -364,11 +426,17 @@ const BadgeDetailPage: FC = () => {
364
426
html = {
365
427
isBadgeDescEditingMode
366
428
? badgeDetailsHandler . data ?. badge_description as string
367
- : md . render ( badgeDetailsHandler . data ?. badge_description as string )
429
+ : md . render (
430
+ badgeDetailsHandler . data ?. badge_description as string ,
431
+ )
368
432
}
369
433
onChange = { noop }
370
- onFocus = { ( ) => setIsBadgeDescEditingMode ( true ) }
371
- className = { isBadgeDescEditingMode ? styles . badgeEditableMode : styles . badgeEditable }
434
+ onFocus = { handleContentEditFocus }
435
+ className = {
436
+ isBadgeDescEditingMode
437
+ ? styles . badgeEditableMode
438
+ : styles . badgeEditable
439
+ }
372
440
/>
373
441
{
374
442
isBadgeDescEditingMode && (
@@ -377,7 +445,7 @@ const BadgeDetailPage: FC = () => {
377
445
label = 'Cancel'
378
446
buttonStyle = 'secondary'
379
447
size = 'xs'
380
- onClick = { ( ) => setIsBadgeDescEditingMode ( false ) }
448
+ onClick = { cancelEditBadge }
381
449
/>
382
450
< Button
383
451
label = 'Save'
@@ -405,7 +473,7 @@ const BadgeDetailPage: FC = () => {
405
473
&& (
406
474
< BadgeActivatedModal
407
475
isOpen = { showActivatedModal }
408
- onClose = { ( ) => setShowActivatedModal ( false ) }
476
+ onClose = { hideActivateModal }
409
477
badge = { badgeDetailsHandler . data }
410
478
/>
411
479
)
0 commit comments