6
6
EditableInput ,
7
7
EditablePreview ,
8
8
Flex ,
9
+ FormControl ,
9
10
IconButton ,
10
11
Input ,
11
12
Switch ,
@@ -14,8 +15,10 @@ import {
14
15
useEditableControls ,
15
16
useToast ,
16
17
} from "@chakra-ui/react" ;
17
- import { Assignment , Location } from "@prisma/client" ;
18
+
19
+ import { Assignment , Category , Location } from "@prisma/client" ;
18
20
import { UseTRPCMutationResult } from "@trpc/react/shared" ;
21
+ import { MultiValue , Select , SingleValue } from "chakra-react-select" ;
19
22
import { useState } from "react" ;
20
23
import { FaEye , FaEyeSlash } from "react-icons/fa" ;
21
24
import { DARK_GRAY_COLOR } from "../../utils/constants" ;
@@ -73,15 +76,47 @@ const AdminCard = (props: AdminCardProps) => {
73
76
const [ isPriority , setIsPriority ] = useState (
74
77
isAssignment ? ( assignmentOrLocation as Assignment ) . isPriority : false ,
75
78
) ;
79
+ const [ assignmentCategoryId , setAssignmentCategoryId ] = useState (
80
+ isAssignment ? ( assignmentOrLocation as Assignment ) . categoryId : undefined ,
81
+ ) ;
82
+ const [ locationCategoryIds , setLocationCategoryIds ] = useState < number [ ] > ( ) ;
83
+ const [ allCategories , setAllCategories ] = useState < Category [ ] > ( ) ;
84
+
76
85
const context = trpc . useContext ( ) ;
77
86
const toast = useToast ( ) ;
78
87
88
+ trpc . admin . getCategoriesForLocation . useQuery (
89
+ {
90
+ locationId : isAssignment
91
+ ? undefined
92
+ : ( assignmentOrLocation as Location ) . id ,
93
+ } ,
94
+ {
95
+ refetchOnWindowFocus : false ,
96
+ onSuccess : ( data ) => {
97
+ setLocationCategoryIds ( data ?. categories . map ( ( category ) => category . id ) ) ;
98
+ } ,
99
+ enabled : ! isAssignment ,
100
+ } ,
101
+ ) ;
102
+
103
+ trpc . admin . getAllCategories . useQuery ( undefined , {
104
+ refetchOnWindowFocus : false ,
105
+ onSuccess : ( data ) => {
106
+ setAllCategories ( data ) ;
107
+ } ,
108
+ } ) ;
109
+
79
110
const handleNameChange = async ( newName : string ) => {
80
111
await editMutation . mutateAsync ( {
81
112
id : assignmentOrLocation . id ,
82
113
name : newName ,
83
114
isActive : assignmentOrLocation . isActive ,
84
115
isHidden : assignmentOrLocation . isHidden ,
116
+ categoryId : isAssignment
117
+ ? ( assignmentOrLocation as Assignment ) . categoryId
118
+ : undefined ,
119
+ categoryIds : isAssignment ? undefined : locationCategoryIds ,
85
120
} ) ;
86
121
} ;
87
122
@@ -93,6 +128,10 @@ const AdminCard = (props: AdminCardProps) => {
93
128
isActive : assignmentOrLocation . isActive ,
94
129
isHidden : assignmentOrLocation . isHidden ,
95
130
isPriority : newPriority ,
131
+ categoryId : isAssignment
132
+ ? ( assignmentOrLocation as Assignment ) . categoryId
133
+ : undefined ,
134
+ categoryIds : isAssignment ? undefined : locationCategoryIds ,
96
135
} ) ;
97
136
} ;
98
137
@@ -105,6 +144,10 @@ const AdminCard = (props: AdminCardProps) => {
105
144
name : assignmentOrLocation . name ,
106
145
isActive : newActive ,
107
146
isHidden : newActive ? false : isHidden ,
147
+ categoryId : isAssignment
148
+ ? ( assignmentOrLocation as Assignment ) . categoryId
149
+ : undefined ,
150
+ categoryIds : isAssignment ? undefined : locationCategoryIds ,
108
151
} )
109
152
. then ( ( ) => {
110
153
context . admin . getAllLocations . invalidate ( ) ;
@@ -130,6 +173,62 @@ const AdminCard = (props: AdminCardProps) => {
130
173
name : assignmentOrLocation . name ,
131
174
isActive : assignmentOrLocation . isActive ,
132
175
isHidden : ! isHidden ,
176
+ categoryId : isAssignment
177
+ ? ( assignmentOrLocation as Assignment ) . categoryId
178
+ : undefined ,
179
+ categoryIds : isAssignment ? undefined : locationCategoryIds ,
180
+ } )
181
+ . then ( ( ) => {
182
+ context . admin . getAllLocations . invalidate ( ) ;
183
+ context . admin . getAllAssignments . invalidate ( ) ;
184
+ } )
185
+ . catch ( ( err ) => {
186
+ toast ( {
187
+ title : "Error" ,
188
+ description : err . message ,
189
+ status : "error" ,
190
+ duration : 3000 ,
191
+ isClosable : true ,
192
+ position : "top-right" ,
193
+ } ) ;
194
+ } ) ;
195
+ } ;
196
+
197
+ const handleAssignmentCategoryChange = async ( categoryId : number ) => {
198
+ setAssignmentCategoryId ( categoryId ) ;
199
+ await editMutation
200
+ . mutateAsync ( {
201
+ id : assignmentOrLocation . id ,
202
+ name : assignmentOrLocation . name ,
203
+ isActive : isActive ,
204
+ isHidden : isHidden ,
205
+ categoryId : categoryId ,
206
+ } )
207
+ . then ( ( ) => {
208
+ context . admin . getAllLocations . invalidate ( ) ;
209
+ context . admin . getAllAssignments . invalidate ( ) ;
210
+ } )
211
+ . catch ( ( err ) => {
212
+ toast ( {
213
+ title : "Error" ,
214
+ description : err . message ,
215
+ status : "error" ,
216
+ duration : 3000 ,
217
+ isClosable : true ,
218
+ position : "top-right" ,
219
+ } ) ;
220
+ } ) ;
221
+ } ;
222
+
223
+ const handleLocationCategoriesChange = async ( categoryIds : number [ ] ) => {
224
+ setLocationCategoryIds ( categoryIds ) ;
225
+ await editMutation
226
+ . mutateAsync ( {
227
+ id : assignmentOrLocation . id ,
228
+ name : assignmentOrLocation . name ,
229
+ isActive : isActive ,
230
+ isHidden : isHidden ,
231
+ categoryIds : categoryIds ,
133
232
} )
134
233
. then ( ( ) => {
135
234
context . admin . getAllLocations . invalidate ( ) ;
@@ -160,59 +259,114 @@ const AdminCard = (props: AdminCardProps) => {
160
259
backgroundColor = { boxColor }
161
260
justifyContent = "space-between"
162
261
>
163
- < Flex >
164
- < Editable
165
- onSubmit = { handleNameChange }
166
- textAlign = "center"
167
- fontWeight = "semibold"
168
- display = "flex"
169
- defaultValue = { assignmentOrLocation . name }
170
- fontSize = "xl"
171
- isPreviewFocusable = { false }
172
- >
173
- < EditablePreview />
174
- < Input as = { EditableInput } />
175
- < EditableControls />
176
- </ Editable >
177
- < Text fontSize = "large" mt = { 1.5 } ml = { 5 } >
178
- Active?
179
- </ Text >
180
- < Switch
181
- onChange = { handleActiveChange }
182
- mt = { 2.5 }
183
- ml = { 3 }
184
- isChecked = { isActive }
185
- />
186
- </ Flex >
187
- < Checkbox
188
- hidden = { ! isActive || ! isAssignment }
189
- onChange = { ( ) => handlePriorityChange ( ! isPriority ) }
190
- colorScheme = "telegram"
191
- size = "lg"
192
- ml = { 2 }
193
- isChecked = { isPriority }
194
- >
195
- Priority
196
- </ Checkbox >
197
- { ! isActive && (
198
- < Flex >
199
- { isHidden ? (
200
- < FaEyeSlash
201
- size = "20px"
202
- className = "hover-cursor"
203
- style = { { marginTop : "10px" } }
204
- onClick = { handleHidden }
205
- />
206
- ) : (
207
- < FaEye
208
- size = "20px"
209
- className = "hover-cursor"
210
- style = { { marginTop : "10px" } }
211
- onClick = { handleHidden }
212
- />
213
- ) }
262
+ < >
263
+ < Flex w = "50%" >
264
+ < Editable
265
+ onSubmit = { handleNameChange }
266
+ textAlign = "center"
267
+ fontWeight = "semibold"
268
+ display = "flex"
269
+ defaultValue = { assignmentOrLocation . name }
270
+ fontSize = "xl"
271
+ isPreviewFocusable = { false }
272
+ >
273
+ < EditablePreview />
274
+ < Input as = { EditableInput } />
275
+ < EditableControls />
276
+ </ Editable >
277
+ < Text fontSize = "large" mt = { 1.5 } ml = { 5 } >
278
+ Active?
279
+ </ Text >
280
+ < Switch
281
+ onChange = { handleActiveChange }
282
+ mt = { 2.5 }
283
+ ml = { 3 }
284
+ isChecked = { isActive }
285
+ />
286
+ { /*uppercaseFirstLetter(allCategories?.find((category) => category.id === assignmentCategoryId).name)*/ }
287
+ < FormControl w = { isAssignment ? "30%" : "50%" } ml = { 2 } >
288
+ { isAssignment ? (
289
+ < Select
290
+ options = { allCategories ?. map ( ( category ) => ( {
291
+ label : category . name ,
292
+ value : category . id ,
293
+ } ) ) }
294
+ value = {
295
+ assignmentCategoryId !== undefined
296
+ ? {
297
+ label : allCategories ?. find (
298
+ ( category ) => category . id === assignmentCategoryId ,
299
+ ) ?. name ,
300
+ value : assignmentCategoryId ,
301
+ }
302
+ : { label : "" , value : - 1 }
303
+ }
304
+ onChange = { (
305
+ newValue : SingleValue < {
306
+ label : string | undefined ;
307
+ value : number ;
308
+ } > ,
309
+ ) => handleAssignmentCategoryChange ( newValue ?. value ?? - 1 ) }
310
+ />
311
+ ) : (
312
+ < Select
313
+ isMulti
314
+ options = { allCategories ?. map ( ( category ) => ( {
315
+ label : category . name ,
316
+ value : category . id ,
317
+ } ) ) }
318
+ value = { allCategories
319
+ ?. filter ( ( category ) =>
320
+ locationCategoryIds ?. includes ( category . id ) ,
321
+ )
322
+ ?. map ( ( category ) => ( {
323
+ value : category . id ,
324
+ label : category . name ,
325
+ } ) ) }
326
+ onChange = { (
327
+ newValue : MultiValue < {
328
+ label : string ;
329
+ value : number ;
330
+ } > ,
331
+ ) =>
332
+ handleLocationCategoriesChange (
333
+ newValue . map ( ( item ) => item . value ) ,
334
+ )
335
+ }
336
+ />
337
+ ) }
338
+ </ FormControl >
214
339
</ Flex >
215
- ) }
340
+ < Checkbox
341
+ hidden = { ! isActive || ! isAssignment }
342
+ onChange = { ( ) => handlePriorityChange ( ! isPriority ) }
343
+ colorScheme = "telegram"
344
+ size = "lg"
345
+ ml = { 2 }
346
+ isChecked = { isPriority }
347
+ >
348
+ Priority
349
+ </ Checkbox >
350
+ { ! isActive && (
351
+ < Flex >
352
+ { isHidden ? (
353
+ < FaEyeSlash
354
+ size = "20px"
355
+ className = "hover-cursor"
356
+ style = { { marginTop : "10px" } }
357
+ onClick = { handleHidden }
358
+ />
359
+ ) : (
360
+ < FaEye
361
+ size = "20px"
362
+ className = "hover-cursor"
363
+ style = { { marginTop : "10px" } }
364
+ onClick = { handleHidden }
365
+ />
366
+ ) }
367
+ </ Flex >
368
+ ) }
369
+ </ >
216
370
</ Flex >
217
371
) ;
218
372
} ;
0 commit comments