src/app/profile/profile.page.ts
                OnInit
    
| providers | 
                            CertificateDownloadAsPdfService
                 | 
            
| selector | app-profile | 
            
| styleUrls | ./profile.page.scss | 
            
| templateUrl | ./profile.page.html | 
            
constructor(profileService: ProfileService, authService: AuthService, contentService: ContentService, courseService: CourseService, formService: FormService, frameworkService: FrameworkService, certificateService: CertificateService, zone: NgZone, router: Router, popoverCtrl: PopoverController, events: Events, appGlobalService: AppGlobalService, telemetryGeneratorService: TelemetryGeneratorService, formAndFrameworkUtilService: FormAndFrameworkUtilService, commonUtilService: CommonUtilService, socialSharing: SocialSharing, headerService: AppHeaderService, permissionService: AndroidPermissionsService, appVersion: AppVersion, navService: NavigationService, sbProgressLoader: SbProgressLoader, fileOpener: FileOpener, toastController: ToastController, translate: TranslateService, certificateDownloadAsPdfService: CertificateDownloadAsPdfService, profileHandler: ProfileHandler, segmentationTagService: SegmentationTagService, platform: Platform, locationHandler: LocationHandler, unnatiDataService: UnnatiDataService)
                     | 
                |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 
                                 Defined in src/app/profile/profile.page.ts:163 
                             | 
                        |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 
                             
                                    Parameters :
                                     
                    
  | 
                
| Private Async callOTPPopover | ||||||||||||||||
                    
                    callOTPPopover(type: string, key?: any, updateContact: boolean)
                 | 
            ||||||||||||||||
| 
                     Defined in src/app/profile/profile.page.ts:874 
                 | 
            ||||||||||||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :      
                    unknown
                     | 
            
| Private Async checkForPermissions | 
                    
                    checkForPermissions()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1063 
                 | 
            
| 
                     
                        Returns :      
                Promise<boolean | undefined>
                     | 
            
| Private dismissMessage | 
                    
                    dismissMessage()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:988 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| Async doRefresh | ||||
                    
                    doRefresh(refresher?)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:256 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :      
                    unknown
                     | 
            
| downloadCertificate | ||||||
downloadCertificate(data, type?)
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:590 
                 | 
            ||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| Private Async downloadLegacyCertificate | ||||||
                    
                    downloadLegacyCertificate(course, toast)
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:670 
                 | 
            ||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| Async downloadTrainingCertificate | ||||||
                    
                    downloadTrainingCertificate(course: literal type)
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:617 
                 | 
            ||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| Async editEmail | 
                    
                    editEmail()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:813 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| Async editMobileNumber | 
                    
                    editMobileNumber()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:799 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| Async editRecoveryId | 
                    
                    editRecoveryId()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1015 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| formatRoles | 
formatRoles()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:384 
                 | 
            
| 
                     Method to store all roles from different organizations into single array 
                        Returns :          
                void
                     | 
            
| Private getCategories | 
                    
                    getCategories()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1276 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| Async getEnrolledCourses | ||||||
                    
                    getEnrolledCourses(refresher?, refreshCourseList?)
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:474 
                 | 
            ||||||
