Update profile sidebar title, add comments counter next to the title

This commit is contained in:
esvyridov
2021-10-23 11:39:33 -05:00
committed by Umputun
parent aa34dc8384
commit eb941fc095
24 changed files with 111 additions and 50 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ export const getPostComments = (sort: Sorting) => apiFetcher.get<Tree>('/find',
export const getComment = (id: Comment['id']): Promise<Comment> => 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<void> =>
@@ -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);
}
@@ -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(<Counter>{children}</Counter>);
expect(getByText(children)).toBeInTheDocument();
});
});
@@ -0,0 +1,6 @@
import { h } from 'preact';
import styles from './counter.module.css';
export const Counter: React.FC = ({ children }) => {
return <div className={styles.container}>{children}</div>;
};
@@ -0,0 +1 @@
export { Counter } from './counter';
@@ -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);
@@ -63,7 +63,9 @@ describe('<Profile />', () => {
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(<Profile />);
@@ -75,18 +77,20 @@ describe('<Profile />', () => {
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(<Profile />);
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(<Profile />);
@@ -97,18 +101,22 @@ describe('<Profile />', () => {
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(<Profile />);
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(<Profile />);
+17 -8
View File
@@ -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<CommentType[] | null>(null);
const [commentsCounts, setCommentsCounts] = useState<number | null>(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 ? (
<>
<h3 className={clsx('profile-title', styles.title)}>
{isCurrent ? (
<FormattedMessage id="user.my-comments" defaultMessage="My recent comments" />
) : (
<FormattedMessage key="user.recent-comments" id="user.recent-comments" defaultMessage="Recent comments" />
)}
</h3>
<div className={styles.titleWrapper}>
<h3 className={clsx('profile-title', styles.title)}>
{isCurrent ? (
<FormattedMessage key="user.my-comments" id="user.my-comments" defaultMessage="My comments" />
) : (
<FormattedMessage key="user.comments" id="user.comments" defaultMessage="Comments" />
)}
</h3>
<div className={styles.counterWrapper}>
<Counter>{commentsCounts}</Counter>
</div>
</div>
{comments.map((comment) => (
<Comment
key={comment.id}
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Нумараваны спіс",
"toolbar.quote": "Цытата",
"toolbar.unordered-list": "Ненумараваны спіс",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Ананімныя карыстальнікі не могуць галасаваць",
"vote.deleted": "Нельга галасаваць за выдалены каментар",
"vote.guest": "Увайдзіце ў сістэму, каб галасаваць",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Добави номериран списък",
"toolbar.quote": "Добави цитат",
"toolbar.unordered-list": "Добави обозначен списък",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Анонимни потребители не могат да гласуват",
"vote.deleted": "Не може да гласъвате за изтрит коментарт",
"vote.guest": "Влезте за да гласувате",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Adicionar uma lista numerada",
"toolbar.quote": "Inserir citação",
"toolbar.unordered-list": "Adicionar lista com marcadores",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Usuários anônimos não podem votar",
"vote.deleted": "Não posso votar em um comentário excluído",
"vote.guest": "Faça login para votar",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Nummerierte Liste einfügen",
"toolbar.quote": "Zitat einfügen",
"toolbar.unordered-list": "Aufzählungsliste einfügen",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Anonyme Benutzer können leider nicht abstimmen",
"vote.deleted": "Sie können nicht für einen gelöschten Kommentar abstimmen",
"vote.guest": "Melden Sie sich an, um abzustimmen",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Add a numbered list",
"toolbar.quote": "Insert a quote",
"toolbar.unordered-list": "Add a bulleted list",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Anonymous users can't vote",
"vote.deleted": "Can't vote for deleted comment",
"vote.guest": "Sign in to vote",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Agrega una lista numerada",
"toolbar.quote": "Inserta una cita",
"toolbar.unordered-list": "Agrega una lista sin numerar",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Los usuarios anónimos no puede votar",
"vote.deleted": "No se puede votar un comentario eliminado",
"vote.guest": "Accede para votar",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Järjestetty luettelo",
"toolbar.quote": "Lainaus",
"toolbar.unordered-list": "Järjestämätön luettelo",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Anonyymit käyttäjät eivät voi äänestää",
"vote.deleted": "Poistettua kommenttia ei voi äänestää",
"vote.guest": "Kirjaudu sisään äänestääksesi",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Ajouter une liste numérotée",
"toolbar.quote": "Insérer une citation",
"toolbar.unordered-list": "Ajouter une liste à puces",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Les utilisateurs anonymes ne peuvent pas voter",
"vote.deleted": "Vous ne pouvez pas voter pour un commentaire supprimé",
"vote.guest": "Connectez-vous pour voter",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "番号付きリストの追加",
"toolbar.quote": "引用符の挿入",
"toolbar.unordered-list": "記号付きリストの追加",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "匿名ユーザーは投稿できません",
"vote.deleted": "削除済みコメントには投票できません",
"vote.guest": "投票するにはサインインしてください",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "숫자 지정된 목록 추가",
"toolbar.quote": "인용구 삽입",
"toolbar.unordered-list": "글머리 기호가 지정된 목록 추가",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "익명의 사용자는 투표할 수 없습니다",
"vote.deleted": "삭제된 댓글에는 투표할 수 없습니다",
"vote.guest": "투표하려면 로그인하세요",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Dodaj numerowaną listę",
"toolbar.quote": "Dodaj cytat",
"toolbar.unordered-list": "Dodaj listę punktowaną",
"user.my-comments": "Moje ostatnie komentarze",
"user.recent-comments": "Ostatnie komentarze",
"user.my-comments": "Moje komentarze",
"user.comments": "Komentarze",
"vote.anonymous": "Anonimowi użytkownicy nie mogą głosować",
"vote.deleted": "Nie można głosować na usunięte komentarze",
"vote.guest": "Zaloguj się żeby głosować",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Добавить нумерованный список",
"toolbar.quote": "Вставить цитату",
"toolbar.unordered-list": "Добавить маркированный список",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "Мои комментарии",
"user.comments": "Комментарии",
"vote.anonymous": "Анонимные пользователи не могут голосовать",
"vote.deleted": "Нельзя голосовать за удаленный комментарий",
"vote.guest": "Войдите, чтобы проголосовать",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Sıralı liste ekle",
"toolbar.quote": "Alıntı ekle",
"toolbar.unordered-list": "Liste ekle",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Anonim kullanıcılar oy kullanamaz",
"vote.deleted": "Silinmiş yorum oylanamaz",
"vote.guest": "Oy vermek için giriş yapın",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Упорядкованний список",
"toolbar.quote": "Цитата",
"toolbar.unordered-list": "Неупорядкованний список",
"user.my-comments": "Мої нещодавні коментарі",
"user.recent-comments": "Нещодавні коментарі",
"user.my-comments": "Мої коментарі",
"user.comments": "Коментарі",
"vote.anonymous": "Не можна голосувати анонімному користувачу",
"vote.deleted": "Не можна голосувати за видалений коментар",
"vote.guest": "Увійдіть в систему для голосування",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "Thêm danh sách số",
"toolbar.quote": "Thêm trích dẫn",
"toolbar.unordered-list": "Thêm danh sách",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "Người dùng ẩn danh không thể vote",
"vote.deleted": "Không thể vote bình luận đã xoá",
"vote.guest": "Đăng nhập để vote",
+2 -2
View File
@@ -157,8 +157,8 @@
"toolbar.ordered-list": "添加编号列表",
"toolbar.quote": "插入引用文本",
"toolbar.unordered-list": "添加项目符号列表",
"user.my-comments": "My recent comments",
"user.recent-comments": "Recent comments",
"user.my-comments": "My comments",
"user.comments": "Comments",
"vote.anonymous": "匿名用户无法投票",
"vote.deleted": "无法为已删除的评论投票",
"vote.guest": "登录以投票",