@7365admin1/layer-common 3.0.3 → 3.0.6
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/CHANGELOG.md +20 -0
- package/components/InvitationForm.vue +6 -2
- package/components/InvitationMain.vue +1 -0
- package/components/OnlineFormConfigurationForm.vue +141 -239
- package/components/OnlineFormFill.vue +456 -0
- package/components/OnlineFormsConfiguration.vue +81 -126
- package/components/RolePermissionFormCreate.vue +5 -1
- package/components/SignaturePad.vue +132 -61
- package/composables/useMember.ts +13 -1
- package/composables/useOnlineFormPages.ts +642 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
3
|
<v-col cols="12" class="mb-2">
|
|
4
|
-
<v-row no-gutters>
|
|
4
|
+
<v-row no-gutters style="gap: 8px">
|
|
5
5
|
<v-btn
|
|
6
6
|
class="text-none"
|
|
7
7
|
rounded="pill"
|
|
@@ -32,6 +32,16 @@
|
|
|
32
32
|
>
|
|
33
33
|
<v-icon>mdi-refresh</v-icon>
|
|
34
34
|
</v-btn>
|
|
35
|
+
<v-btn
|
|
36
|
+
fab
|
|
37
|
+
icon
|
|
38
|
+
density="comfortable"
|
|
39
|
+
:color="sortAlpha ? 'primary' : undefined"
|
|
40
|
+
:title="sortAlpha ? 'Sorted A–Z' : 'Sort A–Z'"
|
|
41
|
+
@click="sortAlpha = !sortAlpha"
|
|
42
|
+
>
|
|
43
|
+
<v-icon>mdi-sort-alphabetical-ascending</v-icon>
|
|
44
|
+
</v-btn>
|
|
35
45
|
<v-text-field
|
|
36
46
|
v-model="search"
|
|
37
47
|
density="compact"
|
|
@@ -59,7 +69,7 @@
|
|
|
59
69
|
</v-toolbar>
|
|
60
70
|
<v-data-table
|
|
61
71
|
:headers="headers"
|
|
62
|
-
:items="
|
|
72
|
+
:items="sortedItems"
|
|
63
73
|
item-value="_id"
|
|
64
74
|
items-per-page="10"
|
|
65
75
|
fixed-header
|
|
@@ -97,118 +107,55 @@
|
|
|
97
107
|
</v-dialog>
|
|
98
108
|
|
|
99
109
|
<!-- Preview Dialog -->
|
|
100
|
-
<v-dialog v-model="previewDialog" width="
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
class="me-1 mb-2"
|
|
133
|
-
>
|
|
134
|
-
{{ input.label }}
|
|
135
|
-
</v-chip>
|
|
136
|
-
</div>
|
|
137
|
-
</v-col>
|
|
138
|
-
</v-row>
|
|
139
|
-
</v-card-text>
|
|
140
|
-
<v-toolbar class="pa-0" density="compact">
|
|
141
|
-
<v-row no-gutters>
|
|
142
|
-
<v-col cols="6" class="pa-0">
|
|
143
|
-
<v-btn
|
|
144
|
-
block
|
|
145
|
-
variant="text"
|
|
146
|
-
class="text-none"
|
|
147
|
-
size="large"
|
|
148
|
-
@click="previewDialog = false"
|
|
149
|
-
height="48"
|
|
150
|
-
>
|
|
151
|
-
Close
|
|
152
|
-
</v-btn>
|
|
153
|
-
</v-col>
|
|
154
|
-
<v-col cols="6" class="pa-0" v-if="canUpdate">
|
|
155
|
-
<v-menu>
|
|
156
|
-
<template #activator="{ props }">
|
|
157
|
-
<v-btn
|
|
158
|
-
block
|
|
159
|
-
variant="flat"
|
|
160
|
-
color="black"
|
|
161
|
-
class="text-none"
|
|
162
|
-
height="48"
|
|
163
|
-
v-bind="props"
|
|
164
|
-
tile
|
|
165
|
-
:disabled="
|
|
166
|
-
!canUpdateOnlineFormConfiguration &&
|
|
167
|
-
!canDeleteOnlineFormConfiguration
|
|
168
|
-
"
|
|
169
|
-
>
|
|
170
|
-
More actions
|
|
171
|
-
</v-btn>
|
|
172
|
-
</template>
|
|
173
|
-
<v-list class="pa-0">
|
|
174
|
-
<v-list-item @click="previewDialog = false; formRenderPreviewDialog = true">
|
|
175
|
-
<v-list-item-title class="text-subtitle-2">
|
|
176
|
-
Preview
|
|
177
|
-
</v-list-item-title>
|
|
178
|
-
</v-list-item>
|
|
179
|
-
|
|
180
|
-
<v-list-item
|
|
181
|
-
v-if="canUpdateOnlineFormConfiguration"
|
|
182
|
-
@click="openEditDialog()"
|
|
183
|
-
>
|
|
184
|
-
<v-list-item-title class="text-subtitle-2">
|
|
185
|
-
Edit
|
|
186
|
-
</v-list-item-title>
|
|
187
|
-
</v-list-item>
|
|
110
|
+
<v-dialog v-model="previewDialog" width="600" persistent scrollable>
|
|
111
|
+
<OnlineFormFill
|
|
112
|
+
v-if="selectedFormDefinition"
|
|
113
|
+
:definition="selectedFormDefinition"
|
|
114
|
+
:site-id="siteId"
|
|
115
|
+
:org-id="orgId"
|
|
116
|
+
readonly
|
|
117
|
+
@cancel="previewDialog = false"
|
|
118
|
+
>
|
|
119
|
+
<template #title-actions>
|
|
120
|
+
<v-btn
|
|
121
|
+
v-if="canUpdate && canUpdateOnlineFormConfiguration"
|
|
122
|
+
icon
|
|
123
|
+
size="small"
|
|
124
|
+
variant="text"
|
|
125
|
+
color="white"
|
|
126
|
+
@click="openEditDialog()"
|
|
127
|
+
>
|
|
128
|
+
<v-icon>mdi-pencil</v-icon>
|
|
129
|
+
</v-btn>
|
|
130
|
+
<v-btn
|
|
131
|
+
v-if="canDelete && canDeleteOnlineFormConfiguration"
|
|
132
|
+
icon
|
|
133
|
+
size="small"
|
|
134
|
+
variant="text"
|
|
135
|
+
color="error"
|
|
136
|
+
@click="openDeleteDialog()"
|
|
137
|
+
>
|
|
138
|
+
<v-icon>mdi-delete</v-icon>
|
|
139
|
+
</v-btn>
|
|
140
|
+
</template>
|
|
141
|
+
</OnlineFormFill>
|
|
188
142
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
</v-row>
|
|
143
|
+
<!-- Fallback: no block definition found for this form type -->
|
|
144
|
+
<v-card v-else width="100%">
|
|
145
|
+
<v-card-text class="text-center pa-10">
|
|
146
|
+
<v-icon size="48" class="mb-3 text-medium-emphasis">mdi-file-question-outline</v-icon>
|
|
147
|
+
<div class="text-body-2 text-medium-emphasis">
|
|
148
|
+
No preview available for "{{ selectedFormType }}".
|
|
149
|
+
</div>
|
|
150
|
+
</v-card-text>
|
|
151
|
+
<v-toolbar density="compact">
|
|
152
|
+
<v-btn tile block variant="text" class="text-none" size="48" @click="previewDialog = false">
|
|
153
|
+
Close
|
|
154
|
+
</v-btn>
|
|
202
155
|
</v-toolbar>
|
|
203
156
|
</v-card>
|
|
204
157
|
</v-dialog>
|
|
205
158
|
|
|
206
|
-
<!-- Form Render Preview Dialog -->
|
|
207
|
-
<OnlineFormRenderPreview
|
|
208
|
-
v-model="formRenderPreviewDialog"
|
|
209
|
-
:form="selectedOnlineForm"
|
|
210
|
-
/>
|
|
211
|
-
|
|
212
159
|
<!-- Delete Dialog -->
|
|
213
160
|
<v-dialog
|
|
214
161
|
v-model="confirmDialog"
|
|
@@ -272,14 +219,10 @@
|
|
|
272
219
|
</template>
|
|
273
220
|
<script setup lang="ts">
|
|
274
221
|
import OnlineFormConfigurationForm from "./OnlineFormConfigurationForm.vue";
|
|
275
|
-
import
|
|
276
|
-
import useFile from "../composables/useFile";
|
|
222
|
+
import OnlineFormFill from "./OnlineFormFill.vue";
|
|
277
223
|
import useOnlineFormConfiguration from "../composables/useOnlineFormConfiguration";
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
middleware: ["01-auth", "02-org"],
|
|
281
|
-
memberOnly: true,
|
|
282
|
-
});
|
|
224
|
+
import useOnlineFormPages from "../composables/useOnlineFormPages";
|
|
225
|
+
import useUtils from "../composables/useUtils";
|
|
283
226
|
const props = defineProps({
|
|
284
227
|
headers: {
|
|
285
228
|
type: Array as PropType<Array<Record<string, any>>>,
|
|
@@ -319,7 +262,7 @@ const props = defineProps({
|
|
|
319
262
|
});
|
|
320
263
|
|
|
321
264
|
const { getAll: _getAll, deleteById: _deleteById } = useOnlineFormConfiguration();
|
|
322
|
-
const {
|
|
265
|
+
const { formPages } = useOnlineFormPages();
|
|
323
266
|
|
|
324
267
|
const page = ref(1);
|
|
325
268
|
const pages = ref(0);
|
|
@@ -335,6 +278,12 @@ const siteId = route.params.site as string;
|
|
|
335
278
|
const orgId = route.params.org as string;
|
|
336
279
|
|
|
337
280
|
const items = ref<Array<Record<string, any>>>([]);
|
|
281
|
+
const sortAlpha = ref(false);
|
|
282
|
+
const sortedItems = computed(() =>
|
|
283
|
+
sortAlpha.value
|
|
284
|
+
? [...items.value].sort((a, b) => (a.formType ?? "").localeCompare(b.formType ?? ""))
|
|
285
|
+
: items.value
|
|
286
|
+
);
|
|
338
287
|
|
|
339
288
|
const { formatDateDDMMYYYYLocal } = useUtils();
|
|
340
289
|
|
|
@@ -374,22 +323,16 @@ watchEffect(() => {
|
|
|
374
323
|
const createDialog = ref(false);
|
|
375
324
|
const editDialog = ref(false);
|
|
376
325
|
const previewDialog = ref(false);
|
|
377
|
-
const formRenderPreviewDialog = ref(false);
|
|
378
326
|
const selectedOnlineForm = ref<TOnlineForm>({
|
|
379
327
|
_id: "",
|
|
380
328
|
name: "",
|
|
381
329
|
createdAt: "",
|
|
382
330
|
status: "",
|
|
383
331
|
attachment: "",
|
|
384
|
-
inputs: [
|
|
385
|
-
{
|
|
386
|
-
label: "",
|
|
387
|
-
dataType: "",
|
|
388
|
-
required: false,
|
|
389
|
-
multiple: false,
|
|
390
|
-
},
|
|
391
|
-
],
|
|
332
|
+
inputs: [{ label: "", dataType: "", required: false, multiple: false }],
|
|
392
333
|
});
|
|
334
|
+
const selectedFormType = ref("");
|
|
335
|
+
const selectedFormDefinition = ref<any>(null);
|
|
393
336
|
const deleteLoading = ref(false);
|
|
394
337
|
const confirmDialog = ref(false);
|
|
395
338
|
const selectedOnlineFormId = ref<string | null>(null);
|
|
@@ -405,6 +348,17 @@ function parseFieldsToInputs(fields: Record<string, string>): any[] {
|
|
|
405
348
|
|
|
406
349
|
function tableRowClickHandler(_: any, data: any) {
|
|
407
350
|
const item = data.item;
|
|
351
|
+
selectedFormType.value = item.formType ?? "";
|
|
352
|
+
|
|
353
|
+
// Parse blocks stored as JSON string, fallback to hardcoded definition
|
|
354
|
+
let def = null;
|
|
355
|
+
if (item.fields?.blocks) {
|
|
356
|
+
try {
|
|
357
|
+
def = { title: item.formType, blocks: JSON.parse(item.fields.blocks) };
|
|
358
|
+
} catch {}
|
|
359
|
+
}
|
|
360
|
+
selectedFormDefinition.value = def ?? formPages[selectedFormType.value] ?? null;
|
|
361
|
+
|
|
408
362
|
selectedOnlineForm.value = {
|
|
409
363
|
...item,
|
|
410
364
|
inputs: parseFieldsToInputs(item.fields ?? {}),
|
|
@@ -475,4 +429,5 @@ function successUpdate() {
|
|
|
475
429
|
getOnlineFormConfigurations();
|
|
476
430
|
showMessage("Online form configuration updated successfully!", "success");
|
|
477
431
|
}
|
|
432
|
+
|
|
478
433
|
</script>
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
height="48"
|
|
159
159
|
@click="cancel"
|
|
160
160
|
>
|
|
161
|
-
|
|
161
|
+
{{ props.cancelText }}
|
|
162
162
|
</v-btn>
|
|
163
163
|
</v-col>
|
|
164
164
|
|
|
@@ -207,6 +207,10 @@ const props = defineProps({
|
|
|
207
207
|
type: Boolean,
|
|
208
208
|
default: true,
|
|
209
209
|
},
|
|
210
|
+
cancelText: {
|
|
211
|
+
type: String,
|
|
212
|
+
default: "Cancel"
|
|
213
|
+
}
|
|
210
214
|
});
|
|
211
215
|
|
|
212
216
|
const emit = defineEmits(["cancel", "success", "success:create-more"]);
|
|
@@ -1,85 +1,156 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
3
|
+
<div
|
|
4
|
+
style="
|
|
5
|
+
position: relative;
|
|
6
|
+
border: 1.5px dashed #bbb;
|
|
7
|
+
border-radius: 6px;
|
|
8
|
+
background: #fafafa;
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
"
|
|
11
|
+
>
|
|
12
|
+
<canvas
|
|
13
|
+
ref="canvasRef"
|
|
14
|
+
:width="W"
|
|
15
|
+
:height="H"
|
|
16
|
+
style="
|
|
17
|
+
display: block;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 130px;
|
|
20
|
+
cursor: crosshair;
|
|
21
|
+
touch-action: none;
|
|
22
|
+
"
|
|
23
|
+
@mousedown="startMouse"
|
|
24
|
+
@mousemove="moveMouse"
|
|
25
|
+
@mouseup="stop"
|
|
26
|
+
@mouseleave="stop"
|
|
27
|
+
@touchstart.prevent="startTouch"
|
|
28
|
+
@touchmove.prevent="moveTouch"
|
|
29
|
+
@touchend="stop"
|
|
21
30
|
/>
|
|
31
|
+
<div
|
|
32
|
+
v-if="isEmpty"
|
|
33
|
+
style="
|
|
34
|
+
position: absolute;
|
|
35
|
+
inset: 0;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
"
|
|
41
|
+
>
|
|
42
|
+
<span class="text-caption text-disabled">Draw your signature here</span>
|
|
43
|
+
</div>
|
|
22
44
|
</div>
|
|
45
|
+
|
|
46
|
+
<v-row no-gutters align="center" class="mt-1" style="min-height: 28px">
|
|
47
|
+
<span class="text-caption text-medium-emphasis">{{ label }}</span>
|
|
48
|
+
<v-spacer />
|
|
49
|
+
<v-btn
|
|
50
|
+
v-if="!isEmpty"
|
|
51
|
+
size="x-small"
|
|
52
|
+
variant="text"
|
|
53
|
+
color="error"
|
|
54
|
+
class="text-none"
|
|
55
|
+
@click="clear"
|
|
56
|
+
>
|
|
57
|
+
Clear
|
|
58
|
+
</v-btn>
|
|
59
|
+
</v-row>
|
|
23
60
|
</div>
|
|
24
61
|
</template>
|
|
25
|
-
|
|
26
62
|
<script setup lang="ts">
|
|
27
|
-
import { ref, defineProps, defineEmits } from "vue";
|
|
28
|
-
import Vue3Signature from "vue3-signature";
|
|
29
|
-
|
|
30
63
|
const props = defineProps({
|
|
31
|
-
modelValue: String,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
default: false,
|
|
35
|
-
}
|
|
64
|
+
modelValue: { type: String, default: "" },
|
|
65
|
+
label: { type: String, default: "" },
|
|
66
|
+
hideToast: { type: Boolean, default: false },
|
|
36
67
|
});
|
|
37
|
-
|
|
38
68
|
const emit = defineEmits(["update:modelValue"]);
|
|
39
69
|
|
|
40
|
-
|
|
70
|
+
// Internal canvas resolution (retina-friendly)
|
|
71
|
+
const W = 960;
|
|
72
|
+
const H = 260;
|
|
41
73
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
74
|
+
const canvasRef = ref<HTMLCanvasElement | null>(null);
|
|
75
|
+
const drawing = ref(false);
|
|
76
|
+
const isEmpty = ref(true);
|
|
77
|
+
let px = 0;
|
|
78
|
+
let py = 0;
|
|
46
79
|
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
function getCtx() {
|
|
81
|
+
const c = canvasRef.value?.getContext("2d");
|
|
82
|
+
if (c) {
|
|
83
|
+
c.strokeStyle = "#111";
|
|
84
|
+
c.lineWidth = 2.5;
|
|
85
|
+
c.lineCap = "round";
|
|
86
|
+
c.lineJoin = "round";
|
|
87
|
+
}
|
|
88
|
+
return c ?? null;
|
|
89
|
+
}
|
|
51
90
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
91
|
+
function scaled(clientX: number, clientY: number) {
|
|
92
|
+
const rect = canvasRef.value!.getBoundingClientRect();
|
|
93
|
+
return {
|
|
94
|
+
x: ((clientX - rect.left) / rect.width) * W,
|
|
95
|
+
y: ((clientY - rect.top) / rect.height) * H,
|
|
96
|
+
};
|
|
56
97
|
}
|
|
57
98
|
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
99
|
+
function startMouse(e: MouseEvent) {
|
|
100
|
+
drawing.value = true;
|
|
101
|
+
const p = scaled(e.clientX, e.clientY);
|
|
102
|
+
px = p.x;
|
|
103
|
+
py = p.y;
|
|
63
104
|
}
|
|
64
105
|
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
function moveMouse(e: MouseEvent) {
|
|
107
|
+
if (!drawing.value) return;
|
|
108
|
+
paint(scaled(e.clientX, e.clientY));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function startTouch(e: TouchEvent) {
|
|
112
|
+
drawing.value = true;
|
|
113
|
+
const t = e.touches[0];
|
|
114
|
+
const p = scaled(t.clientX, t.clientY);
|
|
115
|
+
px = p.x;
|
|
116
|
+
py = p.y;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function moveTouch(e: TouchEvent) {
|
|
120
|
+
if (!drawing.value) return;
|
|
121
|
+
paint(scaled(e.touches[0].clientX, e.touches[0].clientY));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function stop() {
|
|
125
|
+
if (drawing.value && !isEmpty.value) {
|
|
126
|
+
emit("update:modelValue", canvasRef.value!.toDataURL("image/png"));
|
|
76
127
|
}
|
|
128
|
+
drawing.value = false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function paint({ x, y }: { x: number; y: number }) {
|
|
132
|
+
const c = getCtx();
|
|
133
|
+
if (!c) return;
|
|
134
|
+
c.beginPath();
|
|
135
|
+
c.moveTo(px, py);
|
|
136
|
+
c.lineTo(x, y);
|
|
137
|
+
c.stroke();
|
|
138
|
+
px = x;
|
|
139
|
+
py = y;
|
|
140
|
+
isEmpty.value = false;
|
|
77
141
|
}
|
|
78
142
|
|
|
79
143
|
function clear() {
|
|
80
|
-
|
|
81
|
-
if(!
|
|
82
|
-
|
|
83
|
-
|
|
144
|
+
const cv = canvasRef.value;
|
|
145
|
+
if (!cv) return;
|
|
146
|
+
cv.getContext("2d")?.clearRect(0, 0, W, H);
|
|
147
|
+
isEmpty.value = true;
|
|
148
|
+
emit("update:modelValue", "");
|
|
84
149
|
}
|
|
150
|
+
|
|
151
|
+
// Allow parent to programmatically clear by setting modelValue to ""
|
|
152
|
+
watch(
|
|
153
|
+
() => props.modelValue,
|
|
154
|
+
(v) => { if (!v && !isEmpty.value) clear(); }
|
|
155
|
+
);
|
|
85
156
|
</script>
|
package/composables/useMember.ts
CHANGED
|
@@ -109,13 +109,15 @@ export default function useMember() {
|
|
|
109
109
|
app: string;
|
|
110
110
|
siteId?: string;
|
|
111
111
|
siteName?: string;
|
|
112
|
+
onboardingRequired?: boolean;
|
|
112
113
|
}) {
|
|
113
114
|
return useNuxtApp().$api<TMember>("/api/members/direct", {
|
|
114
115
|
method: "POST",
|
|
115
116
|
body: payload,
|
|
116
|
-
})
|
|
117
|
+
})
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
|
|
119
121
|
function updateMemberSite(id: string, siteId: string, siteName: string) {
|
|
120
122
|
return useNuxtApp().$api(`/api/members/site`, {
|
|
121
123
|
method: "PUT",
|
|
@@ -137,6 +139,15 @@ export default function useMember() {
|
|
|
137
139
|
);
|
|
138
140
|
}
|
|
139
141
|
|
|
142
|
+
function completeMemberOnboarding(id: string) {
|
|
143
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
144
|
+
`/api/members/${id}/onboarding/complete`,
|
|
145
|
+
{
|
|
146
|
+
method: "PUT",
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
return {
|
|
141
152
|
members,
|
|
142
153
|
member,
|
|
@@ -156,5 +167,6 @@ export default function useMember() {
|
|
|
156
167
|
updateMemberSite,
|
|
157
168
|
getAllByUserId,
|
|
158
169
|
getByUserTypeOrg,
|
|
170
|
+
completeMemberOnboarding,
|
|
159
171
|
};
|
|
160
172
|
}
|