import * as React from "react" ; import Button from "react-bootstrap/esm/Button" ; import "../scss/Championleaderboard.scss" ; import { Dropdown , IDropdownStyles } from "office-ui-fabric-react/lib/Dropdown" ; import { TextField } from "office-ui-fabric-react/lib/TextField" ; import * as _ from "lodash" ; import { sp } from "@pnp/sp" ; import { SPHttpClient , SPHttpClientResponse , ISPHttpClientOptions , } from "@microsoft/sp-http" ; import "@pnp/sp/webs" ; import "@pnp/sp/lists" ; import "@pnp/sp/items" ; import { Icon , initializeIcons } from "office-ui-fabric-react" ; import siteconfig from "../config/siteconfig.json" ; initializeIcons ( ) ; export interface ISidebarStateProps { becomec : boolean ; context ? : any ; onClickCancel : ( ) => void ; callBack ? : Function ; siteUrl : string ; } interface IUserDetail { ID : number ; LoginName : string ; } export class ISPLists { public value : ISPList [ ] ; } export class ISPList { public Title : string ; public FirstName : string ; public LastName : string ; public Country : string ; public Status : string ; public Role : string ; public Region : string ; public Points : number ; public Group : string ; public FocusArea : string ; } interface IState { currentUser : ISPList ; list : ISPLists ; isAddChampion : boolean ; SuccessMessage : string ; UserDetails : Array < any > ; selectedUsers : Array < any > ; bc : boolean ; siteUrl : string ; user : any ; isLoaded : boolean ; form : boolean ; totalUserPointsfromList : number ; totalUsers : number ; userRank : number ; isActive : boolean ; coutries : Array < any > ; regions : Array < any > ; users : Array < any > ; roles : Array < any > ; status : Array < any > ; memberData : any ; buttonText : any ; bFlag : boolean ; isMember : boolean ; emailValue : string ; sitename : string ; inclusionpath : string ; edetails : Array < string > ; edetailsIds : Array < EventList > ; } export interface EventList { Title : string ; Id : number ; } let displayName = "" ; export default class Sidebar extends React . Component < ISidebarStateProps , IState > { constructor ( props ) { super ( props ) ; sp . setup ( { spfxContext : this . props . context , } ) ; this . state = { user : { } , bc : this . props . becomec , form : false , siteUrl : this . props . siteUrl , isLoaded : false , list : null , isAddChampion : false , SuccessMessage : "" , UserDetails : [ ] , currentUser : new ISPList ( ) , selectedUsers : [ ] , totalUserPointsfromList : 0 , isActive : false , totalUsers : 0 , userRank : 0 , coutries : [ ] , regions : [ ] , users : [ ] , roles : [ ] , status : [ ] , memberData : { region : "" , role : "" , status : "" , country : "" } , buttonText : "Become a Champion" , bFlag : true , isMember : false , emailValue : "" , sitename : siteconfig . sitename , inclusionpath : siteconfig . inclusionPath , edetails : [ ] , edetailsIds : [ ] , } ; this . handleInput = this . handleInput . bind ( this ) ; this . _createorupdateItem = this . _createorupdateItem . bind ( this ) ; this . _getPeoplePickerItems = this . _getPeoplePickerItems . bind ( this ) ; this . _getListData = this . _getListData . bind ( this ) ; this . optionsEventsList = this . optionsEventsList . bind ( this ) ; } public options = ( optionArray ) => { let myoptions = [ ] ; myoptions . push ( { key : "All" , text : "All" } ) ; optionArray . forEach ( ( element ) => { myoptions . push ( { key : element , text : element } ) ; } ) ; return myoptions ; } ; public optionsEventsList ( ) { let optionArray = [ ] ; let optionArrayIds = [ ] ; if ( this . state . edetails . length == 0 ) this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Events List')/Items" , SPHttpClient . configurations . v1 ) . then ( async ( response ) => { if ( response . status === 200 ) { await response . json ( ) . then ( ( responseJSON ) => { let i = 0 ; while ( i < responseJSON . value . length ) { if ( responseJSON . value [ i ] && responseJSON . value [ i ] . hasOwnProperty ( "Title" ) && responseJSON . value [ i ] . IsActive ) { optionArray . push ( responseJSON . value [ i ] . Title ) ; optionArrayIds . push ( { Title : responseJSON . value [ i ] . Title , Id : responseJSON . value [ i ] . Id , } ) ; } i ++ ; } this . setState ( { edetails : optionArray , edetailsIds : optionArrayIds , } ) ; } ) ; } } ) . catch ( ( ) => { throw new Error ( "Asynchronous error" ) ; } ) ; let myOptions = [ ] ; myOptions . push ( { key : "Select Event Type" , text : "Select Event Type" } ) ; this . state . edetails . forEach ( ( element ) => { myOptions . push ( { key : element , text : element } ) ; } ) ; return myOptions ; } public dropdownStyles : Partial < IDropdownStyles > = { dropdown : { width : "auto" } , } ; public handleInput ( event , key ) { let user = this . state . currentUser ; user [ key ] = event . target . value ; this . setState ( { currentUser : user } ) ; } public componentDidMount ( ) { this . optionsEventsList ( ) ; this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/fields/GetByInternalNameOrTitle('Region')" , SPHttpClient . configurations . v1 ) . then ( ( response ) => { response . json ( ) . then ( ( regions ) => { if ( ! regions . error ) { this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/fields/GetByInternalNameOrTitle('Country')" , SPHttpClient . configurations . v1 ) . then ( ( response ) => { response . json ( ) . then ( ( coutries ) => { if ( ! coutries . error ) { this . setState ( { regions : regions . Choices , coutries : coutries . Choices , } ) ; } } ) ; } ) ; } } ) ; } ) ; this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/fields/GetByInternalNameOrTitle('Group')" , SPHttpClient . configurations . v1 ) . then ( ( response ) => { response . json ( ) . then ( ( roles ) => { if ( ! roles . error ) { this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/fields/GetByInternalNameOrTitle('FocusArea')" , SPHttpClient . configurations . v1 ) . then ( ( response ) => { response . json ( ) . then ( ( status ) => { if ( ! status . error ) { this . setState ( { roles : roles . Choices , status : status . Choices , } ) ; } } ) ; } ) ; } } ) ; } ) ; } public componentDidUpdate ( prevPro ) { if ( prevPro != this . props ) { this . componentWillMount ( ) ; } } public componentWillMount ( ) { this . props . context . spHttpClient . get ( "/_api/SP.UserProfiles.PeopleManager/GetMyProperties" , SPHttpClient . configurations . v1 ) . then ( ( responseuser ) => { responseuser . json ( ) . then ( ( datauser ) => { if ( ! datauser . error ) { this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/Items?$top=1000" , SPHttpClient . configurations . v1 ) . then ( ( response ) => { response . json ( ) . then ( ( datada ) => { let memberDataIds = datada . value . find ( ( d ) => d . Title . toLowerCase ( ) === datauser . Email . toLowerCase ( ) ) ; let memberData = memberDataIds !== undefined ? memberDataIds . ID : 0 ; if ( memberData === 0 ) this . setState ( { emailValue : datauser . Email , isMember : false , buttonText : "Become a Champion" , isLoaded : true , } ) ; else this . setState ( { emailValue : datauser . Email , isMember : true , buttonText : "Champion submission pending" , isLoaded : true , } ) ; localStorage . setItem ( "memberid" , memberData ) ; let user = this . state . currentUser ; user [ "FirstName" ] = datauser . DisplayName . split ( " " ) [ 0 ] . replace ( "," , "" ) ; user [ "LastName" ] = datauser . DisplayName . split ( " " ) [ 1 ] ; user [ "Title" ] = datauser . Email ; user [ "Country" ] = datauser . Country ; user [ "Region" ] = datauser . Region ; user [ "Group" ] = datauser . Group ; user [ "FocusArea" ] = datauser . FocusArea ; displayName = datauser . DisplayName . replace ( "," , "" ) ; this . setState ( { currentUser : user } ) ; if ( ! datada . error ) { let totalchamps = 0 ; totalchamps = datada . value . filter ( ( x ) => ( x . Role . toLowerCase ( ) === "champion" || x . Role . toLowerCase ( ) === "manager" ) && x . Status !== null && x . Status !== undefined ? x . Status . toLowerCase ( ) === "approved" : false ) . length ; if ( this . state . isMember === true && ( memberDataIds . Role == "Champion" || memberDataIds . Role === "Manager" ) && memberDataIds . Status === "Approved" ) this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Event Track Details')/Items?$top=5000" , SPHttpClient . configurations . v1 ) . then ( ( responseeventsdetails ) => { responseeventsdetails . json ( ) . then ( ( eventsdatauser ) => { if ( ! eventsdatauser . error ) { let presentuser = eventsdatauser . value . filter ( ( x ) => x . MemberId === datada . value . find ( ( d ) => d . Title . toLowerCase ( ) === datauser . Email . toLowerCase ( ) ) . ID ) ; let memberids = _ . uniqBy ( eventsdatauser . value , "MemberId" ) ; let counts = _ . countBy ( eventsdatauser . value , "MemberId" ) ; let memcount = [ ] ; if ( presentuser . length === 0 && memberData !== 0 ) { let eventItem = null ; eventItem = this . state . edetailsIds [ 0 ] ; const listDefinition = { Title : eventItem . Title , EventId : eventItem . Id , MemberId : memberData , DateofEvent : new Date ( ) , Count : 10 , MemberName : datauser . DisplayName , EventName : eventItem . Title } ; const spHttpClientOptions = { body : JSON . stringify ( listDefinition ) , } ; if ( true ) { const url = "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Event Track Details')/items" ; this . props . context . spHttpClient . post ( url , SPHttpClient . configurations . v1 , spHttpClientOptions ) ; memcount . push ( { id : memberData , points : 10 , } ) ; } } for ( let i = 0 ; i < memberids . length ; i ++ ) { if ( datada . value . findIndex ( ( v ) => v . ID === memberids [ i ] . MemberId ) !== - 1 ) { let totalUserPoints = 0 ; eventsdatauser . value . filter ( ( z ) => z . MemberId === memberids [ i ] . MemberId ) . map ( ( z ) => { totalUserPoints = totalUserPoints + z . Count ; } ) ; memcount . push ( { id : memberids [ i ] . MemberId , points : totalUserPoints , } ) ; } } let pointsTotal = 0 ; let rank ; memcount . sort ( ( x , y ) => y . points - x . points ) . map ( ( x , ind ) => { if ( x . id === datada . value . find ( ( d ) => d . Title . toLowerCase ( ) === datauser . Email . toLowerCase ( ) ) . ID ) { rank = ind + 1 ; pointsTotal = x . points ; } } ) ; this . setState ( { user : datauser , isLoaded : true , totalUserPointsfromList : pointsTotal , totalUsers : totalchamps , userRank : rank , } ) ; if ( presentuser . length === 0 ) { this . props . callBack ( ) ; } } } ) ; } ) ; } } ) ; } ) ; } } ) ; } ) ; } public onRenderCaretDown = ( ) : JSX . Element => { return < span > < /span>; } ; public async _createorupdateItem ( ) { let usersave = this . state . currentUser ; usersave . Country = this . state . memberData . country ; usersave . Region = this . state . memberData . region ; usersave . FocusArea = this . state . memberData . focusarea ; usersave . Group = this . state . memberData . group ; usersave . Role = "Champion" ; usersave . Status = "Pending" ; const spHttpClientOptions = { body : JSON . stringify ( usersave ) , } ; let flag = await this . _getListData ( usersave . Title ) ; if ( flag == 0 ) { const url = "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/items" ; if ( this . props . context ) this . props . context . spHttpClient . post ( url , SPHttpClient . configurations . v1 , spHttpClientOptions ) . then ( ( response ) => { if ( response . status === 201 ) { alert ( "Champion request submission successful" ) ; { this . props . onClickCancel ( ) ; } } else { alert ( "Response status " + response . status + " - " + response . statusText ) ; } } ) ; } else { alert ( "Record Already Exist" ) ; { this . props . onClickCancel ( ) ; } } this . setState ( { currentUser : new ISPList ( ) , } ) ; this . setState ( { isActive : ! this . state . isActive , form : ! this . state . form } ) ; } private async _getListData ( email ) { return this . props . context . spHttpClient . get ( "/" + this . state . inclusionpath + "/" + this . state . sitename + "/_api/web/lists/GetByTitle('Member List')/Items?$filter=Title eq '" + email . toLowerCase ( ) + "'" , SPHttpClient . configurations . v1 ) . then ( async ( response ) => { if ( response . status === 200 ) { let flag = 0 ; await response . json ( ) . then ( ( responseJSON ) => { let i = 0 ; while ( i < responseJSON . value . length ) { if ( responseJSON . value [ i ] . Title . toLowerCase ( ) == email . toLowerCase ( ) ) { flag = 1 ; return flag ; } i ++ ; } return flag ; } ) ; return flag ; } } ) ; } public addDefaultSrc ( ev ) { ev . target . src = require ( "../assets/images/noprofile.png" ) ; } private _getPeoplePickerItems ( items ) { let userarr = [ ] ; items . forEach ( ( user ) => { userarr . push ( { ID : user . id , LoginName : user . loginName } ) ; user [ "FirstName" ] = user . text . split ( "," ) [ 0 ] || "" ; user [ "LastName" ] = user . text . split ( "," ) [ 1 ] || "" ; user [ "Title" ] = user . loginName . split ( "|" ) [ 2 ] || "" ; this . setState ( { currentUser : user } ) ; } ) ; this . setState ( { UserDetails : userarr } ) ; } public filterUsers ( type , value ) { if ( value . target . innerText !== "All" ) { this . setState ( { memberData : { ... this . state . memberData , [ type ] : value . target . innerText , } , } ) ; } } public render ( ) { return ( < div className = "Championleaderboard" > { this . state . isLoaded && ( < div className = "sidenav" > < div className = "back-btn" onClick = { this . props . onClickCancel } > < Icon iconName = "ChevronLeftSmall" id = "chevLeft" / > < span className = "backText" title = "Back" > Back < /span> < /div> < div > { } < img src = { "/_layouts/15/userphoto.aspx?username=" + this . state . emailValue } className = "profilepic" onError = { this . addDefaultSrc } / > { } < div className = "championname" > { displayName } < /div> < /div> { ! this . state . bc && ! this . state . form && ( < div > { } < div className = "pointcircle" > < div className = "insidecircle" > < div className = "pointsscale" > < div > < Icon iconName = "FavoriteStarFill" id = "star" className = "yellowStar" / > < /div> < div > { this . state . totalUserPointsfromList } Points < /div> < /div> < div className = "line" > < /div> < div className = "globalrank" > < span className = "bold" > { this . state . userRank } < /span> Global Rank <br / > of { this . state . totalUsers } Champions < /div> < /div> < /div> < /div>)} { this . state . bc && ( < div > { < Button variant = "primary" className = "bc-btn" disabled = { this . state . isMember ? true : false } onClick = { ( ) => this . setState ( { form : ! this . state . form , isActive : ! this . state . isActive , } ) } > < span > { this . state . buttonText } < /span> < /Button>} < /div>)} { this . state . form && this . state . isActive && ( < div > < div className = "bc-form" > < label htmlFor = "fname" className = "bc-label" > First Name < /label> < TextField value = { this . state . currentUser . FirstName ? this . state . currentUser . FirstName : "" } onChange = { ( evt ) => this . handleInput ( evt , "FirstName" ) } /> < label htmlFor = "lname" className = "bc-label" > Last Name < /label> < TextField value = { this . state . currentUser . LastName ? this . state . currentUser . LastName : "" } onChange = { ( evt ) => this . handleInput ( evt , "LastName" ) } /> < label htmlFor = "email" className = "bc-label" > Email Id < /label> < TextField value = { this . state . currentUser . Title ? this . state . currentUser . Title : "" } onChange = { ( evt ) => this . handleInput ( evt , "Title" ) } /> < label htmlFor = "Region" className = "bc-label" > Region < /label> < Dropdown onChange = { ( event ) => this . filterUsers ( "region" , event ) } placeholder = "Select an Region" options = { this . options ( this . state . regions ) } styles = { this . dropdownStyles } onRenderCaretDown = { this . onRenderCaretDown } defaultValue = { this . state . currentUser . Region } / > < label htmlFor = "Country" className = "bc-label" > Country < /label> < Dropdown onChange = { ( event ) => this . filterUsers ( "country" , event ) } placeholder = "Select an Country" options = { this . options ( this . state . coutries ) } styles = { this . dropdownStyles } onRenderCaretDown = { this . onRenderCaretDown } defaultValue = { this . state . currentUser . Country } / > < label htmlFor = "Focus Area" className = "bc-label" > Focus Area < /label> < Dropdown onChange = { ( event ) => this . filterUsers ( "focusarea" , event ) } placeholder = "Select Focus Area" options = { this . options ( this . state . status ) } styles = { this . dropdownStyles } onRenderCaretDown = { this . onRenderCaretDown } defaultValue = { this . state . currentUser . FocusArea } / > < label htmlFor = "Group" className = "bc-label" > Group < /label> < Dropdown onChange = { ( event ) => this . filterUsers ( "group" , event ) } placeholder = "Select Group" options = { this . options ( this . state . roles ) } styles = { this . dropdownStyles } onRenderCaretDown = { this . onRenderCaretDown } defaultValue = { this . state . currentUser . Group } / > < Button className = "sub-btn" type = "reset" onClick = { ( ) => this . _createorupdateItem ( ) } > Submit < /Button> < /div> < /div>)} < /div>)} < /div>); } }