Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenge tabs #90

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/web/components/icons/liked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 11 additions & 10 deletions apps/web/components/molecules/commentItem/commentItem.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
import Image from 'next/image';
import { Card } from 'ui';
import { getTimeDiffFromTimestamp } from 'utils/timeDifference/getTimeDiffFromTimestamp';
import type { Comment } from '../../../types/types';
import { ReactComponent as Reply } from '/components/icons/reply.svg';
import { ReactComponent as Like } from '/components/icons/like.svg';
import { CommentReply } from 'molecules/commentItem/commentReply';
import { UserAvatar } from 'molecules/userAvatar/userAvatar';

type CommentItemProps = Comment;

export const CommentItem = ({
author,
avatar,
comment,
date,
timestamp,
}: CommentItemProps) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make a comment: Comment prop accepting an object. No need for spreading then and you have everything contained in one object

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make a comment: Comment prop accepting an object. No need for spreading then and you have everything contained in one object

Sure, but you neeed to destructure it later or write redundant object prop calls

comment.timestamp
comment.avatar
...and so on

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather have a param destructurization than something like that tbh.
As for now the CommentItemProps is redundant as the props could be directly typed as Comment.
I used to spread props but over the time I learned in most of the cases it is better to explicitly pass props. There are some exceptions ofc (for example register function for form libs)

return (
<div className="flex-col w-full py-2 mx-auto bg-white sm:px-4 md:px-4 md:w-2/3">
<Card tag="div">
<div className="flex flex-row md-10">
<Image
className="object-cover w-12 h-12 border-2 border-gray-300 rounded-full"
alt="Noob master's avatar"
src={avatar}
width={48}
height={48}
/>
<UserAvatar avatar={avatar} size={12} />
<div className="flex-col mt-1">
<div className="flex items-center flex-1 px-4 font-bold leading-tight">
{author}
<span className="ml-2 text-xs font-normal text-gray-500">
{getTimeDiffFromTimestamp(date)}
{getTimeDiffFromTimestamp(timestamp)}
</span>
</div>
<div className="flex-1 px-2 ml-2 text-sm font-medium leading-loose text-gray-600">
Expand All @@ -46,6 +41,12 @@ export const CommentItem = ({
</button>
</div>
</div>
<CommentReply
author={author}
avatar={avatar}
comment={comment}
timestamp={timestamp}
/>
</Card>
</div>
);
Expand Down
109 changes: 0 additions & 109 deletions apps/web/components/molecules/commentItem/commentItemWithReply.tsx

This file was deleted.

45 changes: 45 additions & 0 deletions apps/web/components/molecules/commentItem/commentReply.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Comment } from '../../../types/types';
import { ReactComponent as Reply } from '/components/icons/reply.svg';
import { ReactComponent as Liked } from '/components/icons/liked.svg';
import { getTimeDiffFromTimestamp } from 'utils/timeDifference/getTimeDiffFromTimestamp';
import { UserAvatar } from 'molecules/userAvatar/userAvatar';

type CommentItemWithReplyProps = Comment;

export const CommentReply = ({
avatar,
author,
timestamp,
comment,
}: CommentItemWithReplyProps) => {
// TODO: Add reply functionality
return (
<>
<hr className="my-2 ml-16 border-gray-200" />
<div className="flex flex-row pt-1 md-10 md:ml-16">
<UserAvatar avatar={avatar} size={12} />
<div className="flex-col mt-1">
<div className="flex items-center flex-1 px-4 font-bold leading-tight">
{author}
<span className="ml-2 text-xs font-normal text-gray-500">
{getTimeDiffFromTimestamp(timestamp)}
</span>
</div>
<div className="flex-1 px-2 ml-2 text-sm font-medium leading-loose text-gray-600">
{comment}
</div>
<button className="inline-flex items-center px-1 pt-2 ml-1 flex-column">
<div className="w-5 h-5">
<Reply />
</div>
</button>
<button className="inline-flex items-center px-1 -ml-1 flex-column">
<div className="w-5 h-5">
<Liked />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This buttons with icons are a good candidate for a separate component as well ;)

</div>
</button>
</div>
</div>
</>
);
};
14 changes: 7 additions & 7 deletions apps/web/components/molecules/comments/comments.mock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,33 @@ export const commentsMock: Comment[] = [
'To zadanie frontendowe wydaje się bardzo wymagające, ale na pewno pozwoli na rozwinięcie umiejętności i poszerzenie wiedzy. Trzeba będzie zwrócić uwagę na każdy szczegół, aby stworzyć estetyczny i responsywny interfejs.',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
date: 1264938840000,
timestamp: 1264938840000,
},

