diff --git a/apps/admin-x-settings/src/api/mentions.ts b/apps/admin-x-settings/src/api/mentions.ts deleted file mode 100644 index 74f9c4e431..0000000000 --- a/apps/admin-x-settings/src/api/mentions.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {InfiniteData} from '@tanstack/react-query'; -import {Meta, createInfiniteQuery} from '../utils/api/hooks'; - -export type Mention = { - id: string; - source: string; - source_title: string|null; - source_site_title: string|null; - source_excerpt: string|null; - source_author: string|null; - source_featured_image: string|null; - source_favicon: string|null; - target: string; - verified: boolean; - created_at: string; -}; - -export interface MentionsResponseType { - meta?: Meta - mentions: Mention[]; -} - -const dataType = 'MentionsResponseType'; - -export const useBrowseMentions = createInfiniteQuery({ - dataType, - path: '/mentions/', - returnData: (originalData) => { - const {pages} = originalData as InfiniteData; - let mentions = pages.flatMap(page => page.mentions); - - // Remove duplicates - mentions = mentions.filter((mention, index) => { - return mentions.findIndex(({id}) => id === mention.id) === index; - }); - - return { - mentions, - meta: pages[pages.length - 1].meta - }; - } -}); diff --git a/apps/admin-x-settings/src/api/recommendations.ts b/apps/admin-x-settings/src/api/recommendations.ts index 6933e6967c..53c6855b9f 100644 --- a/apps/admin-x-settings/src/api/recommendations.ts +++ b/apps/admin-x-settings/src/api/recommendations.ts @@ -99,3 +99,37 @@ export const useGetRecommendationByUrl = () => { } }; }; + +export type IncomingRecommendation = { + id: string + title: string + url: string + excerpt: string|null + featured_image: string|null + favicon: string|null + recommending_back: boolean +} + +export interface IncomingRecommendationResponseType { + meta?: Meta + recommendations: IncomingRecommendation[] +} + +export const useBrowseIncomingRecommendations = createInfiniteQuery({ + dataType, + path: '/incoming_recommendations/', + returnData: (originalData) => { + const {pages} = originalData as InfiniteData; + let recommendations = pages.flatMap(page => page.recommendations); + + // Remove duplicates + recommendations = recommendations.filter((mention, index) => { + return recommendations.findIndex(({id}) => id === mention.id) === index; + }); + + return { + recommendations, + meta: pages[pages.length - 1].meta + }; + } +}); diff --git a/apps/admin-x-settings/src/components/settings/site/Recommendations.tsx b/apps/admin-x-settings/src/components/settings/site/Recommendations.tsx index fb2cb7ea48..a403887107 100644 --- a/apps/admin-x-settings/src/components/settings/site/Recommendations.tsx +++ b/apps/admin-x-settings/src/components/settings/site/Recommendations.tsx @@ -7,8 +7,7 @@ import TabView from '../../../admin-x-ds/global/TabView'; import useRouting from '../../../hooks/useRouting'; import useSettingGroup from '../../../hooks/useSettingGroup'; import {ShowMoreData} from '../../../admin-x-ds/global/Table'; -import {useBrowseMentions} from '../../../api/mentions'; -import {useBrowseRecommendations} from '../../../api/recommendations'; +import {useBrowseIncomingRecommendations, useBrowseRecommendations} from '../../../api/recommendations'; import {useReferrerHistory} from '../../../api/referrers'; import {withErrorBoundary} from '../../../admin-x-ds/global/ErrorBoundary'; @@ -52,11 +51,10 @@ const Recommendations: React.FC<{ keywords: string[] }> = ({keywords}) => { loadMore: fetchNextPage }; - // Fetch "Recommending you" (mentions & stats) - const {data: {mentions, meta: mentionsMeta} = {}, isLoading: areMentionsLoading, hasNextPage: hasMentionsNextPage, fetchNextPage: fetchMentionsNextPage} = useBrowseMentions({ + // Fetch "Recommending you", including stats + const {data: {recommendations: incomingRecommendations, meta: incomingRecommendationsMeta} = {}, isLoading: areIncomingRecommendationsLoading, hasNextPage: hasIncomingRecommendationsNextPage, fetchNextPage: fetchIncomingRecommendationsNextPage} = useBrowseIncomingRecommendations({ searchParams: { limit: '5', - filter: `source:~$'/.well-known/recommendations.json'+verified:true`, order: 'created_at desc' }, @@ -81,12 +79,12 @@ const Recommendations: React.FC<{ keywords: string[] }> = ({keywords}) => { keepPreviousData: true }); - const showMoreMentions: ShowMoreData = { - hasMore: !!hasMentionsNextPage, - loadMore: fetchMentionsNextPage - }; + const {data: {stats} = {}, isLoading: areStatsLoading} = useReferrerHistory({}); - const {data: {stats: mentionsStats} = {}, isLoading: areSourcesLoading} = useReferrerHistory({}); + const showMoreMentions: ShowMoreData = { + hasMore: !!hasIncomingRecommendationsNextPage, + loadMore: fetchIncomingRecommendationsNextPage + }; // Select "Your recommendations" by default const [selectedTab, setSelectedTab] = useState('your-recommendations'); @@ -101,8 +99,8 @@ const Recommendations: React.FC<{ keywords: string[] }> = ({keywords}) => { { id: 'recommending-you', title: `Recommending you`, - counter: mentionsMeta?.pagination?.total, - contents: + counter: incomingRecommendationsMeta?.pagination?.total, + contents: } ]; diff --git a/apps/admin-x-settings/src/components/settings/site/recommendations/IncomingRecommendationList.tsx b/apps/admin-x-settings/src/components/settings/site/recommendations/IncomingRecommendationList.tsx index 31653defbd..87f2f15601 100644 --- a/apps/admin-x-settings/src/components/settings/site/recommendations/IncomingRecommendationList.tsx +++ b/apps/admin-x-settings/src/components/settings/site/recommendations/IncomingRecommendationList.tsx @@ -6,26 +6,26 @@ import Table, {ShowMoreData} from '../../../../admin-x-ds/global/Table'; import TableCell from '../../../../admin-x-ds/global/TableCell'; import TableRow from '../../../../admin-x-ds/global/TableRow'; import useRouting from '../../../../hooks/useRouting'; -import {Mention} from '../../../../api/mentions'; +import {IncomingRecommendation} from '../../../../api/recommendations'; import {PaginationData} from '../../../../hooks/usePagination'; import {ReferrerHistoryItem} from '../../../../api/referrers'; interface IncomingRecommendationListProps { - mentions: Mention[], + incomingRecommendations: IncomingRecommendation[], stats: ReferrerHistoryItem[], pagination?: PaginationData, showMore?: ShowMoreData, isLoading: boolean } -const IncomingRecommendationItem: React.FC<{mention: Mention, stats: ReferrerHistoryItem[]}> = ({mention, stats}) => { - const cleanedSource = mention.source.replace('/.well-known/recommendations.json', ''); +const IncomingRecommendationItem: React.FC<{incomingRecommendation: IncomingRecommendation, stats: ReferrerHistoryItem[]}> = ({incomingRecommendation, stats}) => { + const {updateRoute} = useRouting(); const signups = useMemo(() => { // Note: this should match the `getDomainFromUrl` method from OutboundLinkTagger - let cleanedDomain = cleanedSource; + let cleanedDomain = incomingRecommendation.url; try { - cleanedDomain = new URL(cleanedSource).hostname.replace(/^www\./, ''); + cleanedDomain = new URL(incomingRecommendation.url).hostname.replace(/^www\./, ''); } catch (_) { // Ignore invalid urls } @@ -36,33 +36,33 @@ const IncomingRecommendationItem: React.FC<{mention: Mention, stats: ReferrerHis } return s; }, 0); - }, [stats, cleanedSource]); + }, [stats, incomingRecommendation.url]); - const showDetails = () => { - // Open url - window.open(cleanedSource, '_blank'); + const recommendBack = () => { + updateRoute({route: `recommendations/add?url=${incomingRecommendation.url}`}); }; - const freeMembersLabel = (signups) === 1 ? 'free member' : 'free members'; + const showDetails = () => { + window.open(incomingRecommendation.url, '_blank'); + }; - const {updateRoute} = useRouting(); - - const action = ( -
-
- ); + const freeMembersLabel = signups === 1 ? 'free member' : 'free members'; return ( - + +