diff --git a/itenium-socks/package-lock.json b/itenium-socks/package-lock.json index 295c374..dfa1bc5 100644 --- a/itenium-socks/package-lock.json +++ b/itenium-socks/package-lock.json @@ -18,6 +18,7 @@ "@angular/router": "^18.0.0", "@fortawesome/angular-fontawesome": "^0.15.0", "@fortawesome/fontawesome-free": "^6.5.2", + "date-fns": "^3.6.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.3" @@ -5771,6 +5772,16 @@ "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", diff --git a/itenium-socks/package.json b/itenium-socks/package.json index 6b3a9d6..bfe66b8 100644 --- a/itenium-socks/package.json +++ b/itenium-socks/package.json @@ -20,6 +20,7 @@ "@angular/router": "^18.0.0", "@fortawesome/angular-fontawesome": "^0.15.0", "@fortawesome/fontawesome-free": "^6.5.2", + "date-fns": "^3.6.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.3" diff --git a/itenium-socks/src/app/pipes/time-ago.pipe.spec.ts b/itenium-socks/src/app/pipes/time-ago.pipe.spec.ts new file mode 100644 index 0000000..1ea3c43 --- /dev/null +++ b/itenium-socks/src/app/pipes/time-ago.pipe.spec.ts @@ -0,0 +1,59 @@ +import { TimeAgoPipe } from './time-ago.pipe'; + +describe('TimeAgoPipe', () => { + let pipe: TimeAgoPipe; + + beforeEach(() => { + pipe = new TimeAgoPipe(); + }); + + it('should return "Just now" for a date less than 30 seconds ago', () => { + const date = new Date(Date.now() - 25 * 1000); // 25 seconds ago + expect(pipe.transform(date)).toBe('less than a minute ago'); + }); + + it('should return 1 minute for a date just less than 1 minute ago', () => { + const date = new Date(Date.now() - 55 * 1000); // 55 seconds ago + expect(pipe.transform(date)).toBe('1 minute ago'); + }); + + it('should return "44 minutes ago" for a date less than 1 hour ago', () => { + const date = new Date(Date.now() - 44 * 60 * 1000); // 44 minutes ago + expect(pipe.transform(date)).toBe('44 minutes ago'); + }); + + it('should return "about 1 hour ago" for a date less than 2 hours ago', () => { + const date = new Date(Date.now() - 61 * 60 * 1000); // 61 minutes ago + expect(pipe.transform(date)).toBe('about 1 hour ago'); + }); + + it('should return "about 23 hours ago" for a date less than 1 day ago', () => { + const date = new Date(Date.now() - 23 * 60 * 60 * 1000); // 23 hours ago + expect(pipe.transform(date)).toBe('about 23 hours ago'); + }); + + it('should return "1 day ago" for a date less than 2 days ago', () => { + const date = new Date(Date.now() - 25 * 60 * 60 * 1000); // 25 hours ago + expect(pipe.transform(date)).toBe('1 day ago'); + }); + + it('should return "30 days ago" for a date less than 1 month ago', () => { + const date = new Date(Date.now() - 30 * 24 * 60 * 60 * 999); // 30 days ago + expect(pipe.transform(date)).toBe('30 days ago'); + }); + + it('should return "1 month ago" for a date less than 2 months ago', () => { + const date = new Date(Date.now() - 44 * 24 * 60 * 60 * 1000); // 44 days ago + expect(pipe.transform(date)).toBe('about 1 month ago'); + }); + + it('should return "11 months ago" for a date less than 1 year ago', () => { + const date = new Date(Date.now() - 11 * 30 * 24 * 60 * 60 * 1000); // 11 months ago + expect(pipe.transform(date)).toBe('11 months ago'); + }); + + it('should return "1 year ago" for a date less than 2 years ago', () => { + const date = new Date(Date.now() - 13 * 30 * 24 * 60 * 60 * 1000); // 13 months ago + expect(pipe.transform(date)).toBe('about 1 year ago'); + }); +}); diff --git a/itenium-socks/src/app/pipes/time-ago.pipe.ts b/itenium-socks/src/app/pipes/time-ago.pipe.ts new file mode 100644 index 0000000..843d41e --- /dev/null +++ b/itenium-socks/src/app/pipes/time-ago.pipe.ts @@ -0,0 +1,37 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { formatDistance } from 'date-fns'; + +@Pipe({ + name: 'timeAgo', + standalone: true +}) +export class TimeAgoPipe implements PipeTransform { + // rules for date-fns + // 0 ... 30 secs -> less than a minute + // 30 secs ... 1 min 30 secs -> 1 minute + // 1 min 30 secs ... 44 mins 30 secs -> [2..44] minutes + // 44 mins ... 30 secs ... 89 mins 30 secs -> about 1 hour + // 89 mins 30 secs ... 23 hrs 59 mins 30 secs about -> [2..24] hours + // 23 hrs 59 mins 30 secs ... 41 hrs 59 mins 30 secs -> 1 day + // 41 hrs 59 mins 30 secs ... 29 days 23 hrs 59 mins 30 secs -> [2..30] days + // 29 days 23 hrs 59 mins 30 secs ... 44 days 23 hrs 59 mins 30 secs -> about 1 month + // 44 days 23 hrs 59 mins 30 secs ... 59 days 23 hrs 59 mins 30 secs -> about 2 months + // 59 days 23 hrs 59 mins 30 secs ... 1 yr -> [2..12] months + // 1 yr ... 1 yr 3 months -> about 1 year + // 1 yr 3 months ... 1 yr 9 month s -> over 1 year + // 1 yr 9 months ... 2 yrs -> almost 2 years + // N yrs ... N yrs 3 months -> about N years + // N yrs 3 months ... N yrs 9 months -> over N years + // N yrs 9 months ... N+1 yrs -> almost N+1 years + + transform(value: Date): string { + if (!value) { + return ''; + } + + const now = new Date(); + const date = new Date(value); + + return formatDistance(date, now, { addSuffix: true }); + } +} diff --git a/itenium-socks/src/app/socks/sock-reviews.component.html b/itenium-socks/src/app/socks/sock-reviews.component.html index 696aab3..f599dbc 100644 --- a/itenium-socks/src/app/socks/sock-reviews.component.html +++ b/itenium-socks/src/app/socks/sock-reviews.component.html @@ -17,7 +17,7 @@