535 lines
20 KiB
TypeScript
535 lines
20 KiB
TypeScript
|
|
import {
|
|||
|
|
Button,
|
|||
|
|
FormContainer,
|
|||
|
|
FormItem,
|
|||
|
|
Input,
|
|||
|
|
Notification,
|
|||
|
|
Radio,
|
|||
|
|
Select,
|
|||
|
|
Tabs,
|
|||
|
|
toast,
|
|||
|
|
} from '@/components/ui'
|
|||
|
|
import TabContent from '@/components/ui/Tabs/TabContent'
|
|||
|
|
import TabList from '@/components/ui/Tabs/TabList'
|
|||
|
|
import TabNav from '@/components/ui/Tabs/TabNav'
|
|||
|
|
import { UserInfoViewModel } from '@/proxy/admin/models'
|
|||
|
|
import { dynamicFetch } from '@/services/form.service'
|
|||
|
|
import { putUserDetail } from '@/services/identity.service'
|
|||
|
|
import { SelectBoxOption } from '@/types/shared'
|
|||
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|||
|
|
import dayjs from 'dayjs'
|
|||
|
|
import { Field, FieldProps, Formik, FormikProps } from 'formik'
|
|||
|
|
import { useEffect, useMemo, useState } from 'react'
|
|||
|
|
import PlatformViewHost from '@/components/componentEditor/PlatformViewHost'
|
|||
|
|
|
|||
|
|
type HealthValues = UserInfoViewModel & Record<string, unknown>
|
|||
|
|
|
|||
|
|
interface DoctorOption {
|
|||
|
|
key: string
|
|||
|
|
name: string
|
|||
|
|
diplomaNo?: string
|
|||
|
|
diplomaDate?: string
|
|||
|
|
ohsCertificateNo?: string
|
|||
|
|
ohsCertificateDate?: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const H = '::Abp.Identity.User.HealthCard'
|
|||
|
|
|
|||
|
|
const familyRows = ['Mother', 'Father', 'Sibling', 'Child']
|
|||
|
|
const vaccinationRows = ['TetanusVaccination', 'HepatitisVaccination', 'OtherVaccination']
|
|||
|
|
|
|||
|
|
/** [alan, girintili mi] — görseldeki "- Kan" gibi alt kalemler girintilidir. */
|
|||
|
|
const labRows: [string, boolean][] = [
|
|||
|
|
['LabBiologicalAnalysis', false],
|
|||
|
|
['LabBlood', true],
|
|||
|
|
['LabUrine', true],
|
|||
|
|
['LabRadiological', false],
|
|||
|
|
['LabRadiologicalPhysiological', false],
|
|||
|
|
['LabAudiometry', true],
|
|||
|
|
['LabPulmonaryFunction', true],
|
|||
|
|
['LabPsychologicalTests', false],
|
|||
|
|
['LabOther', false],
|
|||
|
|
]
|
|||
|
|
const examRows: [string, boolean][] = [
|
|||
|
|
['ExamSensoryOrgans', false],
|
|||
|
|
['ExamEye', true],
|
|||
|
|
['ExamEnt', true],
|
|||
|
|
['ExamSkin', true],
|
|||
|
|
['ExamCardiovascular', false],
|
|||
|
|
['ExamRespiratory', false],
|
|||
|
|
['ExamDigestive', false],
|
|||
|
|
['ExamUrogenital', false],
|
|||
|
|
['ExamMusculoskeletal', false],
|
|||
|
|
]
|
|||
|
|
const otherExamRows: [string, boolean][] = [
|
|||
|
|
['ExamNeurological', false],
|
|||
|
|
['ExamPsychiatric', false],
|
|||
|
|
['ExamOther', false],
|
|||
|
|
['ExamBloodPressure', true],
|
|||
|
|
['ExamPulse', true],
|
|||
|
|
]
|
|||
|
|
const complaintRows = [
|
|||
|
|
'ComplaintProductiveCough',
|
|||
|
|
'ComplaintDyspnea',
|
|||
|
|
'ComplaintChestPain',
|
|||
|
|
'ComplaintPalpitation',
|
|||
|
|
'ComplaintBackPain',
|
|||
|
|
'ComplaintDiarrheaConstipation',
|
|||
|
|
'ComplaintJointPain',
|
|||
|
|
]
|
|||
|
|
const diagnosisRows = [
|
|||
|
|
'DiagnosisHeartDisease',
|
|||
|
|
'DiagnosisDiabetes',
|
|||
|
|
'DiagnosisKidneyDisease',
|
|||
|
|
'DiagnosisJaundice',
|
|||
|
|
'DiagnosisPepticUlcer',
|
|||
|
|
'DiagnosisHearingLoss',
|
|||
|
|
'DiagnosisVisionImpairment',
|
|||
|
|
'DiagnosisNervousSystemDisease',
|
|||
|
|
'DiagnosisSkinDisease',
|
|||
|
|
'DiagnosisFoodPoisoning',
|
|||
|
|
]
|
|||
|
|
const questionRows = [
|
|||
|
|
'Hospitalized',
|
|||
|
|
'HadSurgery',
|
|||
|
|
'HadWorkAccident',
|
|||
|
|
'OccupationalDiseaseExam',
|
|||
|
|
'DisabilityPension',
|
|||
|
|
'UnderTreatment',
|
|||
|
|
]
|
|||
|
|
const bloodTypes = ['A Rh+', 'A Rh-', 'B Rh+', 'B Rh-', 'AB Rh+', 'AB Rh-', '0 Rh+', '0 Rh-']
|
|||
|
|
|
|||
|
|
/** Kullanıcıya göre süzülen alt listeler; sekme adı = ListForm kodunun son parçası. */
|
|||
|
|
const healthLists = ['UserPeriodicExamination', 'UserPatientProtocol', 'UserSickLeave']
|
|||
|
|
|
|||
|
|
const fieldName = (name: string) => name.charAt(0).toLowerCase() + name.slice(1)
|
|||
|
|
|
|||
|
|
const formatDateNo = (date?: string, no?: string) =>
|
|||
|
|
`${date ? dayjs(date).format('DD.MM.YYYY') : ''} / ${no ?? ''}`
|
|||
|
|
|
|||
|
|
interface HealthCardTabProps {
|
|||
|
|
userDetails: UserInfoViewModel
|
|||
|
|
onSaved: () => void
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function HealthCardTab({ userDetails, onSaved }: HealthCardTabProps) {
|
|||
|
|
const { translate } = useLocalization()
|
|||
|
|
const [doctors, setDoctors] = useState<DoctorOption[]>([])
|
|||
|
|
const [activeTab, setActiveTab] = useState('history')
|
|||
|
|
// Yeni satırın UserId değeri de bu filtreden dolar (applyNewRowDefaults).
|
|||
|
|
const userSearchParams = useMemo(
|
|||
|
|
() => new URLSearchParams({ filter: JSON.stringify(['UserId', '=', userDetails.id]) }),
|
|||
|
|
[userDetails.id],
|
|||
|
|
)
|
|||
|
|
const isListTab = healthLists.includes(activeTab)
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
// Hekim listesi kullanıcı ekranının alan lookup'ından gelir; sorgu kiracıya göre süzülür.
|
|||
|
|
const loadDoctors = async () => {
|
|||
|
|
try {
|
|||
|
|
const response = await dynamicFetch('list-form-select/lookup', 'POST', null, {
|
|||
|
|
listFormCode: 'AbpIdentity.Users',
|
|||
|
|
listFormFieldName: 'FitnessDoctorId',
|
|||
|
|
})
|
|||
|
|
const rows = Array.isArray(response?.data) ? response.data : []
|
|||
|
|
setDoctors(
|
|||
|
|
rows.map((row: Record<string, string>) => ({
|
|||
|
|
key: row.Key,
|
|||
|
|
name: row.Name,
|
|||
|
|
diplomaNo: row.DiplomaNo,
|
|||
|
|
diplomaDate: row.DiplomaDate,
|
|||
|
|
ohsCertificateNo: row.OhsCertificateNo,
|
|||
|
|
ohsCertificateDate: row.OhsCertificateDate,
|
|||
|
|
})),
|
|||
|
|
)
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('Doctors could not be loaded:', error)
|
|||
|
|
setDoctors([])
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
void loadDoctors()
|
|||
|
|
}, [])
|
|||
|
|
|
|||
|
|
const healthStatusOptions: SelectBoxOption[] = [
|
|||
|
|
{ value: 'Alive', label: translate('::App.StaticLookup.Alive') },
|
|||
|
|
{ value: 'Deceased', label: translate('::App.StaticLookup.Deceased') },
|
|||
|
|
]
|
|||
|
|
const bloodTypeOptions: SelectBoxOption[] = bloodTypes.map((bloodType) => ({
|
|||
|
|
value: bloodType,
|
|||
|
|
label: bloodType,
|
|||
|
|
}))
|
|||
|
|
const smokingOptions: SelectBoxOption[] = [
|
|||
|
|
{ value: 'No', label: translate('::App.Platform.No') },
|
|||
|
|
{ value: 'Yes', label: translate('::App.Platform.Yes') },
|
|||
|
|
{ value: 'Quit', label: translate('::App.StaticLookup.Quit') },
|
|||
|
|
]
|
|||
|
|
const alcoholOptions: SelectBoxOption[] = [
|
|||
|
|
{ value: 'No', label: translate('::App.Platform.No') },
|
|||
|
|
{ value: 'Occasionally', label: translate('::App.StaticLookup.Occasionally') },
|
|||
|
|
{ value: 'Yes', label: translate('::App.Platform.Yes') },
|
|||
|
|
]
|
|||
|
|
const doctorOptions: SelectBoxOption[] = doctors.map((doctor) => ({
|
|||
|
|
value: doctor.key,
|
|||
|
|
label: doctor.name,
|
|||
|
|
}))
|
|||
|
|
|
|||
|
|
const label = (name: string) => translate(`${H}.${name}`)
|
|||
|
|
|
|||
|
|
const renderSelect = (name: string, options: SelectBoxOption[], values: HealthValues) => (
|
|||
|
|
<Field name={name}>
|
|||
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|||
|
|
<Select
|
|||
|
|
field={field}
|
|||
|
|
form={form}
|
|||
|
|
options={options}
|
|||
|
|
isClearable={true}
|
|||
|
|
value={options.filter((option) => option.value === values[name])}
|
|||
|
|
onChange={(option) => form.setFieldValue(field.name, option?.value ?? null)}
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
</Field>
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const renderText = (name: string, placeholder: string) => (
|
|||
|
|
<Field type="text" name={name} placeholder={placeholder} component={Input} />
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const renderYesNo = (name: string, { values, setFieldValue }: FormikProps<HealthValues>) => (
|
|||
|
|
<div className="flex gap-4 items-center h-full">
|
|||
|
|
{[true, false].map((answer) => (
|
|||
|
|
<Radio
|
|||
|
|
key={String(answer)}
|
|||
|
|
name={name}
|
|||
|
|
checked={values[name] === answer}
|
|||
|
|
onChange={() => setFieldValue(name, answer)}
|
|||
|
|
>
|
|||
|
|
{translate(answer ? '::App.Platform.Yes' : '::App.Platform.No')}
|
|||
|
|
</Radio>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
/** Görseldeki üst "Evet / Hayır" seçimi: bloğun bütün sorularını tek seferde işaretler. */
|
|||
|
|
const renderSetAll = (names: string[], { setFieldValue }: FormikProps<HealthValues>) => (
|
|||
|
|
<div className="flex gap-2 mb-2">
|
|||
|
|
{[true, false].map((answer) => (
|
|||
|
|
<Button
|
|||
|
|
key={String(answer)}
|
|||
|
|
size="xs"
|
|||
|
|
type="button"
|
|||
|
|
onClick={() => names.forEach((name) => setFieldValue(fieldName(name), answer))}
|
|||
|
|
>
|
|||
|
|
{translate(answer ? '::App.Platform.Yes' : '::App.Platform.No')}
|
|||
|
|
</Button>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const renderTextRows = (rows: [string, boolean][]) =>
|
|||
|
|
rows.map(([name, indented]) => (
|
|||
|
|
<div key={name} className="grid grid-cols-[180px_1fr] gap-x-3 items-start">
|
|||
|
|
<div className={`font-semibold pt-2 ${indented ? 'pl-4' : ''}`}>
|
|||
|
|
{indented ? '- ' : ''}
|
|||
|
|
{label(name)}
|
|||
|
|
</div>
|
|||
|
|
<FormItem>{renderText(fieldName(name), label(name))}</FormItem>
|
|||
|
|
</div>
|
|||
|
|
))
|
|||
|
|
|
|||
|
|
const renderYesNoRows = (rows: string[], formik: FormikProps<HealthValues>) => (
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6">
|
|||
|
|
{rows.map((name) => (
|
|||
|
|
<div key={name} className="grid grid-cols-[1fr_150px] gap-x-3 items-center mb-2">
|
|||
|
|
<div className="font-semibold">{label(name)}</div>
|
|||
|
|
{renderYesNo(fieldName(name), formik)}
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const renderDoctor = (name: string, values: HealthValues) => {
|
|||
|
|
const doctor = doctors.find((item) => item.key === values[fieldName(name)])
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[180px_1fr_180px_1fr_240px_1fr] gap-x-3 items-start">
|
|||
|
|
<div className="font-semibold pt-2">{label(name)}</div>
|
|||
|
|
<FormItem>{renderSelect(fieldName(name), doctorOptions, values)}</FormItem>
|
|||
|
|
<div className="font-semibold pt-2">{label('DiplomaDateNo')}</div>
|
|||
|
|
<FormItem>
|
|||
|
|
<Input disabled value={formatDateNo(doctor?.diplomaDate, doctor?.diplomaNo)} />
|
|||
|
|
</FormItem>
|
|||
|
|
<div className="font-semibold pt-2">{label('OhsCertificateDateNo')}</div>
|
|||
|
|
<FormItem>
|
|||
|
|
<Input
|
|||
|
|
disabled
|
|||
|
|
value={formatDateNo(doctor?.ohsCertificateDate, doctor?.ohsCertificateNo)}
|
|||
|
|
/>
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const bodyMassIndex = (values: HealthValues) => {
|
|||
|
|
const height = Number(values.examHeight)
|
|||
|
|
const weight = Number(values.examWeight)
|
|||
|
|
if (!height || !weight) return 0
|
|||
|
|
return Number((weight / (height / 100) ** 2).toFixed(2))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Formik
|
|||
|
|
enableReinitialize
|
|||
|
|
initialValues={userDetails as HealthValues}
|
|||
|
|
onSubmit={async (values, { setSubmitting }) => {
|
|||
|
|
setSubmitting(true)
|
|||
|
|
// Sayı kutusu metin döndürür; API decimal bekler.
|
|||
|
|
const toNumber = (value: unknown) =>
|
|||
|
|
value === '' || value === null || value === undefined ? undefined : Number(value)
|
|||
|
|
await putUserDetail({
|
|||
|
|
...values,
|
|||
|
|
examHeight: toNumber(values.examHeight),
|
|||
|
|
examWeight: toNumber(values.examWeight),
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
toast.push(
|
|||
|
|
<Notification type="success" duration={2000}>
|
|||
|
|
{translate('::App.Platform.Save')}
|
|||
|
|
</Notification>,
|
|||
|
|
{
|
|||
|
|
placement: 'bottom-end',
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
onSaved()
|
|||
|
|
setSubmitting(false)
|
|||
|
|
}}
|
|||
|
|
>
|
|||
|
|
{(formik) => {
|
|||
|
|
const { isSubmitting, values } = formik
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
// Alt listeler bu bileşenin içinde çizildiği için form etiketi kullanılmaz; liste
|
|||
|
|
// düğmeleri kart formunu göndermesin.
|
|||
|
|
<div>
|
|||
|
|
<FormContainer size="md">
|
|||
|
|
<Tabs value={activeTab} variant="pill" onChange={(tab) => setActiveTab(String(tab))}>
|
|||
|
|
<TabList>
|
|||
|
|
<TabNav value="history">{label('History')}</TabNav>
|
|||
|
|
<TabNav value="labPhysical">{label('LabPhysical')}</TabNav>
|
|||
|
|
<TabNav value="anamnesis">{label('Anamnesis')}</TabNav>
|
|||
|
|
<TabNav value="result">{label('Result')}</TabNav>
|
|||
|
|
{healthLists.map((code) => (
|
|||
|
|
<TabNav key={code} value={code}>
|
|||
|
|
{translate(`::App.IdentityManagement.${code}`)}
|
|||
|
|
</TabNav>
|
|||
|
|
))}
|
|||
|
|
</TabList>
|
|||
|
|
|
|||
|
|
<TabContent value="history">
|
|||
|
|
<div className="pt-4">
|
|||
|
|
<h6 className="mb-4">{label('FamilyHistory')}</h6>
|
|||
|
|
{familyRows.map((member) => (
|
|||
|
|
<div
|
|||
|
|
key={member}
|
|||
|
|
className="grid grid-cols-1 md:grid-cols-[200px_200px_1fr] gap-x-5 items-start"
|
|||
|
|
>
|
|||
|
|
<div className="font-semibold pt-2">{label(`${member}HealthStatus`)}</div>
|
|||
|
|
<FormItem>
|
|||
|
|
{renderSelect(
|
|||
|
|
fieldName(`${member}HealthStatus`),
|
|||
|
|
healthStatusOptions,
|
|||
|
|
values,
|
|||
|
|
)}
|
|||
|
|
</FormItem>
|
|||
|
|
<FormItem>
|
|||
|
|
{renderText(
|
|||
|
|
fieldName(`${member}HealthNote`),
|
|||
|
|
label(`${member}HealthNote`),
|
|||
|
|
)}
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
|
|||
|
|
<h6 className="mt-4 mb-4">{label('PersonalHistory')}</h6>
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[200px_1fr] gap-x-5 items-start">
|
|||
|
|
<div className="font-semibold pt-2">
|
|||
|
|
{translate('::Abp.Account.BloodType')}
|
|||
|
|
</div>
|
|||
|
|
<FormItem>{renderSelect('bloodType', bloodTypeOptions, values)}</FormItem>
|
|||
|
|
|
|||
|
|
<div className="font-semibold pt-2">{label('ChronicDisease')}</div>
|
|||
|
|
<FormItem>{renderText('chronicDisease', label('ChronicDisease'))}</FormItem>
|
|||
|
|
|
|||
|
|
<div className="font-semibold pt-2 md:col-span-2 mb-2">
|
|||
|
|
{label('Immunization')}
|
|||
|
|
</div>
|
|||
|
|
{vaccinationRows.map((vaccination) => (
|
|||
|
|
<div key={vaccination} className="contents">
|
|||
|
|
<div className="font-semibold pt-2 md:pl-4">- {label(vaccination)}</div>
|
|||
|
|
<FormItem>
|
|||
|
|
{renderText(fieldName(vaccination), label(vaccination))}
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</TabContent>
|
|||
|
|
|
|||
|
|
<TabContent value="labPhysical">
|
|||
|
|
<div className="pt-4 grid grid-cols-1 xl:grid-cols-[1fr_2fr] gap-x-8">
|
|||
|
|
<div>
|
|||
|
|
<h6 className="mb-4">{label('LaboratoryFindings')}</h6>
|
|||
|
|
{renderTextRows(labRows)}
|
|||
|
|
</div>
|
|||
|
|
<div>
|
|||
|
|
<h6 className="mb-4">{label('PhysicalExamResults')}</h6>
|
|||
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-6">
|
|||
|
|
<div>{renderTextRows(examRows)}</div>
|
|||
|
|
<div>
|
|||
|
|
{renderTextRows(otherExamRows)}
|
|||
|
|
{['ExamHeight', 'ExamWeight'].map((name) => (
|
|||
|
|
<div
|
|||
|
|
key={name}
|
|||
|
|
className="grid grid-cols-[180px_1fr] gap-x-3 items-start"
|
|||
|
|
>
|
|||
|
|
<div className="font-semibold pt-2 pl-4">- {label(name)}</div>
|
|||
|
|
<FormItem>
|
|||
|
|
<Field
|
|||
|
|
type="number"
|
|||
|
|
name={fieldName(name)}
|
|||
|
|
placeholder={label(name)}
|
|||
|
|
component={Input}
|
|||
|
|
/>
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
<div className="grid grid-cols-[180px_1fr] gap-x-3 items-start">
|
|||
|
|
<div className="font-semibold pt-2 pl-4">
|
|||
|
|
- {label('BodyMassIndex')}
|
|||
|
|
</div>
|
|||
|
|
<FormItem>
|
|||
|
|
<Input disabled value={bodyMassIndex(values)} />
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</TabContent>
|
|||
|
|
|
|||
|
|
<TabContent value="anamnesis">
|
|||
|
|
<div className="pt-4">
|
|||
|
|
{renderSetAll([...complaintRows, ...diagnosisRows], formik)}
|
|||
|
|
<div className="grid grid-cols-1 xl:grid-cols-2 gap-x-8">
|
|||
|
|
<div>
|
|||
|
|
<h6 className="mb-4">{label('ComplaintsQuestion')}</h6>
|
|||
|
|
{renderYesNoRows(complaintRows, formik)}
|
|||
|
|
</div>
|
|||
|
|
<div>
|
|||
|
|
<h6 className="mb-4">{label('DiagnosesQuestion')}</h6>
|
|||
|
|
{renderYesNoRows(diagnosisRows, formik)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="mt-6">
|
|||
|
|
{renderSetAll(questionRows, formik)}
|
|||
|
|
{questionRows.map((name) => (
|
|||
|
|
<div key={name}>
|
|||
|
|
<h6 className="mb-2">{label(name)}</h6>
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[150px_1fr] gap-x-3 items-start">
|
|||
|
|
{renderYesNo(fieldName(name), formik)}
|
|||
|
|
<FormItem>
|
|||
|
|
{renderText(fieldName(`${name}Note`), label(`${name}Note`))}
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
{(
|
|||
|
|
[
|
|||
|
|
['Smoking', smokingOptions],
|
|||
|
|
['Alcohol', alcoholOptions],
|
|||
|
|
] as const
|
|||
|
|
).map(([name, options]) => (
|
|||
|
|
<div key={name}>
|
|||
|
|
<h6 className="mb-2">{label(name)}</h6>
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[150px_1fr] gap-x-3 items-start">
|
|||
|
|
<FormItem>
|
|||
|
|
{renderSelect(fieldName(name), [...options], values)}
|
|||
|
|
</FormItem>
|
|||
|
|
<FormItem>
|
|||
|
|
{renderText(fieldName(`${name}Note`), label(`${name}Note`))}
|
|||
|
|
</FormItem>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</TabContent>
|
|||
|
|
|
|||
|
|
<TabContent value="result">
|
|||
|
|
<div className="pt-4">
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[40px_1fr_auto] gap-x-3 items-start">
|
|||
|
|
<div className="font-semibold pt-2">1.</div>
|
|||
|
|
<FormItem>{renderText('fitForWorkJob', label('FitForWorkJob'))}</FormItem>
|
|||
|
|
<div className="font-semibold pt-2">{label('FitForWorkJobSuffix')}</div>
|
|||
|
|
|
|||
|
|
<div className="font-semibold pt-2">2.</div>
|
|||
|
|
<FormItem>
|
|||
|
|
{renderText('fitForWorkCondition', label('FitForWorkCondition'))}
|
|||
|
|
</FormItem>
|
|||
|
|
<div className="font-semibold pt-2">{label('FitForWorkConditionSuffix')}</div>
|
|||
|
|
</div>
|
|||
|
|
{renderDoctor('FitnessDoctorId', values)}
|
|||
|
|
|
|||
|
|
<p className="my-6 text-center font-semibold">{label('ShiftNightInfo')}</p>
|
|||
|
|
|
|||
|
|
<div className="grid grid-cols-1 md:grid-cols-[200px_150px] gap-2 items-center mb-4">
|
|||
|
|
{['ShiftWorkFit', 'NightWorkFit'].map((name) => (
|
|||
|
|
<div key={name} className="contents">
|
|||
|
|
<div className="font-semibold">{label(name)}</div>
|
|||
|
|
{renderYesNo(fieldName(name), formik)}
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
{renderDoctor('ShiftNightDoctorId', values)}
|
|||
|
|
</div>
|
|||
|
|
</TabContent>
|
|||
|
|
|
|||
|
|
{healthLists.map((code) => (
|
|||
|
|
<TabContent key={code} value={code}>
|
|||
|
|
<div className="pt-4">
|
|||
|
|
<PlatformViewHost
|
|||
|
|
view="List"
|
|||
|
|
listFormCode={`App.IdentityManagement.${code}`}
|
|||
|
|
height="320px"
|
|||
|
|
searchParams={userSearchParams}
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
</TabContent>
|
|||
|
|
))}
|
|||
|
|
</Tabs>
|
|||
|
|
</FormContainer>
|
|||
|
|
|
|||
|
|
{!isListTab && (
|
|||
|
|
<div className="mt-4 ltr:text-right">
|
|||
|
|
<Button
|
|||
|
|
variant="solid"
|
|||
|
|
loading={isSubmitting}
|
|||
|
|
type="button"
|
|||
|
|
onClick={() => void formik.submitForm()}
|
|||
|
|
>
|
|||
|
|
{isSubmitting
|
|||
|
|
? translate('::App.Platform.Saving')
|
|||
|
|
: translate('::App.Platform.Save')}
|
|||
|
|
</Button>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}}
|
|||
|
|
</Formik>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default HealthCardTab
|