@airoom/nextmin-react 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import React from 'react';
4
4
  import { formatCell } from '../../views/list/formatters';
5
5
  import { summarizeObject } from '../../views/list/jsonSummary';
6
6
  // Hide technical keys in the viewer
7
- const HIDDEN_KEYS = new Set(['id', '_id', 'v', '__v', 'baseId', 'exId', '__childId']);
7
+ const HIDDEN_KEYS = new Set(['id', '_id', 'v', '__v', 'baseId', 'exId', '__childId', 'createdAt', 'updatedAt', 'deletedAt']);
8
8
  // Detect password-like keys generically (no value should be visible)
9
9
  function normKey(k) {
10
10
  return k.toLowerCase().replace(/[^a-z]/g, '');
@@ -75,6 +75,49 @@ function humanizeLabel(key) {
75
75
  const spaced = key.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/_/g, ' ');
76
76
  return spaced.slice(0, 1).toUpperCase() + spaced.slice(1);
77
77
  }
78
+ /** ---------- Date/time helpers (local timezone formatting) ---------- */
79
+ // Check if a field name is a date field
80
+ function isDateField(key) {
81
+ if (!key)
82
+ return false;
83
+ const k = key.toLowerCase().replace(/[^a-z]/g, '');
84
+ return k === 'createdat' || k === 'updatedat' || k === 'deletedat';
85
+ }
86
+ function tryParseDate(val) {
87
+ if (val == null)
88
+ return null;
89
+ // Already a Date
90
+ if (val instanceof Date)
91
+ return isNaN(val.getTime()) ? null : val;
92
+ // ONLY parse ISO-like strings, NOT numbers (to avoid phone numbers, experience years, etc.)
93
+ if (typeof val === 'string') {
94
+ const s = val.trim();
95
+ // Must look like an ISO date: YYYY-MM-DD or contain 'T' or end with 'Z'
96
+ const looksIso = /^\d{4}-\d{2}-\d{2}/.test(s) || s.includes('T') || s.endsWith('Z');
97
+ if (!looksIso)
98
+ return null;
99
+ const d = new Date(s);
100
+ return isNaN(d.getTime()) ? null : d;
101
+ }
102
+ return null;
103
+ }
104
+ function formatDateTimeLocal(d) {
105
+ // Use the runtime locale and include seconds for precision
106
+ try {
107
+ return d.toLocaleString(undefined, {
108
+ year: 'numeric',
109
+ month: 'short',
110
+ day: '2-digit',
111
+ hour: '2-digit',
112
+ minute: '2-digit',
113
+ second: '2-digit',
114
+ hour12: true,
115
+ });
116
+ }
117
+ catch {
118
+ return d.toString();
119
+ }
120
+ }
78
121
  function isPrivate(attr) {
79
122
  const a = (Array.isArray(attr) ? attr[0] : attr);
80
123
  return !!a?.private;
@@ -171,6 +214,14 @@ function renderValue(input, key) {
171
214
  const val = maybeParseJson(input);
172
215
  if (val == null)
173
216
  return _jsx("span", { className: "text-foreground/50", children: "\u2014" });
217
+ // Only parse dates for known date fields (createdAt, updatedAt, deletedAt)
218
+ if (isDateField(key)) {
219
+ const d = tryParseDate(val);
220
+ if (d) {
221
+ const iso = d.toISOString();
222
+ return (_jsx("time", { dateTime: iso, title: iso, className: "whitespace-pre-wrap", children: formatDateTimeLocal(d) }));
223
+ }
224
+ }
174
225
  // Detect images
175
226
  const urls = extractAllImageUrls(val);
176
227
  if (urls.length)