Skip to content

Commit

Permalink
feat: display date as time has passed
Browse files Browse the repository at this point in the history
  • Loading branch information
onim-at committed Sep 5, 2024
1 parent d551b2b commit 008f1ed
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 73 deletions.
26 changes: 4 additions & 22 deletions packages/components/src/CommentItem/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createRef, useEffect, useState } from 'react'
import { format, formatDistanceToNow } from 'date-fns'
import { Avatar, Box, Flex, Text } from 'theme-ui'

import defaultProfileImage from '../../assets/images/default_member.svg'
import { Button } from '../Button/Button'
import { ConfirmModal } from '../ConfirmModal/ConfirmModal'
import { DisplayDate } from '../DisplayDate/DisplayDate'
import { EditComment } from '../EditComment/EditComment'
import { LinkifyText } from '../LinkifyText/LinkifyText'
import { Modal } from '../Modal/Modal'
Expand All @@ -23,20 +23,6 @@ export interface IProps {
isReply: boolean
}

const formatDate = (d: string | undefined): string => {
if (!d) {
return ''
}
return format(new Date(d), 'dd MMMM yyyy h:mm a')
}

const relativeDateFormat = (d: string | undefined): string => {
if (!d) {
return ''
}
return formatDistanceToNow(new Date(d), { addSuffix: true })
}

export const CommentItem = (props: IProps) => {
const textRef = createRef<any>()
const [showEditModal, setShowEditModal] = useState(false)
Expand Down Expand Up @@ -66,8 +52,6 @@ export const CommentItem = (props: IProps) => {
isSupporter: !!isUserSupporter,
}

const date = formatDate(_edited || _created)
const relativeDate = relativeDateFormat(_edited || _created)
const maxHeight = isShowMore ? 'max-content' : '128px'
const item = isReply ? 'ReplyItem' : 'CommentItem'

Expand Down Expand Up @@ -132,11 +116,9 @@ export const CommentItem = (props: IProps) => {
}}
>
<Username user={user} />
{_edited && (
<Text sx={{ fontSize: 0, color: 'grey' }}>(Edited)</Text>
)}
<Text sx={{ fontSize: 1 }} title={date}>
{relativeDate}
<Text sx={{ fontSize: 1, color: 'darkGrey' }}>
{_edited && 'Edited '}
<DisplayDate date={_edited || _created} />
</Text>
</Flex>

Expand Down
24 changes: 24 additions & 0 deletions packages/components/src/DisplayDate/DisplayDate.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { subMonths } from 'date-fns'

import { DisplayDate } from './DisplayDate'

import type { Meta, StoryFn } from '@storybook/react'

export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Components/DisplayDate',
component: DisplayDate,
} as Meta<typeof DisplayDate>

export const Default: StoryFn<typeof DisplayDate> = () => {
return (
<>
<DisplayDate date={new Date()}></DisplayDate>
<br />
<DisplayDate date={subMonths(new Date(), 2)}></DisplayDate>
</>
)
}
31 changes: 31 additions & 0 deletions packages/components/src/DisplayDate/DisplayDate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { format, formatDistanceToNow } from 'date-fns'
import { Text } from 'theme-ui'

type DateType = string | number | Date

export interface DisplayDateProps {
date?: DateType
}

const formatDateTime = (date: DateType | undefined) => {
if (!date) {
return ''
}

return format(new Date(date), 'dd-MM-yyyy HH:mm')
}

const relativeDateFormat = (d: DateType | undefined): string => {
if (!d) {
return ''
}
return formatDistanceToNow(new Date(d), { addSuffix: true })
}

export const DisplayDate = ({ date }: DisplayDateProps) => {
console.log(date)
const formattedDate = formatDateTime(date)
const relativeDate = relativeDateFormat(date)

return <Text title={formattedDate}>{relativeDate}</Text>
}
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { ConfirmModal } from './ConfirmModal/ConfirmModal'
export { CreateComment } from './CreateComment/CreateComment'
export { DiscussionContainer } from './DiscussionContainer/DiscussionContainer'
export { DiscussionTitle } from './DiscussionTitle/DiscussionTitle'
export { DisplayDate } from './DisplayDate/DisplayDate'
export { DonationRequest } from './DonationRequest/DonationRequest'
export { DonationRequestModal } from './DonationRequestModal/DonationRequestModal'
export { DownloadButton } from './DownloadButton/DownloadButton'
Expand Down
40 changes: 30 additions & 10 deletions src/pages/Research/Content/ResearchArticle.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { ThemeProvider } from '@emotion/react'
import { faker } from '@faker-js/faker'
import { act, render, waitFor, within } from '@testing-library/react'
import { formatDistanceToNow } from 'date-fns'
import { Provider } from 'mobx-react'
import { ResearchUpdateStatus, UserRole } from 'oa-shared'
import { useResearchStore } from 'src/stores/Research/research.store'
Expand All @@ -19,7 +20,6 @@ import {
} from 'src/test/factories/ResearchItem'
import { FactoryUser } from 'src/test/factories/User'
import { testingThemeStyles } from 'src/test/utils/themeUtils'
import { formatDate } from 'src/utils/date'
import { describe, expect, it, vi } from 'vitest'

