Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
592a3d9
feat: 베스트 게시물 기능 추가
Jan 17, 2025
c94f749
feat: 게시글 SSR로 작업
Jan 17, 2025
7c3cfc5
feat: 게시글 orderBy 기능 작업
Jan 17, 2025
498ba56
feat: 게시글 검색 기능 구현
Jan 17, 2025
32ae842
feat: 반응형 작업 완료
Jan 18, 2025
8d3017f
feat: 반응형 pagesize 작업 및 로딩중, 비어있음 적용
Jan 18, 2025
2f83b8f
feat: pagesize 무한스크롤 기능 및 useOutsideClick hook 추가
Jan 18, 2025
87d6588
fix: 네트리파이 배포 오류 수정
Jan 18, 2025
e8cb077
style: css파일 삭제 후 인라인속성으로 변경
Jan 18, 2025
ecc2dbb
fix: 반응형 버그 수정
Jan 22, 2025
0011b09
refactor: 날짜포맷 dayjs 라이브러리로 변경
Jan 22, 2025
863aca2
pref: boards 데이터 불러오기 성능 개선
Jan 22, 2025
406d403
pref: useCallback으로 boards 데이터 불러오기 함수 메모이제이션
Jan 22, 2025
3871bf7
style: board 검색 form태그 추가 시멘틱하게 수정
Jan 22, 2025
fe6b0f8
feat: 게시글 작성, 게시글 상세 작업완료
Jan 22, 2025
ae625b6
refactor: 컴포넌트 분리
Jan 22, 2025
a63a913
feat: 입력값 입력 시 버튼 활성화
Jan 22, 2025
9fe291d
feat: 반응형 작업완료
Jan 23, 2025
5d3c518
fix: 반응형 스타일 수정
Jan 23, 2025
59e5603
feat: 회원가입, 로그인 html, css 작성
Jan 25, 2025
2777c37
feat: 로그인, 회원가입 기능 작업 완료
Jan 27, 2025
eb288f0
Merge branch 'Next-김승석' into Next-김승석-sprint11
kss761036 Jan 27, 2025
9ba593a
Merge branch 'Next-김승석' into Next-김승석-sprint11
kss761036 Feb 5, 2025
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
475 changes: 461 additions & 14 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
},
"dependencies": {
"@svgr/webpack": "^8.1.0",
"axios": "^1.7.9",
"dayjs": "^1.11.13",

"next": "14.2.23",
"react": "^18",
"react-dom": "^18",
Expand Down
Binary file added public/assets/img/comment_empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions public/assets/img/icon_add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/assets/img/icon_back.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/img/icon_close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/img/icon_dot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions public/assets/img/icon_google.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions public/assets/img/icon_kakao.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/assets/img/icon_wish_active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/components/board-best-list.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
line-clamp: 2;
}
.board_best_box .content figure {
overflow: hidden;
display: block;
width: 70px;
height: 70px;
Expand Down
2 changes: 1 addition & 1 deletion src/components/board-best-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import formatDate from "@/lib/format-data";
export default function BoardBestList(data: Article) {
return (
<li className={styles.board_best_box}>
<Link href="">
<Link href={`/board/${data.id}`}>
<div className={styles.best}>
<img src="/assets/img/icon_best.svg" alt="베스트" />
Best
Expand Down
41 changes: 41 additions & 0 deletions src/components/board-comment.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.comment {
padding-right: 30px;
position: relative;
padding-bottom: 12px;
margin-bottom: 24px;
border-bottom: 1px solid #e5e7eb;
}
.comment > h3 {
font-size: 14px;
font-weight: 400;
line-height: 1.7142;
margin-bottom: 24px;
}
.comment > .info {
display: flex;
}
.comment > .info > figure {
overflow: hidden;
display: block;
margin-right: 8px;
width: 32px;
height: 32px;
border-radius: 9999px;
}
.comment > .info > figure > img {
width: 100%;
height: 100%;
object-fit: cover;
}
.comment > .info > .right {
font-size: 12px;
line-height: 1.5;
}
.comment > .info > .right > p {
color: #4b5563;
margin-bottom: 4px;
}
.comment > .info > .right > span {
display: block;
color: #9ca3af;
}
37 changes: 37 additions & 0 deletions src/components/board-comment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import formatDateNow from "@/lib/format-data-now";
import ToggleMenu from "@/components/toggle-menu";
import styles from "./board-comment.module.css";
import { Comment } from "../../types";

/**
* 질문하기
* Comment 인터페이스의 타입을 전부 사용안했는데 오류가 나지않는 이유??
* 예를 들어 createdAt는 ?. 처럼 선택적이 아니지만 오류가 안남
*/

const BoardComment = (props: Comment) => {
return (
<li className={styles.comment}>
<ToggleMenu />
<h3>{props.content}</h3>
<div className={styles.info}>
<figure>
<img
src={
props.writer.image
? props.writer.image
: "/assets/img/icon_my.svg"
}
alt={props.writer.nickname}
/>
</figure>
<div className={styles.right}>
<p>{props.writer.nickname}</p>
<span>{formatDateNow(props.updatedAt)}</span>
</div>
</div>
</li>
);
};

export default BoardComment;
1 change: 1 addition & 0 deletions src/components/board-list.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
flex-direction: column;
}
.board_common_box .right figure {
overflow: hidden;
display: block;
margin-bottom: 16px;
margin-left: auto;
Expand Down
2 changes: 1 addition & 1 deletion src/components/board-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import formatDate from "@/lib/format-data";
export default function BoardList(data: Article) {
return (
<li className={styles.board_common_box}>
<Link href="">
<Link href={`/board/${data.id}`}>
<div className={styles.left}>
<h4>{data.title}</h4>
<div className={styles.bottom}>
Expand Down
24 changes: 24 additions & 0 deletions src/components/form/form-input.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

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

import React from "react";

type InputProps = React.InputHTMLAttributes<HTMLInputElement>;

const CustomInput: React.FC<InputProps> = (props) => {
  return <input {...props} />;
};

export default CustomInput;

이렇게props를 넘긴다면 보다 확장성 있겠죠?

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import styles from "./form.module.css";

interface Props {
type: string;
placeholder: string;
value?: string;
name?: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

const FormInput = ({ type, placeholder, value, name, onChange }: Props) => {
return (
<input
className={styles.input}
type={type}
placeholder={placeholder}
value={value}
name={name}
onChange={onChange}
/>
);
};

export default FormInput;
21 changes: 21 additions & 0 deletions src/components/form/form-textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styles from "./form.module.css";

interface Props {
placeholder: string;
height?: number;
value?: string;
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
}

const FormTextarea = ({ placeholder, height, value, onChange }: Props) => {
return (
<textarea
value={value}
onChange={onChange}
className={styles.textarea}
placeholder={placeholder}
style={{ height: height && `${height}px` }}></textarea>
);
};

export default FormTextarea;
52 changes: 52 additions & 0 deletions src/components/form/form.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.input {
display: block;
background: inherit;
border: none;
outline: none;
box-shadow: none;
border-radius: 0;
padding: 0;
overflow: visible;
}
.input {
width: 100%;
background-color: #f3f4f6;
font-size: 16px;
padding: 0 24px;
border-radius: 12px;
height: 56px;
display: flex;
align-items: center;
}
.input::placeholder {
color: #9ca3af;
}

.textarea {
display: block;
background: inherit;
border: none;
outline: none;
box-shadow: none;
border-radius: 0;
padding: 0;
overflow: visible;
resize: none;
}
.textarea {
width: 100%;
background-color: #f3f4f6;
font-size: 16px;
padding: 16px 24px;
border-radius: 12px;
height: 282px;
}
.textarea::placeholder {
color: #9ca3af;
}

@media (max-width: 744px) {
.textarea {
height: 200px;
}
}
1 change: 1 addition & 0 deletions src/components/header-layout.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
}
.header .my {
margin-left: auto;
cursor: pointer;
}

@media (max-width: 744px) {
Expand Down
35 changes: 32 additions & 3 deletions src/components/header-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
import Link from "next/link";
import styles from "./header-layout.module.css";
import { useEffect, useState } from "react";
import { useRouter } from "next/router";

export default function HeaderLayout() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const router = useRouter();

useEffect(() => {
const accessToken = localStorage.getItem("accessToken");
if (accessToken) {
setIsLoggedIn(true);
}
}, [router.pathname]);

const onLogout: React.MouseEventHandler<HTMLDivElement> = () => {
const result = confirm("로그아웃 하시겠습니까?");
if (result) {
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
localStorage.removeItem("user");
setIsLoggedIn(false);
} else {
return;
}
Comment on lines +19 to +26
Copy link
Collaborator

Choose a reason for hiding this comment

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

if(!result) return;
 localStorage.removeItem("accessToken");
      localStorage.removeItem("refreshToken");
      localStorage.removeItem("user");
      setIsLoggedIn(false);

이런식으로 early return기법을 사용해보는건 어떨까요

};
return (
<header className={styles.header}>
<div className="inner">
Expand All @@ -27,9 +50,15 @@ export default function HeaderLayout() {
<Link href="">중고마켓</Link>
</li>
</ul>
<Link className={styles.my} href="">
<img src="/assets/img/icon_my.svg" alt="마이페이지" />
</Link>
{isLoggedIn ? (
<div className={styles.my} onClick={onLogout}>
<img src="/assets/img/icon_my.svg" alt="마이페이지" />
</div>
) : (
<Link href="/login" className={`btn ${styles.my}`}>
로그인
</Link>
)}
</div>
</header>
);
Expand Down
31 changes: 31 additions & 0 deletions src/components/toggle-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useState } from "react";
import styles from "./toggle.menu.module.css";
import { useOutsideClick } from "@/hooks/useOutsideClick";

const ToggleMenu = () => {
const [menu, setMenu] = useState(false);

const onMenuToggle = () => {
setMenu(!menu);
};

const ref = useOutsideClick(() => {
setMenu(false);
});

return (
<div className={styles.menu}>
<p onClick={onMenuToggle} ref={ref}>
<img src="/assets/img/icon_dot.svg" alt="메뉴버튼" />
</p>
{menu && (
<ul>
<li>수정하기</li>
<li>삭제하기</li>
</ul>
)}
</div>
);
};

export default ToggleMenu;
25 changes: 25 additions & 0 deletions src/components/toggle.menu.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.menu {
position: absolute;
top: 0;
right: 0;
}
.menu > p {
cursor: pointer;
}
.menu > ul {
position: absolute;
top: calc(100% + 5px);
right: 0;
z-index: 10;
width: 100px;
text-align: center;
border: 1px solid #e5e7eb;
background-color: #fff;
padding: 5px 0;
border-radius: 12px;
}
.menu > ul > li {
padding: 5px 0;
font-size: 14px;
cursor: pointer;
}
Loading