Browse Source

fix(birthplace): align string format with backend contract (Country, City)

master
mortezaei 3 days ago
parent
commit
f33e40b82d
  1. 28
      src/components/Componentes/question-birthplace.test.ts
  2. 64
      src/components/Componentes/question-birthplace.tsx
  3. 2
      src/components/Componentes/ui-config.test.tsx

28
src/components/Componentes/question-birthplace.test.ts

@ -15,34 +15,34 @@ describe("QuestionBirthplace parseValue", () => {
});
});
it("parses standard 'City, Country' strings", () => {
expect(parseValue("Tehran, Iran")).toEqual({
city: "Tehran",
it("parses standard 'Country, City' strings", () => {
expect(parseValue("Iran, Tehran")).toEqual({
country: "Iran",
city: "Tehran",
});
expect(parseValue("شیراز, ایران")).toEqual({
city: "شیراز",
expect(parseValue("ایران, شیراز")).toEqual({
country: "ایران",
city: "شیراز",
});
});
it("never swaps city and country even when city equals country name", () => {
// City typed as 'albania' and country selected as 'Afghanistan'
expect(parseValue("albania, Afghanistan")).toEqual({
city: "albania",
it("never swaps country and city even when city equals country name", () => {
// Country selected as 'Afghanistan' and city typed as 'albania'
expect(parseValue("Afghanistan, albania")).toEqual({
country: "Afghanistan",
city: "albania",
});
// City typed as 'Albania' and country selected as 'Albania'
// Country selected as 'Albania' and city typed as 'Albania'
expect(parseValue("Albania, Albania")).toEqual({
city: "Albania",
country: "Albania",
city: "Albania",
});
// City typed as 'Georgia' and country selected as 'United States (US)'
expect(parseValue("Georgia, United States (US)")).toEqual({
city: "Georgia",
// Country selected as 'United States (US)' and city typed as 'Georgia'
expect(parseValue("United States (US), Georgia")).toEqual({
country: "United States (US)",
city: "Georgia",
});
});

64
src/components/Componentes/question-birthplace.tsx

@ -66,22 +66,22 @@ export function parseValue(rawValue: unknown): { country: string; city: string }
);
if (str.includes(",")) {
const idx = str.lastIndexOf(",");
const cityPart = str.slice(0, idx).trim();
const countryPart = str.slice(idx + 1).trim();
return { city: cityPart, country: countryPart };
const idx = str.indexOf(",");
const countryPart = str.slice(0, idx).trim();
const cityPart = str.slice(idx + 1).trim();
return { country: countryPart, city: cityPart };
}
if (str.includes("،")) {
const idx = str.lastIndexOf("،");
const cityPart = str.slice(0, idx).trim();
const countryPart = str.slice(idx + 1).trim();
return { city: cityPart, country: countryPart };
const idx = str.indexOf("،");
const countryPart = str.slice(0, idx).trim();
const cityPart = str.slice(idx + 1).trim();
return { country: countryPart, city: cityPart };
}
if (str.includes(" - ")) {
const idx = str.lastIndexOf(" - ");
const cityPart = str.slice(0, idx).trim();
const countryPart = str.slice(idx + 3).trim();
return { city: cityPart, country: countryPart };
const idx = str.indexOf(" - ");
const countryPart = str.slice(0, idx).trim();
const cityPart = str.slice(idx + 3).trim();
return { country: countryPart, city: cityPart };
}
if (isKnownCountry(str)) {
@ -113,7 +113,7 @@ export function QuestionBirthplace({
const initialCity = initial.city || storedRegion?.city || "";
const initialLoc =
localizedInitialCountry || initialCity
? [initialCity, localizedInitialCountry].filter(Boolean).join(", ")
? [localizedInitialCountry, initialCity].filter(Boolean).join(", ")
: "";
const [selectedCountry, setSelectedCountry] = useState(
@ -182,9 +182,9 @@ export function QuestionBirthplace({
const cleanCountry = country?.trim() || "";
const cleanCity = city?.trim() || "";
const formatted =
cleanCity && cleanCountry
? `${cleanCity}, ${cleanCountry}`
: cleanCity || cleanCountry || null;
cleanCountry && cleanCity
? `${cleanCountry}, ${cleanCity}`
: cleanCountry || cleanCity || null;
lastInternalAnswerRef.current = formatted;
setAnswerValue(question, formatted);
};
@ -196,7 +196,7 @@ export function QuestionBirthplace({
const parsed = parseValue(rawValue);
const cName = resolveCountryName(parsed.country, locale) || parsed.country;
if (cName || parsed.city) {
const loc = [parsed.city, cName].filter(Boolean).join(", ");
const loc = [cName, parsed.city].filter(Boolean).join(", ");
if (cName) setSelectedCountry(cName);
if (parsed.city) setCityInput(parsed.city);
setDetectedLocation(loc);
@ -215,10 +215,10 @@ export function QuestionBirthplace({
const rawCountry = region.country || region.countryCode || "";
const country = resolveCountryName(rawCountry, locale) || rawCountry;
if (city || country) {
const loc = [city, country].filter(Boolean).join(", ");
if (country || city) {
setSelectedCountry(country);
setCityInput(city);
const loc = [country, city].filter(Boolean).join(", ");
setDetectedLocation(loc);
updateAnswers(country, city);
setMode("auto");
@ -234,7 +234,7 @@ export function QuestionBirthplace({
setIsDetecting(false);
}
}
}, [rawValue, locale]);
}, [rawValue, locale, question, setAnswerValue]);
useEffect(() => {
if (isLoading) return;
@ -264,7 +264,7 @@ export function QuestionBirthplace({
setSelectedCountry(country);
setCityInput(city);
updateAnswers(country, city);
setDetectedLocation([city, country].filter(Boolean).join(", "));
setDetectedLocation([country, city].filter(Boolean).join(", "));
};
// Synchronize state ONLY if rawValue changes externally (e.g. draft fetch or reset)
@ -274,14 +274,6 @@ export function QuestionBirthplace({
}
const updated = parseValue(rawValue);
const resolvedC = resolveCountryName(updated.country, locale) || updated.country;
console.log("[BIRTHPLACE_DEBUG] 🔄 External sync triggered: " + JSON.stringify({
rawValue,
lastInternal: lastInternalAnswerRef.current,
parsed: updated,
resolvedCountry: resolvedC,
currentSelectedCountry: selectedCountry,
currentCityInput: cityInput,
}));
if (resolvedC !== selectedCountry) {
setSelectedCountry(resolvedC);
}
@ -289,7 +281,7 @@ export function QuestionBirthplace({
setCityInput(updated.city);
}
if (resolvedC || updated.city) {
setDetectedLocation([updated.city, resolvedC].filter(Boolean).join(", "));
setDetectedLocation([resolvedC, updated.city].filter(Boolean).join(", "));
}
lastInternalAnswerRef.current = typeof rawValue === "string" ? rawValue : null;
}, [rawValue, locale]);
@ -303,14 +295,10 @@ export function QuestionBirthplace({
if (typeof window !== "undefined") {
localStorage.setItem("hasCheckedGeoIPResidence", "true");
}
console.log("[BIRTHPLACE_DEBUG] 🚩 handleSelectCountry called: " + JSON.stringify({
chosenCountry: country,
currentCityInput: cityInput,
}));
setSelectedCountry(country);
closeSheet();
updateAnswers(country, cityInput);
setDetectedLocation([cityInput, country].filter(Boolean).join(", "));
setDetectedLocation([country, cityInput].filter(Boolean).join(", "));
window.setTimeout(() => {
cityInputRef.current?.focus({ preventScroll: true });
}, EXIT_ANIMATION_MS);
@ -321,13 +309,9 @@ export function QuestionBirthplace({
localStorage.setItem("hasCheckedGeoIPResidence", "true");
}
const newCity = e.target.value;
console.log("[BIRTHPLACE_DEBUG] ✍️ handleCityChange called: " + JSON.stringify({
currentSelectedCountry: selectedCountry,
typedCity: newCity,
}));
setCityInput(newCity);
updateAnswers(selectedCountry, newCity);
setDetectedLocation([newCity, selectedCountry].filter(Boolean).join(", "));
setDetectedLocation([selectedCountry, newCity].filter(Boolean).join(", "));
};
const isRtl = locale === "fa" || locale === "ar" || locale === "ur";

2
src/components/Componentes/ui-config.test.tsx

@ -117,7 +117,7 @@ describe("UI Config based behavior", () => {
);
await waitFor(() => {
expect(screen.getByText(/Tehran.*(Iran|ایران)/i)).toBeDefined();
expect(screen.getByText(/(ایران|Iran).*Tehran/i)).toBeDefined();
});
});

Loading…
Cancel
Save