Skip to content

Commit c9269c8

Browse files
authored
Merge pull request #1383 from bcgov/stories/ecer-5199
ECER-5199: Add toggle button /my-certifications
2 parents 49a806c + 67cecbb commit c9269c8

File tree

20 files changed

+360
-192
lines changed

20 files changed

+360
-192
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { beforeAll } from 'vitest';
2-
import { setProjectAnnotations } from '@storybook/vue3-vite';
3-
import * as projectAnnotations from './preview';
1+
import { beforeAll } from "vitest";
2+
import { setProjectAnnotations } from "@storybook/vue3-vite";
3+
import * as projectAnnotations from "./preview";
44

55
// This is an important step to apply the right configuration when testing your stories.
66
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
77
const project = setProjectAnnotations([projectAnnotations]);
88

9-
beforeAll(project.beforeAll);
9+
beforeAll(project.beforeAll);
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
{
2-
"recommendations": [
3-
"Vue.volar",
4-
"dbaeumer.vscode-eslint",
5-
"esbenp.prettier-vscode"
6-
]
7-
}
2+
"recommendations": ["Vue.volar", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
3+
}

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package-lock.json

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"uuid": "^11.1.0",
3434
"vue": "^3.5.17",
3535
"vue-router": "^4.5.1",
36-
"vuetify": "^3.9.0"
36+
"vuetify": "^3.9.5"
3737
},
3838
"devDependencies": {
3939
"@chromatic-com/storybook": "^4.0.1",
@@ -63,6 +63,7 @@
6363
"husky": "^9.1.7",
6464
"openapicmd": "^2.6.1",
6565
"playwright": "^1.53.1",
66+
"prettier": "^3.6.2",
6667
"sass": "^1.86.3",
6768
"storybook": "^9.0.17",
6869
"tsx": "^4.20.3",

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/api/application.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const cancelDraftApplication = async (applicationId: string): Promise<ApiRespons
4747

4848
return await apiResultHandler.execute<Components.Schemas.CancelDraftApplicationResponse | null | undefined>({
4949
request: client.draftapplication_delete(pathParameters),
50-
key: "draftapplication_delete"
50+
key: "draftapplication_delete",
5151
});
5252
};
5353

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/Breadcrumb.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ export default defineComponent({
351351
case "certificate-terms-and-conditions":
352352
return [...this.baseItems, { title: "Terms and conditions", disabled: true, href: `/certificate-terms-and-conditions/${params.certificationId}` }];
353353
354-
case "my-other-certifications":
355-
return [...this.baseItems, { title: "My other certifications", disabled: true, href: "/my-other-certifications" }];
354+
case "my-certifications":
355+
return [...this.baseItems, { title: "My certifications", disabled: true, href: "/my-certifications" }];
356356
357357
case "profile":
358358
return [...this.baseItems, { title: "Profile", disabled: true, href: "/profile" }];

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/CertificationCard.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@
2626
<!-- Certificate Inline on mobile -->
2727
<template v-if="!mdAndUp">
2828
<a v-if="isCertificateActive && doesCertificateFileExist" :href="pdfUrl" target="_blank">{{ generateFileDisplayName() }}</a>
29-
<span v-if="certificateGenerationRequested" class="d-flex align-center ga-4">
29+
<span v-if="isCertificateActive && certificateGenerationRequested" class="d-flex align-center ga-4">
3030
<v-progress-circular class="mb-2" color="primary" indeterminate></v-progress-circular>
3131
<h4>Your certificate is being generated. This may take up to 10 minutes. Please check back later to download it.</h4>
3232
</span>
3333
</template>
3434

35-
<RenewAction v-if="!hasApplication" :certification="certification" />
35+
<RenewAction v-if="!hasApplication && isLatestOfType" :certification="certification" />
3636
</div>
3737
</v-col>
3838
<v-col v-if="mdAndUp" cols="4" class="text-center d-flex justify-end align-center" style="min-width: 215px">
3939
<div v-if="isCertificateActive && doesCertificateFileExist" class="d-flex flex-column align-center justify-center">
4040
<img src="../assets/certificate.svg" width="215" class="logo" alt="Certificate" />
4141
<a v-if="isCertificateActive && doesCertificateFileExist" :href="pdfUrl" target="_blank">{{ generateFileDisplayName() }}</a>
4242
</div>
43-
<div v-if="certificateGenerationRequested" class="mt-8">
43+
<div v-if="isCertificateActive && certificateGenerationRequested" class="mt-8">
4444
<v-progress-circular class="mb-2" color="primary" indeterminate></v-progress-circular>
4545
<h4>Your certificate is being generated. This may take up to 10 minutes. Please check back later to download it.</h4>
4646
</div>
@@ -81,6 +81,10 @@ export default defineComponent({
8181
type: Boolean,
8282
default: false,
8383
},
84+
isLatestOfType: {
85+
type: Boolean,
86+
default: false,
87+
},
8488
},
8589
setup() {
8690
const certificationStore = useCertificationStore();

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/CertificationList.stories.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,30 @@ const meta = {
3535
],
3636
certificateConditions: [],
3737
},
38+
{
39+
id: "f403a278-8020-f011-998a-6045bdf9b81b",
40+
name: "KARISSA CAULKINS",
41+
number: "016359",
42+
expiryDate: "2026-04-23T00:00:00",
43+
effectiveDate: "2025-04-23T00:00:00",
44+
date: "2025-04-23T00:00:00",
45+
printDate: null,
46+
hasConditions: false,
47+
levelName: "ECE Assistant",
48+
statusCode: "Expired",
49+
certificatePDFGeneration: "Yes",
50+
levels: [{ id: "556b387e-8020-f011-998a-7c1e52871876", type: "Assistant" }],
51+
files: [
52+
{
53+
id: "3979ff88-f262-4747-b294-c289caa2402a",
54+
url: "ecer_certificate/f403a278-8020-f011-998a-6045bdf9b81b",
55+
extention: ".pdf",
56+
size: "322.00 KB",
57+
name: "Cover Letter-016359.pdf",
58+
},
59+
],
60+
certificateConditions: [],
61+
},
3862
{
3963
id: "f403a278-8020-f011-998a-6045bdf9b81b",
4064
name: "KARISSA CAULKINS",

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/CertificationList.vue

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
<template>
22
<v-row>
3-
<v-col cols="12" v-for="(cert, index) in certifications" :key="index">
4-
<CertificationCard :certification="cert" :has-application="applicationStore.hasApplication" />
3+
<v-col cols="12">
4+
<div class="d-flex">
5+
<p class="align-self-center mr-4"><strong>SHOW:</strong></p>
6+
<v-sheet class="">
7+
<v-btn-toggle v-model="filter" color="primary" mandatory>
8+
<v-btn value="latest">Latest</v-btn>
9+
<v-btn value="all">All</v-btn>
10+
</v-btn-toggle>
11+
</v-sheet>
12+
</div>
13+
</v-col>
14+
<v-col cols="12">
15+
<p v-if="filter === 'latest'">Showing only your most recent certificate of each type</p>
16+
<p v-else>Showing your entire certification history</p>
17+
</v-col>
18+
<v-col cols="12" v-for="(cert, index) in displayCertifications" :key="index">
19+
<CertificationCard :certification="cert" :has-application="applicationStore.hasApplication" :is-latest-of-type="latestCertifications.includes(cert)" />
520
</v-col>
621
</v-row>
722
</template>
823

924
<script lang="ts">
1025
import { defineComponent, type PropType } from "vue";
26+
import { orderBy } from "lodash";
1127
import type { Components } from "@/types/openapi";
1228
import CertificationCard from "@/components/CertificationCard.vue";
1329
import { useApplicationStore } from "@/store/application";
@@ -23,9 +39,83 @@ export default defineComponent({
2339
required: true,
2440
},
2541
},
42+
computed: {
43+
// Helper function to get the highest priority certification type
44+
getCertificationTypePriority() {
45+
return (cert: Components.Schemas.Certification) => {
46+
if (cert.levels?.some((level) => level.type === "ECE 5 YR")) {
47+
return 1; // Highest priority
48+
} else if (cert.levels?.some((level) => level.type === "ECE 1 YR")) {
49+
return 2; // Medium priority
50+
} else if (cert.levels?.some((level) => level.type === "Assistant")) {
51+
return 3; // Lowest priority
52+
}
53+
return 4; // Other types
54+
};
55+
},
56+
57+
// Helper function to get status priority
58+
getStatusPriority() {
59+
return (statusCode: string) => {
60+
switch (statusCode) {
61+
case "Active":
62+
return 1;
63+
case "Cancelled":
64+
return 2;
65+
case "Suspended":
66+
return 3;
67+
case "Expired":
68+
return 4;
69+
default:
70+
return 5;
71+
}
72+
};
73+
},
74+
75+
// Sort certifications by status, expiry date, and certification type priority
76+
sortedCertifications() {
77+
return orderBy(
78+
this.certifications,
79+
[({ statusCode }: Components.Schemas.Certification) => this.getStatusPriority(statusCode || ""), "expiryDate", this.getCertificationTypePriority],
80+
["asc", "desc", "asc"], // asc for status (Active first), desc for expiry date (latest first), asc for type priority (ECE 5 YR = 1, Assistant = 3)
81+
);
82+
},
83+
84+
latestCertifications() {
85+
// Get the best certification from each type from the already sorted list
86+
const seenTypes = new Set<string>();
87+
const result: Components.Schemas.Certification[] = [];
88+
89+
for (const cert of this.sortedCertifications) {
90+
const certType = cert.levels?.find((level) => level.type === "ECE 5 YR" || level.type === "ECE 1 YR" || level.type === "Assistant")?.type;
91+
92+
if (certType && !seenTypes.has(certType)) {
93+
seenTypes.add(certType);
94+
result.push(cert);
95+
}
96+
}
97+
98+
return result;
99+
},
100+
101+
displayCertifications() {
102+
return this.filter === "latest" ? this.latestCertifications : this.sortedCertifications;
103+
},
104+
},
105+
data() {
106+
return {
107+
filter: "latest",
108+
};
109+
},
26110
setup() {
27111
const applicationStore = useApplicationStore();
28112
return { applicationStore };
29113
},
30114
});
31115
</script>
116+
117+
<style scoped>
118+
.v-btn-toggle > .v-btn {
119+
border-radius: 0 !important;
120+
}
121+
</style>

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/src/components/ECEFiveYearRenewalRequirements.vue

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
<v-col cols="12">
1515
<ECEHeader title="Character reference" />
1616
<div class="d-flex flex-column ga-3 my-6">
17-
<p>You will need to provide a character reference. You'll enter their name and email. We'll contact them later
18-
after you submit your application.</p>
17+
<p>You will need to provide a character reference. You'll enter their name and email. We'll contact them later after you submit your application.</p>
1918
<p>The reference must be someone who:</p>
2019
<ul class="ml-10">
2120
<li>Can speak to your character</li>
@@ -31,16 +30,14 @@
3130
<ECEHeader title="Work experience" />
3231
<div v-if="!expired" class="d-flex flex-column ga-3 my-6">
3332
<p>
34-
You need to have completed 400 hours of work experience and be able to provide references to verify the hours.
35-
If you worked at multiple locations, you
33+
You need to have completed 400 hours of work experience and be able to provide references to verify the hours. If you worked at multiple locations, you
3634
can provide multiple references.
3735
</p>
3836
<p>The hours must:</p>
3937
<ul class="ml-10">
4038
<li>Be related to the field of early childhood education</li>
4139
<li>
42-
Have been completed within the term of your current certificate (between {{
43-
formattedLatestCertificationEffectiveDate }} and
40+
Have been completed within the term of your current certificate (between {{ formattedLatestCertificationEffectiveDate }} and
4441
{{ formattedLatestCertificationExpiryDate }})
4542
</li>
4643
</ul>
@@ -53,8 +50,7 @@
5350
</div>
5451
<div v-if="expired && !expiredMoreThan5Years" class="d-flex flex-column ga-3 my-6">
5552
<p>
56-
You need to have completed 400 hours of work experience and be able to provide references to verify the hours.
57-
If you worked at multiple locations, you
53+
You need to have completed 400 hours of work experience and be able to provide references to verify the hours. If you worked at multiple locations, you
5854
can provide multiple references.
5955
</p>
6056
<p>The hours must:</p>
@@ -70,8 +66,7 @@
7066
</ul>
7167
</div>
7268
<div v-if="expired && expiredMoreThan5Years" class="d-flex flex-column ga-3 my-6">
73-
<p>You need to have completed 500 hours of work experience and be able to provide references to verify the hours.
74-
</p>
69+
<p>You need to have completed 500 hours of work experience and be able to provide references to verify the hours.</p>
7570
<p>Important information about calculating hours:</p>
7671
<ul class="ml-10">
7772
<li>Only include hours you worked once you began your early childhood education training program</li>

0 commit comments

Comments
 (0)