@terreno/ui 0.7.2 → 0.8.0
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/BooleanField.js +23 -23
- package/dist/BooleanField.js.map +1 -1
- package/dist/ConsentFormScreen.d.ts +14 -0
- package/dist/ConsentFormScreen.js +93 -0
- package/dist/ConsentFormScreen.js.map +1 -0
- package/dist/ConsentHistory.d.ts +8 -0
- package/dist/ConsentHistory.js +70 -0
- package/dist/ConsentHistory.js.map +1 -0
- package/dist/ConsentNavigator.d.ts +9 -0
- package/dist/ConsentNavigator.js +72 -0
- package/dist/ConsentNavigator.js.map +1 -0
- package/dist/DataTable.js +1 -1
- package/dist/DataTable.js.map +1 -1
- package/dist/DateTimeActionSheet.js +22 -6
- package/dist/DateTimeActionSheet.js.map +1 -1
- package/dist/DateTimeField.d.ts +22 -0
- package/dist/DateTimeField.js +187 -67
- package/dist/DateTimeField.js.map +1 -1
- package/dist/DraggableList.d.ts +66 -0
- package/dist/DraggableList.js +241 -0
- package/dist/DraggableList.js.map +1 -0
- package/dist/Link.js +1 -1
- package/dist/Link.js.map +1 -1
- package/dist/MarkdownEditor.d.ts +12 -0
- package/dist/MarkdownEditor.js +12 -0
- package/dist/MarkdownEditor.js.map +1 -0
- package/dist/MarkdownEditorField.d.ts +1 -0
- package/dist/MarkdownEditorField.js +16 -16
- package/dist/MarkdownEditorField.js.map +1 -1
- package/dist/Modal.js +11 -1
- package/dist/Modal.js.map +1 -1
- package/dist/PickerSelect.js +10 -0
- package/dist/PickerSelect.js.map +1 -1
- package/dist/TerrenoProvider.js +10 -1
- package/dist/TerrenoProvider.js.map +1 -1
- package/dist/UpgradeRequiredScreen.d.ts +8 -0
- package/dist/UpgradeRequiredScreen.js +10 -0
- package/dist/UpgradeRequiredScreen.js.map +1 -0
- package/dist/generateConsentHistoryPdf.d.ts +2 -0
- package/dist/generateConsentHistoryPdf.js +185 -0
- package/dist/generateConsentHistoryPdf.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/useConsentForms.d.ts +29 -0
- package/dist/useConsentForms.js +50 -0
- package/dist/useConsentForms.js.map +1 -0
- package/dist/useConsentHistory.d.ts +31 -0
- package/dist/useConsentHistory.js +17 -0
- package/dist/useConsentHistory.js.map +1 -0
- package/dist/useSubmitConsent.d.ts +12 -0
- package/dist/useSubmitConsent.js +23 -0
- package/dist/useSubmitConsent.js.map +1 -0
- package/package.json +4 -2
- package/src/BooleanField.test.tsx +3 -5
- package/src/BooleanField.tsx +33 -31
- package/src/ConsentFormScreen.tsx +216 -0
- package/src/ConsentHistory.tsx +249 -0
- package/src/ConsentNavigator.test.tsx +111 -0
- package/src/ConsentNavigator.tsx +128 -0
- package/src/DataTable.tsx +1 -1
- package/src/DateTimeActionSheet.tsx +19 -6
- package/src/DateTimeField.tsx +416 -133
- package/src/DraggableList.tsx +424 -0
- package/src/Link.tsx +1 -1
- package/src/MarkdownEditor.tsx +66 -0
- package/src/MarkdownEditorField.tsx +32 -28
- package/src/Modal.tsx +19 -1
- package/src/PickerSelect.tsx +11 -0
- package/src/TerrenoProvider.tsx +10 -1
- package/src/TimezonePicker.test.tsx +9 -1
- package/src/UpgradeRequiredScreen.tsx +52 -0
- package/src/__snapshots__/BooleanField.test.tsx.snap +167 -203
- package/src/__snapshots__/DataTable.test.tsx.snap +0 -114
- package/src/__snapshots__/Field.test.tsx.snap +53 -69
- package/src/__snapshots__/Link.test.tsx.snap +14 -21
- package/src/__snapshots__/TimezonePicker.test.tsx.snap +0 -4710
- package/src/generateConsentHistoryPdf.ts +211 -0
- package/src/index.tsx +9 -1
- package/src/useConsentForms.ts +70 -0
- package/src/useConsentHistory.ts +40 -0
- package/src/useSubmitConsent.ts +35 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {jsPDF} from "jspdf";
|
|
2
|
+
import {DateTime} from "luxon";
|
|
3
|
+
|
|
4
|
+
import type {ConsentHistoryEntry} from "./useConsentHistory";
|
|
5
|
+
|
|
6
|
+
const PAGE_WIDTH = 210;
|
|
7
|
+
const MARGIN_LEFT = 20;
|
|
8
|
+
const MARGIN_RIGHT = 20;
|
|
9
|
+
const CONTENT_WIDTH = PAGE_WIDTH - MARGIN_LEFT - MARGIN_RIGHT;
|
|
10
|
+
const PAGE_HEIGHT = 297;
|
|
11
|
+
const MARGIN_BOTTOM = 20;
|
|
12
|
+
|
|
13
|
+
const formatDate = (value: unknown): string => {
|
|
14
|
+
if (!value) {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
const dt = DateTime.fromISO(String(value));
|
|
18
|
+
if (!dt.isValid) {
|
|
19
|
+
return String(value);
|
|
20
|
+
}
|
|
21
|
+
return dt.toLocaleString(DateTime.DATETIME_FULL);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const ensureSpace = (doc: jsPDF, y: number, needed: number): number => {
|
|
25
|
+
if (y + needed > PAGE_HEIGHT - MARGIN_BOTTOM) {
|
|
26
|
+
doc.addPage();
|
|
27
|
+
return 20;
|
|
28
|
+
}
|
|
29
|
+
return y;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const generateConsentHistoryPdf = async (entry: ConsentHistoryEntry): Promise<void> => {
|
|
33
|
+
const doc = new jsPDF({format: "a4", orientation: "portrait", unit: "mm"});
|
|
34
|
+
|
|
35
|
+
const formTitle = entry.form?.title ?? "Unknown Form";
|
|
36
|
+
const formSlug = entry.form?.slug ?? "";
|
|
37
|
+
const formType = entry.form?.type ?? "";
|
|
38
|
+
const formVersion = entry.form?.version ?? entry.formVersionSnapshot;
|
|
39
|
+
|
|
40
|
+
let y = 20;
|
|
41
|
+
|
|
42
|
+
// Title
|
|
43
|
+
doc.setFontSize(18);
|
|
44
|
+
doc.setFont("helvetica", "bold");
|
|
45
|
+
doc.text("Consent Record", MARGIN_LEFT, y);
|
|
46
|
+
y += 10;
|
|
47
|
+
|
|
48
|
+
// Form title
|
|
49
|
+
doc.setFontSize(14);
|
|
50
|
+
doc.setFont("helvetica", "normal");
|
|
51
|
+
doc.text(formTitle, MARGIN_LEFT, y);
|
|
52
|
+
y += 10;
|
|
53
|
+
|
|
54
|
+
// Separator
|
|
55
|
+
doc.setDrawColor(200, 200, 200);
|
|
56
|
+
doc.line(MARGIN_LEFT, y, PAGE_WIDTH - MARGIN_RIGHT, y);
|
|
57
|
+
y += 8;
|
|
58
|
+
|
|
59
|
+
// Helper to add a labeled field
|
|
60
|
+
const addField = (label: string, value: string) => {
|
|
61
|
+
y = ensureSpace(doc, y, 8);
|
|
62
|
+
doc.setFontSize(9);
|
|
63
|
+
doc.setFont("helvetica", "bold");
|
|
64
|
+
doc.setTextColor(100, 100, 100);
|
|
65
|
+
doc.text(label, MARGIN_LEFT, y);
|
|
66
|
+
doc.setFont("helvetica", "normal");
|
|
67
|
+
doc.setTextColor(0, 0, 0);
|
|
68
|
+
doc.setFontSize(10);
|
|
69
|
+
doc.text(value, MARGIN_LEFT + 45, y);
|
|
70
|
+
y += 6;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Response Details
|
|
74
|
+
doc.setFontSize(12);
|
|
75
|
+
doc.setFont("helvetica", "bold");
|
|
76
|
+
doc.setTextColor(0, 0, 0);
|
|
77
|
+
doc.text("Response Details", MARGIN_LEFT, y);
|
|
78
|
+
y += 8;
|
|
79
|
+
|
|
80
|
+
if (formSlug) {
|
|
81
|
+
addField("Form Slug:", formSlug);
|
|
82
|
+
}
|
|
83
|
+
if (formType) {
|
|
84
|
+
addField("Form Type:", formType);
|
|
85
|
+
}
|
|
86
|
+
if (formVersion !== undefined) {
|
|
87
|
+
addField("Form Version:", String(formVersion));
|
|
88
|
+
}
|
|
89
|
+
addField("Decision:", entry.agreed ? "Agreed" : "Declined");
|
|
90
|
+
if (entry.agreedAt) {
|
|
91
|
+
addField("Agreed At:", formatDate(entry.agreedAt));
|
|
92
|
+
}
|
|
93
|
+
if (entry.locale) {
|
|
94
|
+
addField("Locale:", entry.locale);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
y += 4;
|
|
98
|
+
|
|
99
|
+
// Checkbox Values
|
|
100
|
+
const checkboxEntries =
|
|
101
|
+
entry.checkboxValues && typeof entry.checkboxValues === "object"
|
|
102
|
+
? Object.entries(entry.checkboxValues)
|
|
103
|
+
: [];
|
|
104
|
+
|
|
105
|
+
if (checkboxEntries.length > 0) {
|
|
106
|
+
y = ensureSpace(doc, y, 12 + checkboxEntries.length * 6);
|
|
107
|
+
doc.setFontSize(12);
|
|
108
|
+
doc.setFont("helvetica", "bold");
|
|
109
|
+
doc.setTextColor(0, 0, 0);
|
|
110
|
+
doc.text("Checkbox Responses", MARGIN_LEFT, y);
|
|
111
|
+
y += 8;
|
|
112
|
+
|
|
113
|
+
for (const [index, checked] of checkboxEntries) {
|
|
114
|
+
y = ensureSpace(doc, y, 6);
|
|
115
|
+
doc.setFontSize(10);
|
|
116
|
+
doc.setFont("helvetica", "normal");
|
|
117
|
+
const label = entry.form?.checkboxes?.[Number(index)]?.label;
|
|
118
|
+
const checkmark = checked ? "[x]" : "[ ]";
|
|
119
|
+
doc.text(`${checkmark} ${label ?? `Checkbox ${index}`}`, MARGIN_LEFT + 4, y);
|
|
120
|
+
y += 6;
|
|
121
|
+
}
|
|
122
|
+
y += 4;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Audit Trail
|
|
126
|
+
const hasAuditTrail = entry.ipAddress || entry.userAgent || entry.formVersionSnapshot;
|
|
127
|
+
|
|
128
|
+
if (hasAuditTrail) {
|
|
129
|
+
y = ensureSpace(doc, y, 20);
|
|
130
|
+
doc.setFontSize(12);
|
|
131
|
+
doc.setFont("helvetica", "bold");
|
|
132
|
+
doc.setTextColor(0, 0, 0);
|
|
133
|
+
doc.text("Audit Trail", MARGIN_LEFT, y);
|
|
134
|
+
y += 8;
|
|
135
|
+
|
|
136
|
+
if (entry.ipAddress) {
|
|
137
|
+
addField("IP Address:", entry.ipAddress);
|
|
138
|
+
}
|
|
139
|
+
if (entry.userAgent) {
|
|
140
|
+
addField("User Agent:", entry.userAgent);
|
|
141
|
+
}
|
|
142
|
+
if (entry.formVersionSnapshot !== undefined) {
|
|
143
|
+
addField("Form Version:", String(entry.formVersionSnapshot));
|
|
144
|
+
}
|
|
145
|
+
if (entry.signedAt) {
|
|
146
|
+
addField("Signed At:", formatDate(entry.signedAt));
|
|
147
|
+
}
|
|
148
|
+
y += 4;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Signature
|
|
152
|
+
if (entry.signature) {
|
|
153
|
+
y = ensureSpace(doc, y, 50);
|
|
154
|
+
doc.setFontSize(12);
|
|
155
|
+
doc.setFont("helvetica", "bold");
|
|
156
|
+
doc.setTextColor(0, 0, 0);
|
|
157
|
+
doc.text("Signature", MARGIN_LEFT, y);
|
|
158
|
+
y += 6;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const format = entry.signature.includes("image/png") ? "PNG" : "JPEG";
|
|
162
|
+
doc.addImage(entry.signature, format, MARGIN_LEFT, y, 80, 30);
|
|
163
|
+
y += 34;
|
|
164
|
+
} catch {
|
|
165
|
+
doc.setFontSize(10);
|
|
166
|
+
doc.setFont("helvetica", "italic");
|
|
167
|
+
doc.text("(Signature image could not be embedded)", MARGIN_LEFT, y);
|
|
168
|
+
y += 6;
|
|
169
|
+
}
|
|
170
|
+
y += 4;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Content Snapshot
|
|
174
|
+
if (entry.contentSnapshot) {
|
|
175
|
+
y = ensureSpace(doc, y, 20);
|
|
176
|
+
doc.setFontSize(12);
|
|
177
|
+
doc.setFont("helvetica", "bold");
|
|
178
|
+
doc.setTextColor(0, 0, 0);
|
|
179
|
+
doc.text("Content Snapshot", MARGIN_LEFT, y);
|
|
180
|
+
y += 8;
|
|
181
|
+
|
|
182
|
+
doc.setFontSize(9);
|
|
183
|
+
doc.setFont("helvetica", "normal");
|
|
184
|
+
doc.setTextColor(50, 50, 50);
|
|
185
|
+
|
|
186
|
+
const lines = doc.splitTextToSize(entry.contentSnapshot, CONTENT_WIDTH);
|
|
187
|
+
for (const line of lines) {
|
|
188
|
+
y = ensureSpace(doc, y, 5);
|
|
189
|
+
doc.text(line, MARGIN_LEFT, y);
|
|
190
|
+
y += 4;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Footer
|
|
195
|
+
y = ensureSpace(doc, y, 20);
|
|
196
|
+
y += 8;
|
|
197
|
+
doc.setDrawColor(200, 200, 200);
|
|
198
|
+
doc.line(MARGIN_LEFT, y, PAGE_WIDTH - MARGIN_RIGHT, y);
|
|
199
|
+
y += 6;
|
|
200
|
+
doc.setFontSize(8);
|
|
201
|
+
doc.setFont("helvetica", "italic");
|
|
202
|
+
doc.setTextColor(150, 150, 150);
|
|
203
|
+
doc.text(`Generated ${DateTime.now().toLocaleString(DateTime.DATETIME_FULL)}`, MARGIN_LEFT, y);
|
|
204
|
+
if (entry._id) {
|
|
205
|
+
doc.text(`Response ID: ${entry._id}`, PAGE_WIDTH - MARGIN_RIGHT, y, {align: "right"});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Download
|
|
209
|
+
const filename = `consent-${formSlug || "response"}-${DateTime.now().toFormat("yyyy-MM-dd")}.pdf`;
|
|
210
|
+
doc.save(filename);
|
|
211
|
+
};
|
package/src/index.tsx
CHANGED
|
@@ -16,6 +16,9 @@ export * from "./Button";
|
|
|
16
16
|
export * from "./Card";
|
|
17
17
|
export * from "./CheckBox";
|
|
18
18
|
export * from "./Common";
|
|
19
|
+
export * from "./ConsentFormScreen";
|
|
20
|
+
export * from "./ConsentHistory";
|
|
21
|
+
export * from "./ConsentNavigator";
|
|
19
22
|
export * from "./Constants";
|
|
20
23
|
export * from "./CustomSelectField";
|
|
21
24
|
export * from "./DataTable";
|
|
@@ -24,6 +27,7 @@ export * from "./DateTimeField";
|
|
|
24
27
|
export * from "./DateUtilities";
|
|
25
28
|
export * from "./DecimalRangeActionSheet";
|
|
26
29
|
export * from "./DismissButton";
|
|
30
|
+
export {DraggableList} from "./DraggableList";
|
|
27
31
|
export * from "./EmailField";
|
|
28
32
|
export {default as EmojiSelector} from "./EmojiSelector";
|
|
29
33
|
export * from "./ErrorBoundary";
|
|
@@ -44,7 +48,7 @@ export * from "./InfoModalIcon";
|
|
|
44
48
|
export * from "./InfoTooltipButton";
|
|
45
49
|
export * from "./Link";
|
|
46
50
|
export * from "./login";
|
|
47
|
-
|
|
51
|
+
export * from "./MarkdownEditor";
|
|
48
52
|
export * from "./MarkdownEditorField";
|
|
49
53
|
export * from "./MarkdownView";
|
|
50
54
|
export * from "./MediaQuery";
|
|
@@ -97,9 +101,13 @@ export * from "./table/TableTitle";
|
|
|
97
101
|
export * from "./table/tableContext";
|
|
98
102
|
export * from "./UnifiedAddressAutoComplete";
|
|
99
103
|
export * from "./Unifier";
|
|
104
|
+
export * from "./UpgradeRequiredScreen";
|
|
100
105
|
export * from "./UserInactivity";
|
|
101
106
|
export * from "./Utilities";
|
|
107
|
+
export * from "./useConsentForms";
|
|
108
|
+
export * from "./useConsentHistory";
|
|
102
109
|
export * from "./useStoredState";
|
|
110
|
+
export * from "./useSubmitConsent";
|
|
103
111
|
export * from "./WebAddressAutocomplete";
|
|
104
112
|
|
|
105
113
|
// export * from "./Layout";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export interface ConsentFormPublic {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
version: number;
|
|
6
|
+
order: number;
|
|
7
|
+
type: string;
|
|
8
|
+
content: Record<string, string>;
|
|
9
|
+
defaultLocale: string;
|
|
10
|
+
active: boolean;
|
|
11
|
+
captureSignature: boolean;
|
|
12
|
+
requireScrollToBottom: boolean;
|
|
13
|
+
checkboxes: Array<{label: string; required: boolean; confirmationPrompt?: string}>;
|
|
14
|
+
agreeButtonText: string;
|
|
15
|
+
allowDecline: boolean;
|
|
16
|
+
declineButtonText: string;
|
|
17
|
+
required: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
import {getLocales} from "expo-localization";
|
|
21
|
+
|
|
22
|
+
export const detectLocale = (): string => {
|
|
23
|
+
// Web
|
|
24
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
25
|
+
return navigator.language;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Native — expo-localization
|
|
29
|
+
try {
|
|
30
|
+
const locale = getLocales()[0]?.languageTag;
|
|
31
|
+
if (locale) {
|
|
32
|
+
return locale;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// expo-localization not available in this environment
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return "en";
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const useConsentForms = (api: any, baseUrl?: string) => {
|
|
42
|
+
const base = baseUrl || "";
|
|
43
|
+
const apiWithConsentTags = api.enhanceEndpoints({addTagTypes: ["PendingConsents"]});
|
|
44
|
+
|
|
45
|
+
const enhancedApi = apiWithConsentTags.injectEndpoints({
|
|
46
|
+
endpoints: (build: any) => ({
|
|
47
|
+
getPendingConsents: build.query({
|
|
48
|
+
async onQueryStarted(_arg: unknown, {queryFulfilled}: {queryFulfilled: Promise<unknown>}) {
|
|
49
|
+
console.info("[useConsentForms] Fetching pending consent forms");
|
|
50
|
+
try {
|
|
51
|
+
const result = (await queryFulfilled) as {data?: ConsentFormPublic[]};
|
|
52
|
+
console.info("[useConsentForms] Pending consent forms fetched", {
|
|
53
|
+
count: result?.data?.length ?? 0,
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.warn("[useConsentForms] Failed to fetch pending consent forms", {error});
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
providesTags: ["PendingConsents"],
|
|
60
|
+
query: () => `${base}/consents/pending`,
|
|
61
|
+
}),
|
|
62
|
+
}),
|
|
63
|
+
overrideExisting: false,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const {data, isLoading, error, refetch} = enhancedApi.useGetPendingConsentsQuery();
|
|
67
|
+
const forms: ConsentFormPublic[] = Array.isArray(data) ? data : (data?.data ?? []);
|
|
68
|
+
|
|
69
|
+
return {error, forms, isLoading, refetch};
|
|
70
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface ConsentHistoryEntry {
|
|
2
|
+
_id: string;
|
|
3
|
+
agreed: boolean;
|
|
4
|
+
agreedAt: string;
|
|
5
|
+
checkboxValues?: Record<string, boolean>;
|
|
6
|
+
contentSnapshot?: string;
|
|
7
|
+
form: {
|
|
8
|
+
captureSignature: boolean;
|
|
9
|
+
checkboxes: Array<{label: string; required: boolean; confirmationPrompt?: string}>;
|
|
10
|
+
slug: string;
|
|
11
|
+
title: string;
|
|
12
|
+
type: string;
|
|
13
|
+
version: number;
|
|
14
|
+
} | null;
|
|
15
|
+
formVersionSnapshot?: number;
|
|
16
|
+
ipAddress?: string;
|
|
17
|
+
locale?: string;
|
|
18
|
+
signature?: string;
|
|
19
|
+
signedAt?: string;
|
|
20
|
+
userAgent?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const useConsentHistory = (api: any, baseUrl?: string) => {
|
|
24
|
+
const base = baseUrl || "";
|
|
25
|
+
|
|
26
|
+
const enhancedApi = api.injectEndpoints({
|
|
27
|
+
endpoints: (build: any) => ({
|
|
28
|
+
getMyConsents: build.query({
|
|
29
|
+
providesTags: ["MyConsents"],
|
|
30
|
+
query: () => `${base}/consents/my`,
|
|
31
|
+
}),
|
|
32
|
+
}),
|
|
33
|
+
overrideExisting: false,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const {data, isLoading, error, refetch} = enhancedApi.useGetMyConsentsQuery();
|
|
37
|
+
const entries: ConsentHistoryEntry[] = Array.isArray(data) ? data : (data?.data ?? []);
|
|
38
|
+
|
|
39
|
+
return {entries, error, isLoading, refetch};
|
|
40
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface SubmitConsentBody {
|
|
2
|
+
agreed: boolean;
|
|
3
|
+
checkboxValues?: Record<string, boolean>;
|
|
4
|
+
consentFormId: string;
|
|
5
|
+
locale: string;
|
|
6
|
+
signature?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const useSubmitConsent = (api: any, baseUrl?: string) => {
|
|
10
|
+
const base = baseUrl || "";
|
|
11
|
+
const apiWithConsentTags = api.enhanceEndpoints({addTagTypes: ["PendingConsents"]});
|
|
12
|
+
|
|
13
|
+
const enhancedApi = apiWithConsentTags.injectEndpoints({
|
|
14
|
+
endpoints: (build: any) => ({
|
|
15
|
+
submitConsentResponse: build.mutation({
|
|
16
|
+
invalidatesTags: ["PendingConsents"],
|
|
17
|
+
query: (body: SubmitConsentBody) => ({
|
|
18
|
+
body,
|
|
19
|
+
method: "POST",
|
|
20
|
+
url: `${base}/consents/respond`,
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
}),
|
|
24
|
+
overrideExisting: false,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const [submitMutation, {isLoading: isSubmitting, error}] =
|
|
28
|
+
enhancedApi.useSubmitConsentResponseMutation();
|
|
29
|
+
|
|
30
|
+
const submit = async (body: SubmitConsentBody) => {
|
|
31
|
+
return submitMutation(body).unwrap();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {error, isSubmitting, submit};
|
|
35
|
+
};
|