github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/components/FormattedDate/FormattedDate.tsx (about)

     1  /*This file is part of kuberpult.
     2  
     3  Kuberpult is free software: you can redistribute it and/or modify
     4  it under the terms of the Expat(MIT) License as published by
     5  the Free Software Foundation.
     6  
     7  Kuberpult is distributed in the hope that it will be useful,
     8  but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  MIT License for more details.
    11  
    12  You should have received a copy of the MIT License
    13  along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>.
    14  
    15  Copyright 2023 freiheit.com*/
    16  import React, { useEffect } from 'react';
    17  
    18  const getRelativeDate = (current: Date, target: Date | undefined): string => {
    19      if (!target) return '';
    20      const elapsedTime = current.valueOf() - target.valueOf();
    21      const msPerMinute = 1000 * 60;
    22      const msPerHour = msPerMinute * 60;
    23      const msPerDay = msPerHour * 24;
    24      const msPerMonth = msPerDay * 30;
    25      const msPerYear = msPerDay * 365;
    26  
    27      if (elapsedTime < msPerMinute) {
    28          return 'just now';
    29      } else if (elapsedTime < msPerHour) {
    30          return Math.round(elapsedTime / msPerMinute) === 1
    31              ? `1 minute ago`
    32              : `${Math.round(elapsedTime / msPerMinute)} minutes ago`;
    33      } else if (elapsedTime < msPerDay) {
    34          return Math.round(elapsedTime / msPerHour) === 1
    35              ? '1 hour ago'
    36              : `${Math.round(elapsedTime / msPerHour)} hours ago`;
    37      } else if (elapsedTime < msPerMonth) {
    38          return Math.round(elapsedTime / msPerDay) === 1
    39              ? '~ 1 day ago'
    40              : `~ ${Math.round(elapsedTime / msPerDay)} days ago`;
    41      } else if (elapsedTime < msPerYear) {
    42          return Math.round(elapsedTime / msPerMonth) === 1
    43              ? '~ 1 month ago'
    44              : `~ ${Math.round(elapsedTime / msPerMonth)} months ago`;
    45      } else {
    46          return Math.round(elapsedTime / msPerYear) === 1
    47              ? '~ 1 year ago'
    48              : `~ ${Math.round(elapsedTime / msPerYear)} years ago`;
    49      }
    50  };
    51  
    52  export const FormattedDate: React.FC<{ createdAt: Date; className?: string }> = ({ createdAt, className }) => {
    53      const [relativeDate, setRelativeDate] = React.useState(getRelativeDate(new Date(), createdAt));
    54      useEffect(() => {
    55          const handle = setInterval(() => setRelativeDate(getRelativeDate(new Date(), createdAt)), 20000);
    56          return () => clearInterval(handle);
    57      }, [createdAt]);
    58  
    59      return (
    60          <span className={className} title={createdAt.toString()}>
    61              <i>{relativeDate}</i>
    62          </span>
    63      );
    64  };