11/* eslint-disable import/no-unresolved */
22import { 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'
414import { Params , useLocation , useParams } from 'react-router-dom'
515import { toast } from 'react-toastify'
616import { KeyedMutator , useSWRConfig } from 'swr'
@@ -9,9 +19,29 @@ import ContentEditable from 'react-contenteditable'
919import MarkdownIt from 'markdown-it'
1020import sanitizeHtml from 'sanitize-html'
1121
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'
1337import { 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'
1545import { BadgeActivatedModal } from '../../game-lib/modals/badge-activated-modal'
1646import { badgeListingColumns } from '../badge-listing/badge-listing-table'
1747
@@ -65,20 +95,26 @@ const BadgeDetailPage: FC = () => {
6595
6696 const fileInputRef : RefObject < HTMLInputElement > = createRef < HTMLInputElement > ( )
6797
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 )
70100
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 > ( )
72103
73- const [ isBadgeDescEditingMode , setIsBadgeDescEditingMode ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState < boolean > ( false )
104+ const [ isBadgeDescEditingMode , setIsBadgeDescEditingMode ] : [ boolean , Dispatch < SetStateAction < boolean > > ]
105+ = useState < boolean > ( false )
74106
75107 // badgeListingMutate will reset badge listing page cache when called
76108 const sort : Sort = tableGetDefaultSort ( badgeListingColumns )
77109 const { mutate : badgeListingMutate } : { mutate : KeyedMutator < any > } = useGetGameBadgesPage ( sort )
78110
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 > ( )
80115
81- const [ showActivatedModal , setShowActivatedModal ] : [ boolean , Dispatch < SetStateAction < boolean > > ] = useState < boolean > ( false )
116+ const [ showActivatedModal , setShowActivatedModal ] : [ boolean , Dispatch < SetStateAction < boolean > > ]
117+ = useState < boolean > ( false )
82118
83119 const { cache, mutate } : FullConfiguration = useSWRConfig ( )
84120
@@ -135,6 +171,7 @@ const BadgeDetailPage: FC = () => {
135171 onClick : onActivateBadge ,
136172 } )
137173 break
174+ default : break
138175 }
139176 }
140177 } , [
@@ -256,6 +293,28 @@ const BadgeDetailPage: FC = () => {
256293 badgeListingMutate ( )
257294 }
258295
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+
259318 function validateFilePicked ( e : ChangeEvent < HTMLInputElement > ) : void {
260319 if ( e . target . files ?. length ) {
261320 if ( GamificationConfig . ACCEPTED_BADGE_MIME_TYPES . includes ( e . target . files [ 0 ] . type ) ) {
@@ -327,9 +386,12 @@ const BadgeDetailPage: FC = () => {
327386 buttonStyle = 'icon'
328387 icon = { IconOutline . PencilIcon }
329388 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'
331394 />
332- < img src = { fileDataURL || badgeDetailsHandler . data ?. badge_image_url } alt = 'badge media preview' />
333395 < input
334396 type = 'file'
335397 ref = { fileInputRef }
@@ -343,7 +405,7 @@ const BadgeDetailPage: FC = () => {
343405 < ContentEditable
344406 innerRef = { badgeNameRef }
345407 html = { badgeDetailsHandler . data ?. badge_name as string }
346- onChange = { ( ) => ( badgeNameErrorText ? setBadgeNameErrorText ( undefined ) : '' ) }
408+ onChange = { handleContentChange }
347409 onKeyDown = { onNameEditKeyDown }
348410 onBlur = { onSaveBadgeName }
349411 onFocus = { onBadgeNameEditFocus }
@@ -364,11 +426,17 @@ const BadgeDetailPage: FC = () => {
364426 html = {
365427 isBadgeDescEditingMode
366428 ? 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+ )
368432 }
369433 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+ }
372440 />
373441 {
374442 isBadgeDescEditingMode && (
@@ -377,7 +445,7 @@ const BadgeDetailPage: FC = () => {
377445 label = 'Cancel'
378446 buttonStyle = 'secondary'
379447 size = 'xs'
380- onClick = { ( ) => setIsBadgeDescEditingMode ( false ) }
448+ onClick = { cancelEditBadge }
381449 />
382450 < Button
383451 label = 'Save'
@@ -405,7 +473,7 @@ const BadgeDetailPage: FC = () => {
405473 && (
406474 < BadgeActivatedModal
407475 isOpen = { showActivatedModal }
408- onClose = { ( ) => setShowActivatedModal ( false ) }
476+ onClose = { hideActivateModal }
409477 badge = { badgeDetailsHandler . data }
410478 />
411479 )
0 commit comments