Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions src/components/ArticleItemCard.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
border-bottom: 1px solid #e5e7eb;
}

.link {
text-decoration: none;
}

.content_wrapper {
display: flex;
justify-content: space-between;
Expand Down
35 changes: 19 additions & 16 deletions src/components/ArticleItemCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,32 @@ import profileImg from "@/assets/images/profile.svg";
import heartIcon from "@/assets/icons/heart.svg";
import Image from "next/image";
import { formatDate } from "@/utils/formattedDate";
import Link from "next/link";

export function ArticleItemCard({ title, content, image, likeCount, writer, updatedAt }: Article) {
export function ArticleItemCard({ id, title, content, image, likeCount, writer, updatedAt }: Article) {
const formattedDate = formatDate(updatedAt);

return (
<div className={style.container}>
<div className={style.content_wrapper}>
<p>{content}</p>
<div>
<img src={image || profileImg.src} alt={title} />
<Link href={`/boards/${id}`} className={style.link}>
<div className={style.content_wrapper}>
<p>{content}</p>
<div>
<img src={image || profileImg.src} alt={title} />
</div>
</div>
</div>
<div className={style.content_footer}>
<div className={style.content_footer_wrapper}>
<Image src={profileImg} alt="프로필" width={24} height={24} />
<p className={style.nickname}>{writer.nickname}</p>
<p className={style.date}>{formattedDate}</p>
<div className={style.content_footer}>
<div className={style.content_footer_wrapper}>
<Image src={profileImg} alt="프로필" width={24} height={24} />
<p className={style.nickname}>{writer.nickname}</p>
<p className={style.date}>{formattedDate}</p>
</div>
<div className={style.likeCount}>
<Image src={heartIcon} alt="좋아요" width={24} height={24} />
<p>{likeCount}</p>
</div>
</div>
<div className={style.likeCount}>
<Image src={heartIcon} alt="좋아요" width={24} height={24} />
<p>{likeCount}</p>
</div>
</div>
</Link>
</div>
);
}
4 changes: 4 additions & 0 deletions src/components/BestItemCard.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
background-color: #f9fafb;
}

.link {
text-decoration: none;
}
Comment on lines +11 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

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

자주 등장하게 될텐데 저는 개인적으로 이런 스타일은 global에 적용해두긴 해요ㅎㅎ;;

예외적으로 몇개 있긴 한데, 링크에 underline도 그렇고 appearance도 그래요...!
한번 참고만 해두셔도 좋을것같아요~

https://developer.mozilla.org/en-US/docs/Web/CSS/appearance

물론 해주신 방법대로 해도 문제될건 없습니다!


.content_wrapper {
display: flex;
gap: 20px;
Expand Down
35 changes: 19 additions & 16 deletions src/components/BestItemCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,32 @@ import style from "./BestItemCard.module.css";
import badge from "@/assets/images/img_badge.svg";
import heart from "@/assets/icons/heart.svg";
import { formatDate } from "@/utils/formattedDate";
import Link from "next/link";

export default function BestItemCard({ content, updatedAt, likeCount, writer, image, title }: Article) {
export default function BestItemCard({ id, content, updatedAt, likeCount, writer, image, title }: Article) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

ArticleItemCard 이랑 차이점이 size밖에 없는것같은데, 이런 부분은 아에 props로 size를 지정해주면 오히려 관리하기가 좀더 좋을것같아요ㅎㅎ!

const formattedDate = formatDate(updatedAt);
Copy link
Collaborator

Choose a reason for hiding this comment

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

큰건 아닌데, 이런 상수성 변수들은 차라리 useMemo 로 감싸두면 좋긴 해요ㅎㅎ!
useMemo랑 useCallback 쓰는 습관을 들이면 좋긴 한데, React 버전 올라가면서 없어질꺼라는 얘기도 나오긴 하더라구요;;


return (
<div className={style.container}>
<Image src={badge.src || badge} alt="Best" width={102} height={30} />
<div className={style.content_wrapper}>
<p>{content}</p>
<div>
<img src={image} alt={title} />
</div>
</div>
<div className={style.card_footer}>
<div className={style.card_footer_wrapper}>
<p>{writer.nickname}</p>
<Link href={`boards/${id}`} className={style.link}>
<div className={style.container}>
<Image src={badge.src || badge} alt="Best" width={102} height={30} />
<div className={style.content_wrapper}>
<p>{content}</p>
<div>
<Image src={heart} alt="좋아요" />
<p>{likeCount}</p>
<img src={image} alt={title} />
</div>
</div>
<div className={style.card_footer}>
<div className={style.card_footer_wrapper}>
<p>{writer.nickname}</p>
<div>
<Image src={heart} alt="좋아요" />
<p>{likeCount}</p>
</div>
</div>
<p className={style.updated_date}>{formattedDate}</p>
</div>
<p className={style.updated_date}>{formattedDate}</p>
</div>
</div>
</Link>
);
}
2 changes: 1 addition & 1 deletion src/components/BoardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default function BoardHeader() {
const router = useRouter();

const handleClick = () => {
router.push("/boards/write");
router.push("/addboard");
};

return (
Expand Down
43 changes: 43 additions & 0 deletions src/components/CommentCard.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.container {
display: flex;
flex-direction: column;
gap: 4px;
padding-bottom: 12px;
background-color: #fcfcfc;
border-bottom: 1px solid #e5e7eb;
}

.wrapper {
display: flex;
flex-direction: column;
gap: 24px;
}

.content {
font-size: 14px;
line-height: 24px;
color: #1f2937;
}

.info {
display: flex;
gap: 8px;
}

.info div {
display: flex;
flex-direction: column;
gap: 4px;
}

.nickname {
font-size: 12px;
line-height: 18px;
color: #4b5563;
}

.date {
font-size: 12px;
line-height: 18px;
color: #9ca3af;
}
28 changes: 28 additions & 0 deletions src/components/CommentCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import style from "./CommentCard.module.css";
import ProfileImg from "@/assets/images/profile.svg";
import { Comment } from "@/types";
import { formatRelativeTime } from "@/utils/formatRelativeTime";
import Image from "next/image";

interface CommentProps {
comment: Comment;
}

export default function CommentCard({ comment }: CommentProps) {
const formatDate = formatRelativeTime(comment.updatedAt);

return (
<div className={style.container}>
<div className={style.wrapper}>
<p className={style.content}>{comment.content}</p>
<div className={style.info}>
<Image src={ProfileImg} alt="프로필이미지" width={32} height={32} />
<div>
<p className={style.nickname}>{comment.writer.nickname}</p>
<p className={style.date}>{formatDate}</p>
</div>
</div>
</div>
</div>
);
}
118 changes: 118 additions & 0 deletions src/components/LoginForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
.formGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-bottom: 1rem;
}

.label {
font-size: 0.875rem;
font-weight: 500;
}

.inputContainer {
position: relative;
}

.inputField {
width: 100%;
padding: 0.75rem 2.5rem 0.75rem 0.75rem;
background-color: #f9fafb;
border: 1px solid #d1d5db;
border-radius: 0.375rem;
font-size: 1rem;
}

.inputField:focus {
outline: 2px solid #3692ff;
outline-offset: -2px;
}

.toggleButton {
position: absolute;
right: 0.75rem;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
cursor: pointer;
color: #6b7280;
}

.button {
width: 100%;
padding: 0.75rem;
background-color: #9ca3af;
color: #ffffff;
border: none;
border-radius: 0.375rem;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s;
margin-top: 1rem;
}

.button:hover:not(:disabled) {
background-color: #6b7280;
}

.button:disabled {
background-color: #d1d5db;
cursor: not-allowed;
}

.divider {
position: relative;
width: 100%;
height: 1px;
background-color: #d1d5db;
margin: 2rem 0;
}

.dividerText {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
padding: 0 0.5rem;
font-size: 0.875rem;
color: #6b7280;
}

.socialButtons {
display: flex;
gap: 1rem;
justify-content: center;
margin-bottom: 1rem;
}

.socialButton {
padding: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 9999px;
cursor: pointer;
transition: background-color 0.2s;
}

.socialButton:hover {
background-color: #f9fafb;
}

.socialImg {
width: 1.5rem;
height: 1.5rem;
}

.prompt {
text-align: center;
font-size: 0.875rem;
color: #4b5563;
}

.prompt a {
color: #3692ff;
text-decoration: underline;
cursor: pointer;
}
Loading
Loading