| 
                     To get enrolled course(s) of logged-in user i.e, trainings in the UI. It internally calls course handler of genie sdk 
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| getFieldDisplayValues | 
getFieldDisplayValues(field: Array
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1256 
                 | 
            
| 
                    
                     
                        Returns :      
                    any[]
                     | 
            
| Private Async getFrameworkDetails | 
                    
                    getFrameworkDetails()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1221 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| Async getLearnerPassbook | 
                    
                    getLearnerPassbook()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:542 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| getOrgDetails | 
getOrgDetails()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:996 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| getProjectsCertificate | 
getProjectsCertificate()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1282 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| Async getSelfDeclaredDetails | 
                    
                    getSelfDeclaredDetails()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1165 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| Private Async handleCertificateDownloadIssue | 
                    
                    handleCertificateDownloadIssue(toast: any, err: any)
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:686 
                 | 
            
| 
                    
                     
                        Returns :          
                    any
                     | 
            
| handleHeaderEvents | ||||
handleHeaderEvents($event)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:950 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| ionViewDidEnter | 
ionViewDidEnter()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:252 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| ionViewWillEnter | 
ionViewWillEnter()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:235 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| ionViewWillLeave | 
ionViewWillLeave()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:246 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| mapTrainingsToCertificates | ||||||
mapTrainingsToCertificates(trainings: Course[])
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:505 
                 | 
            ||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| navigateToCategoriesEditPage | 
navigateToCategoriesEditPage()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:755 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| navigateToDetailPage | 
navigateToDetailPage(content: any, layoutName: string, index: number)
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:712 
                 | 
            
| 
                     Navigate to the course/content details page 
                        Returns :          
                    void
                     | 
            
| Async ngOnInit | 
                    
                    ngOnInit()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:229 
                 | 
            
| 
                     
                        Returns :          
                any
                     | 
            
| onEditProfileClicked | 
onEditProfileClicked()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:767 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| Private Async openContactVerifyPopup | ||||||||
                    
                    openContactVerifyPopup(component, componentProps, cssClass)
                 | 
            ||||||||
| 
                     Defined in src/app/profile/profile.page.ts:911 
                 | 
            ||||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :      
                    unknown
                     | 
            
| Async openEnrolledCourse | ||||
                    
                    openEnrolledCourse(training)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:1049 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| openpdf | ||||
openpdf(path)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:699 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| openSelfDeclareTeacherForm | ||||
openSelfDeclareTeacherForm(type)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:1141 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| Async projectCertificateDownload | ||||
                    
                    projectCertificateDownload(project)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:597 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| Private redirectToActiveDownloads | 
                    
                    redirectToActiveDownloads()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:956 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| refreshProfileData | ||||
refreshProfileData(refresher?)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:301 
                 | 
            ||||
| 
                     To refresh Profile data on pull to refresh or on click on the profile 
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| resetProfile | 
resetProfile()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:294 
                 | 
            
| 
                     To reset Profile Before calling new fresh API for Profile 
                        Returns :          
                void
                     | 
            
| Async searchContent | 
                    
                    searchContent()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:774 
                 | 
            
| 
                     Searches contents created by the user 
                        Returns :          
                any
                     | 
            
| shareUsername | 
shareUsername()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1208 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| Private Async showEditContactPopup | ||||
                    
                    showEditContactPopup(componentProps)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:859 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| showLessBadges | 
showLessBadges()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:432 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| showLessItems | 
showLessItems()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:419 
                 | 
            
| 
                     To show Less items in skills list DEFAULT_PAGINATION_LIMIT = 10 
                        Returns :          
                void
                     | 
            
| showLessTrainings | ||||
showLessTrainings(listName)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:456 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| showMoreBadges | 
showMoreBadges()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:423 
                 | 
            
| 
                     
                        Returns :          
                void
                     | 
            
| showMoreItems | 
showMoreItems()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:406 
                 | 
            
| 
                     To show more Items in skills list 
                        Returns :          
                void
                     | 
            
| Async showMoreTrainings | ||||
                    
                    showMoreTrainings(listName)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:436 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :      
                    Promise<void>
                     | 
            
| Private Async showStoragePermissionPopup | 
                    
                    showStoragePermissionPopup()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:1088 
                 | 
            
| 
                     
                        Returns :      
                Promise<boolean | undefined>
                     | 
            
| toggleTooltips | ||||||
toggleTooltips(event, field)
                 | 
            ||||||
| 
                     Defined in src/app/profile/profile.page.ts:966 
                 | 
            ||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| Private Async updateEmailInfo | ||||
                    
                    updateEmailInfo(email)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:928 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| updateLocalProfile | ||||
updateLocalProfile(framework)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:739 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    void
                     | 
            
| Private Async updatePhoneInfo | ||||
                    
                    updatePhoneInfo(phone)
                 | 
            ||||
| 
                     Defined in src/app/profile/profile.page.ts:919 
                 | 
            ||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| Private Async updateProfile | |||||||||
                    
                    updateProfile(request: UpdateServerProfileInfoRequest, successMessage: string)
                 | 
            |||||||||
| 
                     Defined in src/app/profile/profile.page.ts:937 
                 | 
            |||||||||
| 
                     
                        Parameters :
                        
                         
                    
 
                        Returns :          
                    any
                     | 
            
| Private Async validateAndEditContact | 
                    
                    validateAndEditContact()
                 | 
            
| 
                     Defined in src/app/profile/profile.page.ts:834 
                 | 
            
| 
                     
                        Returns :      
                Promise<boolean>
                     | 
            
| appName | 
                        Type :         string
                     | 
                
                        Default value : ''
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:111 
                         | 
                    
| badgesLimit | 
                        Type :         number
                     | 
                
                        Default value : 2
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:123 
                         | 
                    
| boardList | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:112 
                         | 
                    
| categories | 
                        Type :         any
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:160 
                         | 
                    
| checked | 
                        Default value : false
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:104 
                         | 
                    
| contentCreatedByMe | 
                        Type :         any
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:132 
                         | 
                    
| custodianOrgId | 
                        Type :         string
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:128 
                         | 
                    
| Readonly DEFAULT_ENROLLED_COURSE_LIMIT | 
                        Type :         number
                     | 
                
                        Default value : 3
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:120 
                         | 
                    
| Readonly DEFAULT_PAGINATION_LIMIT | 
                        Type :         number
                     | 
                
                        Default value : 3
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:119 
                         | 
                    
| Readonly DEFAULT_PROJECTS_LIMIT | 
                        Type :         number
                     | 
                
                        Default value : 1
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:121 
                         | 
                    
| enrolledCourseList | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:159 
                         | 
                    
| Private frameworkCategoriesMap | 
                        Type :     literal type
                     | 
                
                        Default value : {}
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:94 
                         | 
                    
| gradeLevelList | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:114 
                         | 
                    
| headerObservable | 
                        Type :         any
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:140 
                         | 
                    
| imageUri | 
                        Type :         string
                     | 
                
                        Default value : 'assets/imgs/ic_profile_default.png'
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:117 
                         | 
                    
| informationOrgName | 
                        Default value : false
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:103 
                         | 
                    
| informationProfileName | 
                        Default value : false
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:102 
                         | 
                    
| isCustodianOrgId | 
                        Type :         boolean
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:129 
                         | 
                    
| isDefaultChannelProfile | 
                        Type :         boolean
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:153 
                         | 
                    
| isLoggedInUser | 
                        Default value : false
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:100 
                         | 
                    
| isRefreshProfile | 
                        Default value : false
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:101 
                         | 
                    
| isStateValidated | 
                        Type :         boolean
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:130 
                         | 
                    
| layoutPopular | 
                        Default value : ContentCard.LAYOUT_POPULAR
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:139 
                         | 
                    
| learnerPassbook | 
                        Type :     any[]
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:157 
                         | 
                    
| learnerPassbookCount | 
                        Type :         any
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:158 
                         | 
                    
| learnerPassbookLimit | 
                        Default value : this.DEFAULT_ENROLLED_COURSE_LIMIT
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:126 
                         | 
                    
| loggedInUserId | 
                        Type :         string
                     | 
                
                        Default value : ''
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:105 
                         | 
                    
| mappedTrainingCertificates | 
                        Type :     literal type[]
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:142 
                         | 
                    
| mediumList | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:113 
                         | 
                    
| myImprovementsLimit | 
                        Default value : this.DEFAULT_PROJECTS_LIMIT
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:125 
                         | 
                    
| myLearningLimit | 
                        Default value : this.DEFAULT_ENROLLED_COURSE_LIMIT
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:124 
                         | 
                    
| onProfile | 
                        Default value : true
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:108 
                         | 
                    
| organisationName | 
                        Type :         string
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:131 
                         | 
                    
| orgDetails | 
                        Type :     literal type
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:133 
                         | 
                    
| personaTenantDeclaration | 
                        Type :         string
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:154 
                         | 
                    
| profile | 
                        Type :         any
                     | 
                
                        Default value : {}
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:98 
                         | 
                    
| profileName | 
                        Type :         string
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:107 
                         | 
                    
| projects | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:161 
                         | 
                    
| projectsCount | 
                        Type :         number
                     | 
                
                        Default value : 0
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:162 
                         | 
                    
| projectStatus | 
                        Default value : statusType
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:163 
                         | 
                    
| refresh | 
                        Type :         boolean
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:106 
                         | 
                    
| refresher | 
                        Type :     IonRefresher
                     | 
                
                        Decorators : 
                        
                            @ViewChild('refresher', {static: false})
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:96 
                         | 
                    
| roles | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:109 
                         | 
                    
| rolesLimit | 
                        Type :         number
                     | 
                
                        Default value : 2
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:122 
                         | 
                    
| selfDeclarationInfo | 
                        Type :         any
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:156 
                         | 
                    
| selfDeclaredDetails | 
                        Type :     any[]
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:155 
                         | 
                    
| startLimit | 
                        Type :         number
                     | 
                
                        Default value : 0
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:127 
                         | 
                    
| subjectList | 
                        Type :     []
                     | 
                
                        Default value : []
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:115 
                         | 
                    
| timer | 
                        Type :         any
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:141 
                         | 
                    
| userId | 
                        Type :         string
                     | 
                
                        Default value : ''
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:99 
                         | 
                    
| userLocation | 
                        Type :         object
                     | 
                
                        Default value : {}
                     | 
                
| 
                                 Defined in src/app/profile/profile.page.ts:110 
                         | 
                    
import { Component, NgZone, OnInit, Inject, ViewChild } from '@angular/core';
import {
  PopoverController,
  ToastController,
  IonRefresher,
  Platform,
} from '@ionic/angular';
import { Events } from '@app/util/events';
import {
  ContentCard,
  ProfileConstants,
  RouterLinks,
  ContentFilterConfig,
  EventTopics,
  OTPTemplates
} from '@app/app/app.constant';
import { FormAndFrameworkUtilService } from '@app/services/formandframeworkutil.service';
import { AppGlobalService } from '@app/services/app-global-service.service';
import { CommonUtilService } from '@app/services/common-util.service';
import { TelemetryGeneratorService } from '@app/services/telemetry-generator.service';
import { AppHeaderService } from '@app/services/app-header.service';
import {
  AuthService,
  ContentSearchCriteria,
  ContentSearchResult,
  ContentService,
  ContentSortCriteria,
  Course,
  CourseService,
  OAuthSession,
  ProfileService,
  SearchType,
  ServerProfileDetailsRequest,
  SortOrder,
  TelemetryObject,
  UpdateServerProfileInfoRequest,
  CachedItemRequestSourceFrom,
  CourseCertificate,
  CertificateAlreadyDownloaded,
  NetworkError,
  FormService,
  FrameworkService,
  ProfileType,
  Batch,
  GetLearnerCerificateRequest,
  GenerateOtpRequest,
  CertificateService,
  CSGetLearnerCerificateRequest,
  CsLearnerCertificate,
  Framework,
  FrameworkCategoryCodesGroup,
  FrameworkDetailsRequest
} from 'sunbird-sdk';
import { Environment, InteractSubtype, InteractType, PageId, ID } from '@app/services/telemetry-constants';
import { Router } from '@angular/router';
import { EditContactVerifyPopupComponent } from '@app/app/components/popups/edit-contact-verify-popup/edit-contact-verify-popup.component';
import {
  EditContactDetailsPopupComponent
} from '@app/app/components/popups/edit-contact-details-popup/edit-contact-details-popup.component';
import {
  AccountRecoveryInfoComponent
} from '../components/popups/account-recovery-id/account-recovery-id-popup.component';
import { SocialSharing } from '@ionic-native/social-sharing/ngx';
import { AndroidPermissionsService } from '@app/services';
import {
  AndroidPermissionsStatus,
  AndroidPermission
} from '@app/services/android-permissions/android-permission';
import { AppVersion } from '@ionic-native/app-version/ngx';
import { SbProgressLoader } from '@app/services/sb-progress-loader.service';
import { FileOpener } from '@ionic-native/file-opener/ngx';
import { TranslateService } from '@ngx-translate/core';
import { FieldConfig } from 'common-form-elements';
import { CertificateDownloadAsPdfService } from 'sb-svg2pdf';
import { NavigationService } from '@app/services/navigation-handler.service';
import { ContentUtil } from '@app/util/content-util';
import { CsPrimaryCategory } from '@project-sunbird/client-services/services/content';
import { FormConstants } from '../form.constants';
import { ProfileHandler } from '@app/services/profile-handler';
import { SegmentationTagService, TagPrefixConstants } from '@app/services/segmentation-tag/segmentation-tag.service';
import { OrganizationSearchCriteria } from '@project-sunbird/sunbird-sdk';
import { FrameworkCategory } from '@project-sunbird/client-services/models/channel';
import { LocationHandler } from '@app/services/location-handler';
import { urlConstants } from '../manage-learn/core/constants/urlConstants';
import { UnnatiDataService } from '../manage-learn/core/services/unnati-data.service';
import { statusType } from '../manage-learn/core';
@Component({
  selector: 'app-profile',
  templateUrl: './profile.page.html',
  styleUrls: ['./profile.page.scss'],
  providers: [CertificateDownloadAsPdfService]
})
export class ProfilePage implements OnInit {
  private frameworkCategoriesMap: { [code: string]: FrameworkCategory | undefined } = {};
  @ViewChild('refresher', { static: false }) refresher: IonRefresher;
  profile: any = {};
  userId = '';
  isLoggedInUser = false;
  isRefreshProfile = false;
  informationProfileName = false;
  informationOrgName = false;
  checked = false;
  loggedInUserId = '';
  refresh: boolean;
  profileName: string;
  onProfile = true;
  roles = [];
  userLocation = {};
  appName = '';
  boardList = [];
  mediumList = [];
  gradeLevelList = [];
  subjectList = [];
  imageUri = 'assets/imgs/ic_profile_default.png';
  readonly DEFAULT_PAGINATION_LIMIT = 3;
  readonly DEFAULT_ENROLLED_COURSE_LIMIT = 3;
  readonly DEFAULT_PROJECTS_LIMIT = 1;
  rolesLimit = 2;
  badgesLimit = 2;
  myLearningLimit = this.DEFAULT_ENROLLED_COURSE_LIMIT;
  myImprovementsLimit = this.DEFAULT_PROJECTS_LIMIT;
  learnerPassbookLimit = this.DEFAULT_ENROLLED_COURSE_LIMIT;
  startLimit = 0;
  custodianOrgId: string;
  isCustodianOrgId: boolean;
  isStateValidated: boolean;
  organisationName: string;
  contentCreatedByMe: any = [];
  orgDetails: {
    'state': string,
    'district': string,
    'block': string
  };
  layoutPopular = ContentCard.LAYOUT_POPULAR;
  headerObservable: any;
  timer: any;
  mappedTrainingCertificates: {
    courseName: string,
    batch: Batch,
    dateTime: string,
    courseId: string,
    certificate?: string,
    issuedCertificate?: string,
    status: number,
    style: string,
    label: string
  }[] = [];
  isDefaultChannelProfile: boolean;
  personaTenantDeclaration: string;
  selfDeclaredDetails: any[] = [];
  selfDeclarationInfo: any;
  learnerPassbook: any[] = [];
  learnerPassbookCount: any;
  enrolledCourseList = [];
  categories: any;
  projects=[];
  projectsCount =0;
  projectStatus =statusType;
  constructor(
    @Inject('PROFILE_SERVICE') private profileService: ProfileService,
    @Inject('AUTH_SERVICE') private authService: AuthService,
    @Inject('CONTENT_SERVICE') private contentService: ContentService,
    @Inject('COURSE_SERVICE') private courseService: CourseService,
    @Inject('FORM_SERVICE') private formService: FormService,
    @Inject('FRAMEWORK_SERVICE') private frameworkService: FrameworkService,
    @Inject('CERTIFICATE_SERVICE') private certificateService: CertificateService,
    private zone: NgZone,
    private router: Router,
    private popoverCtrl: PopoverController,
    private events: Events,
    private appGlobalService: AppGlobalService,
    private telemetryGeneratorService: TelemetryGeneratorService,
    private formAndFrameworkUtilService: FormAndFrameworkUtilService,
    private commonUtilService: CommonUtilService,
    private socialSharing: SocialSharing,
    private headerService: AppHeaderService,
    private permissionService: AndroidPermissionsService,
    private appVersion: AppVersion,
    private navService: NavigationService,
    private sbProgressLoader: SbProgressLoader,
    private fileOpener: FileOpener,
    private toastController: ToastController,
    private translate: TranslateService,
    private certificateDownloadAsPdfService: CertificateDownloadAsPdfService,
    private profileHandler: ProfileHandler,
    private segmentationTagService: SegmentationTagService,
    private platform: Platform,
    private locationHandler: LocationHandler,
    private unnatiDataService : UnnatiDataService
  ) {
    const extrasState = this.router.getCurrentNavigation().extras.state;
    if (extrasState) {
      this.userId = extrasState.userId || '';
      this.isRefreshProfile = extrasState.returnRefreshedUserProfileDetails;
    }
    this.isLoggedInUser = !this.userId;
    // Event for optional and forceful upgrade
    this.events.subscribe('force_optional_upgrade', async (upgrade) => {
      if (upgrade) {
        await this.appGlobalService.openPopover(upgrade);
      }
    });
    this.events.subscribe('loggedInProfile:update', (framework) => {
      if (framework) {
        this.updateLocalProfile(framework);
        this.refreshProfileData();
      } else {
        this.doRefresh();
      }
    });
    this.events.subscribe(EventTopics.SIGN_IN_RELOAD, async (data) => {
      this.doRefresh();
    });
    this.formAndFrameworkUtilService.getCustodianOrgId().then((orgId: string) => {
      this.custodianOrgId = orgId;
    });
  }
  async ngOnInit() {
    this.getCategories();
    this.doRefresh();
    this.appName = await this.appVersion.getAppName();
  }
  ionViewWillEnter() {
    this.getCategories();
    this.events.subscribe('update_header', () => {
      this.headerService.showHeaderWithHomeButton();
    });
    this.headerObservable = this.headerService.headerEventEmitted$.subscribe(eventName => {
      this.handleHeaderEvents(eventName);
    });
    this.headerService.showHeaderWithHomeButton();
  }
  ionViewWillLeave(): void {
    this.headerObservable.unsubscribe();
    this.events.unsubscribe('update_header');
    this.refresher.disabled = true;
  }
  ionViewDidEnter() {
    this.refresher.disabled = false;
  }
  async doRefresh(refresher?) {
    const loader = await this.commonUtilService.getLoader();
    this.isRefreshProfile = true;
    if (!refresher) {
      await loader.present();
    } else if (refresher.target) {
      this.telemetryGeneratorService.generatePullToRefreshTelemetry(PageId.PROFILE, Environment.HOME);
      refresher.target.complete();
      this.refresh = true;
    }
    return this.refreshProfileData(refresher)
      .then(() => {
        return new Promise((resolve) => {
          setTimeout(async () => {
            this.events.publish('refresh:profile');
            this.refresh = false;
            await loader.dismiss();
            await this.sbProgressLoader.hide({ id: 'login' });
            resolve();
          }, 500);
          // This method is used to handle trainings completed by user
          this.getLearnerPassbook();
          this.getEnrolledCourses(refresher);
          this.searchContent();
          this.getSelfDeclaredDetails();
          this.getProjectsCertificate();
        });
      })
      .catch(async error => {
        this.refresh = false;
        await loader.dismiss();
      });
  }
  /**
   * To reset Profile Before calling new fresh API for Profile
   */
  resetProfile() {
    this.profile = {};
  }
  /**
   * To refresh Profile data on pull to refresh or on click on the profile
   */
  refreshProfileData(refresher?) {
    const that = this;
    return new Promise((resolve, reject) => {
      that.authService.getSession().toPromise().then((session: OAuthSession) => {
        if (session === null || session === undefined) {
          reject('session is null');
        } else {
          that.loggedInUserId = session.userToken;
          if (that.userId && session.userToken === that.userId) {
            that.isLoggedInUser = true;
          }
          const serverProfileDetailsRequest: ServerProfileDetailsRequest = {
            userId: that.userId && that.userId !== session.userToken ? that.userId : session.userToken,
            requiredFields: ProfileConstants.REQUIRED_FIELDS,
            from: CachedItemRequestSourceFrom.SERVER
          };
          if (that.isLoggedInUser) {
            that.isRefreshProfile = !that.isRefreshProfile;
          }
          that.profileService.getServerProfilesDetails(serverProfileDetailsRequest).toPromise()
            .then((profileData) => {
              that.zone.run(async () => {
                that.resetProfile();
                that.profile = profileData;
                // ******* Segmentation
                let segmentDetails = JSON.parse(JSON.stringify(profileData.framework));
                Object.keys(segmentDetails).forEach((key) => {
                  if (key !== 'id' && Array.isArray(segmentDetails[key])) {
                  segmentDetails[key] = segmentDetails[key].map( x => x.replace(/\s/g, '').toLowerCase());
                  }
                });
                window['segmentation'].SBTagService.pushTag(segmentDetails, TagPrefixConstants.USER_ATRIBUTE, true);
                let userLocation = [];
                (profileData['userLocations'] || []).forEach(element => {
                  userLocation.push({ name: element.name, code: element.code });
                });
                window['segmentation'].SBTagService.pushTag({ location: userLocation }, TagPrefixConstants.USER_LOCATION, true);
                window['segmentation'].SBTagService.pushTag(profileData.profileUserType.type, TagPrefixConstants.USER_LOCATION, true);
                this.segmentationTagService.evalCriteria();
                // *******
                that.frameworkService.setActiveChannelId(profileData.rootOrg.hashTagId).toPromise();
                that.isDefaultChannelProfile = await that.profileService.isDefaultChannelProfile().toPromise();
                const role: string = (!that.profile.profileUserType.type ||
                  (that.profile.profileUserType.type
                    && that.profile.profileUserType.type === ProfileType.OTHER.toUpperCase())) ? '' : that.profile.profileUserType.type;
                that.profile['persona'] =  await that.profileHandler.getPersonaConfig(role.toLowerCase());
                that.userLocation = that.commonUtilService.getUserLocation(that.profile);
                that.profile['subPersona'] = await that.profileHandler.getSubPersona(this.profile,
                      role.toLowerCase(), this.userLocation);
                that.profileService.getActiveSessionProfile({ requiredFields: ProfileConstants.REQUIRED_FIELDS }).toPromise()
                  .then((activeProfile) => {
                    that.formAndFrameworkUtilService.updateLoggedInUser(profileData, activeProfile)
                      .then((frameWorkData) => {
                        if (!frameWorkData['status']) {
                        }
                      });
                    that.formatRoles();
                    that.getOrgDetails();
                    that.isCustodianOrgId = (that.profile.rootOrg.rootOrgId === this.custodianOrgId);
                    that.isStateValidated = that.profile.stateValidated;
                    resolve();
                  });
                  if(profileData && profileData.framework && Object.keys(profileData.framework).length == 0) {
                    await this.getFrameworkDetails();
                  }
              });
            }).catch(err => {
              if (refresher) {
                refresher.target.complete();
              }
              reject();
            });
        }
      });
    });
  }
  /**
   * Method to store all roles from different organizations into single array
   */
  formatRoles() {
    this.roles = [];
    if (this.profile && this.profile.roleList) {
      const roles = {};
      this.profile.roleList.forEach((r) => {
        roles[r.id] = r;
      });
      if (this.profile.roles && this.profile.roles.length) {
        for (let i = 0, len = this.profile.roles.length; i < len; i++) {
          const roleKey = this.profile.roles[i].role;
          const val = roles[roleKey];
          if (val && val.name.toLowerCase() !== 'public') {
            this.roles.push(val.name);
          }
        }
      }
    }
  }
  /**
   * To show more Items in skills list
   */
  showMoreItems(): void {
    this.rolesLimit = this.roles.length;
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.VIEW_MORE_CLICKED,
      Environment.HOME,
      PageId.PROFILE, null);
  }
  /**
   * To show Less items in skills list
   * DEFAULT_PAGINATION_LIMIT = 10
   */
  showLessItems(): void {
    this.rolesLimit = this.DEFAULT_PAGINATION_LIMIT;
  }
  showMoreBadges(): void {
    this.badgesLimit = this.profile.badgeAssertions.length;
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.VIEW_MORE_CLICKED,
      Environment.HOME,
      PageId.PROFILE, null);
  }
  showLessBadges(): void {
    this.badgesLimit = this.DEFAULT_PAGINATION_LIMIT;
  }
  async showMoreTrainings(listName): Promise<void> {
    switch (listName) {
      case 'myLearning':
        this.myLearningLimit = this.mappedTrainingCertificates.length;
        break;
      case 'learnerPassbook':
        await this.getLearnerPassbook();
        this.learnerPassbookLimit = this.learnerPassbook.length;
        break;
        case 'myImprovements':
          this.myImprovementsLimit = this.projects.length;
          break;
    }
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.VIEW_MORE_CLICKED,
      Environment.HOME,
      PageId.PROFILE, null);
  }
  showLessTrainings(listName): void {
    switch (listName) {
      case 'myLearning':
        this.myLearningLimit = this.DEFAULT_ENROLLED_COURSE_LIMIT;
        break;
      case 'learnerPassbook':
        this.learnerPassbookLimit = this.DEFAULT_ENROLLED_COURSE_LIMIT;
        this.learnerPassbookCount = null;
        this.getLearnerPassbook();
        break;
    }
  }
  /**
   * To get enrolled course(s) of logged-in user i.e, trainings in the UI.
   *
   * It internally calls course handler of genie sdk
   */
  async getEnrolledCourses(refresher?, refreshCourseList?) {
    const loader = await this.commonUtilService.getLoader();
    if (refreshCourseList) {
      await loader.present();
      this.telemetryGeneratorService.generateInteractTelemetry(
        InteractType.TOUCH,
        InteractSubtype.REFRESH_CLICKED,
        Environment.USER,
        PageId.PROFILE
      );
    }
    const option = {
      userId: this.profile.userId || this.profile.id,
      returnFreshCourses: !!refresher
    };
    this.mappedTrainingCertificates = [];
    this.courseService.getEnrolledCourses(option).toPromise()
      .then(async (res: Course[]) => {
        if (res.length) {
          this.enrolledCourseList = res.sort((a, b) => (a.enrolledDate > b.enrolledDate ? -1 : 1));
          this.mappedTrainingCertificates = this.mapTrainingsToCertificates(res);
        }
        if (refreshCourseList) {
          await loader.dismiss();
        } 
      })
      .catch((error: any) => {
        console.error('error while loading enrolled courses', error);
      });
  }
  mapTrainingsToCertificates(trainings: Course[]) {
    /**
     * If certificate is there loop through certificates and add certificates in accumulator
     * with Course_Name and Date
     * if not then add only Course_Name and Date and add in to the accumulator
     */
    return trainings.reduce((accumulator, course) => {
      const oneCert = {
        courseName: course.courseName,
        batch: course.batch,
        dateTime: course.dateTime,
        courseId: course.courseId,
        certificate: undefined,
        issuedCertificate: undefined,
        status: course.status,
        style: 'completed-status-text',
        label: 'COMPLETED'
      };
      if(course.status === 0 || course.status === 1) {
        oneCert.style = 'ongoing-status-text';
        oneCert.label = 'ONGOING';
        if(course.batch && course.batch.status === 2) {
          oneCert.style = 'ongoing-status-text';
          oneCert.label = 'BATCH_EXPIRED';
        }
      }
      if (course.certificates && course.certificates.length) {
        oneCert.certificate = course.certificates[0];
      }
      if (course.issuedCertificates && course.issuedCertificates.length) {
        oneCert.issuedCertificate = course.issuedCertificates[0];
      }
      accumulator = accumulator.concat(oneCert);
      return accumulator;
    }, []);
  }
  async getLearnerPassbook() {
    try {
      const request: GetLearnerCerificateRequest = { userId: this.profile.userId || this.profile.id };
      request.size = this.learnerPassbookCount ? this.learnerPassbookCount : null;
      const getCertsReq: CSGetLearnerCerificateRequest = {
        userId: this.profile.userId || this.profile.id,
        schemaName: 'certificate',
        size: this.learnerPassbookCount? this.learnerPassbookCount : null
      };
      await this.certificateService.getCertificates(getCertsReq).toPromise().then(response => {
        this.learnerPassbookCount = response.certRegCount + response.rcCount || null;
        this.learnerPassbook = response.certificates
          .map((learnerCertificate: CsLearnerCertificate) => {
            const oneCert: any = {
              issuingAuthority: learnerCertificate.issuerName,
              issuedOn: learnerCertificate.issuedOn,
              courseName: learnerCertificate.trainingName,
              courseId: learnerCertificate.courseId,
            };
            if (learnerCertificate.pdfUrl) {
              oneCert.certificate = {
                url: learnerCertificate.pdfUrl || undefined,
                id: learnerCertificate.id || undefined,
                identifier: learnerCertificate.id,
                issuedOn: learnerCertificate.issuedOn,
                name: learnerCertificate.issuerName,
                type: learnerCertificate.type,
                templateUrl: learnerCertificate.templateUrl
              };
            } else {
              oneCert.issuedCertificate = {
                identifier: learnerCertificate.id,
                name: learnerCertificate.issuerName,
                issuedOn: learnerCertificate.issuedOn,
                type: learnerCertificate.type,
                templateUrl: learnerCertificate.templateUrl
              };
            }
            return oneCert;
          });
      });
    } catch (error) {
      console.log('Learner Passbook API Error', error);
    }
  }
  downloadCertificate(data,type?){
    if(type && type == 'project'){
    this.projectCertificateDownload(data);
    }else{
      this.downloadTrainingCertificate(data)
    }
  }
  async projectCertificateDownload(project){
    if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
      this.commonUtilService.showToast('OFFLINE_CERTIFICATE_MESSAGE', false, '', 3000, 'top');
      return;
    }
    await this.checkForPermissions().then(async (result) => {
      if (result) {
          const request = { type:'project',name:project.title, project: project._id, certificate: project.certificate, templateUrl : project.certificate.templateUrl };
          if (this.platform.is('ios')) {
            (window as any).cordova.InAppBrowser.open(request.certificate['templateUrl'], '_blank', "toolbarposition=top");
          } else {
            this.router.navigate([`/${RouterLinks.PROFILE}/${RouterLinks.CERTIFICATE_VIEW}`], {
              state: { request }
            });
          }
      } else {
        this.commonUtilService.showSettingsPageToast('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
      }
    });
  }
  async downloadTrainingCertificate(course: {
    courseName: string,
    dateTime: string,
    courseId: string,
    certificate?: CourseCertificate,
    issuedCertificate?: CourseCertificate,
    status: number
  }) {
    const telemetryObject: TelemetryObject = new TelemetryObject(course.courseId, 'Certificate', undefined);
    const values = new Map();
    values['courseId'] = course.courseId;
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.DOWNLOAD_CERTIFICATE_CLICKED,
      Environment.USER,
      PageId.PROFILE,
      telemetryObject,
      values);
    await this.checkForPermissions().then(async (result) => {
      if (result) {
        if (course.issuedCertificate) {
          const request = { courseId: course.courseId, certificate: course.issuedCertificate };
          if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
            if (!(await this.courseService.certificateManager.isCertificateCached(request).toPromise())) {
              this.commonUtilService.showToast('OFFLINE_CERTIFICATE_MESSAGE', false, '', 3000, 'top');
              return;
            }
          }
          this.router.navigate([`/${RouterLinks.PROFILE}/${RouterLinks.CERTIFICATE_VIEW}`], {
            state: { request }
          });
        } else {
          if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
            this.commonUtilService.showToast('OFFLINE_CERTIFICATE_MESSAGE', false, '', 3000, 'top');
            return;
          }
          const downloadMessage = await this.translate.get('CERTIFICATE_DOWNLOAD_INFO').toPromise();
          const toastOptions = {
            message: downloadMessage || 'Certificate getting downloaded'
          };
          const toast = await this.toastController.create(toastOptions);
          await toast.present();
          await this.downloadLegacyCertificate(course, toast);
        }
      } else {
        this.commonUtilService.showSettingsPageToast('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
      }
    });
  }
  private async downloadLegacyCertificate(course, toast) {
    const downloadRequest = {
      courseId: course.courseId,
      certificate: course.certificate
    };
    this.courseService.downloadCurrentProfileCourseCertificate(downloadRequest).toPromise()
      .then(async (res) => {
        if (toast) {
          await toast.dismiss();
        }
        this.openpdf(res.path);
      }).catch(async (err) => {
        await this.handleCertificateDownloadIssue(toast, err);
      });
  }
  private async handleCertificateDownloadIssue(toast: any, err: any) {
    if (toast) {
      await toast.dismiss();
    }
    if (err instanceof CertificateAlreadyDownloaded) {
      this.openpdf(err.filePath);
    } else if (NetworkError.isInstance(err)) {
      this.commonUtilService.showToast('OFFLINE_CERTIFICATE_MESSAGE', false, '', 3000, 'top');
    } else {
      this.commonUtilService.showToast(this.commonUtilService.translateMessage('SOMETHING_WENT_WRONG'));
    }
  }
  openpdf(path) {
    this.fileOpener
      .open(path, 'application/pdf')
      .then(() => console.log('File is opened'))
      .catch((e) => {
        console.log('Error opening file', e);
        this.commonUtilService.showToast('CERTIFICATE_ALREADY_DOWNLOADED');
      });
  }
  /**
   * Navigate to the course/content details page
   */
  navigateToDetailPage(content: any, layoutName: string, index: number): void {
    const identifier = content.contentId || content.identifier;
    let telemetryObject: TelemetryObject;
    if (layoutName === ContentCard.LAYOUT_INPROGRESS) {
      telemetryObject = new TelemetryObject(identifier, CsPrimaryCategory.COURSE, undefined);
    } else {
      telemetryObject = ContentUtil.getTelemetryObject(content);
    }
    const values = new Map();
    values['sectionName'] = 'Contributions';
    values['positionClicked'] = index;
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.CONTENT_CLICKED,
      Environment.USER,
      PageId.PROFILE,
      telemetryObject,
      values);
    this.navService.navigateToDetailPage(
      content,
      {
        content
      }
    );
  }
  updateLocalProfile(framework) {
    this.profile.framework = framework;
    this.profileService.getActiveSessionProfile({ requiredFields: ProfileConstants.REQUIRED_FIELDS })
      .toPromise()
      .then((resp: any) => {
        if (framework.userType) {
          resp.profileType = framework.userType;
        }
        this.formAndFrameworkUtilService.updateLoggedInUser(this.profile, resp)
          .then((success) => {
            console.log('updateLocalProfile-- ', success);
          });
      });
  }
  navigateToCategoriesEditPage() {
    if (this.commonUtilService.networkInfo.isNetworkAvailable) {
      this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
        InteractSubtype.EDIT_CLICKED,
        Environment.HOME,
        PageId.PROFILE, null);
      this.router.navigate([`/${RouterLinks.PROFILE}/${RouterLinks.CATEGORIES_EDIT}`]);
    } else {
      this.commonUtilService.showToast('NEED_INTERNET_TO_CHANGE');
    }
  }
  onEditProfileClicked() {
    this.navService.navigateToEditPersonalDetails(this.profile, PageId.PROFILE);
  }
  /**
   * Searches contents created by the user
   */
  async searchContent() {
    const contentSortCriteria: ContentSortCriteria = {
      sortAttribute: 'lastUpdatedOn',
      sortOrder: SortOrder.DESC
    };
    const contentTypes = await this.formAndFrameworkUtilService.getSupportedContentFilterConfig(
      ContentFilterConfig.NAME_DOWNLOADS);
    const contentSearchCriteria: ContentSearchCriteria = {
      createdBy: [this.userId || this.loggedInUserId],
      limit: 100,
      contentTypes,
      sortCriteria: [contentSortCriteria],
      searchType: SearchType.SEARCH
    };
    this.contentService.searchContent(contentSearchCriteria).toPromise()
      .then((result: ContentSearchResult) => {
        this.contentCreatedByMe = result.contentDataList || [];
      })
      .catch((error: any) => {
        console.error('Error', error);
      });
  }
  async editMobileNumber() {
    const componentProps = {
      phone: this.profile.phone,
      title: this.commonUtilService.translateMessage('UPDATE_PHONE_POPUP_TITLE'),
      description: this.commonUtilService.translateMessage('ERROR_RECOVERY_ID_PHONE_INVALID'),
      type: ProfileConstants.CONTACT_TYPE_PHONE,
      userId: this.profile.userId
    };
    this.validateAndEditContact()
    .then((_) => this.showEditContactPopup(componentProps))
    .catch(err => console.log(err) );
  }
  async editEmail() {
    const componentProps = {
      email: this.profile.email,
      title: this.commonUtilService.translateMessage('UPDATE_EMAIL_POPUP_TITLE'),
      description: this.commonUtilService.translateMessage('EMAIL_PLACEHOLDER'),
      type: ProfileConstants.CONTACT_TYPE_EMAIL,
      userId: this.profile.userId
    };
    this.validateAndEditContact()
    .then((_) => this.showEditContactPopup(componentProps))
    .catch(e => {
      if (e && e.response && e.response.body && e.response.body.params && e.response.body.params.err &&
        e.response.body.params.err === 'UOS_OTPCRT0059') {
        this.commonUtilService.showToast('ERROR_OTP_LIMIT_EXCEEDED');
      } else if (e.message !== 'CANCEL') {
        this.commonUtilService.showToast('SOMETHING_WENT_WRONG');
      }
    });
  }
  private async validateAndEditContact(): Promise<boolean> {
        const request: GenerateOtpRequest = {
            key: this.profile.email || this.profile.phone || this.profile.recoveryEmail,
            userId: this.profile.userId,
            templateId: OTPTemplates.EDIT_CONTACT_OTP_TEMPLATE,
            type: ''
        };
        if ((this.profile.email && !this.profile.phone) ||
        (!this.profile.email && !this.profile.phone && this.profile.recoveryEmail)) {
            request.type = ProfileConstants.CONTACT_TYPE_EMAIL;
        } else if (this.profile.phone || this.profile.recoveryPhone) {
            request.type = ProfileConstants.CONTACT_TYPE_PHONE;
        }
        const resp = await this.profileService.generateOTP(request).toPromise();
        if (resp) {
            const response = await this.callOTPPopover(request.type, request.key, false);
            if (response && response.OTPSuccess) {
                return Promise.resolve(true);
            } else {
                return Promise.reject(true);
            }
        }
  }
  private async showEditContactPopup(componentProps) {
    const popover = await this.popoverCtrl.create({
      component: EditContactDetailsPopupComponent,
      componentProps,
      cssClass: 'popover-alert input-focus',
      translucent: true
    });
    await popover.present();
    const { data } = await popover.onDidDismiss();
    if (data && data.isEdited) {
      await this.callOTPPopover(componentProps.type, data.value);
    }
  }
  private async callOTPPopover(type: string, key?: any, updateContact: boolean = true) {
    if (type === ProfileConstants.CONTACT_TYPE_PHONE) {
      const componentProps = {
        key,
        phone: this.profile.phone,
        title: !updateContact ? this.commonUtilService.translateMessage('AUTHRISE_USER_OTP_TITLE') :
            this.commonUtilService.translateMessage('AUTHRISE_USER_OTP_DESCRIPTION'),
        description: !updateContact ? this.commonUtilService.translateMessage('AUTHRISE_USER_OTP_DESCRIPTION') :
            this.commonUtilService.translateMessage('VERIFY_PHONE_OTP_DESCRIPTION'),
        type: ProfileConstants.CONTACT_TYPE_PHONE,
        userId: this.profile.userId
      };
      const data = await this.openContactVerifyPopup(EditContactVerifyPopupComponent, componentProps, 'popover-alert input-focus');
      if (updateContact && data && data.OTPSuccess) {
        this.updatePhoneInfo(data.value);
      }
    } else {
      const componentProps = {
        key,
        phone: this.profile.email,
        title: !updateContact ? this.commonUtilService.translateMessage('AUTHRISE_USER_OTP_TITLE') :
            this.commonUtilService.translateMessage('VERIFY_EMAIL_OTP_TITLE'),
        description: !updateContact ? this.commonUtilService.translateMessage('AUTHRISE_USER_OTP_DESCRIPTION') :
            this.commonUtilService.translateMessage('VERIFY_EMAIL_OTP_DESCRIPTION'),
        type: ProfileConstants.CONTACT_TYPE_EMAIL,
        userId: this.profile.userId
      };
      const data = await this.openContactVerifyPopup(EditContactVerifyPopupComponent, componentProps, 'popover-alert input-focus');
      if (updateContact && data && data.OTPSuccess) {
        this.updateEmailInfo(data.value);
      }
      return data;
    }
  }
  private async openContactVerifyPopup(component, componentProps, cssClass) {
    const popover = await this.popoverCtrl.create({ component, componentProps, cssClass });
    await popover.present();
    const { data } = await popover.onDidDismiss();
    return data;
  }
  private async updatePhoneInfo(phone) {
    const req: UpdateServerProfileInfoRequest = {
      userId: this.profile.userId,
      phone,
      phoneVerified: true
    };
    await this.updateProfile(req, 'PHONE_UPDATE_SUCCESS');
  }
  private async updateEmailInfo(email) {
    const req: UpdateServerProfileInfoRequest = {
      userId: this.profile.userId,
      email,
      emailVerified: true
    };
    await this.updateProfile(req, 'EMAIL_UPDATE_SUCCESS');
  }
  private async updateProfile(request: UpdateServerProfileInfoRequest, successMessage: string) {
    const loader = await this.commonUtilService.getLoader();
    this.profileService.updateServerProfile(request).toPromise()
      .then(async () => {
        await loader.dismiss();
        this.doRefresh();
        this.commonUtilService.showToast(this.commonUtilService.translateMessage(successMessage));
      }).catch(async () => {
        await loader.dismiss();
        this.commonUtilService.showToast(this.commonUtilService.translateMessage('SOMETHING_WENT_WRONG'));
      });
  }
  handleHeaderEvents($event) {
    if ($event.name === 'download') {
      this.redirectToActiveDownloads();
    }
  }
  private redirectToActiveDownloads() {
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.ACTIVE_DOWNLOADS_CLICKED,
      Environment.HOME,
      PageId.PROFILE);
    this.router.navigate([RouterLinks.ACTIVE_DOWNLOADS]);
  }
  toggleTooltips(event, field) {
    clearTimeout(this.timer);
    if (field === 'name') {
      this.informationProfileName = !Boolean(this.informationProfileName);
      this.informationOrgName = false;
      if (this.informationProfileName) {
        this.dismissMessage();
      }
    } else if (field === 'org') {
      this.informationOrgName = !Boolean(this.informationOrgName);
      this.informationProfileName = false;
      if (this.informationOrgName) {
        this.dismissMessage();
      }
    } else {
      this.informationProfileName = false;
      this.informationOrgName = false;
    }
    event.stopPropagation();
  }
  private dismissMessage() {
    this.timer = setTimeout(() => {
      this.informationProfileName = false;
      this.informationOrgName = false;
    }, 3000);
  }
  getOrgDetails() {
    const orgList = [];
    let orgItemList;
    orgItemList = this.profile.organisations;
    if (orgItemList.length > 1) {
      orgItemList.map((org) => {
        if (this.profile.rootOrgId !== org.organisationId) {
          orgList.push(org);
        }
      });
      orgList.sort((orgDate1, orgdate2) => orgDate1.orgjoindate > orgdate2.organisation ? 1 : -1);
      this.organisationName = orgList[0].orgName;
      this.orgDetails = this.commonUtilService.getOrgLocation(orgList[0]);
    } else if (orgItemList.length === 1) {
      this.organisationName = orgItemList[0].orgName;
      this.orgDetails = this.commonUtilService.getOrgLocation(orgItemList[0]);
    }
  }
  async editRecoveryId() {
    this.telemetryGeneratorService.generateInteractTelemetry(
        InteractType.TOUCH,
        InteractSubtype.RECOVERY_ACCOUNT_ID_CLICKED,
        Environment.USER,
        PageId.PROFILE
    );
    const componentProps = {
      recoveryEmail: this.profile.recoveryEmail ? this.profile.recoveryEmail : '',
      recoveryPhone: this.profile.recoveryPhone ? this.profile.recoveryPhone : '',
    };
    this.validateAndEditContact()
    .then(async (_) => {
        const popover = await this.popoverCtrl.create({
          component: AccountRecoveryInfoComponent,
          componentProps,
          cssClass: 'popover-alert input-focus'
        });
        await popover.present();
        const { data } = await popover.onDidDismiss();
        if (data && data.isEdited) {
          const req: UpdateServerProfileInfoRequest = {
            userId: this.profile.userId
          };
          await this.updateProfile(req, 'RECOVERY_ACCOUNT_UPDATE_SUCCESS');
        }
    })
    .catch(err => console.log(err) );
  }
  async openEnrolledCourse(training) {
    try {
      const content = this.enrolledCourseList.find((course) => (course.courseId === training.courseId)
          && training.batch.batchId === course.batch.batchId);
      this.navService.navigateToTrackableCollection(
        {
          content
        }
      );
    } catch (err) {
      console.error(err);
    }
  }
  private async checkForPermissions(): Promise<boolean | undefined> {
    if(this.platform.is('ios')) {
      return new Promise<boolean | undefined>(async (resolve, reject) => {
        resolve(true);
      });
    }
    return new Promise<boolean | undefined>(async (resolve) => {
      const permissionStatus = await this.commonUtilService.getGivenPermissionStatus(AndroidPermission.WRITE_EXTERNAL_STORAGE);
      if (permissionStatus.hasPermission) {
        resolve(true);
      } else if (permissionStatus.isPermissionAlwaysDenied) {
        await this.commonUtilService.showSettingsPageToast('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
        resolve(false);
      } else {
        this.showStoragePermissionPopup().then((result) => {
          if (result) {
            resolve(true);
          } else {
            resolve(false);
          }
        });
      }
    });
  }
  private async showStoragePermissionPopup(): Promise<boolean | undefined> {
    return new Promise<boolean | undefined>(async (resolve) => {
      const confirm = await this.commonUtilService.buildPermissionPopover(
        async (selectedButton: string) => {
          if (selectedButton === this.commonUtilService.translateMessage('NOT_NOW')) {
            this.telemetryGeneratorService.generateInteractTelemetry(
              InteractType.TOUCH,
              InteractSubtype.NOT_NOW_CLICKED,
              Environment.SETTINGS,
              PageId.PERMISSION_POPUP);
            await this.commonUtilService.showSettingsPageToast('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
          } else if (selectedButton === this.commonUtilService.translateMessage('ALLOW')) {
            this.telemetryGeneratorService.generateInteractTelemetry(
              InteractType.TOUCH,
              InteractSubtype.ALLOW_CLICKED,
              Environment.SETTINGS,
              PageId.PERMISSION_POPUP);
            this.appGlobalService.isNativePopupVisible = true;
            this.permissionService.requestPermission(AndroidPermission.WRITE_EXTERNAL_STORAGE)
              .subscribe(async (status: AndroidPermissionsStatus) => {
                if (status.hasPermission) {
                  this.telemetryGeneratorService.generateInteractTelemetry(
                    InteractType.TOUCH,
                    InteractSubtype.ALLOW_CLICKED,
                    Environment.SETTINGS,
                    PageId.APP_PERMISSION_POPUP
                  );
                  resolve(true);
                } else if (status.isPermissionAlwaysDenied) {
                  await this.commonUtilService.showSettingsPageToast
                    ('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
                  resolve(false);
                } else {
                  this.telemetryGeneratorService.generateInteractTelemetry(
                    InteractType.TOUCH,
                    InteractSubtype.DENY_CLICKED,
                    Environment.SETTINGS,
                    PageId.APP_PERMISSION_POPUP
                  );
                  await this.commonUtilService.showSettingsPageToast
                    ('FILE_MANAGER_PERMISSION_DESCRIPTION', this.appName, PageId.PROFILE, true);
                }
                this.appGlobalService.setNativePopupVisible(false);
                resolve(undefined);
              });
          }
        }, this.appName, this.commonUtilService.translateMessage
        ('FILE_MANAGER'), 'FILE_MANAGER_PERMISSION_DESCRIPTION', PageId.PROFILE, true
      );
      await confirm.present();
    });
  }
  openSelfDeclareTeacherForm(type) {
    if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
      this.commonUtilService.showToast('NEED_INTERNET_TO_CHANGE');
    }
    const telemetryId = type === 'add' ? ID.BTN_I_AM_A_TEACHER : ID.BTN_UPDATE;
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      '',
      Environment.USER,
      PageId.PROFILE,
      undefined,
      undefined,
      undefined,
      undefined,
      telemetryId
    );
    this.router.navigate([`/${RouterLinks.PROFILE}/${RouterLinks.SELF_DECLARED_TEACHER_EDIT}/${type}`], {
      state: {
        profile: this.profile
      }
    });
  }
  async getSelfDeclaredDetails() {
    if (this.isCustodianOrgId && this.profile && this.profile.declarations && this.profile.declarations.length) {
      this.selfDeclarationInfo = this.profile.declarations[0];
      const tenantPersonaList = await this.formAndFrameworkUtilService.getFormFields(
        FormConstants.TENANT_PERSONAINFO, this.profile.rootOrg.rootOrgId);
      const tenantConfig: any = tenantPersonaList.find(config => config.code === 'tenant');
      const searchOrganizationReq: OrganizationSearchCriteria<{ orgName: string, rootOrgId: string}> = {
        filters: {
            isTenant: true
        },
        fields: ['orgName', 'rootOrgId']
    };
      const organisations = (await this.frameworkService.searchOrganization(searchOrganizationReq).toPromise()).content;
      let index = 0;
      const organisationList = organisations.map((org) => ({
        value: org.rootOrgId,
        label: org.orgName,
        index: index++
      }));
      index = 0;
      tenantConfig.templateOptions.options = organisationList;
      const tenantDetails = tenantConfig.templateOptions && tenantConfig.templateOptions.options &&
        tenantConfig.templateOptions.options.find(tenant => tenant.value === this.selfDeclarationInfo.orgId);
      this.personaTenantDeclaration = this.commonUtilService.translateMessage('FRMELEMNTS_LBL_SHARE_DATA_WITH', {
          '%tenant': (tenantDetails && tenantDetails.label) || ''
        });
      if (this.selfDeclarationInfo.orgId) {
        const formConfig = await this.formAndFrameworkUtilService.getFormFields(
          FormConstants.SELF_DECLARATION, this.selfDeclarationInfo.orgId);
        const externalIdConfig = formConfig.find(config => config.code === 'externalIds');
        this.selfDeclaredDetails = [];
        (externalIdConfig.children as FieldConfig<any>[]).forEach(config => {
          if (this.profile.declarations[0].info[config.code]) {
            this.selfDeclaredDetails.push({ name: config.fieldName, value: this.profile.declarations[0].info[config.code] });
          }
        });
      }
    }
  }
  shareUsername() {
    let fullName = this.profile.firstName;
    if (this.profile.lastName) {
      fullName = fullName + ' ' + this.profile.lastName;
    }
    const translatedMsg = this.commonUtilService.translateMessage('SHARE_USERNAME', {
      app_name: this.appName,
      user_name: fullName,
      sunbird_id: this.profile.userName
    });
    this.socialSharing.share(translatedMsg);
  }
  private async getFrameworkDetails() {
    const guestUser = await this.commonUtilService.getGuestUserConfig();
    let id = "";
      id = guestUser.syllabus[0];
    const frameworkDetailsRequest: FrameworkDetailsRequest = {
      frameworkId: id,
      requiredCategories: FrameworkCategoryCodesGroup.DEFAULT_FRAMEWORK_CATEGORIES
    };
    await this.frameworkService.getFrameworkDetails(frameworkDetailsRequest).toPromise()
      .then(async (framework: Framework) => {
        this.frameworkCategoriesMap = framework.categories.reduce((acc, category) => {
          acc[category.code] = category;
          return acc;
        }, {});
        this.profile.framework.board = [];
        this.profile.framework.medium = [];
        this.profile.framework.grade = [];
        this.profile.framework.subject = [];
        setTimeout(() => {
          this.boardList = this.getFieldDisplayValues(guestUser.board, 'board');
          this.mediumList = this.getFieldDisplayValues(guestUser.medium, 'medium');
          this.gradeLevelList = this.getFieldDisplayValues(guestUser.grade, 'gradeLevel');
          this.subjectList = this.getFieldDisplayValues(guestUser.subject, 'subject');
          this.profile.framework.board = this.boardList;
          this.profile.framework.medium = this.mediumList;
          this.profile.framework.gradeLevel = this.gradeLevelList;
          this.profile.framework.grade = this.gradeLevelList;
          this.profile.framework.subject = this.subjectList;
        }, 0);
      });
      this.profile.userLocations = await this.locationHandler.getAvailableLocation(guestUser, true);
      this.userLocation = this.commonUtilService.getUserLocation(this.profile);
      this.profile['persona'] =  await this.profileHandler.getPersonaConfig(guestUser.profileType.toLowerCase());
  }
  getFieldDisplayValues(field: Array<any>, categoryCode: string, lowerCase?: boolean): any[] {
    const displayValues = [];
    if (!this.frameworkCategoriesMap[categoryCode]) {
      return displayValues;
    }
    this.frameworkCategoriesMap[categoryCode].terms.forEach(element => {
      if (field.includes(element.code) || field.includes(element.name.replace(/[^a-zA-Z0-9]/g,'').toLowerCase())) {
        if (lowerCase) {
          displayValues.push(element.name.toLowerCase());
        } else {
          displayValues.push(element.name);
        }
      }
    });
    return displayValues;
  }
  private getCategories() {
    this.formAndFrameworkUtilService.getFrameworkCategoryList().then((categories) => {
      this.categories = categories.supportedFrameworkConfig;
    });
  }
  
  getProjectsCertificate(){
    const config ={
      url : urlConstants.API_URLS.PROJECT_CERTIFICATES
    }
    this.unnatiDataService.get(config).subscribe(resp =>{
      this.projects =  resp.result.data;
    })
  }
}
    <ion-content hide-header-footer overflow-scroll="true" (click)="toggleTooltips($event,'')"
    class="main-container avoid-bottom-tabs-space" #contentView scrollEvents="true">
    <!-- Pull to Refresh -->
    <div class="spinner-div" *ngIf="refresh">
        <ion-spinner icon="spiral" class="refreshspinner"></ion-spinner>
    </div>
    <ion-refresher #refresher slot="fixed" (ionRefresh)="doRefresh($event)">
        <ion-refresher-content refreshingSpinner="circles"></ion-refresher-content>
    </ion-refresher>
    <div class="MT15 ion-text-center ion-padding-horizontal" *ngIf="profile?.firstName">
        <app-profile-avatar [username]="profile?.firstName" *ngIf="!isStateValidated"></app-profile-avatar>
        <img *ngIf="isStateValidated" src="./assets/imgs/avatar-tickmark.svg" alt="certified" class="avatar-tickmark">
        <app-profile-avatar [username]="profile?.firstName" [isStateUser]="isStateValidated" class="profileAvatar"
            *ngIf="isStateValidated"></app-profile-avatar>
    </div>
    <div style="margin-top: 16px" class="ion-text-center ion-padding-horizontal">
        <p class="profile-head">
            <span class="profile-name">{{ profile?.firstName | titlecase }}{{ profile?.lastName | titlecase }}</span>
        </p>
        <p class="MT0 MB15">
            <span class="app-name"> {{appName}} </span>
            <span class="txt-uppercase"> {{'ID' | translate }}: </span>
            <span>{{profile?.userName}}</span>
            <span role="button" aria-label="Share profile" class="profile-share-icon" (click)="shareUsername()" tabindex="0">
                <ion-icon name="share-social" aria-hidden="true" class="share-icon"></ion-icon>
            </span>
        </p>
    </div>
    <div class="roles-container ion-text-center ion-padding-horizontal">
        <div class="MB5 ion-text-center" *ngFor="let role of roles | slice : startLimit:rolesLimit;">
            <div class="roles">
                {{role}}
            </div>
        </div>
        <div class="ion-text-center">
            <ion-button fill="clear" *ngIf="rolesLimit < roles?.length" (click)="showMoreItems()"
                class="txt-capitalize">
                + {{roles?.length - 2}} {{'MORE' | translate}}
                <ion-icon role="button" class="ML10" name="arrow-down" aria-label="Show more items"></ion-icon>
            </ion-button>
            <ion-button fill="clear" *ngIf="rolesLimit > DEFAULT_PAGINATION_LIMIT" (click)="showLessItems()"
                class="txt-capitalize">
                {{'SHOW_LESS' | translate }}
                <ion-icon class="ML10" name="arrow-up" aria-label="show less items"></ion-icon>
            </ion-button>
        </div>
    </div>
   <div *ngIf="profile" class="school-details text-center">
    <div *ngIf="profile?.persona || profile?.framework" class="preference-info" role="heading" aria-level="2">{{ 'CONTENT_PREFERENCE' | translate }}</div>
    <div class="location-mapping-block">
    <div *ngIf="profile?.persona?.name" class="text-center">
        <div>
            <span class="bolder">{{'FRMELEMNTS_LBL_PERSONA' | translate}}: </span>
            <span>{{profile?.persona?.name}}</span>
        </div>
    </div>
    <div *ngIf="profile?.subPersona && profile?.subPersona.length" class="text-center">
        <div>
            <span class="bolder">{{'FRMELEMNTS_LBL_SUBPERSONA' | translate}}: </span>
            <span>{{profile?.subPersona.join(', ')}}</span>
        </div>
    </div>
    <div *ngIf="userLocation?.state && userLocation?.state?.name && userLocation?.state?.name?.length">
        <span class="bolder">{{'STATE' | translate}}: </span>
        <span>{{userLocation.state.name}}</span>
        <span *ngIf="!(userLocation?.state && userLocation?.state?.name && userLocation?.state?.name?.length)"
            class="lighter">{{'ADD_STATE' | translate}}</span>
    </div>
    <div *ngIf="userLocation?.district && userLocation?.district?.name && userLocation?.district?.name?.length">
        <span class="bolder">{{'DISTRICT' | translate}}: </span>
        <span>{{userLocation.district.name}}</span>
        <span
            *ngIf="!(userLocation?.district && userLocation?.district?.name && userLocation?.district?.name?.length)"
            class="lighter">{{'ADD_DISTRICT' | translate}}</span>
    </div>
    <div *ngIf="userLocation?.block && userLocation?.block?.name && userLocation?.block?.name?.length">
        <span class="bolder">{{'FRMELEMNTS_LBL_BLOCK' | translate}}: </span>
        <span>{{userLocation.block.name}}</span>
        <span *ngIf="!(userLocation?.block && userLocation?.block?.name && userLocation?.block?.name?.length)"
            class="lighter">{{'FRMELEMNTS_LBL_ADD_BLOCK' | translate}}</span>
    </div>
    <div *ngIf="userLocation?.cluster && userLocation?.cluster?.name && userLocation?.cluster?.name?.length">
        <span class="bolder">{{'FRMELEMNTS_LBL_CLUSTER' | translate}}: </span>
        <span>{{userLocation.cluster.name}}</span>
        <span *ngIf="!(userLocation?.cluster && userLocation?.cluster?.name && userLocation?.cluster?.name?.length)"
            class="lighter">{{'FRMELEMNTS_LBL_ADD_CLUSTER' | translate}}</span>
    </div>
    <div *ngIf="userLocation" class="location text-center">
        <div *ngIf="userLocation?.school && userLocation?.school?.name && userLocation?.school?.name?.length">
            <span  class="bolder">{{'FRMELEMNTS_LBL_SCHOOL' | translate}}: </span>
            <span>{{userLocation.school.name}}</span>
            <span *ngIf="!(userLocation?.school && userLocation?.school?.name && userLocation?.school?.name?.length)"
                class="lighter">{{'FRMELEMNTS_LBL_ADD_SCHOOL' | translate}}</span>
        </div>
        <div class="container MT10 MB10 edit-options">
            <ion-button shape="round" aria-label="Edit Role, Block, District, State"  (click)="onEditProfileClicked()"
                class="custom-round ion-text-capitalize">
                {{'EDIT' | translate }}
            </ion-button>
        </div>
    </div>
    </div>
    <div class="framework-block" *ngIf="profile?.framework && categories.length>0">
        <div *ngFor="let category of categories">
            <div class="container" *ngIf="profile?.framework[category.frameworkCode]">
                <span>{{category.label | translateJson}}: </span>
                <span class="bolder">{{profile?.framework[category.frameworkCode].join(', ') | aliased}} ‎</span>
            </div>
        </div>
        <div class="container">
            <ion-button shape="round" aria-label="Edit Board, Medium, Classes, subjects" (click)="navigateToCategoriesEditPage()" class="custom-round ion-text-capitalize">
                {{'EDIT' | translate }}
            </ion-button>
        </div>
    </div>
   </div>
    <div class="self-declare-btn text-center" *ngIf="!profile?.declarations?.length && !profile?.isMinor && isCustodianOrgId">
        <ion-button shape="round" (click)="openSelfDeclareTeacherForm('add')">
            {{'SUBMIT_MY_DETAILS' | translate}}
        </ion-button>
    </div>
    <div class="contacts" *ngIf="!profile?.managedBy && (profile?.phone || profile?.email)">
        <div *ngIf="profile?.phone">
            <div class="phone" role="button" (click)="editMobileNumber();">
                <span class="icon MR10 align-middle">
                    <ion-icon aria-hidden="true" name="call"></ion-icon>
                </span>
                <span class="value align-middle">+91 {{ profile?.phone }}</span>
            </div>
        </div>
        <div *ngIf="!profile?.phone">
            <div class="phone light" role="button"  (click)="editMobileNumber();" tabindex="0">
                <span class="icon MR10 align-middle">
                    <ion-icon aria-hidden="true" name="call"></ion-icon>
                </span>
                <span class="value align-middle">{{'ADD_PHONE' | translate}}</span>
            </div>
        </div>
        <div *ngIf="profile?.email">
            <div class="email " role="button" (click)="editEmail();" tabindex="0">
                <span class="icon MR10 align-middle">
                    <ion-icon aria-hidden="true" name="mail"></ion-icon>
                </span>
                <span class="value align-middle">{{ profile?.email }}</span>
            </div>
        </div>
        <div *ngIf="!profile?.email">
            <div class="email light" role="button" (click)="editEmail();" tabindex="0">
                <span class="icon MR10 align-middle">
                    <ion-icon aria-hidden="true" name="mail"></ion-icon>
                </span>
                <span class="value align-middle">{{'ADD_EMAIL' | translate}}</span>
            </div>
        </div>
        <div class="MT10" *ngIf=" ( profile?.recoveryEmail?.length > 0 ) || ( profile?.recoveryPhone?.length > 0 )">
            <div class="email" role="button" (click)="editRecoveryId();">
                <span class="icon MR10 align-middle">
                    <ion-icon src="assets/imgs/recovery_icon.svg"></ion-icon>
                </span>
                <span class="value align-middle" *ngIf="profile?.recoveryEmail?.length > 0">{{ profile?.recoveryEmail
                    }}</span>
                <span class="value align-middle" *ngIf="profile?.recoveryPhone?.length > 0">
                    +91 {{ profile?.recoveryPhone }}
                </span>
            </div>
        </div>
        <div class="MT10" *ngIf="(!profile?.recoveryEmail && !profile?.recoveryPhone) || 
        ((profile?.recoveryEmail?.length === 0) && (profile?.recoveryPhone?.length === 0))">
            <div class="email light" role="button" (click)="editRecoveryId();" tabindex="0">
                <span class="icon MR10 align-middle">
                    <ion-icon src="assets/imgs/recovery_icon.svg"></ion-icon>
                </span>
                <span class="value align-middle">{{'ADD_RECOVERY_ID' | translate}}</span>
            </div>
        </div>
    </div>
    <div class="self-declare-teacher-details" *ngIf="isCustodianOrgId &&  profile?.declarations?.length">
        <p class="declare-info">{{'MY_DETAILS' | translate | titlecase }}</p>
        <div class="container" *ngIf="personaTenantDeclaration">
            <div>{{personaTenantDeclaration}}</div>
        </div>
        <div class="container" *ngFor="let details of selfDeclaredDetails">
            <div>{{ details.name | translate }}:</div>
            <div class="bolder">{{ details.value }}</div>
        </div>
        <ion-button shape="round" (click)="openSelfDeclareTeacherForm('edit')" class="custom-round">
            {{'UPDATE' | translate }}
        </ion-button>
    </div>
    <div class="badges ion-text-center ion-padding-horizontal" *ngIf="profile?.badgeAssertions?.length > 0">
        <p class="bolder f16">{{'MY_BADGES' | translate }} ({{profile?.badgeAssertions?.length}})‎</p>
        <ion-avatar item-center="" *ngFor="let batch of profile.badgeAssertions | slice : startLimit:badgesLimit;">
            <img height="80px" width="auto" alt="badge" [src]="commonUtilService.convertFileSrc(batch.badgeClassImage)">
        </ion-avatar>
        <div class="ion-text-center">
            <ion-button shape="round" *ngIf="badgesLimit < profile?.badgeAssertions?.length" (click)="showMoreBadges()"
                class="txt-capitalize custom-round">
                + {{profile?.badgeAssertions?.length - 2}} {{'MORE' | translate}}
                <ion-icon role="button" class="ML10" name="arrow-down" aria-label="Show more badges"></ion-icon>
            </ion-button>
            <ion-button shape="round" *ngIf="badgesLimit > DEFAULT_PAGINATION_LIMIT" (click)="showLessBadges()"
                class="txt-capitalize custom-round">
                {{'SHOW_LESS' | translate }}
                <ion-icon class="ML10" role="button" name="arrow-up" aria-label="Show Less badges"></ion-icon>
            </ion-button>
        </div>
    </div>
    <div class="bottom-block" *ngIf="mappedTrainingCertificates?.length > 0 || projects?.length > 0 || learnerPassbook?.length > 0 || contentCreatedByMe.length > 0">
        <div class="trainings" *ngIf="mappedTrainingCertificates?.length > 0">
            <div class="bolder heading f16">
                <span>{{'FRMELEMNTS_LBL_MY_LEARNINGS' | translate}} ({{mappedTrainingCertificates?.length}})‎</span>
                <span role="button" aria-label="Refresh"><ion-icon role="button" aria-label="Refresh" name="refresh-circle" class="refresh-icon"
                    (click)="getEnrolledCourses(true, true)"></ion-icon></span>
            </div>
            <div class="content">
                <div *ngFor="let training of (mappedTrainingCertificates | slice : startLimit:myLearningLimit) |sortBy: 'status' : 'asc'; let i = index;"
                    [ngClass]="{'flex-nowrap': i !== mappedTrainingCertificates.length-1, 'flex-nowrap-last': i == mappedTrainingCertificates.length-1}">
                    <div class="training-1">
                        <div class="fw sb__ellipsis sb__ellipsis--two" (click)="openEnrolledCourse(training)">
                            {{training.courseName}}
                        </div>
                        <div class="batch-detail">
                            {{training?.batch?.name}}
                        </div>
                        <div>
                            <span [ngClass]="[training.style]"> {{ training.label | translate }}</span>
                            <span class="lighter"> {{training.dateTime | date:'dd/MM/yyyy'}} </span>
                        </div>
                    </div>
                    <div class="training-2" *ngIf="training?.certificate || training?.issuedCertificate">
                        <button class="sb-btn-tile ion-activatable ripple-parent"
                            (click)="downloadTrainingCertificate(training)">
                            <ion-icon class="view-icon" name="eye"></ion-icon>
                            <span class="sb-btn-footer-text m-t-4">{{ 'CERTIFICATE' | translate }}</span>
                            <ion-ripple-effect type="unbounded"></ion-ripple-effect>
                        </button>
                    </div>
                </div>
                <div class="ion-text-center"
                    *ngIf="mapTrainingsToCertificates(mappedTrainingCertificates).length > myLearningLimit">
                    <ion-button shape="round" class="txt-capitalize custom-round"
                        *ngIf="myLearningLimit < mappedTrainingCertificates?.length"
                        (click)="showMoreTrainings('myLearning')">
                        + {{mappedTrainingCertificates?.length - myLearningLimit}} {{'MORE' | translate}}
                        <ion-icon class="ML10" name="arrow-down" aria-label="show more trainings"></ion-icon>
                    </ion-button>
                    <ion-button shape="round" class="txt-capitalize custom-round"
                        *ngIf="myLearningLimit >= mappedTrainingCertificates?.length"
                        (click)="showLessTrainings('myLearning')">
                        {{'SHOW_LESS' | translate }}
                        <ion-icon role="button" class="ML10" name="arrow-up" aria-label="show less trainings"></ion-icon>
                    </ion-button>
                </div>
            </div>
        </div>
                <!-- Projects -->
                <div class="trainings" *ngIf="projects?.length > 0">
                    <div class="bolder heading f16">
                        <span>{{'FRMELEMNTS_LBL_IMP_CERTIFICATE' | translate}} ({{projects?.length}})‎</span>
                        <span role="button" aria-label="Refresh"><ion-icon role="button" aria-label="Refresh" name="refresh-circle" class="refresh-icon"
                            (click)="getProjectsCertificate()"></ion-icon></span>
                    </div>
                    <div class="content">
                        <div *ngFor="let training of (projects | slice : startLimit:myImprovementsLimit) |sortBy: 'status' : 'asc'; let i = index;"
                            [ngClass]="{'flex-nowrap': i !== projects.length-1, 'flex-nowrap-last': i == projects.length-1}">
                            <div class="training-1">
                                <div class="fw sb__ellipsis sb__ellipsis--two">
                                    {{training.title}}
                                </div>
                                <div class="batch-detail">
                                    {{training.completedDate | date :'dd/MM/yyyy'}}
                                </div>
                                <div class="batch-detail" [ngClass]="{'project-submitted': training.status === projectStatus.submitted}">
                                    {{training?.status | titlecase}}
                                </div>
                                <div>
                                    <span [ngClass]="[training.style]"> {{ training.label | translate }}</span>
                                    <span class="lighter"> {{training.dateTime | date:'dd/MM/yyyy'}} </span>
                                </div>
                            </div>
                            <div class="training-2" *ngIf="training?.certificate || training?.issuedCertificate">
                                <button class="sb-btn-tile ion-activatable ripple-parent"
                                    (click)="downloadCertificate(training,'project')">
                                    <ion-icon class="view-icon" name="eye"></ion-icon>
                                    <span class="sb-btn-footer-text m-t-4">{{ 'CERTIFICATE' | translate }}</span>
                                    <ion-ripple-effect type="unbounded"></ion-ripple-effect>
                                </button>
                            </div>
                        </div>
                        <div class="ion-text-center"
                            *ngIf="projects.length > myImprovementsLimit">
                            <ion-button shape="round" class="custom-btn-txt-transform-none  custom-round"
                                *ngIf="myImprovementsLimit < projects?.length"
                                (click)="showMoreTrainings('myImprovements')">
                                {{'FRMELEMNTS_BTN_LOAD_MORE' | translate}}
                                <ion-icon class="ML10" name="arrow-down" aria-label="show more trainings"></ion-icon>
                            </ion-button>
                            <ion-button shape="round" class="custom-btn-txt-transform-none custom-round"
                                *ngIf="myImprovementsLimit >= projects?.length"
                                (click)="showLessTrainings('myImprovements')">
                                {{'SHOW_LESS' | translate }}
                                <ion-icon role="button" class="ML10" name="arrow-up" aria-label="show less trainings"></ion-icon>
                            </ion-button>
                        </div>
                    </div>
                </div>
        <div class="trainings" *ngIf="learnerPassbook?.length > 0">
            <div class="bolder heading f16">
                <span>{{'FRMELEMNTS_LBL_LEARNER_PASSBOOK' | translate}} ({{learnerPassbookCount}})‎</span>
            </div>
            <div class="content">
                <div *ngFor="let certificate of (learnerPassbook | slice : startLimit:learnerPassbookLimit) |sortBy: 'status' : 'asc'; let i = index;"
                    [ngClass]="{'flex-nowrap': i !== learnerPassbook.length-1, 'flex-nowrap-last': i == learnerPassbook.length-1}">
                    <div class="training-1">
                        <div class="fw sb__ellipsis sb__ellipsis--two" (click)="openEnrolledCourse(certificate)">
                            {{certificate.courseName}}
                        </div>
                        <div>
                            <span class="lighter">{{certificate.issuedOn | date:'dd/MM/yyyy'}} </span>
                        </div>
                    </div>
                    <div class="training-2" *ngIf="certificate?.certificate || certificate?.issuedCertificate">
                        <button class="sb-btn-tile ion-activatable ripple-parent"
                            (click)="downloadTrainingCertificate(certificate)">
                            <ion-icon class="view-icon" name="eye"></ion-icon>
                            <span class="sb-btn-footer-text m-t-4">{{ 'CERTIFICATE' | translate }}</span>
                            <ion-ripple-effect type="unbounded"></ion-ripple-effect>
                        </button>
                    </div>
                </div>
                <div class="ion-text-center" *ngIf="learnerPassbook.length >= learnerPassbookLimit">
                    <ion-button shape="round" class="txt-capitalize custom-round"
                        *ngIf="learnerPassbookLimit < learnerPassbook?.length"
                        (click)="showMoreTrainings('learnerPassbook')">
                        + {{learnerPassbookCount - learnerPassbookLimit}} {{'MORE' | translate}}
                        <ion-icon class="ML10" role="button" name="arrow-down" aria-label="more"></ion-icon>
                    </ion-button>
                    <ion-button shape="round" class="txt-capitalize custom-round"
                        *ngIf="learnerPassbookLimit >= learnerPassbook?.length"
                        (click)="showLessTrainings('learnerPassbook')">
                        {{'SHOW_LESS' | translate }}
                        <ion-icon class="ML10" role="button" name="arrow-up" aria-label="show less trainings"></ion-icon>
                    </ion-button>
                </div>
            </div>
        </div>
        <div class="contributions" *ngIf="contentCreatedByMe.length > 0">
            <div class="bolder f16" style="padding: 15px; background-color: #fff; margin-bottom:  2px;">
                {{'CONTRIBUTIONS' | translate}} ({{contentCreatedByMe.length}})‎
            </div>
            <div class="cards-container" style="padding:0 5px; background-color: #fff; overflow-x: scroll; ">
                <div style="width: 100%" class="ion-no-padding">
                    <div class="flex-container" *ngIf="contentCreatedByMe  && isLoggedInUser">
                        <ion-card *ngFor="let courseItem of contentCreatedByMe; let i=index"
                            (click)="navigateToDetailPage(courseItem, layoutPopular, i);"
                            style="min-width: 84%;height: 10.313rem;">
                            <ion-card-content>
                                <ion-row class="top">
                                    <ion-col size="3" class="img-container">
                                        <img class="app-icon" alt="app"
                                            [src]="commonUtilService.convertFileSrc(courseItem?.appIcon)" />
                                    </ion-col>
                                    <ion-col size="9" style="margin-bottom: 5px; padding: 0 0 0 15px;">
                                        <div style="margin-bottom: 5px;" *ngIf="courseItem.resourceType">
                                            <ion-button fill="outline" class="badge">
                                                {{courseItem?.resourceType}}
                                            </ion-button>
                                        </div>
                                        <div class="f11 ellipsis info" *ngIf="courseItem.subject">
                                            {{'SUBJECT'| translate}}: {{courseItem?.subject}}
                                        </div>
                                        <div class="f11 ellipsis info"
                                            *ngIf="courseItem.gradeLevel && courseItem.gradeLevel.length">
                                            {{'CLASS' | translate}}: {{courseItem?.gradeLevel}}
                                        </div>
                                        <div class="f11 ellipsis info" *ngIf="courseItem.medium">
                                            {{'MEDIUM' | translate}}: {{courseItem?.medium}}
                                        </div>
                                    </ion-col>
                                </ion-row>
                                <ion-row>
                                    <ion-col size="12" class="PTB0">
                                        <h6 class="name second-line-ellipsis">{{courseItem?.name}}</h6>
                                    </ion-col>
                                    <ion-col size="12" class="PTB0">
                                        <p class="author">{{courseItem?.creator}}</p>
                                    </ion-col>
                                </ion-row>
                            </ion-card-content>
                        </ion-card>
                    </div>
                </div>
            </div>
        </div>
    </div>
