|
|
// group-admin.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, useParams, useHistory } from 'react-router-dom' import { faCheckCircle, faIdCard } from '@fortawesome/free-solid-svg-icons'
import { handleApiError } from '../../api/errors' import { initForm, initField } from '../../actions/forms' import { fetchGroup, updateGroup } from '../../actions/groups' import { getEntity } from '../../selectors/entities' import { getForm } from '../../selectors/forms'
import { useDeepCompareEffect, useTheme } from '../../hooks' import { setTitle, valueFromForm } from '../../utils' import { AppState, AppThunkDispatch, Group, GroupMembershipType, Tab, EntityType, } from '../../types'
import Title from '../../components/title' import Subtitle from '../../components/subtitle' import Section from '../../components/section' import HorizontalRule from '../../components/horizontal-rule' import PrimaryButton from '../../components/controls/primary-button' import MemberList from '../../components/member-list' import GroupInvitations from '../../components/group-invitations' import GroupLogs from '../../components/group-logs' import Loading from '../../components/pages/loading'
import TextareaField from '../../components/controls/textarea-field' import ImageField from '../../components/controls/image-field' import CoverImageField from '../../components/controls/cover-image-field' import IconImageField from '../../components/controls/icon-image-field' import StaticField from '../../components/controls/static-field'
interface Params { id: string tab: string }
const tabs: Tab[] = [ { id: '', label: 'General' }, { id: 'members', label: 'Members' }, { id: 'logs', label: 'Logs' }, ]
const GroupAdmin: FC = () => { const theme = useTheme() const { id, tab = '' } = useParams<Params>() const history = useHistory() const group = useSelector<AppState, Group | undefined>(state => getEntity<Group>(state, EntityType.Group, id)) const form = useSelector(getForm)
const dispatch = useDispatch<AppThunkDispatch>()
useEffect(() => { try { dispatch(fetchGroup(id)) } catch (err) { handleApiError(err, dispatch, history) } }, [])
useDeepCompareEffect(() => { if (group && group.membership) { if (group.membership !== GroupMembershipType.Admin) { history.push(`/c/${group.id}`) return }
dispatch(initForm()) dispatch(initField('about', group.about)) dispatch(initField('expiration', '0')) dispatch(initField('limit', '0')) dispatch(initField('image', group.imageUrl)) dispatch(initField('coverImage', group.coverImageUrl)) dispatch(initField('iconImage', group.iconImageUrl))
setTitle(`${group.name} Administration`) } }, [group])
const handleUpdateGroup = async () => { try { await dispatch(updateGroup(id, { about: valueFromForm<string>(form, 'about'), imageUrl: valueFromForm<string>(form, 'image'), coverImageUrl: valueFromForm<string>(form, 'coverImage'), iconImageUrl: valueFromForm<string>(form, 'iconImage'), }))
await dispatch(fetchGroup(id)) } catch (err) { handleApiError(err, dispatch, history) } }
if (!group) return <Loading />
return ( <div> <Section> <Title>{group.name}</Title> <Subtitle>Administration</Subtitle> <HorizontalRule />
<div className="tabs" style={{ backgroundColor: theme.backgroundSecondary }}> {tabs.map(t => ( <div key={t.id} className={tab === t.id ? 'active': ''} style={{ borderColor: theme.primary }}> <Link style={{ color: theme.secondary}} to={`/c/${group.id}/admin/${t.id}`}> {t.label} </Link> </div> ))} </div>
<div> {tab === '' && <div> <StaticField label="ID" icon={faIdCard} value={group.id} /> <StaticField label="Name" value={group.name} /> <TextareaField name="about" label="About" placeholder="About this Community" /> <ImageField name="image" /> <CoverImageField name="coverImage" /> <IconImageField name="iconImage" /> <br />
<PrimaryButton text="Save" icon={faCheckCircle} onClick={e => handleUpdateGroup()} /> </div> }
{tab === 'members' && <div> <GroupInvitations group={id} /> <HorizontalRule />
<Subtitle>Members</Subtitle> <MemberList group={id} /> </div> }
{tab === 'logs' && <div> <GroupLogs group={id} /> </div> } </div> </Section> </div> ) }
export default GroupAdmin
|