@cc-openmrs/cc-esm-active-prescriptions 1.0.55 → 1.0.57
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.
- package/dist/499.js +1 -1
- package/dist/845.js +1 -0
- package/dist/main.js +1 -1
- package/dist/openmrs-esm-template-app.js.buildmanifest.json +26 -26
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/root.component.tsx +254 -159
- package/dist/11.js +0 -1
|
@@ -1,29 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"chunks": [
|
|
3
|
-
{
|
|
4
|
-
"rendered": true,
|
|
5
|
-
"initial": false,
|
|
6
|
-
"entry": false,
|
|
7
|
-
"recorded": false,
|
|
8
|
-
"size": 61649,
|
|
9
|
-
"sizes": {
|
|
10
|
-
"javascript": 61649
|
|
11
|
-
},
|
|
12
|
-
"names": [],
|
|
13
|
-
"idHints": [],
|
|
14
|
-
"runtime": [
|
|
15
|
-
"@cc-openmrs/cc-esm-active-prescriptions",
|
|
16
|
-
"main"
|
|
17
|
-
],
|
|
18
|
-
"files": [
|
|
19
|
-
"11.js"
|
|
20
|
-
],
|
|
21
|
-
"auxiliaryFiles": [
|
|
22
|
-
"11.js.map"
|
|
23
|
-
],
|
|
24
|
-
"hash": "add31f0c3fc094bc",
|
|
25
|
-
"childrenByOrder": {}
|
|
26
|
-
},
|
|
27
3
|
{
|
|
28
4
|
"rendered": true,
|
|
29
5
|
"initial": false,
|
|
@@ -379,7 +355,7 @@
|
|
|
379
355
|
"auxiliaryFiles": [
|
|
380
356
|
"499.js.map"
|
|
381
357
|
],
|
|
382
|
-
"hash": "
|
|
358
|
+
"hash": "18fd701fd0bcbb5c",
|
|
383
359
|
"childrenByOrder": {}
|
|
384
360
|
},
|
|
385
361
|
{
|
|
@@ -499,7 +475,7 @@
|
|
|
499
475
|
"auxiliaryFiles": [
|
|
500
476
|
"main.js.map"
|
|
501
477
|
],
|
|
502
|
-
"hash": "
|
|
478
|
+
"hash": "fe28e32959133b2b",
|
|
503
479
|
"childrenByOrder": {}
|
|
504
480
|
},
|
|
505
481
|
{
|
|
@@ -529,6 +505,30 @@
|
|
|
529
505
|
"hash": "31524ae59d310e8c",
|
|
530
506
|
"childrenByOrder": {}
|
|
531
507
|
},
|
|
508
|
+
{
|
|
509
|
+
"rendered": true,
|
|
510
|
+
"initial": false,
|
|
511
|
+
"entry": false,
|
|
512
|
+
"recorded": false,
|
|
513
|
+
"size": 55232,
|
|
514
|
+
"sizes": {
|
|
515
|
+
"javascript": 55232
|
|
516
|
+
},
|
|
517
|
+
"names": [],
|
|
518
|
+
"idHints": [],
|
|
519
|
+
"runtime": [
|
|
520
|
+
"@cc-openmrs/cc-esm-active-prescriptions",
|
|
521
|
+
"main"
|
|
522
|
+
],
|
|
523
|
+
"files": [
|
|
524
|
+
"845.js"
|
|
525
|
+
],
|
|
526
|
+
"auxiliaryFiles": [
|
|
527
|
+
"845.js.map"
|
|
528
|
+
],
|
|
529
|
+
"hash": "b81c9b4af8da9da5",
|
|
530
|
+
"childrenByOrder": {}
|
|
531
|
+
},
|
|
532
532
|
{
|
|
533
533
|
"rendered": true,
|
|
534
534
|
"initial": false,
|
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"extensions":[{"name":"Red box","component":"redBox","slot":"Boxes"},{"name":"Blue box","component":"blueBox","slot":"Boxes"},{"name":"Brand box","component":"blueBox","slot":"Boxes"},{"name":"prescriptions-action-menu","component":"prescriptionsActionButton","slot":"action-menu-patient-chart-items-slot"}],"workspaces":[{"name":"active-prescriptions","title":"activePrescriptionsWorkspaceTitle","component":"root","type":"active-prescriptions","canHide":false,"width":"wider"}],"version":"1.0.
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"extensions":[{"name":"Red box","component":"redBox","slot":"Boxes"},{"name":"Blue box","component":"blueBox","slot":"Boxes"},{"name":"Brand box","component":"blueBox","slot":"Boxes"},{"name":"prescriptions-action-menu","component":"prescriptionsActionButton","slot":"action-menu-patient-chart-items-slot"}],"workspaces":[{"name":"active-prescriptions","title":"activePrescriptionsWorkspaceTitle","component":"root","type":"active-prescriptions","canHide":false,"width":"wider"}],"version":"1.0.56"}
|
package/package.json
CHANGED
package/src/root.component.tsx
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
import React, { useMemo, useState } from 'react';
|
|
12
12
|
import { PrescriptionService, PrescriptionPayload } from './prescriptions.service';
|
|
13
|
+
import useSWR from 'swr';
|
|
14
|
+
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
13
15
|
import {
|
|
14
16
|
Checkbox,
|
|
15
17
|
ComboBox,
|
|
@@ -32,128 +34,245 @@ interface RootProps {
|
|
|
32
34
|
patient?: { uuid: string }; // Alguns workspaces passam assim
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
const Root: React.FC<RootProps> = (props) => {
|
|
36
|
-
console.log('Root props:', props); // 👈 ADICIONE para debug
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
// Hook para buscar ConceptDrugs do OpenMRS
|
|
41
|
+
function useConceptDrugs(query: string) {
|
|
42
|
+
const url = query ? `${restBaseUrl}/drug?q=${encodeURIComponent(query)}&v=custom:(uuid,name,display)` : null;
|
|
43
|
+
const swr = useSWR<any>(url, openmrsFetch);
|
|
44
|
+
return {
|
|
45
|
+
drugs: swr.data?.data?.results || [],
|
|
46
|
+
error: swr.error,
|
|
47
|
+
isLoading: swr.isValidating,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
// Tipo para dados do medicamento
|
|
53
|
+
type MedicationFormData = {
|
|
54
|
+
drugName: string;
|
|
55
|
+
dosage: string;
|
|
56
|
+
unit: string;
|
|
57
|
+
route: string;
|
|
58
|
+
frequency: string;
|
|
59
|
+
patientInstructions?: string;
|
|
60
|
+
asNeeded?: boolean;
|
|
61
|
+
asNeededCondition?: string;
|
|
62
|
+
startDate?: string;
|
|
63
|
+
duration?: string;
|
|
64
|
+
durationUnit?: string;
|
|
65
|
+
indication?: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const MOCK_UNITS = [
|
|
69
|
+
{ value: 'mg' },
|
|
70
|
+
{ value: 'ml' },
|
|
71
|
+
{ value: 'g' },
|
|
72
|
+
];
|
|
73
|
+
const MOCK_FREQUENCIES = [
|
|
74
|
+
{ value: '1x ao dia' },
|
|
75
|
+
{ value: '2x ao dia' },
|
|
76
|
+
{ value: '8/8h' },
|
|
77
|
+
{ value: '12/12h' },
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
type MedicationFormProps = {
|
|
81
|
+
initialData?: MedicationFormData;
|
|
82
|
+
onSubmit: (data: MedicationFormData) => void;
|
|
83
|
+
onCancel: () => void;
|
|
84
|
+
t: any;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const MedicationForm: React.FC<MedicationFormProps> = ({ initialData, onSubmit, onCancel, t }) => {
|
|
88
|
+
const [drugName, setDrugName] = useState(initialData?.drugName || '');
|
|
89
|
+
const [dosage, setDosage] = useState(initialData?.dosage || '');
|
|
90
|
+
const [unit, setUnit] = useState(initialData?.unit || '');
|
|
91
|
+
const [route, setRoute] = useState(initialData?.route || '');
|
|
92
|
+
const [frequency, setFrequency] = useState(initialData?.frequency || '');
|
|
93
|
+
const [patientInstructions, setPatientInstructions] = useState(initialData?.patientInstructions || '');
|
|
94
|
+
const [asNeeded, setAsNeeded] = useState(initialData?.asNeeded || false);
|
|
95
|
+
const [asNeededCondition, setAsNeededCondition] = useState(initialData?.asNeededCondition || '');
|
|
96
|
+
const [indication, setIndication] = useState(initialData?.indication || '');
|
|
97
|
+
|
|
98
|
+
// Busca ConceptDrugs conforme digitação
|
|
99
|
+
const { drugs, isLoading } = useConceptDrugs(drugName);
|
|
100
|
+
const drugOptions = drugs.map((d: any) => ({ value: d.name, uuid: d.uuid, display: d.display }));
|
|
101
|
+
|
|
102
|
+
const handleDrugInput = (input: string) => {
|
|
103
|
+
setDrugName(input);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
107
|
+
e.preventDefault();
|
|
108
|
+
if (!drugName || !dosage || !unit || !frequency) return;
|
|
109
|
+
onSubmit({
|
|
110
|
+
drugName,
|
|
111
|
+
dosage,
|
|
112
|
+
unit,
|
|
113
|
+
route,
|
|
114
|
+
frequency,
|
|
115
|
+
patientInstructions,
|
|
116
|
+
asNeeded,
|
|
117
|
+
asNeededCondition,
|
|
118
|
+
indication,
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
|
124
|
+
<ComboBox
|
|
125
|
+
id="drug-name"
|
|
126
|
+
items={drugOptions}
|
|
127
|
+
itemToString={(item) => item?.value || ''}
|
|
128
|
+
selectedItem={drugOptions.find((d: any) => d.value === drugName) || null}
|
|
129
|
+
onInputChange={handleDrugInput}
|
|
130
|
+
onChange={({ selectedItem }) => setDrugName(selectedItem?.value || '')}
|
|
131
|
+
placeholder={t('drugName', 'Nome do medicamento')}
|
|
132
|
+
titleText={t('drugName', 'Nome do medicamento')}
|
|
133
|
+
required
|
|
134
|
+
disabled={isLoading}
|
|
135
|
+
/>
|
|
136
|
+
<TextInput
|
|
137
|
+
id="dosage"
|
|
138
|
+
labelText={t('dosage', 'Dose')}
|
|
139
|
+
value={dosage}
|
|
140
|
+
onChange={(e) => setDosage(e.target.value)}
|
|
141
|
+
required
|
|
142
|
+
/>
|
|
143
|
+
<ComboBox
|
|
144
|
+
id="unit"
|
|
145
|
+
items={MOCK_UNITS}
|
|
146
|
+
itemToString={(item) => item?.value || ''}
|
|
147
|
+
selectedItem={MOCK_UNITS.find((u) => u.value === unit) || null}
|
|
148
|
+
onChange={({ selectedItem }) => setUnit(selectedItem?.value || '')}
|
|
149
|
+
placeholder={t('unit', 'Unidade')}
|
|
150
|
+
titleText={t('unit', 'Unidade')}
|
|
151
|
+
required
|
|
152
|
+
/>
|
|
153
|
+
<TextInput
|
|
154
|
+
id="route"
|
|
155
|
+
labelText={t('route', 'Via de administração')}
|
|
156
|
+
value={route}
|
|
157
|
+
onChange={(e) => setRoute(e.target.value)}
|
|
158
|
+
/>
|
|
159
|
+
<ComboBox
|
|
160
|
+
id="frequency"
|
|
161
|
+
items={MOCK_FREQUENCIES}
|
|
162
|
+
itemToString={(item) => item?.value || ''}
|
|
163
|
+
selectedItem={MOCK_FREQUENCIES.find((f) => f.value === frequency) || null}
|
|
164
|
+
onChange={({ selectedItem }) => setFrequency(selectedItem?.value || '')}
|
|
165
|
+
placeholder={t('frequency', 'Frequência')}
|
|
166
|
+
titleText={t('frequency', 'Frequência')}
|
|
167
|
+
required
|
|
168
|
+
/>
|
|
169
|
+
<TextInput
|
|
170
|
+
id="patient-instructions"
|
|
171
|
+
labelText={t('patientInstructions', 'Instruções ao paciente')}
|
|
172
|
+
value={patientInstructions}
|
|
173
|
+
onChange={(e) => setPatientInstructions(e.target.value)}
|
|
174
|
+
/>
|
|
175
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
176
|
+
<Checkbox
|
|
177
|
+
id="as-needed"
|
|
178
|
+
labelText={t('asNeeded', 'Tomar se necessário (P.R.N.)')}
|
|
179
|
+
checked={asNeeded}
|
|
180
|
+
onChange={() => setAsNeeded((prev) => !prev)}
|
|
181
|
+
/>
|
|
182
|
+
<TextInput
|
|
183
|
+
id="as-needed-condition"
|
|
184
|
+
labelText={t('asNeededCondition', 'Motivo P.R.N.')}
|
|
185
|
+
value={asNeededCondition}
|
|
186
|
+
onChange={(e) => setAsNeededCondition(e.target.value)}
|
|
187
|
+
disabled={!asNeeded}
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
<TextInput
|
|
191
|
+
id="indication"
|
|
192
|
+
labelText={t('indication', 'Indicação')}
|
|
193
|
+
value={indication}
|
|
194
|
+
onChange={(e) => setIndication(e.target.value)}
|
|
48
195
|
/>
|
|
49
|
-
|
|
50
|
-
|
|
196
|
+
<div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
|
|
197
|
+
<button type="submit" style={{ flex: 1 }}>
|
|
198
|
+
{t('saveMedication', 'Salvar medicamento')}
|
|
199
|
+
</button>
|
|
200
|
+
<button type="button" onClick={onCancel} style={{ flex: 1 }}>
|
|
201
|
+
{t('cancel', 'Cancelar')}
|
|
202
|
+
</button>
|
|
203
|
+
</div>
|
|
204
|
+
</form>
|
|
205
|
+
);
|
|
206
|
+
};
|
|
51
207
|
|
|
208
|
+
const Root: React.FC<RootProps> = ({ patientUuid, patient }) => {
|
|
209
|
+
const { t } = useTranslation();
|
|
52
210
|
const [activeTab, setActiveTab] = useState<'new' | 'past'>('new');
|
|
53
211
|
const [selectedLocation, setSelectedLocation] = useState<Location | null>(null);
|
|
54
212
|
const [policyNumber, setPolicyNumber] = useState('');
|
|
55
|
-
const [selectedOrders, setSelectedOrders] = useState<Set<string>>(new Set());
|
|
56
213
|
const [digitallySigned, setDigitallySigned] = useState(false);
|
|
57
214
|
const [printRequested, setPrintRequested] = useState(false);
|
|
58
215
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
59
|
-
const
|
|
60
|
-
const
|
|
216
|
+
const [medications, setMedications] = useState<MedicationFormData[]>([]);
|
|
217
|
+
const [showAddMedication, setShowAddMedication] = useState(false);
|
|
218
|
+
const [editIndex, setEditIndex] = useState<number | null>(null);
|
|
61
219
|
|
|
220
|
+
const locations = useLocations();
|
|
62
221
|
const locationItems = useMemo(() => locations ?? [], [locations]);
|
|
63
|
-
const selectedOrdersLabel =
|
|
64
|
-
selectedOrders.size > 0
|
|
65
|
-
? t('selectedOrdersCount', {
|
|
66
|
-
count: selectedOrders.size,
|
|
67
|
-
})
|
|
68
|
-
: null;
|
|
69
222
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
updated.delete(orderUuid);
|
|
75
|
-
} else {
|
|
76
|
-
updated.add(orderUuid);
|
|
77
|
-
}
|
|
78
|
-
return updated;
|
|
79
|
-
});
|
|
223
|
+
// Adiciona novo medicamento
|
|
224
|
+
const handleAddMedication = (med: MedicationFormData) => {
|
|
225
|
+
setMedications((prev) => [...prev, med]);
|
|
226
|
+
setShowAddMedication(false);
|
|
80
227
|
};
|
|
81
228
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return (
|
|
89
|
-
<InlineNotification
|
|
90
|
-
lowContrast
|
|
91
|
-
kind="error"
|
|
92
|
-
title={t('ordersErrorTitle', 'Unable to load orders')}
|
|
93
|
-
subtitle={t('ordersErrorSubtitle', 'Try again or refresh the patient chart.')}
|
|
94
|
-
/>
|
|
95
|
-
);
|
|
229
|
+
// Edita medicamento existente
|
|
230
|
+
const handleEditMedication = (med: MedicationFormData) => {
|
|
231
|
+
if (editIndex !== null) {
|
|
232
|
+
setMedications((prev) => prev.map((m, idx) => (idx === editIndex ? med : m)));
|
|
233
|
+
setEditIndex(null);
|
|
234
|
+
setShowAddMedication(false);
|
|
96
235
|
}
|
|
236
|
+
};
|
|
97
237
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
238
|
+
// Remove medicamento
|
|
239
|
+
const handleRemoveMedication = (idx: number) => {
|
|
240
|
+
setMedications((prev) => prev.filter((_, i) => i !== idx));
|
|
241
|
+
};
|
|
101
242
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
title={t('ordersEmptyState', 'There are no orders for this patient yet.')}
|
|
108
|
-
/>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
243
|
+
// Abre tela de adicionar
|
|
244
|
+
const openAddMedication = () => {
|
|
245
|
+
setEditIndex(null);
|
|
246
|
+
setShowAddMedication(true);
|
|
247
|
+
};
|
|
111
248
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<Checkbox
|
|
117
|
-
key={order.uuid}
|
|
118
|
-
id={`order-${order.uuid}`}
|
|
119
|
-
labelText={
|
|
120
|
-
<span className={styles.orderLabel}>
|
|
121
|
-
<span className={styles.orderName}>{order.conceptName}</span>
|
|
122
|
-
{order.display && <span className={styles.orderMeta}>{order.display}</span>}
|
|
123
|
-
{!order.display && order.orderNumber && <span className={styles.orderMeta}>{order.orderNumber}</span>}
|
|
124
|
-
</span>
|
|
125
|
-
}
|
|
126
|
-
checked={selectedOrders.has(order.uuid)}
|
|
127
|
-
onChange={() => toggleOrderSelection(order.uuid)}
|
|
128
|
-
/>
|
|
129
|
-
))}
|
|
130
|
-
</div>
|
|
131
|
-
{selectedOrdersLabel ? <p className={styles.selectionSummary}>{selectedOrdersLabel}</p> : null}
|
|
132
|
-
</>
|
|
133
|
-
);
|
|
249
|
+
// Abre tela de editar
|
|
250
|
+
const openEditMedication = (idx: number) => {
|
|
251
|
+
setEditIndex(idx);
|
|
252
|
+
setShowAddMedication(true);
|
|
134
253
|
};
|
|
135
254
|
|
|
136
255
|
return (
|
|
137
256
|
<div className={styles.workspace}>
|
|
138
257
|
<div className={styles.header}>
|
|
139
|
-
<h2>{t('activePrescriptionsWorkspaceTitle', '
|
|
258
|
+
<h2>{t('activePrescriptionsWorkspaceTitle', 'Prescrições ativas')}</h2>
|
|
140
259
|
<p className={styles.subtitle}>
|
|
141
260
|
{t(
|
|
142
261
|
'activePrescriptionsHelper',
|
|
143
|
-
'
|
|
262
|
+
'Revise o contexto do paciente, escolha os detalhes da visita e adicione os medicamentos à prescrição.'
|
|
144
263
|
)}
|
|
145
264
|
</p>
|
|
146
265
|
</div>
|
|
147
266
|
|
|
148
267
|
<section className={styles.section}>
|
|
149
|
-
<p className={styles.fieldLabel}>{t('visitTimingLabel', '
|
|
268
|
+
<p className={styles.fieldLabel}>{t('visitTimingLabel', 'A visita é')}</p>
|
|
150
269
|
<Tabs
|
|
151
270
|
selectedIndex={activeTab === 'new' ? 0 : 1}
|
|
152
271
|
onChange={({ selectedIndex }) => setActiveTab(selectedIndex === 0 ? 'new' : 'past')}
|
|
153
272
|
>
|
|
154
|
-
<TabList aria-label={t('visitTimingLabel', '
|
|
155
|
-
<Tab>{t('visitTimingNew', '
|
|
156
|
-
<Tab>{t('visitTimingPast', '
|
|
273
|
+
<TabList aria-label={t('visitTimingLabel', 'A visita é')}>
|
|
274
|
+
<Tab>{t('visitTimingNew', 'Nova')}</Tab>
|
|
275
|
+
<Tab>{t('visitTimingPast', 'No passado')}</Tab>
|
|
157
276
|
</TabList>
|
|
158
277
|
<TabPanels>
|
|
159
278
|
<TabPanel className={styles.tabContent}>
|
|
@@ -164,25 +283,17 @@ const Root: React.FC<RootProps> = (props) => {
|
|
|
164
283
|
itemToString={(item) => item?.display ?? ''}
|
|
165
284
|
selectedItem={selectedLocation}
|
|
166
285
|
onChange={({ selectedItem }) => setSelectedLocation((selectedItem as Location) ?? null)}
|
|
167
|
-
placeholder={t('visitLocationPlaceholder', '
|
|
168
|
-
titleText={t('visitLocationHeading', '
|
|
169
|
-
helperText={t('visitLocationHelper', '
|
|
286
|
+
placeholder={t('visitLocationPlaceholder', 'Selecione o local')}
|
|
287
|
+
titleText={t('visitLocationHeading', 'Local da visita')}
|
|
288
|
+
helperText={t('visitLocationHelper', 'Selecione onde a visita ocorrerá.')}
|
|
170
289
|
/>
|
|
171
290
|
</div>
|
|
172
291
|
|
|
173
|
-
<div className={styles.fieldGroup}>
|
|
174
|
-
<p className={styles.fieldLabel}>{t('visitTypeHeading', 'Visit type')}</p>
|
|
175
|
-
<p className={styles.helperText}>
|
|
176
|
-
{t('visitTypeHelper', 'Select the orders that should be included in this prescription.')}
|
|
177
|
-
</p>
|
|
178
|
-
{renderOrdersSection()}
|
|
179
|
-
</div>
|
|
180
|
-
|
|
181
292
|
<div className={styles.fieldGroup}>
|
|
182
293
|
<TextInput
|
|
183
294
|
id="insurance-policy"
|
|
184
|
-
labelText={t('insurancePolicyNumberLabel', '
|
|
185
|
-
placeholder={t('insurancePolicyNumberPlaceholder', '
|
|
295
|
+
labelText={t('insurancePolicyNumberLabel', 'Número da apólice (opcional)')}
|
|
296
|
+
placeholder={t('insurancePolicyNumberPlaceholder', 'Digite o número da apólice')}
|
|
186
297
|
value={policyNumber}
|
|
187
298
|
onChange={(event) => setPolicyNumber(event.target.value)}
|
|
188
299
|
/>
|
|
@@ -190,81 +301,65 @@ const Root: React.FC<RootProps> = (props) => {
|
|
|
190
301
|
<div className={styles.fieldGroup}>
|
|
191
302
|
<Checkbox
|
|
192
303
|
id="sign-prescription-checkbox"
|
|
193
|
-
labelText={t('signPrescriptionLabel', '
|
|
304
|
+
labelText={t('signPrescriptionLabel', 'Assinar digitalmente a prescrição')}
|
|
194
305
|
checked={digitallySigned}
|
|
195
306
|
onChange={() => setDigitallySigned((prev) => !prev)}
|
|
196
307
|
/>
|
|
197
308
|
<Checkbox
|
|
198
309
|
id="print-prescription-checkbox"
|
|
199
|
-
labelText={t('printPrescriptionLabel', '
|
|
310
|
+
labelText={t('printPrescriptionLabel', 'Imprimir a prescrição')}
|
|
200
311
|
checked={printRequested}
|
|
201
312
|
onChange={() => setPrintRequested((prev) => !prev)}
|
|
202
313
|
/>
|
|
203
314
|
</div>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
// TODO: obter dados reais do paciente e do médico
|
|
226
|
-
const payload: PrescriptionPayload = {
|
|
227
|
-
patient: {
|
|
228
|
-
uuid: patientUuid,
|
|
229
|
-
},
|
|
230
|
-
provider: {
|
|
231
|
-
uuid: 'provider-uuid', // Substituir pelo uuid real do médico
|
|
232
|
-
},
|
|
233
|
-
location: {
|
|
234
|
-
uuid: selectedLocation.uuid,
|
|
235
|
-
name: selectedLocation.display,
|
|
236
|
-
},
|
|
237
|
-
policyNumber,
|
|
238
|
-
orderUuids: Array.from(selectedOrders),
|
|
239
|
-
digitallySigned,
|
|
240
|
-
printRequested,
|
|
241
|
-
};
|
|
242
|
-
try {
|
|
243
|
-
await PrescriptionService.createPrescription(payload);
|
|
244
|
-
// Limpar formulário após sucesso
|
|
245
|
-
setSelectedLocation(null);
|
|
246
|
-
setPolicyNumber('');
|
|
247
|
-
setSelectedOrders(new Set());
|
|
248
|
-
setDigitallySigned(false);
|
|
249
|
-
setPrintRequested(false);
|
|
250
|
-
} catch (e) {
|
|
251
|
-
// TODO: tratar erro
|
|
252
|
-
} finally {
|
|
253
|
-
setIsSubmitting(false);
|
|
254
|
-
}
|
|
255
|
-
}}
|
|
256
|
-
disabled={isSubmitting}
|
|
257
|
-
>
|
|
258
|
-
{isSubmitting ? t('loading', 'Loading') : t('createPrescriptionButtonLabel', 'Create Prescription')}
|
|
315
|
+
|
|
316
|
+
{/* Lista de medicamentos adicionados */}
|
|
317
|
+
<div className={styles.fieldGroup}>
|
|
318
|
+
<h3>{t('medicationsList', 'Medicamentos adicionados')}</h3>
|
|
319
|
+
{medications.length === 0 ? (
|
|
320
|
+
<p>{t('noMedicationsAdded', 'Nenhum medicamento adicionado ainda.')}</p>
|
|
321
|
+
) : (
|
|
322
|
+
<ul className={styles.medicationsList}>
|
|
323
|
+
{medications.map((med, idx) => (
|
|
324
|
+
<li key={idx} className={styles.medicationItem}>
|
|
325
|
+
<span>
|
|
326
|
+
<b>{med.drugName}</b> - {med.dosage} {med.unit} - {med.frequency}
|
|
327
|
+
</span>
|
|
328
|
+
<button type="button" onClick={() => openEditMedication(idx)}>{t('edit', 'Editar')}</button>
|
|
329
|
+
<button type="button" onClick={() => handleRemoveMedication(idx)}>{t('remove', 'Remover')}</button>
|
|
330
|
+
</li>
|
|
331
|
+
))}
|
|
332
|
+
</ul>
|
|
333
|
+
)}
|
|
334
|
+
<button type="button" onClick={openAddMedication} className={styles.addMedicationBtn}>
|
|
335
|
+
{t('addMedication', '+ Adicionar medicamento')}
|
|
259
336
|
</button>
|
|
260
337
|
</div>
|
|
338
|
+
|
|
339
|
+
{/* Tela sobreposta para adicionar/editar medicamento */}
|
|
340
|
+
{showAddMedication && (
|
|
341
|
+
<div className={styles.overlayForm}>
|
|
342
|
+
<div className={styles.overlayContent}>
|
|
343
|
+
<h3>{editIndex === null ? t('addMedication', 'Adicionar medicamento') : t('editMedication', 'Editar medicamento')}</h3>
|
|
344
|
+
<MedicationForm
|
|
345
|
+
initialData={editIndex !== null ? medications[editIndex] : undefined}
|
|
346
|
+
onSubmit={editIndex === null ? handleAddMedication : handleEditMedication}
|
|
347
|
+
onCancel={() => {
|
|
348
|
+
setShowAddMedication(false);
|
|
349
|
+
setEditIndex(null);
|
|
350
|
+
}}
|
|
351
|
+
t={t}
|
|
352
|
+
/>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
)}
|
|
261
356
|
</TabPanel>
|
|
262
357
|
<TabPanel className={styles.tabContent}>
|
|
263
358
|
<InlineNotification
|
|
264
359
|
lowContrast
|
|
265
360
|
kind="info"
|
|
266
|
-
title={t('inPastTabPlaceholderTitle', '
|
|
267
|
-
subtitle={t('inPastTabPlaceholderSubtitle', '
|
|
361
|
+
title={t('inPastTabPlaceholderTitle', 'Receitas históricas em breve')}
|
|
362
|
+
subtitle={t('inPastTabPlaceholderSubtitle', 'Volte para Nova para gerenciar medicamentos atuais.')}
|
|
268
363
|
/>
|
|
269
364
|
</TabPanel>
|
|
270
365
|
</TabPanels>
|