import { createContext, useContext } from 'react' import pick from 'lodash/pick' export type TocItem = { fullPath: string title: string intro?: string childTocItems?: Array<{ fullPath: string title: string }> } export type FeaturedLink = { title: string href: string intro?: string authors?: Array hideIntro?: boolean date?: string fullTitle?: string } export type CodeExample = { title: string description: string languages: string // single comma separated string href: string tags: Array } export type Product = { title: string href: string } export type ProductLandingContextT = { title: string introPlainText: string shortTitle: string intro: string beta_product: boolean product: Product introLinks: Record | null product_video?: string featuredLinks: Record> productCodeExamples: Array productUserExamples: Array<{ username: string; description: string }> productCommunityExamples: Array<{ repo: string; description: string }> featuredArticles: Array<{ label: string // Guides viewAllHref?: string // If provided, adds a "View All ->" to the header viewAllTitleText?: string // Adds 'title' attribute text for the "View All" href articles: Array }> changelogUrl?: string whatsNewChangelog?: Array<{ href: string; title: string; date: string }> tocItems: Array hasGuidesPage: boolean releases: Array<{ version: string firstPreviousRelease: string secondPreviousRelease: string patches: Array<{ date: string; version: string }> }> } export const ProductLandingContext = createContext(null) export const useProductLandingContext = (): ProductLandingContextT => { const context = useContext(ProductLandingContext) if (!context) { throw new Error( '"useProductLandingContext" may only be used inside "ProductLandingContext.Provider"' ) } return context } export const getFeaturedLinksFromReq = (req: any): Record> => { return Object.fromEntries( Object.entries(req.context.featuredLinks || {}).map(([key, entries]) => { return [ key, ((entries as Array) || []).map((entry: any) => ({ href: entry.href, title: entry.title, intro: entry.intro || null, authors: entry.page?.authors || [], fullTitle: entry.fullTitle || null, })), ] }) ) } export const getProductLandingContextFromRequest = (req: any): ProductLandingContextT => { const productTree = req.context.currentProductTree const page = req.context.page const hasGuidesPage = (page.children || []).includes('/guides') return { ...pick(page, [ 'title', 'shortTitle', 'introPlainText', 'beta_product', 'intro', 'product_video', ]), hasGuidesPage, product: { href: productTree.href, title: productTree.renderedShortTitle || productTree.renderedFullTitle, }, whatsNewChangelog: req.context.whatsNewChangelog || [], changelogUrl: req.context.changelogUrl || [], productCodeExamples: req.context.productCodeExamples || [], productCommunityExamples: req.context.productCommunityExamples || [], releases: req.context.releases || [], productUserExamples: (req.context.productUserExamples || []).map( ({ user, description }: any) => ({ username: user, description, }) ), introLinks: page.introLinks || null, featuredLinks: getFeaturedLinksFromReq(req), tocItems: req.context.tocItems || [], featuredArticles: Object.entries(req.context.featuredLinks || []) .filter(([key]) => { return key === 'guides' || key === 'popular' || key === 'videos' }) .map(([key, links]: any) => { return { label: key === 'popular' || key === 'videos' ? req.context.page.featuredLinks[key + 'Heading'] || req.context.site.data.ui.toc[key] : req.context.site.data.ui.toc[key], viewAllHref: key === 'guides' && !req.context.currentCategory && hasGuidesPage ? `${req.context.currentPath}/guides` : '', articles: links.map((link: any) => { return { hideIntro: key === 'popular', href: link.href, title: link.title, intro: link.intro || null, authors: link.page?.authors || [], fullTitle: link.fullTitle || null, } }), } }), } }