[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

122 lines
4.4 KiB

// group-invitations.tsx
// Copyright (C) 2020 Dwayne Harris
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { FC, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { Link, useHistory } from 'react-router-dom'
import { faCheckCircle, faStopwatch, faPauseCircle } from '@fortawesome/free-solid-svg-icons'
import moment from 'moment'
import { useTheme } from '../hooks'
import { handleApiError } from '../api/errors'
import { fetchInvitations, createInvitation } from '../actions/groups'
import { getInvitations } from '../selectors/groups'
import { getFieldValue } from '../selectors/forms'
import { AppState, AppThunkDispatch } from '../types'
import PrimaryButton from '../components/controls/primary-button'
import Subtitle from '../components/subtitle'
import SelectField from '../components/controls/select-field'
interface Props {
group: string
}
const GroupInvitations: FC<Props> = ({ group }) => {
const theme = useTheme()
const invitations = useSelector(getInvitations)
const expiration = useSelector<AppState, string>(state => getFieldValue<string>(state, 'expiration', '0'))
const limit = useSelector<AppState, string>(state => getFieldValue<string>(state, 'limit', '0'))
const dispatch = useDispatch<AppThunkDispatch>()
const history = useHistory()
const handleCreateInvitation = async () => {
try {
await dispatch(createInvitation(moment().add(expiration, 'day').valueOf(), parseInt(limit, 10)))
await dispatch(fetchInvitations())
} catch (err) {
handleApiError(err, dispatch, history)
}
}
useEffect(() => {
if (invitations.length === 0) {
try {
dispatch(fetchInvitations())
} catch (err) {
handleApiError(err, dispatch, history)
}
}
}, [group])
const expirationOptions = {
'0': 'No Expiration',
'1': '1 Day',
'7': '1 Week',
'30': '1 Month',
}
const limitOptions = {
'0': 'No Limit',
'1': '1',
'5': '5',
'20': '20',
}
return (
<div>
<Subtitle>Invitations</Subtitle>
<p style={{ color: theme.text }}>Create an invitation for someone to create a new account in this Community.</p>
<SelectField name="expiration" label="Expires" options={expirationOptions} icon={faStopwatch} />
<SelectField name="limit" label="Uses" options={limitOptions} icon={faPauseCircle} />
<PrimaryButton text="Create" icon={faCheckCircle} onClick={() => handleCreateInvitation()} />
<br />
{invitations.length > 0 &&
<table>
<thead>
<tr>
<th>Code</th>
<th>Created By</th>
<th>Uses</th>
<th>Limit</th>
<th>Expires</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{invitations.map(invitation => (
<tr key={invitation.id}>
<td>{invitation.id}</td>
<td><Link to={`/u/${invitation.user.id}`}>{invitation.user.id}</Link></td>
<td>{invitation.uses ?? 0}</td>
<td>{invitation.limit ?? 'None'}</td>
<td>{invitation.expiration ?? 'Never'}</td>
<td>{moment(invitation.created).format('MMMM Do YYYY, h:mm:ss a')}</td>
</tr>
))}
</tbody>
</table>
}
</div>
)
}
export default GroupInvitations