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);
ts/Copyright/Copyright.tsx?id=df9e8b1985a0f1c71c0657e72fad008bf437faba'>Copyright.tsx</a></div><div class='content'>blob: 9a57f9c817755fa056b7be59ab6482852ae12d53 (<a href='/www.armandphilippot.com/plain/src/components/Copyright/Copyright.tsx?id=df9e8b1985a0f1c71c0657e72fad008bf437faba'>plain</a>)
<table summary='blob content' class='blob'>
<tr><td class='linenumbers'><pre><a id='n1' href='#n1'>1</a>
<a id='n2' href='#n2'>2</a>
<a id='n3' href='#n3'>3</a>
<a id='n4' href='#n4'>4</a>
<a id='n5' href='#n5'>5</a>
<a id='n6' href='#n6'>6</a>
<a id='n7' href='#n7'>7</a>
<a id='n8' href='#n8'>8</a>
<a id='n9' href='#n9'>9</a>
<a id='n10' href='#n10'>10</a>
<a id='n11' href='#n11'>11</a>
<a id='n12' href='#n12'>12</a>
<a id='n13' href='#n13'>13</a>
<a id='n14' href='#n14'>14</a>
<a id='n15' href='#n15'>15</a>
<a id='n16' href='#n16'>16</a>
<a id='n17' href='#n17'>17</a>
</pre></td>
<td class='lines'><pre><code>