diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/atoms/layout/copyright.tsx | 39 | ||||
| -rw-r--r-- | src/components/atoms/layout/index.ts | 1 | ||||
| -rw-r--r-- | src/components/atoms/layout/time/index.ts | 1 | ||||
| -rw-r--r-- | src/components/atoms/layout/time/time.stories.tsx | 32 | ||||
| -rw-r--r-- | src/components/atoms/layout/time/time.test.tsx | 39 | ||||
| -rw-r--r-- | src/components/atoms/layout/time/time.tsx | 136 | ||||
| -rw-r--r-- | src/components/organisms/layout/comment.fixture.ts | 4 | ||||
| -rw-r--r-- | src/components/organisms/layout/comment.test.tsx | 10 | ||||
| -rw-r--r-- | src/components/organisms/layout/comment.tsx | 20 | ||||
| -rw-r--r-- | src/components/organisms/layout/summary.tsx | 18 | ||||
| -rw-r--r-- | src/i18n/en.json | 8 | ||||
| -rw-r--r-- | src/i18n/fr.json | 8 | ||||
| -rw-r--r-- | src/pages/article/[slug].tsx | 18 | ||||
| -rw-r--r-- | src/pages/cv.tsx | 18 | ||||
| -rw-r--r-- | src/pages/index.tsx | 15 | ||||
| -rw-r--r-- | src/pages/mentions-legales.tsx | 18 | ||||
| -rw-r--r-- | src/pages/projets/[slug].tsx | 22 | ||||
| -rw-r--r-- | src/pages/sujet/[slug].tsx | 18 | ||||
| -rw-r--r-- | src/pages/thematique/[slug].tsx | 18 | ||||
| -rw-r--r-- | src/utils/helpers/dates.ts | 40 | ||||
| -rw-r--r-- | src/utils/helpers/index.ts | 1 | 
21 files changed, 263 insertions, 221 deletions
| diff --git a/src/components/atoms/layout/copyright.tsx b/src/components/atoms/layout/copyright.tsx index c60ff8b..3d56059 100644 --- a/src/components/atoms/layout/copyright.tsx +++ b/src/components/atoms/layout/copyright.tsx @@ -1,5 +1,6 @@  import type { FC, ReactNode } from 'react';  import styles from './copyright.module.scss'; +import { Time } from './time';  export type CopyrightDates = {    /** @@ -32,26 +33,18 @@ export type CopyrightProps = {   *   * Renders a copyright information (owner, dates, license icon).   */ -export const Copyright: FC<CopyrightProps> = ({ owner, dates, icon }) => { -  const getFormattedDate = (date: string) => { -    const datetime = new Date(date).toISOString(); - -    return <time dateTime={datetime}>{date}</time>; -  }; - -  return ( -    <div className={styles.wrapper}> -      <span className={styles.owner}>{owner}</span> -      {icon} -      {getFormattedDate(dates.start)} -      {dates.end ? ( -        <> -          <span>-</span> -          {getFormattedDate(dates.end)} -        </> -      ) : ( -        '' -      )} -    </div> -  ); -}; +export const Copyright: FC<CopyrightProps> = ({ owner, dates, icon }) => ( +  <div className={styles.wrapper}> +    <span className={styles.owner}>{owner}</span> +    {icon} +    <Time date={dates.start} hideDay hideMonth /> +    {dates.end ? ( +      <> +        <span>-</span> +        <Time date={dates.end} hideDay hideMonth /> +      </> +    ) : ( +      '' +    )} +  </div> +); diff --git a/src/components/atoms/layout/index.ts b/src/components/atoms/layout/index.ts index 3f2f8dc..c37ff02 100644 --- a/src/components/atoms/layout/index.ts +++ b/src/components/atoms/layout/index.ts @@ -6,3 +6,4 @@ export * from './header';  export * from './main';  export * from './nav';  export * from './section'; +export * from './time'; diff --git a/src/components/atoms/layout/time/index.ts b/src/components/atoms/layout/time/index.ts new file mode 100644 index 0000000..47e4e1f --- /dev/null +++ b/src/components/atoms/layout/time/index.ts @@ -0,0 +1 @@ +export * from './time'; diff --git a/src/components/atoms/layout/time/time.stories.tsx b/src/components/atoms/layout/time/time.stories.tsx new file mode 100644 index 0000000..d534f14 --- /dev/null +++ b/src/components/atoms/layout/time/time.stories.tsx @@ -0,0 +1,32 @@ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import { Time } from './time'; + +/** + * Time - Storybook Meta + */ +export default { +  title: 'Atoms/Layout/Time', +  component: Time, +  argTypes: { +    date: { +      control: { +        type: 'text', +      }, +      description: 'A valid date string.', +      type: { +        name: 'string', +        required: true, +      }, +    }, +  }, +} as ComponentMeta<typeof Time>; + +const Template: ComponentStory<typeof Time> = (args) => <Time {...args} />; + +/** + * Time Stories - Default + */ +export const Default = Template.bind({}); +Default.args = { +  date: '2022-03-15 10:44:20', +}; diff --git a/src/components/atoms/layout/time/time.test.tsx b/src/components/atoms/layout/time/time.test.tsx new file mode 100644 index 0000000..910285d --- /dev/null +++ b/src/components/atoms/layout/time/time.test.tsx @@ -0,0 +1,39 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen as rtlScreen } from '../../../../../tests/utils'; +import { settings } from '../../../../utils/config'; +import { Time } from './time'; + +describe('Time', () => { +  it('renders a date wrapped in a time element', () => { +    const date = '2022'; + +    render(<Time date={date} />); + +    expect(rtlScreen.getByText(new RegExp(date))).toHaveAttribute( +      'datetime', +      new Date(date).toISOString() +    ); +  }); + +  it('can show the time in addition to the date', () => { +    const date = '2022'; + +    render(<Time date={date} showTime />); + +    expect(rtlScreen.getByText(new RegExp(date))).toHaveTextContent(/\sat\s/); +  }); + +  it('can show the week day in front of the date', () => { +    const date = new Date(); + +    render(<Time date={date.toDateString()} showWeekDay />); + +    expect( +      rtlScreen.getByText(new RegExp(`${date.getFullYear()}`)) +    ).toHaveTextContent( +      new Intl.DateTimeFormat(settings.locales.defaultLocale, { +        weekday: 'long', +      }).format(date) +    ); +  }); +}); diff --git a/src/components/atoms/layout/time/time.tsx b/src/components/atoms/layout/time/time.tsx new file mode 100644 index 0000000..02b4763 --- /dev/null +++ b/src/components/atoms/layout/time/time.tsx @@ -0,0 +1,136 @@ +import { +  type ForwardRefRenderFunction, +  type TimeHTMLAttributes, +  forwardRef, +} from 'react'; +import { useIntl } from 'react-intl'; +import { settings } from '../../../../utils/config'; + +type GetDateOptionsConfig = { +  hasDay: boolean; +  hasMonth: boolean; +  hasWeekDay: boolean; +  hasYear: boolean; +}; + +const getDateOptions = ({ +  hasDay, +  hasMonth, +  hasWeekDay, +  hasYear, +}: GetDateOptionsConfig): Intl.DateTimeFormatOptions => { +  const day: Intl.DateTimeFormatOptions['day'] = 'numeric'; +  const month: Intl.DateTimeFormatOptions['month'] = 'long'; +  const weekDay: Intl.DateTimeFormatOptions['weekday'] = 'long'; +  const year: Intl.DateTimeFormatOptions['year'] = 'numeric'; +  const options: [ +    keyof Intl.DateTimeFormatOptions, +    Intl.DateTimeFormatOptions[keyof Intl.DateTimeFormatOptions], +  ][] = []; + +  if (hasDay) options.push(['day', day]); +  if (hasMonth) options.push(['month', month]); +  if (hasWeekDay) options.push(['weekday', weekDay]); +  if (hasYear) options.push(['year', year]); + +  return Object.fromEntries(options); +}; + +export type TimeProps = Omit< +  TimeHTMLAttributes<HTMLTimeElement>, +  'children' | 'dateTime' +> & { +  /** +   * A valid date string. +   */ +  date: string; +  /** +   * Should we hide the day number? +   * +   * @default false +   */ +  hideDay?: boolean; +  /** +   * Should we hide the month? +   * +   * @default false +   */ +  hideMonth?: boolean; +  /** +   * Should we hide the year? +   * +   * @default false +   */ +  hideYear?: boolean; +  /** +   * The current locale. +   * +   * @default settings.locales.defaultLocale +   */ +  locale?: string; +  /** +   * Should we display the time in addition to the date? +   * +   * @default false +   */ +  showTime?: boolean; +  /** +   * Should we display the week day? +   * +   * @default false +   */ +  showWeekDay?: boolean; +}; + +const TimeWithRef: ForwardRefRenderFunction<HTMLTimeElement, TimeProps> = ( +  { +    date, +    hideDay = false, +    hideMonth = false, +    hideYear = false, +    locale = settings.locales.defaultLocale, +    showTime = false, +    showWeekDay = false, +    ...props +  }, +  ref +) => { +  const intl = useIntl(); +  const dateOptions = getDateOptions({ +    hasDay: !hideDay, +    hasMonth: !hideMonth, +    hasWeekDay: showWeekDay, +    hasYear: !hideYear, +  }); +  const fullDate = new Date(date); +  const dateTime = fullDate.toISOString(); +  const readableDate = fullDate.toLocaleDateString(locale, dateOptions); +  const formattedTime = fullDate.toLocaleTimeString(locale, { +    hour: 'numeric', +    minute: 'numeric', +  }); +  const readableTime = +    locale === 'fr' ? formattedTime.replace(':', 'h') : formattedTime; + +  return ( +    <time {...props} dateTime={dateTime} ref={ref}> +      {showTime +        ? intl.formatMessage( +            { +              defaultMessage: '{date} at {time}', +              description: 'Time: readable date and time', +              id: '8q5PXx', +            }, +            { date: readableDate, time: readableTime } +          ) +        : readableDate} +    </time> +  ); +}; + +/** + * Time component. + * + * Render a date with an optional time in a `<time>` element. + */ +export const Time = forwardRef(TimeWithRef); diff --git a/src/components/organisms/layout/comment.fixture.ts b/src/components/organisms/layout/comment.fixture.ts index f626be9..bb18d22 100644 --- a/src/components/organisms/layout/comment.fixture.ts +++ b/src/components/organisms/layout/comment.fixture.ts @@ -1,4 +1,3 @@ -import { getFormattedDate, getFormattedTime } from '../../../utils/helpers';  import type { UserCommentProps } from './comment';  export const author = { @@ -36,6 +35,3 @@ export const data: UserCommentProps = {    parentId: 0,    saveComment,  }; - -export const formattedDate = getFormattedDate(date); -export const formattedTime = getFormattedTime(date); diff --git a/src/components/organisms/layout/comment.test.tsx b/src/components/organisms/layout/comment.test.tsx index b64f84a..0e0ea3a 100644 --- a/src/components/organisms/layout/comment.test.tsx +++ b/src/components/organisms/layout/comment.test.tsx @@ -1,13 +1,7 @@  import { describe, expect, it } from '@jest/globals';  import { render, screen as rtlScreen } from '../../../../tests/utils';  import { UserComment } from './comment'; -import { -  author, -  data, -  formattedDate, -  formattedTime, -  id, -} from './comment.fixture'; +import { author, data, id } from './comment.fixture';  describe('UserComment', () => {    it('renders an avatar', () => { @@ -29,7 +23,7 @@ describe('UserComment', () => {      render(<UserComment canReply={true} {...data} />);      expect(        rtlScreen.getByRole('link', { -        name: `${formattedDate} at ${formattedTime}`, +        name: /\sat\s/,        })      ).toHaveAttribute('href', `#comment-${id}`);    }); diff --git a/src/components/organisms/layout/comment.tsx b/src/components/organisms/layout/comment.tsx index e1ea6b5..cb2f16f 100644 --- a/src/components/organisms/layout/comment.tsx +++ b/src/components/organisms/layout/comment.tsx @@ -5,9 +5,8 @@ import { type FC, useCallback, useState } from 'react';  import { useIntl } from 'react-intl';  import type { Comment as CommentSchema, WithContext } from 'schema-dts';  import type { SingleComment } from '../../../types'; -import { getFormattedDate, getFormattedTime } from '../../../utils/helpers';  import { useSettings } from '../../../utils/hooks'; -import { Button, Link } from '../../atoms'; +import { Button, Link, Time } from '../../atoms';  import { MetaList } from '../../molecules';  import { CommentForm, type CommentFormProps } from '../forms';  import styles from './comment.module.scss'; @@ -61,21 +60,6 @@ export const UserComment: FC<UserCommentProps> = ({    }    const { author, date } = meta; -  const [publicationDate, publicationTime] = date.split(' '); -  const isoDateTime = new Date( -    `${publicationDate}T${publicationTime}` -  ).toISOString(); -  const commentDate = intl.formatMessage( -    { -      defaultMessage: '{date} at {time}', -      description: 'Comment: publication date and time', -      id: 'Ld6yMP', -    }, -    { -      date: getFormattedDate(publicationDate), -      time: getFormattedTime(`${publicationDate}T${publicationTime}`), -    } -  );    const buttonLabel = isReplying      ? intl.formatMessage({ @@ -163,7 +147,7 @@ export const UserComment: FC<UserCommentProps> = ({                }),                value: (                  <Link href={`#comment-${id}`}> -                  <time dateTime={isoDateTime}>{commentDate}</time> +                  <Time date={date} showTime />                  </Link>                ),              }, diff --git a/src/components/organisms/layout/summary.tsx b/src/components/organisms/layout/summary.tsx index f5c16cd..4fe7632 100644 --- a/src/components/organisms/layout/summary.tsx +++ b/src/components/organisms/layout/summary.tsx @@ -2,7 +2,6 @@ import NextImage, { type ImageProps as NextImageProps } from 'next/image';  import type { FC, ReactNode } from 'react';  import { useIntl } from 'react-intl';  import type { Article, Meta as MetaType } from '../../../types'; -import { getFormattedDate } from '../../../utils/helpers';  import { useReadingTime } from '../../../utils/hooks';  import {    ButtonLink, @@ -11,6 +10,7 @@ import {    Icon,    Link,    Figure, +  Time,  } from '../../atoms';  import { MetaList, type MetaItemData } from '../../molecules';  import styles from './summary.module.scss'; @@ -72,18 +72,6 @@ export const Summary: FC<SummaryProps> = ({    );    const readingTime = useReadingTime(meta.wordsCount, true); -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const getMetaItems = (): MetaItemData[] => {      const summaryMeta: MetaItemData[] = [        { @@ -93,7 +81,7 @@ export const Summary: FC<SummaryProps> = ({            description: 'Summary: publication date label',            id: 'TvQ2Ee',          }), -        value: getDate(meta.dates.publication), +        value: <Time date={meta.dates.publication} />,        },      ]; @@ -105,7 +93,7 @@ export const Summary: FC<SummaryProps> = ({            description: 'Summary: update date label',            id: 'f0Z/Po',          }), -        value: getDate(meta.dates.update), +        value: <Time date={meta.dates.update} />,        });      summaryMeta.push({ diff --git a/src/i18n/en.json b/src/i18n/en.json index 92a0c45..9bfe248 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -155,6 +155,10 @@      "defaultMessage": "{website} picture",      "description": "Layout: photo alternative text"    }, +  "8q5PXx": { +    "defaultMessage": "{date} at {time}", +    "description": "Time: readable date and time" +  },    "9DfuHk": {      "defaultMessage": "Updated on:",      "description": "TopicPage: update date label" @@ -299,10 +303,6 @@      "defaultMessage": "Close search",      "description": "Search: Close label"    }, -  "Ld6yMP": { -    "defaultMessage": "{date} at {time}", -    "description": "Comment: publication date and time" -  },    "LszkU6": {      "defaultMessage": "All posts in {thematicName}",      "description": "ThematicPage: posts list heading" diff --git a/src/i18n/fr.json b/src/i18n/fr.json index f602b20..a988729 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -155,6 +155,10 @@      "defaultMessage": "Photo d’{website}",      "description": "Layout: photo alternative text"    }, +  "8q5PXx": { +    "defaultMessage": "{date} à {time}", +    "description": "Time: readable date and time" +  },    "9DfuHk": {      "defaultMessage": "Mis à jour le :",      "description": "TopicPage: update date label" @@ -299,10 +303,6 @@      "defaultMessage": "Fermer la recherche",      "description": "Search: Close label"    }, -  "Ld6yMP": { -    "defaultMessage": "{date} à {time}", -    "description": "Comment: publication date and time" -  },    "LszkU6": {      "defaultMessage": "Tous les articles dans {thematicName}",      "description": "ThematicPage: posts list heading" diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index bce493b..dea240f 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -15,6 +15,7 @@ import {    Sharing,    Spinner,    type MetaItemData, +  Time,  } from '../../components';  import {    getAllArticlesSlugs, @@ -26,7 +27,6 @@ import type { Article, NextPageWithLayout, SingleComment } from '../../types';  import { ROUTES } from '../../utils/constants';  import {    getBlogSchema, -  getFormattedDate,    getSchemaJson,    getSinglePageSchema,    getWebPageSchema, @@ -83,18 +83,6 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({    const { content, id, intro, meta, title } = article;    const { author, commentsCount, cover, dates, seo, thematics, topics } = meta; -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      author        ? { @@ -114,7 +102,7 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({          description: 'ArticlePage: publication date label',          id: 'RecdwX',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update && dates.publication !== dates.update        ? { @@ -124,7 +112,7 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({              description: 'ArticlePage: update date label',              id: 'ZAqGZ6',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,      { diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index 652b913..d9f7031 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -20,13 +20,13 @@ import {    SocialMedia,    ListItem,    type MetaItemData, +  Time,  } from '../components';  import CVContent, { data, meta } from '../content/pages/cv.mdx';  import styles from '../styles/pages/cv.module.scss';  import type { NextPageWithLayout } from '../types';  import { PERSONAL_LINKS, ROUTES } from '../utils/constants';  import { -  getFormattedDate,    getSchemaJson,    getSinglePageSchema,    getWebPageSchema, @@ -153,18 +153,6 @@ const CVPage: NextPageWithLayout = () => {      id: '+Dre5J',    }); -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      {        id: 'publication-date', @@ -173,7 +161,7 @@ const CVPage: NextPageWithLayout = () => {          description: 'Page: publication date label',          id: '4QbTDq',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update        ? { @@ -183,7 +171,7 @@ const CVPage: NextPageWithLayout = () => {              description: 'Page: update date label',              id: 'Ez8Qim',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,    ]; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index cdc51c5..fb6ba9a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -21,17 +21,14 @@ import {    type SectionProps,    Heading,    Figure, +  Time,  } from '../components';  import HomePageContent from '../content/pages/homepage.mdx';  import { getArticlesCard } from '../services/graphql';  import styles from '../styles/pages/home.module.scss';  import type { ArticleCard, NextPageWithLayout } from '../types';  import { PERSONAL_LINKS, ROUTES } from '../utils/constants'; -import { -  getFormattedDate, -  getSchemaJson, -  getWebPageSchema, -} from '../utils/helpers'; +import { getSchemaJson, getWebPageSchema } from '../utils/helpers';  import { loadTranslation, type Messages } from '../utils/helpers/server';  import { useBreadcrumb, useSettings } from '../utils/hooks'; @@ -301,8 +298,6 @@ const HomePage: NextPageWithLayout<HomeProps> = ({ recentPosts }) => {     */    const getRecentPosts = (): JSX.Element => {      const posts: CardsListItem[] = recentPosts.map((post) => { -      const isoDate = new Date(`${post.dates.publication}`).toISOString(); -        return {          cover: post.cover,          id: post.slug, @@ -310,11 +305,7 @@ const HomePage: NextPageWithLayout<HomeProps> = ({ recentPosts }) => {            {              id: 'publication-date',              label: publicationDate, -            value: ( -              <time dateTime={isoDate}> -                {getFormattedDate(post.dates.publication)} -              </time> -            ), +            value: <Time date={post.dates.publication} />,            },          ],          title: post.title, diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx index 25c2dd9..4e14d90 100644 --- a/src/pages/mentions-legales.tsx +++ b/src/pages/mentions-legales.tsx @@ -12,12 +12,12 @@ import {    PageLayout,    Figure,    type MetaItemData, +  Time,  } from '../components';  import LegalNoticeContent, { meta } from '../content/pages/legal-notice.mdx';  import type { NextPageWithLayout } from '../types';  import { ROUTES } from '../utils/constants';  import { -  getFormattedDate,    getSchemaJson,    getSinglePageSchema,    getWebPageSchema, @@ -47,18 +47,6 @@ const LegalNoticePage: NextPageWithLayout = () => {      url: ROUTES.LEGAL_NOTICE,    }); -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      {        id: 'publication-date', @@ -67,7 +55,7 @@ const LegalNoticePage: NextPageWithLayout = () => {          description: 'Page: publication date label',          id: '4QbTDq',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update        ? { @@ -77,7 +65,7 @@ const LegalNoticePage: NextPageWithLayout = () => {              description: 'Page: update date label',              id: 'Ez8Qim',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,    ]; diff --git a/src/pages/projets/[slug].tsx b/src/pages/projets/[slug].tsx index 6ef3df5..3d3c57e 100644 --- a/src/pages/projets/[slug].tsx +++ b/src/pages/projets/[slug].tsx @@ -24,12 +24,12 @@ import {    Figure,    type MetaItemData,    type MetaValues, +  Time,  } from '../../components';  import styles from '../../styles/pages/project.module.scss';  import type { NextPageWithLayout, ProjectPreview, Repos } from '../../types';  import { ROUTES } from '../../utils/constants';  import { -  getFormattedDate,    getSchemaJson,    getSinglePageSchema,    getWebPageSchema, @@ -167,18 +167,6 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {      url: `${website.url}${asPath}`,    }; -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      {        id: 'publication-date', @@ -187,7 +175,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {          description: 'ProjectsPage: publication date label',          id: 'HxZvY4',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update && dates.update !== dates.publication        ? { @@ -197,7 +185,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {              description: 'ProjectsPage: update date label',              id: 'wQrvgw',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,    ]; @@ -299,7 +287,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {          description: 'ProjectsPage: creation date label',          id: 'wVFA4m',        }), -      value: getDate(data.created_at), +      value: <Time date={data.created_at} />,      },      {        id: 'update-date', @@ -308,7 +296,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {          description: 'ProjectsPage: update date label',          id: 'wQrvgw',        }), -      value: getDate(data.updated_at), +      value: <Time date={data.updated_at} />,      },      license        ? { diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index cacc972..87c3340 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -13,6 +13,7 @@ import {    type MetaItemData,    PageLayout,    PostsList, +  Time,  } from '../../components';  import {    getAllTopicsSlugs, @@ -24,7 +25,6 @@ import styles from '../../styles/pages/topic.module.scss';  import type { NextPageWithLayout, PageLink, Topic } from '../../types';  import { ROUTES } from '../../utils/constants';  import { -  getFormattedDate,    getLinksListItems,    getPageLinkFromRawData,    getPostsWithUrl, @@ -60,18 +60,6 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({      url: `${ROUTES.TOPICS}/${slug}`,    }); -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      {        id: 'publication-date', @@ -80,7 +68,7 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({          description: 'TopicPage: publication date label',          id: 'KV+NMZ',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update        ? { @@ -90,7 +78,7 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({              description: 'TopicPage: update date label',              id: '9DfuHk',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,      officialWebsite diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index a5badf3..8e21ff6 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -12,6 +12,7 @@ import {    type MetaItemData,    PageLayout,    PostsList, +  Time,  } from '../../components';  import {    getAllThematicsSlugs, @@ -22,7 +23,6 @@ import {  import type { NextPageWithLayout, PageLink, Thematic } from '../../types';  import { ROUTES } from '../../utils/constants';  import { -  getFormattedDate,    getLinksListItems,    getPageLinkFromRawData,    getPostsWithUrl, @@ -51,18 +51,6 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({      url: `${ROUTES.THEMATICS.INDEX}/${slug}`,    }); -  /** -   * Retrieve a formatted date (and time). -   * -   * @param {string} date - A date string. -   * @returns {JSX.Element} The formatted date wrapped in a time element. -   */ -  const getDate = (date: string): JSX.Element => { -    const isoDate = new Date(`${date}`).toISOString(); - -    return <time dateTime={isoDate}>{getFormattedDate(date)}</time>; -  }; -    const headerMeta: (MetaItemData | undefined)[] = [      {        id: 'publication-date', @@ -71,7 +59,7 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({          description: 'ThematicPage: publication date label',          id: 'UTGhUU',        }), -      value: getDate(dates.publication), +      value: <Time date={dates.publication} />,      },      dates.update        ? { @@ -81,7 +69,7 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({              description: 'ThematicPage: update date label',              id: '24FIsG',            }), -          value: getDate(dates.update), +          value: <Time date={dates.update} />,          }        : undefined,      articles diff --git a/src/utils/helpers/dates.ts b/src/utils/helpers/dates.ts deleted file mode 100644 index 82c14db..0000000 --- a/src/utils/helpers/dates.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { settings } from '../config'; - -/** - * Format a date based on a locale. - * - * @param {string} date - The date. - * @param {string} [locale] - A locale. - * @returns {string} The locale date string. - */ -export const getFormattedDate = ( -  date: string, -  locale: string = settings.locales.defaultLocale -): string => { -  const dateOptions: Intl.DateTimeFormatOptions = { -    day: 'numeric', -    month: 'long', -    year: 'numeric', -  }; - -  return new Date(date).toLocaleDateString(locale, dateOptions); -}; - -/** - * Format a time based on a locale. - * - * @param {string} time - The time. - * @param {string} [locale] - A locale. - * @returns {string} The locale time string. - */ -export const getFormattedTime = ( -  time: string, -  locale: string = settings.locales.defaultLocale -): string => { -  const formattedTime = new Date(time).toLocaleTimeString(locale, { -    hour: 'numeric', -    minute: 'numeric', -  }); - -  return locale === 'fr' ? formattedTime.replace(':', 'h') : formattedTime; -}; diff --git a/src/utils/helpers/index.ts b/src/utils/helpers/index.ts index 1a35583..b2a4534 100644 --- a/src/utils/helpers/index.ts +++ b/src/utils/helpers/index.ts @@ -1,5 +1,4 @@  export * from './author'; -export * from './dates';  export * from './images';  export * from './pages';  export * from './rss'; | 
