@kenyaemr/esm-morgue-app 5.4.2-pre.2333 → 5.4.2-pre.2347

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.turbo/turbo-build.log +20 -25
  2. package/dist/1.js +2 -0
  3. package/dist/1.js.map +1 -0
  4. package/dist/197.js +2 -1
  5. package/dist/197.js.map +1 -0
  6. package/dist/221.js +1 -1
  7. package/dist/221.js.map +1 -1
  8. package/dist/293.js +1 -1
  9. package/dist/294.js +1 -1
  10. package/dist/300.js +1 -1
  11. package/dist/340.js +2 -0
  12. package/dist/340.js.map +1 -0
  13. package/dist/351.js +1 -0
  14. package/dist/351.js.map +1 -0
  15. package/dist/404.js +1 -0
  16. package/dist/404.js.map +1 -0
  17. package/dist/441.js +1 -0
  18. package/dist/441.js.map +1 -0
  19. package/dist/578.js +1 -0
  20. package/dist/608.js +1 -0
  21. package/dist/608.js.map +1 -0
  22. package/dist/611.js +2 -0
  23. package/dist/611.js.map +1 -0
  24. package/dist/632.js +1 -1
  25. package/dist/632.js.map +1 -1
  26. package/dist/653.js +1 -1
  27. package/dist/653.js.map +1 -1
  28. package/dist/758.js +1 -0
  29. package/dist/758.js.map +1 -0
  30. package/dist/805.js +1 -1
  31. package/dist/805.js.map +1 -1
  32. package/dist/814.js +2 -0
  33. package/dist/814.js.LICENSE.txt +5 -0
  34. package/dist/814.js.map +1 -0
  35. package/dist/824.js +1 -1
  36. package/dist/824.js.map +1 -1
  37. package/dist/845.js +1 -0
  38. package/dist/845.js.map +1 -0
  39. package/dist/888.js +1 -0
  40. package/dist/888.js.map +1 -0
  41. package/dist/918.js +1 -1
  42. package/dist/918.js.map +1 -1
  43. package/dist/990.js +1 -0
  44. package/dist/990.js.map +1 -0
  45. package/dist/kenyaemr-esm-morgue-app.js +1 -1
  46. package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +250 -203
  47. package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
  48. package/dist/main.js +1 -1
  49. package/dist/main.js.LICENSE.txt +0 -6
  50. package/dist/main.js.map +1 -1
  51. package/dist/routes.json +1 -1
  52. package/package.json +1 -1
  53. package/src/bed/bed.component.tsx +63 -134
  54. package/src/bed/components/deceased-patient-card-header.component.tsx +73 -0
  55. package/src/bed/components/deceased-patient-info.component.tsx +47 -0
  56. package/src/bed/components/deceased-patient-status-footer.component.tsx +43 -0
  57. package/src/bed-layout/admitted/admitted-bed-layout.component.tsx +175 -96
  58. package/src/bed-layout/awaiting/awaiting-bed-layout.component.tsx +103 -36
  59. package/src/bed-layout/bed-layout.scss +4 -0
  60. package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +131 -73
  61. package/src/bed-linelist-view/admitted/admitted-bed-linelist-view.component.tsx +182 -134
  62. package/src/bed-linelist-view/awaiting/awaiting-bed-linelist-view.component.tsx +115 -71
  63. package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +181 -109
  64. package/src/config-schema.ts +140 -4
  65. package/src/context/deceased-person-context.tsx +33 -0
  66. package/src/extension/actionButton.component.tsx +1 -1
  67. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.resource.ts +84 -166
  68. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.scss +14 -0
  69. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.workspace.tsx +504 -334
  70. package/src/forms/discharge-deceased-person-workspace/discharge-body.resource.ts +0 -1
  71. package/src/forms/discharge-deceased-person-workspace/discharge-body.scss +15 -0
  72. package/src/forms/discharge-deceased-person-workspace/discharge-body.workspace.tsx +303 -244
  73. package/src/helpers/expression-helper.ts +122 -0
  74. package/src/home/home.component.tsx +23 -4
  75. package/src/index.ts +0 -2
  76. package/src/metrics/metrics-card.component.tsx +2 -2
  77. package/src/routes.json +0 -6
  78. package/src/schemas/index.ts +243 -51
  79. package/src/summary/summary.component.tsx +16 -9
  80. package/src/switcher/content-switcher.component.tsx +61 -35
  81. package/src/switcher/content-switcher.scss +13 -0
  82. package/src/types/index.ts +43 -1
  83. package/translations/am.json +16 -6
  84. package/translations/en.json +16 -6
  85. package/translations/sw.json +16 -6
  86. package/dist/373.js +0 -2
  87. package/dist/373.js.map +0 -1
  88. package/dist/398.js +0 -1
  89. package/dist/398.js.map +0 -1
  90. package/dist/410.js +0 -1
  91. package/dist/410.js.map +0 -1
  92. package/dist/429.js +0 -2
  93. package/dist/429.js.map +0 -1
  94. package/dist/467.js +0 -1
  95. package/dist/467.js.map +0 -1
  96. package/dist/579.js +0 -2
  97. package/dist/579.js.map +0 -1
  98. package/dist/619.js +0 -1
  99. package/dist/619.js.map +0 -1
  100. package/dist/633.js +0 -1
  101. package/dist/633.js.map +0 -1
  102. package/dist/712.js +0 -1
  103. package/dist/712.js.map +0 -1
  104. package/dist/713.js +0 -1
  105. package/dist/713.js.map +0 -1
  106. package/dist/723.js +0 -1
  107. package/dist/723.js.map +0 -1
  108. package/dist/989.js +0 -2
  109. package/dist/989.js.map +0 -1
  110. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.resource.ts +0 -18
  111. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.scss +0 -84
  112. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.workspace.tsx +0 -505
  113. /package/dist/{373.js.LICENSE.txt → 1.js.LICENSE.txt} +0 -0
  114. /package/dist/{989.js.LICENSE.txt → 197.js.LICENSE.txt} +0 -0
  115. /package/dist/{579.js.LICENSE.txt → 340.js.LICENSE.txt} +0 -0
  116. /package/dist/{429.js.LICENSE.txt → 611.js.LICENSE.txt} +0 -0
