diff --git a/projects/gameboard-ui/src/app/admin/admin.module.ts b/projects/gameboard-ui/src/app/admin/admin.module.ts index 912dbcba3..63b187a08 100644 --- a/projects/gameboard-ui/src/app/admin/admin.module.ts +++ b/projects/gameboard-ui/src/app/admin/admin.module.ts @@ -88,6 +88,8 @@ import { ToSupportCodePipe } from '@/standalone/core/pipes/to-support-code.pipe' import { IfHasPermissionDirective } from '@/standalone/directives/if-has-permission.directive'; import { FeedbackTemplatePickerComponent } from "../feedback/components/feedback-template-picker/feedback-template-picker.component"; import { UserPickerComponent } from '@/standalone/users/user-picker/user-picker.component'; +import { CertificateTemplatePickerComponent } from '@/certificates/components/certificate-template-picker/certificate-template-picker.component'; +import { CertificatePreviewerComponent } from '@/certificates/components/certificate-previewer/certificate-previewer.component'; @NgModule({ declarations: [ @@ -160,6 +162,7 @@ import { UserPickerComponent } from '@/standalone/users/user-picker/user-picker. RouterModule.forChild([ { path: '', component: AdminPageComponent, title: "Admin", children: [ + { path: "certificates/templates/:templateId/preview", component: CertificatePreviewerComponent, title: "Certificate Template Preview" }, { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, { path: 'dashboard', component: DashboardComponent }, { @@ -225,6 +228,8 @@ import { UserPickerComponent } from '@/standalone/users/user-picker/user-picker. SafeUrlPipe, SpinnerComponent, ToSupportCodePipe, + CertificatePreviewerComponent, + CertificateTemplatePickerComponent, FeedbackTemplatePickerComponent, UserPickerComponent, ] diff --git a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-settings/game-center-settings.component.html b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-settings/game-center-settings.component.html index 5589c676b..7b2a05580 100644 --- a/projects/gameboard-ui/src/app/admin/components/game-center/game-center-settings/game-center-settings.component.html +++ b/projects/gameboard-ui/src/app/admin/components/game-center/game-center-settings/game-center-settings.component.html @@ -147,6 +147,7 @@
- Insert dynamic content by referring to a property with double-curly syntax
- {{"\{\{game_name\}\}"}}
. For example,
- <h1>{{"\{\{leaderboard_name\}\}"}}</h1>
.
- The following properties will get replaced when a player certificate renders:
-
- game_name — Name of this game - competition — Competition type of this game - season — Season of this game - round — Round of this game - track — Track of this game - user_name — Individual user's approved name - score — Total player score for this game - rank — Final leaderboard ranking of the player - leaderboard_name — Approved name for either team or individual - date — Date player's session ended for this game - player_count — Number of players who participated in this game - team_count — Number of teams who participated in this game-
- Tip: Create an outer div with fixed height and width and position: relative
.
- Create inner
- divs with position: absolute; text-align: center;
and set textbox width and X/Y
- position with
- top: __px; left: __px; width: __px;
.
- To add a background image, use
- background-size: 100% 100%; background-image: url('URL_HERE');
-
Name | +Requested Name | +Override Name | +Status | ++ + + + |
---|---|---|---|---|
{{ player.name }} | +{{ player.pendingName || "--" }} | ++ + | ++ + | ++ + + + | +
- Players are able to save certificates in PDF format for each practice challenge they fully complete. Use - this field to customize the appearance of these certificates. + Players are able to save certificates in PDF format for each practice challenge they fully complete. Choose + a template below to customize the appearance of these certificates.
- - +
diff --git a/projects/gameboard-ui/src/app/prac/components/practice-challenge-solved-modal/practice-challenge-solved-modal.component.ts b/projects/gameboard-ui/src/app/prac/components/practice-challenge-solved-modal/practice-challenge-solved-modal.component.ts
index 1ef1bc2a8..081e820de 100644
--- a/projects/gameboard-ui/src/app/prac/components/practice-challenge-solved-modal/practice-challenge-solved-modal.component.ts
+++ b/projects/gameboard-ui/src/app/prac/components/practice-challenge-solved-modal/practice-challenge-solved-modal.component.ts
@@ -6,6 +6,7 @@ import { PracticeService } from '@/services/practice.service';
import { RouterService } from '@/services/router.service';
import { UnsubscriberService } from '@/services/unsubscriber.service';
import { BsModalRef } from 'ngx-bootstrap/modal';
+import { GameService } from '@/api/game.service';
export interface PracticeChallengeSolvedModalContext {
challenge: UserActiveChallenge;
@@ -20,9 +21,11 @@ export interface PracticeChallengeSolvedModalContext {
export class PracticeChallengeSolvedModalComponent implements OnInit {
context?: PracticeChallengeSolvedModalContext;
protected certificateUrl?: string;
+ protected feedbackTemplateId?: string;
protected isCertificateConfigured = false;
constructor(
+ private gameService: GameService,
private practiceService: PracticeService,
private routerService: RouterService,
private unsub: UnsubscriberService,
@@ -33,13 +36,14 @@ export class PracticeChallengeSolvedModalComponent implements OnInit {
throw new Error("Can't resolve the context for the PracticeChallengeSolvedModalComponent.");
}
+ // we need the game to check its challenges feedback template and its cert template
+ const game = await firstValueFrom(this.gameService.retrieve(this.context.challenge.game.id));
+
+ this.feedbackTemplateId = game.challengesFeedbackTemplateId;
const practiceSettings = await firstValueFrom(this.practiceService.getSettings());
- this.isCertificateConfigured = !!practiceSettings.certificateHtmlTemplate;
+ this.isCertificateConfigured = !!game.practiceCertificateTemplateId || !!practiceSettings.certificateTemplateId;
this.certificateUrl = this.routerService.getCertificatePrintableUrl(PlayerMode.practice, this.context.challenge.spec.id);
- // load feedback form data
- // this.feedbackFormContext = await this.loadFeedbackFormContext(this.context.challenge);
-
// wire up event handler for background-click dismiss
if (this.modalRef.onHidden) {
this.unsub.add(
@@ -52,22 +56,4 @@ export class PracticeChallengeSolvedModalComponent implements OnInit {
this.modalRef.hide();
this.routerService.toPracticeArea();
}
-
- // private async loadFeedbackFormContext(challenge: UserActiveChallenge): PromiseSummary
Questions
Need help?
-
+
+
-
+
-
- {{cert.game.name}}
+
+ {{certificate.game.name}}
- {{cert.player.rank}}
-
-
+
+
{{ certificate.score }}
{{ certificate.date | friendlyDateAndTime }}
diff --git a/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.scss b/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.scss
index c989ffa38..018775bee 100644
--- a/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.scss
+++ b/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.scss
@@ -1,4 +1,4 @@
.data-row {
- height: 3rem !important;
- line-height: 3rem !important;
+ height: 3rem !important;
+ // line-height: 3rem !important;
}
diff --git a/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.ts b/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.ts
index 5d3c52ddf..13d3e2731 100644
--- a/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.ts
+++ b/projects/gameboard-ui/src/app/users/components/practice-certificates/practice-certificates.component.ts
@@ -4,8 +4,8 @@ import { slug } from '@/../tools/functions';
import { CertificatesService } from '@/api/certificates.service';
import { UserService as LocalUser } from '@/utility/user.service';
import { ConfigService } from '@/utility/config.service';
-import { PracticeModeCertificate } from '@/users/users.models';
import { practiceCertificateToPublishedViewModel } from '@/users/functions';
+import { PracticeModeCertificate } from '@/certificates/certificates.models';
interface PracticeCertificatesContext {
certificates: PracticeModeCertificate[];
diff --git a/projects/gameboard-ui/src/app/users/functions.ts b/projects/gameboard-ui/src/app/users/functions.ts
index 3a5ba6900..5f4eec1a3 100644
--- a/projects/gameboard-ui/src/app/users/functions.ts
+++ b/projects/gameboard-ui/src/app/users/functions.ts
@@ -1,5 +1,5 @@
-import { PlayerCertificate, PlayerMode } from "@/api/player-models";
-import { PracticeModeCertificate, PublishedCertificateViewModel } from "./users.models";
+import { PlayerMode } from "@/api/player-models";
+import { CompetitiveModeCertificate, PracticeModeCertificate, PublishedCertificateViewModel } from "@/certificates/certificates.models";
export function practiceCertificateToPublishedViewModel(certificate: PracticeModeCertificate): PublishedCertificateViewModel {
return {
@@ -9,12 +9,10 @@ export function practiceCertificateToPublishedViewModel(certificate: PracticeMod
};
}
-export function competitiveCertificateToPublishedViewmodel(certificate: PlayerCertificate): PublishedCertificateViewModel {
+export function competitiveCertificateToPublishedViewmodel(certificate: CompetitiveModeCertificate): PublishedCertificateViewModel {
return {
- id: undefined,
- publishedOn: certificate.publishedOn,
+ ...certificate,
awardedForEntity: { id: certificate.game.id, name: certificate.game.name },
- ownerUser: { id: certificate.player.userId, name: certificate.player.approvedName },
mode: PlayerMode.competition
};
}
diff --git a/projects/gameboard-ui/src/app/users/users.models.ts b/projects/gameboard-ui/src/app/users/users.models.ts
index ffe2a613f..0411ccbfa 100644
--- a/projects/gameboard-ui/src/app/users/users.models.ts
+++ b/projects/gameboard-ui/src/app/users/users.models.ts
@@ -1,37 +1,3 @@
-import { Duration } from "luxon";
-import { SimpleEntity } from "@/api/models";
-import { PlayerMode } from "@/api/player-models";
-
-export interface PracticeModeCertificate {
- challenge: {
- id: string;
- name: string;
- description: string;
- challengeSpecId: string;
- };
- date: Date;
- game: {
- id: string;
- name: string;
- season: string;
- track: string;
- division: string;
- }
- ownerUser: SimpleEntity;
- playerName: string;
- publishedOn?: Date;
- score: number;
- time: Duration;
-}
-
-export interface PublishedCertificateViewModel {
- id?: string;
- publishedOn?: Date;
- awardedForEntity: SimpleEntity;
- ownerUser: SimpleEntity;
- mode: PlayerMode;
-}
-
export interface UserAppSettings {
useStickyChallengePanel: boolean;
}
diff --git a/projects/gameboard-ui/src/app/users/users.module.ts b/projects/gameboard-ui/src/app/users/users.module.ts
index f5efe7128..66ee78df1 100644
--- a/projects/gameboard-ui/src/app/users/users.module.ts
+++ b/projects/gameboard-ui/src/app/users/users.module.ts
@@ -14,7 +14,6 @@ import { ProfileHistoryComponent } from './components/profile-history/profile-hi
import { UserPageComponent } from './components/user-page/user-page.component';
import { SponsorsModule } from '@/sponsors/sponsors.module';
import { SettingsComponent } from './components/settings/settings.component';
-import { UserService as LocalUserService } from '@/utility/user.service';
import { UserRolePermissionsService } from '@/api/user-role-permissions.service';
import { SpinnerComponent } from '@/standalone/core/components/spinner/spinner.component';
@@ -59,7 +58,6 @@ const DECLARED_COMPONENTS = [
component: SettingsComponent,
canActivate: [() => {
const permissionsService = inject(UserRolePermissionsService);
- const localUser = inject(LocalUserService);
return permissionsService.can("Admin_View");
}]
diff --git a/projects/gameboard-ui/src/assets/templates/certificate-template.sample.html b/projects/gameboard-ui/src/assets/templates/certificate-template.sample.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/projects/gameboard-ui/src/assets/templates/practice-certificate.template.html b/projects/gameboard-ui/src/assets/templates/practice-certificate.template.html
deleted file mode 100644
index 7d5fcddf8..000000000
--- a/projects/gameboard-ui/src/assets/templates/practice-certificate.template.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-