From eb941fc095dbb358729233e9dedecb788c82fed2 Mon Sep 17 00:00:00 2001 From: esvyridov Date: Tue, 7 Sep 2021 23:24:19 +0200 Subject: [PATCH] Update profile sidebar title, add comments counter next to the title --- frontend/app/common/api.ts | 2 +- .../components/counter/counter.module.css | 13 ++++++++++ .../components/counter/counter.spec.tsx | 13 ++++++++++ .../profile/components/counter/counter.tsx | 6 +++++ .../profile/components/counter/index.ts | 1 + .../app/components/profile/profile.module.css | 15 +++++++++-- .../app/components/profile/profile.spec.tsx | 22 ++++++++++------ frontend/app/components/profile/profile.tsx | 25 +++++++++++++------ frontend/app/locales/be.json | 4 +-- frontend/app/locales/bg.json | 4 +-- frontend/app/locales/bp.json | 4 +-- frontend/app/locales/de.json | 4 +-- frontend/app/locales/en.json | 4 +-- frontend/app/locales/es.json | 4 +-- frontend/app/locales/fi.json | 4 +-- frontend/app/locales/fr.json | 4 +-- frontend/app/locales/ja.json | 4 +-- frontend/app/locales/ko.json | 4 +-- frontend/app/locales/pl.json | 4 +-- frontend/app/locales/ru.json | 4 +-- frontend/app/locales/tr.json | 4 +-- frontend/app/locales/ua.json | 4 +-- frontend/app/locales/vi.json | 4 +-- frontend/app/locales/zh.json | 4 +-- 24 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 frontend/app/components/profile/components/counter/counter.module.css create mode 100644 frontend/app/components/profile/components/counter/counter.spec.tsx create mode 100644 frontend/app/components/profile/components/counter/counter.tsx create mode 100644 frontend/app/components/profile/components/counter/index.ts diff --git a/frontend/app/common/api.ts b/frontend/app/common/api.ts index 558a93e9..e8ca2838 100644 --- a/frontend/app/common/api.ts +++ b/frontend/app/common/api.ts @@ -11,7 +11,7 @@ export const getPostComments = (sort: Sorting) => apiFetcher.get('/find', export const getComment = (id: Comment['id']): Promise => apiFetcher.get(`/id/${id}`, { url }); -export const getUserComments = (userId: User['id']): Promise<{ comments: Comment[] }> => +export const getUserComments = (userId: User['id']): Promise<{ comments: Comment[]; count: number }> => apiFetcher.get('/comments', { user: userId, limit: 10 }); export const putCommentVote = ({ id, value }: { id: Comment['id']; value: number }): Promise => diff --git a/frontend/app/components/profile/components/counter/counter.module.css b/frontend/app/components/profile/components/counter/counter.module.css new file mode 100644 index 00000000..8faaa8c9 --- /dev/null +++ b/frontend/app/components/profile/components/counter/counter.module.css @@ -0,0 +1,13 @@ +.container { + font-size: 14px; + line-height: 1; + background-color: var(--color29); + color: var(--color6); + font-weight: 700; + padding: 3px 4px 2px; + border-radius: 2px; +} + +:global(.dark) .container { + background-color: rgba(var(--white-color), .12); +} \ No newline at end of file diff --git a/frontend/app/components/profile/components/counter/counter.spec.tsx b/frontend/app/components/profile/components/counter/counter.spec.tsx new file mode 100644 index 00000000..df635043 --- /dev/null +++ b/frontend/app/components/profile/components/counter/counter.spec.tsx @@ -0,0 +1,13 @@ +import { h } from 'preact'; +import '@testing-library/jest-dom'; +import { render } from 'tests/utils'; +import { Counter } from '.'; + +describe('Counter', () => { + it('renders correctly', () => { + const children = 11; + const { getByText } = render({children}); + + expect(getByText(children)).toBeInTheDocument(); + }); +}); diff --git a/frontend/app/components/profile/components/counter/counter.tsx b/frontend/app/components/profile/components/counter/counter.tsx new file mode 100644 index 00000000..c0f70ad4 --- /dev/null +++ b/frontend/app/components/profile/components/counter/counter.tsx @@ -0,0 +1,6 @@ +import { h } from 'preact'; +import styles from './counter.module.css'; + +export const Counter: React.FC = ({ children }) => { + return
{children}
; +}; diff --git a/frontend/app/components/profile/components/counter/index.ts b/frontend/app/components/profile/components/counter/index.ts new file mode 100644 index 00000000..c4d46e63 --- /dev/null +++ b/frontend/app/components/profile/components/counter/index.ts @@ -0,0 +1 @@ +export { Counter } from './counter'; diff --git a/frontend/app/components/profile/profile.module.css b/frontend/app/components/profile/profile.module.css index dc9d6072..77d50972 100644 --- a/frontend/app/components/profile/profile.module.css +++ b/frontend/app/components/profile/profile.module.css @@ -149,12 +149,11 @@ } } -.title { +.titleWrapper { position: sticky; top: 0; left: 0; margin: 0 0 4px; - padding-top: 12px 0; background-color: rgb(var(--primary-background-color)); z-index: 1; @@ -173,6 +172,18 @@ } } +.title { + display: inline; + margin: 0; + padding-right: 6px; + vertical-align: middle; +} + +.counterWrapper { + display: inline-block; + vertical-align: middle; +} + .preloader { margin: auto; color: var(--color13); diff --git a/frontend/app/components/profile/profile.spec.tsx b/frontend/app/components/profile/profile.spec.tsx index 65f82979..3c8e82d8 100644 --- a/frontend/app/components/profile/profile.spec.tsx +++ b/frontend/app/components/profile/profile.spec.tsx @@ -63,7 +63,9 @@ describe('', () => { it('should render user without comments', async () => { jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub })); - const getUserComments = jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: [] })); + const getUserComments = jest + .spyOn(api, 'getUserComments') + .mockImplementation(async () => ({ comments: [], count: 0 })); const { findByText, queryByLabelText, queryByRole } = render(); @@ -75,18 +77,20 @@ describe('', () => { it('should render user with comments', async () => { jest.spyOn(pq, 'parseQuery').mockImplementation(() => userParamsStub); - jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: commentsStub })); + jest + .spyOn(api, 'getUserComments') + .mockImplementation(async () => ({ comments: commentsStub, count: commentsStub.length })); const { findByText, queryByLabelText, queryByRole } = render(); - expect(await findByText('Recent comments')).toBeInTheDocument(); + expect(await findByText('Comments')).toBeInTheDocument(); expect(queryByLabelText('Loading...')).not.toBeInTheDocument(); expect(queryByRole('button', { name: /retry/i })).not.toBeInTheDocument(); }); it('should render current user without comments', async () => { jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub, current: '1' })); - jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: [] })); + jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: [], count: 0 })); const { getByText, getByTitle, findByText } = render(); @@ -97,18 +101,22 @@ describe('', () => { it('should render current user with comments', async () => { jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub, current: '1' })); - jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: commentsStub })); + jest + .spyOn(api, 'getUserComments') + .mockImplementation(async () => ({ comments: commentsStub, count: commentsStub.length })); const { findByText, queryByTitle, queryByText } = render(); expect(queryByTitle('Sign Out')).toBeInTheDocument(); expect(queryByText('Request my data removal')).toBeInTheDocument(); - expect(await findByText('My recent comments')).toBeInTheDocument(); + expect(await findByText('My comments')).toBeInTheDocument(); }); it('should render user without footer', async () => { jest.spyOn(pq, 'parseQuery').mockImplementation(() => ({ ...userParamsStub })); - jest.spyOn(api, 'getUserComments').mockImplementation(async () => ({ comments: commentsStub })); + jest + .spyOn(api, 'getUserComments') + .mockImplementation(async () => ({ comments: commentsStub, count: commentsStub.length })); const { container } = render(); diff --git a/frontend/app/components/profile/profile.tsx b/frontend/app/components/profile/profile.tsx index ef27c353..12ec2590 100644 --- a/frontend/app/components/profile/profile.tsx +++ b/frontend/app/components/profile/profile.tsx @@ -21,6 +21,7 @@ import { messages as authMessages } from 'components/auth/auth.messsages'; import type { Comment as CommentType, Theme } from 'common/types'; import styles from './profile.module.css'; +import { Counter } from './components/counter'; async function signout() { postMessageToParent({ profile: null, signout: true }); @@ -35,17 +36,20 @@ export function Profile() { const [isCommentsLoading, setIsCommentsLoading] = useState(false); const [error, setError] = useState(false); const [comments, setComments] = useState(null); + const [commentsCounts, setCommentsCounts] = useState(null); const [isSigningOut, setSigningOut] = useState(false); async function fetchUserComments(userId: string) { setIsCommentsLoading(true); setError(false); setComments(null); + setCommentsCounts(null); try { - const { comments } = await getUserComments(userId); + const { comments, count } = await getUserComments(userId); setComments(comments); + setCommentsCounts(count); } catch (err) { setError(true); } finally { @@ -115,13 +119,18 @@ export function Profile() { const isCurrent = user.current === '1'; const commentsJSX = comments?.length ? ( <> -

- {isCurrent ? ( - - ) : ( - - )} -

+
+

+ {isCurrent ? ( + + ) : ( + + )} +

+
+ {commentsCounts} +
+
{comments.map((comment) => (