@ -1,21 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { buildGroup } from 'soapbox/jest/factory';
|
||||
import { render, screen } from 'soapbox/jest/test-helpers';
|
||||
|
||||
import GroupGridItem from './group-grid-item';
|
||||
|
||||
describe('<GroupGridItem', () => {
|
||||
it('should render correctly', () => {
|
||||
const group = buildGroup({
|
||||
display_name: 'group name here',
|
||||
locked: false,
|
||||
members_count: 6,
|
||||
});
|
||||
render(<GroupGridItem group={group} />);
|
||||
|
||||
expect(screen.getByTestId('group-grid-item')).toHaveTextContent(group.display_name);
|
||||
expect(screen.getByTestId('group-grid-item')).toHaveTextContent('Public');
|
||||
expect(screen.getByTestId('group-grid-item')).toHaveTextContent('6 members');
|
||||
});
|
||||
});
|
||||
@ -1,74 +0,0 @@
|
||||
import React, { forwardRef } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import GroupAvatar from 'soapbox/components/groups/group-avatar';
|
||||
import { HStack, Stack, Text } from 'soapbox/components/ui';
|
||||
import GroupActionButton from 'soapbox/features/group/components/group-action-button';
|
||||
import GroupHeaderImage from 'soapbox/features/group/components/group-header-image';
|
||||
import GroupMemberCount from 'soapbox/features/group/components/group-member-count';
|
||||
import GroupPrivacy from 'soapbox/features/group/components/group-privacy';
|
||||
|
||||
import type { Group } from 'soapbox/schemas';
|
||||
|
||||
interface IGroup {
|
||||
group: Group;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
const GroupGridItem = forwardRef((props: IGroup, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||
const { group, width = 'auto' } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={group.id}
|
||||
className='relative flex shrink-0 flex-col space-y-2 px-1'
|
||||
style={{
|
||||
width,
|
||||
}}
|
||||
data-testid='group-grid-item'
|
||||
>
|
||||
<Link to={`/group/${group.id}`}>
|
||||
<Stack
|
||||
className='aspect-h-7 aspect-w-10 h-full w-full overflow-hidden rounded-lg'
|
||||
ref={ref}
|
||||
style={{ minHeight: 180 }}
|
||||
>
|
||||
<GroupHeaderImage
|
||||
group={group}
|
||||
className='absolute inset-0 object-cover'
|
||||
/>
|
||||
|
||||
<div
|
||||
className='absolute inset-x-0 bottom-0 flex justify-center rounded-b-lg bg-gradient-to-t from-gray-900 to-transparent pb-8 pt-12 transition-opacity duration-500'
|
||||
/>
|
||||
|
||||
<Stack justifyContent='end' className='p-4 text-white' space={3}>
|
||||
<GroupAvatar
|
||||
group={group}
|
||||
size={44}
|
||||
/>
|
||||
|
||||
<Stack space={1}>
|
||||
<Text
|
||||
weight='bold'
|
||||
dangerouslySetInnerHTML={{ __html: group.display_name_html }}
|
||||
theme='inherit'
|
||||
truncate
|
||||
/>
|
||||
|
||||
<HStack alignItems='center' space={1}>
|
||||
<GroupPrivacy group={group} />
|
||||
<span>•</span>
|
||||
<GroupMemberCount group={group} />
|
||||
</HStack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Link>
|
||||
|
||||
<GroupActionButton group={group} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default GroupGridItem;
|
||||
@ -1,38 +0,0 @@
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { render, screen, within } from 'soapbox/jest/test-helpers';
|
||||
|
||||
import LayoutButtons, { GroupLayout } from './layout-buttons';
|
||||
|
||||
describe('<LayoutButtons', () => {
|
||||
describe('when LIST view', () => {
|
||||
it('should render correctly', async () => {
|
||||
const onSelectFn = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<LayoutButtons layout={GroupLayout.LIST} onSelect={onSelectFn} />);
|
||||
|
||||
expect(within(screen.getByTestId('layout-list-action')).getByTestId('svg-icon-loader')).toHaveClass('text-primary-600');
|
||||
expect(within(screen.getByTestId('layout-grid-action')).getByTestId('svg-icon-loader')).not.toHaveClass('text-primary-600');
|
||||
|
||||
await user.click(screen.getByTestId('layout-grid-action'));
|
||||
expect(onSelectFn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when GRID view', () => {
|
||||
it('should render correctly', async () => {
|
||||
const onSelectFn = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<LayoutButtons layout={GroupLayout.GRID} onSelect={onSelectFn} />);
|
||||
|
||||
expect(within(screen.getByTestId('layout-list-action')).getByTestId('svg-icon-loader')).not.toHaveClass('text-primary-600');
|
||||
expect(within(screen.getByTestId('layout-grid-action')).getByTestId('svg-icon-loader')).toHaveClass('text-primary-600');
|
||||
|
||||
await user.click(screen.getByTestId('layout-grid-action'));
|
||||
expect(onSelectFn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,48 +0,0 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { HStack, Icon } from 'soapbox/components/ui';
|
||||
|
||||
enum GroupLayout {
|
||||
LIST = 'LIST',
|
||||
GRID = 'GRID'
|
||||
}
|
||||
|
||||
interface ILayoutButtons {
|
||||
layout: GroupLayout;
|
||||
onSelect(layout: GroupLayout): void;
|
||||
}
|
||||
|
||||
const LayoutButtons = ({ layout, onSelect }: ILayoutButtons) => (
|
||||
<HStack alignItems='center' space={1}>
|
||||
<button
|
||||
data-testid='layout-list-action'
|
||||
onClick={() => onSelect(GroupLayout.LIST)}
|
||||
>
|
||||
<Icon
|
||||
src={require('@tabler/icons/outline/layout-list.svg')}
|
||||
className={
|
||||
clsx('h-5 w-5 text-gray-600', {
|
||||
'text-primary-600': layout === GroupLayout.LIST,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
data-testid='layout-grid-action'
|
||||
onClick={() => onSelect(GroupLayout.GRID)}
|
||||
>
|
||||
<Icon
|
||||
src={require('@tabler/icons/outline/layout-grid.svg')}
|
||||
className={
|
||||
clsx('h-5 w-5 text-gray-600', {
|
||||
'text-primary-600': layout === GroupLayout.GRID,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
</HStack>
|
||||
);
|
||||
|
||||
export { LayoutButtons as default, GroupLayout };
|
||||
@ -1,41 +0,0 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Tabs } from 'soapbox/components/ui';
|
||||
|
||||
import type { Item } from 'soapbox/components/ui/tabs/tabs';
|
||||
|
||||
export enum TabItems {
|
||||
MY_GROUPS = 'MY_GROUPS',
|
||||
FIND_GROUPS = 'FIND_GROUPS'
|
||||
}
|
||||
|
||||
interface ITabBar {
|
||||
activeTab: TabItems;
|
||||
}
|
||||
|
||||
const TabBar = ({ activeTab }: ITabBar) => {
|
||||
const history = useHistory();
|
||||
|
||||
const tabItems: Item[] = useMemo(() => ([
|
||||
{
|
||||
text: 'My Groups',
|
||||
action: () => history.push('/groups'),
|
||||
name: TabItems.MY_GROUPS,
|
||||
},
|
||||
{
|
||||
text: 'Find Groups',
|
||||
action: () => history.push('/groups/discover'),
|
||||
name: TabItems.FIND_GROUPS,
|
||||
},
|
||||
]), []);
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
items={tabItems}
|
||||
activeItem={activeTab}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TabBar;
|
||||
Reference in New Issue
Block a user