</ion-content>
    
                    ./profile.page.scss
                
@import "src/assets/styles/variables";
@import "src/assets/styles/base/_variables.scss";
@import "src/assets/styles/_custom-mixins";
@import "src/assets/styles/fonts";
@import "src/assets/styles/_variables.scss";
:host {
  .refreshspinner {
    stroke: $blue !important;
    width: 1.875rem;
    left: 0;
    top: 0;
    height: 2.5rem;
    position: relative !important;
  }
  .spinner-div {
    padding: 40px;
    background-color: map-get($colors, light_gray);
    text-align: center;
    border: none !important;
  }
  .profile-last-login-text {
    color: map-get($colors, light_gray_bd);
    text-align: center;
    @include margin(0);
    font-size: 1.2rem;
    @include padding(0, 5px, 8px, 5px);
  }
  .profile-name {
    color: map-get($colors, dark);
    text-align: center;
    font-size: 2rem;
    @extend .font-weight-bold;
    @include margin(0);
    @include padding(10px, 5px, 0, 5px);
  }
  .profile-head {
    position: relative;
    .profile-symbol {
      position: absolute;
      top: -0.375rem;
     }
  }
  .profile-share-icon{
    .share-icon{
      color: $blue;
      position: relative;
      top: 0.375rem;
      margin-left: 8px;
    }
  }
  
  ion-row {
    @include padding(0 !important);
  }
  ion-spinner {
    position: absolute;
    display: inline-block;
    width: 1.25rem;
    left: 47vw;
    top: 10vh;
    height: 1.25rem;
  }
  .badges {
    ion-avatar img,
    ion-thumbnail img {
      display: block;
      @include margin(30px auto);
    }
  }
  ion-card {
    border-radius: 4px;
    box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.16);
    background-color: map-get($colors, white);
    border: solid 0.5px map-get($colors, medium_gray);
    width: 80vw;
    display: inline-block;
    .badge {
      color: map-get($colors, primary);
      font-size: 0.688rem;
      height: 1.25rem;
      box-shadow: none;
      --border-width: 0.031rem;
      @extend .font-weight-400;
      text-transform: capitalize;
      letter-spacing: normal;
    }
    .top {
      min-height: 5.313rem;
      .img-container {
        border: 1px solid map-get($colors, pale_cyan);
        @include padding(0 !important);
        background: map-get($colors, white_e9);
        min-height: 5.313rem;
        max-height: 5.313rem;
        border-radius: 4px;
        img {
          max-height: 5.313rem;
          @include margin(0 auto);
          width: auto;
          transform: translateY(-56%);
          position: relative;
          top: 50%;
        }
      }
      .info {
        color: map-get($colors, dark_gray_61);
      }
    }
    h6.name {
      word-break: break-all;
      white-space: normal;
      min-height: 2rem;
      font-size: 0.875rem !important;
      color: map-get($colors, primary_black);
      width: 100%;
    }
    h6.second-line-ellipsis {
      -webkit-line-clamp: 2;
      text-overflow: ellipsis;
      overflow: hidden;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      height: 2rem;
    }
    .author {
      font-size: 0.813rem;
      font-weight: normal;
      font-style: normal;
      font-stretch: normal;
      line-height: normal;
      letter-spacing: normal;
      color: map-get($colors, granite_gray);
      min-height: 1.25rem;
    }
  }
  .roles-container {
    color: map-get($colors, primary_blue);
    @include margin(5px, 0);
  }
  .roles {
    border: 0.5px solid map-get($colors, primary_blue);
    @include padding(4px, 15px);
    border-radius: 4px;
    display: inline-block;
  }
  .school-recent {
    margin: 0 auto;
    @include padding(8px, 16px, 8px, 16px);
    text-align: center;
  }
  .sb-btn-footer-text {
    color : $gray;
    font-weight: 100;
    font-size: ($font-size-base - 0.125);
    text-align: center;
    text-transform: initial;
  }
