Skip to content

Commit eea464f

Browse files
authored
Merge pull request #1394 from bcgov/stories/ecer-5272
ECER-5272: ICRA Wizard Configuration
2 parents 6ccffaa + 9ba1278 commit eea464f

34 files changed

+2139
-82
lines changed

src/ECER.Clients.RegistryPortal/ECER.Clients.RegistryPortal.Server/ICRA/ICRAEligibilitiesEndpoints.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public void Register(IEndpointRouteBuilder endpointRouteBuilder)
1919

2020
if (request.Eligibility.Id != id) return TypedResults.BadRequest("resource id and payload id do not match");
2121
var userContext = ctx.User.GetUserContext();
22-
var eligibility = mapper.Map<Managers.Registry.Contract.ICRA.ICRAEligibility>(request.Eligibility, opts => opts.Items.Add("ApplicantId", userContext!.UserId))!;
22+
request.Eligibility.ApplicantId = userContext!.UserId;
23+
var eligibility = mapper.Map<Managers.Registry.Contract.ICRA.ICRAEligibility>(request.Eligibility)!;
2324

2425
if (id != null)
2526
{
@@ -71,6 +72,8 @@ public record ICRAEligibility()
7172
public string? Id { get; set; }
7273
public string ApplicantId { get; set; } = string.Empty;
7374
public string? PortalStage { get; set; }
75+
public DateTime? SignedDate { get; set; }
76+
public DateTime? CreatedOn { get; set; }
7477

7578
public ICRAStatus Status { get; set; }
7679
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { getClient } from "@/api/client";
2+
import type { Components, Paths } from "@/types/openapi";
3+
import ApiResultHandler, { type ApiResponse } from "@/utils/apiResultHandler";
4+
5+
const apiResultHandler = new ApiResultHandler();
6+
7+
const getIcraEligibilities = async (): Promise<ApiResponse<Components.Schemas.ICRAEligibility[] | null | undefined>> => {
8+
const client = await getClient();
9+
10+
return apiResultHandler.execute<Components.Schemas.ICRAEligibility[] | null | undefined>({
11+
request: client.icra_get({ id: "" }),
12+
key: "icra_get",
13+
});
14+
};
15+
16+
const createOrUpdateDraftIcraEligibility = async (
17+
icraEligibility: Components.Schemas.ICRAEligibility,
18+
): Promise<ApiResponse<Components.Schemas.DraftICRAEligibilityResponse | null | undefined>> => {
19+
const client = await getClient();
20+
const body: Paths.IcraPut.RequestBody = {
21+
eligibility: icraEligibility,
22+
};
23+
const pathParameters: Paths.IcraPut.PathParameters = {
24+
id: icraEligibility.id || "",
25+
};
26+
27+
return apiResultHandler.execute<Components.Schemas.DraftICRAEligibilityResponse | null | undefined>({
28+
request: client.icra_put(pathParameters, body),
29+
key: "icra_put",
30+
});
31+
};
32+
33+
export { createOrUpdateDraftIcraEligibility, getIcraEligibilities };

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,16 +370,23 @@ export default defineComponent({
370370
case "manageApplication":
371371
return [...this.baseItems, { title: "Application", disabled: true, href: `/manage-application/${params.applicationId}` }];
372372
373+
case "icra-eligibility":
374+
return [...this.baseItems, { title: "Apply with international certificate", disabled: true, href: "/icra-eligibility/check" }];
375+
373376
case "icra-eligibility-requirements":
374377
return [
375378
...this.baseItems,
376-
{ title: "Apply with international certificate", disabled: false, href: "/icra/eligibility" },
377-
{ title: "Requirements", disabled: true, href: "/icra/eligibility/requirements" },
379+
{ title: "Apply with international certificate", disabled: false, href: "/icra-eligibility/check" },
380+
{ title: "Requirements", disabled: true, href: "/icra-eligibility/requirements" },
378381
];
379382
380-
381-
case "icra-eligibility":
382-
return [...this.baseItems, { title: "Apply with international certificate", disabled: true, href: "/icra/eligibility" }];
383+
case "icra-eligibility-declaration":
384+
return [
385+
...this.baseItems,
386+
{ title: "Apply with international certificate", disabled: false, href: "/icra-eligibility/check" },
387+
{ title: "Requirements", disabled: false, href: "/icra-eligibility/requirements" },
388+
{ title: "Declaration", disabled: true, href: "/icra-eligibility/declaration" },
389+
];
383390
384391
default:
385392
return this.baseItems;

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
<script lang="ts">
4141
import { DateTime } from "luxon";
42-
import { defineComponent } from "vue";
42+
import { defineComponent, type PropType } from "vue";
4343
import type { VForm } from "vuetify/components";
4444
import { getProfile } from "@/api/profile";
4545
import Breadcrumb from "@/components/Breadcrumb.vue";
@@ -54,6 +54,9 @@ import { useUserStore } from "@/store/user";
5454
import { formatDate } from "@/utils/format";
5555
import * as Rules from "@/utils/formRules";
5656
import { useRouter } from "vue-router";
57+
import { useIcraStore } from "@/store/icra";
58+
59+
export type StreamType = "Eligibility" | "Application";
5760
5861
export default defineComponent({
5962
name: "Declaration",
@@ -65,6 +68,7 @@ export default defineComponent({
6568
const alertStore = useAlertStore();
6669
const loadingStore = useLoadingStore();
6770
const router = useRouter();
71+
const icraStore = useIcraStore();
6872
6973
// Refresh userProfile from the server
7074
const userProfile = await getProfile();
@@ -73,7 +77,14 @@ export default defineComponent({
7377
userStore.setUserProfile(userProfile);
7478
}
7579
76-
return { Rules, userStore, applicationStore, alertStore, loadingStore, configStore, router };
80+
return { Rules, userStore, applicationStore, alertStore, loadingStore, configStore, router, icraStore };
81+
},
82+
props: {
83+
stream: {
84+
type: String as PropType<StreamType>,
85+
required: false,
86+
default: "Application",
87+
},
7788
},
7889
data() {
7990
return {
@@ -98,6 +109,15 @@ export default defineComponent({
98109
return;
99110
}
100111
112+
if (this.stream === "Application") {
113+
await this.applicationPath();
114+
} else if (this.stream === "Eligibility") {
115+
await this.eligibilityPath();
116+
} else {
117+
console.warn("unknown stream type");
118+
}
119+
},
120+
async applicationPath() {
101121
this.applicationStore.$patch({ draftApplication: { signedDate: this.date } });
102122
103123
let response = await this.applicationStore.upsertDraftApplication();
@@ -106,6 +126,15 @@ export default defineComponent({
106126
this.router.push("/application");
107127
}
108128
},
129+
async eligibilityPath() {
130+
this.icraStore.$patch({ draftIcraEligibility: { signedDate: this.date, portalStage: "ContactInformation" } });
131+
132+
let response = await this.icraStore.upsertDraftIcraEligibility();
133+
134+
if (response) {
135+
this.router.push("/icra-eligibility");
136+
}
137+
},
109138
},
110139
});
111140
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<template>
2+
<v-card min-width="100%" variant="elevated" rounded="lg" class="custom-card-styling" elevation="4">
3+
<template #title>
4+
<v-card-title>
5+
<v-row>
6+
<v-col>
7+
<p class="font-weight-bold">{{ referenceFullName }}</p>
8+
</v-col>
9+
<v-spacer />
10+
</v-row>
11+
</v-card-title>
12+
</template>
13+
<template #append>
14+
<v-tooltip text="Edit reference" location="top">
15+
<template #activator="{ props }">
16+
<v-btn v-bind="props" icon="mdi-pencil" variant="plain" @click="editReference" :loading="loadingStore.isLoading('draftapplication_put')" />
17+
</template>
18+
</v-tooltip>
19+
<v-tooltip text="Delete reference" location="top">
20+
<template #activator="{ props }">
21+
<v-btn
22+
v-bind="props"
23+
icon="mdi-trash-can-outline"
24+
variant="plain"
25+
@click="deleteReference"
26+
:loading="loadingStore.isLoading('draftapplication_put')"
27+
/>
28+
</template>
29+
</v-tooltip>
30+
</template>
31+
</v-card>
32+
</template>
33+
34+
<script lang="ts">
35+
import { defineComponent } from "vue";
36+
import { useLoadingStore } from "@/store/loading";
37+
import { cleanPreferredName } from "@/utils/functions";
38+
import type { Components } from "@/types/openapi";
39+
40+
export default defineComponent({
41+
name: "WorkExperienceReferenceCard",
42+
setup() {
43+
const loadingStore = useLoadingStore();
44+
45+
return { loadingStore };
46+
},
47+
props: {
48+
reference: {
49+
type: Object as () => Components.Schemas.WorkExperienceReference,
50+
required: true,
51+
},
52+
},
53+
54+
emits: {
55+
edit: (_reference: Components.Schemas.WorkExperienceReference) => true,
56+
delete: (_reference: Components.Schemas.WorkExperienceReference) => true,
57+
},
58+
computed: {
59+
referenceFullName() {
60+
return cleanPreferredName(this.reference.firstName, this.reference.lastName);
61+
},
62+
},
63+
methods: {
64+
editReference() {
65+
// Emit an event or implement edit logic here
66+
this.$emit("edit", this.reference);
67+
},
68+
deleteReference() {
69+
// Emit an event or implement delete logic here
70+
this.$emit("delete", this.reference);
71+
},
72+
},
73+
});
74+
</script>
75+
76+
<style scoped lang="scss">
77+
.custom-card-styling {
78+
border: 1px solid #adb5bd;
79+
padding: 0.5rem;
80+
}
81+
</style>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<template>
2+
<v-card :rounded="!isRounded ? '0' : ''" flat color="primary">
3+
<v-card-item class="ma-4">
4+
<h2 class="text-white">{{ title }}</h2>
5+
<p class="small text-white mt-4">
6+
{{ subTitle }}
7+
</p>
8+
</v-card-item>
9+
10+
<div class="d-flex flex-row justify-start ga-3 flex-wrap ma-4">
11+
<!-- ICRA eligibility status Draft -->
12+
<v-card-actions v-if="icraStore.icraEligibilityStatus === 'Draft' || icraStore.icraEligibilityStatus === 'Active'">
13+
<v-btn size="large" variant="flat" color="warning" @click="router.push('/icra-eligibility')">
14+
<v-icon size="large" icon="mdi-arrow-right" />
15+
Open ICRA eligibility
16+
</v-btn>
17+
<!-- <v-btn class="ma-0" size="large" variant="outlined" color="white" @click="$emit('cancel-application')">Cancel application</v-btn> -->
18+
</v-card-actions>
19+
20+
<!-- ICRA Eligibility status Submitted, Ready, In Progress, Pending Queue -->
21+
<v-card-actions
22+
v-if="
23+
icraStore.icraEligibilityStatus === 'Submitted' ||
24+
icraStore.icraEligibilityStatus === 'ReadyforReview' ||
25+
icraStore.icraEligibilityStatus === 'InReview'
26+
"
27+
>
28+
<v-btn variant="flat" size="large" color="warning" @click="handleManageIcraEligibility">
29+
<v-icon size="large" icon="mdi-arrow-right" />
30+
Manage ICRA eligibility
31+
</v-btn>
32+
</v-card-actions>
33+
</div>
34+
</v-card>
35+
</template>
36+
37+
<script lang="ts">
38+
import { defineComponent } from "vue";
39+
40+
import { useIcraStore } from "@/store/icra";
41+
import { useRouter } from "vue-router";
42+
43+
export default defineComponent({
44+
name: "IcraEligibilityCard",
45+
props: {
46+
isRounded: {
47+
type: Boolean,
48+
default: true,
49+
},
50+
},
51+
// emits: ["cancel-application"],
52+
setup() {
53+
const icraStore = useIcraStore();
54+
const router = useRouter();
55+
56+
return {
57+
icraStore,
58+
router,
59+
};
60+
},
61+
computed: {
62+
title(): string {
63+
switch (this.icraStore.icraEligibilityStatus) {
64+
case "Draft":
65+
case "Submitted":
66+
case "InReview":
67+
case "ReadyforReview":
68+
case "Active":
69+
return "ICRA Eligibility in progress";
70+
default:
71+
return "Apply with international certification";
72+
}
73+
},
74+
subTitle(): string {
75+
switch (this.icraStore.icraEligibilityStatus) {
76+
case "Draft":
77+
case "Active":
78+
return "Your ICRA eligibility application is in progress.";
79+
case "Submitted":
80+
case "InReview":
81+
case "ReadyforReview":
82+
return "Your ICRA eligibility application has been submitted and is being reviewed.";
83+
default:
84+
return "Apply for ECE Five Year Certification if you are internationally certified in a country that regulates the ECE profession and do not have 500 hours work experience supervised by a Canadian-certified ECE.";
85+
}
86+
},
87+
},
88+
methods: {
89+
handleManageIcraEligibility() {
90+
this.router.push({ name: "manage-icra-eligibility", params: { icraEligibilityId: this.icraStore?.icraEligibility?.id } });
91+
},
92+
},
93+
});
94+
</script>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
</v-row>
4848
<v-row>
4949
<v-col>
50-
<v-btn class="mt-6" rounded="lg" color="primary" @click="router.push({ name: 'not-found' })" id="btnContinue">Continue (not implemented)</v-btn>
50+
<v-btn class="mt-6" rounded="lg" color="primary" @click="router.push({ name: 'icra-eligibility-declaration' })" id="btnContinue">Continue</v-btn>
5151
</v-col>
5252
</v-row>
5353
</v-container>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template></template>
2+
3+
<script lang="ts">
4+
import { defineComponent } from "vue";
5+
6+
export default defineComponent({
7+
name: "IcraEligibilitySummary",
8+
});
9+
</script>

0 commit comments

Comments
 (0)