Browse Source

feat: support full 195 countries dataset merging in QuestionSheet for nationality and country fields

master
mortezaei 4 days ago
parent
commit
6121938a17
  1. 90
      src/components/Componentes/question-sheet.tsx

90
src/components/Componentes/question-sheet.tsx

@ -2,7 +2,8 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { getLanguageList, LANGUAGES_EN, LANGUAGES_FA } from "@/data/languages";
import { COUNTRIES_EN, COUNTRIES_FA } from "@/data/countries";
import { LANGUAGES_EN, LANGUAGES_FA } from "@/data/languages";
import type { QuestionField } from "@/lib/schema-adapter";
import { useI18n } from "@/translations/provider";
import { Button } from "./button";
@ -81,12 +82,26 @@ export function QuestionSheet({ question, disabled }: QuestionSheetProps) {
question.title?.includes("زبان") ||
question.ui_config?.dataset === "languages";
const isCountryQuestion =
question.id?.toLowerCase().includes("nationality") ||
question.id?.toLowerCase().includes("citizenship") ||
question.id?.toLowerCase().includes("country") ||
question.id?.toLowerCase().includes("birthplace") ||
question.id?.toLowerCase().includes("residence") ||
question.title?.toLowerCase().includes("nationality") ||
question.title?.toLowerCase().includes("citizenship") ||
question.title?.toLowerCase().includes("country") ||
question.title?.includes("ملیت") ||
question.title?.includes("تابعیت") ||
question.title?.includes("کشور") ||
question.title?.includes("سکونت") ||
question.ui_config?.dataset === "countries" ||
question.ui_config?.dataset === "nationalities";
const options = useMemo(() => {
const rawOptions = question.options || [];
if (!isLanguageQuestion) {
return rawOptions;
}
if (isLanguageQuestion) {
const existingByLabel = new Map(
rawOptions.map((opt) => [opt.label.toLowerCase().trim(), opt]),
);
@ -137,7 +152,63 @@ export function QuestionSheet({ question, disabled }: QuestionSheetProps) {
});
return mergedOptions;
}, [question, isLanguageQuestion, locale, t]);
}
if (isCountryQuestion) {
const existingByLabel = new Map(
rawOptions.map((opt) => [opt.label.toLowerCase().trim(), opt]),
);
const existingByVal = new Map(
rawOptions.map((opt) => [String(opt.value).toLowerCase().trim(), opt]),
);
const existingById = new Map(
rawOptions.map((opt) => [opt.id.toLowerCase().trim(), opt]),
);
const mergedOptions: typeof rawOptions = [];
const seenIds = new Set<string>();
COUNTRIES_EN.forEach((enCountry, idx) => {
const localizedLabel =
(locale === "fa" || locale === "fa-ir"
? COUNTRIES_FA[idx]
: (t as any)[enCountry]) || enCountry;
const cleanSlug = enCountry
.toLowerCase()
.replace(/[^a-z0-9]+/g, "_")
.replace(/^_+|_+$/g, "");
const generatedId = `${question.id}.${cleanSlug}`;
const existing =
existingByLabel.get(enCountry.toLowerCase()) ||
existingByLabel.get(localizedLabel.toLowerCase()) ||
existingByVal.get(cleanSlug) ||
existingById.get(generatedId.toLowerCase());
const finalId = existing?.id || generatedId;
if (seenIds.has(finalId)) return;
seenIds.add(finalId);
mergedOptions.push({
id: finalId,
value: existing?.value ?? cleanSlug,
label: existing?.label ?? localizedLabel,
order: existing?.order ?? idx,
});
});
rawOptions.forEach((opt) => {
if (!seenIds.has(opt.id)) {
seenIds.add(opt.id);
mergedOptions.push(opt);
}
});
return mergedOptions;
}
return rawOptions;
}, [question, isLanguageQuestion, isCountryQuestion, locale, t]);
const COMPACT_OPTIONS_MAX = 6;
@ -166,7 +237,14 @@ export function QuestionSheet({ question, disabled }: QuestionSheetProps) {
);
const getCleanLabel = (optId: string) => {
const opt = options.find((o) => o.id === optId);
const normalized = String(optId || "").toLowerCase().trim();
const opt = options.find(
(o) =>
o.id === optId ||
o.id.toLowerCase() === normalized ||
String(o.value).toLowerCase() === normalized ||
o.id.endsWith(`.${normalized}`),
);
if (!opt) return optId;
return opt.label.split(" - ")[0];
};

Loading…
Cancel
Save