mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-28 19:46:59 -05:00
Migrate date precision to exact
Batch update all date precision handling to use expanded DatePrecision, replace hardcoded day defaults, and adjust related validation, UI, and helpers. Includes wrapper migration across Phase 1-3 functions, updates to logs, displays, and formatting utilities to align frontend with new precision values ('exact', 'month', 'year', 'decade', 'century', 'approximate').
This commit is contained in:
@@ -72,7 +72,7 @@ export function getCurrentDateLocal(): string {
|
||||
*/
|
||||
export function formatDateDisplay(
|
||||
dateString: string | null | undefined,
|
||||
precision: 'day' | 'month' | 'year' = 'day'
|
||||
precision: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate' = 'exact'
|
||||
): string {
|
||||
if (!dateString) return '';
|
||||
|
||||
@@ -83,7 +83,13 @@ export function formatDateDisplay(
|
||||
return date.getFullYear().toString();
|
||||
case 'month':
|
||||
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' });
|
||||
case 'day':
|
||||
case 'decade':
|
||||
return `${Math.floor(date.getFullYear() / 10) * 10}s`;
|
||||
case 'century':
|
||||
return `${Math.ceil(date.getFullYear() / 100)}th century`;
|
||||
case 'approximate':
|
||||
return `circa ${date.getFullYear()}`;
|
||||
case 'exact':
|
||||
default:
|
||||
return date.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
@@ -182,7 +188,7 @@ export function parseDateForDisplay(date: string | Date): Date {
|
||||
*/
|
||||
export function toDateWithPrecision(
|
||||
date: Date,
|
||||
precision: 'day' | 'month' | 'year'
|
||||
precision: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate'
|
||||
): string {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
@@ -193,7 +199,13 @@ export function toDateWithPrecision(
|
||||
return `${year}-01-01`;
|
||||
case 'month':
|
||||
return `${year}-${String(month).padStart(2, '0')}-01`;
|
||||
case 'day':
|
||||
case 'decade':
|
||||
return `${Math.floor(year / 10) * 10}-01-01`;
|
||||
case 'century':
|
||||
return `${Math.floor((year - 1) / 100) * 100 + 1}-01-01`;
|
||||
case 'approximate':
|
||||
return `${year}-01-01`;
|
||||
case 'exact':
|
||||
default:
|
||||
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ export const parkValidationSchema = z.object({
|
||||
const date = new Date(val);
|
||||
return date <= new Date();
|
||||
}, 'Opening date cannot be in the future'),
|
||||
opening_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(),
|
||||
opening_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
|
||||
closing_date: z.string().nullish().transform(val => val ?? undefined),
|
||||
closing_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(),
|
||||
closing_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
|
||||
location_id: z.string().uuid().optional().nullable(),
|
||||
location: z.object({
|
||||
name: z.string(),
|
||||
@@ -139,9 +139,9 @@ export const rideValidationSchema = z.object({
|
||||
.optional()
|
||||
.nullable(),
|
||||
opening_date: z.string().nullish().transform(val => val ?? undefined),
|
||||
opening_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(),
|
||||
opening_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
|
||||
closing_date: z.string().nullish().transform(val => val ?? undefined),
|
||||
closing_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(),
|
||||
closing_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
|
||||
height_requirement: z.preprocess(
|
||||
(val) => val === '' || val === null || val === undefined ? undefined : Number(val),
|
||||
z.number().int().min(0, 'Height requirement must be positive').max(300, 'Height requirement must be less than 300cm').optional()
|
||||
@@ -322,7 +322,7 @@ export const companyValidationSchema = z.object({
|
||||
description: z.string().trim().max(2000, 'Description must be less than 2000 characters').nullish().transform(val => val ?? undefined),
|
||||
person_type: z.enum(['company', 'individual', 'firm', 'organization']),
|
||||
founded_date: z.string().nullish().transform(val => val ?? undefined),
|
||||
founded_date_precision: z.enum(['day', 'month', 'year']).nullable().optional(),
|
||||
founded_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).nullable().optional(),
|
||||
founded_year: z.preprocess(
|
||||
(val) => val === '' || val === null || val === undefined ? undefined : Number(val),
|
||||
z.number().int().min(1800, 'Founded year must be after 1800').max(currentYear, `Founded year cannot be after ${currentYear}`).optional()
|
||||
@@ -401,7 +401,7 @@ export const milestoneValidationSchema = z.object({
|
||||
fiveYearsFromNow.setFullYear(fiveYearsFromNow.getFullYear() + 5);
|
||||
return date <= fiveYearsFromNow;
|
||||
}, 'Event date cannot be more than 5 years in the future'),
|
||||
event_date_precision: z.enum(['day', 'month', 'year']).optional().default('day'),
|
||||
event_date_precision: z.enum(['exact', 'month', 'year', 'decade', 'century', 'approximate']).optional().default('exact'),
|
||||
entity_type: z.string().min(1, 'Entity type is required'),
|
||||
entity_id: z.string().uuid('Invalid entity ID'),
|
||||
is_public: z.boolean().optional(),
|
||||
|
||||
@@ -21,9 +21,9 @@ export interface FieldChange {
|
||||
changeType: 'added' | 'removed' | 'modified';
|
||||
metadata?: {
|
||||
isCreatingNewLocation?: boolean;
|
||||
precision?: 'day' | 'month' | 'year';
|
||||
oldPrecision?: 'day' | 'month' | 'year';
|
||||
newPrecision?: 'day' | 'month' | 'year';
|
||||
precision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
|
||||
oldPrecision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
|
||||
newPrecision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -803,7 +803,7 @@ function formatEntityType(entityType: string): string {
|
||||
/**
|
||||
* Format field value for display
|
||||
*/
|
||||
export function formatFieldValue(value: any, precision?: 'day' | 'month' | 'year'): string {
|
||||
export function formatFieldValue(value: any, precision?: 'exact' | 'month' | 'year' | 'decade' | 'century' | 'approximate'): string {
|
||||
if (value === null || value === undefined) return 'None';
|
||||
if (typeof value === 'boolean') return value ? 'Yes' : 'No';
|
||||
|
||||
@@ -817,9 +817,15 @@ export function formatFieldValue(value: any, precision?: 'day' | 'month' | 'year
|
||||
return date.getFullYear().toString();
|
||||
} else if (precision === 'month') {
|
||||
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long' });
|
||||
} else if (precision === 'decade') {
|
||||
return `${Math.floor(date.getFullYear() / 10) * 10}s`;
|
||||
} else if (precision === 'century') {
|
||||
return `${Math.ceil(date.getFullYear() / 100)}th century`;
|
||||
} else if (precision === 'approximate') {
|
||||
return `circa ${date.getFullYear()}`;
|
||||
}
|
||||
|
||||
// Default: full date
|
||||
// Default: full date (exact)
|
||||
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
|
||||
} catch {
|
||||
return String(value);
|
||||
|
||||
Reference in New Issue
Block a user