From 0d23767c3502bde8b6cf248ba819f6dbfd7ef99a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= <crazyserver@gmail.com>
Date: Tue, 13 Nov 2018 11:38:07 +0100
Subject: [PATCH] MOBILE-2638 badges: Add 2.0 specification fields

---
 scripts/langindex.json                        |  16 +++
 src/addon/badges/lang/en.json                 |  18 ++-
 .../pages/issued-badge/issued-badge.html      | 112 +++++++++++++++++-
 .../badges/pages/issued-badge/issued-badge.ts |  45 +++----
 src/assets/lang/en.json                       |  18 ++-
 5 files changed, 183 insertions(+), 26 deletions(-)

diff --git a/scripts/langindex.json b/scripts/langindex.json
index 5ca395007..9cbade8ab 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -1,15 +1,31 @@
 {
+  "addon.badges.alignment": "badges",
   "addon.badges.badgedetails": "badges",
   "addon.badges.badges": "badges",
+  "addon.badges.bendorsement": "badges",
+  "addon.badges.claimcomment": "badges",
+  "addon.badges.claimid": "badges",
   "addon.badges.contact": "badges",
   "addon.badges.dateawarded": "badges",
   "addon.badges.expired": "badges",
   "addon.badges.expirydate": "badges",
+  "addon.badges.imageauthoremail": "badges",
+  "addon.badges.imageauthorname": "badges",
+  "addon.badges.imageauthorurl": "badges",
+  "addon.badges.imagecaption": "badges",
   "addon.badges.issuancedetails": "badges",
   "addon.badges.issuerdetails": "badges",
+  "addon.badges.issueremail": "badges",
   "addon.badges.issuername": "badges",
+  "addon.badges.language": "badges",
+  "addon.badges.noalignment": "badges",
   "addon.badges.nobadges": "badges",
+  "addon.badges.noendorsement": "badges",
+  "addon.badges.norelated": "badges",
   "addon.badges.recipientdetails": "badges",
+  "addon.badges.relatedbages": "badges",
+  "addon.badges.version": "badges",
+  "addon.badges.warnexpired": "badges",
   "addon.block_activitymodules.pluginname": "block_activity_modules",
   "addon.block_myoverview.all": "block_myoverview",
   "addon.block_myoverview.favourites": "block_myoverview",
diff --git a/src/addon/badges/lang/en.json b/src/addon/badges/lang/en.json
index 4443773c4..5a02d9185 100644
--- a/src/addon/badges/lang/en.json
+++ b/src/addon/badges/lang/en.json
@@ -1,13 +1,29 @@
 {
+    "alignment": "Competencies alignment",
     "badgedetails": "Badge details",
     "badges": "Badges",
+    "bendorsement": "Endorsement",
+    "claimcomment": "Endorsement Comment",
+    "claimid": "Claim URL",
     "contact": "Contact",
     "dateawarded": "Date issued",
     "expired": "Expired",
     "expirydate": "Expiry date",
+    "imageauthoremail": "Image author's email",
+    "imageauthorname": "Image author's name",
+    "imageauthorurl": "Image author's URL",
+    "imagecaption": "Image caption",
     "issuancedetails": "Badge expiry",
     "issuerdetails": "Issuer details",
     "issuername": "Issuer name",
+    "issueremail": "Email",
+    "language": "Language",
+    "noalignment": "This badge does not have a competencies alignment.",
     "nobadges": "There are no badges available.",
-    "recipientdetails": "Recipient details"
+    "noendorsement": "This badge does not have an endorsement.",
+    "norelated": "This badge does not have related badges.",
+    "recipientdetails": "Recipient details",
+    "relatedbages": "Related badges",
+    "version": "Version",
+    "warnexpired": " (This badge has expired!)"
 }
diff --git a/src/addon/badges/pages/issued-badge/issued-badge.html b/src/addon/badges/pages/issued-badge/issued-badge.html
index 65491218d..65f1272d0 100644
--- a/src/addon/badges/pages/issued-badge/issued-badge.html
+++ b/src/addon/badges/pages/issued-badge/issued-badge.html
@@ -54,7 +54,15 @@
             </ion-item-divider>
             <ion-item text-wrap *ngIf="badge.name">
                 <h2>{{ 'core.name' | translate}}</h2>
-                <p>{{badge.name}}</p>
+                <p>{{ badge.name }}</p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.version">
+                <h2>{{ 'addon.badges.version' | translate}}</h2>
+                <p>{{ badge.version }}</p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.language">
+                <h2>{{ 'addon.badges.language' | translate}}</h2>
+                <p>{{ badge.language }}</p>
             </ion-item>
             <ion-item text-wrap *ngIf="badge.description">
                 <h2>{{ 'core.description' | translate}}</h2>
@@ -62,12 +70,33 @@
                     <core-format-text clean="true" [text]="badge.description"></core-format-text>
                 </p>
             </ion-item>
+            <ion-item text-wrap *ngIf="badge.imageauthorname">
+                <h2>{{ 'addon.badges.imageauthorname' | translate}}</h2>
+                <p>{{ badge.imageauthorname }}</p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.imageauthoremail">
+                <h2>{{ 'addon.badges.imageauthoremail' | translate}}</h2>
+                <p><a href="mailto:{{badge.imageauthoremail}}" core-link auto-login="no">
+                    <core-format-text [text]="badge.imageauthoremail"></core-format-text>
+                </a></p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.imageauthorurl">
+                <h2>{{ 'addon.badges.imageauthorurl' | translate}}</h2>
+                <p><a [href]="badge.imageauthorurl" core-link auto-login="no">
+                    <core-format-text [text]="badge.imageauthorurl"></core-format-text>
+                </a></p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.imagecaption">
+                <h2>{{ 'addon.badges.imagecaption' | translate}}</h2>
+                <p><core-format-text [text]="badge.imagecaption"></core-format-text></p>
+            </ion-item>
             <ion-item text-wrap *ngIf="course.fullname">
                 <h2>{{ 'core.course' | translate}}</h2>
                 <p>
                     <core-format-text [text]="course.fullname"></core-format-text>
                 </p>
             </ion-item>
+            <!-- Criteria (not yet avalaible) -->
         </ion-item-group>
 
         <ion-item-group>
@@ -80,7 +109,86 @@
             </ion-item>
             <ion-item text-wrap *ngIf="badge.dateexpire">
                 <h2>{{ 'addon.badges.expirydate' | translate}}</h2>
-                <p>{{badge.dateexpire | coreToLocaleString }}</p>
+                <p>
+                    {{ badge.dateexpire | coreToLocaleString }}
+                    <span class="text-danger" *ngIf="currentTime >= badge.dateexpire">
+                        {{ 'addon.badges.warnexpired' | translate }}
+                    </span>
+                </p>
+            </ion-item>
+            <!-- Evidence (not yet avalaible) -->
+        </ion-item-group>
+
+        <!-- Endorsement -->
+        <ion-item-group *ngIf="badge.endorsement">
+            <ion-item-divider color="light">
+                <h2>{{ 'addon.badges.bendorsement' | translate}}</h2>
+            </ion-item-divider>
+            <ion-item text-wrap *ngIf="badge.endorsement.issuername">
+                <h2>{{ 'addon.badges.issuername' | translate}}</h2>
+                <p>{{ badge.endorsement.issuername }}</p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.endorsement.issueremail">
+                <h2>{{ 'addon.badges.issueremail' | translate}}</h2>
+                <p><a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no">
+                    <core-format-text [text]="badge.endorsement.issueremail"></core-format-text>
+                </a></p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.endorsement.issuerurl">
+                <h2>{{ 'addon.badges.issuerurl' | translate}}</h2>
+                <p><a [href]="badge.endorsement.issuerurl" core-link auto-login="no">
+                    <core-format-text [text]="badge.endorsement.issuerurl"></core-format-text>
+                </a></p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.endorsement.dateissued">
+                <h2>{{ 'addon.badges.dateawarded' | translate}}</h2>
+                <p>{{ badge.endorsement.dateissued | coreToLocaleString }}</p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.endorsement.claimid">
+                <h2>{{ 'addon.badges.claimid' | translate}}</h2>
+                <p><a [href]="badge.endorsement.claimid" core-link auto-login="no">
+                    <core-format-text [text]="badge.endorsement.claimid"></core-format-text>
+                </a></p>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.endorsement.claimcomment">
+                <h2>{{ 'addon.badges.claimcomment' | translate}}</h2>
+                <p>
+                    <core-format-text [text]="badge.endorsement.claimcomment"></core-format-text>
+                </p>
+            </ion-item>
+        </ion-item-group>
+        <ion-item-group *ngIf="badge.relatedbadges && !badge.endorsement">
+            <ion-item-divider color="light">
+                <h2>{{ 'addon.badges.bendorsement' | translate}}</h2>
+            </ion-item-divider>
+            <ion-item text-wrap>
+                <h2>{{ 'addon.badges.noendorsement' | translate}}</h2>
+            </ion-item>
+        </ion-item-group>
+
+        <!-- Related badges -->
+        <ion-item-group *ngIf="badge.relatedbadges">
+            <ion-item-divider color="light">
+                <h2>{{ 'addon.badges.relatedbages' | translate}}</h2>
+            </ion-item-divider>
+            <ion-item text-wrap *ngFor="let relatedBadge of badge.relatedbadges">
+                <h2><core-format-text [text]="relatedBadge.name"></core-format-text></h2>
+            </ion-item>
+            <ion-item text-wrap *ngIf="badge.relatedbadges.length == 0">
+                <h2>{{ 'addon.badges.norelated' | translate}}</h2>
+            </ion-item>
+        </ion-item-group>
+
+        <!-- Competencies alignment -->
+        <ion-item-group *ngIf="badge.competencies">
+            <ion-item-divider color="light">
+                <h2>{{ 'addon.badges.alignment' | translate}}</h2>
+            </ion-item-divider>
+            <a ion-item text-wrap *ngFor="let competency of badge.competencies" [href]="competency.targeturl" core-link auto-login="no">
+                <h2><core-format-text [text]="competency.targetname"></core-format-text></h2>
+            </a>
+            <ion-item text-wrap *ngIf="badge.competencies.length == 0">
+                <h2>{{ 'addon.badges.noalignment' | translate}}</h2>
             </ion-item>
         </ion-item-group>
     </core-loading>
diff --git a/src/addon/badges/pages/issued-badge/issued-badge.ts b/src/addon/badges/pages/issued-badge/issued-badge.ts
index 62c38f98d..ff79f7841 100644
--- a/src/addon/badges/pages/issued-badge/issued-badge.ts
+++ b/src/addon/badges/pages/issued-badge/issued-badge.ts
@@ -14,12 +14,12 @@
 
 import { Component, ViewChild } from '@angular/core';
 import { IonicPage, Content, NavParams } from 'ionic-angular';
-import { AddonBadgesProvider } from '../../providers/badges';
 import { CoreTimeUtilsProvider } from '@providers/utils/time';
 import { CoreDomUtilsProvider } from '@providers/utils/dom';
 import { CoreSitesProvider } from '@providers/sites';
 import { CoreUserProvider } from '@core/user/providers/user';
 import { CoreCoursesProvider } from '@core/courses/providers/courses';
+import { AddonBadgesProvider } from '../../providers/badges';
 
 /**
  * Page that displays the list of calendar events.
@@ -32,9 +32,10 @@ import { CoreCoursesProvider } from '@core/courses/providers/courses';
 export class AddonBadgesIssuedBadgePage {
     @ViewChild(Content) content: Content;
 
-    courseId: number;
-    userId: number;
-    badgeHash: string;
+    protected badgeHash: string;
+    protected userId: number;
+    protected courseId: number;
+
     user: any = {};
     course: any = {};
     badge: any = {};
@@ -70,29 +71,29 @@ export class AddonBadgesIssuedBadgePage {
         const promises = [];
 
         this.currentTime = this.timeUtils.timestamp();
-        let promise = this.userProvider.getProfile(this.userId, this.courseId, true).then((user) => {
+        promises.push(this.userProvider.getProfile(this.userId, this.courseId, true).then((user) => {
             this.user = user;
-        });
-        promises.push(promise);
+        }));
 
-        promise = this.badgesProvider.getUserBadges(this.courseId, this.userId).then((badges) => {
-            badges.forEach((badge) => {
-                if (this.badgeHash == badge.uniquehash) {
-                    this.badge = badge;
-                    if (badge.courseid) {
-                        return this.coursesProvider.getUserCourse(badge.courseid, true).then((course) => {
-                            this.course = course;
-                        }).catch(() => {
-                            // Maybe an old deleted course.
-                            this.course = null;
-                        });
-                    }
-                }
+        promises.push(this.badgesProvider.getUserBadges(this.courseId, this.userId).then((badges) => {
+            const badge = badges.find((badge) => {
+                return this.badgeHash == badge.uniquehash;
             });
+
+            if (badge) {
+                this.badge = badge;
+                if (badge.courseid) {
+                    return this.coursesProvider.getUserCourse(badge.courseid, true).then((course) => {
+                        this.course = course;
+                    }).catch(() => {
+                        // Maybe an old deleted course.
+                        this.course = null;
+                    });
+                }
+            }
         }).catch((message) => {
             this.domUtils.showErrorModalDefault(message, 'Error getting badge data.');
-        });
-        promises.push(promise);
+        }));
 
         return Promise.all(promises);
     }
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index cc1fa5926..b3b201ba3 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -1,15 +1,31 @@
 {
+    "addon.badges.alignment": "Competencies alignment",
     "addon.badges.badgedetails": "Badge details",
     "addon.badges.badges": "Badges",
+    "addon.badges.bendorsement": "Endorsement",
+    "addon.badges.claimcomment": "Endorsement Comment",
+    "addon.badges.claimid": "Claim URL",
     "addon.badges.contact": "Contact",
     "addon.badges.dateawarded": "Date issued",
     "addon.badges.expired": "Expired",
     "addon.badges.expirydate": "Expiry date",
+    "addon.badges.imageauthoremail": "Image author's email",
+    "addon.badges.imageauthorname": "Image author's name",
+    "addon.badges.imageauthorurl": "Image author's URL",
+    "addon.badges.imagecaption": "Image caption",
     "addon.badges.issuancedetails": "Badge expiry",
     "addon.badges.issuerdetails": "Issuer details",
+    "addon.badges.issueremail": "Email",
     "addon.badges.issuername": "Issuer name",
+    "addon.badges.language": "Language",
+    "addon.badges.noalignment": "This badge does not have a competencies alignment.",
     "addon.badges.nobadges": "There are no badges available.",
+    "addon.badges.noendorsement": "This badge does not have an endorsement.",
+    "addon.badges.norelated": "This badge does not have related badges.",
     "addon.badges.recipientdetails": "Recipient details",
+    "addon.badges.relatedbages": "Related badges",
+    "addon.badges.version": "Version",
+    "addon.badges.warnexpired": " (This badge has expired!)",
     "addon.block_activitymodules.pluginname": "Activities",
     "addon.block_myoverview.all": "All",
     "addon.block_myoverview.favourites": "Starred",
@@ -1661,4 +1677,4 @@
     "core.year": "year",
     "core.years": "years",
     "core.yes": "Yes"
-}
+}
\ No newline at end of file