@ -1,5 +1,5 @@
import { useState , useEffect } from 'react' ;
import { useNavigate } from 'react-router-dom' ;
import { useNavigate , useSearchParams } from 'react-router-dom' ;
import {
Typography ,
Box ,
@ -42,6 +42,12 @@ const ContactListPage = () => {
const [ isLoading , setIsLoading ] = useState ( true ) ;
const theme = useTheme ( ) ;
const navigate = useNavigate ( ) ;
const [ searchParams ] = useSearchParams ( ) ;
// Check if we're in selection mode for group invitations
const isSelectionMode = searchParams . get ( 'mode' ) === 'select' ;
const returnTo = searchParams . get ( 'returnTo' ) ;
const groupId = searchParams . get ( 'groupId' ) ;
useEffect ( ( ) = > {
const loadContacts = async ( ) = > {
@ -70,9 +76,20 @@ const ContactListPage = () => {
} , [ searchQuery , contacts ] ) ;
const handleContactClick = ( contactId : string ) = > {
if ( isSelectionMode ) {
// Don't navigate in selection mode, let the select button handle it
return ;
}
navigate ( ` /contacts/ ${ contactId } ` ) ;
} ;
const handleSelectContact = ( contact : Contact ) = > {
if ( returnTo === 'group-invite' && groupId ) {
// Navigate back to group page with selected contact data
navigate ( ` /groups/ ${ groupId } ?selectedContactName= ${ encodeURIComponent ( contact . name ) } &selectedContactEmail= ${ encodeURIComponent ( contact . email ) } ` ) ;
}
} ;
const handleTabChange = ( _event : React.SyntheticEvent , newValue : number ) = > {
setTabValue ( newValue ) ;
} ;
@ -109,35 +126,42 @@ const ContactListPage = () => {
< Box sx = { { display : 'flex' , justifyContent : 'space-between' , alignItems : 'center' , mb : 3 } } >
< Box >
< Typography variant = "h4" component = "h1" sx = { { fontWeight : 700 , mb : 1 } } >
Contacts
{ isSelectionMode ? 'Select Contact to Invite' : 'Contacts' }
< / Typography >
{ isSelectionMode && (
< Typography variant = "body2" color = "text.secondary" >
Choose a contact from your network to invite to the group
< / Typography >
) }
< / Box >
< Box sx = { { display : 'flex' , gap : 1 , flexWrap : 'wrap' } } >
< Button
variant = "outlined"
startIcon = { < CloudDownload / > }
onClick = { ( ) = > navigate ( '/import' ) }
sx = { { borderRadius : 2 } }
>
Import
< / Button >
< Button
variant = "outlined"
startIcon = { < QrCode / > }
onClick = { handleInvite }
sx = { { borderRadius : 2 } }
>
Invite
< / Button >
< Button
variant = "contained"
startIcon = { < Add / > }
onClick = { handleAddContact }
sx = { { borderRadius : 2 } }
>
Add Contacts
< / Button >
< / Box >
{ ! isSelectionMode && (
< Box sx = { { display : 'flex' , gap : 1 , flexWrap : 'wrap' } } >
< Button
variant = "outlined"
startIcon = { < CloudDownload / > }
onClick = { ( ) = > navigate ( '/import' ) }
sx = { { borderRadius : 2 } }
>
Import
< / Button >
< Button
variant = "outlined"
startIcon = { < QrCode / > }
onClick = { handleInvite }
sx = { { borderRadius : 2 } }
>
Invite
< / Button >
< Button
variant = "contained"
startIcon = { < Add / > }
onClick = { handleAddContact }
sx = { { borderRadius : 2 } }
>
Add Contacts
< / Button >
< / Box >
) }
< / Box >
< Card sx = { { mb : 3 } } >
@ -209,15 +233,15 @@ const ContactListPage = () => {
< Card
onClick = { ( ) = > handleContactClick ( contact . id ) }
sx = { {
cursor : 'pointer' ,
cursor : isSelectionMode ? 'default' : 'pointer' ,
transition : 'all 0.2s ease-in-out' ,
border : 1 ,
borderColor : 'divider' ,
'&:hover' : {
'&:hover' : ! isSelectionMode ? {
borderColor : 'primary.main' ,
boxShadow : theme.shadows [ 4 ] ,
transform : 'translateY(-2px)' ,
} ,
} : { } ,
} }
>
< CardContent sx = { { p : 3 } } >
@ -336,6 +360,25 @@ const ContactListPage = () => {
Added { formatDate ( contact . createdAt ) }
< / Typography >
< / Box >
{ /* Select button for selection mode */ }
{ isSelectionMode && (
< Button
variant = "contained"
onClick = { ( e ) = > {
e . stopPropagation ( ) ;
handleSelectContact ( contact ) ;
} }
sx = { {
borderRadius : 2 ,
textTransform : 'none' ,
alignSelf : 'center' ,
minWidth : 80
} }
>
Select
< / Button >
) }
< / Box >
< / CardContent >
< / Card >