From b8b5edb58188ee32ec61089f5a583e2c685f2cc7 Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Wed, 5 Aug 2020 23:54:23 -0500 Subject: [PATCH] Updated GroupHeader, GroupInfoPanel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Updated: - GroupHeader, GroupInfoPanel --- .../gabsocial/components/group_header.js | 192 ++++++++----- .../components/panel/group_info_panel.js | 262 +++++++++++++----- 2 files changed, 314 insertions(+), 140 deletions(-) diff --git a/app/javascript/gabsocial/components/group_header.js b/app/javascript/gabsocial/components/group_header.js index 56d377a3..15902b60 100644 --- a/app/javascript/gabsocial/components/group_header.js +++ b/app/javascript/gabsocial/components/group_header.js @@ -12,13 +12,16 @@ import { me } from '../initial_state' import Responsive from '../features/ui/util/responsive_component' import Button from './button' import Block from './block' +import Heading from './heading' import Image from './image' +import Icon from './icon' import TabBar from './tab_bar' +import Pills from './pills' import Text from './text' const messages = defineMessages({ join: { id: 'groups.join', defaultMessage: 'Join group' }, - leave: { id: 'groups.leave', defaultMessage: 'Leave group' }, + member: { id: 'groups.member', defaultMessage: 'Member' }, removed_accounts: { id: 'groups.removed_accounts', defaultMessage: 'Removed Accounts' }, group_archived: { id: 'group.detail.archived_group', defaultMessage: 'Archived group' }, group_admin: { id: 'groups.detail.role_admin', defaultMessage: 'You\'re an admin' } @@ -54,6 +57,7 @@ class GroupHeader extends ImmutablePureComponent { group: ImmutablePropTypes.map, children: PropTypes.any, intl: PropTypes.object.isRequired, + isXS: PropTypes.bool, onToggleMembership: PropTypes.func.isRequired, onOpenGroupOptions: PropTypes.func.isRequired, relationships: ImmutablePropTypes.map, @@ -79,35 +83,55 @@ class GroupHeader extends ImmutablePureComponent { children, group, intl, + isXS, relationships, } = this.props - const tabs = !group ? null : [ - { - to: `/groups/${group.get('id')}`, - title: 'Latest', - }, - ] - const coverSrc = !!group ? group.get('cover_image_url') : '' const coverSrcMissing = coverSrc.indexOf(PLACEHOLDER_MISSING_HEADER_SRC) > -1 || !coverSrc const title = !!group ? group.get('title') : undefined - + const slug = !!group ? !!group.get('slug') ? `g/${group.get('slug')}` : undefined : undefined + let isAdmin = false let actionButtonTitle let actionButtonOptions = {} if (relationships) { isAdmin = relationships.get('admin') const isMember = relationships.get('member') - actionButtonTitle = intl.formatMessage(!isMember ? messages.join : messages.leave) - if (isMember) { - actionButtonOptions = { - backgroundColor: 'danger', - color: 'white', - } + + actionButtonTitle = intl.formatMessage(isMember ? messages.member : messages.join) + actionButtonOptions = { + isOutline: !isMember, + backgroundColor: isMember ? 'brand' : 'none', + color: isMember ? 'white' : 'brand', } } + const tabs = !group ? [] : [ + { + to: `/groups/${group.get('id')}`, + title: 'Timeline', + }, + { + to: `/groups/${group.get('id')}/media`, + title: 'Media', + }, + ] + + if (isAdmin && group) { + tabs.push({ + to: `/groups/${group.get('id')}/members`, + title: 'Members', + }) + } + + if (isXS && group) { + tabs.push({ + to: `/groups/${group.get('id')}/about`, + title: 'About', + }) + } + // : todo : // {group.get('archived') && } @@ -128,38 +152,36 @@ class GroupHeader extends ImmutablePureComponent { {children} -
- { - !!actionButtonTitle && + { + !!me && +
+ { + !!actionButtonTitle && + + } + - } - - { - isAdmin && -
+
+ } -
+
- +
@@ -169,49 +191,79 @@ class GroupHeader extends ImmutablePureComponent { { /** desktop */} - +
{ coverSrc && !coverSrcMissing && {title} } + +
+
+
+
+ +
+ + {title} + + { + !!slug && + + {slug} + + } +
+
+
+
+
+
+ + -
-
- -
- { - !!actionButtonTitle && - - } - - { - !!me && -
+ } + { + !!actionButtonTitle && + + } +
- +
) diff --git a/app/javascript/gabsocial/components/panel/group_info_panel.js b/app/javascript/gabsocial/components/panel/group_info_panel.js index 74f2145c..79263d09 100644 --- a/app/javascript/gabsocial/components/panel/group_info_panel.js +++ b/app/javascript/gabsocial/components/panel/group_info_panel.js @@ -1,117 +1,239 @@ import { Fragment } from 'react' -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl' +import { defineMessages, injectIntl } from 'react-intl' import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePropTypes from 'react-immutable-proptypes' -import { openModal } from '../../actions/modal' -import { MODAL_GROUP_MEMBERS } from '../../constants' -import { me } from '../../initial_state' +import moment from 'moment-mini' import { shortNumberFormat } from '../../utils/numbers' import PanelLayout from './panel_layout' import Button from '../button' import Divider from '../divider' -import Dummy from '../dummy' +import Heading from '../heading' import Icon from '../icon' import Text from '../text' -import RelativeTimestamp from '../relative_timestamp' +import DotTextSeperator from '../dot_text_seperator' +import ProfileInfoPanelPlaceholder from '../placeholder/profile_info_panel_placeholder' const messages = defineMessages({ title: { id: 'about', defaultMessage: 'About' }, members: { id: 'members', defaultMessage: 'Members' }, + created: { id: 'created', defaultMessage: 'Created' }, + category: { id: 'category', defaultMessage: 'Category' }, + tags: { id: 'tags', defaultMessage: 'Tags' }, + privateGroup: { id: 'group.private', defaultMessage: 'Private' }, + publicGroup: { id: 'group.public', defaultMessage: 'Public' }, + visibleGroup: { id: 'group.visible', defaultMessage: 'Visible' }, + invisibleGroup: { id: 'group.invisible', defaultMessage: 'Invisible' }, }) -const mapDispatchToProps = (dispatch) => ({ - onOpenGroupMembersModal(groupId) { - dispatch(openModal(MODAL_GROUP_MEMBERS, { groupId })) - }, -}) +const mapStateToProps = (state, { group }) => { + const groupId = group ? group.get('id') : -1 + const relationships = group === -1 ? null : state.getIn(['group_relationships', groupId]) + + return { relationships } +} export default @injectIntl -@connect(null, mapDispatchToProps) +@connect(mapStateToProps) class GroupInfoPanel extends ImmutablePureComponent { static propTypes = { group: ImmutablePropTypes.map.isRequired, intl: PropTypes.object.isRequired, - onOpenGroupMembersModal: PropTypes.func.isRequired, noPanel: PropTypes.bool, - } - - handleOnOpenGroupMembersModal = () => { - this.props.onOpenGroupMembersModal(this.props.group.get('id')) + relationships: ImmutablePropTypes.map, } render() { - const { intl, group, noPanel } = this.props + const { + intl, + group, + noPanel, + relationships, + } = this.props - const Wrapper = noPanel ? Dummy : PanelLayout + if (!group && !noPanel) { + return ( +
+ +
+ ) + } + + const isAdmin = relationships ? relationships.get('admin') : false + const groupId = !!group ? group.get('id') : '' + const slug = !!group ? !!group.get('slug') ? `g/${group.get('slug')}` : undefined : undefined + const isPrivate = !!group ? group.get('is_private') : false + const isVisible = !!group ? group.get('is_visible') : false + const tags = !!group ? group.get('tags') : [] + + if (noPanel) { + return ( +
+ { + !!group && + + + {group.get('title')} + + { + !!slug && + + {slug} + + } + + {group.get('description')} + +
+ + + + {intl.formatMessage(isPrivate ? messages.privateGroup : messages.publicGroup)} + + + + + {shortNumberFormat(group.get('member_count'))} +   + {intl.formatMessage(messages.members)} + +
+
+ } +
+ ) + } return ( - + { !!group && -
- - {group.get('title')} - -
+ + {group.get('description')} + - { - !!me && - -
-
- - - {intl.formatMessage(messages.members)} - -
- -
+ + + + + + + + + + + + + + + + + + + General + + + + + + + {moment(group.get('created_at')).format('LL')} + + + + { + !!tags && + + +
+ { + tags.map((tag) => ( +
+ + {tag} + +
+ )) + } +
+
} -
- - - { - , - }} /> - } - -
- - - - - {group.get('description')} -
} -
+ ) } +} + +class GroupInfoPanelRow extends PureComponent { + + static propTypes = { + icon: PropTypes.string, + title: PropTypes.string.isRequired, + } + + render() { + const { icon, title } = this.props + + return ( +
+
+ + + {title} + +
+
+ {this.props.children} +
+
+ ) + + } + } \ No newline at end of file