mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-15 03:01:37 -05:00
Wired archived and active tiers list in adminX (#17300)
refs https://github.com/TryGhost/Product/issues/3580
This commit is contained in:
parent
49f6477ad5
commit
36b23b49a9
9 changed files with 78 additions and 40 deletions
|
@ -7,7 +7,7 @@ import useSettingGroup from '../../../hooks/useSettingGroup';
|
|||
import {GroupBase, MultiValue} from 'react-select';
|
||||
import {Label, Offer, Tier} from '../../../types/api';
|
||||
import {ServicesContext} from '../../providers/ServiceProvider';
|
||||
import {getOptionLabel, getSettingValues} from '../../../utils/helpers';
|
||||
import {getOptionLabel, getPaidActiveTiers, getSettingValues} from '../../../utils/helpers';
|
||||
|
||||
type RefipientValueArgs = {
|
||||
defaultEmailRecipients: string;
|
||||
|
@ -87,7 +87,7 @@ const DefaultRecipients: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||
|
||||
useEffect(() => {
|
||||
api.tiers.browse().then((response) => {
|
||||
setTiers(response.tiers);
|
||||
setTiers(getPaidActiveTiers(response.tiers));
|
||||
});
|
||||
|
||||
api.labels.browse().then((response) => {
|
||||
|
|
|
@ -7,7 +7,7 @@ import useSettingGroup from '../../../hooks/useSettingGroup';
|
|||
import {GroupBase, MultiValue} from 'react-select';
|
||||
import {ServicesContext} from '../../providers/ServiceProvider';
|
||||
import {Tier} from '../../../types/api';
|
||||
import {getOptionLabel, getSettingValues} from '../../../utils/helpers';
|
||||
import {getOptionLabel, getPaidActiveTiers, getSettingValues} from '../../../utils/helpers';
|
||||
|
||||
const MEMBERS_SIGNUP_ACCESS_OPTIONS = [
|
||||
{value: 'all', label: 'Anyone can sign up'},
|
||||
|
@ -52,7 +52,7 @@ const Access: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||
|
||||
useEffect(() => {
|
||||
api.tiers.browse().then((response) => {
|
||||
setTiers(response.tiers);
|
||||
setTiers(getPaidActiveTiers(response.tiers));
|
||||
});
|
||||
}, [api]);
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup';
|
|||
import TabView from '../../../admin-x-ds/global/TabView';
|
||||
import TiersList from './tiers/TiersList';
|
||||
import useRouting from '../../../hooks/useRouting';
|
||||
import {getArchivedTiers, getPaidActiveTiers} from '../../../utils/helpers';
|
||||
import {useTiers} from '../../providers/ServiceProvider';
|
||||
|
||||
const Tiers: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||
const {updateRoute} = useRouting();
|
||||
|
@ -11,6 +13,9 @@ const Tiers: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||
updateRoute('tiers/add');
|
||||
};
|
||||
const [selectedTab, setSelectedTab] = useState('active-tiers');
|
||||
const {data: tiers, update: updateTiers} = useTiers();
|
||||
const activeTiers = getPaidActiveTiers(tiers);
|
||||
const archivedTiers = getArchivedTiers(tiers);
|
||||
|
||||
const buttons = (
|
||||
<Button color='green' label='Add tier' link={true} onClick={() => {
|
||||
|
@ -22,12 +27,12 @@ const Tiers: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||
{
|
||||
id: 'active-tiers',
|
||||
title: 'Active',
|
||||
contents: (<TiersList tab='active-tiers' />)
|
||||
contents: (<TiersList tab='active-tiers' tiers={activeTiers} updateTiers={updateTiers} />)
|
||||
},
|
||||
{
|
||||
id: 'archived-tiers',
|
||||
title: 'Archived',
|
||||
contents: (<TiersList tab='archive-tiers' />)
|
||||
contents: (<TiersList tab='archive-tiers' tiers={archivedTiers} updateTiers={updateTiers} />)
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import React, {useContext, useEffect, useState} from 'react';
|
|||
import Select from '../../../../admin-x-ds/global/form/Select';
|
||||
import TextField from '../../../../admin-x-ds/global/form/TextField';
|
||||
import {SettingsContext} from '../../../providers/SettingsProvider';
|
||||
import {getHomepageUrl} from '../../../../utils/helpers';
|
||||
import {getHomepageUrl, getPaidActiveTiers} from '../../../../utils/helpers';
|
||||
import {useTiers} from '../../../providers/ServiceProvider';
|
||||
|
||||
interface PortalLinkPrefs {
|
||||
|
@ -40,7 +40,8 @@ const PortalLinks: React.FC = () => {
|
|||
const [isDataAttributes, setIsDataAttributes] = useState(false);
|
||||
const [selectedTier, setSelectedTier] = useState('');
|
||||
const {siteData} = useContext(SettingsContext);
|
||||
const {data: tiers} = useTiers();
|
||||
const {data: allTiers} = useTiers();
|
||||
const tiers = getPaidActiveTiers(allTiers);
|
||||
|
||||
const toggleIsDataAttributes = () => {
|
||||
setIsDataAttributes(!isDataAttributes);
|
||||
|
|
|
@ -11,7 +11,7 @@ import useRouting from '../../../../hooks/useRouting';
|
|||
import {PreviewModalContent} from '../../../../admin-x-ds/global/modal/PreviewModal';
|
||||
import {Setting, SettingValue, Tier} from '../../../../types/api';
|
||||
import {SettingsContext} from '../../../providers/SettingsProvider';
|
||||
import {fullEmailAddress} from '../../../../utils/helpers';
|
||||
import {fullEmailAddress, getPaidActiveTiers} from '../../../../utils/helpers';
|
||||
import {useTiers} from '../../../providers/ServiceProvider';
|
||||
|
||||
const Sidebar: React.FC<{
|
||||
|
@ -67,7 +67,8 @@ const PortalModal: React.FC = () => {
|
|||
const [selectedPreviewTab, setSelectedPreviewTab] = useState('signup');
|
||||
|
||||
const {settings, saveSettings, siteData} = useContext(SettingsContext);
|
||||
const {data: tiers, update: updateTiers} = useTiers();
|
||||
const {data: allTiers, update: updateTiers} = useTiers();
|
||||
const tiers = getPaidActiveTiers(allTiers);
|
||||
|
||||
const {formState, saveState, handleSave, updateForm} = useForm({
|
||||
initialState: {
|
||||
|
|
|
@ -4,40 +4,54 @@ import ListItem from '../../../../admin-x-ds/global/ListItem';
|
|||
import NiceModal from '@ebay/nice-modal-react';
|
||||
import React from 'react';
|
||||
import TierDetailModal from './TierDetailModal';
|
||||
import {Tier} from '../../../../types/api';
|
||||
|
||||
interface TiersListProps {
|
||||
tab?: string;
|
||||
tiers: Tier[];
|
||||
updateTiers: (data: Tier[]) => Promise<void>;
|
||||
}
|
||||
|
||||
const TiersList: React.FC<TiersListProps> = ({
|
||||
tab
|
||||
}) => {
|
||||
const action = tab === 'active-tiers' ? (
|
||||
<Button color='green' label='Archive' link />
|
||||
) : (
|
||||
<Button color='green' label='Activate' link />
|
||||
);
|
||||
interface TierActionsProps {
|
||||
tier: Tier;
|
||||
updateTiers: (data: Tier[]) => Promise<void>;
|
||||
}
|
||||
|
||||
const TierActions: React.FC<TierActionsProps> = ({tier, updateTiers}) => {
|
||||
if (tier.active) {
|
||||
return (
|
||||
<Button color='green' label='Archive' link onClick={() => {
|
||||
updateTiers([{...tier, active: false}]);
|
||||
}} />
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Button color='green' label='Activate' link onClick={() => {
|
||||
updateTiers([{...tier, active: true}]);
|
||||
}}/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const TiersList: React.FC<TiersListProps> = ({
|
||||
tiers,
|
||||
updateTiers
|
||||
}) => {
|
||||
return (
|
||||
<List>
|
||||
<ListItem
|
||||
action={action}
|
||||
detail='Yet another tier'
|
||||
title='Dummy tier one'
|
||||
hideActions
|
||||
onClick={() => {
|
||||
NiceModal.show(TierDetailModal);
|
||||
}}
|
||||
/>
|
||||
<ListItem
|
||||
action={action}
|
||||
detail='Yet another tier again'
|
||||
title='Dummy tier two'
|
||||
hideActions
|
||||
onClick={() => {
|
||||
NiceModal.show(TierDetailModal);
|
||||
}}
|
||||
/>
|
||||
{tiers.map((tier) => {
|
||||
return (
|
||||
<ListItem
|
||||
action={<TierActions tier={tier} updateTiers={updateTiers} />}
|
||||
detail={tier?.description || ''}
|
||||
title={tier?.name}
|
||||
hideActions
|
||||
onClick={() => {
|
||||
NiceModal.show(TierDetailModal);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -399,8 +399,7 @@ function setupGhostApi({ghostVersion}: GhostApiOptions): API {
|
|||
},
|
||||
tiers: {
|
||||
browse: async () => {
|
||||
const filter = encodeURIComponent('type:paid+active:true');
|
||||
const response = await fetcher(`/tiers/?filter=${filter}&limit=all`);
|
||||
const response = await fetcher(`/tiers/?limit=all`);
|
||||
const data: TiersResponseType = await response.json();
|
||||
return data;
|
||||
},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Config, Setting, SettingValue, SiteData, User} from '../types/api';
|
||||
import {Config, Setting, SettingValue, SiteData, Tier, User} from '../types/api';
|
||||
|
||||
export interface IGhostPaths {
|
||||
adminRoot: string;
|
||||
|
@ -125,3 +125,21 @@ export function checkStripeEnabled(settings: Setting[], config: Config) {
|
|||
|
||||
return hasConnectKeys || hasDirectKeys;
|
||||
}
|
||||
|
||||
export function getPaidActiveTiers(tiers: Tier[]) {
|
||||
return tiers.filter((tier) => {
|
||||
return tier.type === 'paid' && tier.active;
|
||||
});
|
||||
}
|
||||
|
||||
export function getActiveTiers(tiers: Tier[]) {
|
||||
return tiers.filter((tier) => {
|
||||
return tier.active;
|
||||
});
|
||||
}
|
||||
|
||||
export function getArchivedTiers(tiers: Tier[]) {
|
||||
return tiers.filter((tier) => {
|
||||
return !tier.active;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -386,7 +386,7 @@ export async function mockApi({page,responses}: {page: Page, responses?: Respons
|
|||
|
||||
await mockApiResponse({
|
||||
page,
|
||||
path: /\/ghost\/api\/admin\/tiers\/\?filter=/,
|
||||
path: /\/ghost\/api\/admin\/tiers\//,
|
||||
respondTo: {
|
||||
GET: {
|
||||
body: responses?.tiers?.browse ?? responseFixtures.tiers,
|
||||
|
|
Loading…
Add table
Reference in a new issue