@eeplatform/nuxt-layer-common 1.5.0 → 1.6.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/CHANGELOG.md +12 -0
- package/components/Curriculum.vue +269 -0
- package/components/CurriculumForm.vue +347 -0
- package/components/CurriculumSubject.vue +273 -0
- package/components/CurriculumSubjectForm.vue +597 -0
- package/components/EnrollmentForm.vue +5 -3
- package/composables/useBasicEdu.ts +15 -3
- package/composables/useCurriculum.ts +49 -0
- package/composables/useCurriculumSubject.ts +58 -0
- package/package.json +1 -1
- package/types/curriculum.d.ts +31 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5">
|
|
6
|
+
{{ props.title }}
|
|
7
|
+
</span>
|
|
8
|
+
</v-row>
|
|
9
|
+
</v-toolbar>
|
|
10
|
+
|
|
11
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
12
|
+
<v-form v-model="formValid" :disabled="disable">
|
|
13
|
+
<v-row no-gutters>
|
|
14
|
+
<v-col cols="12" class="mt-2">
|
|
15
|
+
<v-row no-gutters>
|
|
16
|
+
<InputLabel
|
|
17
|
+
class="text-capitalize"
|
|
18
|
+
title="Curriculum"
|
|
19
|
+
:required="props.mode !== 'view'"
|
|
20
|
+
/>
|
|
21
|
+
<v-col cols="12">
|
|
22
|
+
<v-combobox
|
|
23
|
+
v-model="curriculumSubject.curriculum"
|
|
24
|
+
v-model:search="searchCurriculum"
|
|
25
|
+
density="comfortable"
|
|
26
|
+
:rules="[requiredRule]"
|
|
27
|
+
:return-object="false"
|
|
28
|
+
:items="curriculums"
|
|
29
|
+
item-title="name"
|
|
30
|
+
item-value="_id"
|
|
31
|
+
:error-messages="errorCurriculum"
|
|
32
|
+
:readonly="props.mode === 'view'"
|
|
33
|
+
>
|
|
34
|
+
<template v-slot:no-data>
|
|
35
|
+
<v-list-item>
|
|
36
|
+
<v-list-item-title>
|
|
37
|
+
No results matching "<strong>{{
|
|
38
|
+
searchCurriculum
|
|
39
|
+
}}</strong
|
|
40
|
+
>". Click the search button and try again.
|
|
41
|
+
</v-list-item-title>
|
|
42
|
+
</v-list-item>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<template #append>
|
|
46
|
+
<v-btn
|
|
47
|
+
variant="tonal"
|
|
48
|
+
:disabled="curriculumReqStatus"
|
|
49
|
+
class="text-none"
|
|
50
|
+
size="48"
|
|
51
|
+
width="100"
|
|
52
|
+
icon
|
|
53
|
+
@click="_getAllCurriculum()"
|
|
54
|
+
>
|
|
55
|
+
<v-icon>ph:magnifying-glass-bold</v-icon>
|
|
56
|
+
</v-btn>
|
|
57
|
+
</template>
|
|
58
|
+
</v-combobox>
|
|
59
|
+
</v-col>
|
|
60
|
+
</v-row>
|
|
61
|
+
</v-col>
|
|
62
|
+
|
|
63
|
+
<v-col cols="12" class="mt-2">
|
|
64
|
+
<v-row no-gutters>
|
|
65
|
+
<InputLabel
|
|
66
|
+
class="text-capitalize"
|
|
67
|
+
title="Education Level"
|
|
68
|
+
:required="props.mode !== 'view'"
|
|
69
|
+
/>
|
|
70
|
+
<v-col cols="12">
|
|
71
|
+
<v-combobox
|
|
72
|
+
v-model="curriculumSubject.educationLevel"
|
|
73
|
+
density="comfortable"
|
|
74
|
+
:rules="[requiredRule]"
|
|
75
|
+
:return-object="false"
|
|
76
|
+
:items="educationLevels"
|
|
77
|
+
:readonly="props.mode === 'view'"
|
|
78
|
+
></v-combobox>
|
|
79
|
+
</v-col>
|
|
80
|
+
</v-row>
|
|
81
|
+
</v-col>
|
|
82
|
+
|
|
83
|
+
<v-col cols="12" class="mt-2">
|
|
84
|
+
<v-row no-gutters>
|
|
85
|
+
<InputLabel
|
|
86
|
+
class="text-capitalize"
|
|
87
|
+
title="Grade Level"
|
|
88
|
+
:required="props.mode !== 'view'"
|
|
89
|
+
/>
|
|
90
|
+
<v-col cols="12">
|
|
91
|
+
<v-autocomplete
|
|
92
|
+
v-model="curriculumSubject.gradeLevel"
|
|
93
|
+
density="comfortable"
|
|
94
|
+
:rules="[requiredRule]"
|
|
95
|
+
:items="selectedGradeLevels"
|
|
96
|
+
:readonly="props.mode === 'view'"
|
|
97
|
+
multiple
|
|
98
|
+
chips
|
|
99
|
+
></v-autocomplete>
|
|
100
|
+
</v-col>
|
|
101
|
+
</v-row>
|
|
102
|
+
</v-col>
|
|
103
|
+
|
|
104
|
+
<v-col cols="12" class="mt-2">
|
|
105
|
+
<v-row no-gutters>
|
|
106
|
+
<InputLabel
|
|
107
|
+
class="text-capitalize"
|
|
108
|
+
title="Subject Code"
|
|
109
|
+
:required="props.mode !== 'view'"
|
|
110
|
+
/>
|
|
111
|
+
<v-col cols="12">
|
|
112
|
+
<v-text-field
|
|
113
|
+
v-model="curriculumSubject.subjectCode"
|
|
114
|
+
density="comfortable"
|
|
115
|
+
:rules="[requiredRule]"
|
|
116
|
+
:readonly="props.mode === 'view'"
|
|
117
|
+
></v-text-field>
|
|
118
|
+
</v-col>
|
|
119
|
+
</v-row>
|
|
120
|
+
</v-col>
|
|
121
|
+
|
|
122
|
+
<v-col cols="12" class="mt-2">
|
|
123
|
+
<v-row no-gutters>
|
|
124
|
+
<InputLabel
|
|
125
|
+
class="text-capitalize"
|
|
126
|
+
title="Subject Name"
|
|
127
|
+
:required="props.mode !== 'view'"
|
|
128
|
+
/>
|
|
129
|
+
<v-col cols="12">
|
|
130
|
+
<v-text-field
|
|
131
|
+
v-model="curriculumSubject.subjectName"
|
|
132
|
+
density="comfortable"
|
|
133
|
+
:rules="[requiredRule]"
|
|
134
|
+
:readonly="props.mode === 'view'"
|
|
135
|
+
></v-text-field>
|
|
136
|
+
</v-col>
|
|
137
|
+
</v-row>
|
|
138
|
+
</v-col>
|
|
139
|
+
|
|
140
|
+
<v-col cols="12" class="mt-2">
|
|
141
|
+
<v-row no-gutters>
|
|
142
|
+
<InputLabel
|
|
143
|
+
class="text-capitalize"
|
|
144
|
+
title="Subject Type"
|
|
145
|
+
:required="props.mode !== 'view'"
|
|
146
|
+
/>
|
|
147
|
+
<v-col cols="12">
|
|
148
|
+
<v-autocomplete
|
|
149
|
+
v-model="curriculumSubject.subjectType"
|
|
150
|
+
density="comfortable"
|
|
151
|
+
:rules="[requiredRule]"
|
|
152
|
+
:items="subjectTypes"
|
|
153
|
+
:readonly="props.mode === 'view'"
|
|
154
|
+
></v-autocomplete>
|
|
155
|
+
</v-col>
|
|
156
|
+
</v-row>
|
|
157
|
+
</v-col>
|
|
158
|
+
|
|
159
|
+
<v-col cols="12" class="mt-2">
|
|
160
|
+
<v-row no-gutters>
|
|
161
|
+
<InputLabel
|
|
162
|
+
class="text-capitalize"
|
|
163
|
+
title="Session Frequency (Classes per week)"
|
|
164
|
+
:required="props.mode !== 'view'"
|
|
165
|
+
/>
|
|
166
|
+
<v-col cols="12">
|
|
167
|
+
<v-combobox
|
|
168
|
+
v-model.number="curriculumSubject.sessionFrequency"
|
|
169
|
+
:items="sessionPerWeekOptions"
|
|
170
|
+
density="comfortable"
|
|
171
|
+
:rules="[requiredRule]"
|
|
172
|
+
type="number"
|
|
173
|
+
:readonly="props.mode === 'view'"
|
|
174
|
+
></v-combobox>
|
|
175
|
+
</v-col>
|
|
176
|
+
</v-row>
|
|
177
|
+
</v-col>
|
|
178
|
+
|
|
179
|
+
<v-col cols="12" class="mt-2">
|
|
180
|
+
<v-row no-gutters>
|
|
181
|
+
<InputLabel
|
|
182
|
+
class="text-capitalize"
|
|
183
|
+
title="Session Duration (Minutes per class)"
|
|
184
|
+
:required="props.mode !== 'view'"
|
|
185
|
+
/>
|
|
186
|
+
<v-col cols="12">
|
|
187
|
+
<v-combobox
|
|
188
|
+
v-model.number="curriculumSubject.sessionDuration"
|
|
189
|
+
density="comfortable"
|
|
190
|
+
:rules="[requiredRule]"
|
|
191
|
+
:items="sessionDurationOptions"
|
|
192
|
+
type="number"
|
|
193
|
+
:readonly="props.mode === 'view'"
|
|
194
|
+
></v-combobox>
|
|
195
|
+
</v-col>
|
|
196
|
+
</v-row>
|
|
197
|
+
</v-col>
|
|
198
|
+
|
|
199
|
+
<v-col v-if="props.mode === 'create'" cols="12">
|
|
200
|
+
<v-checkbox v-model="createMore" density="comfortable" hide-details>
|
|
201
|
+
<template #label>
|
|
202
|
+
<span class="text-subtitle-2 font-weight-bold">
|
|
203
|
+
Create more
|
|
204
|
+
</span>
|
|
205
|
+
</template>
|
|
206
|
+
</v-checkbox>
|
|
207
|
+
</v-col>
|
|
208
|
+
|
|
209
|
+
<v-col v-if="message" cols="12" class="my-2">
|
|
210
|
+
<v-row no-gutters>
|
|
211
|
+
<v-col cols="12" class="text-center">
|
|
212
|
+
<span
|
|
213
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
214
|
+
>
|
|
215
|
+
{{ message }}
|
|
216
|
+
</span>
|
|
217
|
+
</v-col>
|
|
218
|
+
</v-row>
|
|
219
|
+
</v-col>
|
|
220
|
+
</v-row>
|
|
221
|
+
</v-form>
|
|
222
|
+
</v-card-text>
|
|
223
|
+
|
|
224
|
+
<v-toolbar density="compact">
|
|
225
|
+
<v-row no-gutters>
|
|
226
|
+
<v-col
|
|
227
|
+
v-if="modeViewEdit && (props.canEdit || props.canDelete)"
|
|
228
|
+
:cols="props.canEdit || props.canDelete ? 6 : 12"
|
|
229
|
+
>
|
|
230
|
+
<v-btn
|
|
231
|
+
tile
|
|
232
|
+
block
|
|
233
|
+
variant="text"
|
|
234
|
+
class="text-none"
|
|
235
|
+
size="48"
|
|
236
|
+
@click="emit('cancel')"
|
|
237
|
+
>
|
|
238
|
+
Close
|
|
239
|
+
</v-btn>
|
|
240
|
+
</v-col>
|
|
241
|
+
|
|
242
|
+
<v-col
|
|
243
|
+
v-if="modeViewEdit && props.canEdit && !props.canDelete"
|
|
244
|
+
:cols="props.canEdit ? 6 : 12"
|
|
245
|
+
>
|
|
246
|
+
<v-btn
|
|
247
|
+
tile
|
|
248
|
+
block
|
|
249
|
+
variant="flat"
|
|
250
|
+
color="black"
|
|
251
|
+
class="text-none"
|
|
252
|
+
size="48"
|
|
253
|
+
@click="emit('cancel')"
|
|
254
|
+
>
|
|
255
|
+
Edit curriculum
|
|
256
|
+
</v-btn>
|
|
257
|
+
</v-col>
|
|
258
|
+
|
|
259
|
+
<v-col
|
|
260
|
+
v-if="modeViewEdit && props.canDelete && !props.canEdit"
|
|
261
|
+
:cols="props.canDelete ? 6 : 12"
|
|
262
|
+
>
|
|
263
|
+
<v-btn
|
|
264
|
+
tile
|
|
265
|
+
block
|
|
266
|
+
variant="flat"
|
|
267
|
+
class="text-none text-error"
|
|
268
|
+
size="48"
|
|
269
|
+
@click="emit('cancel')"
|
|
270
|
+
>
|
|
271
|
+
Delete curriculum
|
|
272
|
+
</v-btn>
|
|
273
|
+
</v-col>
|
|
274
|
+
|
|
275
|
+
<v-col v-if="hasMoreActions" cols="6">
|
|
276
|
+
<v-menu>
|
|
277
|
+
<template #activator="{ props }">
|
|
278
|
+
<v-btn
|
|
279
|
+
block
|
|
280
|
+
variant="flat"
|
|
281
|
+
color="black"
|
|
282
|
+
class="text-none"
|
|
283
|
+
height="48"
|
|
284
|
+
v-bind="props"
|
|
285
|
+
tile
|
|
286
|
+
>
|
|
287
|
+
More actions
|
|
288
|
+
</v-btn>
|
|
289
|
+
</template>
|
|
290
|
+
|
|
291
|
+
<v-list class="pa-0">
|
|
292
|
+
<v-list-item @click="emit('edit')">
|
|
293
|
+
<v-list-item-title class="text-subtitle-2">
|
|
294
|
+
Edit curriculum
|
|
295
|
+
</v-list-item-title>
|
|
296
|
+
</v-list-item>
|
|
297
|
+
|
|
298
|
+
<v-list-item @click="emit('delete')" class="text-red">
|
|
299
|
+
<v-list-item-title class="text-subtitle-2">
|
|
300
|
+
Delete curriculum
|
|
301
|
+
</v-list-item-title>
|
|
302
|
+
</v-list-item>
|
|
303
|
+
</v-list>
|
|
304
|
+
</v-menu>
|
|
305
|
+
</v-col>
|
|
306
|
+
|
|
307
|
+
<v-col v-if="props.mode === 'edit'" cols="6">
|
|
308
|
+
<v-btn
|
|
309
|
+
tile
|
|
310
|
+
block
|
|
311
|
+
variant="flat"
|
|
312
|
+
color="black"
|
|
313
|
+
class="text-none"
|
|
314
|
+
size="48"
|
|
315
|
+
:disabled="!formValid"
|
|
316
|
+
@click="submitUpdate"
|
|
317
|
+
>
|
|
318
|
+
Submit update
|
|
319
|
+
</v-btn>
|
|
320
|
+
</v-col>
|
|
321
|
+
|
|
322
|
+
<v-col v-if="props.mode === 'create'" cols="6">
|
|
323
|
+
<v-btn
|
|
324
|
+
tile
|
|
325
|
+
block
|
|
326
|
+
variant="text"
|
|
327
|
+
class="text-none"
|
|
328
|
+
size="48"
|
|
329
|
+
@click="emit('cancel')"
|
|
330
|
+
>
|
|
331
|
+
Cancel
|
|
332
|
+
</v-btn>
|
|
333
|
+
</v-col>
|
|
334
|
+
|
|
335
|
+
<v-col v-if="props.mode === 'create'" cols="6">
|
|
336
|
+
<v-btn
|
|
337
|
+
tile
|
|
338
|
+
block
|
|
339
|
+
variant="flat"
|
|
340
|
+
color="black"
|
|
341
|
+
class="text-none"
|
|
342
|
+
size="48"
|
|
343
|
+
:disabled="!formValid"
|
|
344
|
+
@click="submit"
|
|
345
|
+
>
|
|
346
|
+
Submit
|
|
347
|
+
</v-btn>
|
|
348
|
+
</v-col>
|
|
349
|
+
</v-row>
|
|
350
|
+
</v-toolbar>
|
|
351
|
+
</v-card>
|
|
352
|
+
</template>
|
|
353
|
+
|
|
354
|
+
<script setup lang="ts">
|
|
355
|
+
const props = defineProps({
|
|
356
|
+
title: {
|
|
357
|
+
type: String,
|
|
358
|
+
default: "Subject Form",
|
|
359
|
+
},
|
|
360
|
+
mode: {
|
|
361
|
+
type: String,
|
|
362
|
+
default: "create",
|
|
363
|
+
},
|
|
364
|
+
data: {
|
|
365
|
+
type: Object as PropType<TCurriculumSubject>,
|
|
366
|
+
default: () => ({}),
|
|
367
|
+
},
|
|
368
|
+
canEdit: {
|
|
369
|
+
type: Boolean,
|
|
370
|
+
default: false,
|
|
371
|
+
},
|
|
372
|
+
canDelete: {
|
|
373
|
+
type: Boolean,
|
|
374
|
+
default: false,
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const emit = defineEmits([
|
|
379
|
+
"cancel",
|
|
380
|
+
"edit",
|
|
381
|
+
"delete",
|
|
382
|
+
"success",
|
|
383
|
+
"success:create-more",
|
|
384
|
+
]);
|
|
385
|
+
|
|
386
|
+
const formValid = ref(false);
|
|
387
|
+
|
|
388
|
+
const curriculums = ref<Array<TCurriculum>>([]);
|
|
389
|
+
const searchCurriculum = ref("");
|
|
390
|
+
|
|
391
|
+
const { getAll: getAllCurriculum } = useCurriculum();
|
|
392
|
+
|
|
393
|
+
const {
|
|
394
|
+
data: getCurriculumReq,
|
|
395
|
+
refresh: _getAllCurriculum,
|
|
396
|
+
status: getAllCurriculumStatus,
|
|
397
|
+
} = await useLazyAsyncData(
|
|
398
|
+
`curriculums-as-options-list-${searchCurriculum.value ?? "search"}`,
|
|
399
|
+
() =>
|
|
400
|
+
getAllCurriculum({
|
|
401
|
+
limit: 20,
|
|
402
|
+
search: searchCurriculum.value,
|
|
403
|
+
})
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
const curriculumReqStatus = computed(
|
|
407
|
+
() => getAllCurriculumStatus.value === "pending"
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
watchEffect(() => {
|
|
411
|
+
if (getCurriculumReq.value) {
|
|
412
|
+
curriculums.value = getCurriculumReq.value.items;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
const curriculumSubject = ref<TCurriculumSubject>({
|
|
417
|
+
educationLevel: "",
|
|
418
|
+
gradeLevel: [],
|
|
419
|
+
subjectCode: "",
|
|
420
|
+
subjectName: "",
|
|
421
|
+
subjectType: "",
|
|
422
|
+
sessionFrequency: 0,
|
|
423
|
+
sessionDuration: 0,
|
|
424
|
+
totalMinutesPerWeek: 0,
|
|
425
|
+
curriculum: "",
|
|
426
|
+
curriculumName: "",
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
watchEffect(() => {
|
|
430
|
+
if (curriculumSubject.value.curriculum) {
|
|
431
|
+
const selected = curriculums.value.find(
|
|
432
|
+
(curr) => curr._id === curriculumSubject.value.curriculum
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
if (selected) {
|
|
436
|
+
curriculumSubject.value.curriculumName = selected.name;
|
|
437
|
+
curriculumSubject.value.effectiveSchoolYear = selected.effectiveSchoolYear
|
|
438
|
+
.split("-")
|
|
439
|
+
.map((year: any) => parseInt(year));
|
|
440
|
+
} else {
|
|
441
|
+
curriculumSubject.value.curriculumName = "";
|
|
442
|
+
curriculumSubject.value.effectiveSchoolYear = [];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
const selectedCurriculum = computed(() =>
|
|
448
|
+
curriculums.value.find(
|
|
449
|
+
(curr) => curr._id === curriculumSubject.value.curriculum
|
|
450
|
+
)
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
const errorCurriculum = computed(() => {
|
|
454
|
+
return !selectedCurriculum.value && curriculumSubject.value.curriculum
|
|
455
|
+
? ["Please select a valid curriculum"]
|
|
456
|
+
: [];
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
if (["view", "edit"].includes(props.mode) && props.data) {
|
|
460
|
+
Object.assign(
|
|
461
|
+
curriculumSubject.value,
|
|
462
|
+
JSON.parse(JSON.stringify(props.data))
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
watchEffect(() => {
|
|
467
|
+
curriculumSubject.value.totalMinutesPerWeek =
|
|
468
|
+
curriculumSubject.value.sessionFrequency *
|
|
469
|
+
curriculumSubject.value.sessionDuration;
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
const subjectHeaders = [
|
|
473
|
+
{ title: "Education Level", value: "educationLevel", width: "140px" },
|
|
474
|
+
{ title: "Grade Level", value: "gradeLevel", width: "120px" },
|
|
475
|
+
{ title: "Code", value: "subjectCode", width: "100px" },
|
|
476
|
+
{ title: "Name", value: "subjectName" },
|
|
477
|
+
{ title: "Type", value: "subjectType", width: "100px" },
|
|
478
|
+
{ title: "Session Frequency", value: "sessionFrequency", width: "100px" },
|
|
479
|
+
{ title: "Session Duration", value: "sessionDuration", width: "100px" },
|
|
480
|
+
{ title: "Minutes Per Week", value: "totalMinutesPerWeek", width: "120px" },
|
|
481
|
+
];
|
|
482
|
+
|
|
483
|
+
const dialogSubject = ref(false);
|
|
484
|
+
const formSubject = ref(false);
|
|
485
|
+
|
|
486
|
+
const { generateSchoolYears, gradeLevels } = useBasicEdu();
|
|
487
|
+
|
|
488
|
+
const effectiveSchoolYearOptions = computed(() =>
|
|
489
|
+
generateSchoolYears(5, "future")
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
const selectedGradeLevels = computed(() => {
|
|
493
|
+
return curriculumSubject.value.educationLevel
|
|
494
|
+
? gradeLevels.filter(
|
|
495
|
+
(level) => level.level === curriculumSubject.value.educationLevel
|
|
496
|
+
)
|
|
497
|
+
: [];
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
const { educationLevels } = useBasicEdu();
|
|
501
|
+
|
|
502
|
+
const subjectTypes = ["Core", "Applied", "Specialized", "Elective", "Other"];
|
|
503
|
+
|
|
504
|
+
const sessionPerWeekOptions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
505
|
+
|
|
506
|
+
const sessionDurationOptions = [30, 35, 40, 45, 50, 55, 60, 75, 90, 120];
|
|
507
|
+
|
|
508
|
+
const createMore = ref(false);
|
|
509
|
+
const disable = ref(false);
|
|
510
|
+
|
|
511
|
+
const { requiredRule } = useUtils();
|
|
512
|
+
|
|
513
|
+
const message = ref("");
|
|
514
|
+
const type = defineModel("type", {
|
|
515
|
+
type: String,
|
|
516
|
+
default: "",
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const { add, updateById } = useCurriculumSubject();
|
|
520
|
+
|
|
521
|
+
async function submit() {
|
|
522
|
+
disable.value = true;
|
|
523
|
+
try {
|
|
524
|
+
if (props.mode === "create") {
|
|
525
|
+
await add(curriculumSubject.value);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
console.log(props.mode === "edit");
|
|
529
|
+
|
|
530
|
+
if (props.mode === "edit") {
|
|
531
|
+
await updateById(curriculumSubject.value._id ?? "", {
|
|
532
|
+
curriculum: curriculumSubject.value.curriculum,
|
|
533
|
+
educationLevel: curriculumSubject.value.educationLevel,
|
|
534
|
+
gradeLevel: curriculumSubject.value.gradeLevel,
|
|
535
|
+
subjectCode: curriculumSubject.value.subjectCode,
|
|
536
|
+
subjectName: curriculumSubject.value.subjectName,
|
|
537
|
+
subjectType: curriculumSubject.value.subjectType,
|
|
538
|
+
sessionFrequency: curriculumSubject.value.sessionFrequency,
|
|
539
|
+
sessionDuration: curriculumSubject.value.sessionDuration,
|
|
540
|
+
totalMinutesPerWeek: curriculumSubject.value.totalMinutesPerWeek,
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (createMore.value) {
|
|
545
|
+
message.value = "";
|
|
546
|
+
emit("success:create-more");
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
emit("success");
|
|
551
|
+
} catch (error: any) {
|
|
552
|
+
message.value = error.response._data.message;
|
|
553
|
+
} finally {
|
|
554
|
+
disable.value = false;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const canAdd = computed(() => {
|
|
559
|
+
return ["create", "edit"].includes(props.mode);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
async function submitUpdate() {
|
|
563
|
+
disable.value = true;
|
|
564
|
+
try {
|
|
565
|
+
await updateById(curriculumSubject.value._id ?? "", {
|
|
566
|
+
curriculum: curriculumSubject.value.curriculum,
|
|
567
|
+
educationLevel: curriculumSubject.value.educationLevel,
|
|
568
|
+
gradeLevel: curriculumSubject.value.gradeLevel,
|
|
569
|
+
subjectCode: curriculumSubject.value.subjectCode,
|
|
570
|
+
subjectName: curriculumSubject.value.subjectName,
|
|
571
|
+
subjectType: curriculumSubject.value.subjectType,
|
|
572
|
+
sessionFrequency: curriculumSubject.value.sessionFrequency,
|
|
573
|
+
sessionDuration: curriculumSubject.value.sessionDuration,
|
|
574
|
+
totalMinutesPerWeek: curriculumSubject.value.totalMinutesPerWeek,
|
|
575
|
+
});
|
|
576
|
+
if (createMore.value) {
|
|
577
|
+
message.value = "";
|
|
578
|
+
emit("success:create-more");
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
emit("success");
|
|
583
|
+
} catch (error: any) {
|
|
584
|
+
message.value = error.response._data.message;
|
|
585
|
+
} finally {
|
|
586
|
+
disable.value = false;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const modeViewEdit = computed(() => {
|
|
591
|
+
return ["view", "edit"].includes(props.mode);
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
const hasMoreActions = computed(() => {
|
|
595
|
+
return props.mode === "view" && props.canEdit && props.canDelete;
|
|
596
|
+
});
|
|
597
|
+
</script>
|
|
@@ -1486,8 +1486,11 @@ const isSeniorHighSchool = computed(() => {
|
|
|
1486
1486
|
return ["grade-11", "grade-12"].includes(gradeLevel);
|
|
1487
1487
|
});
|
|
1488
1488
|
|
|
1489
|
-
const effectiveSchoolYearOptions =
|
|
1490
|
-
|
|
1489
|
+
const effectiveSchoolYearOptions = computed(() =>
|
|
1490
|
+
generateSchoolYears(0, "future")
|
|
1491
|
+
);
|
|
1492
|
+
|
|
1493
|
+
const lastSchoolYearOptions = generateSchoolYears(50);
|
|
1491
1494
|
|
|
1492
1495
|
const indigenousCommunitiesPhilippines = [
|
|
1493
1496
|
// Luzon (Northern Philippines) - Cordillera Groups (Igorot Subgroups)
|
|
@@ -1664,7 +1667,6 @@ watchEffect(() => {
|
|
|
1664
1667
|
});
|
|
1665
1668
|
|
|
1666
1669
|
import { useMask } from "vuetify";
|
|
1667
|
-
import { fa } from "zod/v4/locales";
|
|
1668
1670
|
|
|
1669
1671
|
watchEffect(() => {
|
|
1670
1672
|
const mask = useMask({ mask: "##/##/####" });
|
|
@@ -114,12 +114,24 @@ export default function useBasicEdu() {
|
|
|
114
114
|
},
|
|
115
115
|
];
|
|
116
116
|
|
|
117
|
-
function generateSchoolYears(generation = 0) {
|
|
117
|
+
function generateSchoolYears(generation = 0, mode = "past") {
|
|
118
118
|
const currentYear = new Date().getFullYear();
|
|
119
119
|
const years = [];
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
|
|
121
|
+
if (mode === "past") {
|
|
122
|
+
// Generate from current year going back to past years
|
|
123
|
+
for (let i = 0; i <= generation; i++) {
|
|
124
|
+
const year = currentYear - i;
|
|
125
|
+
years.push(`${year}-${year + 1}`);
|
|
126
|
+
}
|
|
127
|
+
} else if (mode === "future") {
|
|
128
|
+
// Generate from current year going forward to future years
|
|
129
|
+
for (let i = 0; i <= generation; i++) {
|
|
130
|
+
const year = currentYear + i;
|
|
131
|
+
years.push(`${year}-${year + 1}`);
|
|
132
|
+
}
|
|
122
133
|
}
|
|
134
|
+
|
|
123
135
|
return years;
|
|
124
136
|
}
|
|
125
137
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export default function useCurriculum() {
|
|
2
|
+
const resource = "basic-education/curriculums";
|
|
3
|
+
|
|
4
|
+
function add(value: TCurriculum) {
|
|
5
|
+
return $fetch<Record<string, any>>(`/api/${resource}`, {
|
|
6
|
+
method: "POST",
|
|
7
|
+
body: value,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function getAll({
|
|
12
|
+
page = 1,
|
|
13
|
+
search = "",
|
|
14
|
+
limit = 10,
|
|
15
|
+
status = "active",
|
|
16
|
+
school = "",
|
|
17
|
+
} = {}) {
|
|
18
|
+
return $fetch<Record<string, any>>(`/api/${resource}`, {
|
|
19
|
+
method: "GET",
|
|
20
|
+
query: { page, limit, search, status, school },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function updateById(
|
|
25
|
+
id: string,
|
|
26
|
+
value: Pick<
|
|
27
|
+
TCurriculum,
|
|
28
|
+
"name" | "effectiveSchoolYear" | "maxTeachingHoursPerDay"
|
|
29
|
+
>
|
|
30
|
+
) {
|
|
31
|
+
return $fetch<Record<string, any>>(`/api/${resource}/${id}`, {
|
|
32
|
+
method: "PUT",
|
|
33
|
+
body: value,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function deleteById(id: string) {
|
|
38
|
+
return $fetch<Record<string, any>>(`/api/${resource}/${id}`, {
|
|
39
|
+
method: "DELETE",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
add,
|
|
45
|
+
getAll,
|
|
46
|
+
updateById,
|
|
47
|
+
deleteById,
|
|
48
|
+
};
|
|
49
|
+
}
|