0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00

Added new provider to manage settings for admin-x

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

- adds new settings provider that fetches settings for a site and allows saving them
- adds new helpers for making admin api calls and fetching setting values
This commit is contained in:
Rishabh 2023-05-18 02:03:14 +05:30
parent cfbcd6fc1a
commit 5b0eba9b1f
5 changed files with 172 additions and 3 deletions

View file

@ -1,6 +1,7 @@
import Heading from './admin-x-ds/global/Heading';
import Settings from './components/Settings';
import Sidebar from './components/Sidebar';
import {SettingsProvider} from './components/SettingsProvider';
function App() {
return (
@ -22,7 +23,9 @@ function App() {
<Sidebar />
</div>
<div className="flex-auto pt-[3vmin] md:pt-[72px]">
<Settings />
<SettingsProvider>
<Settings />
</SettingsProvider>
</div>
</div>
</div>

View file

@ -1,8 +1,20 @@
import React from 'react';
import React, {useContext} from 'react';
import GeneralSettings from './settings/general/GeneralSettings';
import {SettingsContext} from './SettingsProvider';
const Settings: React.FC = () => {
const {settings} = useContext(SettingsContext) || {};
// Show loader while settings is first fetched
if (!settings) {
return (
<div className="flex h-full flex-col items-center justify-center">
<div className="text-center text-2xl font-bold">Loading...</div>
</div>
);
}
return (
<>
<GeneralSettings />

View file

@ -0,0 +1,62 @@
import React, {createContext, useEffect, useState} from 'react';
import {getSettings, updateSettings} from '../utils/api';
// Define the Setting type
export interface ISetting {
key: string;
value: string;
}
// Define the Settings Context
interface SettingsContextProps {
settings: ISetting[] | null;
saveSettings: (updatedSettings: ISetting[]) => void;
}
interface SettingsProviderProps {
children?: React.ReactNode;
}
const SettingsContext = createContext < SettingsContextProps | undefined > (undefined);
// Create a Settings Provider component
const SettingsProvider: React.FC<SettingsProviderProps> = ({children}) => {
const [settings, setSettings] = useState <ISetting[] | null> (null);
useEffect(() => {
const fetchSettings = async (): Promise<void> => {
try {
// Make an API call to fetch the settings
const data = await getSettings();
setSettings(data.settings);
} catch (error) {
// Log error in settings API
}
};
// Fetch the initial settings from the API
fetchSettings();
}, []);
const saveSettings = async (updatedSettings: ISetting[]): Promise<void> => {
try {
// Make an API call to save the updated settings
const data = await updateSettings(updatedSettings);
// Update the local state with the new settings
setSettings(data.settings);
} catch (error) {
console.log('Error', error);
// Log error in settings API
}
};
// Provide the settings and the saveSettings function to the children components
return (
<SettingsContext.Provider value={{settings, saveSettings}}>
{children}
</SettingsContext.Provider>
);
};
export {SettingsContext, SettingsProvider};

View file

@ -0,0 +1,61 @@
import {getGhostPaths} from './helpers';
interface IQueryParams {
group: string;
[key: string]: string;
}
// Define the Setting type
export interface ISetting {
key: string;
value: string;
}
// Define the SettingsResponse type
export interface ISettingsResponse {
meta: any;
settings: ISetting[];
}
export async function getSettings() {
const {apiRoot} = getGhostPaths();
const queryParams: IQueryParams = {group: 'site,theme,private,members,portal,newsletter,email,amp,labs,slack,unsplash,views,firstpromoter,editor,comments,analytics,announcement,pintura'};
const queryString = Object.keys(queryParams).map((key) => {
return `${key}=${queryParams[key] || ''}`;
}).join('&');
const response = await fetch(`${apiRoot}/settings/?${queryString}`, {
headers: {
'app-pragma': 'no-cache',
'x-ghost-version': '5.47'
},
method: 'GET',
mode: 'cors',
credentials: 'include'
});
const data: ISettingsResponse = await response.json();
return data;
}
export async function updateSettings(newSettings: ISetting[]) {
const {apiRoot} = getGhostPaths();
const payload = JSON.stringify({
settings: newSettings
});
const response = await fetch(`${apiRoot}/settings/`, {
headers: {
'app-pragma': 'no-cache',
'x-ghost-version': '5.47',
'Content-Type': 'application/json'
},
body: payload,
method: 'PUT',
mode: 'cors',
credentials: 'include'
});
const data: ISettingsResponse = await response.json();
return data;
}

View file

@ -0,0 +1,31 @@
import {ISetting} from '../components/SettingsProvider';
export interface IGhostPaths {
adminRoot: string;
assetRoot: string;
apiRoot: string;
}
export function getSettingValue(settings: ISetting[] | null | undefined, key: string): string {
if (!settings) {
return '';
}
const setting = settings.find(d => d.key === key);
return setting ? setting.value : '';
}
export function getGhostPaths(): IGhostPaths {
let path = window.location.pathname;
let subdir = path.substr(0, path.search('/ghost/'));
let adminRoot = `${subdir}/ghost/`;
let assetRoot = `${subdir}/ghost/assets/`;
let apiRoot = `${subdir}/ghost/api/admin`;
return {adminRoot, assetRoot, apiRoot};
}
export function getLocalTime({timeZone}) {
const date = new Date();
const options = {timeZone: timeZone, hour12: false, hour: 'numeric', minute: 'numeric', second: 'numeric'};
const localTime = date.toLocaleString('en-US', options);
return localTime;
}