@@ -1,3 +1,4 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
1
2
  import {
2
3
  Button,
3
4
  ButtonSet,
@@ -5,8 +6,11 @@ import {
5
6
  DatePicker,
6
7
  DatePickerInput,
7
8
  Form,
9
+ FormGroup,
8
10
  InlineLoading,
9
11
  InlineNotification,
12
+ RadioButton,
13
+ RadioButtonGroup,
10
14
  SelectItem,
11
15
  Stack,
12
16
  TextInput,
@@ -16,31 +20,29 @@ import {
16
20
  import { zodResolver } from '@hookform/resolvers/zod';
17
21
  import {
18
22
  ExtensionSlot,
19
- fhirBaseUrl,
20
23
  ResponsiveWrapper,
21
- restBaseUrl,
22
- setCurrentVisit,
23
24
  showSnackbar,
24
25
  useConfig,
25
26
  useLayoutType,
26
27
  useVisit,
28
+ usePatient,
29
+ restBaseUrl,
30
+ fhirBaseUrl,
31
+ setCurrentVisit, // Add this import
27
32
  } from '@openmrs/esm-framework';
28
- import React, { useCallback, useEffect, useState } from 'react';
29
33
  import { Controller, useForm } from 'react-hook-form';
30
34
  import { useTranslation } from 'react-i18next';
31
- import { mutate as mutateSWR } from 'swr';
32
- import { z } from 'zod';
33
35
  import styles from './discharge-body.scss';
34
36
  import DeceasedInfo from '../../deceased-patient-header/deceasedInfo/deceased-info.component';
35
- import { PatientInfo } from '../../types';
36
37
  import { useBlockDischargeWithPendingBills, usePersonAttributes } from './discharge-body.resource';
37
- import { ConfigObject } from '../../config-schema';
38
38
  import { getCurrentTime } from '../../utils/utils';
39
- import { dischargeSchema } from '../../schemas';
39
+ import { dischargeFormSchema, DischargeType } from '../../schemas';
40
40
  import { useVisitQueueEntry } from '../../home/home.resource';
41
41
  import classNames from 'classnames';
42
42
  import { useMortuaryOperation } from '../admit-deceased-person-workspace/admit-deceased-person.resource';
43
-
43
+ import { ConfigObject } from '../../config-schema';
44
+ import { PatientInfo } from '../../types';
45
+ import { mutate as mutateSWR } from 'swr';
44
46
  interface DischargeFormProps {
45
47
  closeWorkspace: () => void;
46
48
  patientUuid: string;
@@ -48,8 +50,6 @@ interface DischargeFormProps {
48
50
  mutate: () => void;
49
51
  }
50
52
 
51
- type DischargeFormValues = z.infer<typeof dischargeSchema>;
52
-
53
53
  const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUuid, bedId, mutate }) => {
54
54
  const { t } = useTranslation();
55
55
  const isTablet = useLayoutType() === 'tablet';
@@ -57,93 +57,80 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
57
57
 
58
58
  const { activeVisit, currentVisitIsRetrospective } = useVisit(patientUuid);
59
59
  const { queueEntry } = useVisitQueueEntry(patientUuid, activeVisit?.uuid);
60
-
61
- const { dischargeBody, isLoadingEmrConfiguration } = useMortuaryOperation();
60
+ const { dischargeBody } = useMortuaryOperation();
61
+ const { patient } = usePatient(patientUuid);
62
62
 
63
63
  const {
64
64
  createOrUpdatePersonAttribute,
65
65
  personAttributes,
66
66
  isLoading: isLoadingAttributes,
67
67
  } = usePersonAttributes(patientUuid);
68
-
69
68
  const { isDischargeBlocked, blockingMessage, isLoadingBills } = useBlockDischargeWithPendingBills({
70
69
  patientUuid,
71
70
  actionType: 'discharge',
72
71
  });
73
72
 
74
- const { nextOfKinNameUuid, nextOfKinRelationshipUuid, nextOfKinPhoneUuid, nextOfKinAddressUuid } =
73
+ const { nextOfKinNameUuid, nextOfKinRelationshipUuid, nextOfKinPhoneUuid, nextOfKinNationalIdUuid } =
75
74
  useConfig<ConfigObject>();
76
-
77
75
  const { time: defaultTime, period: defaultPeriod } = getCurrentTime();
78
76
 
79
- const getAttributeValue = useCallback(
80
- (attributeTypeUuid: string) => {
81
- if (!personAttributes || !Array.isArray(personAttributes)) {
82
- return '';
83
- }
84
- const attribute = personAttributes.find((attr) => attr.attributeType.uuid === attributeTypeUuid);
85
- return attribute ? attribute.value : '';
86
- },
87
- [personAttributes],
88
- );
89
-
90
- const getExistingAttributeUuid = useCallback(
91
- (attributeTypeUuid: string) => {
92
- if (!personAttributes || !Array.isArray(personAttributes)) {
93
- return null;
94
- }
95
- const attribute = personAttributes.find((attr) => attr.attributeType.uuid === attributeTypeUuid);
96
- return attribute ? attribute.uuid : null;
97
- },
98
- [personAttributes],
99
- );
100
-
101
77
  const {
102
78
  control,
103
79
  setValue,
104
80
  handleSubmit,
105
- formState: { errors, isDirty, isSubmitting },
106
81
  watch,
107
- } = useForm<DischargeFormValues>({
108
- resolver: zodResolver(dischargeSchema),
82
+ formState: { errors, isDirty, isSubmitting },
83
+ } = useForm({
84
+ resolver: zodResolver(dischargeFormSchema),
109
85
  defaultValues: {
86
+ dischargeType: 'discharge',
110
87
  dateOfDischarge: new Date(),
111
88
  timeOfDischarge: defaultTime,
112
89
  period: defaultPeriod,
113
90
  burialPermitNumber: '',
91
+ dischargeArea: '',
92
+ receivingArea: '',
93
+ reasonForTransfer: '',
114
94
  nextOfKinNames: '',
115
95
  relationshipType: '',
116
96
  nextOfKinContact: '',
117
- nextOfKinAddress: '',
97
+ nextOfKinNationalId: '',
98
+ serialNumber: '',
99
+ courtOrderCaseNumber: '',
118
100
  },
119
101
  });
120
102
 
121
- useEffect(() => {
122
- if (Array.isArray(personAttributes) && personAttributes.length > 0) {
123
- const initialValues = {
124
- nextOfKinNames: getAttributeValue(nextOfKinNameUuid),
125
- relationshipType: getAttributeValue(nextOfKinRelationshipUuid),
126
- nextOfKinContact: getAttributeValue(nextOfKinPhoneUuid),
127
- nextOfKinAddress: getAttributeValue(nextOfKinAddressUuid),
128
- };
103
+ const selectedDischargeType = watch('dischargeType');
129
104
 
130
- Object.entries(initialValues).forEach(([field, value]) => {
131
- if (value !== undefined && value !== null && value !== '') {
132
- setValue(field as keyof DischargeFormValues, value);
133
- }
134
- });
105
+ useEffect(() => {
106
+ if (personAttributes?.length) {
107
+ setValue('nextOfKinNames', getAttributeValue(nextOfKinNameUuid));
108
+ setValue('relationshipType', getAttributeValue(nextOfKinRelationshipUuid));
109
+ setValue('nextOfKinContact', getAttributeValue(nextOfKinPhoneUuid));
110
+ setValue('nextOfKinNationalId', getAttributeValue(nextOfKinNationalIdUuid));
135
111
  }
136
112
  }, [
137
113
  personAttributes,
138
114
  setValue,
139
- getAttributeValue,
140
115
  nextOfKinNameUuid,
141
116
  nextOfKinRelationshipUuid,
142
117
  nextOfKinPhoneUuid,
143
- nextOfKinAddressUuid,
118
+ nextOfKinNationalIdUuid,
144
119
  ]);
145
120
 
146
- const onSubmit = async (data: DischargeFormValues) => {
121
+ const getAttributeValue = useCallback(
122
+ (attributeTypeUuid: string) =>
123
+ personAttributes?.find((attr) => attr.attributeType.uuid === attributeTypeUuid)?.value || '',
124
+ [personAttributes],
125
+ );
126
+
127
+ const getExistingAttributeUuid = useCallback(
128
+ (attributeTypeUuid: string) =>
129
+ personAttributes?.find((attr) => attr.attributeType.uuid === attributeTypeUuid)?.uuid || null,
130
+ [personAttributes],
131
+ );
132
+
133
+ const onSubmit = async (data) => {
147
134
  setSubmissionError(null);
148
135
 
149
136
  if (currentVisitIsRetrospective) {
@@ -153,10 +140,8 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
153
140
  }
154
141
 
155
142
  try {
156
- // First, perform the discharge operation
157
143
  await dischargeBody(activeVisit, queueEntry, bedId, data);
158
144
 
159
- // Then update person attributes
160
145
  const attributeUpdates = [
161
146
  {
162
147
  uuid: nextOfKinNameUuid,
@@ -174,9 +159,9 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
174
159
  existingUuid: getExistingAttributeUuid(nextOfKinPhoneUuid),
175
160
  },
176
161
  {
177
- uuid: nextOfKinAddressUuid,
178
- value: data.nextOfKinAddress,
179
- existingUuid: getExistingAttributeUuid(nextOfKinAddressUuid),
162
+ uuid: nextOfKinNationalIdUuid,
163
+ value: data.nextOfKinNationalId,
164
+ existingUuid: getExistingAttributeUuid(nextOfKinNationalIdUuid),
180
165
  },
181
166
  ].filter((attr) => attr.value !== undefined && attr.value !== null && attr.value !== '');
182
167
 
@@ -207,7 +192,6 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
207
192
  }
208
193
  }
209
194
 
210
- // Invalidate relevant caches
211
195
  await Promise.all([
212
196
  mutateSWR((key) => typeof key === 'string' && key.startsWith(`${restBaseUrl}/visit`)),
213
197
  mutateSWR((key) => typeof key === 'string' && key.startsWith(`${restBaseUrl}/patient`)),
@@ -243,109 +227,120 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
243
227
  }
244
228
  };
245
229
 
246
- if (isLoadingEmrConfiguration || isLoadingAttributes || !activeVisit) {
247
- return <InlineLoading status="active" iconDescription="Loading" description={t('loading', 'Loading...')} />;
248
- }
249
-
250
230
  return (
251
231
  <Form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
252
232
  <div className={styles.formContainer}>
253
- {isLoadingBills && (
254
- <InlineLoading
255
- status="active"
256
- iconDescription="Loading"
257
- description={t('loadingBills', 'Loading bills...')}
258
- />
259
- )}
260
-
233
+ {isLoadingBills && <InlineLoading description={t('loadingBills', 'Loading bills...')} />}
261
234
  {isDischargeBlocked && (
262
- <InlineNotification
263
- kind="warning"
264
- title={t('warningMsg', 'Warning')}
265
- subtitle={blockingMessage}
266
- lowContrast={true}
267
- className={styles.blockingNotification}
268
- />
235
+ <InlineNotification kind="warning" title={t('warning', 'Warning')} subtitle={blockingMessage} lowContrast />
269
236
  )}
270
-
271
237
  {submissionError && (
272
- <InlineNotification
273
- kind="error"
274
- title={t('error', 'Error')}
275
- subtitle={submissionError}
276
- lowContrast={true}
277
- className={styles.errorNotification}
278
- />
238
+ <InlineNotification kind="error" title={t('error', 'Error')} subtitle={submissionError} lowContrast />
279
239
  )}
280
240
 
281
241
  <Stack gap={3}>
282
242
  <DeceasedInfo patientUuid={patientUuid} />
283
243
 
284
- <ResponsiveWrapper>
285
- <div className={styles.dateTimePickerContainer}>
286
- <Column>
287
- <Controller
288
- name="dateOfDischarge"
289
- control={control}
290
- render={({ field }) => (
291
- <DatePicker
292
- datePickerType="single"
293
- className={styles.formAdmissionDatepicker}
294
- onChange={(event) => {
295
- if (event.length) {
296
- field.onChange(event[0]);
297
- }
298
- }}
299
- value={field.value ? new Date(field.value) : null}>
300
- <DatePickerInput
301
- {...field}
302
- id="date-of-discharge"
303
- placeholder="yyyy-mm-dd"
304
- labelText={t('dateOfDischarge', 'Date of discharge*')}
305
- invalid={!!errors.dateOfDischarge}
306
- invalidText={errors.dateOfDischarge?.message}
307
- />
308
- </DatePicker>
309
- )}
310
- />
311
- </Column>
312
-
313
- <Column>
314
- <div className={styles.dateTimeSection}>
315
- <ResponsiveWrapper>
316
- <Controller
317
- name="timeOfDischarge"
318
- control={control}
319
- render={({ field }) => (
320
- <TimePicker
244
+ <FormGroup legendText={t('dischargeType', 'Discharge type')}>
245
+ <Controller
246
+ name="dischargeType"
247
+ control={control}
248
+ render={({ field }) => (
249
+ <RadioButtonGroup
250
+ name="dischargeType"
251
+ orientation="vertical"
252
+ value={field.value}
253
+ defaultSelected={field.value}
254
+ onChange={field.onChange}>
255
+ <RadioButton
256
+ className={styles.radioButton}
257
+ value="discharge"
258
+ labelText={t('discharge', 'Discharge')}
259
+ />
260
+ <RadioButton className={styles.radioButton} value="transfer" labelText={t('transfer', 'Transfer')} />
261
+ <RadioButton className={styles.radioButton} value="dispose" labelText={t('dispose', 'Dispose')} />
262
+ </RadioButtonGroup>
263
+ )}
264
+ />
265
+ </FormGroup>
266
+
267
+ {(selectedDischargeType === 'discharge' || selectedDischargeType === 'transfer') && (
268
+ <ResponsiveWrapper>
269
+ <div className={styles.dateTimePickerContainer}>
270
+ <Column>
271
+ <Controller
272
+ name="dateOfDischarge"
273
+ control={control}
274
+ render={({ field }) => (
275
+ <DatePicker
276
+ datePickerType="single"
277
+ className={styles.formAdmissionDatepicker}
278
+ onChange={(event) => {
279
+ if (event.length) {
280
+ field.onChange(event[0]);
281
+ }
282
+ }}
283
+ value={field.value ? new Date(field.value) : null}>
284
+ <DatePickerInput
321
285
  {...field}
322
- id="time-of-discharge-picker"
323
- labelText={t('timeOfDischarge', 'Time of discharge*')}
324
- className={styles.formAdmissionTimepicker}
325
- invalid={!!errors.timeOfDischarge}
326
- invalidText={errors.timeOfDischarge?.message}
286
+ id="date-of-discharge"
287
+ placeholder="yyyy-mm-dd"
288
+ labelText={
289
+ selectedDischargeType === 'discharge'
290
+ ? t('dateOfDischarge', 'Date of discharge*')
291
+ : t('dateOfTransfer', 'Date of transfer*')
292
+ }
293
+ invalid={!!errors.dateOfDischarge}
294
+ invalidText={errors.dateOfDischarge?.message}
327
295
  />
328
- )}
329
- />
330
- <Controller
331
- name="period"
332
- control={control}
333
- render={({ field }) => (
334
- <TimePickerSelect
335
- {...field}
336
- className={styles.formDeathTimepickerSelector}
337
- id="time-picker-select">
338
- <SelectItem value="AM" text="AM" />
339
- <SelectItem value="PM" text="PM" />
340
- </TimePickerSelect>
341
- )}
342
- />
343
- </ResponsiveWrapper>
344
- </div>
345
- </Column>
346
- </div>
296
+ </DatePicker>
297
+ )}
298
+ />
299
+ </Column>
300
+
301
+ <Column>
302
+ <div className={styles.dateTimeSection}>
303
+ <ResponsiveWrapper>
304
+ <Controller
305
+ name="timeOfDischarge"
306
+ control={control}
307
+ render={({ field }) => (
308
+ <TimePicker
309
+ {...field}
310
+ id="time-of-discharge-picker"
311
+ labelText={
312
+ selectedDischargeType === 'discharge'
313
+ ? t('timeOfDischarge', 'Time of discharge*')
314
+ : t('timeOfTransfer', 'Time of transfer*')
315
+ }
316
+ className={styles.formAdmissionTimepicker}
317
+ invalid={!!errors.timeOfDischarge}
318
+ invalidText={errors.timeOfDischarge?.message}
319
+ />
320
+ )}
321
+ />
322
+ <Controller
323
+ name="period"
324
+ control={control}
325
+ render={({ field }) => (
326
+ <TimePickerSelect
327
+ {...field}
328
+ className={styles.formDeathTimepickerSelector}
329
+ id="time-picker-select">
330
+ <SelectItem value="AM" text="AM" />
331
+ <SelectItem value="PM" text="PM" />
332
+ </TimePickerSelect>
333
+ )}
334
+ />
335
+ </ResponsiveWrapper>
336
+ </div>
337
+ </Column>
338
+ </div>
339
+ </ResponsiveWrapper>
340
+ )}
347
341
 
348
- <Column className={styles.fieldColumn}>
342
+ <ResponsiveWrapper>
343
+ <Column>
349
344
  <Controller
350
345
  name="burialPermitNumber"
351
346
  control={control}
@@ -353,126 +348,190 @@ const DischargeForm: React.FC<DischargeFormProps> = ({ closeWorkspace, patientUu
353
348
  <TextInput
354
349
  {...field}
355
350
  id="burialPermitNumber"
356
- type="text"
357
- className={styles.sectionField}
358
- placeholder={t('burialPermitNumber', 'Burial permit number')}
359
- labelText={t('burialPermitNumber', 'Burial permit number')}
351
+ labelText={t('permitSerialNumber', 'Permit serial number*')}
360
352
  invalid={!!errors.burialPermitNumber}
361
353
  invalidText={errors.burialPermitNumber?.message}
362
354
  />
363
355
  )}
364
356
  />
365
357
  </Column>
358
+ </ResponsiveWrapper>
366
359
 
367
- <Column className={styles.fieldColumn}>
360
+ <ResponsiveWrapper>
361
+ <Column>
368
362
  <Controller
369
- name="nextOfKinNames"
363
+ name="dischargeArea"
370
364
  control={control}
371
365
  render={({ field }) => (
372
366
  <TextInput
373
367
  {...field}
374
- id="nextOfKinNames"
375
- type="text"
376
- className={styles.sectionField}
377
- placeholder={t('nextOfKinNames', 'Next of kin names')}
378
- labelText={t('nextOfKinNames', 'Next of kin names')}
379
- invalid={!!errors.nextOfKinNames}
380
- invalidText={errors.nextOfKinNames?.message}
368
+ id="dischargeArea"
369
+ labelText={t('dischargeArea', 'Discharge Area*')}
370
+ invalid={!!errors.dischargeArea}
371
+ invalidText={errors.dischargeArea?.message}
381
372
  />
382
373
  )}
383
374
  />
384
375
  </Column>
376
+ </ResponsiveWrapper>
385
377
 
386
- <Column className={styles.fieldColumn}>
387
- <Controller
388
- name="relationshipType"
389
- control={control}
390
- render={({ field }) => (
391
- <TextInput
392
- {...field}
393
- id="relationshipType"
394
- type="text"
395
- className={styles.sectionField}
396
- placeholder={t('relationshipType', 'Relationship')}
397
- labelText={t('relationshipType', 'Relationship')}
398
- invalid={!!errors.relationshipType}
399
- invalidText={errors.relationshipType?.message}
378
+ {selectedDischargeType === 'transfer' && (
379
+ <>
380
+ <ResponsiveWrapper>
381
+ <Column>
382
+ <Controller
383
+ name="receivingArea"
384
+ control={control}
385
+ render={({ field }) => (
386
+ <TextInput
387
+ {...field}
388
+ id="receivingArea"
389
+ labelText={t('receivingArea', 'Receiving mortuary*')}
390
+ invalid={!!errors.receivingArea}
391
+ invalidText={errors.receivingArea?.message}
392
+ />
393
+ )}
400
394
  />
401
- )}
402
- />
403
- </Column>
404
-
405
- <Column className={styles.fieldColumn}>
406
- <Controller
407
- name="nextOfKinContact"
408
- control={control}
409
- render={({ field }) => (
410
- <TextInput
411
- {...field}
412
- id="nextOfKinContact"
413
- type="text"
414
- className={styles.sectionField}
415
- placeholder={t('nextOfKinContact', 'Next of kin contact')}
416
- labelText={t('nextOfKinContact', 'Next of kin contact')}
417
- invalid={!!errors.nextOfKinContact}
418
- invalidText={errors.nextOfKinContact?.message}
395
+ </Column>
396
+ </ResponsiveWrapper>
397
+ <ResponsiveWrapper>
398
+ <Column>
399
+ <Controller
400
+ name="reasonForTransfer"
401
+ control={control}
402
+ render={({ field }) => (
403
+ <TextInput
404
+ {...field}
405
+ id="reasonForTransfer"
406
+ labelText={t('reasonForTransfer', 'Reason for transfer*')}
407
+ invalid={!!errors.reasonForTransfer}
408
+ invalidText={errors.reasonForTransfer?.message}
409
+ />
410
+ )}
419
411
  />
420
- )}
421
- />
422
- </Column>
412
+ </Column>
413
+ </ResponsiveWrapper>
414
+ </>
415
+ )}
423
416
 
424
- <Column className={styles.fieldColumn}>
425
- <Controller
426
- name="nextOfKinAddress"
427
- control={control}
428
- render={({ field }) => (
429
- <TextInput
430
- {...field}
431
- id="nextOfKinAddress"
432
- type="text"
433
- className={styles.sectionField}
434
- placeholder={t('nextOfKinAddress', 'Next of kin address')}
435
- labelText={t('nextOfKinAddress', 'Next of kin address')}
436
- invalid={!!errors.nextOfKinAddress}
437
- invalidText={errors.nextOfKinAddress?.message}
417
+ {selectedDischargeType === 'dispose' && (
418
+ <>
419
+ <ResponsiveWrapper>
420
+ <Column>
421
+ <Controller
422
+ name="serialNumber"
423
+ control={control}
424
+ render={({ field }) => (
425
+ <TextInput
426
+ {...field}
427
+ id="serialNumber"
428
+ labelText={t('serialNumber', 'Serial Number*')}
429
+ invalid={!!errors.serialNumber}
430
+ invalidText={errors.serialNumber?.message}
431
+ />
432
+ )}
438
433
  />
439
- )}
440
- />
441
- </Column>
442
- </ResponsiveWrapper>
434
+ </Column>
435
+ </ResponsiveWrapper>
436
+ <ResponsiveWrapper>
437
+ <Column>
438
+ <Controller
439
+ name="courtOrderCaseNumber"
440
+ control={control}
441
+ render={({ field }) => (
442
+ <TextInput
443
+ {...field}
444
+ id="courtOrderCaseNumber"
445
+ labelText={t('courtOrderCaseNumber', 'Court Order Case Number*')}
446
+ invalid={!!errors.courtOrderCaseNumber}
447
+ invalidText={errors.courtOrderCaseNumber?.message}
448
+ />
449
+ )}
450
+ />
451
+ </Column>
452
+ </ResponsiveWrapper>
453
+ </>
454
+ )}
443
455
 
444
- <ResponsiveWrapper>
445
- <Column>
446
- <ExtensionSlot
447
- name="patient-chart-attachments-dashboard-slot"
448
- className={styles.sectionField}
449
- state={{
450
- patientUuid,
451
- }}
452
- />
453
- </Column>
454
- </ResponsiveWrapper>
456
+ <FormGroup legendText={t('nextOfKinInformation', 'Next of Kin Information')}>
457
+ <Stack gap={3}>
458
+ <Column>
459
+ <Controller
460
+ name="nextOfKinNames"
461
+ control={control}
462
+ render={({ field }) => (
463
+ <TextInput
464
+ {...field}
465
+ id="nextOfKinNames"
466
+ labelText={t('nextOfKinNames', 'Next of kin names*')}
467
+ invalid={!!errors.nextOfKinNames}
468
+ invalidText={errors.nextOfKinNames?.message}
469
+ />
470
+ )}
471
+ />
472
+ </Column>
473
+ <Column>
474
+ <Controller
475
+ name="relationshipType"
476
+ control={control}
477
+ render={({ field }) => (
478
+ <TextInput
479
+ {...field}
480
+ id="relationshipType"
481
+ labelText={t('relationshipType', 'Relationship*')}
482
+ invalid={!!errors.relationshipType}
483
+ invalidText={errors.relationshipType?.message}
484
+ />
485
+ )}
486
+ />
487
+ </Column>
488
+ <Column>
489
+ <Controller
490
+ name="nextOfKinContact"
491
+ control={control}
492
+ render={({ field }) => (
493
+ <TextInput
494
+ {...field}
495
+ id="nextOfKinContact"
496
+ labelText={t('nextOfKinContact', 'Next of kin contact*')}
497
+ invalid={!!errors.nextOfKinContact}
498
+ invalidText={errors.nextOfKinContact?.message}
499
+ />
500
+ )}
501
+ />
502
+ </Column>
503
+ <Column>
504
+ <Controller
505
+ name="nextOfKinNationalId"
506
+ control={control}
507
+ render={({ field }) => (
508
+ <TextInput
509
+ {...field}
510
+ id="nextOfKinNationalId"
511
+ labelText={t('nextOfKinNationalId', 'Next of kin National ID*')}
512
+ invalid={!!errors.nextOfKinNationalId}
513
+ invalidText={errors.nextOfKinNationalId?.message}
514
+ />
515
+ )}
516
+ />
517
+ </Column>
518
+ </Stack>
519
+ </FormGroup>
520
+
521
+ <ExtensionSlot name="patient-chart-attachments-dashboard-slot" state={{ patientUuid }} />
455
522
  </Stack>
456
523
  </div>
457
524
 
458
- <ButtonSet
459
- className={classNames({
460
- [styles.tablet]: isTablet,
461
- [styles.desktop]: !isTablet,
462
- })}>
463
- <Button className={styles.buttonContainer} kind="secondary" onClick={() => closeWorkspace()}>
525
+ <ButtonSet className={classNames(styles.buttonSet, { [styles.tablet]: isTablet })}>
526
+ <Button kind="secondary" onClick={closeWorkspace}>
464
527
  {t('cancel', 'Cancel')}
465
528
  </Button>
466
529
  <Button
467
- className={styles.buttonContainer}
468
- disabled={isSubmitting || !isDirty || isDischargeBlocked || isLoadingBills}
469
530
  kind="primary"
470
- type="submit">
531
+ type="submit"
532
+ disabled={isSubmitting || !isDirty || isDischargeBlocked || isLoadingBills || !patient}>
471
533
  {isSubmitting ? (
472
- <span className={styles.inlineLoading}>
473
- {t('submitting', 'Submitting...')}
474
- <InlineLoading status="active" iconDescription="Loading" />
475
- </span>
534
+ <InlineLoading description={t('submitting', 'Submitting...')} />
476
535
  ) : (
477
536
  t('saveAndClose', 'Save & close')
478
537
  )}