From 6e7ceec7cf0fe91e90093a46b6c078d4ee224fc0 Mon Sep 17 00:00:00 2001 From: Mark van Aalst Date: Wed, 18 Dec 2024 09:28:45 +0100 Subject: [PATCH 1/4] add filter to list component --- .../lists/accelerate/AccelerateUpdates.tsx | 107 ++++++++++++------ src/pages/index.tsx | 2 +- 2 files changed, 72 insertions(+), 37 deletions(-) diff --git a/src/components/lists/accelerate/AccelerateUpdates.tsx b/src/components/lists/accelerate/AccelerateUpdates.tsx index d0a8376c3..658be4f20 100644 --- a/src/components/lists/accelerate/AccelerateUpdates.tsx +++ b/src/components/lists/accelerate/AccelerateUpdates.tsx @@ -1,6 +1,6 @@ import { AccelerateRecipe } from '@/src/lib/accelerate/types/recipe'; import { Product, Variant } from '@/src/lib/assets'; -import { Box, Card, CardBody, CardHeader, CardProps, chakra, Flex, Heading, HStack, IconButton, Link, SimpleGrid, Stack, Text, useColorModeValue } from '@chakra-ui/react'; +import { Box, Card, CardBody, CardHeader, CardProps, chakra, Flex, Heading, HStack, IconButton, Link, SimpleGrid, Stack, Tab, TabList, TabPanel, TabPanels, Tabs, Text, useColorModeValue } from '@chakra-ui/react'; import { mdiRss } from '@mdi/js'; import Icon from '@mdi/react'; import { TextLink } from '@src/components/links'; @@ -25,52 +25,87 @@ const CustomImage = chakra(Image, { const AccelerateUpdates = ({ title = 'Sitecore Accelerate updates', linkHref = '/learn/accelerate', linkText = 'See all recipes', recipes, hideProductIcon, columns }: AccelerateUpdatesProps) => { return ( - + {title} - } aria-label={'RSS'} colorScheme="primary" variant="ghost" size={'xs'} /> + } aria-label={'RSS'} colorScheme="neutral" variant="ghost" size={'xs'} /> - - {recipes.map((entry, key) => { - return ( - - {!hideProductIcon && ( - - - - )} - - - - {entry.title} - - - - - {new Date(entry.lastUpdated).toLocaleString('en-US', { dateStyle: 'medium' })} - - - - ); - })} - + + + + All + + + XM Cloud + + + Content Hub + + + + + + + + recipe.product === 'XMCloud')} /> + + } aria-label={'RSS'} colorScheme="neutral" variant="ghost" size={'sm'} /> + + + + recipe.product === 'ContentHub')} /> + + } aria-label={'RSS'} colorScheme="neutral" variant="ghost" size={'sm'} /> + + + + ); }; +const RecipeList = ({ recipes, hideProductIcon, columns = 1, show = 5 }: { recipes: AccelerateRecipe[]; hideProductIcon?: boolean; columns?: number; show?: number }) => { + return ( + + {recipes.slice(0, show).map((entry, key) => { + return ( + + {!hideProductIcon && ( + + + + )} + + + + {entry.title} + + + + + {new Date(entry.lastUpdated).toLocaleString('en-US', { dateStyle: 'medium' })} + + + + ); + })} + + ); +}; + export default AccelerateUpdates; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index e1d19f7f0..b1da106b2 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -20,7 +20,7 @@ import { AccelerateRecipe } from '../lib/accelerate/types/recipe'; export async function getStaticProps() { const pageInfo = await getPageInfo('home'); - const recipes = await getLatestRecipes(undefined, 5); + const recipes = await getLatestRecipes(); return { props: { From 22f07e0e69326e645e5f9ddb65d591cd1df6eecd Mon Sep 17 00:00:00 2001 From: Mark van Aalst Date: Wed, 18 Dec 2024 09:28:53 +0100 Subject: [PATCH 2/4] align color rss icon --- src/components/changelog/ChangelogEntries.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/changelog/ChangelogEntries.tsx b/src/components/changelog/ChangelogEntries.tsx index 52b121d99..606c1d8ae 100644 --- a/src/components/changelog/ChangelogEntries.tsx +++ b/src/components/changelog/ChangelogEntries.tsx @@ -55,7 +55,7 @@ const ChangelogEntries = ({ entries, title = 'Sitecore Changelog', linkHref = '/ {title} - } aria-label={'RSS'} colorScheme="primary" variant="ghost" size={'xs'} /> + } aria-label={'RSS'} colorScheme="neutral" variant="ghost" size={'xs'} /> From c8e02b327b9f3a48d835f7f6292d82fcbb6836f8 Mon Sep 17 00:00:00 2001 From: Mark van Aalst Date: Thu, 19 Dec 2024 10:46:07 +0100 Subject: [PATCH 3/4] add pagecontext --- .../pre-development/discovery/index.md | 4 ++- src/components/cards/ChildPagesList.tsx | 25 +++++++++++++++ src/components/markdown/MarkdownContent.tsx | 2 ++ src/context/DeveloperPortalContext.tsx | 32 +++++++++++++++++++ src/hooks/useSidebarNav.ts | 10 +++--- src/lib/interfaces/page-info.ts | 1 + src/lib/utils/cookieUtil.ts | 21 ++++++++++++ src/lib/utils/index.ts | 2 +- src/pages/[...slug].tsx | 16 ++++++++-- src/pages/_app.tsx | 19 ++++++----- 10 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 src/components/cards/ChildPagesList.tsx create mode 100644 src/context/DeveloperPortalContext.tsx create mode 100644 src/lib/utils/cookieUtil.ts diff --git a/data/markdown/pages/learn/accelerate/content-hub/pre-development/discovery/index.md b/data/markdown/pages/learn/accelerate/content-hub/pre-development/discovery/index.md index 1335d8c8c..02287029f 100644 --- a/data/markdown/pages/learn/accelerate/content-hub/pre-development/discovery/index.md +++ b/data/markdown/pages/learn/accelerate/content-hub/pre-development/discovery/index.md @@ -8,4 +8,6 @@ hasInPageNav: false ### Discovery -Discovery is the foundation of every successful implementation. It's where we define the "why," uncover the "what," and plan the "how." In this crucial phase, it's imperative the business needs, align on goals, and chart a path to deliver exceptional digital experiences. From identifying user personas to mapping content strategies, discovery ensures your solution is tailored to drive impact and scalability. \ No newline at end of file +Discovery is the foundation of every successful implementation. It's where we define the "why," uncover the "what," and plan the "how." In this crucial phase, it's imperative the business needs, align on goals, and chart a path to deliver exceptional digital experiences. From identifying user personas to mapping content strategies, discovery ensures your solution is tailored to drive impact and scalability. + + \ No newline at end of file diff --git a/src/components/cards/ChildPagesList.tsx b/src/components/cards/ChildPagesList.tsx new file mode 100644 index 000000000..0ae19f6e2 --- /dev/null +++ b/src/components/cards/ChildPagesList.tsx @@ -0,0 +1,25 @@ +import { usePageContext } from '@/src/context/DeveloperPortalContext'; +import useSidebarNav from '@/src/hooks/useSidebarNav'; +import { getItemUrl } from '@/src/lib/sidebarNav'; +import { CardProps, Link, List, ListItem } from '@chakra-ui/react'; +import { useRouter } from 'next/router'; + +type ChildPagesListProps = CardProps & {}; + +export const ChildPagesList = ({ ...rest }: ChildPagesListProps) => { + const { context } = usePageContext(); + const router = useRouter(); + if (context) { + const { children } = useSidebarNav(context.pageInfo.fileName, context.navigation, router.asPath); + + return ( + + {children?.map((child, i) => ( + + {child.title} + + ))} + + ); + } +}; diff --git a/src/components/markdown/MarkdownContent.tsx b/src/components/markdown/MarkdownContent.tsx index 860db066a..1a3147221 100644 --- a/src/components/markdown/MarkdownContent.tsx +++ b/src/components/markdown/MarkdownContent.tsx @@ -10,6 +10,7 @@ import { NewsletterStory } from '@components/newsletter'; import { ImageModal } from '@components/ui/imageModal'; import { Row } from '@components/ui/sections'; import { YouTube } from '@components/video'; +import { ChildPagesList } from '../cards/ChildPagesList'; import styles from './MarkdownContent.module.css'; /* eslint-disable react/no-unknown-property */ import { MarkdownIntro } from './MarkdownIntro'; @@ -78,6 +79,7 @@ function CustomMdx(children: string) { Td, TableCaption, TableContainer, + ChildPagesList, }} /> ); diff --git a/src/context/DeveloperPortalContext.tsx b/src/context/DeveloperPortalContext.tsx new file mode 100644 index 000000000..f81b037c6 --- /dev/null +++ b/src/context/DeveloperPortalContext.tsx @@ -0,0 +1,32 @@ +import { createContext, ReactNode, useContext, useState } from 'react'; +import { ChildPageInfo, PageInfo, SidebarNavigationConfig } from '../lib/interfaces/page-info'; + +type Context = { + pageInfo: PageInfo; + childPages: Array | []; + navigation: SidebarNavigationConfig; +}; + +// Define the context type +type DeveloperPortalContextType = { + context: Context | undefined; + setContext: (context: Context) => void; +}; + +// Create the context with a default value of null +export const DeveloperPortalContext = createContext(undefined); + +// Create a provider component +export const DeveloperPortalProvider = ({ children }: { children: ReactNode }) => { + const [context, setContext] = useState(); // Initial state is null + + return {children}; +}; + +export const usePageContext = (): DeveloperPortalContextType => { + const context = useContext(DeveloperPortalContext); + if (!context) { + throw new Error('useDeveloperPortalContext must be used within a DeveloperPortalProvider'); + } + return context; +}; diff --git a/src/hooks/useSidebarNav.ts b/src/hooks/useSidebarNav.ts index 033e3417b..044b9bdc7 100644 --- a/src/hooks/useSidebarNav.ts +++ b/src/hooks/useSidebarNav.ts @@ -14,6 +14,7 @@ const useSidebarNav = (fileName: string, sidebarNavConfig: SidebarNavigationConf const [currentItem, setCurrentItem] = useState(null); const [previousItem, setPreviousItem] = useState(null); const [nextItem, setNextItem] = useState(null); + const [children, setChildren] = useState(null); const [parentItem, setParentItem] = useState(null); const [currentLevel, setCurrentLevel] = useState | null>(null); @@ -39,16 +40,12 @@ const useSidebarNav = (fileName: string, sidebarNavConfig: SidebarNavigationConf const parentItem = getParentRoute(sidebarNavConfig.routes, currentItem.path); // Find the previous and next items in the sidebar navigation - - if (root) { - // nextItem = currentItem?.children[1] || null; - } - - // setNextItem(nextItem); setNextItem(nextItem); setCurrentItem(currentItem); + setChildren(currentItem.children); setParentItem(parentItem); setPreviousItem(previousItem); + setCurrentLevel(findCurrentLevel(sidebarNavConfig.routes, currentUrlSegment)); }, [fileName, root, currentPath, sidebarNavConfig]); @@ -58,6 +55,7 @@ const useSidebarNav = (fileName: string, sidebarNavConfig: SidebarNavigationConf previousItem, nextItem, currentLevel, + children, }; }; diff --git a/src/lib/interfaces/page-info.ts b/src/lib/interfaces/page-info.ts index a0dc8d6da..aa0402501 100644 --- a/src/lib/interfaces/page-info.ts +++ b/src/lib/interfaces/page-info.ts @@ -92,6 +92,7 @@ export type SidebarNavigationItem = { ignoreLink?: boolean; children: Array; collapsed?: boolean; + url: string; }; export type ChildPageInfo = PageInfo & { diff --git a/src/lib/utils/cookieUtil.ts b/src/lib/utils/cookieUtil.ts new file mode 100644 index 000000000..0b190c7cb --- /dev/null +++ b/src/lib/utils/cookieUtil.ts @@ -0,0 +1,21 @@ +export const setCookie = (name: string, value: string, days: number) => { + const expires = new Date(); + + expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); + document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/`; +}; + +export const getCookie = (name: string) => { + const cookieArray = document.cookie.split(';'); + + for (let i = 0; i < cookieArray.length; i++) { + const cookiePair = cookieArray[i].split('='); + const cookieName = cookiePair[0].trim(); + + if (cookieName === name) { + return decodeURIComponent(cookiePair[1]); + } + } + + return null; +}; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 48526f600..7e053afc2 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1,5 +1,5 @@ +export * from './cookieUtil'; export * from './dateUtil'; -// export * from './fsUtils'; export * from './requests'; export * from './sortUtil'; export * from './stringUtil'; diff --git a/src/pages/[...slug].tsx b/src/pages/[...slug].tsx index d61898efc..6ff2b66d0 100644 --- a/src/pages/[...slug].tsx +++ b/src/pages/[...slug].tsx @@ -1,11 +1,12 @@ import { ChildPageInfo, PageInfo, SidebarNavigationConfig } from '@lib/interfaces/page-info'; import { getChildNavgationInfo, getChildPageInfo, getPageInfo } from '@lib/page-info'; import { getStaticPathsRecursively } from '@lib/staticPaths'; + import ArticlePage from '@src/layouts/ArticlePage'; import ChildOverviewPage from '@src/layouts/ChildOverviewPage'; import DefaultContentPage from '@src/layouts/DefaultContentPage'; import SocialPage from '@src/layouts/SocialPage'; - +import { usePageContext } from '../context/DeveloperPortalContext'; import NewsLetterPage from '../layouts/NewsLetterPage'; import Tutorial from '../layouts/Tutorial'; @@ -43,9 +44,18 @@ export async function getStaticProps(context: any) { } export default function Slug({ pageInfo, childPageInfo, sidebarNavConfig }: { pageInfo: PageInfo; childPageInfo: Array; sidebarNavConfig: SidebarNavigationConfig }) { + const { context, setContext } = usePageContext(); + if (pageInfo != null) { + setContext({ + pageInfo: pageInfo, + childPages: childPageInfo, + navigation: sidebarNavConfig, + }); + } + // Check for other page types - if (pageInfo.pageType) { - switch (pageInfo.pageType.toLowerCase()) { + if (context != null && context?.pageInfo?.pageType) { + switch (context?.pageInfo?.pageType.toLowerCase()) { case 'childoverview': return ; case 'social': diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index ebe3f7481..458965ae6 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -15,6 +15,7 @@ import { PreviewProvider } from '../context/PreviewContext'; import { scdpTheme } from '../theme'; import { UserProvider } from '@auth0/nextjs-auth0/client'; +import { DeveloperPortalProvider } from '../context/DeveloperPortalContext'; const SearchWrapper = ({ children }: any) => (IsSearchEnabled() ? {children} : children); @@ -91,14 +92,16 @@ function MyApp({ Component, pageProps }: AppProps) { - - {progress && } - - - - -