diff --git a/src/components/BuyProcess/NewPlanSelection/ContactsPlan/index.js b/src/components/BuyProcess/NewPlanSelection/ContactsPlan/index.js
index 057498213..d6588e015 100644
--- a/src/components/BuyProcess/NewPlanSelection/ContactsPlan/index.js
+++ b/src/components/BuyProcess/NewPlanSelection/ContactsPlan/index.js
@@ -235,7 +235,14 @@ export const ContactsPlan = InjectAppServices(
appliedPromocode.toLowerCase() === savedPromocode.toLowerCase();
const shouldShowLosePromotionWarning =
!isTailoredPlan && isUpgradePlan && isAppliedPromocodeSameAsSaved;
+ const shouldShowCurrentPlanWarning =
+ !isFreeAccount &&
+ sessionPlan?.plan?.planType === PLAN_TYPE.byContact &&
+ isEqualPlan &&
+ !isTailoredPlan;
const shouldUseAdvisorCta = isTailoredPlan || shouldShowDowngradeWarning;
+ const shouldHideSubscriptionAndPromocode =
+ isTailoredPlan || shouldShowDowngradeWarning || shouldShowCurrentPlanWarning;
const shouldDisablePaymentFrequency = !isFreeAccount && !keepControlsEnabled;
const stickyDiscountSummary = useMemo(() => {
@@ -352,37 +359,43 @@ export const ContactsPlan = InjectAppServices(
-
-
+ {!shouldHideSubscriptionAndPromocode && (
+ <>
+
+
+ >
+ )}
{isMoreThan100kSelected && (
-
+ , bold: (chunks) => {chunks} }}
+ />
+
+
+
-
-
-
)}
{shouldShowLosePromotionWarning && (
@@ -434,6 +450,19 @@ export const ContactsPlan = InjectAppServices(
)}
+ {shouldShowCurrentPlanWarning && (
+
+ )}
@@ -503,6 +532,7 @@ export const ContactsPlan = InjectAppServices(
,
percentage: selectedDiscountPercentage,
currency: 'US$',
period: _(
diff --git a/src/components/BuyProcess/NewPlanSelection/EmailsPlan/index.js b/src/components/BuyProcess/NewPlanSelection/EmailsPlan/index.js
index fe82a5736..d4ce602a0 100644
--- a/src/components/BuyProcess/NewPlanSelection/EmailsPlan/index.js
+++ b/src/components/BuyProcess/NewPlanSelection/EmailsPlan/index.js
@@ -161,7 +161,12 @@ export const EmailsPlan = InjectAppServices(
selectedEmailCapacity < currentSessionEmailCapacity));
const shouldShowHighVolumeMessage = isMoreThan10mSelected;
const shouldUseAdvisorCta = shouldShowDowngradeWarning || shouldShowHighVolumeMessage;
- const shouldShowPromocode = !shouldUseAdvisorCta;
+ const shouldShowCurrentPlanWarning =
+ !isFreeAccount &&
+ sessionPlan?.plan?.planType === PLAN_TYPE.byEmail &&
+ isEqualPlan &&
+ !shouldUseAdvisorCta;
+ const shouldShowPromocode = !shouldUseAdvisorCta && !shouldShowCurrentPlanWarning;
const extraEmailPrice = selectedPlan?.extraEmailPrice ?? 0;
const stickyDiscountSummary = useMemo(() => {
@@ -327,6 +332,19 @@ export const EmailsPlan = InjectAppServices(
)}
+ {shouldShowCurrentPlanWarning && (
+
+ )}
diff --git a/src/components/BuyProcess/NewPlanSelection/index.styles.js b/src/components/BuyProcess/NewPlanSelection/index.styles.js
index 04b0098f6..487c12547 100644
--- a/src/components/BuyProcess/NewPlanSelection/index.styles.js
+++ b/src/components/BuyProcess/NewPlanSelection/index.styles.js
@@ -367,6 +367,7 @@ export const NewPlanSelectionStyled = styled.div`
}
.dp-new-plan-selection-price .dp-button {
+ margin-top: 10px;
width: 250px;
}
@@ -644,7 +645,7 @@ export const NewPlanSelectionStyled = styled.div`
}
.dp-new-plan-selection-included-features {
- margin: 28px auto 30px;
+ margin: 44px auto 30px;
width: 100%;
}
@@ -853,7 +854,7 @@ export const NewPlanSelectionStyled = styled.div`
}
.dp-new-plan-selection-addons {
- margin: 34px auto 36px;
+ margin: 34px auto 52px;
}
.dp-new-plan-selection-addons-header {
@@ -886,6 +887,7 @@ export const NewPlanSelectionStyled = styled.div`
display: flex;
flex: 1 1 auto;
gap: 18px;
+ padding: 6px 8px 10px;
}
.dp-new-plan-selection-addon-card {
@@ -894,6 +896,7 @@ export const NewPlanSelectionStyled = styled.div`
flex: 0 0 calc((100% - 36px) / 3);
margin-bottom: 0;
min-height: 100%;
+ padding: 24px 24px 20px;
}
.dp-new-plan-selection-addon-card .card-title {
@@ -967,6 +970,14 @@ export const NewPlanSelectionStyled = styled.div`
max-width: none;
}
+ .dp-new-plan-selection-faq section {
+ padding-top: 32px;
+ }
+
+ .dp-new-plan-selection-faq .dp-title-faq {
+ margin-top: 0;
+ }
+
.dp-new-plan-selection-faq .dp-accordion li .dp-accordion-thumb {
color: #333;
font-weight: 400;
diff --git a/src/components/BuyProcess/NewPlanSelection/index.test.js b/src/components/BuyProcess/NewPlanSelection/index.test.js
index 55e7260d0..f129d5634 100644
--- a/src/components/BuyProcess/NewPlanSelection/index.test.js
+++ b/src/components/BuyProcess/NewPlanSelection/index.test.js
@@ -613,6 +613,7 @@ describe('NewPlanSelection component', () => {
planType: PLAN_TYPE.byContact,
isFreeAccount: false,
planSubscription: 12,
+ subscribersCount: 900,
promotion: {
idUserTypePlan: 10222,
code: 'PROMOCODE_ANNUAL',
@@ -625,7 +626,9 @@ describe('NewPlanSelection component', () => {
const promocodeInput = within(getContactsPlanSection()).getByRole('textbox');
expect(promocodeInput).toHaveValue('');
- expect(screen.queryByRole('link', { name: /Elegir Plan/i })).not.toBeInTheDocument();
+ const choosePlanHref = screen.getByRole('link', { name: /Elegir Plan/i }).getAttribute('href');
+ expect(choosePlanHref).not.toContain('PromoCode=');
+ expect(choosePlanHref).not.toContain('promo-code=');
});
it('should update selected contacts plan in checkout URL when contacts dropdown changes', async () => {
@@ -693,6 +696,30 @@ describe('NewPlanSelection component', () => {
).toHaveAttribute('href', '/checkout/premium/monthly-deliveries?selected-plan=30223&buyType=1');
});
+ it('should show current plan warning and hide promocode when selected byEmail plan equals current one', async () => {
+ await renderNewPlanSelection(
+ ['/new-plan-selection'],
+ {
+ appSessionUser: {
+ plan: {
+ idPlan: 30223,
+ planType: PLAN_TYPE.byEmail,
+ isFreeAccount: false,
+ planSubscription: 1,
+ },
+ },
+ },
+ { useI18nKeysAsValues: true },
+ );
+
+ expect(getEmailsSelect()).toHaveValue('1');
+ expect(screen.getByTestId('dp-emails-current-plan-message')).toBeInTheDocument();
+ expect(
+ screen.getByText('buy_process.new_plan_selection.contacts_current_plan_warning_message'),
+ ).toBeInTheDocument();
+ expect(within(getEmailsPlanSection()).queryByRole('textbox')).not.toBeInTheDocument();
+ });
+
it('should preselect the next contact plan when subscribers count is lower than current plan capacity and a higher plan exists', async () => {
const contactPlansWithExtraLevel = [
{
@@ -792,6 +819,34 @@ describe('NewPlanSelection component', () => {
).toBeDisabled();
});
+ it('should show current plan warning and hide subscription and promocode when selected plan equals current one', async () => {
+ await renderNewPlanSelection(
+ ['/new-plan-selection'],
+ {
+ appSessionUser: {
+ plan: {
+ idPlan: 10223,
+ planType: PLAN_TYPE.byContact,
+ isFreeAccount: false,
+ planSubscription: 1,
+ subscribersCount: 1300,
+ },
+ },
+ },
+ { useI18nKeysAsValues: true },
+ );
+
+ expect(getContactsSelect()).toHaveValue('1');
+ expect(screen.getByTestId('dp-contacts-current-plan-message')).toBeInTheDocument();
+ expect(
+ screen.getByText('buy_process.new_plan_selection.contacts_current_plan_warning_message'),
+ ).toBeInTheDocument();
+ expect(
+ within(getContactsPlanSection()).queryByRole('button', { name: /Mensual/i }),
+ ).not.toBeInTheDocument();
+ expect(within(getContactsPlanSection()).queryByRole('textbox')).not.toBeInTheDocument();
+ });
+
it('should preselect a higher contact plan when subscribers count is greater than current plan capacity', async () => {
await renderNewPlanSelection(['/new-plan-selection'], {
appSessionUser: {
@@ -967,6 +1022,10 @@ describe('NewPlanSelection component', () => {
await waitFor(() =>
expect(screen.getByTestId('dp-contacts-downgrade-message')).toBeInTheDocument(),
);
+ expect(
+ within(getContactsPlanSection()).queryByRole('button', { name: /Mensual/i }),
+ ).not.toBeInTheDocument();
+ expect(within(getContactsPlanSection()).queryByRole('textbox')).not.toBeInTheDocument();
expect(
screen.getByText('buy_process.new_plan_selection.contacts_downgrade_warning_message'),
).toBeInTheDocument();
@@ -1135,10 +1194,11 @@ describe('NewPlanSelection component', () => {
},
});
- const annualFrequencyButton = within(getContactsPlanSection()).getByRole('button', {
- name: /Anual/i,
- });
- expect(annualFrequencyButton).toBeDisabled();
+ expect(screen.getByTestId('dp-contacts-current-plan-message')).toBeInTheDocument();
+ expect(
+ within(getContactsPlanSection()).queryByRole('button', { name: /Anual/i }),
+ ).not.toBeInTheDocument();
+ expect(within(getContactsPlanSection()).queryByRole('textbox')).not.toBeInTheDocument();
});
it('should render credits plan before contacts plan for users with current credit plan', async () => {
@@ -1195,6 +1255,10 @@ describe('NewPlanSelection component', () => {
const infoBanner = screen.getByTestId('dp-more-than-100k-message');
expect(infoBanner).toBeInTheDocument();
+ expect(
+ within(getContactsPlanSection()).queryByRole('button', { name: /Mensual/i }),
+ ).not.toBeInTheDocument();
+ expect(within(getContactsPlanSection()).queryByRole('textbox')).not.toBeInTheDocument();
expect(within(infoBanner).getByText(/base supera los 100k de Contactos/i)).toBeInTheDocument();
expect(
within(infoBanner).getByRole('link', { name: /cont[aá]ctanos|contact us/i }),
@@ -1431,4 +1495,29 @@ describe('NewPlanSelection component', () => {
within(getCreditsPlanSection()).getByText(/Incluye 5.000 Creditos extra/i),
).toBeInTheDocument();
});
+
+ it('should keep prepayment breakdown in a new line for quarterly, semiannual and annual frequencies', async () => {
+ await renderNewPlanSelection();
+
+ const contactsSection = getContactsPlanSection();
+ const scenarios = [
+ { buttonName: /Trimestral/i, expectedText: '1 pago trimestral de' },
+ { buttonName: /Semestral/i, expectedText: '1 pago semestral de' },
+ { buttonName: /Anual/i, expectedText: '1 pago anual de' },
+ ];
+
+ for (const scenario of scenarios) {
+ fireEvent.click(within(contactsSection).getByRole('button', { name: scenario.buttonName }));
+ await settleAsyncState();
+
+ await waitFor(() => {
+ const savingsElement = contactsSection.querySelector(
+ '.dp-new-plan-selection-price-detail .dp-new-plan-selection-savings',
+ );
+ expect(savingsElement).toBeInTheDocument();
+ expect(savingsElement.textContent.toLowerCase()).toContain(scenario.expectedText);
+ expect(savingsElement.querySelector('br')).toBeInTheDocument();
+ });
+ }
+ });
});
diff --git a/src/i18n/en.js b/src/i18n/en.js
index 21d769f3f..f644073dc 100644
--- a/src/i18n/en.js
+++ b/src/i18n/en.js
@@ -173,6 +173,7 @@ other {}}}}}}}}}}
buy_credits: 'Buy Credits',
choose_plan: 'Choose Plan',
contact_advisor_cta: 'Contact an Advisor',
+ contacts_current_plan_warning_message: 'You cannot select this Plan because it is your current one.',
contacts_downgrade_warning_message: 'Need to reduce contacts?{br}If you want to switch to a smaller Contacts Plan, contact us so we can advise you.',
contacts_label: 'How many Contacts do you have?',
contacts_option: '{contacts}',
@@ -218,7 +219,7 @@ other {}}}}}}}}}}
},
month_period: 'month',
more_than_100k_contact_link: 'CONTACT US',
- more_than_100k_info_message: 'Do you exceed 100k contacts? The Email Plan gives you unlimited Contacts and a lower cost per send. Talk to our advisors and build a tailored Plan.',
+ more_than_100k_info_message: 'Do you exceed 100k contacts?{br}The Email Plan gives you unlimited Contacts and a lower cost per send. Talk to our advisors and build a tailored Plan.',
payment_period_half_yearly: 'semiannual',
payment_period_monthly: 'monthly',
payment_period_quarterly: 'quarterly',
@@ -227,7 +228,7 @@ other {}}}}}}}}}}
price_label: 'Price',
promocode_savings_text: 'You save {percentage}% for {months, plural, one {# month} other {# months}}',
promocode_savings_text_without_months: 'You save {percentage}%',
- savings_text: 'You save {percentage}% with 1 {period} payment of {currency}{total}',
+ savings_text: 'You save {percentage}% with{br}1 {period} payment of {currency}{total}',
single_payment_period: 'one-time payment',
sticky_contacts_subtitle: 'Up to {contacts} Contacts + Unlimited emails',
sticky_custom_cta: 'Consult with Doppler Team',
diff --git a/src/i18n/es.js b/src/i18n/es.js
index 2de781357..ad0dd08a4 100644
--- a/src/i18n/es.js
+++ b/src/i18n/es.js
@@ -174,6 +174,7 @@ other {}}}}}}}}}}
buy_credits: 'Comprar Creditos',
choose_plan: 'Elegir Plan',
contact_advisor_cta: 'Contactar a Asesor',
+ contacts_current_plan_warning_message: 'No puedes seleccionar este Plan porque es el que posees actualmente.',
contacts_downgrade_warning_message: '¿Necesitas disminuir los contactos?{br}Si deseas pasar a un Plan con menos Contactos, contáctanos para que podamos asesorarte.',
contacts_label: '¿Cuántos Contactos tienes?',
contacts_option: '{contacts}',
@@ -219,7 +220,8 @@ other {}}}}}}}}}}
},
month_period: 'mes',
more_than_100k_contact_link: 'CONTÁCTANOS',
- more_than_100k_info_message: '¿Tu base supera los 100k de Contactos? El Plan Envíos te da Contactos ilimitados y el costo por Envío más bajo. Habla con nuestros asesores y arma el Plan personalizado.',
+ more_than_100k_info_message:
+ '¿Tu base supera los 100k de Contactos?{br}El Plan Envíos te da Contactos ilimitados y el costo por Envío más bajo. Habla con nuestros asesores y arma el Plan personalizado.',
payment_period_half_yearly: 'semestral',
payment_period_monthly: 'mensual',
payment_period_quarterly: 'trimestral',
@@ -228,7 +230,7 @@ other {}}}}}}}}}}
price_label: 'Precio',
promocode_savings_text: 'Ahorras {percentage}% durante {months, plural, one {# mes} other {# meses}}',
promocode_savings_text_without_months: 'Ahorras {percentage}%',
- savings_text: 'Ahorras {percentage}% realizando 1 pago {period} de {currency}{total}',
+ savings_text: 'Ahorras {percentage}% realizando{br}1 pago {period} de {currency}{total}',
single_payment_period: 'pago unico',
sticky_contacts_subtitle: 'Hasta {contacts} Contactos + Envios ilimitados',
sticky_custom_cta: 'Consultar con Doppler Team',