From b6ddd741d30aeba60cbc963fda4d5ea36509db4e Mon Sep 17 00:00:00 2001 From: Jia Xu Date: Mon, 20 Jan 2025 09:09:47 -0800 Subject: [PATCH] 24918 - Products and Payments UX (#3208) --- .../account-info/AccountAccessType.vue | 9 +-- .../account-info/AccountInfo.vue | 6 +- .../account-info/AccountMailingAddress.vue | 11 +++- .../payment/AccountPaymentMethods.vue | 46 +++++++++++++- .../product/ProductPayment.vue | 7 ++- .../components/auth/common/PaymentMethods.vue | 4 +- .../src/components/auth/common/Product.vue | 62 ++++++++++++++----- .../create-account/SelectProductPayment.vue | 2 +- .../auth/create-account/UserProfileForm.vue | 9 ++- auth-web/src/locales/en.json | 9 ++- auth-web/src/views/auth/AccountSettings.vue | 7 ++- 11 files changed, 136 insertions(+), 36 deletions(-) diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountAccessType.vue b/auth-web/src/components/auth/account-settings/account-info/AccountAccessType.vue index d8f4a2da84..154da09715 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountAccessType.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountAccessType.vue @@ -34,7 +34,7 @@ {{ getAccessTypeText }}
GOVN and GOVN -> PREMIUM - isChangeButtonEnabled: computed(() => { - // Check access type and orgtype must be premium + isAccessTypeChangeButtonEnabled: computed(() => { const accessType: any = props.organization.accessType - const isAllowedAccessType = props.organization.orgType === Account.PREMIUM && - [AccessType.REGULAR, AccessType.EXTRA_PROVINCIAL, AccessType.REGULAR_BCEID, AccessType.GOVN].includes(accessType) + const isAllowedAccessType = [AccessType.REGULAR, AccessType.EXTRA_PROVINCIAL, AccessType.REGULAR_BCEID, AccessType.GOVN].includes(accessType) return isAllowedAccessType && props.canChangeAccessType // canChangeAccessType is the role based access passed as a property }), getAccessTypeText: computed(() => { diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue index b23e57126a..8395eb6508 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountInfo.vue @@ -350,8 +350,10 @@ export default defineComponent({ userStore.currentUser.roles.includes(Role.StaffSuspendAccounts) )), isDeactivateButtonVisible: computed(() => currentOrganization.value?.statusCode !== AccountStatus.INACTIVE), - canChangeAccessType: computed(() => userStore.currentUser.roles.includes(Role.StaffManageAccounts)) && - !userStore.currentUser.roles.includes(Role.ContactCentreStaff), + canChangeAccessType: computed(() => ( + userStore.currentUser.roles.includes(Role.StaffManageAccounts) && + !userStore.currentUser.roles.includes(Role.ContactCentreStaff) + )), isAdminContactViewable: computed(() => [Permission.VIEW_ADMIN_CONTACT].some(per => permissions.value.includes(per))), isAccountStatusActive: computed(() => currentOrganization.value.statusCode === AccountStatus.ACTIVE), accountType: computed(() => { diff --git a/auth-web/src/components/auth/account-settings/account-info/AccountMailingAddress.vue b/auth-web/src/components/auth/account-settings/account-info/AccountMailingAddress.vue index 1f53db3512..bf3e2dd342 100644 --- a/auth-web/src/components/auth/account-settings/account-info/AccountMailingAddress.vue +++ b/auth-web/src/components/auth/account-settings/account-info/AccountMailingAddress.vue @@ -27,7 +27,7 @@ />
import { defineComponent, ref } from '@vue/composition-api' import BaseAddressForm from '@/components/auth/common/BaseAddressForm.vue' +import { MembershipType } from '@/models/Organization' import { addressSchema } from '@/schemas' +import { useOrgStore } from '@/stores' export default defineComponent({ name: 'AccountMailingAddress', @@ -100,6 +102,9 @@ export default defineComponent({ }, emit: ['valid', 'update:address'], setup (props, { emit }) { + const { + currentMembership + } = useOrgStore() const baseAddressSchema = ref(addressSchema) const mailingAddress = ref(null) @@ -122,7 +127,9 @@ export default defineComponent({ mailingAddress, updateAddress, checkBaseAddressValidity, - triggerValidate + triggerValidate, + currentMembership, + MembershipType } } }) diff --git a/auth-web/src/components/auth/account-settings/payment/AccountPaymentMethods.vue b/auth-web/src/components/auth/account-settings/payment/AccountPaymentMethods.vue index f15d90bbe9..736413d566 100644 --- a/auth-web/src/components/auth/account-settings/payment/AccountPaymentMethods.vue +++ b/auth-web/src/components/auth/account-settings/payment/AccountPaymentMethods.vue @@ -79,6 +79,32 @@ + + +
@@ -141,6 +167,7 @@ export default defineComponent({ }) const errorDialog = ref>() + const unsavedChangesDialog = ref>() const { currentOrganization, currentOrgPaymentType, currentOrgAddress, currentMembership, permissions, currentOrgGLInfo } = useAccount() @@ -265,10 +292,24 @@ export default defineComponent({ } async function cancel () { + if (state.paymentMethodChanged) { + unsavedChangesDialog.value.open() + } else { + await initialize() + emit('disable-editing') + } + } + + async function exitWithoutSaving () { + unsavedChangesDialog.value.close() await initialize() emit('disable-editing') } + function closeUnsavedChangesDialog() { + unsavedChangesDialog.value.close() + } + async function getCreateRequestBody () { let isValid = false let createRequestBody: CreateRequestBody @@ -415,7 +456,10 @@ export default defineComponent({ currentOrgAddress, permissions, currentUser, - setBcolInfo + setBcolInfo, + unsavedChangesDialog, + exitWithoutSaving, + closeUnsavedChangesDialog } } }) diff --git a/auth-web/src/components/auth/account-settings/product/ProductPayment.vue b/auth-web/src/components/auth/account-settings/product/ProductPayment.vue index e856e6ea0b..467fcc9007 100644 --- a/auth-web/src/components/auth/account-settings/product/ProductPayment.vue +++ b/auth-web/src/components/auth/account-settings/product/ProductPayment.vue @@ -159,6 +159,7 @@ import { TaskType } from '@/util/constants' import { + MembershipType, OrgProduct, OrgProductCode, OrgProductsRequestBody @@ -202,7 +203,8 @@ export default defineComponent({ updateAccountFees, needStaffReview, removeOrgProduct, - currentOrganization + currentOrganization, + currentMembership } = useOrgStore() const { @@ -240,6 +242,9 @@ export default defineComponent({ // check for role and account can have service fee (GOVM and GOVN account) return currentUser?.roles?.includes(Role.StaffManageAccounts) && state.isVariableFeeAccount }), + canChangePayment: computed((): boolean => { + return currentMembership.membershipTypeCode !== MembershipType.Coordinator + }), /** * Return any sub-product that has a status indicating activity * Prioritize Active/Pending for edge-cases when multiple sub product statuses exist diff --git a/auth-web/src/components/auth/common/PaymentMethods.vue b/auth-web/src/components/auth/common/PaymentMethods.vue index 10386af3c3..644b6374ca 100644 --- a/auth-web/src/components/auth/common/PaymentMethods.vue +++ b/auth-web/src/components/auth/common/PaymentMethods.vue @@ -26,7 +26,7 @@ /> {{ payment.icon }} @@ -167,7 +167,7 @@

{{ bcOnlineWarningMessage }}

diff --git a/auth-web/src/components/auth/common/Product.vue b/auth-web/src/components/auth/common/Product.vue index e0095b387e..348ee6cb78 100644 --- a/auth-web/src/components/auth/common/Product.vue +++ b/auth-web/src/components/auth/common/Product.vue @@ -9,7 +9,7 @@ :data-test="`div-product-${productDetails.code}`" >
-
+
@@ -83,6 +84,7 @@

@@ -91,7 +93,7 @@ depressed color="primary" width="120" - class="font-weight-bold ml-auto" + class="font-weight-bold ml-auto mt-6" :aria-label="`Select ${productDetails.description}`" :data-test="`btn-productDetails-${productDetails.code}`" text @@ -113,7 +115,7 @@ >mdi-chevron-down
-
+
@@ -125,8 +127,24 @@

+

+ + Visit Information Page + + +

+

-
- -

+

+ +

Supported payment methods:

- {{ paymentTypeIcon[method] }}{{ paymentTypeLabel[method] }} + + {{ paymentTypeIcon[method] }} + {{ paymentTypeLabel[method] }}
@@ -282,6 +305,7 @@ export default defineComponent({ let { code } = props.productDetails let subTitle = `${code?.toLowerCase()}CodeSubtitle` let details = `${code?.toLowerCase()}CodeDescription` + let link = `${code?.toLowerCase()}CodeDescriptionLink` let note = `${code?.toLowerCase()}CodeNote` let decisionMadeIcon = null let decisionMadeColorCode = null @@ -317,7 +341,7 @@ export default defineComponent({ note = '' } } - return { subTitle, details, decisionMadeIcon, decisionMadeColorCode, note } + return { subTitle, details, link, decisionMadeIcon, decisionMadeColorCode, note } }), showPaymentMethodNotSupported: false }) @@ -450,7 +474,17 @@ export default defineComponent({ } .theme--light.v-card.v-card--outlined.selected { - border-color: var(--v-primary-base); + top: 0; +} + +.product-card-contents { + color: $gray7; +} + +.product-payment-icons.v-chip.v-size--x-small.theme--light.v-chip:not(.v-chip--active){ + background-color: $app-lt-blue ; + font-size: 12px; + color: #212529; } .label-color { diff --git a/auth-web/src/components/auth/create-account/SelectProductPayment.vue b/auth-web/src/components/auth/create-account/SelectProductPayment.vue index 040d923e8b..eacd003266 100644 --- a/auth-web/src/components/auth/create-account/SelectProductPayment.vue +++ b/auth-web/src/components/auth/create-account/SelectProductPayment.vue @@ -37,7 +37,7 @@
- Select a default payment method for your account: + Select a payment method for your account:

Enter your contact information. Once your account is created, you may add additional users and assign roles.

This will be reviewed by Registries staff and the account will be approved when authenticated. @@ -77,7 +77,7 @@

This is your legal name as it appears on your BC Services Card.
@@ -649,4 +649,7 @@ export default class UserProfileForm extends Mixins(NextPageMixin, Steppable) { font-weight: 700; letter-spacing: -0.02rem; } +.profile-subtitle { + color: $gray7; +} diff --git a/auth-web/src/locales/en.json b/auth-web/src/locales/en.json index 4aae9b6ee7..48b3ffb181 100644 --- a/auth-web/src/locales/en.json +++ b/auth-web/src/locales/en.json @@ -150,15 +150,18 @@ "esraCodeSubtitle": "Identify properties with environmental records submitted under Part 4 of B.C.'s Environmental Management Act.", "rptCodeDescription": "

  • Search a property's tax amounts over the last 10 years
  • Search a property's tax-paid status
  • Search a property's legal description

", "csoCodeDescription": "
  • View Provincial and Supreme civil court files; view and print electronic documents (if available); purchase documents; file summary reports using eSearch
  • Access daily court lists for Provincial Court small claims matters and Supreme Court Chambers
  • Electronically file civil court documents using eFiling
", - "businessCodeDescription": "
  • Request a name for your business
  • File annual reports
  • View and change your current directors or address
  • See the history of your business' fillings

Visit Information Page ", - "business_searchCodeDescription": "
  • View details about businesses and their filing history,
  • Download the Business Summary for businesses, including current status, registered addresses, directors, etc.
  • Download business filings, such as Annual Reports and more
  • Download other business documents including the Certificate of Good Standing, the Certificate of Status, and the Letter Under Seal.

Visit Information Page ", + "businessCodeDescription": "
  • Request a name for your business
  • File annual reports
  • View and change your current directors or address
  • See the history of your business' fillings

", + "businessCodeDescriptionLink": "https://account.bcregistry.gov.bc.ca/decide-business", + "business_searchCodeDescription": "
  • View details about businesses and their filing history,
  • Download the Business Summary for businesses, including current status, registered addresses, directors, etc.
  • Download business filings, such as Annual Reports and more
  • Download other business documents including the Certificate of Good Standing, the Certificate of Status, and the Letter Under Seal.

", + "business_searchCodeDescriptionLink": "https://www.bcregistry.gov.bc.ca/", "mhrStaffCodeDescription": "

Searches may be based on several different criteria. If more than one home meets the criteria submitted, then a list of matches is displayed.
You may include a Personal Property Registry search (combined search) at an additional cost.

", "mhrCodeDescription": "

  • Complete a search for manufactured homes in B.C.
  • Complete a combined search for personal property liens on a home
  • Search by owner name, organization, registration or serial number
  • Download your search result

", "pprCodeDescription": "

  • Complete a search for personal property liens
  • Register, amend, renew or discharge a registration

", "mhr_qslnCodeDescription": "

Qualified Supplier – Lawyers and Notaries

  • Searches for manufactured homes and for liens on a home
  • Transport permits
  • Transfer transactions
  • Residential exemptions

", "mhr_qshmCodeDescription": "

Qualified Supplier – Home Manufacturers

  • Searches for manufactured homes and for liens on a home
  • Transport permits
  • Transfer transactions (related to homes manufacturers currently own)
  • Registrations

", "mhr_qshdCodeDescription": "

Qualified Supplier – Home Dealers

  • Searches for manufactured homes and for liens on a home
  • Transport permits
  • Transfer due to Sale or Gift

", - "vsCodeDescription": "

The search and registration products are intended for the exclusive use of solicitors and notaries only. To add this product, accept the Terms of Service. Review the terms and check the box below if you confirm. BC Registry staff will review your information and grant access to Wills Registry in 3-4 days if approved.

Visit Information Page

", + "vsCodeDescription": "

The search and registration products are intended for the exclusive use of solicitors and notaries only. To add this product, accept the Terms of Service. Review the terms and check the box below if you confirm. BC Registry staff will review your information and grant access to Wills Registry in 3-4 days if approved.

", + "vsCodeDescriptionLink": "https://www2.gov.bc.ca/gov/content/life-events/death/wills-registry", "strrCodeDescription": "

  • Register a short-term rental property
  • Register a platform service provider
  • Register a strata-titled hotel or motel
  • Manage and renew registrations

", "bcaCodeDescription": "Three reports are available for purchase:
  • Owner Location Report
  • Assessment Roll Report
  • Assessment Inventory Report
", "esraCodeDescription": "Search by the following:
  • Parcel ID (PID)
  • Crown Lands PIN
  • Crown Lands File Number
  • Site ID
  • Address
  • Area
", diff --git a/auth-web/src/views/auth/AccountSettings.vue b/auth-web/src/views/auth/AccountSettings.vue index fd0e28a6c2..7025d67353 100644 --- a/auth-web/src/views/auth/AccountSettings.vue +++ b/auth-web/src/views/auth/AccountSettings.vue @@ -192,6 +192,7 @@ Authentication import { AccountStatus, LoginSource, Pages, Permission, Role } from '@/util/constants' import { Component, Mixins, Prop } from 'vue-property-decorator' -import { Member, Organization } from '@/models/Organization' +import { Member, MembershipType, Organization } from '@/models/Organization' import { mapActions, mapState } from 'pinia' import AccountInactiveAlert from '@/components/auth/common/AccountInactiveAlert.vue' import AccountMixin from '@/components/auth/mixins/AccountMixin.vue' @@ -392,6 +393,10 @@ export default class AccountSettings extends Mixins(AccountMixin) { return this.currentUser.roles.includes(Role.Staff) || this.currentUser.roles.includes(Role.ContactCentreStaff) } + private get isUserMembership ():boolean { + return this.currentMembership.membershipTypeCode !== MembershipType.User + } + private get accountInfoUrl (): string { return `/account/${this.orgId}/settings/account-info` }