{
author: 'Maria Wójcik',
comment:
'Mam nadzieję, że w tym zadaniu będzie można wykorzystać najnowsze technologie i narzędzia, co pozwoli na jeszcze lepsze efekty. Czekam na wyzwania, które pozwolą mi się rozwijać i poszerzać horyzonty.',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
date: 1678794840000,
'https://images.unsplash.com/photo-1509839862600-309617c3201e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80',
timestamp: 1678794840000,
},

{
author: 'Piotr Kowalczyk',
comment:
'Zadanie frontendowe to wspaniała okazja, aby pokazać swoje umiejętności projektowania interfejsów użytkownika. Nie mogę się doczekać, aby zacząć pracę i zobaczyć, co uda mi się stworzyć.',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
date: 1672444800000,
'https://images.unsplash.com/photo-1556157382-97eda2d62296?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80',
timestamp: 1672444800000,
},

{
author: 'Karolina Nowakowska',
comment:
'Zadanie frontendowe może być trudne, ale warto podjąć wyzwanie. Będzie to okazja do nauki nowych technologii i rozwoju umiejętności, co na pewno będzie przydatne w dalszej karierze.',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
date: 1678808591856,
'https://images.unsplash.com/photo-1607982863027-0cb6818ee8b7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80',
timestamp: 1678808591856,
},
];
7 changes: 1 addition & 6 deletions apps/web/components/molecules/comments/comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import { AddComment } from 'organisms/addComment/addComment';
import { CommentItem } from 'molecules/commentItem/commentItem';
import { commentsMock } from 'molecules/comments/comments.mock';

const comments = commentsMock.sort(
(
a: { author: string; comment: string; avatar: string; date: number },
b: { author: string; comment: string; avatar: string; date: number },
) => b.date - a.date,
);
const comments = commentsMock.sort((a, b) => b.timestamp - a.timestamp);
ssynowiec marked this conversation as resolved.
Show resolved Hide resolved

