Migrate to a monorepo structure (#2909)

This commit is contained in:
Charles Bochet
2023-12-10 18:10:54 +01:00
committed by GitHub
parent a70a9281eb
commit 5bdca9de6c
2304 changed files with 37152 additions and 25869 deletions

View File

@ -0,0 +1,38 @@
import styled from '@emotion/styled';
import { Comment as CommentType } from '@/activities/types/Comment';
import { CommentHeader } from './CommentHeader';
type CommentProps = {
comment: CommentType;
actionBar?: React.ReactNode;
};
const StyledContainer = styled.div`
align-items: flex-start;
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(1)};
justify-content: flex-start;
width: 100%;
`;
const StyledCommentBody = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
font-size: ${({ theme }) => theme.font.size.md};
line-height: ${({ theme }) => theme.text.lineHeight.md};
overflow-wrap: anywhere;
padding-left: 24px;
text-align: left;
`;
export const Comment = ({ comment, actionBar }: CommentProps) => (
<StyledContainer>
<CommentHeader comment={comment} actionBar={actionBar} />
<StyledCommentBody>{comment.body}</StyledCommentBody>
</StyledContainer>
);

View File

@ -0,0 +1,28 @@
import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconComment } from '@/ui/display/icon';
const StyledCommentIcon = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.light};
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
const CommentCounter = ({ commentCount }: { commentCount: number }) => {
const theme = useTheme();
return (
<div>
{commentCount > 0 && (
<StyledCommentIcon>
<IconComment size={theme.icon.size.md} />
{commentCount}
</StyledCommentIcon>
)}
</div>
);
};
export default CommentCounter;

View File

@ -0,0 +1,101 @@
import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled';
import { Comment } from '@/activities/types/Comment';
import { Avatar } from '@/users/components/Avatar';
import {
beautifyExactDateTime,
beautifyPastDateRelativeToNow,
} from '~/utils/date-utils';
const StyledContainer = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
padding: ${({ theme }) => theme.spacing(1)};
width: calc(100% - ${({ theme }) => theme.spacing(1)});
`;
const StyledLeftContainer = styled.div`
align-items: end;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
`;
const StyledName = styled.div`
color: ${({ theme }) => theme.font.color.primary};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.regular};
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledDate = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.sm};
font-weight: ${({ theme }) => theme.font.weight.regular};
margin-left: ${({ theme }) => theme.spacing(1)};
`;
const StyledTooltip = styled(Tooltip)`
background-color: ${({ theme }) => theme.background.primary};
box-shadow: 0px 2px 4px 3px
${({ theme }) => theme.background.transparent.light};
box-shadow: 2px 4px 16px 6px
${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.primary};
opacity: 1;
padding: 8px;
`;
type CommentHeaderProps = {
comment: Pick<Comment, 'id' | 'author' | 'createdAt'>;
actionBar?: React.ReactNode;
};
export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt);
const exactCreatedAt = beautifyExactDateTime(comment.createdAt);
const showDate = beautifiedCreatedAt !== '';
const author = comment.author;
const authorName = author.name.firstName + ' ' + author.name.lastName;
const avatarUrl = author.avatarUrl;
const commentId = comment.id;
return (
<StyledContainer>
<StyledLeftContainer>
<Avatar
avatarUrl={avatarUrl}
size="md"
colorId={author.id}
placeholder={authorName}
/>
<StyledName>{authorName}</StyledName>
{showDate && (
<>
<StyledDate id={`id-${commentId}`}>
{beautifiedCreatedAt}
</StyledDate>
<StyledTooltip
anchorSelect={`#id-${commentId}`}
content={exactCreatedAt}
clickable
noArrow
/>
</>
)}
</StyledLeftContainer>
<div>{actionBar}</div>
</StyledContainer>
);
};

View File

@ -0,0 +1,33 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { ActivityActionBar } from '../../right-drawer/components/ActivityActionBar';
import { Comment } from '../Comment';
import { mockComment, mockCommentWithLongValues } from './mock-comment';
const meta: Meta<typeof Comment> = {
title: 'Modules/Activity/Comment/Comment',
component: Comment,
decorators: [ComponentDecorator],
argTypes: {
actionBar: {
type: 'boolean',
mapping: {
true: <ActivityActionBar activityId="test-id" />,
false: undefined,
},
},
},
args: { comment: mockComment },
};
export default meta;
type Story = StoryObj<typeof Comment>;
export const Default: Story = {};
export const WithLongValues: Story = {
args: { comment: mockCommentWithLongValues },
};

View File

@ -0,0 +1,87 @@
import { Meta, StoryObj } from '@storybook/react';
import { DateTime } from 'luxon';
import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { avatarUrl } from '~/testing/mock-data/users';
import { CommentHeader } from '../CommentHeader';
import { mockComment, mockCommentWithLongValues } from './mock-comment';
const meta: Meta<typeof CommentHeader> = {
title: 'Modules/Activity/Comment/CommentHeader',
component: CommentHeader,
decorators: [ComponentDecorator],
argTypes: {
actionBar: {
type: 'boolean',
mapping: {
true: <ActivityActionBar activityId="test-id" />,
false: undefined,
},
},
},
args: { comment: mockComment },
};
export default meta;
type Story = StoryObj<typeof CommentHeader>;
export const Default: Story = {};
export const FewHoursAgo: Story = {
args: {
comment: {
...mockComment,
createdAt: DateTime.now().minus({ hours: 2 }).toISO() ?? '',
},
},
};
export const FewDaysAgo: Story = {
args: {
comment: {
...mockComment,
createdAt: DateTime.now().minus({ days: 2 }).toISO() ?? '',
},
},
};
export const FewMonthsAgo: Story = {
args: {
comment: {
...mockComment,
createdAt: DateTime.now().minus({ months: 2 }).toISO() ?? '',
},
},
};
export const FewYearsAgo: Story = {
args: {
comment: {
...mockComment,
createdAt: DateTime.now().minus({ years: 2 }).toISO() ?? '',
},
},
};
export const WithAvatar: Story = {
args: {
comment: {
...mockComment,
author: {
...mockComment.author,
avatarUrl,
},
},
},
};
export const WithLongUserName: Story = {
args: { comment: mockCommentWithLongValues },
};
export const WithActionBar: Story = {
args: { actionBar: true },
};

View File

@ -0,0 +1,41 @@
import { DateTime } from 'luxon';
import { Comment } from '@/activities/types/Comment';
export const mockComment: Pick<
Comment,
'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' | 'activityId'
> = {
id: 'fake_comment_1_uuid',
body: 'Hello, this is a comment.',
author: {
id: 'fake_comment_1_author_uuid',
name: {
firstName: 'Jony' ?? '',
lastName: 'Ive' ?? '',
},
avatarUrl: null,
},
createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '',
updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '',
activityId: 'fake_activity_1_uuid',
};
export const mockCommentWithLongValues: Pick<
Comment,
'id' | 'author' | 'createdAt' | 'body' | 'updatedAt' | 'activityId'
> = {
id: 'fake_comment_2_uuid',
body: 'Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment. Hello, this is a comment.',
author: {
id: 'fake_comment_1_author_uuid',
name: {
firstName: 'Jony' ?? '',
lastName: 'Ive' ?? '',
},
avatarUrl: null,
},
createdAt: DateTime.fromFormat('2021-03-12', 'yyyy-MM-dd').toISO() ?? '',
updatedAt: DateTime.fromFormat('2021-03-13', 'yyyy-MM-dd').toISO() ?? '',
activityId: 'fake_activity_1_uuid',
};