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

129 lines
4.3 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
5 years ago
5 years ago
4 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
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
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
5 years ago
  1. import React, { FC, useEffect, useState } from 'react'
  2. import { useSelector, useDispatch } from 'react-redux'
  3. import { useParams, useHistory } from 'react-router-dom'
  4. import { faEdit, faUserCheck, faBan } from '@fortawesome/free-solid-svg-icons'
  5. import moment from 'moment'
  6. import { handleApiError } from '../../api/errors'
  7. import { setTheme } from '../../actions/theme'
  8. import { fetchGroup } from '../../actions/groups'
  9. import { getAuthenticated } from '../../selectors/authentication'
  10. import { getEntity } from '../../selectors/entities'
  11. import { getThemeName } from '../../selectors/theme'
  12. import { useDeepCompareEffect, useTheme, useSetting } from '../../hooks'
  13. import { setTitle } from '../../utils'
  14. import { AppState, EntityType, Group, GroupMembershipType, AppThunkDispatch, LevelItem } from '../../types'
  15. import Title from '../../components/title'
  16. import Level from '../../components/level'
  17. import Section from '../../components/section'
  18. import PrimaryButton from '../../components/controls/primary-button'
  19. import Button from '../../components/controls/button'
  20. import Loading from '../../components/pages/loading'
  21. import HorizontalRule from '../../components/horizontal-rule'
  22. interface Params {
  23. id: string
  24. }
  25. const ViewGroup: FC = () => {
  26. const { id } = useParams<Params>()
  27. const theme = useTheme()
  28. const themeName = useSelector(getThemeName)
  29. const [selectedThemeName] = useState(themeName)
  30. const group = useSelector<AppState, Group | undefined>(state => getEntity<Group>(state, EntityType.Group, id))
  31. const authenticated = useSelector(getAuthenticated)
  32. const dispatch = useDispatch<AppThunkDispatch>()
  33. const history = useHistory()
  34. const allowThemeChange = useSetting<boolean>('allowThemeChange', true)
  35. useEffect(() => {
  36. try {
  37. dispatch(fetchGroup(id))
  38. } catch (err) {
  39. handleApiError(err, dispatch, history)
  40. }
  41. }, [])
  42. useDeepCompareEffect(() => {
  43. if (group) {
  44. setTitle(group.name)
  45. if (allowThemeChange) dispatch(setTheme(group.theme))
  46. }
  47. return () => {
  48. if (allowThemeChange) dispatch(setTheme(selectedThemeName))
  49. }
  50. }, [group])
  51. if (!group) return <Loading />
  52. const isAdmin = group.membership === GroupMembershipType.Admin
  53. const isMember = !!group.membership
  54. const items: LevelItem[] = []
  55. items.push({
  56. label: 'Members',
  57. content: group.members,
  58. })
  59. items.push({
  60. label: 'Posts',
  61. content: group.posts,
  62. })
  63. items.push({
  64. label: 'Awards',
  65. content: group.awards,
  66. })
  67. items.push({
  68. label: 'Points',
  69. content: group.points,
  70. })
  71. items.push({
  72. label: 'Created',
  73. content: moment(group.updated).format('MMMM Do, YYYY'),
  74. })
  75. return (
  76. <div>
  77. <Section>
  78. {group.coverImageUrl &&
  79. <div className="cover-image">
  80. <img src={group.coverImageUrl} />
  81. </div>
  82. }
  83. <div className="header">
  84. {group.imageUrl &&
  85. <div className="image">
  86. <img src={group.imageUrl} />
  87. </div>
  88. }
  89. <div>
  90. <Title>{group.name}</Title>
  91. <p style={{ color: theme.text }}>{group.about}</p>
  92. </div>
  93. </div>
  94. <Level items={items} />
  95. <HorizontalRule />
  96. <div className="buttons">
  97. {!authenticated &&
  98. <PrimaryButton text="Create an Account" icon={faUserCheck} onClick={() => history.push(`/c/${group.id}/register`)} />
  99. }
  100. {!isMember &&
  101. <Button text="Block" icon={faBan} onClick={() => history.push(`/c/${group.id}/register`)} color={theme.backgroundPrimary} backgroundColor={theme.red} />
  102. }
  103. {isAdmin &&
  104. <PrimaryButton text={`Edit ${group.name}`} icon={faEdit} onClick={() => history.push(`/c/${group.id}/admin/`)} />
  105. }
  106. </div>
  107. </Section>
  108. </div>
  109. )
  110. }
  111. export default ViewGroup