Skip to content

Commit 8ca8335

Browse files
committed
Relocate formatReviewFields
1 parent 5826470 commit 8ca8335

3 files changed

Lines changed: 116 additions & 20 deletions

File tree

src/components/react/forms/FormReviewTable/FormReviewTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useFormContext } from "react-hook-form";
22
import type { StepConfig } from "@/components/react/forms/FormContainer";
33
import { resolveVisibleFields } from "@/components/react/forms/FormContainer/resolveVisibleFields";
44
import type { FormData } from "@/constants/fields";
5-
import { formatFieldValue, getFieldLabel } from "./fieldFormatters";
5+
import { formatFieldValue, getFieldLabel } from "@/utils/formatReviewFields";
66
import "./FormReviewTable.css";
77
import { smartquotes } from "@/utils/smartquotes";
88

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { describe, expect, it } from "vitest";
2+
import { formatFieldValue, getFieldLabel } from "../formatReviewFields";
3+
4+
describe("formatFieldValue", () => {
5+
describe("boolean fields", () => {
6+
it("formats true as 'Yes'", () => {
7+
expect(formatFieldValue("isCurrentlyUnhoused", true)).toBe("Yes");
8+
});
9+
10+
it("formats false as 'No'", () => {
11+
expect(formatFieldValue("isCurrentlyUnhoused", false)).toBe("No");
12+
});
13+
14+
it("treats undefined as false and formats as 'No'", () => {
15+
expect(formatFieldValue("isCurrentlyUnhoused", undefined)).toBe("No");
16+
});
17+
18+
it("treats null as false and formats as 'No'", () => {
19+
expect(formatFieldValue("isCurrentlyUnhoused", null)).toBe("No");
20+
});
21+
});
22+
23+
describe("string fields", () => {
24+
it("formats string values", () => {
25+
expect(formatFieldValue("oldFirstName", "John")).toBe("John");
26+
});
27+
28+
it("returns undefined for empty string", () => {
29+
expect(formatFieldValue("oldFirstName", "")).toBeUndefined();
30+
});
31+
32+
it("returns undefined for undefined", () => {
33+
expect(formatFieldValue("oldFirstName", undefined)).toBeUndefined();
34+
});
35+
36+
it("returns undefined for null", () => {
37+
expect(formatFieldValue("oldFirstName", null)).toBeUndefined();
38+
});
39+
});
40+
41+
describe("string[] fields", () => {
42+
it("formats array of strings", () => {
43+
expect(formatFieldValue("pronouns", ["they/them", "she/her"])).toBe(
44+
"they/them, she/her",
45+
);
46+
});
47+
48+
it("returns undefined for empty array", () => {
49+
expect(formatFieldValue("pronouns", [])).toBeUndefined();
50+
});
51+
52+
it("returns undefined for undefined", () => {
53+
expect(formatFieldValue("pronouns", undefined)).toBeUndefined();
54+
});
55+
56+
it("returns undefined for null", () => {
57+
expect(formatFieldValue("pronouns", null)).toBeUndefined();
58+
});
59+
});
60+
61+
describe("phone number formatting", () => {
62+
it("formats phone number", () => {
63+
expect(formatFieldValue("phoneNumber", "(123) 456-7890")).toBe(
64+
"(123) 456-7890",
65+
);
66+
});
67+
68+
it("returns undefined for empty phone number", () => {
69+
expect(formatFieldValue("phoneNumber", "")).toBeUndefined();
70+
});
71+
});
72+
73+
describe("date formatting", () => {
74+
it("formats ISO date string", () => {
75+
const result = formatFieldValue("dateOfBirth", "1990-01-15");
76+
expect(result).toBe("January 15, 1990");
77+
});
78+
79+
it("returns undefined for empty date", () => {
80+
expect(formatFieldValue("dateOfBirth", "")).toBeUndefined();
81+
});
82+
});
83+
});
84+
85+
describe("getFieldLabel", () => {
86+
it("returns the label for a known field", () => {
87+
expect(getFieldLabel("isCurrentlyUnhoused")).toBe("Currently unhoused?");
88+
});
89+
90+
it("returns the label for another field", () => {
91+
expect(getFieldLabel("oldFirstName")).toBe("Old first name");
92+
});
93+
94+
it("returns the field name if not found", () => {
95+
// @ts-expect-error - testing with invalid field name
96+
expect(getFieldLabel("unknownField")).toBe("unknownField");
97+
});
98+
});
99+

src/components/react/forms/FormReviewTable/fieldFormatters.ts renamed to src/utils/formatReviewFields.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { parseDate } from "@internationalized/date";
12
import { FIELD_DEFS, type FieldName } from "@/constants/fields";
23

34
/**
@@ -9,21 +10,26 @@ export function formatFieldValue(
910
fieldName: FieldName,
1011
value: any,
1112
): string | undefined {
12-
// Handle empty values - return undefined to trigger warning display
13-
if (value === null || value === undefined || value === "") {
14-
return undefined;
15-
}
16-
1713
// Get the field definition to determine the type
1814
const fieldDef = FIELD_DEFS.find((def) => def.name === fieldName);
1915
if (!fieldDef) {
2016
return String(value);
2117
}
2218

19+
// Handle empty values - return undefined to trigger warning display
20+
// Exception: boolean fields treat undefined/null as false (unchecked checkbox)
21+
if (
22+
fieldDef.type !== "boolean" &&
23+
(value === null || value === undefined || value === "")
24+
) {
25+
return undefined;
26+
}
27+
2328
// Format based on type
2429
switch (fieldDef.type) {
2530
case "boolean":
26-
return value === true ? "Yes" : value === false ? "No" : undefined;
31+
// Treat undefined/null as false for boolean fields (single checkboxes default to unchecked)
32+
return value === true ? "Yes" : "No";
2733

2834
case "string[]":
2935
if (Array.isArray(value)) {
@@ -47,33 +53,24 @@ export function formatFieldValue(
4753
}
4854
}
4955

50-
/**
51-
* Formats a phone number for display
52-
*/
5356
function formatPhoneNumber(phone: string): string | undefined {
5457
if (!phone) return undefined;
5558
// Phone is already formatted by the mask, just return as-is
5659
return phone;
5760
}
5861

59-
/**
60-
* Formats a date for display
61-
*/
6262
function formatDate(date: string): string | undefined {
6363
if (!date) return undefined;
64-
// Assuming date is in ISO format or similar, format it nicely
6564
try {
66-
const dateObj = new Date(date);
67-
if (Number.isNaN(dateObj.getTime())) {
68-
return date; // Return as-is if not a valid date
69-
}
70-
return dateObj.toLocaleDateString("en-US", {
65+
const calendarDate = parseDate(date);
66+
return calendarDate.toDate("UTC").toLocaleDateString("en-US", {
7167
year: "numeric",
7268
month: "long",
7369
day: "numeric",
70+
timeZone: "UTC",
7471
});
7572
} catch {
76-
return date;
73+
return date; // Return as-is if parsing fails
7774
}
7875
}
7976

0 commit comments

Comments
 (0)