|
|
@ -80,10 +80,19 @@ export default function QuestionNumber({ |
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
if (typeof value === "string" && value.length > 0) { |
|
|
if (typeof value === "string" && value.length > 0) { |
|
|
const normalized = normalizeNumberString(value); |
|
|
const normalized = normalizeNumberString(value); |
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] useEffect normalize: id=${question.id}, value="${value}", normalized="${normalized}"`, |
|
|
|
|
|
); |
|
|
if (!NUMBER_INPUT_PATTERN.test(normalized)) { |
|
|
if (!NUMBER_INPUT_PATTERN.test(normalized)) { |
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] useEffect clearing invalid value: id=${question.id}, value="${value}"`, |
|
|
|
|
|
); |
|
|
setAnswerValue(question, null); |
|
|
setAnswerValue(question, null); |
|
|
} else if (normalized !== value) { |
|
|
} else if (normalized !== value) { |
|
|
const parsed = parseFloat(normalized); |
|
|
const parsed = parseFloat(normalized); |
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] useEffect updating normalized: id=${question.id}, parsed=${parsed}`, |
|
|
|
|
|
); |
|
|
setAnswerValue( |
|
|
setAnswerValue( |
|
|
question, |
|
|
question, |
|
|
Number.isNaN(parsed) ? normalized : parsed, |
|
|
Number.isNaN(parsed) ? normalized : parsed, |
|
|
@ -113,6 +122,10 @@ export default function QuestionNumber({ |
|
|
? normalizedRaw |
|
|
? normalizedRaw |
|
|
: ""; |
|
|
: ""; |
|
|
|
|
|
|
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] Render: id=${question.id}, value=${JSON.stringify(value)}, inputValue="${inputValue}", isOutOfRange=${isOutOfRange}`, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
const isMonthlyIncome = question.ui_config?.currency_enabled === true; |
|
|
const isMonthlyIncome = question.ui_config?.currency_enabled === true; |
|
|
const currencyStorageKey = |
|
|
const currencyStorageKey = |
|
|
question.ui_config?.currency_storage_key || "marriage:income:currency"; |
|
|
question.ui_config?.currency_storage_key || "marriage:income:currency"; |
|
|
@ -324,16 +337,26 @@ export default function QuestionNumber({ |
|
|
const normalized = normalizeNumberString(raw); |
|
|
const normalized = normalizeNumberString(raw); |
|
|
const cleaned = normalized.replace(/[^0-9.-]/g, ""); |
|
|
const cleaned = normalized.replace(/[^0-9.-]/g, ""); |
|
|
|
|
|
|
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] onChange: id=${question.id}, raw="${raw}", normalized="${normalized}", cleaned="${cleaned}"`, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
if (cleaned === "" || cleaned === "-") { |
|
|
if (cleaned === "" || cleaned === "-") { |
|
|
|
|
|
console.log(`[NUM_LOG] onChange clearing value (empty)`); |
|
|
setAnswerValue(question, null); |
|
|
setAnswerValue(question, null); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!NUMBER_INPUT_PATTERN.test(cleaned)) { |
|
|
if (!NUMBER_INPUT_PATTERN.test(cleaned)) { |
|
|
|
|
|
console.log(`[NUM_LOG] onChange rejected pattern: "${cleaned}"`); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const parsed = parseFloat(cleaned); |
|
|
const parsed = parseFloat(cleaned); |
|
|
|
|
|
console.log( |
|
|
|
|
|
`[NUM_LOG] onChange calling setAnswerValue with:`, |
|
|
|
|
|
Number.isNaN(parsed) ? cleaned : parsed, |
|
|
|
|
|
); |
|
|
setAnswerValue( |
|
|
setAnswerValue( |
|
|
question, |
|
|
question, |
|
|
Number.isNaN(parsed) ? cleaned : parsed, |
|
|
Number.isNaN(parsed) ? cleaned : parsed, |
|
|
|