bigbuffet-rw/src/pages/group-page.tsx

126 lines
3.1 KiB
TypeScript
Raw Normal View History

2023-03-23 12:20:19 -07:00
import React, { useMemo } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useRouteMatch } from 'react-router-dom';
2023-05-01 11:58:40 -07:00
import { useGroup, useGroupMembershipRequests } from 'soapbox/api/hooks';
2023-09-18 16:01:22 -07:00
import { Column, Icon, Layout, Stack, Text, Tabs } from 'soapbox/components/ui';
import GroupHeader from 'soapbox/features/group/components/group-header';
import LinkFooter from 'soapbox/features/ui/components/link-footer';
import {
CtaBanner,
GroupMediaPanel,
SignUpPanel,
} from 'soapbox/features/ui/util/async-components';
import { useOwnAccount } from 'soapbox/hooks';
const messages = defineMessages({
all: { id: 'group.tabs.all', defaultMessage: 'All' },
members: { id: 'group.tabs.members', defaultMessage: 'Members' },
2023-04-10 13:22:08 -07:00
media: { id: 'group.tabs.media', defaultMessage: 'Media' },
});
interface IGroupPage {
params?: {
groupId?: string;
};
children: React.ReactNode;
}
const PrivacyBlankslate = () => (
<Stack space={4} className='py-10' alignItems='center'>
<div className='rounded-full bg-gray-200 p-3 dark:bg-gray-800'>
<Icon
src={require('@tabler/icons/outline/eye-off.svg')}
className='h-6 w-6 text-gray-600 dark:text-gray-600'
/>
</div>
<Text theme='muted'>
<FormattedMessage
id='group.private.message'
defaultMessage='Content is only visible to group members'
/>
</Text>
</Stack>
);
/** Page to display a group. */
const GroupPage: React.FC<IGroupPage> = ({ params, children }) => {
const intl = useIntl();
const match = useRouteMatch();
2023-06-25 10:35:09 -07:00
const { account: me } = useOwnAccount();
2023-04-17 12:28:20 -07:00
const id = params?.groupId || '';
const { group } = useGroup(id);
2023-03-20 18:02:58 -07:00
const { accounts: pending } = useGroupMembershipRequests(id);
const isMember = !!group?.relationship?.member;
const isPrivate = group?.locked;
2023-03-23 12:20:19 -07:00
const tabItems = useMemo(() => {
const items = [];
items.push({
text: intl.formatMessage(messages.all),
to: `/groups/${id}`,
name: '/groups/:groupId',
2023-03-23 12:20:19 -07:00
});
2023-05-05 05:35:21 -07:00
items.push(
{
text: intl.formatMessage(messages.media),
to: `/groups/${id}/media`,
name: '/groups/:groupId/media',
2023-05-05 05:35:21 -07:00
},
{
text: intl.formatMessage(messages.members),
to: `/groups/${id}/members`,
name: '/groups/:groupId/members',
2023-05-05 05:35:21 -07:00
count: pending.length,
},
);
2023-03-23 12:20:19 -07:00
return items;
}, [pending.length, id]);
const renderChildren = () => {
if (!isMember && isPrivate) {
return <PrivacyBlankslate />;
} else {
return children;
}
};
return (
<>
<Layout.Main>
2023-04-11 05:55:17 -07:00
<Column size='lg' label={group ? group.display_name : ''} withHeader={false}>
<GroupHeader group={group} />
<Tabs
2023-06-05 08:11:57 -07:00
key={`group-tabs-${id}`}
2023-03-23 12:20:19 -07:00
items={tabItems}
activeItem={match.path}
/>
{renderChildren()}
</Column>
{!me && (
<CtaBanner />
)}
</Layout.Main>
<Layout.Aside>
{!me && (
<SignUpPanel />
)}
<GroupMediaPanel group={group} />
<LinkFooter />
</Layout.Aside>
</>
);
};
export { GroupPage as default };