From b77219c814c195583304344a9c4e6014aeeb5ebe Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:58:55 +0900 Subject: [PATCH 01/14] =?UTF-8?q?=E2=9C=A8=20HeartIcon=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fill props를 통해 컬러를 변경할 수 있게 설정 --- components/Heart/HeartIcon.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 components/Heart/HeartIcon.tsx diff --git a/components/Heart/HeartIcon.tsx b/components/Heart/HeartIcon.tsx new file mode 100644 index 0000000..a1d461f --- /dev/null +++ b/components/Heart/HeartIcon.tsx @@ -0,0 +1,19 @@ +/** + * Heart icon + * @param {string} fill - 색상 + */ +export default function HeartIcon({ fill = '#8F95B2' }: { fill?: string }) { + return ( + + + + ); +} From fafa373501ff0164f8de6cd3830c51c2522faeac Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:59:38 +0900 Subject: [PATCH 02/14] =?UTF-8?q?=E2=9C=A8=20Heart=20=EC=B9=B4=EC=9A=B4?= =?UTF-8?q?=ED=8C=85=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 호출 시 onClick이 있으면 컬러 변경 - 없을 경우 클릭 없이 정적 요소로 사용 --- components/Heart/Heart.tsx | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 components/Heart/Heart.tsx diff --git a/components/Heart/Heart.tsx b/components/Heart/Heart.tsx new file mode 100644 index 0000000..ec19f8e --- /dev/null +++ b/components/Heart/Heart.tsx @@ -0,0 +1,43 @@ +import { useState } from 'react'; + +import HeartIcon from './HeartIcon'; + +interface HeartProps { + initialCount: number; + onClick?: () => void; +} + +/** + * Heart count component + * @param {number} initialCount - 초기 카운트 수 + * @param {function} onClick - 클릭 시 동작 할 이벤트(옵션) + * @example console.log('클릭')} /> + */ +export default function Heart({ initialCount, onClick }: HeartProps) { + const [isClicked, setIsClicked] = useState(false); + const [count, setCount] = useState(initialCount); + + const handleClick = () => { + if (onClick) { + onClick(); + setIsClicked((prev) => !prev); + setCount((prevCount) => (isClicked ? prevCount - 1 : prevCount + 1)); + } + }; + + const clickStyles = { + icon: isClicked ? 'var(--red-100)' : 'var(--gray-400)', + text: isClicked && 'text-red-100', + }; + return ( + + + + {count} + + + ); +} From fbdc635033733d0744a596133818a855da205e10 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:59:49 +0900 Subject: [PATCH 03/14] =?UTF-8?q?=F0=9F=A7=AA=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/test/heart.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 pages/test/heart.tsx diff --git a/pages/test/heart.tsx b/pages/test/heart.tsx new file mode 100644 index 0000000..0ea4e38 --- /dev/null +++ b/pages/test/heart.tsx @@ -0,0 +1,10 @@ +import Heart from '@/components/Heart/Heart'; + +export default function HeartTest() { + return ( + <> + + console.log('클릭')} /> + > + ); +} From 5608b2813a70ed7cb2d68b0b0671af01c67623c8 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:29:34 +0900 Subject: [PATCH 04/14] =?UTF-8?q?=E2=9C=A8=20iso=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=20=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/dateConversion.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 utils/dateConversion.js diff --git a/utils/dateConversion.js b/utils/dateConversion.js new file mode 100644 index 0000000..05dcd09 --- /dev/null +++ b/utils/dateConversion.js @@ -0,0 +1,25 @@ +/** + * isoString으로 받아온 날짜를 {year}.{month}.{day} 타입으로 변환해주는 함수 입니다. + * 현재 시간 기준 24시간 이내 일 경우 '{time}분 전', '{time}시간 전' 으로 표기 됩니다. + * @param {string} isoString + * @returns {string} + */ +export default function dateConversion(isoString) { + const createdDate = new Date(isoString); // 생성일 + const currentDate = new Date(); // 현재 날짜 + const timeDifference = currentDate - createdDate; // 오차 계산 + const hoursDifference = Math.floor(timeDifference / (1000 * 60 * 60)); // 시간 환산 + const minutesDifference = Math.floor(timeDifference / (1000 * 60)); // 분 환산 + + if (hoursDifference < 1) { + return `${minutesDifference}분 전`; // 생성한지 1시간이 안되었을 때 + } else if (hoursDifference < 24) { + return `${hoursDifference}시간 전`; // 생성한지 24시간이 안되었을 때 + } else { + // 24시간 이후로는 날짜로 표기 + const year = createdDate.getFullYear(); + const month = (createdDate.getMonth() + 1).toString().padStart(2, '0'); + const day = createdDate.getDate().toString().padStart(2, '0'); + return `${year}-${month}-${day}`; + } +} From 88f1ee0afe883783b2a8c738117480d9d35ce3b0 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:52:17 +0900 Subject: [PATCH 05/14] =?UTF-8?q?=E2=9C=A8=20=EB=82=A0=EC=A7=9C=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/{dateConversion.js => dateConversion.ts} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename utils/{dateConversion.js => dateConversion.ts} (87%) diff --git a/utils/dateConversion.js b/utils/dateConversion.ts similarity index 87% rename from utils/dateConversion.js rename to utils/dateConversion.ts index 05dcd09..643999d 100644 --- a/utils/dateConversion.js +++ b/utils/dateConversion.ts @@ -4,10 +4,10 @@ * @param {string} isoString * @returns {string} */ -export default function dateConversion(isoString) { +export default function dateConversion(isoString: string): string { const createdDate = new Date(isoString); // 생성일 const currentDate = new Date(); // 현재 날짜 - const timeDifference = currentDate - createdDate; // 오차 계산 + const timeDifference = currentDate.getTime() - createdDate.getTime(); // 오차 계산 const hoursDifference = Math.floor(timeDifference / (1000 * 60 * 60)); // 시간 환산 const minutesDifference = Math.floor(timeDifference / (1000 * 60)); // 분 환산 From bb9e6b826cb19471eb52672259e31c83e3708724 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:52:56 +0900 Subject: [PATCH 06/14] =?UTF-8?q?=F0=9F=94=A8=20alias=EC=97=90=20utils=20h?= =?UTF-8?q?ooks=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index c32ac62..bc5a593 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,14 +18,18 @@ "paths": { "@/components/*": ["components/*"], "@/styles/*": ["styles/*"], - "@/pages/*": ["pages/*"] + "@/pages/*": ["pages/*"], + "@/utils/*": ["utils/*"], + "@/hooks/*": ["hooks/*"] } }, "include": [ "pages/**/*.ts", "pages/**/*.tsx", "components/**/*.ts", - "components/**/*.tsx" + "components/**/*.tsx", + "utils/**/*.ts", + "utils/**/*.tsx" ], "exclude": ["node_modules", "dist", ".next"] } From d3fad6943dfb2b2cf9afd5920606e697cda429ed Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:53:41 +0900 Subject: [PATCH 07/14] =?UTF-8?q?=F0=9F=93=84=20boards=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/boards/index.tsx | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 pages/boards/index.tsx diff --git a/pages/boards/index.tsx b/pages/boards/index.tsx new file mode 100644 index 0000000..5756386 --- /dev/null +++ b/pages/boards/index.tsx @@ -0,0 +1,3 @@ +export default function Boards() { + return Boards; +} From c78e136b640bf8958a7db7e50183fd96ff95bf2a Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:53:59 +0900 Subject: [PATCH 08/14] =?UTF-8?q?=E2=9C=A8=20BoardCard=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/boards/components/BoardCard.tsx | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 pages/boards/components/BoardCard.tsx diff --git a/pages/boards/components/BoardCard.tsx b/pages/boards/components/BoardCard.tsx new file mode 100644 index 0000000..cd502eb --- /dev/null +++ b/pages/boards/components/BoardCard.tsx @@ -0,0 +1,42 @@ +import Image from 'next/image'; +import Link from 'next/link'; + +import Heart from '@/components/Heart/Heart'; +import dateConversion from '@/utils/dateConversion'; + +interface BoardCardProps { + id: number; + image: string; + title: string; + name: string; + updatedAt: string; + likeCount: number; +} + +export default function BoardCard({ + id, + image, + title = '게시글 제목', + name = '유저 이름', + updatedAt = '2021-01-01T00:00:00.000Z', + likeCount = 0, +}: BoardCardProps) { + return ( + + + + + + {title} + + {name} + {dateConversion(updatedAt)} + + + + + ); +} From 7ff15780754773206a013ec113489bdf11d82d5b Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:54:41 +0900 Subject: [PATCH 09/14] =?UTF-8?q?=F0=9F=A7=AA=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8C=85=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 더미 데이터로 노출 - 외부 이미지 사용으로 next.config.ts 추가 --- next.config.ts | 3 +++ pages/test/boardCard.tsx | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 pages/test/boardCard.tsx diff --git a/next.config.ts b/next.config.ts index 0748d34..fbfc619 100644 --- a/next.config.ts +++ b/next.config.ts @@ -3,6 +3,9 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { /* config options here */ reactStrictMode: true, + images: { + domains: ['via.placeholder.com'], // 허용할 이미지 도메인 추가 + }, }; export default nextConfig; diff --git a/pages/test/boardCard.tsx b/pages/test/boardCard.tsx new file mode 100644 index 0000000..ff6d83e --- /dev/null +++ b/pages/test/boardCard.tsx @@ -0,0 +1,27 @@ +import BoardCard from '../boards/components/BoardCard'; + +const data = { + updatedAt: '2024-12-17T08:25:07.098Z', + createdAt: '2024-12-17T08:25:07.098Z', + likeCount: 0, + writer: { + name: '이름', + id: 1, + }, + image: 'https://via.placeholder.com/1000', + title: '게시글 제목입니다.', + id: 1, +}; + +export default function BoardCardTest() { + return ( + + ); +} From 7e4769e66da245d2aaa56c38a38d5fd024259867 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:38:15 +0900 Subject: [PATCH 10/14] =?UTF-8?q?=F0=9F=94=A8=20div=EC=99=80=20button?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=20=EC=A1=B0=EA=B1=B4=EC=8B=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - onClick이 있을때는 button 태그와 cursor-pointer - onClick이 없을때는 div태그 --- components/Heart/Heart.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/components/Heart/Heart.tsx b/components/Heart/Heart.tsx index ec19f8e..14cd890 100644 --- a/components/Heart/Heart.tsx +++ b/components/Heart/Heart.tsx @@ -29,15 +29,18 @@ export default function Heart({ initialCount, onClick }: HeartProps) { icon: isClicked ? 'var(--red-100)' : 'var(--gray-400)', text: isClicked && 'text-red-100', }; + + const Wrapper = onClick ? 'button' : 'div'; + return ( - {count} - + ); } From 1bdee5f617b6f38f6227766a3e9ae1c1c3471dbb Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:06:23 +0900 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=94=A8=20image=EA=B0=80=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=EB=95=8C=20=EB=85=B8=EC=B6=9C=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 직접 아이콘 만들었습니다 ㅎ --- pages/boards/components/BoardCard.tsx | 10 +++++++--- public/icon/icon-no-image.svg | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 public/icon/icon-no-image.svg diff --git a/pages/boards/components/BoardCard.tsx b/pages/boards/components/BoardCard.tsx index cd502eb..cdb9bda 100644 --- a/pages/boards/components/BoardCard.tsx +++ b/pages/boards/components/BoardCard.tsx @@ -24,10 +24,14 @@ export default function BoardCard({ return ( - - + + {title} diff --git a/public/icon/icon-no-image.svg b/public/icon/icon-no-image.svg new file mode 100644 index 0000000..fa7c7ee --- /dev/null +++ b/public/icon/icon-no-image.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + From 39fe7f6b33068ad25e45b272d00ac2b29f15f215 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:06:44 +0900 Subject: [PATCH 12/14] =?UTF-8?q?=F0=9F=A7=AA=20image=20=EC=97=86=EC=9D=84?= =?UTF-8?q?=EB=95=8C=EC=99=80=20=EC=9E=88=EC=9D=84=EB=95=8C=20=EA=B5=AC?= =?UTF-8?q?=EB=B6=84=ED=95=98=EC=97=AC=20test=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/test/boardCard.tsx | 41 +++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/pages/test/boardCard.tsx b/pages/test/boardCard.tsx index ff6d83e..fa20a6e 100644 --- a/pages/test/boardCard.tsx +++ b/pages/test/boardCard.tsx @@ -1,6 +1,19 @@ import BoardCard from '../boards/components/BoardCard'; -const data = { +const data_noImage = { + updatedAt: '2024-12-17T08:25:07.098Z', + createdAt: '2024-12-17T08:25:07.098Z', + likeCount: 0, + writer: { + name: '이름', + id: 1, + }, + image: '', + title: '게시글 제목입니다.', + id: 1, +}; + +const data_Image = { updatedAt: '2024-12-17T08:25:07.098Z', createdAt: '2024-12-17T08:25:07.098Z', likeCount: 0, @@ -15,13 +28,23 @@ const data = { export default function BoardCardTest() { return ( - + + + + ); } From 6bfcd7b061f72cd5615b0c724331be5db0864ed4 Mon Sep 17 00:00:00 2001 From: tare <59001439+junghwa1996@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:11:55 +0900 Subject: [PATCH 13/14] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20JSdoc=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/boards/components/BoardCard.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pages/boards/components/BoardCard.tsx b/pages/boards/components/BoardCard.tsx index cdb9bda..e7bfd42 100644 --- a/pages/boards/components/BoardCard.tsx +++ b/pages/boards/components/BoardCard.tsx @@ -13,13 +13,22 @@ interface BoardCardProps { likeCount: number; } +/** + * 게시글 카드 컴포넌트 + * @param {number} id - 게시글 id + * @param {string} image - 게시글 이미지 + * @param {string} title - 게시글 제목 + * @param {string} name - 유저 이름 + * @param {string} updatedAt - 게시글 수정일 + * @param {number} likeCount - 게시글 좋아요 수 + */ export default function BoardCard({ id, image, - title = '게시글 제목', - name = '유저 이름', - updatedAt = '2021-01-01T00:00:00.000Z', - likeCount = 0, + title, + name, + updatedAt, + likeCount, }: BoardCardProps) { return ( Date: Wed, 18 Dec 2024 11:47:53 +0900 Subject: [PATCH 14/14] =?UTF-8?q?=F0=9F=94=A8=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - image alt 동적으로 생성 - title 길어질 경우 말줄임표 --- pages/boards/components/BoardCard.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pages/boards/components/BoardCard.tsx b/pages/boards/components/BoardCard.tsx index e7bfd42..5e320da 100644 --- a/pages/boards/components/BoardCard.tsx +++ b/pages/boards/components/BoardCard.tsx @@ -38,12 +38,14 @@ export default function BoardCard({ - {title} + + {title} + {name} {dateConversion(updatedAt)}
{name}