Skip to content

Commit 5de3876

Browse files
committed
formatDate: update to named export and update format function to formatDateToString. Update import instances
1 parent 7421ef9 commit 5de3876

File tree

7 files changed

+59
-57
lines changed

7 files changed

+59
-57
lines changed

client/modules/IDE/components/CollectionList/CollectionListRow.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import * as ProjectActions from '../../actions/project';
1111
import * as CollectionsActions from '../../actions/collections';
1212
import * as IdeActions from '../../actions/ide';
1313
import * as ToastActions from '../../actions/toast';
14-
import dates from '../../../../utils/formatDate';
14+
import { formatDateToString } from '../../../../utils/formatDate';
1515
import { remSize, prop } from '../../../../theme';
1616

1717
const SketchsTableRow = styled.tr`
@@ -93,7 +93,7 @@ const SketchlistDropdownColumn = styled.td`
9393
}
9494
`;
9595
const formatDateCell = (date, mobile = false) =>
96-
dates.format(date, { showTime: !mobile });
96+
formatDateToString(date, { showTime: !mobile });
9797

9898
const CollectionListRowBase = (props) => {
9999
const [renameOpen, setRenameOpen] = useState(false);

client/modules/IDE/components/SketchListRowBase.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import * as ProjectActions from '../actions/project';
88
import * as IdeActions from '../actions/ide';
99
import TableDropdown from '../../../components/Dropdown/TableDropdown';
1010
import MenuItem from '../../../components/Dropdown/MenuItem';
11-
import dates from '../../../utils/formatDate';
11+
import { formatDateToString } from '../../../utils/formatDate';
1212
import getConfig from '../../../utils/getConfig';
1313

1414
const ROOT_URL = getConfig('API_URL', { nullishString: true });
1515

1616
const formatDateCell = (date, mobile = false) =>
17-
dates.format(date, { showTime: !mobile });
17+
formatDateToString(date, { showTime: !mobile });
1818

1919
const SketchListRowBase = ({
2020
sketch,

client/modules/IDE/components/Timer.jsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
33
import { useTranslation } from 'react-i18next';
44
import { useSelector } from 'react-redux';
55

6-
import dates from '../../../utils/formatDate';
6+
import { distanceInWordsToNow } from '../../../utils/formatDate';
77
import useInterval from '../hooks/useInterval';
88
import { getIsUserOwner } from '../selectors/users';
99

@@ -17,16 +17,14 @@ const Timer = () => {
1717

1818
// Update immediately upon saving.
1919
useEffect(() => {
20-
setTimeAgo(
21-
projectSavedTime ? dates.distanceInWordsToNow(projectSavedTime) : ''
22-
);
20+
setTimeAgo(projectSavedTime ? distanceInWordsToNow(projectSavedTime) : '');
2321
}, [projectSavedTime]);
2422

2523
// Update every 10 seconds.
2624
useInterval(
2725
() =>
2826
setTimeAgo(
29-
projectSavedTime ? dates.distanceInWordsToNow(projectSavedTime) : ''
27+
projectSavedTime ? distanceInWordsToNow(projectSavedTime) : ''
3028
),
3129
10000
3230
);

client/modules/User/components/APIKeyList.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { useTranslation } from 'react-i18next';
55

66
import { APIKeyPropType } from './APIKeyForm';
77

8-
import dates from '../../../utils/formatDate';
8+
import {
9+
distanceInWordsToNow,
10+
formatDateToString
11+
} from '../../../utils/formatDate';
912
import TrashCanIcon from '../../../images/trash-can.svg';
1013

1114
function APIKeyList({ apiKeys, onRemove }) {
@@ -23,13 +26,13 @@ function APIKeyList({ apiKeys, onRemove }) {
2326
<tbody>
2427
{orderBy(apiKeys, ['createdAt'], ['desc']).map((key) => {
2528
const lastUsed = key.lastUsedAt
26-
? dates.distanceInWordsToNow(new Date(key.lastUsedAt))
29+
? distanceInWordsToNow(new Date(key.lastUsedAt))
2730
: t('APIKeyList.Never');
2831

2932
return (
3033
<tr key={key.id}>
3134
<td>{key.label}</td>
32-
<td>{dates.format(key.createdAt)}</td>
35+
<td>{formatDateToString(key.createdAt)}</td>
3336
<td>{lastUsed}</td>
3437
<td className="api-key-list__action">
3538
<button

client/modules/User/components/CollectionItemRow.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
44
import { useTranslation } from 'react-i18next';
55
import { useDispatch } from 'react-redux';
66
import { removeFromCollection } from '../../IDE/actions/collections';
7-
import dates from '../../../utils/formatDate';
7+
import { formatDateToString } from '../../../utils/formatDate';
88
import RemoveIcon from '../../../images/close.svg';
99

1010
const CollectionItemRow = ({ collection, item, isOwner }) => {
@@ -40,7 +40,7 @@ const CollectionItemRow = ({ collection, item, isOwner }) => {
4040
className={`sketches-table__row ${projectIsDeleted ? 'is-deleted' : ''}`}
4141
>
4242
<th scope="row">{name}</th>
43-
<td>{dates.format(item.createdAt)}</td>
43+
<td>{formatDateToString(item.createdAt)}</td>
4444
<td>{sketchOwnerUsername}</td>
4545
<td className="collection-row__action-column">
4646
{isOwner && (

client/utils/formatDate.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import i18next from 'i18next';
2-
import dateUtils from './formatDate';
2+
import { distanceInWordsToNow, formatDateToString } from './formatDate';
33

44
jest.mock('i18next', () => ({
55
t: jest.fn((key: string) => key.split('.')[1])
@@ -20,7 +20,7 @@ describe('dateUtils', () => {
2020
const now = new Date();
2121
const recentDate = new Date(now.getTime() - 5000);
2222

23-
const result = dateUtils.distanceInWordsToNow(recentDate);
23+
const result = distanceInWordsToNow(recentDate);
2424
expect(i18next.t).toHaveBeenCalledWith('formatDate.JustNow');
2525
expect(result).toBe('JustNow');
2626
});
@@ -29,7 +29,7 @@ describe('dateUtils', () => {
2929
const now = new Date();
3030
const recentDate = new Date(now.getTime() - 15000);
3131

32-
const result = dateUtils.distanceInWordsToNow(recentDate);
32+
const result = distanceInWordsToNow(recentDate);
3333
expect(i18next.t).toHaveBeenCalledWith('formatDate.15Seconds');
3434
expect(result).toBe('15Seconds');
3535
});
@@ -42,7 +42,7 @@ describe('dateUtils', () => {
4242
t: jest.fn((key: string, { timeAgo }) => `${key}: ${timeAgo}`)
4343
}));
4444

45-
const result = dateUtils.distanceInWordsToNow(oldDate);
45+
const result = distanceInWordsToNow(oldDate);
4646
expect(i18next.t).toHaveBeenCalledWith(
4747
'formatDate.Ago',
4848
expect.any(Object)
@@ -51,28 +51,28 @@ describe('dateUtils', () => {
5151
});
5252

5353
it('returns empty string for invalid date', () => {
54-
const result = dateUtils.distanceInWordsToNow('not a date');
54+
const result = distanceInWordsToNow('not a date');
5555
expect(result).toBe('');
5656
});
5757
});
5858

5959
describe('format', () => {
6060
it('formats with time by default', () => {
6161
const date = new Date('2025-07-16T12:34:56Z');
62-
const formatted = dateUtils.format(date);
62+
const formatted = formatDateToString(date);
6363

6464
expect(formatted).toMatch(/(\d{1,2}:\d{2})/); // Contains time
6565
});
6666

6767
it('formats without time when showTime is false', () => {
6868
const date = new Date('2025-07-16T12:34:56Z');
69-
const formatted = dateUtils.format(date, { showTime: false });
69+
const formatted = formatDateToString(date, { showTime: false });
7070

7171
expect(formatted).not.toMatch(/(\d{1,2}:\d{2})/); // Contains time
7272
});
7373

7474
it('returns empty string for invalid date', () => {
75-
const formatted = dateUtils.format('invalid date');
75+
const formatted = formatDateToString('invalid date');
7676
expect(formatted).toBe('');
7777
});
7878
});

client/utils/formatDate.ts

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,46 @@ function parse(maybeDate: Date | string) {
2121
return null;
2222
}
2323

24-
export default {
25-
/**
26-
* Returns a human-friendly relative time string from now.
27-
* For very recent dates, returns specific labels (e.g., 'JustNow').
28-
* @param date - Date or string to compare
29-
* @returns Relative time string or empty string if invalid
30-
*/
31-
distanceInWordsToNow(date: Date | string) {
32-
const parsed = parse(date);
24+
/**
25+
* Returns a human-friendly relative time string from now.
26+
* For very recent dates, returns specific labels (e.g., 'JustNow').
27+
* @param date - Date or string to compare
28+
* @returns Relative time string or empty string if invalid
29+
*/
30+
export function distanceInWordsToNow(date: Date | string) {
31+
const parsed = parse(date);
3332

34-
if (!parsed) return '';
33+
if (!parsed) return '';
3534

36-
const diffInMs = Math.abs(differenceInMilliseconds(new Date(), parsed));
35+
const diffInMs = Math.abs(differenceInMilliseconds(new Date(), parsed));
3736

38-
if (diffInMs < 10000) return i18next.t('formatDate.JustNow');
39-
if (diffInMs < 20000) return i18next.t('formatDate.15Seconds');
40-
if (diffInMs < 30000) return i18next.t('formatDate.25Seconds');
41-
if (diffInMs < 46000) return i18next.t('formatDate.35Seconds');
37+
if (diffInMs < 10000) return i18next.t('formatDate.JustNow');
38+
if (diffInMs < 20000) return i18next.t('formatDate.15Seconds');
39+
if (diffInMs < 30000) return i18next.t('formatDate.25Seconds');
40+
if (diffInMs < 46000) return i18next.t('formatDate.35Seconds');
4241

43-
const timeAgo = formatDistanceToNow(parsed, {
44-
includeSeconds: false,
45-
locale: currentDateLocale()
46-
});
42+
const timeAgo = formatDistanceToNow(parsed, {
43+
includeSeconds: false,
44+
locale: currentDateLocale()
45+
});
4746

48-
return i18next.t('formatDate.Ago', { timeAgo });
49-
},
47+
return i18next.t('formatDate.Ago', { timeAgo });
48+
}
5049

51-
/**
52-
* Formats a date as a string. Includes time by default.
53-
* @param date - Date or string to format
54-
* @param options - Formatting options
55-
* @param options.showTime - Whether to include time (default true)
56-
* @returns Formatted date string or empty string if invalid
57-
*/
58-
format(date: Date | string, { showTime = true } = {}): string {
59-
const parsed = parse(date);
60-
if (!parsed) return '';
50+
/**
51+
* Formats a date as a string. Includes time by default.
52+
* @param date - Date or string to format
53+
* @param options - Formatting options
54+
* @param options.showTime - Whether to include time (default true)
55+
* @returns Formatted date string or empty string if invalid
56+
*/
57+
export function formatDateToString(
58+
date: Date | string,
59+
{ showTime = true } = {}
60+
): string {
61+
const parsed = parse(date);
62+
if (!parsed) return '';
6163

62-
const formatType = showTime ? 'PPpp' : 'PP';
63-
return format(parsed, formatType, { locale: currentDateLocale() });
64-
}
65-
};
64+
const formatType = showTime ? 'PPpp' : 'PP';
65+
return format(parsed, formatType, { locale: currentDateLocale() });
66+
}

0 commit comments

Comments
 (0)