export const Comments = () => {
return (
Expand Down
12 changes: 2 additions & 10 deletions apps/web/components/molecules/opinionItem/opinionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Card, Heading, Text } from 'ui';
import Image from 'next/image';
import clsx from 'clsx';
import type { Opinion } from '../../../types/types';
import { UserAvatar } from 'molecules/userAvatar/userAvatar';

type OpinionItemProps = Opinion;

Expand All @@ -15,14 +15,7 @@ export const OpinionItem = ({
<div className="p-2">
<Card tag="div">
<div className="flex flex-col md:flex-row justify-center items-center">
<Image
src={avatar}
alt=""
width={1000}
height={1000}
className="w-full h-full rounded-full w-24 h-24 object-cover"
aria-hidden="true"
/>
<UserAvatar avatar={avatar} size={24} />
<div className="md:pl-5">
<Heading tag="h3" size="large" className="font-bold">
{author}
Expand All @@ -40,7 +33,6 @@ export const OpinionItem = ({
xmlns="http://www.w3.org/2000/svg"
key={i}
>
{/*<title>First star</title>*/}
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"></path>
</svg>
);
Expand Down
10 changes: 5 additions & 5 deletions apps/web/components/molecules/opinions/opinions.mock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import type { Opinion } from '../../../types/types';

export const opinions: Opinion[] = [
{
author: 'Jan Kowalski',
author: 'Adam Nowak',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
rating: 5,
comment:
'Zadanie programistyczne, które otrzymałem, było dobrze sformułowane i precyzyjnie opisywało wymagania dotyczące tworzenia aplikacji internetowej. Zadanie miało na celu zaimplementowanie funkcjonalności wyszukiwania produktów w bazie danych i wyświetlenia wyników na stronie internetowej.',
},
{
author: 'Jan Kowalski',
author: 'Maria Wójcik',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
'https://images.unsplash.com/photo-1509839862600-309617c3201e?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80',
rating: 5,
comment:
'Zadanie programistyczne, które otrzymałem, było dobrze sformułowane i precyzyjnie opisywało wymagania dotyczące tworzenia aplikacji internetowej. Zadanie miało na celu zaimplementowanie funkcjonalności wyszukiwania produktów w bazie danych i wyświetlenia wyników na stronie internetowej.',
},
{
author: 'Jan Kowalski',
author: 'Piotr Kowalczyk',
avatar:
'https://images.unsplash.com/photo-1633332755192-727a05c4013d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2960&q=80',
'https://images.unsplash.com/photo-1556157382-97eda2d62296?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2070&q=80',
rating: 4,
comment:
'Zadanie programistyczne, które otrzymałem, było dobrze sformułowane i precyzyjnie opisywało wymagania dotyczące tworzenia aplikacji internetowej. Zadanie miało na celu zaimplementowanie funkcjonalności wyszukiwania produktów w bazie danych i wyświetlenia wyników na stronie internetowej.',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is mock data but it would be cool to see some variety and how it looks and behaves with different lengths of the comments. 😄
Also is it possible for the rating to be 0 or negative or above 5? What then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User can't give negative or above 5 rating

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any validation for that on the backend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not now

Expand Down
4 changes: 2 additions & 2 deletions apps/web/components/molecules/opinions/opinions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OpinionItem } from 'molecules/opinionItem/opinionItem';
import { NewOpinionForm } from 'organisms/newOpinionForm/newOpinionForm';
import { AddOpinion } from 'organisms/addOpinion/addOpinion';
import { OpinionStats } from 'molecules/opinonStats/opinionStats';
import { ProtectedComponent } from 'organisms/protectedComponent/protectedComponent';
import { opinions } from 'molecules/opinions/opinions.mock';
Expand All @@ -10,7 +10,7 @@ export const Opinions = () => {
<div className="flex flex-col md:flex-row">
<div className="p-2 w-full md:w-1/2">
<ProtectedComponent info="Zaloguj się aby dodać opinię.">
<NewOpinionForm />
<AddOpinion />
</ProtectedComponent>
</div>
<OpinionStats opinions={opinions} />
Expand Down
4 changes: 2 additions & 2 deletions apps/web/components/molecules/opinonStats/opinionStats.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Card, Heading } from 'ui';
import type { Opinion } from '../../../types/types';
import { OpinionPolishPlurals } from 'molecules/opinonStats/opinionStats.utils';
import { opinionPolishPlurals } from 'molecules/opinonStats/opinionStats.utils';

type OpinionStatsProps = {
opinions: Opinion[];
Expand Down Expand Up @@ -69,7 +69,7 @@ export const OpinionStats = ({ opinions }: OpinionStatsProps) => {
<p className="ml-2 text-sm font-medium">4.95 / 5</p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calculate the average, based on the opinions. And map it to display the stars instead of copying them.
But I asume it is something to implement in the future ;)

</div>
<p className="text-sm font-medium text-gray-500 dark:text-gray-400">
{OpinionPolishPlurals(opinions.length)}
{opinionPolishPlurals(opinions.length)}
</p>
</div>
</Card>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { polishPlurals } from 'utils/plurals/PolishPlurals';

export const OpinionPolishPlurals = (value: number) => {
export const opinionPolishPlurals = (value: number) => {
const OpinionsPluralsPosts = {
zero: 'opinii',
one: 'opinia',
Expand Down
23 changes: 23 additions & 0 deletions apps/web/components/molecules/userAvatar/userAvatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Image from 'next/image';
import clsx from 'clsx';

type CommentUserAvatarProps = {
avatar: string;
size?: number;
};

export const UserAvatar = ({ avatar, size = 24 }: CommentUserAvatarProps) => {
const sizeClass = `w-${size} h-${size}`;
return (
<Image
alt=""
src={avatar}
ssynowiec marked this conversation as resolved.
Show resolved Hide resolved
width={1000}
height={1000}
className={clsx(
'object-cover border-2 border-gray-300 rounded-full',
sizeClass,
)}
/>
);
};
Loading