diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx
index a36542d01e..7dcc52599c 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx
@@ -7,10 +7,13 @@ import { CancelSubscriptionButton } from './cancel-subscription-button'
import { CancelSubscription } from './cancel-plan/cancel-subscription'
import { PendingPlanChange } from './pending-plan-change'
import { TrialEnding } from './trial-ending'
-import { ChangePlan } from './change-plan/change-plan'
import { PendingAdditionalLicenses } from './pending-additional-licenses'
import { ContactSupportToChangeGroupPlan } from './contact-support-to-change-group-plan'
import isInFreeTrial from '../../../../util/is-in-free-trial'
+import { ChangePlanModal } from './change-plan/modals/change-plan-modal'
+import { ConfirmChangePlanModal } from './change-plan/modals/confirm-change-plan-modal'
+import { KeepCurrentPlanModal } from './change-plan/modals/keep-current-plan-modal'
+import { ChangeToGroupModal } from './change-plan/modals/change-to-group-modal'
export function ActiveSubscription({
subscription,
@@ -18,7 +21,7 @@ export function ActiveSubscription({
subscription: RecurlySubscription
}) {
const { t } = useTranslation()
- const { recurlyLoadError, setShowChangePersonalPlan, showCancellation } =
+ const { recurlyLoadError, setModalIdShown, showCancellation } =
useSubscriptionDashboardContext()
if (showCancellation) return
@@ -59,7 +62,7 @@ export function ActiveSubscription({
{' '}
@@ -120,7 +123,10 @@ export function ActiveSubscription({
)}
-
+
+
+
+
>
)
}
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-plan.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-plan.tsx
deleted file mode 100644
index 0bb7678a49..0000000000
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-plan.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { useTranslation } from 'react-i18next'
-import LoadingSpinner from '../../../../../../../shared/components/loading-spinner'
-import { useSubscriptionDashboardContext } from '../../../../../context/subscription-dashboard-context'
-import { ChangeToGroupPlan } from './change-to-group-plan'
-import { ConfirmChangePlanModal } from './modals/confirm-change-plan-modal'
-import { IndividualPlansTable } from './individual-plans-table'
-import { KeepCurrentPlanModal } from './modals/keep-current-plan-modal'
-import { ChangeToGroupModal } from './modals/change-to-group-modal'
-
-export function ChangePlan() {
- const { t } = useTranslation()
- const {
- plans,
- queryingIndividualPlansData,
- recurlyLoadError,
- showChangePersonalPlan,
- } = useSubscriptionDashboardContext()
-
- if (!showChangePersonalPlan || !plans || recurlyLoadError) return null
-
- if (queryingIndividualPlansData) {
- return (
- <>
-
{t('change_plan')}
-
- >
- )
- } else {
- return (
- <>
- {t('change_plan')}
-
-
-
-
-
- >
- )
- }
-}
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-to-group-plan.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-to-group-plan.tsx
index 97b1ad275b..8c977efc39 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-to-group-plan.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-to-group-plan.tsx
@@ -10,13 +10,13 @@ export function ChangeToGroupPlan() {
}
return (
- <>
- {t('looking_multiple_licenses')}
+
+
{t('looking_multiple_licenses')}
{t('reduce_costs_group_licenses')}
- >
+
)
}
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/individual-plans-table.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/individual-plans-table.tsx
index b7b53bd58c..98d8c2aa36 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/individual-plans-table.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/individual-plans-table.tsx
@@ -92,10 +92,9 @@ function PlansRows({ plans }: { plans: Array }) {
export function IndividualPlansTable({ plans }: { plans: Array }) {
const { t } = useTranslation()
- const { recurlyLoadError, showChangePersonalPlan } =
- useSubscriptionDashboardContext()
+ const { recurlyLoadError } = useSubscriptionDashboardContext()
- if (!showChangePersonalPlan || !plans || recurlyLoadError) return null
+ if (!plans || recurlyLoadError) return null
return (
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/change-plan-modal.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/change-plan-modal.tsx
new file mode 100644
index 0000000000..7c365525f2
--- /dev/null
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/change-plan-modal.tsx
@@ -0,0 +1,52 @@
+import { Modal } from 'react-bootstrap'
+import { useTranslation } from 'react-i18next'
+import { SubscriptionDashModalIds } from '../../../../../../../../../../types/subscription/dashboard/modal-ids'
+import AccessibleModal from '../../../../../../../../shared/components/accessible-modal'
+import LoadingSpinner from '../../../../../../../../shared/components/loading-spinner'
+import { useSubscriptionDashboardContext } from '../../../../../../context/subscription-dashboard-context'
+import { ChangeToGroupPlan } from '../change-to-group-plan'
+import { IndividualPlansTable } from '../individual-plans-table'
+
+function ChangePlanOptions() {
+ const { plans, queryingIndividualPlansData, recurlyLoadError } =
+ useSubscriptionDashboardContext()
+
+ if (!plans || recurlyLoadError) return null
+
+ if (queryingIndividualPlansData) {
+ return (
+ <>
+
+ >
+ )
+ } else {
+ return (
+ <>
+
+
+
+
+ >
+ )
+ }
+}
+
+export function ChangePlanModal() {
+ const modalId: SubscriptionDashModalIds = 'change-plan'
+ const { t } = useTranslation()
+ const { handleCloseModal, modalIdShown } = useSubscriptionDashboardContext()
+
+ if (modalIdShown !== modalId) return null
+
+ return (
+
+
+ {t('change_plan')}
+
+
+
+
+
+
+ )
+}
diff --git a/services/web/frontend/js/features/subscription/context/subscription-dashboard-context.tsx b/services/web/frontend/js/features/subscription/context/subscription-dashboard-context.tsx
index 7a7cff615d..f3bb0acceb 100644
--- a/services/web/frontend/js/features/subscription/context/subscription-dashboard-context.tsx
+++ b/services/web/frontend/js/features/subscription/context/subscription-dashboard-context.tsx
@@ -66,8 +66,6 @@ type SubscriptionDashboardContextValue = {
setRecurlyLoadError: React.Dispatch>
showCancellation: boolean
setShowCancellation: React.Dispatch>
- showChangePersonalPlan: boolean
- setShowChangePersonalPlan: React.Dispatch>
leavingGroupId?: string
setLeavingGroupId: React.Dispatch>
}
@@ -86,7 +84,6 @@ export function SubscriptionDashboardProvider({
>()
const [recurlyLoadError, setRecurlyLoadError] = useState(false)
const [showCancellation, setShowCancellation] = useState(false)
- const [showChangePersonalPlan, setShowChangePersonalPlan] = useState(false)
const [plans, setPlans] = useState([])
const [queryingIndividualPlansData, setQueryingIndividualPlansData] =
useState(true)
@@ -268,8 +265,6 @@ export function SubscriptionDashboardProvider({
setRecurlyLoadError,
showCancellation,
setShowCancellation,
- showChangePersonalPlan,
- setShowChangePersonalPlan,
leavingGroupId,
setLeavingGroupId,
}),
@@ -304,8 +299,6 @@ export function SubscriptionDashboardProvider({
setRecurlyLoadError,
showCancellation,
setShowCancellation,
- showChangePersonalPlan,
- setShowChangePersonalPlan,
leavingGroupId,
setLeavingGroupId,
]
diff --git a/services/web/frontend/stylesheets/app/plans.less b/services/web/frontend/stylesheets/app/plans.less
index a7166c1126..9e01bd43f7 100644
--- a/services/web/frontend/stylesheets/app/plans.less
+++ b/services/web/frontend/stylesheets/app/plans.less
@@ -578,3 +578,67 @@
}
}
}
+
+/**
+ Subscription Dash
+*/
+
+#change-plan {
+ .modal-dialog {
+ &:extend(.modal-lg);
+ }
+
+ table {
+ @media only screen and (min-width: @screen-md-min) {
+ th:last-child,
+ td:last-child {
+ width: 1%; // will expand to fit the content
+ text-align: center;
+ }
+ }
+
+ @media only screen and (max-width: @screen-sm-max) {
+ display: block;
+
+ thead {
+ display: none;
+ }
+
+ tbody,
+ td,
+ tr {
+ display: inline-block;
+ padding-top: 0;
+ padding-bottom: 0;
+ text-align: center;
+ width: 100%;
+ }
+
+ td:first-child {
+ padding-top: @padding-md;
+ }
+ td:last-child {
+ padding-top: @padding-sm;
+ padding-bottom: @padding-md;
+ }
+
+ tr:first-child {
+ td:first-child {
+ padding-top: @padding-sm;
+ }
+ }
+
+ tr {
+ border-bottom: 1px solid @table-border-color;
+ td,
+ th {
+ border: 0 !important;
+ }
+ }
+
+ tr:last-child {
+ border-bottom: 0;
+ }
+ }
+ }
+}
diff --git a/services/web/frontend/stylesheets/components/card.less b/services/web/frontend/stylesheets/components/card.less
index 8261dd8ca1..e6af58b6c7 100644
--- a/services/web/frontend/stylesheets/components/card.less
+++ b/services/web/frontend/stylesheets/components/card.less
@@ -65,3 +65,9 @@
.card-content {
padding: @padding-md;
}
+
+.card-gray {
+ &:extend(.card);
+ background-color: @neutral-10;
+ border-radius: @card-border-radius;
+}
diff --git a/services/web/frontend/stylesheets/components/tables.less b/services/web/frontend/stylesheets/components/tables.less
index d88ba303c8..5b1f45c513 100755
--- a/services/web/frontend/stylesheets/components/tables.less
+++ b/services/web/frontend/stylesheets/components/tables.less
@@ -83,7 +83,7 @@ th {
}
}
-// Bordered version
+// Bordered versions
//
// Add borders all around the table and between all the columns.
@@ -233,3 +233,13 @@ table {
}
}
}
+
+.table-outlined-container {
+ border: @border-width-sm solid @table-border-color;
+ padding: @padding-sm @padding-sm 0 @padding-sm;
+ border-radius: @border-radius-base-new;
+
+ table {
+ margin-bottom: 0;
+ }
+}
diff --git a/services/web/frontend/stylesheets/core/variables.less b/services/web/frontend/stylesheets/core/variables.less
index a4614a79b9..5b86b9f335 100644
--- a/services/web/frontend/stylesheets/core/variables.less
+++ b/services/web/frontend/stylesheets/core/variables.less
@@ -165,8 +165,10 @@
@line-height-small: 1.5;
@border-radius-base: 3px;
+@border-radius-base-new: 4px;
@border-radius-large: 5px;
@border-radius-small: 2px;
+@border-width-sm: 1px;
@border-width-base: 3px;
@border-color-base: @ol-blue-gray-2;
@@ -932,6 +934,7 @@
// Cards
@card-box-shadow: none;
+@card-border-radius: @border-radius-base-new;
// Project table
@structured-list-link-color: @ol-blue;
diff --git a/services/web/frontend/stylesheets/variables/all.less b/services/web/frontend/stylesheets/variables/all.less
index 039aec49a4..1b326b0b3c 100644
--- a/services/web/frontend/stylesheets/variables/all.less
+++ b/services/web/frontend/stylesheets/variables/all.less
@@ -107,8 +107,10 @@
@line-height-small: 1.5;
@border-radius-base: 3px;
+@border-radius-base-new: 4px;
@border-radius-large: 5px;
@border-radius-small: 2px;
+@border-width-sm: 1px;
@border-width-base: 3px; // only used by plans and cards
@border-size: 1px;
@border-color-base: @neutral-60;
@@ -720,6 +722,7 @@
// Cards
@card-box-shadow: none;
+@card-border-radius: @border-radius-base-new;
// Project table
@structured-list-link-color: @blue;
diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx
index 13a025ab10..131a0e1990 100644
--- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx
+++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx
@@ -1,7 +1,6 @@
import { expect } from 'chai'
import { fireEvent, screen, waitFor, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
-import { ChangePlan } from '../../../../../../../../../frontend/js/features/subscription/components/dashboard/states/active/change-plan/change-plan'
import { groupPlans, plans } from '../../../../../fixtures/plans'
import {
annualActiveSubscription,
@@ -22,7 +21,7 @@ import {
} from '../../../../../../../../../frontend/js/features/subscription/data/subscription-url'
import { renderActiveSubscription } from '../../../../../helpers/render-active-subscription'
-describe('', function () {
+describe('', function () {
let reloadStub: () => void
const originalLocation = window.location
const plansMetaTag = { name: 'ol-plans', value: plans }
@@ -42,15 +41,6 @@ describe('', function () {
})
})
- it('does not render the UI when showChangePersonalPlan is false', function () {
- window.metaAttributesCache.delete('ol-plans')
- const { container } = renderWithSubscriptionDashContext(, {
- metaTags: [plansMetaTag],
- })
-
- expect(container.firstChild).to.be.null
- })
-
it('renders the individual plans table and group plans UI', async function () {
renderActiveSubscription(annualActiveSubscription)
const button = screen.getByRole('button', { name: 'Change plan' })
diff --git a/services/web/types/subscription/dashboard/modal-ids.ts b/services/web/types/subscription/dashboard/modal-ids.ts
index 0c49515501..9e332657ce 100644
--- a/services/web/types/subscription/dashboard/modal-ids.ts
+++ b/services/web/types/subscription/dashboard/modal-ids.ts
@@ -3,3 +3,4 @@ export type SubscriptionDashModalIds =
| 'change-to-group'
| 'keep-current-plan'
| 'leave-group'
+ | 'change-plan'