import ResearchArticle from './ResearchArticle'
Expand Down Expand Up @@ -263,11 +263,9 @@ describe('Research Article', () => {

it('does not show edit timestamp, when create displays the same value', async () => {
const created = faker.date.past()
const modified = new Date(created)
modified.setHours(15)
const update = FactoryResearchItemUpdate({
_created: created.toString(),
_modified: modified.toString(),
_modified: created.toString(),
title: 'A title',
description: 'A description',
})
Expand All @@ -280,22 +278,32 @@ describe('Research Article', () => {
updates: [update],
}),
})

// Act
const wrapper = getWrapper()

// Assert
await waitFor(() => {
expect(() =>
wrapper.getAllByText(`edited ${formatDate(modified)}`),
wrapper.getAllByText(
`${formatDistanceToNow(update._modified, { addSuffix: true })}`,
),
).toThrow()
})
await waitFor(() => {
expect(() =>
wrapper.getAllByText((content) => content.includes('edited')),
).toThrow()
expect(() =>
wrapper.getAllByText((content) => content.includes('created')),
).not.toThrow()
})
})

it('does show both created and edit timestamp, when different', async () => {
const modified = faker.date.future()
const modified = faker.date.past({ years: 1 })
const created = faker.date.past({ years: 2 })
const update = FactoryResearchItemUpdate({
_created: faker.date.past().toString(),
_created: created.toString(),
status: ResearchUpdateStatus.PUBLISHED,
_modified: modified.toString(),
title: 'A title',
Expand All @@ -314,11 +322,23 @@ describe('Research Article', () => {

// Act
const wrapper = getWrapper()

// Assert
await waitFor(() => {
expect(() =>
wrapper.getAllByText(`edited ${formatDate(modified)}`),
wrapper.getAllByText((content) => content.includes('created')),
).not.toThrow()
expect(() =>
wrapper.getAllByText(
`${formatDistanceToNow(created, { addSuffix: true })}`,
),
).not.toThrow()
expect(() =>
wrapper.getAllByText((content) => content.includes('edited')),
).not.toThrow()
expect(() =>
wrapper.getAllByText(
`${formatDistanceToNow(modified, { addSuffix: true })}`,
),
).not.toThrow()
})
})
Expand Down
24 changes: 13 additions & 11 deletions src/pages/Research/Content/ResearchListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo } from 'react'
import {
Category,
DisplayDate,
Icon,
IconCountWithTooltip,
InternalLink,
Expand All @@ -14,7 +15,6 @@ import {
} from 'oa-shared'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { cdnImageUrl } from 'src/utils/cdnImageUrl'
import { formatDate } from 'src/utils/date'
import { Box, Card, Flex, Grid, Heading, Image, Text } from 'theme-ui'

import defaultResearchThumbnail from '../../../assets/images/default-research-thumbnail.jpg'
Expand Down Expand Up @@ -182,7 +182,7 @@ const ResearchListItem = ({ item }: IProps) => {
</Text>
)}
{/* Hide this on mobile, show on tablet & above. */}
{modifiedDate && (
{modifiedDate !== '' && (
<Text
ml={4}
sx={{
Expand Down Expand Up @@ -301,19 +301,21 @@ const getItemThumbnail = (researchItem: IResearch.Item): string => {
)
}

const getItemDate = (item: IResearch.Item, variant: string): string => {
const getItemDate = (item: IResearch.Item, variant: string) => {
try {
const contentModifiedDate = formatDate(
new Date(item._contentModifiedTimestamp),
const contentModifiedDate = (
<DisplayDate date={item._contentModifiedTimestamp} />
)
const creationDate = formatDate(new Date(item._created))
const creationDate = <DisplayDate date={item._created} />

if (contentModifiedDate !== creationDate) {
return variant === 'long'
? `Updated ${contentModifiedDate}`
: contentModifiedDate
if (item._contentModifiedTimestamp !== item._created) {
return variant === 'long' ? (
<>Updated {contentModifiedDate}</>
) : (
contentModifiedDate
)
} else {
return variant === 'long' ? `Created ${creationDate}` : creationDate
return variant === 'long' ? <>Created {creationDate}</> : creationDate
}
} catch (err) {
return ''
Expand Down
11 changes: 4 additions & 7 deletions src/pages/Research/Content/ResearchUpdate.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Link, useNavigate } from 'react-router-dom'
import {
Button,
DisplayDate,
DownloadCounter,
DownloadFileFromLink,
DownloadStaticFile,
Expand All @@ -13,7 +14,6 @@ import {
import { useContributorsData } from 'src/common/hooks/contributorsData'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { useResearchStore } from 'src/stores/Research/research.store'
import { formatDate } from 'src/utils/date'
import { formatImagesForGallery } from 'src/utils/formatImageListForGallery'
import { Box, Card, Flex, Heading, Text } from 'theme-ui'

Expand Down Expand Up @@ -51,8 +51,6 @@ const ResearchUpdate = (props: IProps) => {
const loggedInUser = useCommonStores().stores.userStore.activeUser

const contributors = useContributorsData(collaborators || [])
const formattedCreateDatestamp = formatDate(new Date(_created))
const formattedModifiedDatestamp = formatDate(new Date(_modified))
const research = researchStore.activeResearchItem

const handleDownloadClick = async () => {
Expand Down Expand Up @@ -154,18 +152,17 @@ const ResearchUpdate = (props: IProps) => {
textAlign: ['left', 'right', 'right'],
}}
>
{'created ' + formattedCreateDatestamp}
created <DisplayDate date={_created} />
</Text>

{formattedCreateDatestamp !==
formattedModifiedDatestamp && (
{_created !== _modified && (
<Text
variant="auxiliary"
sx={{
textAlign: ['left', 'right', 'right'],
}}
>
{'edited ' + formattedModifiedDatestamp}
edited <DisplayDate date={_modified} />
</Text>
)}
</Flex>
Expand Down
13 changes: 3 additions & 10 deletions src/pages/common/ContentAuthorTimestamp/ContentAuthorTimestamp.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatDate } from 'src/utils/date'
import { DisplayDate } from 'oa-components'
import { Box, Text } from 'theme-ui'

import { UserNameTag } from '../UserNameTag/UserNameTag'
Expand All @@ -18,13 +18,6 @@ export const ContentAuthorTimestamp = ({
modified,
action,
}: ContentAuthorTimestampProps) => {
const contentModifiedDate = formatDate(new Date(modified))
const creationDate = formatDate(new Date(created))
const modifiedDateText =
contentModifiedDate !== creationDate
? `Last update on ${contentModifiedDate}`
: ''

return (
<Box>
<UserNameTag
Expand All @@ -34,7 +27,7 @@ export const ContentAuthorTimestamp = ({
action={action}
/>
<Text
hidden={!modifiedDateText}
hidden={created === modified}
variant="auxiliary"
sx={{
color: 'lightgrey',
Expand All @@ -45,7 +38,7 @@ export const ContentAuthorTimestamp = ({
mt={1}
mb={2}
>
{modifiedDateText}
Last update <DisplayDate date={modified} />
</Text>
</Box>
)
Expand Down
6 changes: 2 additions & 4 deletions src/pages/common/UserNameTag/UserNameTag.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Username } from 'oa-components'
import { DisplayDate, Username } from 'oa-components'
import { useCommonStores } from 'src/common/hooks/useCommonStores'
import { formatDate } from 'src/utils/date'
import { Flex, Text } from 'theme-ui'

interface UserNameTagProps {
Expand All @@ -18,7 +17,6 @@ export const UserNameTag = ({
}: UserNameTagProps) => {
const { aggregationsStore } = useCommonStores().stores

const dateText = `| ${action} on ${formatDate(new Date(created))}`
const isVerified = aggregationsStore.isVerified(userName)

return (
Expand All @@ -40,7 +38,7 @@ export const UserNameTag = ({
marginBottom: 2,
}}
>
{dateText}
| {action} <DisplayDate date={created}></DisplayDate>
</Text>
</Flex>
</Flex>
Expand Down
9 changes: 0 additions & 9 deletions src/utils/date.ts

This file was deleted.

0 comments on commit 008f1ed

Please sign in to comment.