.sb-btn-tile {
    position: relative;
    flex-direction: column;
    background-color: $white;
    width:4.5rem;
    height:4.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    .view-icon{
      color: $blue;
    }
    .sb-btn-footer-text {
      font-weight: 400;
      color: $blue;
    }
  }
  button.sb-btn-tile:focus {
    outline: none;
  }
  .sb-dt-card-blue-icon{
    font-size : ($font-size-base * 2) + 0.125;
    color: $primary-color;
    @include margin(0, 0, ($base-block-space * .5), 0);
  }
  .contacts {
    padding: 15px;
    background-color: map-get($colors, bright_blue_19);
    text-align: center;
    .phone {
      display: inline-block;
      border-radius: 25px;
      @include padding($base-block-space, $base-block-space * 2);
      @include margin(null, null, 10px, null);
      background-color: map-get($colors, white);
      color: map-get($colors, primary_blue);
      &.light {
        color: $signup-btn-bg-not-active-color;
      }
    }
    .email {
      display: inline-block;
      border-radius: 25px;
      @include padding($base-block-space, $base-block-space * 2);
      background-color: map-get($colors, white);
      color: map-get($colors, primary_blue);
      border-bottom: 0.3px solid map-get($colors, bright_blue_19);
      border-top: 0.3px solid map-get($colors, bright_blue_19);
      &.light {
        color: map-get($colors, gray_9b);
      }
    }
  }
  .school-details {
    padding: 15px;
    background-color: map-get($colors, pale_blue_e0);
    text-align: center;
    border-bottom: 0.3px solid map-get($colors, bright_blue_19);
    border-top: 0.3px solid map-get($colors, bright_blue_19);
    .container {
      text-align: center;
      @include margin(null, null, 10px, null);
    }
  }
  .trainings {
    .heading {
      @include padding(15px);
      background-color: map-get($colors, white);
      @include margin(null, null, 2px, null);
      border-bottom: 0.5px solid map-get($colors, dark_gray);
    }
    .content {
      @include margin(8px);
      background-color: map-get($colors, white);
      border: 0.5px solid map-get($colors, dark_gray);
      border-radius: 4px;
    }
  }
  .contributions {
    min-height: 14.375rem;
    @include margin(0, 0, 16px, 0);
    background: map-get($colors, white);
  }
  .short-btn {
    height: 1.625rem;
  }
  .custom-round {
    border-radius: 64px !important;
    --background: #024F9D !important;
  }
  .bottom-block {
    background: map-get($colors, white_fa);
  }
  .align-middle {
    vertical-align: middle;
    display: inline-block;
  }
  .avatar-tickmark {
    width: $base-block-space*4;
    height: $base-block-space*4;
    position: absolute;
    left: 53%;
  }
  .training-1 {
    width: 80%;
    float: left;
    padding-left: 2rem;
    @include padding(16px, null, 8px, null);
  }
  .training-2 {
    .sb-btn-tile {
      margin: 0.5rem 0 !important;
    }
  }
  .batch-detail {
    color: var(--app-primary);
  }
  .flex-nowrap {
    display: flex;
    justify-content: space-between;
    flex-wrap: nowrap;
    border-bottom: 0.5px solid map-get($colors, dark_gray);
    @include padding(null, 16px, null, 16px);
  }
  .flex-nowrap-last {
    display: flex;
    justify-content: space-between;
    flex-wrap: nowrap;
    @include padding(null, 16px, null, 16px);
  }
  .margin-pull-up {
      margin-top: -18px;
  }
  .m-t-4 {
      margin-top: 4px;
  }
  .cert-download {
      width:2.188rem;
      height:1.563rem;
      margin-bottom: 4px;
  }
  
  .add-size{
    font-size: 1.5rem;
    padding-right: 8px;
  }
  .enrolled-status-text {
    font-family: "Noto Sans", sans-serif;
    font-size: 0.75rem;
    font-weight: bold;
  }
  .ongoing-status-text{
    @extend .enrolled-status-text;
    color: $blue;
  }
  .completed-status-text{
    @extend .enrolled-status-text;
    color: $green;
  }
  .self-declare-btn{
    margin: 8px 0 16px;
    ion-button{
      text-transform: none;
      --background: #{map-get($colors, dark_green)};
      --padding-start: 24px;
      --padding-end: 24px;
    }
  }
  .self-declare-teacher-details{
    padding: 16px;
    background-color: map-get($colors, bright_blue_19);
    text-align: center;
    color: map-get($colors, white);
    font-size: $font-size-base;
    
    .container{
      @include margin(null, null, 8px, null);
    }
    ion-button{
      text-transform: none;
      --padding-start: 24px;
      --padding-end: 24px;
    }
    .declare-info{
      margin: 0;
      font-size: $font-size-base;
      font-weight: bold;
    }
  }
  .app-name{
    text-transform: lowercase;
    display: inline-block;
  }
  .app-name::first-letter{
    text-transform: capitalize
  }
  .refresh-icon {
    color: map-get($colors, primary_blue);
    float: right;
    height: 2.5rem !important;
    width: 2.5rem !important;
    margin-top: -0.5rem;
  }
  ion-icon.refresh-icon.md.hydrated:active {
    background: map-get($colors, white_e8);
    border-radius: 18px;
  }
  .declared-error-container{
    margin: auto;
    @include margin(null, null, 8px, null);
    width: 50%;
    border: 1px solid map-get($colors, danger);
    border-left: 5px solid map-get($colors, danger);
    border-radius: 10px;
    background: map-get($colors, white);
    @include padding(8px, 0, 8px, 0);
    .declared-status{
      color: map-get($colors, danger);
    }
    .declared-message{
      color: map-get($colors, black);
    }
  }
  .preference-info {
    font-size: 1.3rem;
    font-weight: 600;
    text-align: center;
  }
  .framework-block {
    border-style: double;
    margin-top: 8px;
    border-radius: 1rem;
    background-color: aliceblue;
    border-color: aliceblue;
    padding-top: 12px;
  }
  .location-mapping-block {
    border-style: double;
    border-radius: 1rem;
    background-color: aliceblue;
    border-color: aliceblue;
    padding-top: 12px;
  }
}
.project-submitted{
  color : var(--app-green) !important;
}