refactor(date): consolidate formatDate in date.ts with optional format param
Add format?: 'short'|'long' (default 'long') to date.ts formatDate and remove the duplicate from personFormat.ts. Update DocumentTopBar to import from date.ts directly. Move the formatDate tests from personFormat.spec to date.spec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { formatDate } from '$lib/utils/personFormat';
|
import { formatDate } from '$lib/utils/date';
|
||||||
import { clickOutside } from '$lib/actions/clickOutside';
|
import { clickOutside } from '$lib/actions/clickOutside';
|
||||||
import PersonChipRow from './PersonChipRow.svelte';
|
import PersonChipRow from './PersonChipRow.svelte';
|
||||||
import OverflowPillButton from './OverflowPillButton.svelte';
|
import OverflowPillButton from './OverflowPillButton.svelte';
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { formatGermanDateInput, isoToGerman, germanToIso } from './date';
|
import { formatDate, formatGermanDateInput, isoToGerman, germanToIso } from './date';
|
||||||
|
|
||||||
|
// ─── formatDate ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('formatDate', () => {
|
||||||
|
it('defaults to long format when no format arg is passed', () => {
|
||||||
|
expect(formatDate('1943-12-24')).toBe('24. Dezember 1943');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats long date with German month name', () => {
|
||||||
|
expect(formatDate('1943-12-24', 'long')).toBe('24. Dezember 1943');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats short date as dd.mm.yyyy', () => {
|
||||||
|
expect(formatDate('1943-12-24', 'short')).toBe('24.12.1943');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not shift Dec 31 to Jan 1 (T12:00:00 UTC guard)', () => {
|
||||||
|
expect(formatDate('1943-12-31', 'short')).toBe('31.12.1943');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ─── isoToGerman ─────────────────────────────────────────────────────────────
|
// ─── isoToGerman ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* Format an ISO date string (YYYY-MM-DD) for display.
|
* Format an ISO date string (YYYY-MM-DD) for display.
|
||||||
* Uses T12:00:00 to avoid UTC timezone off-by-one when converting to local time.
|
* Uses T12:00:00 to avoid UTC timezone off-by-one when converting to local time.
|
||||||
|
* Defaults to 'long' (e.g. "24. Dezember 1943"); pass 'short' for DD.MM.YYYY.
|
||||||
*/
|
*/
|
||||||
export function formatDate(isoDate: string): string {
|
export function formatDate(isoDate: string, format: 'short' | 'long' = 'long'): string {
|
||||||
|
const date = new Date(isoDate + 'T12:00:00');
|
||||||
|
if (format === 'short') {
|
||||||
|
return new Intl.DateTimeFormat('de-DE', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric'
|
||||||
|
}).format(date);
|
||||||
|
}
|
||||||
return new Intl.DateTimeFormat('de-DE', {
|
return new Intl.DateTimeFormat('de-DE', {
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
year: 'numeric'
|
year: 'numeric'
|
||||||
}).format(new Date(isoDate + 'T12:00:00'));
|
}).format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import {
|
|||||||
abbreviateName,
|
abbreviateName,
|
||||||
formatXsMeta,
|
formatXsMeta,
|
||||||
personAvatarColor,
|
personAvatarColor,
|
||||||
formatDate,
|
|
||||||
statusDotClass,
|
statusDotClass,
|
||||||
statusLabel
|
statusLabel
|
||||||
} from './personFormat';
|
} from './personFormat';
|
||||||
|
import { formatDate } from './date';
|
||||||
|
|
||||||
// ─── getInitials ─────────────────────────────────────────────────────────────
|
// ─── getInitials ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { formatDocumentStatus } from './documentStatusLabel';
|
import { formatDocumentStatus } from './documentStatusLabel';
|
||||||
|
import { formatDate } from './date';
|
||||||
|
|
||||||
type Person = { firstName?: string | null; lastName: string; displayName: string };
|
type Person = { firstName?: string | null; lastName: string; displayName: string };
|
||||||
type DocumentStatus = 'PLACEHOLDER' | 'UPLOADED' | 'TRANSCRIBED' | 'REVIEWED' | 'ARCHIVED';
|
type DocumentStatus = 'PLACEHOLDER' | 'UPLOADED' | 'TRANSCRIBED' | 'REVIEWED' | 'ARCHIVED';
|
||||||
@@ -75,22 +76,6 @@ export function personAvatarColor(personId: string): string {
|
|||||||
return AVATAR_PALETTE[djb2(personId) % AVATAR_PALETTE.length];
|
return AVATAR_PALETTE[djb2(personId) % AVATAR_PALETTE.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatDate(isoDate: string, format: 'short' | 'long'): string {
|
|
||||||
const date = new Date(isoDate + 'T12:00:00');
|
|
||||||
if (format === 'short') {
|
|
||||||
return new Intl.DateTimeFormat('de-DE', {
|
|
||||||
day: '2-digit',
|
|
||||||
month: '2-digit',
|
|
||||||
year: 'numeric'
|
|
||||||
}).format(date);
|
|
||||||
}
|
|
||||||
return new Intl.DateTimeFormat('de-DE', {
|
|
||||||
day: 'numeric',
|
|
||||||
month: 'long',
|
|
||||||
year: 'numeric'
|
|
||||||
}).format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function statusDotClass(status: DocumentStatus): string {
|
export function statusDotClass(status: DocumentStatus): string {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'PLACEHOLDER':
|
case 'PLACEHOLDER':
|
||||||
|
|||||||
Reference in New Issue
Block a user