Skip to content

Commit

Permalink
Merge pull request #77 from vtexdocs/feat/announcement-navigate-to-ar…
Browse files Browse the repository at this point in the history
…ticle

Feat/announcement navigate to article
  • Loading branch information
PedroAntunesCosta authored Oct 8, 2024
2 parents a3d8ebf + 8d0db77 commit d3692cd
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 69 deletions.
24 changes: 21 additions & 3 deletions src/components/announcement-section/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,35 @@ import styles from './styles'
import AnnouncementTimelineCard from '../announcement-timeline-card'
import Link from 'next/link'

import { AnnouncementDataElement } from 'utils/typings/types'
interface AnnouncementSectionProps {
announcements: { title: string; date: string }[]
announcements: AnnouncementDataElement[]
annoucementsAmout: number
}

const AnnouncementSection = ({ announcements }: AnnouncementSectionProps) => {
const AnnouncementSection = ({
announcements,
annoucementsAmout,
}: AnnouncementSectionProps) => {
function getNewestDate(createdAt: string, updatedAt: string) {
const createdAtTimestamp = Date.parse(createdAt)
const updatedAtTimestamp = Date.parse(updatedAt)

return createdAtTimestamp > updatedAtTimestamp ? createdAt : updatedAt
}
const intl = useIntl()
const newAnnouncements = announcements
.map((announcement) => {
return { title: announcement.title, date: new Date(announcement.date) }
return {
title: announcement.title,
date: new Date(
getNewestDate(announcement.createdAt, announcement.updatedAt)
),
articleLink: announcement.url,
}
})
.sort((a, b) => b.date.getTime() - a.date.getTime())
.slice(0, annoucementsAmout)

return (
<Flex sx={styles.sectionContainer}>
Expand Down
66 changes: 36 additions & 30 deletions src/components/announcement-timeline-card/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Link from 'next/link'
import { Box, Flex, Text, Timeline } from '@vtex/brand-ui'

import { getDaysElapsed } from '../../utils/get-days-elapsed'
Expand All @@ -7,16 +6,19 @@ import { useIntl } from 'react-intl'
import styles from './styles'
import MegaphoneIcon from 'components/icons/megaphone-icon'
import NewIcon from 'components/icons/new-icon'
import Link from 'next/link'

export interface AnnouncementTimelineCardProps {
title: string
date: Date
articleLink: string
first?: boolean
}

const AnnouncementTimelineItem = ({
title,
date,
articleLink,
first = false,
}: AnnouncementTimelineCardProps) => {
const intl = useIntl()
Expand All @@ -29,12 +31,18 @@ const AnnouncementTimelineItem = ({
first ? (
<Text sx={styles.newTitle}>New</Text>
) : (
<Text sx={styles.timelineTitle}>{title}</Text>
<Link href={articleLink}>
<Text sx={styles.timelineTitle}>{title}</Text>
</Link>
)
}
icon={first ? <NewIcon sx={styles.icon} /> : null}
>
{first && <Text sx={styles.timelineTitle}>{title}</Text>}
{first && (
<Link href={articleLink}>
<Text sx={styles.timelineTitle}>{title}</Text>
</Link>
)}
{first && <Box sx={styles.placeholder}></Box>}
<Text sx={styles.content}>
{`${getDaysElapsed(date)} ${intl.formatMessage({
Expand All @@ -57,37 +65,35 @@ const AnnouncementTimelineCard = ({ announcements }: Props) => {
sevenDaysAgo.setDate(currentDate.getDate() - 7)

return (
<Link href={'/announcements'}>
<Flex sx={styles.cardContainer}>
<Box>
<Flex sx={styles.title}>
<MegaphoneIcon />
<Text>
{intl.formatMessage({
id: 'landing_page_announcements.title',
})}
</Text>
</Flex>
<Text sx={styles.description}>
<Flex sx={styles.cardContainer}>
<Box>
<Flex sx={styles.title}>
<MegaphoneIcon />
<Text>
{intl.formatMessage({
id: 'landing_page_announcements.description',
id: 'landing_page_announcements.title',
})}
</Text>
</Box>
<Box sx={styles.timelineContainer}>
{announcements.map((announcement, index) => {
const isNew = announcement.date >= sevenDaysAgo

return (
<AnnouncementTimelineItem
key={index}
{...{ ...announcement, first: isNew || index === 0 }}
/>
)
</Flex>
<Text sx={styles.description}>
{intl.formatMessage({
id: 'landing_page_announcements.description',
})}
</Box>
</Flex>
</Link>
</Text>
</Box>
<Box sx={styles.timelineContainer}>
{announcements.map((announcement, index) => {
const isNew = announcement.date >= sevenDaysAgo

return (
<AnnouncementTimelineItem
key={index}
{...{ ...announcement, first: isNew || index === 0 }}
/>
)
})}
</Box>
</Flex>
)
}

Expand Down
20 changes: 5 additions & 15 deletions src/components/announcement-timeline-card/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,6 @@ const cardContainer: SxStyleProp = {
columnGap: '96px',
rowGap: '64px',
flexWrap: 'wrap',

':active, :hover': {
cursor: 'pointer',
borderColor: '#CCCED8',
transition: 'all 0.3s ease-out',
},

':active': {
boxShadow: '0px 0px 0px 1px #FFFFFF, 0px 0px 0px 3px #96B2F2',
},

':hover': {
boxShadow: '0px 0px 16px rgba(0, 0, 0, 0.1)',
},
}

const title: SxStyleProp = {
Expand Down Expand Up @@ -87,7 +73,11 @@ const timeLineBar: SxStyleProp = {

const timelineTitle: SxStyleProp = {
fontSize: '18px',
color: 'muted.0',
transition: 'all .35s',
color: '#5B6E84',
':hover': {
color: '#142032',
},
}

const content: SxStyleProp = {
Expand Down
92 changes: 71 additions & 21 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import type { Page } from 'utils/typings/types'
import NewsletterSection from 'components/newsletter-section'
import DocumentationSection from 'components/documentation-section'
import AnnouncementSection from 'components/announcement-section'
import SupportSection from 'components/support-section'
import FaqSection from 'components/faq-section'

import { getDocsPaths as getAnnouncementsPaths } from 'utils/getDocsPaths'
import Head from 'next/head'
import styles from 'styles/landing-page'
import getNavigation from 'utils/getNavigation'
import { GetStaticProps } from 'next'
import { useContext } from 'react'
import { PreviewContext } from 'utils/contexts/preview'
import SupportSection from 'components/support-section'
import FaqSection from 'components/faq-section'
import { localeType } from 'utils/navigation-utils'
import getAnnouncementsJson from 'utils/getAnnouncementsJson'
import { AnnouncementDataElement } from 'utils/typings/types'
import { getLogger } from 'utils/logging/log-util'
import { serialize } from 'next-mdx-remote/serialize'

interface Props {
branch: string
announcementTimelineData: { title: string; date: string }[]
announcementTimelineData: AnnouncementDataElement[]
}

const Home: Page<Props> = ({ branch, announcementTimelineData }) => {
Expand All @@ -45,51 +47,99 @@ const Home: Page<Props> = ({ branch, announcementTimelineData }) => {
<DocumentationSection />
<FaqSection />
<SupportSection />
<AnnouncementSection announcements={announcementTimelineData} />
<AnnouncementSection
annoucementsAmout={5}
announcements={announcementTimelineData}
/>
</Grid>
</>
)
}

Home.hideSidebar = true

const docsPathsGLOBAL = await getAnnouncementsPaths('announcements')

export const getStaticProps: GetStaticProps = async ({
locale,
preview,
previewData,
}) => {
const sidebarfallback = await getNavigation()
const previewBranch =
preview && JSON.parse(JSON.stringify(previewData)).hasOwnProperty('branch')
? JSON.parse(JSON.stringify(previewData)).branch
: 'main'
const branch = preview ? previewBranch : 'main'
const logger = getLogger('Announcements')
const currentLocale: localeType = locale
? (locale as localeType)
: ('en' as localeType)

const announcementTimelineData: {
title: string
date: string
}[] = []
const slugs = Object.keys(docsPathsGLOBAL)

const fetchFromGithub = async (path: string, slug: string) => {
try {
const response = await fetch(
`https://raw.githubusercontent.com/vtexdocs/help-center-content/${branch}/${path}`
)
const data = await response.text()
return { content: data, slug }
} catch (error) {
logger.error(`Error fetching data for path ${path}` + ' ' + error)
return { content: '', slug }
}
}

const batchSize = 5

const fetchBatch = async (batch: string[]) => {
const promises = batch.map(async (slug) => {
const path = docsPathsGLOBAL[slug]?.find(
(e) => e.locale === currentLocale
)?.path

const announcementJson = await getAnnouncementsJson()
if (path) return fetchFromGithub(path, slug)

for (let i = 0; i < announcementJson.length; i++) {
const announcement = announcementJson[i]
announcementTimelineData.push({
title: announcement.title[currentLocale],
date: String(announcement.date),
return { content: '', slug }
})

announcementTimelineData.push()
return Promise.all(promises)
}

const announcementsData: AnnouncementDataElement[] = []

for (let i = 0; i < slugs.length; i += batchSize) {
const batch = slugs.slice(i, i + batchSize)
const batchResults = await fetchBatch(batch)

for (const data of batchResults) {
if (data?.content) {
try {
const onlyFrontmatter = `---\n${data.content.split('---')[1]}---\n`

const { frontmatter } = await serialize(onlyFrontmatter, {
parseFrontmatter: true,
})

if (frontmatter) {
announcementsData.push({
title: frontmatter.title,
url: `announcements/${data.slug}`,
createdAt: String(frontmatter.createdAt),
updatedAt: String(frontmatter.updatedAt),
})
}
} catch (error) {
logger.error(`${error}`)
}
}
}
}

return {
props: {
sidebarfallback,
branch,
announcementTimelineData,
branch: branch,
announcementTimelineData: announcementsData,
},
}
}
Expand Down

0 comments on commit d3692cd

Please sign in to comment.