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
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
|