|
|
// view-group.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, useState } from 'react' import { useSelector, useDispatch } from 'react-redux' import { useParams, useHistory } from 'react-router-dom' import { faEdit, faUserCheck, faBan } from '@fortawesome/free-solid-svg-icons' import moment from 'moment'
import { handleApiError } from '../../api/errors' import { setTheme } from '../../actions/theme' import { fetchGroup } from '../../actions/groups' import { getAuthenticated } from '../../selectors/authentication' import { getEntity } from '../../selectors/entities' import { getThemeName } from '../../selectors/theme'
import { useDeepCompareEffect, useTheme, useSetting } from '../../hooks' import { setTitle } from '../../utils' import { AppState, EntityType, Group, GroupMembershipType, AppThunkDispatch, LevelItem } from '../../types'
import Title from '../../components/title' import Level from '../../components/level' import Section from '../../components/section' import PrimaryButton from '../../components/controls/primary-button' import Button from '../../components/controls/button' import Loading from '../../components/pages/loading' import HorizontalRule from '../../components/horizontal-rule'
interface Params { id: string }
const ViewGroup: FC = () => { const { id } = useParams<Params>() const theme = useTheme() const themeName = useSelector(getThemeName) const [selectedThemeName] = useState(themeName) const group = useSelector<AppState, Group | undefined>(state => getEntity<Group>(state, EntityType.Group, id)) const authenticated = useSelector(getAuthenticated) const dispatch = useDispatch<AppThunkDispatch>() const history = useHistory() const allowThemeChange = useSetting<boolean>('allowThemeChange', true)
useEffect(() => { try { dispatch(fetchGroup(id)) } catch (err) { handleApiError(err, dispatch, history) } }, [])
useDeepCompareEffect(() => { if (group) { setTitle(group.name) if (allowThemeChange) dispatch(setTheme(group.theme)) }
return () => { if (allowThemeChange) dispatch(setTheme(selectedThemeName)) } }, [group])
if (!group) return <Loading />
const isAdmin = group.membership === GroupMembershipType.Admin const isMember = !!group.membership
const items: LevelItem[] = [] items.push({ label: 'Members', content: group.members, }) items.push({ label: 'Posts', content: group.posts, }) items.push({ label: 'Awards', content: group.awards, }) items.push({ label: 'Points', content: group.points, }) items.push({ label: 'Created', content: moment(group.updated).format('MMMM Do, YYYY'), })
return ( <div> <Section> {group.coverImageUrl && <div className="cover-image"> <img src={group.coverImageUrl} /> </div> }
<div className="header"> {group.imageUrl && <div className="image"> <img src={group.imageUrl} /> </div> } <div> <Title>{group.name}</Title> <p style={{ color: theme.text }}>{group.about}</p> </div> </div> <Level items={items} /> <HorizontalRule />
<div className="buttons"> {!authenticated && <PrimaryButton text="Create an Account" icon={faUserCheck} onClick={() => history.push(`/c/${group.id}/register`)} /> }
{!isMember && <Button text="Block" icon={faBan} onClick={() => history.push(`/c/${group.id}/register`)} color={theme.backgroundPrimary} backgroundColor={theme.red} /> }
{isAdmin && <PrimaryButton text={`Edit ${group.name}`} icon={faEdit} onClick={() => history.push(`/c/${group.id}/admin/`)} /> } </div> </Section> </div> ) }
export default ViewGroup
|