From e79ce50d57eed8ecbcae836431be50f17ffa7b76 Mon Sep 17 00:00:00 2001 From: Mateusz Kolasa Date: Fri, 28 Mar 2025 16:00:13 +0100 Subject: [PATCH] Add review page handling for B2B OPF Checkout --- integration-libs/opf/_index.scss | 7 +- .../assets/translations/en/opfCheckout.json | 3 +- .../opf/checkout/components/b2b/index.ts | 1 + .../b2b/opf-b2b-checkout-components.module.ts | 3 +- ...2b-checkout-payment-type.component.spec.ts | 7 + .../opf-b2b-checkout-payment-type.module.ts | 4 +- .../opf-b2b-checkout-payment-type.spec.ts | 1 - .../b2b/opf-b2b-checkout-review/index.ts | 8 + .../opf-b2b-checkout-review.component.html | 114 ++++++++++++ .../opf-b2b-checkout-review.component.spec.ts | 7 + .../opf-b2b-checkout-review.component.ts | 155 ++++++++++++++++ .../opf-b2b-checkout-review.module.ts | 47 +++++ .../opf/checkout/opf-checkout.module.ts | 2 +- .../config/default-opf-checkout-b2b-config.ts | 8 +- .../config/default-opf-checkout-config.ts | 3 +- .../default-opf-checkout-routing-config.ts | 3 + .../checkout/root/opf-checkout-root.module.ts | 1 + .../opf/checkout/styles/_opf-checkout.scss | 4 +- .../checkout/styles/components/_index.scss | 1 + .../_opf-checkout-payment-and-review.scss | 48 +---- .../components/_opf-checkout-review-card.scss | 43 +++++ .../styles/components/b2b/_index.scss | 1 + .../b2b/_opf-b2b-checkout-review.scss | 166 ++++++++++++++++++ 23 files changed, 574 insertions(+), 63 deletions(-) create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.component.spec.ts delete mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.spec.ts create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/index.ts create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.spec.ts create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.ts create mode 100644 integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.module.ts create mode 100644 integration-libs/opf/checkout/styles/components/_opf-checkout-review-card.scss create mode 100644 integration-libs/opf/checkout/styles/components/b2b/_opf-b2b-checkout-review.scss diff --git a/integration-libs/opf/_index.scss b/integration-libs/opf/_index.scss index 94baea1ae5a..7c6534acbb7 100644 --- a/integration-libs/opf/_index.scss +++ b/integration-libs/opf/_index.scss @@ -10,9 +10,10 @@ $opf-components-allowlist: cx-opf-payment-method-details, cx-opf-checkout-payment-and-review, cx-opf-checkout-payments, cx-opf-checkout-billing-address-form, cx-opf-checkout-payment-wrapper, - cx-opf-checkout-terms-and-conditions-alert, cx-opf-error-modal, - cx-opf-cta-element, cx-opf-google-pay, cx-opf-apple-pay, - cx-opf-quick-buy-buttons, cx-opf-b2b-checkout-payment-type !default; + cx-opf-checkout-review-card, cx-opf-checkout-terms-and-conditions-alert, + cx-opf-error-modal, cx-opf-cta-element, cx-opf-google-pay, cx-opf-apple-pay, + cx-opf-quick-buy-buttons, cx-opf-b2b-checkout-payment-type, + cx-opf-b2b-checkout-review !default; $skipComponentStyles: () !default; diff --git a/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json b/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json index e57b2393b38..7e9ed7e6efa 100644 --- a/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json +++ b/integration-libs/opf/checkout/assets/translations/en/opfCheckout.json @@ -4,7 +4,8 @@ "paymentType": "Method of payment", "shipping": "Shipping", "deliveryMethod": "Delivery Method", - "paymentAndReview": "Payment & Review" + "paymentAndReview": "Payment & Review", + "review": "Review Order" }, "paymentAndReviewTitle": "Payment and review", "billingAddress": "Billing Address", diff --git a/integration-libs/opf/checkout/components/b2b/index.ts b/integration-libs/opf/checkout/components/b2b/index.ts index 6b914ac6536..fe3c1fb0aa2 100644 --- a/integration-libs/opf/checkout/components/b2b/index.ts +++ b/integration-libs/opf/checkout/components/b2b/index.ts @@ -6,3 +6,4 @@ export * from './opf-b2b-checkout-components.module'; export * from './opf-b2b-checkout-payment-type/index'; +export * from './opf-b2b-checkout-review/index'; diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-components.module.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-components.module.ts index 06a09b5c345..55b29dadddd 100644 --- a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-components.module.ts +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-components.module.ts @@ -7,8 +7,9 @@ import { NgModule } from '@angular/core'; import { OpfB2bCheckoutPaymentTypeModule } from './opf-b2b-checkout-payment-type'; +import { OpfB2bCheckoutReviewModule } from './opf-b2b-checkout-review'; @NgModule({ - imports: [OpfB2bCheckoutPaymentTypeModule], + imports: [OpfB2bCheckoutPaymentTypeModule, OpfB2bCheckoutReviewModule], }) export class OpfB2bCheckoutComponentsModule {} diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.component.spec.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.component.spec.ts new file mode 100644 index 00000000000..c97ad81918b --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.component.spec.ts @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// TODO: Add unit tests diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.module.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.module.ts index 2dca6d82c7c..2f20c936fb5 100644 --- a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.module.ts +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.module.ts @@ -26,6 +26,8 @@ import { OpfB2bCheckoutPaymentTypeComponent } from './opf-b2b-checkout-payment-t CommonModule, I18nModule, SpinnerModule, + FeaturesConfigModule, + OpfCheckoutPaymentsModule, ConfigModule.withConfig({ cmsComponents: { OpfCheckoutPaymentType: { @@ -34,8 +36,6 @@ import { OpfB2bCheckoutPaymentTypeComponent } from './opf-b2b-checkout-payment-t }, }, }), - FeaturesConfigModule, - OpfCheckoutPaymentsModule, ], declarations: [OpfB2bCheckoutPaymentTypeComponent], exports: [OpfB2bCheckoutPaymentTypeComponent], diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.spec.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.spec.ts deleted file mode 100644 index a802fe01212..00000000000 --- a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-payment-type/opf-b2b-checkout-payment-type.spec.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO: Add unit tests... diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/index.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/index.ts new file mode 100644 index 00000000000..7a10d4441f3 --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/index.ts @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +export * from './opf-b2b-checkout-review.component'; +export * from './opf-b2b-checkout-review.module'; diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html new file mode 100644 index 00000000000..7d5227d4ee5 --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.html @@ -0,0 +1,114 @@ + +
+ + + + +
+ +
+

