@@ -9,7 +9,7 @@ import Tooltip from "../primitives/Tooltip";
9
9
import AddUser from "../components/AddUser" ;
10
10
import SubscribeCard from "../primitives/SubscribeCard" ;
11
11
import { isEnableSubscription } from "../constant/const" ;
12
- import { checkIsSubscribed } from "../constant/Utils" ;
12
+ import { fetchSubscriptionInfo } from "../constant/Utils" ;
13
13
import Title from "../components/Title" ;
14
14
import { validplan } from "../json/plansArr" ;
15
15
import { useTranslation } from "react-i18next" ;
@@ -19,17 +19,28 @@ const UserList = () => {
19
19
const { t } = useTranslation ( ) ;
20
20
const [ userList , setUserList ] = useState ( [ ] ) ;
21
21
const [ isLoader , setIsLoader ] = useState ( false ) ;
22
- const [ isModal , setIsModal ] = useState ( false ) ;
22
+ const [ isModal , setIsModal ] = useState ( {
23
+ form : false ,
24
+ addseats : false ,
25
+ options : false
26
+ } ) ;
23
27
const location = useLocation ( ) ;
24
28
const isDashboard =
25
29
location ?. pathname === "/dashboard/35KBoSgoAK" ? true : false ;
26
30
const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
27
31
const [ isAlert , setIsAlert ] = useState ( { type : "success" , msg : "" } ) ;
28
32
const [ isActiveModal , setIsActiveModal ] = useState ( { } ) ;
29
33
const [ isActLoader , setIsActLoader ] = useState ( { } ) ;
30
- const [ isSubscribe , setIsSubscribe ] = useState ( { plan : "" , isValid : false } ) ;
34
+ const [ isSubscribe , setIsSubscribe ] = useState ( {
35
+ plan : "" ,
36
+ isValid : false ,
37
+ priceperUser : 0
38
+ } ) ;
31
39
const [ isAdmin , setIsAdmin ] = useState ( false ) ;
32
40
const [ formHeader , setFormHeader ] = useState ( t ( "add-user" ) ) ;
41
+ const [ usersCount , setUserCounts ] = useState ( { allowed : 0 , totalAllowed : 0 } ) ;
42
+ const [ amount , setAmount ] = useState ( { quantity : 1 , price : 0 } ) ;
43
+ const [ isBuyLoader , setIsBuyLoader ] = useState ( false ) ;
33
44
const recordperPage = 10 ;
34
45
const startIndex = ( currentPage - 1 ) * recordperPage ; // user per page
35
46
@@ -81,7 +92,6 @@ const UserList = () => {
81
92
pages . push ( lastPageIndex ) ;
82
93
}
83
94
}
84
-
85
95
return pages ;
86
96
} ;
87
97
const pageNumbers = getPaginationRange ( ) ;
@@ -96,13 +106,44 @@ const UserList = () => {
96
106
async function fetchUserList ( ) {
97
107
try {
98
108
setIsLoader ( true ) ;
109
+ const extUser =
110
+ localStorage . getItem ( "Extand_Class" ) &&
111
+ JSON . parse ( localStorage . getItem ( "Extand_Class" ) ) ?. [ 0 ] ;
99
112
if ( isEnableSubscription ) {
100
- const subscribe = await checkIsSubscribed ( ) ;
101
- setIsSubscribe ( subscribe ) ;
113
+ const subscribe = await fetchSubscriptionInfo ( ) ;
114
+ if ( subscribe ?. plan_code ?. includes ( "team" ) ) {
115
+ const isSupAdmin =
116
+ subscribe ?. adminId && extUser ?. objectId === subscribe ?. adminId ;
117
+ setIsSubscribe ( {
118
+ plan : subscribe . plan_code ,
119
+ isValid : true ,
120
+ adminId : subscribe . adminId ,
121
+ priceperUser : subscribe . price ,
122
+ isSuperAdmin : isSupAdmin
123
+ } ) ;
124
+ setAmount ( ( prev ) => ( { ...prev , price : subscribe . price } ) ) ;
125
+ try {
126
+ const res = await Parse . Cloud . run ( "allowedusers" ) ;
127
+ console . log ( "res " , res ) ;
128
+ setUserCounts ( ( obj ) => ( {
129
+ ...obj ,
130
+ allowed : res ,
131
+ totalAllowed : subscribe ?. totalAllowedUser || 0
132
+ } ) ) ;
133
+ } catch ( err ) {
134
+ console . log ( "err while get users" , err ) ;
135
+ }
136
+ } else {
137
+ setIsSubscribe ( {
138
+ plan : subscribe . plan_code ,
139
+ isValid : false ,
140
+ adminId : subscribe . adminId
141
+ } ) ;
142
+ }
102
143
} else {
103
144
setIsSubscribe ( { plan : "teams-yearly" , isValid : true } ) ;
104
145
}
105
- const extUser = JSON . parse ( localStorage . getItem ( "Extand_Class" ) ) ?. [ 0 ] ;
146
+
106
147
if ( extUser ) {
107
148
const admin =
108
149
extUser ?. UserRole &&
@@ -121,14 +162,12 @@ const UserList = () => {
121
162
console . log ( "Err in fetch userlist" , err ) ;
122
163
setIsAlert ( { type : "danger" , msg : t ( "something-went-wrong-mssg" ) } ) ;
123
164
} finally {
124
- setTimeout ( ( ) => {
125
- setIsAlert ( { type : "success" , msg : "" } ) ;
126
- } , 1500 ) ;
165
+ setTimeout ( ( ) => setIsAlert ( { type : "success" , msg : "" } ) , 1500 ) ;
127
166
setIsLoader ( false ) ;
128
167
}
129
168
}
130
- const handleFormModal = ( ) => {
131
- setIsModal ( ! isModal ) ;
169
+ const handleModal = ( modalName ) => {
170
+ setIsModal ( ( obj ) => ( { ... obj , [ modalName ] : ! obj [ modalName ] } ) ) ;
132
171
} ;
133
172
134
173
// Change page
@@ -196,6 +235,39 @@ const UserList = () => {
196
235
const handleToggleBtn = ( user ) => {
197
236
setIsActiveModal ( { [ user . objectId ] : true } ) ;
198
237
} ;
238
+
239
+ const handleAddOnSubmit = async ( e ) => {
240
+ e . preventDefault ( ) ;
241
+ e . stopPropagation ( ) ;
242
+ setIsBuyLoader ( true ) ;
243
+ try {
244
+ const resAddon = await Parse . Cloud . run ( "buyaddonusers" , {
245
+ users : amount . quantity
246
+ } ) ;
247
+ if ( resAddon ) {
248
+ const _resAddon = JSON . parse ( JSON . stringify ( resAddon ) ) ;
249
+ if ( _resAddon . status === "success" ) {
250
+ setUserCounts ( ( obj ) => ( {
251
+ ...obj ,
252
+ allowed : obj . allowed + amount . quantity ,
253
+ totalAllowed : _resAddon . addon
254
+ } ) ) ;
255
+ }
256
+ }
257
+ } catch ( err ) {
258
+ console . log ( "Err in buy addon" , err ) ;
259
+ setIsAlert ( { type : "danger" , msg : t ( "something-went-wrong-mssg" ) } ) ;
260
+ } finally {
261
+ setTimeout ( ( ) => setIsAlert ( { type : "success" , msg : "" } ) , 2000 ) ;
262
+ setIsBuyLoader ( false ) ;
263
+ handleModal ( "addseats" ) ;
264
+ }
265
+ } ;
266
+ const handlePricePerUser = ( e ) => {
267
+ const quantity = e . target . value ;
268
+ const price = e . target ?. value > 0 ? isSubscribe . priceperUser * quantity : 0 ;
269
+ setAmount ( ( prev ) => ( { ...prev , quantity : quantity , price : price } ) ) ;
270
+ } ;
199
271
return (
200
272
< div className = "relative" >
201
273
< Title title = { isAdmin ? "Users" : "Page not found" } />
@@ -205,7 +277,7 @@ const UserList = () => {
205
277
</ div >
206
278
) }
207
279
{ Object . keys ( isActLoader ) ?. length > 0 && (
208
- < div className = "absolute w-full h-full flex justify-center items-center bg-black bg-opacity- 30 z-30 rounded-box" >
280
+ < div className = "absolute w-full h-full flex justify-center items-center bg-black/ 30 z-30 rounded-box" >
209
281
< Loader />
210
282
</ div >
211
283
) }
@@ -216,19 +288,46 @@ const UserList = () => {
216
288
{ isAlert . msg && < Alert type = { isAlert . type } > { isAlert . msg } </ Alert > }
217
289
< div className = "flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]" >
218
290
< div className = "font-light" >
219
- { t ( "report-name.Users" ) }
291
+ { t ( "report-name.Users" ) } { " " }
220
292
< span className = "text-xs md:text-[13px] font-normal" >
221
293
< Tooltip message = { t ( "users-from-teams" ) } />
222
294
</ span >
223
295
</ div >
224
- < div
225
- className = "cursor-pointer"
226
- onClick = { ( ) => handleFormModal ( ) }
227
- >
228
- < i className = "fa-light fa-square-plus text-accent text-[40px]" > </ i >
296
+ < div className = "flex flex-row gap-2 items-center" >
297
+ { isEnableSubscription && isSubscribe ?. isSuperAdmin && (
298
+ < div
299
+ className = "hidden md:flex op-btn op-btn-sm h-[35px] op-btn-primary op-btn-outline text-xs mb-0.5"
300
+ onClick = { ( ) => handleModal ( "addseats" ) }
301
+ >
302
+ { t ( "buy-users" ) }
303
+ </ div >
304
+ ) }
305
+ < div
306
+ className = "cursor-pointer"
307
+ onClick = { ( ) => handleModal ( "form" ) }
308
+ >
309
+ < i className = "fa-light fa-square-plus text-accent text-[30px] md:text-[40px]" > </ i >
310
+ </ div >
311
+ { isEnableSubscription && isSubscribe ?. isSuperAdmin && (
312
+ < div
313
+ className = "cursor-pointer relative md:hidden mb-0.5"
314
+ onClick = { ( ) => handleModal ( "options" ) }
315
+ >
316
+ < i className = "fa-light fa-ellipsis-vertical fa-xl" > </ i >
317
+ { isModal ?. options && (
318
+ < ul className = "absolute -right-3 top-auto z-[70] w-max op-menu op-menu-xs shadow bg-base-100 text-base-content rounded-box border" >
319
+ < li onClick = { ( ) => handleModal ( "addseats" ) } >
320
+ < span className = "text-[13px] capitalize font-medium" >
321
+ { t ( "buy-users" ) }
322
+ </ span >
323
+ </ li >
324
+ </ ul >
325
+ ) }
326
+ </ div >
327
+ ) }
229
328
</ div >
230
329
</ div >
231
- < div className = { ` overflow-x-auto w-full` } >
330
+ < div className = " overflow-x-auto w-full" >
232
331
< table className = "op-table border-collapse w-full" >
233
332
< thead className = "text-[14px]" >
234
333
< tr className = "border-y-[1px]" >
@@ -313,34 +412,42 @@ const UserList = () => {
313
412
</ tbody >
314
413
</ table >
315
414
</ div >
316
- < div className = "op-join flex flex-wrap items-center p-2" >
317
- { userList . length > recordperPage && (
318
- < button
319
- onClick = { ( ) => paginateBack ( ) }
320
- className = "op-join-item op-btn op-btn-sm"
321
- >
322
- { t ( "prev" ) }
323
- </ button >
324
- ) }
325
- { pageNumbers . map ( ( x , i ) => (
326
- < button
327
- key = { i }
328
- onClick = { ( ) => setCurrentPage ( x ) }
329
- disabled = { x === "..." }
330
- className = { `${
331
- x === currentPage ? "op-btn-active" : ""
332
- } op-join-item op-btn op-btn-sm`}
333
- >
334
- { x }
335
- </ button >
336
- ) ) }
337
- { userList . length > recordperPage && (
338
- < button
339
- onClick = { ( ) => paginateFront ( ) }
340
- className = "op-join-item op-btn op-btn-sm"
341
- >
342
- { t ( "next" ) }
343
- </ button >
415
+ < div className = "flex flex-row justify-between items-center text-xs font-medium" >
416
+ < div className = "op-join flex flex-wrap items-center p-2" >
417
+ { userList . length > recordperPage && (
418
+ < button
419
+ onClick = { ( ) => paginateBack ( ) }
420
+ className = "op-join-item op-btn op-btn-sm"
421
+ >
422
+ { t ( "prev" ) }
423
+ </ button >
424
+ ) }
425
+ { pageNumbers . map ( ( x , i ) => (
426
+ < button
427
+ key = { i }
428
+ onClick = { ( ) => setCurrentPage ( x ) }
429
+ disabled = { x === "..." }
430
+ className = { `${
431
+ x === currentPage ? "op-btn-active" : ""
432
+ } op-join-item op-btn op-btn-sm`}
433
+ >
434
+ { x }
435
+ </ button >
436
+ ) ) }
437
+ { userList . length > recordperPage && (
438
+ < button
439
+ onClick = { ( ) => paginateFront ( ) }
440
+ className = "op-join-item op-btn op-btn-sm"
441
+ >
442
+ { t ( "next" ) }
443
+ </ button >
444
+ ) }
445
+ </ div >
446
+ { isEnableSubscription && isSubscribe ?. isSuperAdmin && (
447
+ < div >
448
+ { t ( "available-seats" ) } : { usersCount . allowed } /
449
+ { usersCount . totalAllowed }
450
+ </ div >
344
451
) }
345
452
</ div >
346
453
{ userList ?. length <= 0 && (
@@ -362,17 +469,59 @@ const UserList = () => {
362
469
</ div >
363
470
) }
364
471
< ModalUi
365
- isOpen = { isModal }
472
+ isOpen = { isModal . form }
366
473
title = { formHeader }
367
- handleClose = { handleFormModal }
474
+ handleClose = { ( ) => handleModal ( "form" ) }
368
475
>
369
476
< AddUser
370
477
setIsAlert = { setIsAlert }
371
478
handleUserData = { handleUserData }
372
- closePopup = { handleFormModal }
479
+ closePopup = { ( ) => handleModal ( "form" ) }
373
480
setFormHeader = { setFormHeader }
374
481
/>
375
482
</ ModalUi >
483
+ < ModalUi
484
+ isOpen = { isModal . addseats }
485
+ title = "Add Seats"
486
+ handleClose = { ( ) => handleModal ( "addseats" ) }
487
+ >
488
+ { isBuyLoader && (
489
+ < div className = "absolute w-full h-full inset-0 flex justify-center items-center bg-base-content/30 z-50" >
490
+ < Loader />
491
+ </ div >
492
+ ) }
493
+ < form onSubmit = { handleAddOnSubmit } className = " px-3 pb-6 pt-6" >
494
+ < div className = "mb-3 flex justify-between" >
495
+ < label
496
+ htmlFor = "quantity"
497
+ className = "block text-xs text-gray-700 font-semibold"
498
+ >
499
+ { t ( "Quantity-of-users" ) }
500
+ < span className = "text-[red] text-[13px]" > *</ span >
501
+ </ label >
502
+ < input
503
+ type = "number"
504
+ name = "quantity"
505
+ value = { amount . quantity }
506
+ onChange = { ( e ) => handlePricePerUser ( e ) }
507
+ className = "w-1/4 op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-xs"
508
+ required
509
+ />
510
+ </ div >
511
+ < div className = "mb-3 flex justify-between" >
512
+ < label className = "block text-xs text-gray-700 font-semibold" >
513
+ { t ( "Price" ) } (1 * { isSubscribe . priceperUser } )
514
+ </ label >
515
+ < div className = "w-1/4 flex justify-center items-center text-sm" >
516
+ USD { amount . price }
517
+ </ div >
518
+ </ div >
519
+ < hr className = "text-base-content mb-3" />
520
+ < button className = "op-btn op-btn-primary w-full" >
521
+ { t ( "Proceed" ) }
522
+ </ button >
523
+ </ form >
524
+ </ ModalUi >
376
525
</ div >
377
526
) : (
378
527
< div className = "flex items-center justify-center h-screen w-full bg-base-100 text-base-content rounded-box" >
0 commit comments