1- import React from 'react'
1+ import React , { useEffect , useState } from 'react'
22
33import { UsersIcon } from '@gitmono/ui'
44
5+ import { AdminGroupEditDialog } from './AdminGroupEditDialog'
6+
57interface GroupItem {
68 id : number
79 name : string
@@ -14,64 +16,106 @@ interface AdminGroupItemProps {
1416 group : GroupItem
1517 onDelete : ( id : number ) => void
1618 onManageMembers : ( id : number ) => void
17- onEdit ?: ( id : number ) => void
19+ onUpdate ?: ( ) => void
1820}
1921
20- export const AdminGroupItem = ( { group, onDelete, onManageMembers, onEdit } : AdminGroupItemProps ) => {
21- const createdDate = new Date ( group . created_at * 1000 ) . toLocaleDateString ( )
22+ export const AdminGroupItem = ( { group, onDelete, onManageMembers, onUpdate } : AdminGroupItemProps ) => {
23+ const [ isEditDialogOpen , setIsEditDialogOpen ] = useState ( false )
24+ const [ localGroup , setLocalGroup ] = useState ( group )
25+ const [ isUpdating , setIsUpdating ] = useState ( false )
26+ const createdDate = new Date ( localGroup . created_at * 1000 ) . toLocaleDateString ( )
2227
23- return (
24- < div className = 'border-primary flex items-center justify-between border-b py-6 transition-colors duration-200 last:border-b-0 hover:bg-gray-50 dark:hover:bg-gray-800/50' >
25- < div className = 'flex items-start' >
26- < div className = 'mr-4 rounded-lg bg-blue-100 p-3 dark:bg-blue-900/30' >
27- < UsersIcon className = 'h-6 w-6 text-blue-600 dark:text-blue-400' aria-hidden = 'true' />
28- </ div >
29- < div >
30- < p className = 'text-primary mb-1 text-lg font-bold' > { group . name } </ p >
31- < div className = 'text-tertiary space-y-1 text-sm' >
32- { group . description && < p className = 'max-w-md text-gray-600 dark:text-gray-400' > { group . description } </ p > }
33- < p className = 'text-xs text-gray-500 dark:text-gray-500' > Created: { createdDate } </ p >
34- </ div >
35- </ div >
36- </ div >
28+ useEffect ( ( ) => {
29+ setLocalGroup ( group )
30+ setIsUpdating ( false )
31+ } , [ group ] )
32+
33+ const handleEditSuccess = ( updatedData : { name : string ; description : string | null } ) => {
34+ setLocalGroup ( ( prev ) => ( {
35+ ...prev ,
36+ name : updatedData . name ,
37+ description : updatedData . description ,
38+ updated_at : Math . floor ( Date . now ( ) / 1000 )
39+ } ) )
3740
38- < div className = 'flex min-w-0 flex-col gap-3' >
39- { /* Group operations - first row */ }
40- < div className = 'flex items-center gap-4' >
41- < div className = 'w-[30%]' >
42- < span className = 'text-sm font-medium text-gray-600 dark:text-gray-400' > Group:</ span >
41+ setIsUpdating ( true )
42+
43+ onUpdate ?.( )
44+
45+ setTimeout ( ( ) => {
46+ setIsUpdating ( false )
47+ } , 3000 )
48+ }
49+
50+ return (
51+ < >
52+ < div className = 'border-primary flex items-center justify-between border-b py-6 transition-colors duration-200 last:border-b-0 hover:bg-gray-50 dark:hover:bg-gray-800/50' >
53+ < div className = 'flex items-start' >
54+ < div className = 'mr-4 rounded-lg bg-blue-100 p-3 dark:bg-blue-900/30' >
55+ < UsersIcon className = 'h-6 w-6 text-blue-600 dark:text-blue-400' aria-hidden = 'true' />
4356 </ div >
44- < div className = 'flex w-[70%] justify-between gap-2' >
45- < button
46- className = 'border-primary flex-1 rounded-md border px-4 py-1 text-sm font-semibold text-blue-600 transition-colors duration-200 hover:bg-blue-600 hover:text-white'
47- onClick = { ( ) => onEdit ?.( group . id ) }
48- >
49- Edit
50- </ button >
51- < button
52- className = 'border-primary flex-1 rounded-md border px-4 py-1 text-sm font-semibold text-red-500 transition-colors duration-200 hover:bg-red-500 hover:text-white'
53- onClick = { ( ) => onDelete ( group . id ) }
54- >
55- Delete
56- </ button >
57+ < div className = 'flex-1' >
58+ < div className = 'flex items-center gap-2' >
59+ < p className = 'text-primary mb-1 text-lg font-bold' > { localGroup . name } </ p >
60+ { isUpdating && (
61+ < div className = 'flex items-center gap-1' >
62+ < div className = 'h-3 w-3 animate-spin rounded-full border border-green-500 border-t-transparent' > </ div >
63+ < span className = 'text-xs text-green-600' > Updated</ span >
64+ </ div >
65+ ) }
66+ </ div >
67+ < div className = 'text-tertiary space-y-1 text-sm' >
68+ { localGroup . description && (
69+ < p className = 'max-w-md text-gray-600 dark:text-gray-400' > { localGroup . description } </ p >
70+ ) }
71+ < p className = 'text-xs text-gray-500 dark:text-gray-500' > Created: { createdDate } </ p >
72+ </ div >
5773 </ div >
5874 </ div >
5975
60- { /* Member operations - second row */ }
61- < div className = 'flex items-center gap-4' >
62- < div className = 'w-[30%]' >
63- < span className = 'text-sm font-medium text-gray-600 dark:text-gray-400' > Members:</ span >
76+ < div className = 'flex min-w-0 flex-col gap-3' >
77+ < div className = 'flex items-center gap-4' >
78+ < div className = 'w-[30%]' >
79+ < span className = 'text-sm font-medium text-gray-600 dark:text-gray-400' > Group:</ span >
80+ </ div >
81+ < div className = 'flex w-[70%] justify-between gap-2' >
82+ < button
83+ className = 'border-primary flex-1 rounded-md border px-4 py-1 text-sm font-semibold text-blue-600 transition-colors duration-200 hover:bg-blue-600 hover:text-white'
84+ onClick = { ( ) => setIsEditDialogOpen ( true ) }
85+ >
86+ Edit
87+ </ button >
88+ < button
89+ className = 'border-primary flex-1 rounded-md border px-4 py-1 text-sm font-semibold text-red-500 transition-colors duration-200 hover:bg-red-500 hover:text-white'
90+ onClick = { ( ) => onDelete ( group . id ) }
91+ >
92+ Delete
93+ </ button >
94+ </ div >
6495 </ div >
65- < div className = 'flex w-[70%] justify-between' >
66- < button
67- className = 'border-primary w-full rounded-md border px-4 py-1 text-sm font-semibold text-purple-600 transition-colors duration-200 hover:bg-purple-600 hover:text-white'
68- onClick = { ( ) => onManageMembers ( group . id ) }
69- >
70- Manage Members
71- </ button >
96+
97+ < div className = 'flex items-center gap-4' >
98+ < div className = 'w-[30%]' >
99+ < span className = 'text-sm font-medium text-gray-600 dark:text-gray-400' > Members:</ span >
100+ </ div >
101+ < div className = 'flex w-[70%] justify-between' >
102+ < button
103+ className = 'border-primary w-full rounded-md border px-4 py-1 text-sm font-semibold text-purple-600 transition-colors duration-200 hover:bg-purple-600 hover:text-white'
104+ onClick = { ( ) => onManageMembers ( group . id ) }
105+ >
106+ Manage Members
107+ </ button >
108+ </ div >
72109 </ div >
73110 </ div >
74111 </ div >
75- </ div >
112+
113+ < AdminGroupEditDialog
114+ open = { isEditDialogOpen }
115+ onOpenChange = { setIsEditDialogOpen }
116+ groupId = { localGroup . id }
117+ onSuccess = { handleEditSuccess }
118+ />
119+ </ >
76120 )
77121}
0 commit comments