- Updated date handling in BlogSeoFields and ScheduleSection to use Tehran timezone utilities for consistency. - Introduced `toTehranClockTime`, `tehranWallClockToUnix`, and `todayIso` functions for accurate date representation. - Modified various components to utilize these new utilities, ensuring that date strings are correctly formatted and timestamps are accurately converted. - Enhanced API documentation to clarify the handling of date fields, emphasizing the importance of server-local midnight. - Added tests to verify that date overrides and holidays maintain the correct day without shifting due to timezone discrepancies.
88 lines
3.8 KiB
TypeScript
88 lines
3.8 KiB
TypeScript
import type { SelectOption } from '../components/ui/SearchableSelect';
|
|
import type { PatientProfile, PatientProfileUpdate } from '../types';
|
|
import type { PatientFormValues } from '../components/PatientRecordInfoForm';
|
|
import { unixToIso, tehranWallClockToUnix } from './utils';
|
|
|
|
// ── enumهای ثابت فرم «اطلاعات پرونده» (بدون منبع API) ─────────────────────────
|
|
export const GENDER_OPTS: SelectOption[] = [
|
|
{ value: 'female', label: 'زن' },
|
|
{ value: 'male', label: 'مرد' },
|
|
];
|
|
export const MARITAL_OPTS: SelectOption[] = [
|
|
{ value: 'single', label: 'مجرد' },
|
|
{ value: 'married', label: 'متأهل' },
|
|
{ value: 'divorced', label: 'مطلقه' },
|
|
{ value: 'widowed', label: 'بیوه' },
|
|
];
|
|
export const EDUCATION_OPTS: SelectOption[] = [
|
|
'زیر دیپلم', 'دیپلم', 'کاردانی', 'کارشناسی', 'کارشناسی ارشد', 'دکتری',
|
|
].map((v) => ({ value: v, label: v }));
|
|
export const REFERRAL_OPTS: SelectOption[] = [
|
|
'اینستاگرام', 'معرفی دوستان', 'جستجوی اینترنتی', 'بیلبورد', 'سایر',
|
|
].map((v) => ({ value: v, label: v }));
|
|
|
|
// ── تبدیل تاریخ: timestamp ثانیهای ↔ رشتهٔ میلادی YYYY-MM-DD ─────────────────
|
|
// هر دو سمت به وقت ایراناند تا با نیمهشبِ محلیِ ذخیرهشده در بکاند همراستا باشند؛
|
|
// تبدیل UTC روز را یک واحد جابهجا میکرد.
|
|
export function tsToDateStr(ts?: number | null): string {
|
|
return ts ? unixToIso(ts) : '';
|
|
}
|
|
export function dateStrToTs(s: string): number | null {
|
|
if (!s) return null;
|
|
const t = tehranWallClockToUnix(s, '00:00');
|
|
return Number.isNaN(t) ? null : t;
|
|
}
|
|
|
|
/** پروفایل API → مقادیر پیشفرض فرم. */
|
|
export function profileToFormValues(p: PatientProfile | null): PatientFormValues {
|
|
return {
|
|
name: p?.name ?? '',
|
|
mobile: p?.mobile ?? '',
|
|
national_code: p?.national_code ?? '',
|
|
gender: p?.gender ?? null,
|
|
birth_date: tsToDateStr(p?.date_of_birth),
|
|
fathers_name: p?.fathers_name ?? '',
|
|
marital_status: p?.marital_status ?? null,
|
|
basic_insurance_id: p?.basic_insurance_id ?? null,
|
|
supplementary_insurance_id: p?.supplementary_insurance_id ?? null,
|
|
field_of_study: p?.field_of_study ?? '',
|
|
education: p?.education ?? null,
|
|
job: p?.job ?? '',
|
|
province_id: p?.province_id ?? null,
|
|
city_id: p?.city_id ?? null,
|
|
home_phone: p?.home_phone ?? '',
|
|
address: p?.address ?? '',
|
|
postal_code: p?.postal_code ?? '',
|
|
referral_source: p?.referral_source ?? null,
|
|
description: p?.description ?? '',
|
|
};
|
|
}
|
|
|
|
/** مقادیر فرم → بدنهٔ PATCH. موبایل خالی ارسال نمیشود تا شناسهٔ ورود دستنخورده بماند. */
|
|
export function formValuesToPayload(v: PatientFormValues): PatientProfileUpdate {
|
|
const num = (x: number | string | null): number | null =>
|
|
x === null || x === '' ? null : Number(x);
|
|
const payload: PatientProfileUpdate = {
|
|
name: v.name,
|
|
national_code: v.national_code,
|
|
gender: v.gender,
|
|
fathers_name: v.fathers_name,
|
|
date_of_birth: dateStrToTs(v.birth_date),
|
|
marital_status: v.marital_status,
|
|
education: v.education,
|
|
field_of_study: v.field_of_study,
|
|
job: v.job,
|
|
basic_insurance_id: num(v.basic_insurance_id),
|
|
supplementary_insurance_id: num(v.supplementary_insurance_id),
|
|
province_id: num(v.province_id),
|
|
city_id: num(v.city_id),
|
|
home_phone: v.home_phone,
|
|
address: v.address,
|
|
postal_code: v.postal_code,
|
|
referral_source: v.referral_source,
|
|
description: v.description,
|
|
};
|
|
if (v.mobile) payload.mobile = v.mobile;
|
|
return payload;
|
|
}
|