From 886ee7e9ec0bbb667b69a5a17764ea9b86ae068d Mon Sep 17 00:00:00 2001 From: Rish Date: Thu, 30 Apr 2020 00:17:16 +0530 Subject: [PATCH] Added new component for membership plans refs https://github.com/TryGhost/members.js/issues/10 Create common plans section UI component as its used in multiple places in app --- .../src/components/common/PlansSection.js | 148 ++++++++++++++++++ .../components/common/PlansSection.test.js | 40 +++++ 2 files changed, 188 insertions(+) create mode 100644 ghost/portal/src/components/common/PlansSection.js create mode 100644 ghost/portal/src/components/common/PlansSection.test.js diff --git a/ghost/portal/src/components/common/PlansSection.js b/ghost/portal/src/components/common/PlansSection.js new file mode 100644 index 0000000000..5ba6296364 --- /dev/null +++ b/ghost/portal/src/components/common/PlansSection.js @@ -0,0 +1,148 @@ +import React from 'react'; + +const Styles = ({style = {}}) => { + return { + input: { + display: 'block', + padding: '0 .6em', + width: '100%', + height: '44px', + outline: '0', + border: '1px solid #c5d2d9', + color: 'inherit', + textDecoration: 'none', + background: '#fff', + borderRadius: '9px', + fontSize: '14px', + marginBottom: '12px', + boxSizing: 'border-box', + ...(style.input || {}) // Override any custom style + }, + label: { + marginBottom: '3px', + fontSize: '12px', + fontWeight: '700', + ...(style.label || {}) // Override any custom style + } + }; +}; + +function Checkbox({name, onPlanSelect, isChecked}) { + const style = { + width: '20px', + height: '20px', + border: 'solid 1px #cccccc' + }; + + return ( + onPlanSelect(e, name)} + /> + ); +} + +function PriceLabel({name, currency, price}) { + if (name === 'Free') { + return ( + Access free members-only posts + ); + } + const type = name === 'Monthly' ? 'month' : 'year'; + return ( +
+ {currency} + {price} + {` / ${type}`} +
+ ); +} + +function PlanOptions({plans, selectedPlan, onPlanSelect}) { + const nameStyle = { + fontSize: '13px', + fontWeight: '500', + display: 'flex', + color: '#343F44', + justifyContent: 'center' + }; + + const priceStyle = { + fontSize: '12px', + fontWeight: 'bold', + display: 'flex', + justifyContent: 'center', + marginBottom: '9px' + }; + const checkboxStyle = { + display: 'flex', + justifyContent: 'center' + }; + const boxStyle = ({isLast = false}) => { + const style = { + padding: '12px 12px', + flexBasis: '100%' + }; + if (!isLast) { + style.borderRight = '1px solid #c5d2d9'; + } + return style; + }; + + return plans.map(({name, currency, price}, i) => { + const isLast = i === plans.length - 1; + const isChecked = selectedPlan === name; + return ( +
onPlanSelect(e, name)}> +
+ +
+
{name.toUpperCase()}
+
+ +
+
+ ); + }); +} + +function PlansSection({plans, selectedPlan, onPlanSelect, style}) { + const containerStyle = { + display: 'flex', + border: '1px solid #c5d2d9', + borderRadius: '9px', + marginBottom: '12px' + }; + + if (!plans || plans.length === 0) { + return null; + } + return ( +
+ +
+ +
+
+ ); +} + +export default PlansSection; diff --git a/ghost/portal/src/components/common/PlansSection.test.js b/ghost/portal/src/components/common/PlansSection.test.js new file mode 100644 index 0000000000..1685336b20 --- /dev/null +++ b/ghost/portal/src/components/common/PlansSection.test.js @@ -0,0 +1,40 @@ +import React from 'react'; +import {render, fireEvent} from '@testing-library/react'; +import PlansSection from './PlansSection'; + +const setup = (overrides = {}) => { + const mockOnPlanSelectFn = jest.fn(); + const props = { + plans: { + monthly: 12, + yearly: 110, + currency: 'USD', + currency_symbol: '$' + }, + selectedPlan: 'Monthly', + onPlanSelect: mockOnPlanSelectFn + }; + const utils = render( + + ); + + const freeCheckboxEl = utils.getByLabelText('Free'); + const monthlyCheckboxEl = utils.getByLabelText('Monthly'); + const yearlyCheckboxEl = utils.getByLabelText('Yearly'); + return { + freeCheckboxEl, + monthlyCheckboxEl, + yearlyCheckboxEl, + mockOnPlanSelectFn, + ...utils + }; +}; + +describe('InputField', () => { + test('renders', () => { + const {freeCheckboxEl, monthlyCheckboxEl, yearlyCheckboxEl} = setup(); + expect(freeCheckboxEl).toBeInTheDocument(); + expect(monthlyCheckboxEl).toBeInTheDocument(); + expect(yearlyCheckboxEl).toBeInTheDocument(); + }); +});