| 1 |
import apiFetch from '@wordpress/api-fetch'; |
| 2 |
import { safeParseJson } from '@shared/lib/parsing'; |
| 3 |
import { create } from 'zustand'; |
| 4 |
import { devtools, persist, createJSONStorage } from 'zustand/middleware'; |
| 5 |
|
| 6 |
const startingState = { |
| 7 |
articles: [], |
| 8 |
recentArticles: [], |
| 9 |
viewedArticles: [], |
| 10 |
searchTerm: '', |
| 11 |
// initialize the state with default values |
| 12 |
...(safeParseJson(window.extHelpCenterData.userData.supportArticlesData) |
| 13 |
?.state ?? {}), |
| 14 |
}; |
| 15 |
|
| 16 |
const state = (set, get) => ({ |
| 17 |
...startingState, |
| 18 |
pushArticle: (article) => { |
| 19 |
const { slug, title } = article; |
| 20 |
const state = get(); |
| 21 |
const lastViewedAt = new Date().toISOString(); |
| 22 |
const firstViewedAt = lastViewedAt; |
| 23 |
const viewed = state.viewedArticles.find((a) => a.slug === slug); |
| 24 |
const viewedArticles = [ |
| 25 |
// Remove the article if it's already in the list |
| 26 |
...state.viewedArticles.filter((a) => a.slug !== slug), |
| 27 |
// Either add the article or update the count |
| 28 |
viewed |
| 29 |
? { ...viewed, count: viewed.count + 1, lastViewedAt } |
| 30 |
: { |
| 31 |
slug, |
| 32 |
title, |
| 33 |
firstViewedAt, |
| 34 |
lastViewedAt, |
| 35 |
count: 1, |
| 36 |
}, |
| 37 |
]; |
| 38 |
|
| 39 |
// Persist the detailed history to the server (don't wait for response) |
| 40 |
apiFetch({ |
| 41 |
path: '/extendify/v1/help-center/support-articles-data', |
| 42 |
method: 'POST', |
| 43 |
data: { state: { viewedArticles } }, |
| 44 |
}); |
| 45 |
|
| 46 |
set({ |
| 47 |
articles: [article, ...state.articles], |
| 48 |
recentArticles: [article, ...state.recentArticles.slice(0, 9)], |
| 49 |
viewedArticles, |
| 50 |
}); |
| 51 |
}, |
| 52 |
popArticle: () => set((state) => ({ articles: state.articles.slice(1) })), |
| 53 |
clearArticles: () => set({ articles: [] }), |
| 54 |
reset: () => set({ articles: [], searchTerm: '' }), |
| 55 |
updateTitle: (slug, title) => |
| 56 |
set((state) => ({ |
| 57 |
articles: state.articles.map((article) => { |
| 58 |
// We don't always know the title until after we fetch the article data |
| 59 |
if (article.slug === slug) { |
| 60 |
article.title = title; |
| 61 |
} |
| 62 |
return article; |
| 63 |
}), |
| 64 |
})), |
| 65 |
clearSearchTerm: () => set({ searchTerm: '' }), |
| 66 |
setSearchTerm: (searchTerm) => set({ searchTerm }), |
| 67 |
}); |
| 68 |
|
| 69 |
export const useKnowledgeBaseStore = create( |
| 70 |
persist(devtools(state, { name: 'Extendify Help Center Knowledge Base' }), { |
| 71 |
name: `extendify-help-center-knowledge-base-${window.extSharedData.siteId}`, |
| 72 |
storage: createJSONStorage(() => sessionStorage), |
| 73 |
}), |
| 74 |
); |
| 75 |
|