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

Wired up recommendations in Portal (#17888)

closes https://github.com/TryGhost/Product/issues/3796
refs https://github.com/TryGhost/Product/issues/3770

- also added a public endpoint for Recommendations in the Content API
This commit is contained in:
Sag 2023-08-31 12:07:49 +02:00 committed by GitHub
parent 69a6388009
commit f56c36ca24
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 25 deletions

View file

@ -1,26 +1,6 @@
import AppContext from '../../AppContext';
import {useContext} from 'react';
// Dummy data for design purposes. To be deleted when wired up with real data.
const recommendations = [
{
title: 'Shes A Beast',
url: 'https://shesabeast.co',
reason: 'She helped me get back into the gym after 8 years.',
excerpt: 'Explore mountains with me and my bike!',
featured_image: 'https://unsplash.com/photos/1527pjeb6jg',
favicon: 'https://www.shesabeast.co/content/images/size/w256h256/2022/08/transparent-icon-black-copy-gray-bar.png'
},
{
title: 'Lennys Newsletter',
url: 'https://www.lennysnewsletter.com/',
reason: 'He knows his stuff about product management and gives away lots of content for free. Highly recommended!',
excerpt: 'Enjoy the sea!',
featured_image: 'https://unsplash.com/photos/V3l7m298DLg',
favicon: 'https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cde267-8f9e-47fa-9aef-5be03bad95ed%2Fapple-touch-icon-1024x1024.png'
}
];
export const RecommendationsPageStyles = `
.gh-portal-recommendation-item {
display: flex;
@ -73,14 +53,16 @@ const RecommendationItem = ({title, url, reason, favicon}) => {
const RecommendationsPage = () => {
const {site, t} = useContext(AppContext);
const {title, icon} = site;
const recommendations = site.recommendations || [];
return (
<div className='gh-portal-content with-footer'>
<div className="gh-portal-recommendations-header">
<img className="gh-portal-signup-logo" alt={site.title} src={site.icon} />
{icon && <img className="gh-portal-signup-logo" alt={title} src={icon} />}
<h1 className="gh-portal-main-title">{t('Recommendations')}</h1>
</div>
<p className="gh-portal-recommendations-description">{t(`Here are a few other sites ${site.title} thinks you may enjoy.`)}</p>
<p className="gh-portal-recommendations-description">{t(`Here are a few other sites ${title} thinks you may enjoy.`)}</p>
<div className="gh-portal-list">
{recommendations.map((recommendation, index) => (

View file

@ -112,6 +112,23 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) {
throw new Error('Failed to fetch offer data');
}
});
},
recommendations() {
const url = contentEndpointFor({resource: 'recommendations'});
return makeRequest({
url,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}).then(function (res) {
if (res.ok) {
return res.json();
} else {
throw new Error('Failed to fetch recommendations');
}
});
}
};
@ -520,17 +537,20 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) {
let newsletters = [];
let tiers = [];
let settings = {};
let recommendations = [];
try {
[{settings}, {tiers}, {newsletters}] = await Promise.all([
[{settings}, {tiers}, {newsletters}, {recommendations}] = await Promise.all([
api.site.settings(),
api.site.tiers(),
api.site.newsletters()
api.site.newsletters(),
api.site.recommendations()
]);
site = {
...settings,
newsletters,
tiers: transformApiTiersData({tiers})
tiers: transformApiTiersData({tiers}),
recommendations
};
} catch (e) {
// Ignore

View file

@ -259,5 +259,9 @@ module.exports = {
get feedbackMembers() {
return apiFramework.pipeline(require('./feedback-members'), localUtils, 'members');
},
get recommendationsPublic() {
return apiFramework.pipeline(require('./recommendations-public'), localUtils, 'content');
}
};

View file

@ -0,0 +1,24 @@
const recommendations = require('../../services/recommendations');
module.exports = {
docName: 'recommendations',
browse: {
headers: {
cacheInvalidate: false
},
options: [
'limit',
'fields',
'filter',
'order',
'debug',
'page'
],
permissions: true,
validation: {},
async query() {
return await recommendations.controller.listRecommendations();
}
}
};

View file

@ -42,5 +42,8 @@ module.exports = function apiRoutes() {
router.get('/collections/:id', mw.authenticatePublic, http(api.collectionsPublic.readById));
router.get('/collections/slug/:slug', mw.authenticatePublic, http(api.collectionsPublic.readBySlug));
// ## Recommendations
router.get('/recommendations', mw.authenticatePublic, http(api.recommendationsPublic.browse));
return router;
};