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

106 lines
3.8 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import React, { FC, useEffect } from 'react'
  2. import { useSelector, useDispatch } from 'react-redux'
  3. import { Link, useHistory } from 'react-router-dom'
  4. import { faCheckCircle, faStopwatch, faPauseCircle } from '@fortawesome/free-solid-svg-icons'
  5. import moment from 'moment'
  6. import { useTheme } from '../hooks'
  7. import { handleApiError } from '../api/errors'
  8. import { fetchInvitations, createInvitation } from '../actions/groups'
  9. import { getInvitations } from '../selectors/groups'
  10. import { getFieldValue } from '../selectors/forms'
  11. import { AppState, AppThunkDispatch } from '../types'
  12. import PrimaryButton from '../components/controls/primary-button'
  13. import Subtitle from '../components/subtitle'
  14. import SelectField from '../components/controls/select-field'
  15. interface Props {
  16. group: string
  17. }
  18. const GroupInvitations: FC<Props> = ({ group }) => {
  19. const theme = useTheme()
  20. const invitations = useSelector(getInvitations)
  21. const expiration = useSelector<AppState, string>(state => getFieldValue<string>(state, 'expiration', '0'))
  22. const limit = useSelector<AppState, string>(state => getFieldValue<string>(state, 'limit', '0'))
  23. const dispatch = useDispatch<AppThunkDispatch>()
  24. const history = useHistory()
  25. const handleCreateInvitation = async () => {
  26. try {
  27. await dispatch(createInvitation(moment().add(expiration, 'day').valueOf(), parseInt(limit, 10)))
  28. await dispatch(fetchInvitations())
  29. } catch (err) {
  30. handleApiError(err, dispatch, history)
  31. }
  32. }
  33. useEffect(() => {
  34. if (invitations.length === 0) {
  35. try {
  36. dispatch(fetchInvitations())
  37. } catch (err) {
  38. handleApiError(err, dispatch, history)
  39. }
  40. }
  41. }, [group])
  42. const expirationOptions = {
  43. '0': 'No Expiration',
  44. '1': '1 Day',
  45. '7': '1 Week',
  46. '30': '1 Month',
  47. }
  48. const limitOptions = {
  49. '0': 'No Limit',
  50. '1': '1',
  51. '5': '5',
  52. '20': '20',
  53. }
  54. return (
  55. <div>
  56. <Subtitle>Invitations</Subtitle>
  57. <p style={{ color: theme.text }}>Create an invitation for someone to create a new account in this Community.</p>
  58. <SelectField name="expiration" label="Expires" options={expirationOptions} icon={faStopwatch} />
  59. <SelectField name="limit" label="Uses" options={limitOptions} icon={faPauseCircle} />
  60. <PrimaryButton text="Create" icon={faCheckCircle} onClick={() => handleCreateInvitation()} />
  61. <br />
  62. {invitations.length > 0 &&
  63. <table>
  64. <thead>
  65. <tr>
  66. <th>Code</th>
  67. <th>Created By</th>
  68. <th>Uses</th>
  69. <th>Limit</th>
  70. <th>Expires</th>
  71. <th>Created</th>
  72. </tr>
  73. </thead>
  74. <tbody>
  75. {invitations.map(invitation => (
  76. <tr key={invitation.id}>
  77. <td>{invitation.id}</td>
  78. <td><Link to={`/u/${invitation.user.id}`}>{invitation.user.id}</Link></td>
  79. <td>{invitation.uses ?? 0}</td>
  80. <td>{invitation.limit ?? 'None'}</td>
  81. <td>{invitation.expiration ?? 'Never'}</td>
  82. <td>{moment(invitation.created).format('MMMM Do YYYY, h:mm:ss a')}</td>
  83. </tr>
  84. ))}
  85. </tbody>
  86. </table>
  87. }
  88. </div>
  89. )
  90. }
  91. export default GroupInvitations