{{ 'opfCheckout.termsAndConditions' | cxTranslate }}

+ + + +
+
+ +
+
+
+ + + + + + + + + + + + +
diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.spec.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.spec.ts new file mode 100644 index 00000000000..c97ad81918b --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.spec.ts @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// TODO: Add unit tests diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.ts new file mode 100644 index 00000000000..228b5cac130 --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.component.ts @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ChangeDetectionStrategy, + Component, + inject, + OnInit, +} from '@angular/core'; +import { + UntypedFormBuilder, + UntypedFormGroup, + Validators, +} from '@angular/forms'; +import { Cart, PaymentType } from '@spartacus/cart/base/root'; +import { CheckoutPaymentTypeFacade } from '@spartacus/checkout/b2b/root'; +import { CheckoutReviewSubmitComponent } from '@spartacus/checkout/base/components'; +import { CmsService, Page } from '@spartacus/core'; +import { + OpfBaseFacade, + OpfMetadataStoreService, +} from '@spartacus/opf/base/root'; +import { OPF_EXPLICIT_TERMS_AND_CONDITIONS_COMPONENT } from '@spartacus/opf/checkout/root'; +import { + Observable, + take, + map, + filter, + combineLatest, + BehaviorSubject, +} from 'rxjs'; +import { Card } from '@spartacus/storefront'; + +@Component({ + selector: 'cx-opf-b2b-checkout-review', + templateUrl: './opf-b2b-checkout-review.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + standalone: false, +}) +export class OpfB2bCheckoutReviewComponent + extends CheckoutReviewSubmitComponent + implements OnInit +{ + protected fb = inject(UntypedFormBuilder); + protected opfMetadataStoreService = inject(OpfMetadataStoreService); + protected cmsService = inject(CmsService); + protected checkoutPaymentTypeFacade = inject(CheckoutPaymentTypeFacade); + protected opfBaseFacade = inject(OpfBaseFacade); + + protected defaultTermsAndConditionsFieldValue = false; + + protected selectedPaymentProviderName$ = new BehaviorSubject< + string | undefined + >(undefined); + + explicitTermsAndConditions$: Observable = this.cmsService + .getCurrentPage() + .pipe( + map((page: Page) => { + return this.isCmsComponentInPage( + OPF_EXPLICIT_TERMS_AND_CONDITIONS_COMPONENT, + page + ); + }) + ); + + checkoutSubmitForm: UntypedFormGroup = this.fb.group({ + termsAndConditions: [ + this.defaultTermsAndConditionsFieldValue, + Validators.requiredTrue, + ], + }); + + get termsAndConditionInvalid(): boolean { + return this.checkoutSubmitForm.invalid; + } + + get termsAndConditionsFieldValue(): boolean { + return Boolean(this.checkoutSubmitForm.get('termsAndConditions')?.value); + } + + get paymentType$(): Observable { + return this.activeCartFacade + .getActive() + .pipe(map((cart: Cart) => cart.paymentType)); + } + + get poNumber$(): Observable { + return this.checkoutPaymentTypeFacade.getPurchaseOrderNumberState().pipe( + filter((state) => !state.loading && !state.error), + map((state) => state.data) + ); + } + + getPoNumberCard(poNumber?: string | null): Observable { + return combineLatest([ + this.translationService.translate('opfCheckout.poNumber'), + this.translationService.translate('opfCheckout.noPoNumber'), + ]).pipe( + map(([textTitle, noneTextTitle]) => { + return { + title: textTitle, + textBold: poNumber ? poNumber : noneTextTitle, + }; + }) + ); + } + + getSelectedPayment$ = this.opfBaseFacade.getActiveConfigurationsState(); + + getSelectedPaymentId$ = this.opfMetadataStoreService + .getOpfMetadataState() + .pipe( + take(1), + map((data) => data?.selectedPaymentOptionId) + ); + + getPaymentMethodNameCard(methodName?: string): Observable { + return combineLatest([ + this.translationService.translate('opfCheckout.paymentMethod'), + this.translationService.translate('opfCheckout.noPaymentMethod'), + ]).pipe( + map(([title, noPaymentMethod]) => ({ + title, + textBold: methodName ?? noPaymentMethod, + text: [], + })) + ); + } + + protected isCmsComponentInPage(cmsComponentUid: string, page: Page): boolean { + return !!page && JSON.stringify(page).includes(cmsComponentUid); + } + + protected updateTermsAndConditionsState() { + this.opfMetadataStoreService.updateOpfMetadata({ + termsAndConditionsChecked: this.termsAndConditionsFieldValue, + }); + } + + toggleTermsAndConditions() { + this.updateTermsAndConditionsState(); + } + + onPaymentProviderSelected(providerName: string) { + this.selectedPaymentProviderName$.next(providerName); + } + + ngOnInit() { + this.updateTermsAndConditionsState(); + } +} diff --git a/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.module.ts b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.module.ts new file mode 100644 index 00000000000..ce1fd9fe3d7 --- /dev/null +++ b/integration-libs/opf/checkout/components/b2b/opf-b2b-checkout-review/opf-b2b-checkout-review.module.ts @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2025 SAP Spartacus team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { + CmsConfig, + ConfigModule, + I18nModule, + UrlModule, +} from '@spartacus/core'; +import { OpfB2bCheckoutReviewComponent } from './opf-b2b-checkout-review.component'; +import { OpfCheckoutReviewCardModule } from '../../opf-checkout-review-card/opf-checkout-review-card.module'; +import { OpfCheckoutTermsAndConditionsAlertModule } from '../../opf-checkout-terms-and-conditions-alert/opf-checkout-terms-and-conditions-alert.module'; +import { OpfCheckoutBillingAddressFormModule } from '../../opf-checkout-billing-address-form/opf-checkout-billing-address-form.module'; +import { OpfCheckoutPaymentsModule } from '../../opf-checkout-payments/opf-checkout-payments.module'; +import { OpfCheckoutReviewCartDetailsModule } from '../../opf-checkout-review-cart-details/opf-checkout-review-cart-details.module'; + +@NgModule({ + imports: [ + CommonModule, + ReactiveFormsModule, + RouterModule, + I18nModule, + UrlModule, + OpfCheckoutReviewCardModule, + OpfCheckoutTermsAndConditionsAlertModule, + OpfCheckoutBillingAddressFormModule, + OpfCheckoutPaymentsModule, + OpfCheckoutReviewCartDetailsModule, + ConfigModule.withConfig({ + cmsComponents: { + OpfCheckoutReview: { + component: OpfB2bCheckoutReviewComponent, + }, + }, + }), + ], + declarations: [OpfB2bCheckoutReviewComponent], + exports: [OpfB2bCheckoutReviewComponent], +}) +export class OpfB2bCheckoutReviewModule {} diff --git a/integration-libs/opf/checkout/opf-checkout.module.ts b/integration-libs/opf/checkout/opf-checkout.module.ts index 8e85b6f7833..20e15bd2e44 100644 --- a/integration-libs/opf/checkout/opf-checkout.module.ts +++ b/integration-libs/opf/checkout/opf-checkout.module.ts @@ -6,8 +6,8 @@ import { NgModule } from '@angular/core'; import { - OpfB2bCheckoutComponentsModule, OpfCheckoutComponentsModule, + OpfB2bCheckoutComponentsModule, } from '@spartacus/opf/checkout/components'; @NgModule({ diff --git a/integration-libs/opf/checkout/root/config/default-opf-checkout-b2b-config.ts b/integration-libs/opf/checkout/root/config/default-opf-checkout-b2b-config.ts index 5d1141d8462..1bc24a57fc4 100644 --- a/integration-libs/opf/checkout/root/config/default-opf-checkout-b2b-config.ts +++ b/integration-libs/opf/checkout/root/config/default-opf-checkout-b2b-config.ts @@ -30,15 +30,15 @@ const opfB2bCheckoutSteps = [ type: [CheckoutStepType.DELIVERY_MODE], }, { - id: 'opfReviewOrder', + id: 'opfPaymentAndReview', name: 'opfCheckout.tabs.paymentAndReview', routeName: 'opfCheckoutPaymentAndReview', type: [CheckoutStepType.PAYMENT_DETAILS], }, { - id: 'reviewOrder', - name: 'checkoutProgress.reviewOrder', - routeName: 'checkoutReviewOrder', + id: 'opfReview', + name: 'opfCheckout.tabs.review', + routeName: 'opfCheckoutReview', type: [CheckoutStepType.REVIEW_ORDER], }, ]; diff --git a/integration-libs/opf/checkout/root/config/default-opf-checkout-config.ts b/integration-libs/opf/checkout/root/config/default-opf-checkout-config.ts index 27c0b6fa4b9..daa5717792c 100644 --- a/integration-libs/opf/checkout/root/config/default-opf-checkout-config.ts +++ b/integration-libs/opf/checkout/root/config/default-opf-checkout-config.ts @@ -25,10 +25,9 @@ const opfCheckoutSteps = [ nameMultiLine: false, }, { - id: 'opfReviewOrder', + id: 'opfPaymentAndReview', name: 'opfCheckout.tabs.paymentAndReview', routeName: 'opfCheckoutPaymentAndReview', - // TODO OPF: provide proper step type (PAYMENT_REVIEW) once augmenting problem is solved type: [CheckoutStepType.PAYMENT_TYPE], nameMultiLine: false, }, diff --git a/integration-libs/opf/checkout/root/config/default-opf-checkout-routing-config.ts b/integration-libs/opf/checkout/root/config/default-opf-checkout-routing-config.ts index b04aafabc29..a9195835786 100644 --- a/integration-libs/opf/checkout/root/config/default-opf-checkout-routing-config.ts +++ b/integration-libs/opf/checkout/root/config/default-opf-checkout-routing-config.ts @@ -15,6 +15,9 @@ export const defaultOpfCheckoutRoutingConfig: RoutingConfig = { opfCheckoutPaymentAndReview: { paths: ['checkout/opf-payment-and-review'], }, + opfCheckoutReview: { + paths: ['checkout/opf-review'], + }, }, }, }; diff --git a/integration-libs/opf/checkout/root/opf-checkout-root.module.ts b/integration-libs/opf/checkout/root/opf-checkout-root.module.ts index 1d6554e35c8..328d1ce66f3 100644 --- a/integration-libs/opf/checkout/root/opf-checkout-root.module.ts +++ b/integration-libs/opf/checkout/root/opf-checkout-root.module.ts @@ -17,6 +17,7 @@ import { OPF_CHECKOUT_FEATURE } from './feature-name'; export const CHECKOUT_OPF_CMS_COMPONENTS: string[] = [ 'OpfCheckoutPaymentType', 'OpfCheckoutPaymentAndReview', + 'OpfCheckoutReview', ]; export function defaultOpfCheckoutComponentsConfig() { diff --git a/integration-libs/opf/checkout/styles/_opf-checkout.scss b/integration-libs/opf/checkout/styles/_opf-checkout.scss index b11c7b91fb5..5be633a7a10 100644 --- a/integration-libs/opf/checkout/styles/_opf-checkout.scss +++ b/integration-libs/opf/checkout/styles/_opf-checkout.scss @@ -3,6 +3,7 @@ @import './components/opf-checkout-payment-wrapper'; @import './components/opf-checkout-payments'; @import './components/opf-checkout-terms-and-conditions-alert'; +@import './components/opf-checkout-review-card'; @import './components/b2b/index'; $opf-checkout-components: ( @@ -10,7 +11,8 @@ $opf-checkout-components: ( cx-opf-checkout-billing-address-form, cx-opf-checkout-payment-wrapper, cx-opf-checkout-payments, - cx-opf-checkout-terms-and-conditions-alert + cx-opf-checkout-terms-and-conditions-alert, + cx-opf-checkout-review-card ) !default; // components diff --git a/integration-libs/opf/checkout/styles/components/_index.scss b/integration-libs/opf/checkout/styles/components/_index.scss index 8d70c2ad6d6..164272319d2 100644 --- a/integration-libs/opf/checkout/styles/components/_index.scss +++ b/integration-libs/opf/checkout/styles/components/_index.scss @@ -3,4 +3,5 @@ @import './opf-checkout-billing-address-form'; @import './opf-checkout-payment-wrapper'; @import './opf-checkout-terms-and-conditions-alert'; +@import './opf-checkout-review-card'; @import './b2b/index'; diff --git a/integration-libs/opf/checkout/styles/components/_opf-checkout-payment-and-review.scss b/integration-libs/opf/checkout/styles/components/_opf-checkout-payment-and-review.scss index 359b62ffd37..85dab5cc0b1 100644 --- a/integration-libs/opf/checkout/styles/components/_opf-checkout-payment-and-review.scss +++ b/integration-libs/opf/checkout/styles/components/_opf-checkout-payment-and-review.scss @@ -124,62 +124,17 @@ } } - .cx-payment-and-review-cards-wrapper { + .cx-opf-review-card-wrapper { display: flex; flex-wrap: wrap; gap: 2rem; margin-bottom: 2rem; - > * { - flex: 1 1 calc(50% - 1rem); - min-width: 250px; - max-width: 100%; - display: block; - position: relative; - margin-bottom: 0; - border: 1px solid var(--cx-color-medium); - padding: 1.75rem; - border-radius: 10px; - background-color: #ffffff; - - button { - position: absolute; - top: 1.75rem; - right: 1.75rem; - color: var(--cx-color-primary); - outline: none; - border: none; - background: none; - padding: 0; - cursor: pointer; - margin: 0; - - cx-icon { - color: inherit; - } - } - - cx-card { - flex-grow: 1; - padding: 0 2rem 0 0; - } - - @include media-breakpoint-down(md) { - flex: 1 1 100%; - margin-top: 0; - } - - .cx-card-body { - padding: 0; - } - } - > *:last-child:nth-child(odd) { flex: 1 1 100%; } } - // Common button styles for all edit icons %edit-button-styles { position: absolute; top: 1.75rem; @@ -197,7 +152,6 @@ } } - // Apply to billing address cx-opf-checkout-billing-address-form { position: relative; diff --git a/integration-libs/opf/checkout/styles/components/_opf-checkout-review-card.scss b/integration-libs/opf/checkout/styles/components/_opf-checkout-review-card.scss new file mode 100644 index 00000000000..e1c48da6d37 --- /dev/null +++ b/integration-libs/opf/checkout/styles/components/_opf-checkout-review-card.scss @@ -0,0 +1,43 @@ +%cx-opf-checkout-review-card { + flex: 1 1 calc(50% - 1rem); + min-width: 250px; + max-width: 100%; + display: block; + position: relative; + margin-bottom: 0; + border: 1px solid var(--cx-color-medium); + padding: 1.75rem; + border-radius: 10px; + background-color: #ffffff; + + button { + position: absolute; + top: 1.75rem; + right: 1.75rem; + color: var(--cx-color-primary); + outline: none; + border: none; + background: none; + padding: 0; + cursor: pointer; + margin: 0; + + cx-icon { + color: inherit; + } + } + + cx-card { + flex-grow: 1; + padding: 0 2rem 0 0; + } + + @include media-breakpoint-down(md) { + flex: 1 1 100%; + margin-top: 0; + } + + .cx-card-body { + padding: 0; + } +} diff --git a/integration-libs/opf/checkout/styles/components/b2b/_index.scss b/integration-libs/opf/checkout/styles/components/b2b/_index.scss index 5bb9066ae83..0b3843a344b 100644 --- a/integration-libs/opf/checkout/styles/components/b2b/_index.scss +++ b/integration-libs/opf/checkout/styles/components/b2b/_index.scss @@ -1 +1,2 @@ @import './opf-b2b-checkout-payment-type'; +@import './opf-b2b-checkout-review'; diff --git a/integration-libs/opf/checkout/styles/components/b2b/_opf-b2b-checkout-review.scss b/integration-libs/opf/checkout/styles/components/b2b/_opf-b2b-checkout-review.scss new file mode 100644 index 00000000000..f99495732e6 --- /dev/null +++ b/integration-libs/opf/checkout/styles/components/b2b/_opf-b2b-checkout-review.scss @@ -0,0 +1,166 @@ +%cx-opf-b2b-checkout-review { + @include checkout-media-style(); + margin-top: 1.5rem; + + @include media-breakpoint-down(md) { + background-color: var(--cx-color-transparent); + } + + h3 { + padding-bottom: 1rem; + margin-bottom: 0; + font-size: 1.15rem; + } + + cx-opf-checkout-billing-address-form, + cx-opf-checkout-payments, + .cx-opf-payment-wrapper, + .cx-opf-terms-and-conditions { + display: block; + margin-bottom: 2rem; + border: 1px solid #d3d6db; + padding: 1.75rem 1.75rem; + border-radius: 10px; + background-color: #ffffff; + } + + .cx-card .cx-card-title { + font-size: var(--cx-font-size, 1.125rem); + line-height: var(--cx-line-height, 1.2222222222); + font-weight: var(--cx-font-weight-normal); + margin-bottom: 0.5rem; + } + + .cx-opf-terms-and-conditions { + margin-bottom: 2rem; + + .form-check, + .form-group { + margin-bottom: 0; + } + } + + .cx-review-cart-item { + padding: 0; + } + + .cx-review-cart-total { + font-size: var(--cx-font-size, 1.125rem); + font-weight: var(--cx-font-weight-bold); + line-height: var(--cx-line-height, 1.2222222222); + padding-top: 1rem; + padding-bottom: 1.25rem; + } + + .cx-items-to-ship-label { + display: flex; + flex-direction: row; + align-items: center; + padding: 1rem 2rem; + font-weight: var(--cx-font-weight-semi); + height: 65px; + background: #f1f1f1; + + @include media-breakpoint-down(md) { + background: #d3d6db; + } + } + + .cx-shipping-and-delivery-info-cards { + display: flex; + gap: 1rem; + margin-top: 1rem; + flex-direction: row; + + @include media-breakpoint-down(md) { + flex-direction: column; + } + + .card-body { + padding: 0; + } + + .cx-review-summary-card { + display: flex; + flex: 1; + position: relative; + border: 1px solid #d3d6db; + border-radius: 10px; + padding: 1.75rem; + background-color: #ffffff; + + button { + position: absolute; + top: 1.75rem; + right: 1.75rem; + color: var(--cx-color-primary); + outline: none; + border: none; + background: none; + padding: 0; + cursor: pointer; + margin: 0; + + cx-icon { + color: inherit; + } + } + + cx-card { + flex-grow: 1; + padding: 0 2rem 0 0; + } + } + + .cx-card-title { + font-weight: var(--cx-font-weight-semi); + } + } + + > section > cx-opf-checkout-terms-and-conditions-alert { + display: none; + @include media-breakpoint-down(md) { + display: block; + } + } + + .cx-opf-review-card-wrapper { + display: flex; + flex-wrap: wrap; + gap: 2rem; + margin-bottom: 2rem; + + > *:last-child:nth-child(odd) { + flex: 1 1 100%; + } + } + + %edit-button-styles { + position: absolute; + top: 1.75rem; + right: 1.75rem; + color: var(--cx-color-primary); + outline: none; + border: none; + background: none; + padding: 0; + cursor: pointer; + margin: 0; + + cx-icon { + color: inherit; + } + } + + cx-opf-checkout-billing-address-form { + position: relative; + + button { + @extend %edit-button-styles; + } + + cx-card { + padding: 0 2rem 0 0; + } + } +}