0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Added offers support in default recipients

This commit is contained in:
Jono Mingard 2023-06-13 16:45:35 +12:00
parent 731858e9e0
commit 778e9a5f96
3 changed files with 60 additions and 12 deletions

View file

@ -5,7 +5,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup';
import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent';
import useSettingGroup from '../../../hooks/useSettingGroup';
import {GroupBase, MultiValue} from 'react-select';
import {Label, Tier} from '../../../types/api';
import {Label, Offer, Tier} from '../../../types/api';
import {ServicesContext} from '../../providers/ServiceProvider';
import {getOptionLabel, getSettingValues} from '../../../utils/helpers';
@ -83,6 +83,7 @@ const DefaultRecipients: React.FC = () => {
const {api} = useContext(ServicesContext);
const [tiers, setTiers] = useState<Tier[]>([]);
const [labels, setLabels] = useState<Label[]>([]);
const [offers, setOffers] = useState<Offer[]>([]);
useEffect(() => {
api.tiers.browse().then((response) => {
@ -92,6 +93,10 @@ const DefaultRecipients: React.FC = () => {
api.labels.browse().then((response) => {
setLabels(response.labels);
});
api.offers.browse().then((response) => {
setOffers(response.offers);
});
}, [api]);
const setDefaultRecipientValue = (value: string) => {
@ -123,19 +128,26 @@ const DefaultRecipients: React.FC = () => {
},
{
label: 'Active Tiers',
options: tiers.map(tier => ({value: tier.id, label: tier.name, color: 'black'}))
options: tiers.filter(({active}) => active).map(tier => ({value: tier.id, label: tier.name, color: 'black'}))
},
{
label: 'Archived Tiers',
options: tiers.filter(({active}) => !active).map(tier => ({value: tier.id, label: tier.name, color: 'black'}))
},
{
label: 'Labels',
options: labels.map(label => ({value: `label:${label.slug}`, label: label.name, color: 'grey'}))
},
{
label: 'Offers',
options: offers.map(offer => ({value: `offer_redemptions:${offer.id}`, label: offer.name, color: 'black'}))
}
];
const segmentOptions = segmentOptionGroups.flatMap(({options}) => options);
const defaultSelectedSegments = (defaultEmailRecipientsFilter?.split(',') || [])
.map(value => segmentOptions.find(option => option.value === value))
.filter((option): option is MultiSelectOption => Boolean(option));
const filters = defaultEmailRecipientsFilter?.split(',') || [];
const defaultSelectedSegments = segmentOptionGroups
.flatMap(({options}) => options)
.filter(({value}) => filters.includes(value));
const setSelectedSegments = (selected: MultiValue<MultiSelectOption>) => {
const selectedGroups = selected?.map(({value}) => value).join(',');
@ -168,7 +180,7 @@ const DefaultRecipients: React.FC = () => {
{(selectedOption === 'segment') && (
<MultiSelect
defaultValues={defaultSelectedSegments}
options={segmentOptionGroups}
options={segmentOptionGroups.filter(group => group.options.length > 0)}
title='Select tiers'
clearBg
onChange={setSelectedSegments}

View file

@ -66,7 +66,7 @@ export type Tier = {
name: string;
description: string | null;
slug: string;
active: true,
active: boolean,
type: string;
welcome_page_url: string | null;
created_at: string;
@ -87,6 +87,27 @@ export type Label = {
updated_at: string;
}
export type Offer = {
id: string;
name: string;
code: string;
display_title: string;
display_description: string;
type: string;
cadence: string;
amount: number;
duration: string;
duration_in_months: number | null;
currency_restriction: boolean;
currency: string | null;
status: string;
redemption_count: number;
tier: {
id: string;
name: string;
}
}
type CustomThemeSettingData =
{ type: 'text', value: string | null, default: string | null } |
{ type: 'color', value: string, default: string } |

View file

@ -1,4 +1,4 @@
import {CustomThemeSetting, Label, Post, Setting, SiteData, Tier, User, UserRole} from '../types/api';
import {CustomThemeSetting, Label, Offer, Post, Setting, SiteData, Tier, User, UserRole} from '../types/api';
import {getGhostPaths} from './helpers';
interface Meta {
@ -68,6 +68,11 @@ export interface LabelsResponseType {
labels: Label[]
}
export interface OffersResponseType {
meta?: Meta
offers: Offer[]
}
export interface SiteResponseType {
site: SiteData;
}
@ -151,7 +156,10 @@ interface API {
};
labels: {
browse: () => Promise<LabelsResponseType>
}
};
offers: {
browse: () => Promise<OffersResponseType>
};
}
interface GhostApiOptions {
@ -367,10 +375,17 @@ function setupGhostApi({ghostVersion}: GhostApiOptions): API {
},
labels: {
browse: async () => {
const response = await fetcher(`/labels/?limit=all`);
const response = await fetcher('/labels/?limit=all');
const data: LabelsResponseType = await response.json();
return data;
}
},
offers: {
browse: async () => {
const response = await fetcher('/offers/?limit=all');
const data: OffersResponseType = await response.json();
return data;
}
}
};