[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

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. // group-invitations.tsx
  2. // Copyright (C) 2020 Dwayne Harris
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. import React, { FC, useEffect } from 'react'
  14. import { useSelector, useDispatch } from 'react-redux'
  15. import { Link, useHistory } from 'react-router-dom'
  16. import { faCheckCircle, faStopwatch, faPauseCircle } from '@fortawesome/free-solid-svg-icons'
  17. import moment from 'moment'
  18. import { useTheme } from '../hooks'
  19. import { handleApiError } from '../api/errors'
  20. import { fetchInvitations, createInvitation } from '../actions/groups'
  21. import { getInvitations } from '../selectors/groups'
  22. import { getFieldValue } from '../selectors/forms'
  23. import { AppState, AppThunkDispatch } from '../types'
  24. import PrimaryButton from '../components/controls/primary-button'
  25. import Subtitle from '../components/subtitle'
  26. import SelectField from '../components/controls/select-field'
  27. interface Props {
  28. group: string
  29. }
  30. const GroupInvitations: FC<Props> = ({ group }) => {
  31. const theme = useTheme()
  32. const invitations = useSelector(getInvitations)
  33. const expiration = useSelector<AppState, string>(state => getFieldValue<string>(state, 'expiration', '0'))
  34. const limit = useSelector<AppState, string>(state => getFieldValue<string>(state, 'limit', '0'))
  35. const dispatch = useDispatch<AppThunkDispatch>()
  36. const history = useHistory()
  37. const handleCreateInvitation = async () => {
  38. try {
  39. await dispatch(createInvitation(moment().add(expiration, 'day').valueOf(), parseInt(limit, 10)))
  40. await dispatch(fetchInvitations())
  41. } catch (err) {
  42. handleApiError(err, dispatch, history)
  43. }
  44. }
  45. useEffect(() => {
  46. if (invitations.length === 0) {
  47. try {
  48. dispatch(fetchInvitations())
  49. } catch (err) {
  50. handleApiError(err, dispatch, history)
  51. }
  52. }
  53. }, [group])
  54. const expirationOptions = {
  55. '0': 'No Expiration',
  56. '1': '1 Day',
  57. '7': '1 Week',
  58. '30': '1 Month',
  59. }
  60. const limitOptions = {
  61. '0': 'No Limit',
  62. '1': '1',
  63. '5': '5',
  64. '20': '20',
  65. }
  66. return (
  67. <div>
  68. <Subtitle>Invitations</Subtitle>
  69. <p style={{ color: theme.text }}>Create an invitation for someone to create a new account in this Community.</p>
  70. <SelectField name="expiration" label="Expires" options={expirationOptions} icon={faStopwatch} />
  71. <SelectField name="limit" label="Uses" options={limitOptions} icon={faPauseCircle} />
  72. <PrimaryButton text="Create" icon={faCheckCircle} onClick={() => handleCreateInvitation()} />
  73. <br />
  74. {invitations.length > 0 &&
  75. <table>
  76. <thead>
  77. <tr>
  78. <th>Code</th>
  79. <th>Created By</th>
  80. <th>Uses</th>
  81. <th>Limit</th>
  82. <th>Expires</th>
  83. <th>Created</th>
  84. </tr>
  85. </thead>
  86. <tbody>
  87. {invitations.map(invitation => (
  88. <tr key={invitation.id}>
  89. <td>{invitation.id}</td>
  90. <td><Link to={`/u/${invitation.user.id}`}>{invitation.user.id}</Link></td>
  91. <td>{invitation.uses ?? 0}</td>
  92. <td>{invitation.limit ?? 'None'}</td>
  93. <td>{invitation.expiration ?? 'Never'}</td>
  94. <td>{moment(invitation.created).format('MMMM Do YYYY, h:mm:ss a')}</td>
  95. </tr>
  96. ))}
  97. </tbody>
  98. </table>
  99. }
  100. </div>
  101. )
  102. }
  103. export default GroupInvitations