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 };