Skip to content

Commit

Permalink
Hid the free tier in Portal settings, if site is set to paid-members …
Browse files Browse the repository at this point in the history
…only
  • Loading branch information
sagzy committed Dec 16, 2024
1 parent a05b73f commit bf428d0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
5 changes: 3 additions & 2 deletions apps/admin-x-design-system/src/global/form/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export interface CheckboxProps {
key?: string;
checked?: boolean;
separator?: boolean;
testId?: string;
}

const Checkbox: React.FC<CheckboxProps> = ({title, label, value, onChange, disabled, error, hint, checked, separator}) => {
const Checkbox: React.FC<CheckboxProps> = ({title, label, value, onChange, disabled, error, hint, checked, separator, testId}) => {
const id = useId();

const handleCheckedChange = (isChecked: boolean | 'indeterminate') => {
Expand All @@ -29,7 +30,7 @@ const Checkbox: React.FC<CheckboxProps> = ({title, label, value, onChange, disab
<div className={`flex flex-col gap-1 ${separator && 'pb-2'}`}>
{title && <Heading grey={true} level={6}>{title}</Heading>}
<label className={`flex cursor-pointer items-start ${title && '-mb-1 mt-1'}`} htmlFor={id}>
<CheckboxPrimitive.Root className="mt-0.5 flex h-4 w-4 cursor-pointer appearance-none items-center justify-center rounded-[3px] border border-solid border-grey-500 bg-white outline-none data-[state=checked]:border-black data-[state=indeterminate]:border-black data-[state=checked]:bg-black data-[state=indeterminate]:bg-black" defaultChecked={checked} disabled={disabled} id={id} value={value} onCheckedChange={handleCheckedChange}>
<CheckboxPrimitive.Root className="mt-0.5 flex h-4 w-4 cursor-pointer appearance-none items-center justify-center rounded-[3px] border border-solid border-grey-500 bg-white outline-none data-[state=checked]:border-black data-[state=indeterminate]:border-black data-[state=checked]:bg-black data-[state=indeterminate]:bg-black" defaultChecked={checked} disabled={disabled} id={id} value={value} onCheckedChange={handleCheckedChange} data-testid={testId}>
<CheckboxPrimitive.Indicator>
<svg fill="none" height="11" viewBox="0 0 10 11" width="10">
<path d="M1 5.88889L4.6 9L9 1" stroke="white" strokeLinecap="round" strokeWidth="2"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,20 @@ const SignupOptions: React.FC<{
// This is a bit unclear in current admin, maybe we should add a message if the settings are disabled?
const isDisabled = membersSignupAccess !== 'all';

const isFreeTierAvailable = membersSignupAccess === 'all';
const isStripeEnabled = checkStripeEnabled(localSettings, config!);

let tiersCheckboxes: CheckboxProps[] = [];

if (localTiers) {
localTiers.forEach((tier) => {
if (tier.type === 'free') {
if (tier.type === 'free' && isFreeTierAvailable) {
tiersCheckboxes.push({
checked: (portalPlans.includes('free')),
disabled: isDisabled,
label: tier.name,
value: 'free',
testId: 'free-tier-checkbox',
onChange: (checked) => {
if (portalPlans.includes('free') && !checked) {
portalPlans.splice(portalPlans.indexOf('free'), 1);
Expand Down
44 changes: 40 additions & 4 deletions apps/admin-x-settings/test/acceptance/membership/portal.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {expect, test} from '@playwright/test';
import {globalDataRequests} from '../../utils/acceptance';
import {mockApi, mockSitePreview, responseFixtures} from '@tryghost/admin-x-framework/test/acceptance';
import {mockApi, mockSitePreview, responseFixtures, updatedSettingsResponse} from '@tryghost/admin-x-framework/test/acceptance';

test.describe('Portal Settings', async () => {
test('Loads Portal Preview Modal', async ({page}) => {
Expand All @@ -22,7 +22,7 @@ test.describe('Portal Settings', async () => {
await page.waitForSelector('[data-testid="portal-modal"]');
});

test('can toggle portal signup options', async ({page}) => {
test('can set portal signup options', async ({page}) => {
const {lastApiRequests} = await mockApi({page, requests: {
...globalDataRequests,
tiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers},
Expand All @@ -44,8 +44,16 @@ test.describe('Portal Settings', async () => {

const modal = await page.getByTestId('portal-modal');

await modal.getByRole('switch').click();
await modal.getByRole('checkbox').click();
const displayNameToggle = await modal.getByLabel('Display name in signup form');
expect(displayNameToggle).toBeVisible();
expect(displayNameToggle).toBeChecked();

const freeTierCheckbox = await modal.getByTestId('free-tier-checkbox');
expect(freeTierCheckbox).toBeVisible();
expect(freeTierCheckbox).toBeChecked();

await freeTierCheckbox.click();
await displayNameToggle.click();
await modal.getByRole('button', {name: 'Save'}).click();

expect(lastApiRequests.editTiers?.body).toMatchObject({
Expand All @@ -56,6 +64,34 @@ test.describe('Portal Settings', async () => {
});
});

test('free tier is hidden from portal signup options if the site is set to paid-members only', async ({page}) => {
await mockApi({page, requests: {
...globalDataRequests,
// Set site to paid-members only
browseSettings: {...globalDataRequests.browseSettings, response: updatedSettingsResponse([
{key: 'members_signup_access', value: 'paid'}
])},
// Free tier is available in the tiers list
browseTiers: {method: 'GET', path: '/tiers/', response: responseFixtures.tiers}
}});

await mockSitePreview({
page,
url: 'http://localhost:2368/?v=modal-portal-settings#/portal/preview?button=true&name=true&isFree=true&isMonthly=true&isYearly=true&page=signup&buttonIcon=icon-1&signupButtonText=Subscribe&membersSignupAccess=all&allowSelfSignup=true&signupTermsHtml=&signupCheckboxRequired=false&portalProducts=6511005e14c14a231e49af15&portalPrices=free%252Cmonthly%252Cyearly&accentColor=%2523FF1A75&buttonStyle=icon-and-text&disableBackground=false',
response: '<html><head><style></style></head><body><div>PortalPreview</div></body></html>'
});

await page.goto('/');
const section = await page.getByTestId('portal');
await section.getByRole('button', {name: 'Customize'}).click();
await page.waitForSelector('[data-testid="portal-modal"]');
const modal = await page.getByTestId('portal-modal');

// In Portal settings, the free tier is hidden because the site is set to paid-members only, even if available in the tiers list
const freeTierCheckbox = await modal.getByTestId('free-tier-checkbox');
expect(freeTierCheckbox).not.toBeVisible();
});

test('can toggle portal Look & Feel options', async ({page}) => {
const {lastApiRequests} = await mockApi({page, requests: {
...globalDataRequests,
Expand Down

0 comments on commit bf428d0

Please sign in to comment.