diff --git a/apps/admin-x-settings/src/App.tsx b/apps/admin-x-settings/src/App.tsx index a990938398..2d4ab477e1 100644 --- a/apps/admin-x-settings/src/App.tsx +++ b/apps/admin-x-settings/src/App.tsx @@ -6,9 +6,8 @@ import RoutingProvider from './components/providers/RoutingProvider'; import Settings from './components/Settings'; import Sidebar from './components/Sidebar'; import {GlobalDirtyStateProvider} from './hooks/useGlobalDirtyState'; -import {OfficialTheme} from './models/themes'; +import {OfficialTheme, ServicesProvider} from './components/providers/ServiceProvider'; import {QueryClient, QueryClientProvider} from '@tanstack/react-query'; -import {ServicesProvider} from './components/providers/ServiceProvider'; import {Toaster} from 'react-hot-toast'; interface AppProps { diff --git a/apps/admin-x-settings/src/api/config.ts b/apps/admin-x-settings/src/api/config.ts new file mode 100644 index 0000000000..260c2f3670 --- /dev/null +++ b/apps/admin-x-settings/src/api/config.ts @@ -0,0 +1,30 @@ +import {createQuery} from '../utils/apiRequests'; + +export type JSONValue = string|number|boolean|null|Date|JSONObject|JSONArray; +export interface JSONObject { [key: string]: JSONValue } +export interface JSONArray extends Array {} + +export type Config = { + version: string; + environment: string; + editor: { + url: string + version: string + }; + labs: Record; + stripeDirect: boolean; + + // Config is relatively fluid, so we only type used properties above and still support arbitrary property access when needed + [key: string]: JSONValue; +}; + +export interface ConfigResponseType { + config: Config; +} + +const dataType = 'ConfigResponseType'; + +export const useBrowseConfig = createQuery({ + dataType, + path: '/config/' +}); diff --git a/apps/admin-x-settings/src/api/customThemeSettings.ts b/apps/admin-x-settings/src/api/customThemeSettings.ts new file mode 100644 index 0000000000..ee030207e8 --- /dev/null +++ b/apps/admin-x-settings/src/api/customThemeSettings.ts @@ -0,0 +1,44 @@ +import {Setting} from './settings'; +import {createMutation, createQuery} from '../utils/apiRequests'; + +type CustomThemeSettingData = + { type: 'text', value: string | null, default: string | null } | + { type: 'color', value: string, default: string } | + { type: 'image', value: string | null } | + { type: 'boolean', value: boolean, default: boolean } | + { + type: 'select', + value: string + default: string + options: string[] + }; + +export type CustomThemeSetting = CustomThemeSettingData & { + id: string + key: string + description?: string + // homepage and post are the only two groups we handle, but technically theme authors can put other things in package.json + group?: 'homepage' | 'post' | string +} + +export interface CustomThemeSettingsResponseType { + custom_theme_settings: CustomThemeSetting[]; +} + +const dataType = 'CustomThemeSettingsResponseType'; + +export const useBrowseCustomThemeSettings = createQuery({ + dataType, + path: '/custom_theme_settings/' +}); + +export const useEditCustomThemeSettings = createMutation({ + method: 'PUT', + path: () => '/custom_theme_settings/', + body: settings => ({custom_theme_settings: settings}), + + updateQueries: { + dataType, + update: newData => newData + } +}); diff --git a/apps/admin-x-settings/src/utils/api/images.ts b/apps/admin-x-settings/src/api/images.ts similarity index 90% rename from apps/admin-x-settings/src/utils/api/images.ts rename to apps/admin-x-settings/src/api/images.ts index 03a28e5503..123bac00d1 100644 --- a/apps/admin-x-settings/src/utils/api/images.ts +++ b/apps/admin-x-settings/src/api/images.ts @@ -1,4 +1,4 @@ -import {createMutation} from '../apiRequests'; +import {createMutation} from '../utils/apiRequests'; export interface ImagesResponseType { images: { diff --git a/apps/admin-x-settings/src/utils/api/invites.ts b/apps/admin-x-settings/src/api/invites.ts similarity index 95% rename from apps/admin-x-settings/src/utils/api/invites.ts rename to apps/admin-x-settings/src/api/invites.ts index d6f7a563d9..4f4e185e3a 100644 --- a/apps/admin-x-settings/src/utils/api/invites.ts +++ b/apps/admin-x-settings/src/api/invites.ts @@ -1,4 +1,4 @@ -import {Meta, createMutation, createQuery} from '../apiRequests'; +import {Meta, createMutation, createQuery} from '../utils/apiRequests'; export interface UserInvite { created_at: string; diff --git a/apps/admin-x-settings/src/utils/api/labels.ts b/apps/admin-x-settings/src/api/labels.ts similarity index 59% rename from apps/admin-x-settings/src/utils/api/labels.ts rename to apps/admin-x-settings/src/api/labels.ts index 8bb0d07013..33af5af02c 100644 --- a/apps/admin-x-settings/src/utils/api/labels.ts +++ b/apps/admin-x-settings/src/api/labels.ts @@ -1,5 +1,12 @@ -import {Label} from '../../types/api'; -import {Meta, createQuery} from '../apiRequests'; +import {Meta, createQuery} from '../utils/apiRequests'; + +export type Label = { + id: string; + name: string; + slug: string; + created_at: string; + updated_at: string; +} export interface LabelsResponseType { meta?: Meta diff --git a/apps/admin-x-settings/src/utils/api/members.ts b/apps/admin-x-settings/src/api/members.ts similarity index 69% rename from apps/admin-x-settings/src/utils/api/members.ts rename to apps/admin-x-settings/src/api/members.ts index 0bb12e13a5..78168a64c9 100644 --- a/apps/admin-x-settings/src/utils/api/members.ts +++ b/apps/admin-x-settings/src/api/members.ts @@ -1,5 +1,8 @@ -import {Member} from '../../types/api'; -import {Meta, createQuery} from '../apiRequests'; +import {Meta, createQuery} from '../utils/apiRequests'; + +export type Member = { + id: string; +}; export interface MembersResponseType { meta?: Meta diff --git a/apps/admin-x-settings/src/utils/api/newsletters.ts b/apps/admin-x-settings/src/api/newsletters.ts similarity index 63% rename from apps/admin-x-settings/src/utils/api/newsletters.ts rename to apps/admin-x-settings/src/api/newsletters.ts index 323c972892..b8a467b237 100644 --- a/apps/admin-x-settings/src/utils/api/newsletters.ts +++ b/apps/admin-x-settings/src/api/newsletters.ts @@ -1,5 +1,43 @@ -import {Meta, createMutation, createQuery} from '../apiRequests'; -import {Newsletter} from '../../types/api'; +import {Meta, createMutation, createQuery} from '../utils/apiRequests'; + +export type Newsletter = { + id: string; + uuid: string; + name: string; + description: string | null; + feedback_enabled: boolean; + slug: string; + sender_name: string | null; + sender_email: string | null; + sender_reply_to: string; + status: string; + visibility: string; + subscribe_on_signup: boolean; + sort_order: number; + header_image: string | null; + show_header_icon: boolean; + show_header_title: boolean; + title_font_category: string; + title_alignment: string; + show_feature_image: boolean; + body_font_category: string; + footer_content: string | null; + show_badge: boolean; + show_header_name: boolean; + show_post_title_section: boolean; + show_comment_cta: boolean; + show_subscription_details: boolean; + show_latest_posts: boolean; + background_color: string; + border_color: string | null; + title_color: string | null; + created_at: string; + updated_at: string; + count?: { + posts?: number; + active_members?: number; + } +} export interface NewslettersResponseType { meta?: Meta diff --git a/apps/admin-x-settings/src/api/offers.ts b/apps/admin-x-settings/src/api/offers.ts new file mode 100644 index 0000000000..fc470895f5 --- /dev/null +++ b/apps/admin-x-settings/src/api/offers.ts @@ -0,0 +1,35 @@ +import {Meta, createQuery} from '../utils/apiRequests'; + +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; + } +} + +export interface OffersResponseType { + meta?: Meta + offers: Offer[] +} + +const dataType = 'OffersResponseType'; + +export const useBrowseOffers = createQuery({ + dataType, + path: '/offers/', + defaultSearchParams: {limit: 'all'} +}); diff --git a/apps/admin-x-settings/src/utils/api/posts.ts b/apps/admin-x-settings/src/api/posts.ts similarity index 65% rename from apps/admin-x-settings/src/utils/api/posts.ts rename to apps/admin-x-settings/src/api/posts.ts index 7d9c46a5b6..d91485b712 100644 --- a/apps/admin-x-settings/src/utils/api/posts.ts +++ b/apps/admin-x-settings/src/api/posts.ts @@ -1,5 +1,9 @@ -import {Meta, createQuery} from '../apiRequests'; -import {Post} from '../../types/api'; +import {Meta, createQuery} from '../utils/apiRequests'; + +export type Post = { + id: string; + url: string; +}; export interface PostsResponseType { meta?: Meta diff --git a/apps/admin-x-settings/src/api/roles.ts b/apps/admin-x-settings/src/api/roles.ts new file mode 100644 index 0000000000..fed26242ce --- /dev/null +++ b/apps/admin-x-settings/src/api/roles.ts @@ -0,0 +1,24 @@ +import {Meta, createQuery} from '../utils/apiRequests'; + +export type UserRoleType = 'Owner' | 'Administrator' | 'Editor' | 'Author' | 'Contributor'; + +export type UserRole = { + id: string; + name: UserRoleType; + description: string; + created_at: string; + updated_at: string; +}; + +export interface RolesResponseType { + meta?: Meta; + roles: UserRole[]; +} + +const dataType = 'RolesResponseType'; + +export const useBrowseRoles = createQuery({ + dataType, + path: '/roles/', + defaultSearchParams: {limit: 'all'} +}); diff --git a/apps/admin-x-settings/src/api/settings.ts b/apps/admin-x-settings/src/api/settings.ts new file mode 100644 index 0000000000..bcb736b824 --- /dev/null +++ b/apps/admin-x-settings/src/api/settings.ts @@ -0,0 +1,85 @@ +import {Config} from './config'; +import {Meta, createMutation, createQuery} from '../utils/apiRequests'; + +// Types + +export type SettingValue = string | boolean | null; + +export type Setting = { + key: string; + value: SettingValue; +} + +export type SettingsResponseMeta = Meta & { sent_email_verification?: boolean } + +export interface SettingsResponseType { + meta?: SettingsResponseMeta; + settings: Setting[]; +} + +// Requests + +const dataType = 'SettingsResponseType'; + +export const useBrowseSettings = createQuery({ + dataType, + path: '/settings/', + defaultSearchParams: { + group: 'site,theme,private,members,portal,newsletter,email,amp,labs,slack,unsplash,views,firstpromoter,editor,comments,analytics,announcement,pintura' + } +}); + +export const useEditSettings = createMutation({ + method: 'PUT', + path: () => '/settings/', + body: settings => ({settings: settings.map(({key, value}) => ({key, value}))}), + updateQueries: { + dataType, + update: newData => ({ + ...newData, + settings: newData.settings + }) + } +}); + +export const useDeleteStripeSettings = createMutation({ + method: 'DELETE', + path: () => '/settings/stripe/connect/', + invalidateQueries: {dataType} +}); + +// Helpers + +export function humanizeSettingKey(key: string) { + const allCaps = ['API', 'CTA', 'RSS']; + + return key + .replace(/^[a-z]/, char => char.toUpperCase()) + .replace(/_/g, ' ') + .replace(new RegExp(`\\b(${allCaps.join('|')})\\b`, 'ig'), match => match.toUpperCase()); +} + +export function getSettingValues(settings: Setting[] | null, keys: string[]): Array { + return keys.map(key => settings?.find(setting => setting.key === key)?.value) as ValueType[]; +} + +export function getSettingValue(settings: Setting[] | null | undefined, key: string): SettingValue { + if (!settings) { + return ''; + } + const setting = settings.find(d => d.key === key); + return setting?.value || null; +} + +export function checkStripeEnabled(settings: Setting[], config: Config) { + const hasSetting = (key: string) => settings.some(setting => setting.key === key && setting.value); + + const hasDirectKeys = hasSetting('stripe_secret_key') && hasSetting('stripe_publishable_key'); + const hasConnectKeys = hasSetting('stripe_connect_secret_key') && hasSetting('stripe_connect_publishable_key'); + + if (config.stripeDirect) { + return hasDirectKeys; + } + + return hasConnectKeys || hasDirectKeys; +} diff --git a/apps/admin-x-settings/src/api/site.ts b/apps/admin-x-settings/src/api/site.ts new file mode 100644 index 0000000000..fdcc0f57af --- /dev/null +++ b/apps/admin-x-settings/src/api/site.ts @@ -0,0 +1,49 @@ +import {createQuery} from '../utils/apiRequests'; + +// Types + +export type SiteData = { + title: string; + description: string; + logo: string; + icon: string; + accent_color: string; + url: string; + locale: string; + version: string; +}; + +export interface SiteResponseType { + site: SiteData; +} + +// Requests + +const dataType = 'SiteResponseType'; + +export const useBrowseSite = createQuery({ + dataType, + path: '/site/' +}); + +// Helpers + +export function getHomepageUrl(siteData: SiteData): string { + const url = new URL(siteData.url); + const subdir = url.pathname.endsWith('/') ? url.pathname : `${url.pathname}/`; + + return `${url.origin}${subdir}`; +} + +export function getEmailDomain(siteData: SiteData): string { + const domain = new URL(siteData.url).hostname || ''; + if (domain.startsWith('www.')) { + return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, ''); + } + return domain; +} + +export function fullEmailAddress(value: 'noreply' | string, siteData: SiteData) { + const emailDomain = getEmailDomain(siteData); + return value === 'noreply' ? `noreply@${emailDomain}` : value; +} diff --git a/apps/admin-x-settings/src/utils/api/themes.ts b/apps/admin-x-settings/src/api/themes.ts similarity index 72% rename from apps/admin-x-settings/src/utils/api/themes.ts rename to apps/admin-x-settings/src/api/themes.ts index f3bfb5bde2..e2b7d0cd2a 100644 --- a/apps/admin-x-settings/src/utils/api/themes.ts +++ b/apps/admin-x-settings/src/api/themes.ts @@ -1,5 +1,35 @@ -import {InstalledTheme, Theme} from '../../types/api'; -import {createMutation, createQuery} from '../apiRequests'; +import {createMutation, createQuery} from '../utils/apiRequests'; + +// Types + +export type Theme = { + active: boolean; + name: string; + package: { + name?: string; + description?: string; + version?: string; + }; + templates?: string[]; +} + +export type InstalledTheme = Theme & { + errors?: ThemeProblem<'error'>[]; + warnings?: ThemeProblem<'warning'>[]; +} + +export type ThemeProblem = { + code: string + details: string + failures: Array<{ + ref: string + message?: string + rule?: string + }> + fatal: boolean + level: Level + rule: string +} export interface ThemesResponseType { themes: Theme[]; @@ -9,6 +39,8 @@ export interface ThemesInstallResponseType { themes: InstalledTheme[]; } +// Requests + const dataType = 'ThemesResponseType'; export const useBrowseThemes = createQuery({ @@ -85,3 +117,17 @@ export const useUploadTheme = createMutation({ @@ -39,3 +60,23 @@ export const useEditTier = createMutation({ }) } }); + +// Helpers + +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; + }); +} diff --git a/apps/admin-x-settings/src/utils/api/users.ts b/apps/admin-x-settings/src/api/users.ts similarity index 68% rename from apps/admin-x-settings/src/utils/api/users.ts rename to apps/admin-x-settings/src/api/users.ts index a5ca7c889e..dcf078e192 100644 --- a/apps/admin-x-settings/src/utils/api/users.ts +++ b/apps/admin-x-settings/src/api/users.ts @@ -1,5 +1,37 @@ -import {Meta, createMutation, createQuery} from '../apiRequests'; -import {User} from '../../types/api'; +import {Meta, createMutation, createQuery} from '../utils/apiRequests'; +import {UserRole} from './roles'; + +// Types + +export type User = { + id: string; + name: string; + slug: string; + email: string; + profile_image: string; + cover_image: string|null; + bio: string; + website: string; + location: string; + facebook: string; + twitter: string; + accessibility: string|null; + status: string; + meta_title: string|null; + meta_description: string|null; + tour: string|null; + last_seen: string|null; + created_at: string; + updated_at: string; + comment_notifications: boolean; + free_member_signup_notification: boolean; + paid_subscription_canceled_notification: boolean; + paid_subscription_started_notification: boolean; + mention_notifications: boolean; + milestone_notifications: boolean; + roles: UserRole[]; + url: string; +} export interface UsersResponseType { meta?: Meta; @@ -25,6 +57,8 @@ export interface DeleteUserResponse { } } +// Requests + const dataType = 'UsersResponseType'; const updateUsers = (newData: UsersResponseType, currentData: unknown) => ({ @@ -95,3 +129,13 @@ export const useMakeOwner = createMutation({ update: updateUsers } }); + +// Helpers + +export function isOwnerUser(user: User) { + return user.roles.some(role => role.name === 'Owner'); +} + +export function isAdminUser(user: User) { + return user.roles.some(role => role.name === 'Administrator'); +} diff --git a/apps/admin-x-settings/src/components/Sidebar.tsx b/apps/admin-x-settings/src/components/Sidebar.tsx index 2a4de2d009..a6db260297 100644 --- a/apps/admin-x-settings/src/components/Sidebar.tsx +++ b/apps/admin-x-settings/src/components/Sidebar.tsx @@ -4,7 +4,7 @@ import SettingNavItem from '../admin-x-ds/settings/SettingNavItem'; import SettingNavSection from '../admin-x-ds/settings/SettingNavSection'; import TextField from '../admin-x-ds/global/form/TextField'; import useRouting from '../hooks/useRouting'; -import {getSettingValues} from '../utils/helpers'; +import {getSettingValues} from '../api/settings'; import {useGlobalData} from './providers/GlobalDataProvider'; import {useSearch} from './providers/ServiceProvider'; diff --git a/apps/admin-x-settings/src/components/providers/GlobalDataProvider.tsx b/apps/admin-x-settings/src/components/providers/GlobalDataProvider.tsx index e70ca6b3c6..4111d2f625 100644 --- a/apps/admin-x-settings/src/components/providers/GlobalDataProvider.tsx +++ b/apps/admin-x-settings/src/components/providers/GlobalDataProvider.tsx @@ -1,9 +1,8 @@ -import {Config, Setting, SiteData, User} from '../../types/api'; +import {Config, useBrowseConfig} from '../../api/config'; import {ReactNode, createContext, useContext} from 'react'; -import {useBrowseConfig} from '../../utils/api/config'; -import {useBrowseSettings} from '../../utils/api/settings'; -import {useBrowseSite} from '../../utils/api/site'; -import {useCurrentUser} from '../../utils/api/users'; +import {Setting, useBrowseSettings} from '../../api/settings'; +import {SiteData, useBrowseSite} from '../../api/site'; +import {User, useCurrentUser} from '../../api/users'; interface GlobalData { settings: Setting[] diff --git a/apps/admin-x-settings/src/components/providers/ServiceProvider.tsx b/apps/admin-x-settings/src/components/providers/ServiceProvider.tsx index 1c29c0b703..59674f0638 100644 --- a/apps/admin-x-settings/src/components/providers/ServiceProvider.tsx +++ b/apps/admin-x-settings/src/components/providers/ServiceProvider.tsx @@ -1,6 +1,14 @@ import React, {createContext, useContext} from 'react'; import useSearchService, {SearchService} from '../../utils/search'; -import {OfficialTheme} from '../../models/themes'; + +export type OfficialTheme = { + name: string; + category: string; + previewUrl: string; + ref: string; + image: string; + url?: string; +}; interface ServicesContextProps { ghostVersion: string diff --git a/apps/admin-x-settings/src/components/settings/advanced/CodeInjection.tsx b/apps/admin-x-settings/src/components/settings/advanced/CodeInjection.tsx index b09f179be2..daa04575c6 100644 --- a/apps/admin-x-settings/src/components/settings/advanced/CodeInjection.tsx +++ b/apps/admin-x-settings/src/components/settings/advanced/CodeInjection.tsx @@ -7,7 +7,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import TabView from '../../../admin-x-ds/global/TabView'; import useSettingGroup from '../../../hooks/useSettingGroup'; import {ReactCodeMirrorRef} from '@uiw/react-codemirror'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; import {html} from '@codemirror/lang-html'; const CodeInjection: React.FC<{ keywords: string[] }> = ({keywords}) => { diff --git a/apps/admin-x-settings/src/components/settings/email/DefaultRecipients.tsx b/apps/admin-x-settings/src/components/settings/email/DefaultRecipients.tsx index afea9758b8..d57bf729d7 100644 --- a/apps/admin-x-settings/src/components/settings/email/DefaultRecipients.tsx +++ b/apps/admin-x-settings/src/components/settings/email/DefaultRecipients.tsx @@ -5,10 +5,11 @@ 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 {getOptionLabel, getSettingValues} from '../../../utils/helpers'; -import {useBrowseLabels} from '../../../utils/api/labels'; -import {useBrowseOffers} from '../../../utils/api/offers'; -import {useBrowseTiers} from '../../../utils/api/tiers'; +import {getOptionLabel} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; +import {useBrowseLabels} from '../../../api/labels'; +import {useBrowseOffers} from '../../../api/offers'; +import {useBrowseTiers} from '../../../api/tiers'; type RefipientValueArgs = { defaultEmailRecipients: string; diff --git a/apps/admin-x-settings/src/components/settings/email/EmailSettings.tsx b/apps/admin-x-settings/src/components/settings/email/EmailSettings.tsx index fabc332e0a..758ffffac2 100644 --- a/apps/admin-x-settings/src/components/settings/email/EmailSettings.tsx +++ b/apps/admin-x-settings/src/components/settings/email/EmailSettings.tsx @@ -4,7 +4,7 @@ import MailGun from './Mailgun'; import Newsletters from './Newsletters'; import React from 'react'; import SettingSection from '../../../admin-x-ds/settings/SettingSection'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; import {useGlobalData} from '../../providers/GlobalDataProvider'; const searchKeywords = { diff --git a/apps/admin-x-settings/src/components/settings/email/EnableNewsletters.tsx b/apps/admin-x-settings/src/components/settings/email/EnableNewsletters.tsx index 78af3e7288..d04adb2543 100644 --- a/apps/admin-x-settings/src/components/settings/email/EnableNewsletters.tsx +++ b/apps/admin-x-settings/src/components/settings/email/EnableNewsletters.tsx @@ -3,9 +3,7 @@ import React from 'react'; import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import Toggle from '../../../admin-x-ds/global/form/Toggle'; -import {Setting} from '../../../types/api'; -import {getSettingValues} from '../../../utils/helpers'; -import {useEditSettings} from '../../../utils/api/settings'; +import {Setting, getSettingValues, useEditSettings} from '../../../api/settings'; import {useGlobalData} from '../../providers/GlobalDataProvider'; const EnableNewsletters: React.FC<{ keywords: string[] }> = ({keywords}) => { diff --git a/apps/admin-x-settings/src/components/settings/email/Mailgun.tsx b/apps/admin-x-settings/src/components/settings/email/Mailgun.tsx index 27839deecc..95450cd198 100644 --- a/apps/admin-x-settings/src/components/settings/email/Mailgun.tsx +++ b/apps/admin-x-settings/src/components/settings/email/Mailgun.tsx @@ -6,7 +6,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; const MAILGUN_REGIONS = [ {label: '🇺🇸 US', value: 'https://api.mailgun.net/v3'}, diff --git a/apps/admin-x-settings/src/components/settings/email/Newsletters.tsx b/apps/admin-x-settings/src/components/settings/email/Newsletters.tsx index 938732c8f6..d1e6d2658d 100644 --- a/apps/admin-x-settings/src/components/settings/email/Newsletters.tsx +++ b/apps/admin-x-settings/src/components/settings/email/Newsletters.tsx @@ -4,7 +4,7 @@ import React, {useState} from 'react'; import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import TabView from '../../../admin-x-ds/global/TabView'; import useRouting from '../../../hooks/useRouting'; -import {useBrowseNewsletters} from '../../../utils/api/newsletters'; +import {useBrowseNewsletters} from '../../../api/newsletters'; const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => { const {updateRoute} = useRouting(); diff --git a/apps/admin-x-settings/src/components/settings/email/newsletters/AddNewsletterModal.tsx b/apps/admin-x-settings/src/components/settings/email/newsletters/AddNewsletterModal.tsx index 9de7946e98..f4bd9199e9 100644 --- a/apps/admin-x-settings/src/components/settings/email/newsletters/AddNewsletterModal.tsx +++ b/apps/admin-x-settings/src/components/settings/email/newsletters/AddNewsletterModal.tsx @@ -10,8 +10,8 @@ import useForm from '../../../../hooks/useForm'; import useRouting from '../../../../hooks/useRouting'; import {showToast} from '../../../../admin-x-ds/global/Toast'; import {toast} from 'react-hot-toast'; -import {useAddNewsletter} from '../../../../utils/api/newsletters'; -import {useBrowseMembers} from '../../../../utils/api/members'; +import {useAddNewsletter} from '../../../../api/newsletters'; +import {useBrowseMembers} from '../../../../api/members'; interface AddNewsletterModalProps {} diff --git a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx index e90de24ebe..26b8d3ddef 100644 --- a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx +++ b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModal.tsx @@ -18,13 +18,13 @@ import Toggle from '../../../../admin-x-ds/global/form/Toggle'; import ToggleGroup from '../../../../admin-x-ds/global/form/ToggleGroup'; import useForm from '../../../../hooks/useForm'; import validator from 'validator'; -import {Newsletter} from '../../../../types/api'; +import {Newsletter, useEditNewsletter} from '../../../../api/newsletters'; import {PreviewModalContent} from '../../../../admin-x-ds/global/modal/PreviewModal'; -import {fullEmailAddress, getSettingValues} from '../../../../utils/helpers'; -import {getImageUrl, useUploadImage} from '../../../../utils/api/images'; +import {fullEmailAddress} from '../../../../api/site'; +import {getImageUrl, useUploadImage} from '../../../../api/images'; +import {getSettingValues} from '../../../../api/settings'; import {showToast} from '../../../../admin-x-ds/global/Toast'; import {toast} from 'react-hot-toast'; -import {useEditNewsletter} from '../../../../utils/api/newsletters'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; interface NewsletterDetailModalProps { diff --git a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterPreview.tsx b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterPreview.tsx index 4297e024bc..0299171547 100644 --- a/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterPreview.tsx +++ b/apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterPreview.tsx @@ -6,8 +6,9 @@ import LatestPosts3 from '../../../../assets/images/latest-posts-3.png'; import React from 'react'; import clsx from 'clsx'; import {ReactComponent as GhostOrb} from '../../../../admin-x-ds/assets/images/ghost-orb.svg'; -import {Newsletter} from '../../../../types/api'; -import {fullEmailAddress, getSettingValues} from '../../../../utils/helpers'; +import {Newsletter} from '../../../../api/newsletters'; +import {fullEmailAddress} from '../../../../api/site'; +import {getSettingValues} from '../../../../api/settings'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; const NewsletterPreview: React.FC<{newsletter: Newsletter}> = ({newsletter}) => { diff --git a/apps/admin-x-settings/src/components/settings/email/newsletters/NewslettersList.tsx b/apps/admin-x-settings/src/components/settings/email/newsletters/NewslettersList.tsx index a8ab640e28..c40a11b642 100644 --- a/apps/admin-x-settings/src/components/settings/email/newsletters/NewslettersList.tsx +++ b/apps/admin-x-settings/src/components/settings/email/newsletters/NewslettersList.tsx @@ -7,8 +7,7 @@ import React from 'react'; import Table from '../../../../admin-x-ds/global/Table'; import TableCell from '../../../../admin-x-ds/global/TableCell'; import TableRow from '../../../../admin-x-ds/global/TableRow'; -import {Newsletter} from '../../../../types/api'; -import {useEditNewsletter} from '../../../../utils/api/newsletters'; +import {Newsletter, useEditNewsletter} from '../../../../api/newsletters'; interface NewslettersListProps { newsletters: Newsletter[] diff --git a/apps/admin-x-settings/src/components/settings/general/Facebook.tsx b/apps/admin-x-settings/src/components/settings/general/Facebook.tsx index de2ca12ce0..25a88878c3 100644 --- a/apps/admin-x-settings/src/components/settings/general/Facebook.tsx +++ b/apps/admin-x-settings/src/components/settings/general/Facebook.tsx @@ -5,8 +5,8 @@ import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupConten import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; import {ReactComponent as FacebookLogo} from '../../../admin-x-ds/assets/images/facebook-logo.svg'; -import {getImageUrl, useUploadImage} from '../../../utils/api/images'; -import {getSettingValues} from '../../../utils/helpers'; +import {getImageUrl, useUploadImage} from '../../../api/images'; +import {getSettingValues} from '../../../api/settings'; const Facebook: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/general/InviteUserModal.tsx b/apps/admin-x-settings/src/components/settings/general/InviteUserModal.tsx index f60487bb79..e979cabea6 100644 --- a/apps/admin-x-settings/src/components/settings/general/InviteUserModal.tsx +++ b/apps/admin-x-settings/src/components/settings/general/InviteUserModal.tsx @@ -5,8 +5,8 @@ import TextField from '../../../admin-x-ds/global/form/TextField'; import useRouting from '../../../hooks/useRouting'; import validator from 'validator'; import {showToast} from '../../../admin-x-ds/global/Toast'; -import {useAddInvite} from '../../../utils/api/invites'; -import {useBrowseRoles} from '../../../utils/api/roles'; +import {useAddInvite} from '../../../api/invites'; +import {useBrowseRoles} from '../../../api/roles'; import {useEffect, useRef, useState} from 'react'; type RoleType = 'administrator' | 'editor' | 'author' | 'contributor'; diff --git a/apps/admin-x-settings/src/components/settings/general/LockSite.tsx b/apps/admin-x-settings/src/components/settings/general/LockSite.tsx index 0d751cde12..64241ec0c8 100644 --- a/apps/admin-x-settings/src/components/settings/general/LockSite.tsx +++ b/apps/admin-x-settings/src/components/settings/general/LockSite.tsx @@ -6,7 +6,7 @@ import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupConten import TextField from '../../../admin-x-ds/global/form/TextField'; import Toggle from '../../../admin-x-ds/global/form/Toggle'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; const LockSite: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/general/Metadata.tsx b/apps/admin-x-settings/src/components/settings/general/Metadata.tsx index e45e0620e9..3f63c573dc 100644 --- a/apps/admin-x-settings/src/components/settings/general/Metadata.tsx +++ b/apps/admin-x-settings/src/components/settings/general/Metadata.tsx @@ -6,7 +6,7 @@ import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; import {ReactComponent as GoogleLogo} from '../../../admin-x-ds/assets/images/google-logo.svg'; import {ReactComponent as MagnifyingGlass} from '../../../admin-x-ds/assets/icons/magnifying-glass.svg'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; interface SearchEnginePreviewProps { title: string; diff --git a/apps/admin-x-settings/src/components/settings/general/PublicationLanguage.tsx b/apps/admin-x-settings/src/components/settings/general/PublicationLanguage.tsx index 95b17ba681..17c1cdfb10 100644 --- a/apps/admin-x-settings/src/components/settings/general/PublicationLanguage.tsx +++ b/apps/admin-x-settings/src/components/settings/general/PublicationLanguage.tsx @@ -3,7 +3,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; const PublicationLanguage: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/general/SocialAccounts.tsx b/apps/admin-x-settings/src/components/settings/general/SocialAccounts.tsx index 51aed9ef6c..b38fa82d01 100644 --- a/apps/admin-x-settings/src/components/settings/general/SocialAccounts.tsx +++ b/apps/admin-x-settings/src/components/settings/general/SocialAccounts.tsx @@ -4,7 +4,7 @@ import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupConten import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; import validator from 'validator'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; function validateFacebookUrl(newUrl: string) { const errMessage = 'The URL must be in a format like https://www.facebook.com/yourPage'; diff --git a/apps/admin-x-settings/src/components/settings/general/TimeZone.tsx b/apps/admin-x-settings/src/components/settings/general/TimeZone.tsx index 0946d1ddaa..63cb25bd2d 100644 --- a/apps/admin-x-settings/src/components/settings/general/TimeZone.tsx +++ b/apps/admin-x-settings/src/components/settings/general/TimeZone.tsx @@ -4,7 +4,8 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import timezoneData from '@tryghost/timezone-data'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getLocalTime, getSettingValues} from '../../../utils/helpers'; +import {getLocalTime} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; interface TimezoneDataDropdownOption { name: string; diff --git a/apps/admin-x-settings/src/components/settings/general/TitleAndDescription.tsx b/apps/admin-x-settings/src/components/settings/general/TitleAndDescription.tsx index 009f12a199..a62e460c80 100644 --- a/apps/admin-x-settings/src/components/settings/general/TitleAndDescription.tsx +++ b/apps/admin-x-settings/src/components/settings/general/TitleAndDescription.tsx @@ -3,7 +3,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; const TitleAndDescription: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/general/Twitter.tsx b/apps/admin-x-settings/src/components/settings/general/Twitter.tsx index 2c2dba75d5..bab5fd998b 100644 --- a/apps/admin-x-settings/src/components/settings/general/Twitter.tsx +++ b/apps/admin-x-settings/src/components/settings/general/Twitter.tsx @@ -5,8 +5,8 @@ import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupConten import TextField from '../../../admin-x-ds/global/form/TextField'; import useSettingGroup from '../../../hooks/useSettingGroup'; import {ReactComponent as TwitterLogo} from '../../../admin-x-ds/assets/images/twitter-logo.svg'; -import {getImageUrl, useUploadImage} from '../../../utils/api/images'; -import {getSettingValues} from '../../../utils/helpers'; +import {getImageUrl, useUploadImage} from '../../../api/images'; +import {getSettingValues} from '../../../api/settings'; const Twitter: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/general/UserDetailModal.tsx b/apps/admin-x-settings/src/components/settings/general/UserDetailModal.tsx index 6b0e001972..735d8f740b 100644 --- a/apps/admin-x-settings/src/components/settings/general/UserDetailModal.tsx +++ b/apps/admin-x-settings/src/components/settings/general/UserDetailModal.tsx @@ -14,13 +14,11 @@ import TextField from '../../../admin-x-ds/global/form/TextField'; import Toggle from '../../../admin-x-ds/global/form/Toggle'; import useStaffUsers from '../../../hooks/useStaffUsers'; import validator from 'validator'; -import {User} from '../../../types/api'; -import {getImageUrl, useUploadImage} from '../../../utils/api/images'; -import {isAdminUser, isOwnerUser} from '../../../utils/helpers'; +import {User, isAdminUser, isOwnerUser, useDeleteUser, useEditUser, useMakeOwner, useUpdatePassword} from '../../../api/users'; +import {getImageUrl, useUploadImage} from '../../../api/images'; import {showToast} from '../../../admin-x-ds/global/Toast'; import {toast} from 'react-hot-toast'; -import {useBrowseRoles} from '../../../utils/api/roles'; -import {useDeleteUser, useEditUser, useMakeOwner, useUpdatePassword} from '../../../utils/api/users'; +import {useBrowseRoles} from '../../../api/roles'; interface CustomHeadingProps { children?: React.ReactNode; diff --git a/apps/admin-x-settings/src/components/settings/general/Users.tsx b/apps/admin-x-settings/src/components/settings/general/Users.tsx index 4dc8cf33c2..5c3c9bad67 100644 --- a/apps/admin-x-settings/src/components/settings/general/Users.tsx +++ b/apps/admin-x-settings/src/components/settings/general/Users.tsx @@ -10,8 +10,8 @@ import TabView from '../../../admin-x-ds/global/TabView'; import UserDetailModal from './UserDetailModal'; import useRouting from '../../../hooks/useRouting'; import useStaffUsers from '../../../hooks/useStaffUsers'; -import {User} from '../../../types/api'; -import {UserInvite, useAddInvite, useDeleteInvite} from '../../../utils/api/invites'; +import {User} from '../../../api/users'; +import {UserInvite, useAddInvite, useDeleteInvite} from '../../../api/invites'; import {generateAvatarColor, getInitials} from '../../../utils/helpers'; import {showToast} from '../../../admin-x-ds/global/Toast'; diff --git a/apps/admin-x-settings/src/components/settings/membership/Access.tsx b/apps/admin-x-settings/src/components/settings/membership/Access.tsx index 4301e33cb1..e41c4ca978 100644 --- a/apps/admin-x-settings/src/components/settings/membership/Access.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/Access.tsx @@ -5,8 +5,9 @@ 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 {getOptionLabel, getSettingValues} from '../../../utils/helpers'; -import {useBrowseTiers} from '../../../utils/api/tiers'; +import {getOptionLabel} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; +import {useBrowseTiers} from '../../../api/tiers'; const MEMBERS_SIGNUP_ACCESS_OPTIONS = [ {value: 'all', label: 'Anyone can sign up'}, diff --git a/apps/admin-x-settings/src/components/settings/membership/Analytics.tsx b/apps/admin-x-settings/src/components/settings/membership/Analytics.tsx index 7987b452eb..b7edba344a 100644 --- a/apps/admin-x-settings/src/components/settings/membership/Analytics.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/Analytics.tsx @@ -4,7 +4,7 @@ import SettingGroup from '../../../admin-x-ds/settings/SettingGroup'; import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupContent'; import Toggle from '../../../admin-x-ds/global/form/Toggle'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; const Analytics: React.FC<{ keywords: string[] }> = ({keywords}) => { const { diff --git a/apps/admin-x-settings/src/components/settings/membership/Tiers.tsx b/apps/admin-x-settings/src/components/settings/membership/Tiers.tsx index 898dd2431b..51c7cf3391 100644 --- a/apps/admin-x-settings/src/components/settings/membership/Tiers.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/Tiers.tsx @@ -4,9 +4,8 @@ import StripeButton from '../../../admin-x-ds/settings/StripeButton'; import TabView from '../../../admin-x-ds/global/TabView'; import TiersList from './tiers/TiersList'; import useRouting from '../../../hooks/useRouting'; -import {Tier} from '../../../types/api'; -import {checkStripeEnabled, getActiveTiers, getArchivedTiers} from '../../../utils/helpers'; -import {useBrowseTiers} from '../../../utils/api/tiers'; +import {Tier, getActiveTiers, getArchivedTiers, useBrowseTiers} from '../../../api/tiers'; +import {checkStripeEnabled} from '../../../api/settings'; import {useGlobalData} from '../../providers/GlobalDataProvider'; const Tiers: React.FC<{ keywords: string[] }> = ({keywords}) => { diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/AccountPage.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/AccountPage.tsx index 5515ab3e40..38adacfc4a 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/AccountPage.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/AccountPage.tsx @@ -1,8 +1,8 @@ import Form from '../../../../admin-x-ds/global/form/Form'; import React, {FocusEventHandler, useState} from 'react'; import TextField from '../../../../admin-x-ds/global/form/TextField'; -import {Setting, SettingValue} from '../../../../types/api'; -import {fullEmailAddress, getEmailDomain, getSettingValues} from '../../../../utils/helpers'; +import {Setting, SettingValue, getSettingValues} from '../../../../api/settings'; +import {fullEmailAddress, getEmailDomain} from '../../../../api/site'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; const AccountPage: React.FC<{ diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/LookAndFeel.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/LookAndFeel.tsx index c9ed12f35d..03f425f64c 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/LookAndFeel.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/LookAndFeel.tsx @@ -1,21 +1,19 @@ import Form from '../../../../admin-x-ds/global/form/Form'; +import Heading from '../../../../admin-x-ds/global/Heading'; +import Icon from '../../../../admin-x-ds/global/Icon'; +import ImageUpload from '../../../../admin-x-ds/global/form/ImageUpload'; import React, {useState} from 'react'; import Select from '../../../../admin-x-ds/global/form/Select'; import TextField from '../../../../admin-x-ds/global/form/TextField'; import Toggle from '../../../../admin-x-ds/global/form/Toggle'; -import {Setting, SettingValue} from '../../../../types/api'; -import {getSettingValues} from '../../../../utils/helpers'; - -import Heading from '../../../../admin-x-ds/global/Heading'; -import Icon from '../../../../admin-x-ds/global/Icon'; -import ImageUpload from '../../../../admin-x-ds/global/form/ImageUpload'; import clsx from 'clsx'; import {ReactComponent as PortalIcon1} from '../../../../assets/icons/portal-icon-1.svg'; import {ReactComponent as PortalIcon2} from '../../../../assets/icons/portal-icon-2.svg'; import {ReactComponent as PortalIcon3} from '../../../../assets/icons/portal-icon-3.svg'; import {ReactComponent as PortalIcon4} from '../../../../assets/icons/portal-icon-4.svg'; import {ReactComponent as PortalIcon5} from '../../../../assets/icons/portal-icon-5.svg'; -import {getImageUrl, useUploadImage} from '../../../../utils/api/images'; +import {Setting, SettingValue, getSettingValues} from '../../../../api/settings'; +import {getImageUrl, useUploadImage} from '../../../../api/images'; const defaultButtonIcons = [ { diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/PortalFrame.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/PortalFrame.tsx index 58694c130a..8fe03cc96b 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/PortalFrame.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/PortalFrame.tsx @@ -1,7 +1,8 @@ import React, {useEffect, useRef, useState} from 'react'; import useSettingGroup from '../../../../hooks/useSettingGroup'; -import {Setting, SiteData, Tier} from '../../../../types/api'; -import {getSettingValue} from '../../../../utils/helpers'; +import {Setting, getSettingValue} from '../../../../api/settings'; +import {SiteData} from '../../../../api/site'; +import {Tier} from '../../../../api/tiers'; type PortalFrameProps = { settings: Setting[]; diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/PortalLinks.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/PortalLinks.tsx index cc628112c9..053c5c0368 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/PortalLinks.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/PortalLinks.tsx @@ -5,8 +5,8 @@ import ModalPage from '../../../../admin-x-ds/global/modal/ModalPage'; import React, {useEffect, useState} from 'react'; import Select from '../../../../admin-x-ds/global/form/Select'; import TextField from '../../../../admin-x-ds/global/form/TextField'; -import {getHomepageUrl, getPaidActiveTiers} from '../../../../utils/helpers'; -import {useBrowseTiers} from '../../../../utils/api/tiers'; +import {getHomepageUrl} from '../../../../api/site'; +import {getPaidActiveTiers, useBrowseTiers} from '../../../../api/tiers'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; interface PortalLinkPrefs { diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/PortalModal.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/PortalModal.tsx index 1085975d1d..da9a588884 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/PortalModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/PortalModal.tsx @@ -9,10 +9,9 @@ import TabView, {Tab} from '../../../../admin-x-ds/global/TabView'; import useForm, {Dirtyable} from '../../../../hooks/useForm'; import useRouting from '../../../../hooks/useRouting'; import {PreviewModalContent} from '../../../../admin-x-ds/global/modal/PreviewModal'; -import {Setting, SettingValue, Tier} from '../../../../types/api'; -import {fullEmailAddress, getPaidActiveTiers} from '../../../../utils/helpers'; -import {useBrowseTiers, useEditTier} from '../../../../utils/api/tiers'; -import {useEditSettings} from '../../../../utils/api/settings'; +import {Setting, SettingValue, useEditSettings} from '../../../../api/settings'; +import {Tier, getPaidActiveTiers, useBrowseTiers, useEditTier} from '../../../../api/tiers'; +import {fullEmailAddress} from '../../../../api/site'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; const Sidebar: React.FC<{ diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/PortalPreview.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/PortalPreview.tsx index fda8af547c..f886cbab9a 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/PortalPreview.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/PortalPreview.tsx @@ -1,7 +1,8 @@ import PortalFrame from './PortalFrame'; import PortalLinks from './PortalLinks'; import React from 'react'; -import {Setting, Tier} from '../../../../types/api'; +import {Setting} from '../../../../api/settings'; +import {Tier} from '../../../../api/tiers'; interface PortalPreviewProps { selectedTab: string; @@ -39,4 +40,4 @@ const PortalPreview: React.FC = ({ return tabContents; }; -export default PortalPreview; \ No newline at end of file +export default PortalPreview; diff --git a/apps/admin-x-settings/src/components/settings/membership/portal/SignupOptions.tsx b/apps/admin-x-settings/src/components/settings/membership/portal/SignupOptions.tsx index 8d9fe81d63..ca891fc0b4 100644 --- a/apps/admin-x-settings/src/components/settings/membership/portal/SignupOptions.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/portal/SignupOptions.tsx @@ -4,8 +4,8 @@ import HtmlField from '../../../../admin-x-ds/global/form/HtmlField'; import React, {useEffect, useMemo} from 'react'; import Toggle from '../../../../admin-x-ds/global/form/Toggle'; import {CheckboxProps} from '../../../../admin-x-ds/global/form/Checkbox'; -import {Setting, SettingValue, Tier} from '../../../../types/api'; -import {checkStripeEnabled, getSettingValues} from '../../../../utils/helpers'; +import {Setting, SettingValue, checkStripeEnabled, getSettingValues} from '../../../../api/settings'; +import {Tier} from '../../../../api/tiers'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; const SignupOptions: React.FC<{ diff --git a/apps/admin-x-settings/src/components/settings/membership/stripe/StripeConnectModal.tsx b/apps/admin-x-settings/src/components/settings/membership/stripe/StripeConnectModal.tsx index abfb4df9a5..2a215ad269 100644 --- a/apps/admin-x-settings/src/components/settings/membership/stripe/StripeConnectModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/stripe/StripeConnectModal.tsx @@ -17,12 +17,12 @@ import useRouting from '../../../../hooks/useRouting'; import useSettingGroup from '../../../../hooks/useSettingGroup'; import {ApiError} from '../../../../utils/apiRequests'; import {ReactComponent as StripeVerified} from '../../../../assets/images/stripe-verified.svg'; -import {checkStripeEnabled, getGhostPaths, getSettingValue, getSettingValues} from '../../../../utils/helpers'; +import {checkStripeEnabled, getSettingValue, getSettingValues, useDeleteStripeSettings, useEditSettings} from '../../../../api/settings'; +import {getGhostPaths} from '../../../../utils/helpers'; import {showToast} from '../../../../admin-x-ds/global/Toast'; import {toast} from 'react-hot-toast'; -import {useBrowseMembers} from '../../../../utils/api/members'; -import {useBrowseTiers, useEditTier} from '../../../../utils/api/tiers'; -import {useDeleteStripeSettings, useEditSettings} from '../../../../utils/api/settings'; +import {useBrowseMembers} from '../../../../api/members'; +import {useBrowseTiers, useEditTier} from '../../../../api/tiers'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; const RETRY_PRODUCT_SAVE_POLL_LENGTH = 1000; diff --git a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx index fbb33fa46c..9d799c681d 100644 --- a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailModal.tsx @@ -14,12 +14,11 @@ import useForm from '../../../../hooks/useForm'; import useRouting from '../../../../hooks/useRouting'; import useSettingGroup from '../../../../hooks/useSettingGroup'; import useSortableIndexedList from '../../../../hooks/useSortableIndexedList'; -import {Tier} from '../../../../types/api'; +import {Tier, useAddTier, useEditTier} from '../../../../api/tiers'; import {currencies, currencyFromDecimal, currencyGroups, currencyToDecimal, getSymbol} from '../../../../utils/currency'; -import {getSettingValues} from '../../../../utils/helpers'; +import {getSettingValues} from '../../../../api/settings'; import {showToast} from '../../../../admin-x-ds/global/Toast'; import {toast} from 'react-hot-toast'; -import {useAddTier, useEditTier} from '../../../../utils/api/tiers'; interface TierDetailModalProps { tier?: Tier diff --git a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx index 8bdcece127..e8538294a8 100644 --- a/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/tiers/TierDetailPreview.tsx @@ -3,8 +3,8 @@ import Heading from '../../../../admin-x-ds/global/Heading'; import Icon from '../../../../admin-x-ds/global/Icon'; import React, {useState} from 'react'; import useSettingGroup from '../../../../hooks/useSettingGroup'; -import {Tier} from '../../../../types/api'; -import {getSettingValues} from '../../../../utils/helpers'; +import {Tier} from '../../../../api/tiers'; +import {getSettingValues} from '../../../../api/settings'; import {getSymbol} from '../../../../utils/currency'; import {numberWithCommas} from '../../../../utils/helpers'; diff --git a/apps/admin-x-settings/src/components/settings/membership/tiers/TiersList.tsx b/apps/admin-x-settings/src/components/settings/membership/tiers/TiersList.tsx index c177965bc0..28c594e4ac 100644 --- a/apps/admin-x-settings/src/components/settings/membership/tiers/TiersList.tsx +++ b/apps/admin-x-settings/src/components/settings/membership/tiers/TiersList.tsx @@ -5,10 +5,9 @@ import NoValueLabel from '../../../../admin-x-ds/global/NoValueLabel'; import React from 'react'; import TierDetailModal from './TierDetailModal'; import useRouting from '../../../../hooks/useRouting'; -import {Tier} from '../../../../types/api'; +import {Tier, useEditTier} from '../../../../api/tiers'; import {currencyToDecimal, getSymbol} from '../../../../utils/currency'; import {numberWithCommas} from '../../../../utils/helpers'; -import {useEditTier} from '../../../../utils/api/tiers'; interface TiersListProps { tab?: 'active-tiers' | 'archive-tiers' | 'free-tier'; diff --git a/apps/admin-x-settings/src/components/settings/site/DesignModal.tsx b/apps/admin-x-settings/src/components/settings/site/DesignModal.tsx index da6277804a..1b63bf8253 100644 --- a/apps/admin-x-settings/src/components/settings/site/DesignModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/DesignModal.tsx @@ -10,12 +10,11 @@ import ThemePreview from './designAndBranding/ThemePreview'; import ThemeSettings from './designAndBranding/ThemeSettings'; import useForm from '../../../hooks/useForm'; import useRouting from '../../../hooks/useRouting'; -import {CustomThemeSetting, Setting, SettingValue} from '../../../types/api'; +import {CustomThemeSetting, useBrowseCustomThemeSettings, useEditCustomThemeSettings} from '../../../api/customThemeSettings'; import {PreviewModalContent} from '../../../admin-x-ds/global/modal/PreviewModal'; -import {getHomepageUrl, getSettingValues} from '../../../utils/helpers'; -import {useBrowseCustomThemeSettings, useEditCustomThemeSettings} from '../../../utils/api/customThemeSettings'; -import {useBrowsePosts} from '../../../utils/api/posts'; -import {useEditSettings} from '../../../utils/api/settings'; +import {Setting, SettingValue, getSettingValues, useEditSettings} from '../../../api/settings'; +import {getHomepageUrl} from '../../../api/site'; +import {useBrowsePosts} from '../../../api/posts'; import {useGlobalData} from '../../providers/GlobalDataProvider'; const Sidebar: React.FC<{ diff --git a/apps/admin-x-settings/src/components/settings/site/NavigationModal.tsx b/apps/admin-x-settings/src/components/settings/site/NavigationModal.tsx index c9faec7ed4..2d7acd1432 100644 --- a/apps/admin-x-settings/src/components/settings/site/NavigationModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/NavigationModal.tsx @@ -5,7 +5,7 @@ import TabView from '../../../admin-x-ds/global/TabView'; import useNavigationEditor, {NavigationItem} from '../../../hooks/site/useNavigationEditor'; import useRouting from '../../../hooks/useRouting'; import useSettingGroup from '../../../hooks/useSettingGroup'; -import {getSettingValues} from '../../../utils/helpers'; +import {getSettingValues} from '../../../api/settings'; import {useState} from 'react'; const NavigationModal = NiceModal.create(() => { diff --git a/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx b/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx index 2a396fbb93..fde412e8e8 100644 --- a/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/ThemeModal.tsx @@ -12,9 +12,8 @@ import TabView from '../../../admin-x-ds/global/TabView'; import ThemeInstalledModal from './theme/ThemeInstalledModal'; import ThemePreview from './theme/ThemePreview'; import useRouting from '../../../hooks/useRouting'; -import {OfficialTheme} from '../../../models/themes'; -import {Theme} from '../../../types/api'; -import {useBrowseThemes, useInstallTheme, useUploadTheme} from '../../../utils/api/themes'; +import {OfficialTheme} from '../../providers/ServiceProvider'; +import {Theme, useBrowseThemes, useInstallTheme, useUploadTheme} from '../../../api/themes'; interface ThemeToolbarProps { selectedTheme: OfficialTheme|null; diff --git a/apps/admin-x-settings/src/components/settings/site/designAndBranding/BrandSettings.tsx b/apps/admin-x-settings/src/components/settings/site/designAndBranding/BrandSettings.tsx index 21e91d673c..6733efe680 100644 --- a/apps/admin-x-settings/src/components/settings/site/designAndBranding/BrandSettings.tsx +++ b/apps/admin-x-settings/src/components/settings/site/designAndBranding/BrandSettings.tsx @@ -4,8 +4,8 @@ import ImageUpload from '../../../../admin-x-ds/global/form/ImageUpload'; import React from 'react'; import SettingGroupContent from '../../../../admin-x-ds/settings/SettingGroupContent'; import TextField from '../../../../admin-x-ds/global/form/TextField'; -import {SettingValue} from '../../../../types/api'; -import {getImageUrl, useUploadImage} from '../../../../utils/api/images'; +import {SettingValue} from '../../../../api/settings'; +import {getImageUrl, useUploadImage} from '../../../../api/images'; export interface BrandSettingValues { description: string diff --git a/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemePreview.tsx b/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemePreview.tsx index b81efe82b7..fb6bcefcc3 100644 --- a/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemePreview.tsx +++ b/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemePreview.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useRef} from 'react'; -import {CustomThemeSetting} from '../../../../types/api'; +import {CustomThemeSetting} from '../../../../api/customThemeSettings'; type BrandSettings = { description: string; diff --git a/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemeSettings.tsx b/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemeSettings.tsx index 262ddbfbd6..61a98212e4 100644 --- a/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemeSettings.tsx +++ b/apps/admin-x-settings/src/components/settings/site/designAndBranding/ThemeSettings.tsx @@ -6,9 +6,9 @@ import Select from '../../../../admin-x-ds/global/form/Select'; import SettingGroupContent from '../../../../admin-x-ds/settings/SettingGroupContent'; import TextField from '../../../../admin-x-ds/global/form/TextField'; import Toggle from '../../../../admin-x-ds/global/form/Toggle'; -import {CustomThemeSetting} from '../../../../types/api'; -import {getImageUrl, useUploadImage} from '../../../../utils/api/images'; -import {humanizeSettingKey} from '../../../../utils/helpers'; +import {CustomThemeSetting} from '../../../../api/customThemeSettings'; +import {getImageUrl, useUploadImage} from '../../../../api/images'; +import {humanizeSettingKey} from '../../../../api/settings'; const ThemeSetting: React.FC<{ setting: CustomThemeSetting, diff --git a/apps/admin-x-settings/src/components/settings/site/theme/AdvancedThemeSettings.tsx b/apps/admin-x-settings/src/components/settings/site/theme/AdvancedThemeSettings.tsx index 85078e2f45..9213b8ee65 100644 --- a/apps/admin-x-settings/src/components/settings/site/theme/AdvancedThemeSettings.tsx +++ b/apps/admin-x-settings/src/components/settings/site/theme/AdvancedThemeSettings.tsx @@ -6,10 +6,8 @@ import Menu from '../../../../admin-x-ds/global/Menu'; import ModalPage from '../../../../admin-x-ds/global/modal/ModalPage'; import NiceModal from '@ebay/nice-modal-react'; import React from 'react'; -import {Theme} from '../../../../types/api'; +import {Theme, isActiveTheme, isDefaultTheme, isDeletableTheme, useActivateTheme, useDeleteTheme} from '../../../../api/themes'; import {downloadFile, getGhostPaths} from '../../../../utils/helpers'; -import {isActiveTheme, isDefaultTheme, isDeletableTheme} from '../../../../models/themes'; -import {useActivateTheme, useDeleteTheme} from '../../../../utils/api/themes'; interface ThemeActionProps { theme: Theme; diff --git a/apps/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx b/apps/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx index fa48cc984b..dae5f26a60 100644 --- a/apps/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx +++ b/apps/admin-x-settings/src/components/settings/site/theme/OfficialThemes.tsx @@ -1,9 +1,8 @@ import Heading from '../../../../admin-x-ds/global/Heading'; import ModalPage from '../../../../admin-x-ds/global/modal/ModalPage'; import React from 'react'; -import {OfficialTheme} from '../../../../models/themes'; +import {OfficialTheme, useOfficialThemes} from '../../../providers/ServiceProvider'; import {getGhostPaths} from '../../../../utils/helpers'; -import {useOfficialThemes} from '../../../providers/ServiceProvider'; const OfficialThemes: React.FC<{ onSelectTheme?: (theme: OfficialTheme) => void; diff --git a/apps/admin-x-settings/src/components/settings/site/theme/ThemeInstalledModal.tsx b/apps/admin-x-settings/src/components/settings/site/theme/ThemeInstalledModal.tsx index d8da8f28db..61ae9b19fe 100644 --- a/apps/admin-x-settings/src/components/settings/site/theme/ThemeInstalledModal.tsx +++ b/apps/admin-x-settings/src/components/settings/site/theme/ThemeInstalledModal.tsx @@ -5,9 +5,8 @@ import ListItem from '../../../../admin-x-ds/global/ListItem'; import NiceModal from '@ebay/nice-modal-react'; import React, {ReactNode, useState} from 'react'; import {ConfirmationModalContent} from '../../../../admin-x-ds/global/modal/ConfirmationModal'; -import {InstalledTheme, ThemeProblem} from '../../../../types/api'; +import {InstalledTheme, ThemeProblem, useActivateTheme} from '../../../../api/themes'; import {showToast} from '../../../../admin-x-ds/global/Toast'; -import {useActivateTheme} from '../../../../utils/api/themes'; const ThemeProblemView = ({problem}:{problem: ThemeProblem}) => { const [isExpanded, setExpanded] = useState(false); diff --git a/apps/admin-x-settings/src/components/settings/site/theme/ThemePreview.tsx b/apps/admin-x-settings/src/components/settings/site/theme/ThemePreview.tsx index 9aea53b67e..f4df3ddd8d 100644 --- a/apps/admin-x-settings/src/components/settings/site/theme/ThemePreview.tsx +++ b/apps/admin-x-settings/src/components/settings/site/theme/ThemePreview.tsx @@ -7,8 +7,8 @@ import MobileChrome from '../../../../admin-x-ds/global/chrome/MobileChrome'; import NiceModal from '@ebay/nice-modal-react'; import PageHeader from '../../../../admin-x-ds/global/layout/PageHeader'; import React, {useState} from 'react'; -import {OfficialTheme} from '../../../../models/themes'; -import {Theme} from '../../../../types/api'; +import {OfficialTheme} from '../../../providers/ServiceProvider'; +import {Theme} from '../../../../api/themes'; const ThemePreview: React.FC<{ selectedTheme?: OfficialTheme; diff --git a/apps/admin-x-settings/src/hooks/useSettingGroup.tsx b/apps/admin-x-settings/src/hooks/useSettingGroup.tsx index d80f8ec665..9b6430a406 100644 --- a/apps/admin-x-settings/src/hooks/useSettingGroup.tsx +++ b/apps/admin-x-settings/src/hooks/useSettingGroup.tsx @@ -1,8 +1,8 @@ import React, {useEffect, useRef, useState} from 'react'; import useForm, {SaveState} from './useForm'; import useGlobalDirtyState from './useGlobalDirtyState'; -import {Setting, SettingValue, SiteData} from '../types/api'; -import {useEditSettings} from '../utils/api/settings'; +import {Setting, SettingValue, useEditSettings} from '../api/settings'; +import {SiteData} from '../api/site'; import {useGlobalData} from '../components/providers/GlobalDataProvider'; interface LocalSetting extends Setting { diff --git a/apps/admin-x-settings/src/hooks/useStaffUsers.tsx b/apps/admin-x-settings/src/hooks/useStaffUsers.tsx index a1c41591e2..5010a94ec7 100644 --- a/apps/admin-x-settings/src/hooks/useStaffUsers.tsx +++ b/apps/admin-x-settings/src/hooks/useStaffUsers.tsx @@ -1,7 +1,6 @@ -import {User} from '../types/api'; -import {UserInvite, useBrowseInvites} from '../utils/api/invites'; -import {useBrowseRoles} from '../utils/api/roles'; -import {useBrowseUsers} from '../utils/api/users'; +import {User, useBrowseUsers} from '../api/users'; +import {UserInvite, useBrowseInvites} from '../api/invites'; +import {useBrowseRoles} from '../api/roles'; import {useGlobalData} from '../components/providers/GlobalDataProvider'; export type UsersHook = { diff --git a/apps/admin-x-settings/src/models/themes.ts b/apps/admin-x-settings/src/models/themes.ts deleted file mode 100644 index 10febec043..0000000000 --- a/apps/admin-x-settings/src/models/themes.ts +++ /dev/null @@ -1,31 +0,0 @@ -export type Theme = { - active: boolean; - name: string; - package: { - name?: string; - description?: string; - version?: string; - }; - templates?: string[]; -} - -export type OfficialTheme = { - name: string; - category: string; - previewUrl: string; - ref: string; - image: string; - url?: string; -}; - -export function isActiveTheme(theme: Theme): boolean { - return theme.active; -} - -export function isDefaultTheme(theme: Theme): boolean { - return theme.name === 'casper'; -} - -export function isDeletableTheme(theme: Theme): boolean { - return !isDefaultTheme(theme) && !isActiveTheme(theme); -} diff --git a/apps/admin-x-settings/src/types/api.ts b/apps/admin-x-settings/src/types/api.ts deleted file mode 100644 index 85c3ed41ef..0000000000 --- a/apps/admin-x-settings/src/types/api.ts +++ /dev/null @@ -1,219 +0,0 @@ -export type JSONValue = string|number|boolean|null|Date|JSONObject|JSONArray; -export interface JSONObject { [key: string]: JSONValue } -export interface JSONArray extends Array {} - -export type SettingValue = string | boolean | null; - -export type Setting = { - key: string; - value: SettingValue; -} - -export type Config = { - version: string; - environment: string; - editor: { - url: string - version: string - }; - labs: Record; - stripeDirect: boolean; - - // Config is relatively fluid, so we only type used properties above and still support arbitrary property access when needed - [key: string]: JSONValue; -}; - -export type User = { - id: string; - name: string; - slug: string; - email: string; - profile_image: string; - cover_image: string|null; - bio: string; - website: string; - location: string; - facebook: string; - twitter: string; - accessibility: string|null; - status: string; - meta_title: string|null; - meta_description: string|null; - tour: string|null; - last_seen: string|null; - created_at: string; - updated_at: string; - comment_notifications: boolean; - free_member_signup_notification: boolean; - paid_subscription_canceled_notification: boolean; - paid_subscription_started_notification: boolean; - mention_notifications: boolean; - milestone_notifications: boolean; - roles: UserRole[]; - url: string; -} - -export type UserRoleType = 'Owner' | 'Administrator' | 'Editor' | 'Author' | 'Contributor'; - -export type UserRole = { - id: string; - name: UserRoleType; - description: string; - created_at: string; - updated_at: string; -}; - -export type SiteData = { - title: string; - description: string; - logo: string; - icon: string; - accent_color: string; - url: string; - locale: string; - version: string; -}; - -export type Post = { - id: string; - url: string; -}; - -export type Member = { - id: string; -}; - -export type Tier = { - id: string; - name: string; - description: string | null; - slug: string; - active: boolean, - type: string; - welcome_page_url: string | null; - created_at: string; - updated_at: string; - visibility: string; - benefits: string[]; - currency?: string; - monthly_price?: number; - yearly_price?: number; - trial_days: number; -} - -export type Label = { - id: string; - name: string; - slug: string; - created_at: string; - 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 } | - { type: 'image', value: string | null } | - { type: 'boolean', value: boolean, default: boolean } | - { - type: 'select', - value: string - default: string - options: string[] - }; - -export type CustomThemeSetting = CustomThemeSettingData & { - id: string - key: string - description?: string - // homepage and post are the only two groups we handle, but technically theme authors can put other things in package.json - group?: 'homepage' | 'post' | string -} - -export type Theme = { - active: boolean; - name: string; - package: { - name?: string; - description?: string; - version?: string; - }; - templates?: string[]; -} - -export type InstalledTheme = Theme & { - errors?: ThemeProblem<'error'>[]; - warnings?: ThemeProblem<'warning'>[]; -} - -export type ThemeProblem = { - code: string - details: string - failures: Array<{ - ref: string - message?: string - rule?: string - }> - fatal: boolean - level: Level - rule: string -} - -export type Newsletter = { - id: string; - uuid: string; - name: string; - description: string | null; - feedback_enabled: boolean; - slug: string; - sender_name: string | null; - sender_email: string | null; - sender_reply_to: string; - status: string; - visibility: string; - subscribe_on_signup: boolean; - sort_order: number; - header_image: string | null; - show_header_icon: boolean; - show_header_title: boolean; - title_font_category: string; - title_alignment: string; - show_feature_image: boolean; - body_font_category: string; - footer_content: string | null; - show_badge: boolean; - show_header_name: boolean; - show_post_title_section: boolean; - show_comment_cta: boolean; - show_subscription_details: boolean; - show_latest_posts: boolean; - background_color: string; - border_color: string | null; - title_color: string | null; - created_at: string; - updated_at: string; - count?: { - posts?: number; - active_members?: number; - } -} diff --git a/apps/admin-x-settings/src/utils/api/config.ts b/apps/admin-x-settings/src/utils/api/config.ts deleted file mode 100644 index 2a0f60ab40..0000000000 --- a/apps/admin-x-settings/src/utils/api/config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {Config} from '../../types/api'; -import {createQuery} from '../apiRequests'; - -export interface ConfigResponseType { - config: Config; -} - -const dataType = 'ConfigResponseType'; - -export const useBrowseConfig = createQuery({ - dataType, - path: '/config/' -}); diff --git a/apps/admin-x-settings/src/utils/api/customThemeSettings.ts b/apps/admin-x-settings/src/utils/api/customThemeSettings.ts deleted file mode 100644 index a029f5314c..0000000000 --- a/apps/admin-x-settings/src/utils/api/customThemeSettings.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {CustomThemeSetting, Setting} from '../../types/api'; -import {createMutation, createQuery} from '../apiRequests'; - -export interface CustomThemeSettingsResponseType { - custom_theme_settings: CustomThemeSetting[]; -} - -const dataType = 'CustomThemeSettingsResponseType'; - -export const useBrowseCustomThemeSettings = createQuery({ - dataType, - path: '/custom_theme_settings/' -}); - -export const useEditCustomThemeSettings = createMutation({ - method: 'PUT', - path: () => '/custom_theme_settings/', - body: settings => ({custom_theme_settings: settings}), - - updateQueries: { - dataType, - update: newData => newData - } -}); diff --git a/apps/admin-x-settings/src/utils/api/offers.ts b/apps/admin-x-settings/src/utils/api/offers.ts deleted file mode 100644 index 19e85c58d5..0000000000 --- a/apps/admin-x-settings/src/utils/api/offers.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {Meta, createQuery} from '../apiRequests'; -import {Offer} from '../../types/api'; - -export interface OffersResponseType { - meta?: Meta - offers: Offer[] -} - -const dataType = 'OffersResponseType'; - -export const useBrowseOffers = createQuery({ - dataType, - path: '/offers/', - defaultSearchParams: {limit: 'all'} -}); diff --git a/apps/admin-x-settings/src/utils/api/roles.ts b/apps/admin-x-settings/src/utils/api/roles.ts deleted file mode 100644 index dfb12a2132..0000000000 --- a/apps/admin-x-settings/src/utils/api/roles.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {Meta, createQuery} from '../apiRequests'; -import {UserRole} from '../../types/api'; - -export interface RolesResponseType { - meta?: Meta; - roles: UserRole[]; -} - -const dataType = 'RolesResponseType'; - -export const useBrowseRoles = createQuery({ - dataType, - path: '/roles/', - defaultSearchParams: {limit: 'all'} -}); diff --git a/apps/admin-x-settings/src/utils/api/settings.ts b/apps/admin-x-settings/src/utils/api/settings.ts deleted file mode 100644 index cdc7290715..0000000000 --- a/apps/admin-x-settings/src/utils/api/settings.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Meta, createMutation, createQuery} from '../apiRequests'; -import {Setting} from '../../types/api'; - -export type SettingsResponseMeta = Meta & { sent_email_verification?: boolean } - -export interface SettingsResponseType { - meta?: SettingsResponseMeta; - settings: Setting[]; -} - -const dataType = 'SettingsResponseType'; - -export const useBrowseSettings = createQuery({ - dataType, - path: '/settings/', - defaultSearchParams: { - group: 'site,theme,private,members,portal,newsletter,email,amp,labs,slack,unsplash,views,firstpromoter,editor,comments,analytics,announcement,pintura' - } -}); - -export const useEditSettings = createMutation({ - method: 'PUT', - path: () => '/settings/', - body: settings => ({settings: settings.map(({key, value}) => ({key, value}))}), - updateQueries: { - dataType, - update: newData => ({ - ...newData, - settings: newData.settings - }) - } -}); - -export const useDeleteStripeSettings = createMutation({ - method: 'DELETE', - path: () => '/settings/stripe/connect/', - invalidateQueries: {dataType} -}); diff --git a/apps/admin-x-settings/src/utils/api/site.ts b/apps/admin-x-settings/src/utils/api/site.ts deleted file mode 100644 index 352dfad360..0000000000 --- a/apps/admin-x-settings/src/utils/api/site.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {SiteData} from '../../types/api'; -import {createQuery} from '../apiRequests'; - -export interface SiteResponseType { - site: SiteData; -} - -const dataType = 'SiteResponseType'; - -export const useBrowseSite = createQuery({ - dataType, - path: '/site/' -}); diff --git a/apps/admin-x-settings/src/utils/helpers.ts b/apps/admin-x-settings/src/utils/helpers.ts index 613fb9d8ce..bc4cc8f9d8 100644 --- a/apps/admin-x-settings/src/utils/helpers.ts +++ b/apps/admin-x-settings/src/utils/helpers.ts @@ -1,19 +1,9 @@ -import {Config, Setting, SettingValue, SiteData, Tier, User} from '../types/api'; - export interface IGhostPaths { adminRoot: string; assetRoot: string; apiRoot: string; } -export function getSettingValue(settings: Setting[] | null | undefined, key: string): SettingValue { - if (!settings) { - return ''; - } - const setting = settings.find(d => d.key === key); - return setting?.value || null; -} - export function getGhostPaths(): IGhostPaths { let path = window.location.pathname; let subdir = path.substr(0, path.search('/ghost/')); @@ -59,27 +49,6 @@ export function generateAvatarColor(name: string) { return 'hsl(' + h + ', ' + s + '%, ' + l + '%)'; } -export function humanizeSettingKey(key: string) { - const allCaps = ['API', 'CTA', 'RSS']; - - return key - .replace(/^[a-z]/, char => char.toUpperCase()) - .replace(/_/g, ' ') - .replace(new RegExp(`\\b(${allCaps.join('|')})\\b`, 'ig'), match => match.toUpperCase()); -} - -export function getSettingValues(settings: Setting[] | null, keys: string[]): Array { - return keys.map(key => settings?.find(setting => setting.key === key)?.value) as ValueType[]; -} - -export function isOwnerUser(user: User) { - return user.roles.some(role => role.name === 'Owner'); -} - -export function isAdminUser(user: User) { - return user.roles.some(role => role.name === 'Administrator'); -} - export function downloadFile(url: string) { let iframe = document.getElementById('iframeDownload'); @@ -93,57 +62,6 @@ export function downloadFile(url: string) { iframe.setAttribute('src', url); } -export function getHomepageUrl(siteData: SiteData): string { - const url = new URL(siteData.url); - const subdir = url.pathname.endsWith('/') ? url.pathname : `${url.pathname}/`; - - return `${url.origin}${subdir}`; -} - -export function getEmailDomain(siteData: SiteData): string { - const domain = new URL(siteData.url).hostname || ''; - if (domain.startsWith('www.')) { - return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, ''); - } - return domain; -} - -export function fullEmailAddress(value: 'noreply' | string, siteData: SiteData) { - const emailDomain = getEmailDomain(siteData); - return value === 'noreply' ? `noreply@${emailDomain}` : value; -} - -export function checkStripeEnabled(settings: Setting[], config: Config) { - const hasSetting = (key: string) => settings.some(setting => setting.key === key && setting.value); - - const hasDirectKeys = hasSetting('stripe_secret_key') && hasSetting('stripe_publishable_key'); - const hasConnectKeys = hasSetting('stripe_connect_secret_key') && hasSetting('stripe_connect_publishable_key'); - - if (config.stripeDirect) { - return hasDirectKeys; - } - - 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; - }); -} - export function numberWithCommas(x: number) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }