Added theme management hooks in adminX

refs https://github.com/TryGhost/Team/issues/3432

- adds new `useRequest` hook to manage API requests
- adds new `useThemes` hook that allows fetching and updating themes
- adds models pattern to store specific type and helper info for themes
This commit is contained in:
Rishabh 2023-06-13 21:59:18 +05:30
parent 01e90dfb65
commit 3dbc2ee507
5 changed files with 90 additions and 2 deletions

View File

@ -1,4 +1,4 @@
import React, {createContext, useMemo} from 'react';
import React, {createContext, useContext, useMemo} from 'react';
import setupGhostApi from '../../utils/api';
export interface FileService {
@ -39,3 +39,7 @@ const ServicesProvider: React.FC<ServicesProviderProps> = ({children, ghostVersi
};
export {ServicesContext, ServicesProvider};
export const useServices = () => useContext(ServicesContext)!;
export const useApi = () => useServices().api;

View File

@ -0,0 +1,37 @@
import {useCallback, useEffect, useState} from 'react';
type FetcherFunction<T> = () => Promise<T>;
export function useRequest<T>(fetcher: FetcherFunction<T>) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isLoading, setIsLoading] = useState(true);
const fetchData = useCallback(async () => {
try {
setIsLoading(true);
const responseData = await fetcher();
setData(responseData);
} catch (err: any) {
setError(err?.message);
} finally {
setIsLoading(false);
}
}, [fetcher]);
useEffect(() => {
fetchData();
}, [fetchData]);
const refetch = async () => {
setIsLoading(true);
await fetchData();
};
return {
data,
error,
isLoading,
refetch
};
}

View File

@ -0,0 +1,25 @@
import {Theme} from '../types/api';
import {ThemesResponseType} from '../utils/api';
import {useApi} from '../components/providers/ServiceProvider';
import {useEffect, useState} from 'react';
import {useRequest} from './useRequest';
export function useThemes() {
const api = useApi();
const [themes, setThemes] = useState<Theme[]>([]);
const {data, error, isLoading} = useRequest<ThemesResponseType>(api.themes.browse);
useEffect(() => {
if (data) {
setThemes(data.themes);
}
}, [data]);
return {
themes,
error,
isLoading,
setThemes
};
}

View File

@ -0,0 +1,22 @@
export type Theme = {
active: boolean;
name: string;
package: {
name?: string;
description?: string;
version?: string;
};
templates?: 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);
}

View File

@ -115,7 +115,7 @@ interface UpdatePasswordOptions {
oldPassword?: string;
}
interface API {
export interface API {
settings: {
browse: () => Promise<SettingsResponseType>;
edit: (newSettings: Setting[]) => Promise<SettingsResponseType>;