1
1
<script setup lang="ts">
2
2
import type { Book } from " ~/types/book"
3
- import type { APIResponsePaginated } from " ~/types/response"
3
+ import type { APIResponseArray , APIResponsePaginated } from " ~/types/response"
4
+ import type { SchoolClass } from " ~/types/schoolclass"
5
+ import type { BookOrderDTO } from " ~/types/bookorder"
6
+ import { z } from " zod"
7
+ import type { FormSubmitEvent } from " #ui/types"
8
+ import type { Year } from " ~/types/year"
9
+
10
+ const { t, locale } = useI18n ()
4
11
5
12
const columns = ref ([
6
13
{
@@ -42,6 +49,58 @@ const columns = ref([
42
49
key: " actions" ,
43
50
},
44
51
])
52
+
53
+ watch (
54
+ locale ,
55
+ () => {
56
+ columns .value = [
57
+ {
58
+ key: " orderNumber" ,
59
+ label: t (" book.orderNumber" ),
60
+ sortable: true ,
61
+ },
62
+ {
63
+ key: " title" ,
64
+ label: t (" book.title" ),
65
+ sortable: true ,
66
+ },
67
+ {
68
+ key: " publisher" ,
69
+ label: t (" book.publisher" ),
70
+ sortable: true ,
71
+ },
72
+ {
73
+ key: " subject" ,
74
+ label: t (" book.subject" ),
75
+ sortable: true ,
76
+ },
77
+ {
78
+ key: " grade" ,
79
+ label: t (" book.grade" ),
80
+ sortable: true ,
81
+ },
82
+ {
83
+ key: " ebook" ,
84
+ label: t (" book.ebook" ),
85
+ sortable: true ,
86
+ },
87
+ {
88
+ key: " ebookPlus" ,
89
+ label: t (" book.ebookPlus" ),
90
+ sortable: true ,
91
+ },
92
+ {
93
+ key: " bookPrice" ,
94
+ label: t (" book.price" ),
95
+ sortable: true ,
96
+ },
97
+ {
98
+ key: " actions" ,
99
+ },
100
+ ]
101
+ },
102
+ { immediate: true },
103
+ )
45
104
const columnsBackup = ref (columns .value )
46
105
const config = useRuntimeConfig ()
47
106
@@ -136,59 +195,101 @@ function resetFilters() {
136
195
selectedColumns .value = columnsBackup .value
137
196
}
138
197
139
- const { t, locale } = useI18n ()
198
+ const { data : schoolClasses, pending : schoolClassesPending } =
199
+ await useLazyFetch <APIResponseArray <SchoolClass >>(" /schoolClasses" , {
200
+ baseURL: config .public .baseURL ,
201
+ pick: [" data" ],
202
+ })
140
203
141
- watch (
142
- locale ,
143
- () => {
144
- columns .value = [
145
- {
146
- key: " orderNumber" ,
147
- label: t (" book.orderNumber" ),
148
- sortable: true ,
149
- },
150
- {
151
- key: " title" ,
152
- label: t (" book.title" ),
153
- sortable: true ,
154
- },
155
- {
156
- key: " publisher" ,
157
- label: t (" book.publisher" ),
158
- sortable: true ,
159
- },
160
- {
161
- key: " subject" ,
162
- label: t (" book.subject" ),
163
- sortable: true ,
164
- },
165
- {
166
- key: " grade" ,
167
- label: t (" book.grade" ),
168
- sortable: true ,
169
- },
170
- {
171
- key: " ebook" ,
172
- label: t (" book.ebook" ),
173
- sortable: true ,
174
- },
175
- {
176
- key: " ebookPlus" ,
177
- label: t (" book.ebookPlus" ),
178
- sortable: true ,
179
- },
180
- {
181
- key: " bookPrice" ,
182
- label: t (" book.price" ),
183
- sortable: true ,
184
- },
185
- {
186
- key: " actions" ,
187
- },
188
- ]
189
- },
190
- { immediate: true },
191
- )
204
+ const isVisible = ref (false )
205
+
206
+ const teacherCopy = ref <boolean >(false )
207
+
208
+ const schema = z .object ({
209
+ schoolClass: z .object ({
210
+ id: z .number (),
211
+ name: z .string (),
212
+ grade: z .number (),
213
+ students: z .number (),
214
+ repetents: z .number (),
215
+ budget: z .number (),
216
+ usedBudget: z .number (),
217
+ }),
218
+ repetents: z .string (),
219
+ teacherCopy: z .boolean (),
220
+ })
221
+
222
+ type Schema = z .output <typeof schema >
223
+
224
+ const state = reactive ({
225
+ schoolClass: undefined ,
226
+ repetents: undefined ,
227
+ teacherCopy: undefined ,
228
+ })
229
+
230
+ const { data : years } = await useLazyFetch <APIResponseArray <Year >>(" /years" , {
231
+ baseURL: config .public .baseURL ,
232
+ })
233
+
234
+ async function addBookOrder(event : FormSubmitEvent <Schema >) {
235
+ if (years .value == null || years .value .data == undefined ) {
236
+ return
237
+ }
238
+
239
+ const bookOrders: BookOrderDTO [] = []
240
+
241
+ selectedRows .value .forEach ((row ) => {
242
+ let count = 0
243
+
244
+ switch (event .data .repetents ) {
245
+ case " With" :
246
+ count =
247
+ event .data .schoolClass .students + event .data .schoolClass .repetents
248
+ break
249
+ case " Without" :
250
+ count = event .data .schoolClass .students
251
+ break
252
+ case " Only" :
253
+ count = event .data .schoolClass .repetents
254
+ break
255
+ }
256
+
257
+ if (event .data .teacherCopy ) count ++
258
+
259
+ bookOrders .push ({
260
+ count: count ,
261
+ teacherCopy: event .data .teacherCopy ,
262
+ schoolClass: event .data .schoolClass .id ,
263
+ book: row .id ,
264
+ year: row .year .id ,
265
+ lastUser: " User 0" ,
266
+ creationUser: " User 0" ,
267
+ })
268
+ })
269
+
270
+ for (const bookOrder of bookOrders ) {
271
+ await $fetch (" bookOrders/create" , {
272
+ method: " POST" ,
273
+ body: bookOrder ,
274
+ baseURL: config .public .baseURL ,
275
+ })
276
+ }
277
+ isVisible .value = false
278
+
279
+ const toast = useToast ()
280
+
281
+ toast .add ({
282
+ title: t (" bookList.order.success" ),
283
+ description: t (" bookList.order.successDescription" ),
284
+ icon: " i-heroicons-check-circle" ,
285
+ })
286
+ }
287
+
288
+ const repententOptions = [
289
+ { label: " With" , value: 1 },
290
+ { label: " Without" , value: 2 },
291
+ { label: " Only" , value: 3 },
292
+ ]
192
293
</script >
193
294
194
295
<template >
@@ -215,6 +316,13 @@ watch(
215
316
icon =" i-heroicons-magnifying-glass-20-solid"
216
317
:placeholder =" $t('bookList.searchForBooks')"
217
318
/>
319
+ <UButton
320
+ label =" Order"
321
+ class =" ml-2"
322
+ size =" md"
323
+ :disabled =" selectedRows.length === 0"
324
+ @click =" isVisible = true"
325
+ />
218
326
</div >
219
327
220
328
<div class =" flex items-center gap-2" >
@@ -260,7 +368,7 @@ watch(
260
368
:progress =" { color: 'primary', animation: 'carousel' }"
261
369
:columns =" columnsTable"
262
370
:ui =" {
263
- wrapper: 'relative overflow-x-auto h-[500px ] overflow-y-auto',
371
+ wrapper: 'relative overflow-x-auto h-[450px ] overflow-y-auto',
264
372
td: {
265
373
padding: 'py-1',
266
374
},
@@ -374,4 +482,90 @@ watch(
374
482
</div >
375
483
</template >
376
484
</UCard >
485
+ <UModal v-model =" isVisible" class =" bg-opacity-0" >
486
+ <UCard >
487
+ <template #header >
488
+ <div class =" flex items-center" >
489
+ <span
490
+ class =" text-base font-semibold leading-6 text-red-600 dark:text-white"
491
+ >
492
+ Ordering
493
+ </span >
494
+ <UButton
495
+ color =" gray"
496
+ variant =" ghost"
497
+ icon =" i-heroicons-x-mark-20-solid"
498
+ class =" ml-auto"
499
+ @click =" isVisible = false"
500
+ />
501
+ </div >
502
+ </template >
503
+ <h1 >Books</h1 >
504
+ <UTable
505
+ class =" mb-4 rounded-lg border-2"
506
+ :rows =" selectedRows"
507
+ :loading-state =" {
508
+ icon: 'i-heroicons-arrow-path-20-solid',
509
+ label: 'Loading...',
510
+ }"
511
+ :loading =" pending"
512
+ :progress =" { color: 'primary', animation: 'carousel' }"
513
+ :columns =" [
514
+ {
515
+ key: 'title',
516
+ },
517
+ ]"
518
+ :ui =" {
519
+ wrapper: 'relative overflow-x-auto h-[150px] overflow-y-auto',
520
+ td: {
521
+ padding: 'py-1',
522
+ },
523
+ th: {
524
+ base: 'hidden',
525
+ },
526
+ }"
527
+ />
528
+
529
+ <UForm
530
+ :schema =" schema"
531
+ :state =" state"
532
+ class =" space-y-4"
533
+ @submit =" addBookOrder"
534
+ >
535
+ <UFormGroup label =" Class" name =" schoolClass" >
536
+ <USelectMenu
537
+ v-if =" !schoolClassesPending"
538
+ v-model =" state.schoolClass"
539
+ placeholder =" Select a class"
540
+ :options =" schoolClasses?.data"
541
+ option-attribute =" name"
542
+ searchable
543
+ />
544
+ </UFormGroup >
545
+
546
+ <UFormGroup label =" Repetents" name =" repetents" >
547
+ <USelectMenu
548
+ v-model =" state.repetents"
549
+ class =" mt-4"
550
+ placeholder =" Order for repetents"
551
+ :options =" repententOptions"
552
+ option-attribute =" label"
553
+ value-attribute =" label"
554
+ />
555
+ </UFormGroup >
556
+
557
+ <UFormGroup label =" Teacher copy" name =" teacherCopy" >
558
+ <UCheckbox
559
+ v-model =" state.teacherCopy"
560
+ class =" mt-4"
561
+ color =" blue"
562
+ label =" Teacher copy"
563
+ help =" Get an extra copy for the teacher"
564
+ />
565
+ </UFormGroup >
566
+
567
+ <UButton type =" submit" > Submit</UButton >
568
+ </UForm >
569
+ </UCard >
570
+ </UModal >
377
571
</template >
0 commit comments