2022-12-18 09:03:41 -08:00
import React , { useCallback , useEffect } from 'react' ;
import { FormattedMessage , defineMessages , useIntl } from 'react-intl' ;
import { authorizeGroupMembershipRequest , fetchGroup , fetchGroupMembershipRequests , rejectGroupMembershipRequest } from 'soapbox/actions/groups' ;
import Account from 'soapbox/components/account' ;
import ScrollableList from 'soapbox/components/scrollable-list' ;
import { Button , Column , HStack , Spinner } from 'soapbox/components/ui' ;
import { useAppDispatch , useAppSelector } from 'soapbox/hooks' ;
import { makeGetAccount , makeGetGroup } from 'soapbox/selectors' ;
2023-01-27 14:04:42 -08:00
import toast from 'soapbox/toast' ;
2022-12-18 09:03:41 -08:00
import ColumnForbidden from '../ui/components/column-forbidden' ;
type RouteParams = { id : string } ;
const messages = defineMessages ( {
heading : { id : 'column.group_pending_requests' , defaultMessage : 'Pending requests' } ,
authorize : { id : 'group.group_mod_authorize' , defaultMessage : 'Accept' } ,
authorized : { id : 'group.group_mod_authorize.success' , defaultMessage : 'Accepted @{name} to group' } ,
reject : { id : 'group.group_mod_reject' , defaultMessage : 'Reject' } ,
rejected : { id : 'group.group_mod_reject.success' , defaultMessage : 'Rejected @{name} from group' } ,
} ) ;
interface IMembershipRequest {
accountId : string
groupId : string
}
const MembershipRequest : React.FC < IMembershipRequest > = ( { accountId , groupId } ) = > {
const intl = useIntl ( ) ;
const dispatch = useAppDispatch ( ) ;
const getAccount = useCallback ( makeGetAccount ( ) , [ ] ) ;
const account = useAppSelector ( ( state ) = > getAccount ( state , accountId ) ) ;
if ( ! account ) return null ;
const handleAuthorize = ( ) = >
dispatch ( authorizeGroupMembershipRequest ( groupId , accountId ) ) . then ( ( ) = > {
2023-01-27 14:04:42 -08:00
toast . success ( intl . formatMessage ( messages . authorized , { name : account.acct } ) ) ;
2022-12-18 09:03:41 -08:00
} ) ;
const handleReject = ( ) = >
dispatch ( rejectGroupMembershipRequest ( groupId , accountId ) ) . then ( ( ) = > {
2023-01-27 14:04:42 -08:00
toast . success ( intl . formatMessage ( messages . rejected , { name : account.acct } ) ) ;
2022-12-18 09:03:41 -08:00
} ) ;
return (
< HStack space = { 1 } alignItems = 'center' justifyContent = 'between' className = 'p-2.5' >
< div className = 'w-full' >
< Account account = { account } withRelationship = { false } / >
< / div >
< HStack space = { 2 } >
< Button
theme = 'secondary'
size = 'sm'
text = { intl . formatMessage ( messages . authorize ) }
onClick = { handleAuthorize }
/ >
< Button
theme = 'danger'
size = 'sm'
text = { intl . formatMessage ( messages . reject ) }
onClick = { handleReject }
/ >
< / HStack >
< / HStack >
) ;
} ;
interface IGroupMembershipRequests {
params : RouteParams
}
const GroupMembershipRequests : React.FC < IGroupMembershipRequests > = ( { params } ) = > {
const intl = useIntl ( ) ;
const dispatch = useAppDispatch ( ) ;
const id = params ? . id || '' ;
const getGroup = useCallback ( makeGetGroup ( ) , [ ] ) ;
const group = useAppSelector ( state = > getGroup ( state , id ) ) ;
const accountIds = useAppSelector ( ( state ) = > state . user_lists . membership_requests . get ( id ) ? . items ) ;
useEffect ( ( ) = > {
if ( ! group ) dispatch ( fetchGroup ( id ) ) ;
dispatch ( fetchGroupMembershipRequests ( id ) ) ;
} , [ id ] ) ;
if ( ! group || ! group . relationship || ! accountIds ) {
return (
< Column label = { intl . formatMessage ( messages . heading ) } >
< Spinner / >
< / Column >
) ;
}
2023-03-15 15:19:42 -07:00
if ( ! group . relationship . role || ! [ 'owner' , 'admin' , 'moderator' ] . includes ( group . relationship . role ) ) {
2022-12-18 09:03:41 -08:00
return ( < ColumnForbidden / > ) ;
}
const emptyMessage = < FormattedMessage id = 'empty_column.group_membership_requests' defaultMessage = 'There are no pending membership requests for this group.' / > ;
return (
< Column label = { intl . formatMessage ( messages . heading ) } backHref = { ` /groups/ ${ id } /manage ` } >
< ScrollableList
scrollKey = 'group_membership_requests'
emptyMessage = { emptyMessage }
>
{ accountIds . map ( ( accountId ) = >
< MembershipRequest key = { accountId } accountId = { accountId } groupId = { id } / > ,
) }
< / ScrollableList >
< / Column >
) ;
} ;
export default GroupMembershipRequests ;