You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.6 KiB
148 lines
4.6 KiB
import {
|
|
isQuestionRequiredForProfile,
|
|
isQuestionVisibleForProfile,
|
|
type QuestionListItem,
|
|
} from "@/data/question-data";
|
|
import { hasQuestionAnswerValue } from "./question-answer-storage";
|
|
|
|
export function getStoredAge(): number | null {
|
|
try {
|
|
if (typeof window === "undefined") return null;
|
|
const rawValue = window.localStorage.getItem(
|
|
"marriage:sections:personal_info:answers",
|
|
);
|
|
if (!rawValue) return null;
|
|
const storedAnswers = JSON.parse(rawValue);
|
|
const ageField = storedAnswers.fields?.find(
|
|
(f: any) =>
|
|
f.type === "number" ||
|
|
f.label === "Age" ||
|
|
f.label === "سن" ||
|
|
(typeof f.key === "string" &&
|
|
(f.key.endsWith("_age") || f.key.endsWith("_sn"))),
|
|
);
|
|
if (ageField && ageField.value !== undefined && ageField.value !== null) {
|
|
const num = Number(ageField.value);
|
|
if (Number.isFinite(num)) return num;
|
|
}
|
|
const dobField = storedAnswers.fields?.find(
|
|
(f: any) =>
|
|
f.type === "date" ||
|
|
f.label === "Date of Birth" ||
|
|
f.label === "تاریخ تولد" ||
|
|
(typeof f.key === "string" &&
|
|
(f.key.endsWith("_date_of_birth") || f.key.endsWith("_tarykh_twld"))),
|
|
);
|
|
if (dobField && dobField.value) {
|
|
const dob = new Date(dobField.value);
|
|
if (!Number.isNaN(dob.getTime())) {
|
|
const today = new Date();
|
|
let age = today.getFullYear() - dob.getFullYear();
|
|
const m = today.getMonth() - dob.getMonth();
|
|
if (m < 0 || (m === 0 && today.getDate() < dob.getDate())) {
|
|
age--;
|
|
}
|
|
return age >= 0 ? age : null;
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
return null;
|
|
}
|
|
|
|
function isFieldAnswered(q: any, field: any): boolean {
|
|
if (!field || !hasQuestionAnswerValue(field.value)) {
|
|
return false;
|
|
}
|
|
if (q.type === "birthplace") {
|
|
const strVal = String(field.value);
|
|
const parts = strVal.split(",").map((p) => p.trim());
|
|
return parts.length >= 2 && parts[0].length > 0 && parts[1].length > 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function getLocalSectionProgress(
|
|
item: QuestionListItem,
|
|
profile: any,
|
|
age: number | null,
|
|
): number | null {
|
|
try {
|
|
if (typeof window === "undefined") return null;
|
|
const storageKey = `marriage:sections:${item.slug}:answers`;
|
|
const rawValue = window.localStorage.getItem(storageKey);
|
|
if (!rawValue) {
|
|
return null;
|
|
}
|
|
const storedValue = JSON.parse(rawValue);
|
|
if (storedValue && storedValue.completed) {
|
|
return 100;
|
|
}
|
|
if (
|
|
!storedValue ||
|
|
!Array.isArray(storedValue.fields) ||
|
|
storedValue.fields.length === 0
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
const profileContext = {
|
|
age,
|
|
gender: profile?.gender,
|
|
};
|
|
|
|
const visibleQuestions = item.questions
|
|
.filter((question) =>
|
|
isQuestionVisibleForProfile(question, profileContext),
|
|
)
|
|
.map((question) => ({
|
|
...question,
|
|
required: isQuestionRequiredForProfile(question, profileContext),
|
|
}));
|
|
|
|
const requiredQuestions = visibleQuestions.filter((q) => q.required);
|
|
if (requiredQuestions.length === 0) {
|
|
if (visibleQuestions.length === 0) {
|
|
return 100;
|
|
}
|
|
const answeredCount = visibleQuestions.filter((q, index) => {
|
|
const slugifyTitle = (title: string) =>
|
|
title
|
|
.normalize("NFKD")
|
|
.replace(/[\u0300-\u036f]/g, "")
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "_")
|
|
.replace(/^_+|_+$/g, "");
|
|
const fieldKey = `q${index + 1}_${slugifyTitle(q.title)}`;
|
|
const field = storedValue.fields.find(
|
|
(f: any) => f.key === fieldKey || f.label === q.title,
|
|
);
|
|
return isFieldAnswered(q, field);
|
|
}).length;
|
|
return Math.round((answeredCount / visibleQuestions.length) * 100);
|
|
}
|
|
|
|
const answeredRequiredCount = requiredQuestions.filter((q) => {
|
|
const originalIndex = item.questions.findIndex(
|
|
(origQ) => origQ.title === q.title,
|
|
);
|
|
if (originalIndex === -1) return false;
|
|
|
|
const slugifyTitle = (title: string) =>
|
|
title
|
|
.normalize("NFKD")
|
|
.replace(/[\u0300-\u036f]/g, "")
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "_")
|
|
.replace(/^_+|_+$/g, "");
|
|
const fieldKey = `q${originalIndex + 1}_${slugifyTitle(q.title)}`;
|
|
const field = storedValue.fields.find(
|
|
(f: any) => f.key === fieldKey || f.label === q.title,
|
|
);
|
|
return isFieldAnswered(q, field);
|
|
}).length;
|
|
|
|
return Math.round((answeredRequiredCount / requiredQuestions.length) * 100);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|