-
Notifications
You must be signed in to change notification settings - Fork 37
[김승석] Sprint10 #311
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
The head ref may contain hidden characters: "Next-\uAE40\uC2B9\uC11D-sprint10"
[김승석] Sprint10 #311
Changes from all commits
592a3d9
c94f749
7c3cfc5
498ba56
32ae842
8d3017f
2f83b8f
87d6588
e8cb077
ecc2dbb
0011b09
863aca2
406d403
3871bf7
fe6b0f8
ae625b6
a63a913
9fe291d
5d3c518
971ee9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| 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; | ||
| } |
| 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} | ||
| /> | ||
|
Comment on lines
+19
to
+26
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. src에 조건문을 넣기보단 src가 달라짐에따라 img 태그자체를 조건부 랜더링하는게 더 괜찮아보이네요 |
||
| </figure> | ||
| <div className={styles.right}> | ||
| <p>{props.writer.nickname}</p> | ||
| <span>{formatDateNow(props.updatedAt)}</span> | ||
| </div> | ||
| </div> | ||
| </li> | ||
| ); | ||
| }; | ||
|
|
||
| export default BoardComment; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 컴포넌트는 결국 input을 고스란히 반환할 뿐인 스타일컴포넌트군요 props의 확장성을 좀더 고민해보시면 좋겠네요 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import styles from "./form.module.css"; | ||
|
|
||
| interface Props { | ||
| type: string; | ||
| placeholder: string; | ||
| value?: string; | ||
| onChange: (e: React.ChangeEvent<HTMLInputElement>) => void; | ||
| } | ||
|
|
||
| const FormInput = ({ type, placeholder, value, onChange }: Props) => { | ||
| return ( | ||
| <input | ||
| className={styles.input} | ||
| type={type} | ||
| placeholder={placeholder} | ||
| value={value} | ||
| onChange={onChange} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| export default FormInput; |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 위와 마찬가지입니다 |
| 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; |
| 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; | ||
| } | ||
| } |
| 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); | ||
| }); | ||
|
Comment on lines
+12
to
+14
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍 |
||
|
|
||
| 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; | ||
| 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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { Review } from "../../types"; | ||
|
|
||
| const fetchBoard = async (id: number): Promise<Review | null> => { | ||
| const url = `https://panda-market-api.vercel.app/articles/${id}`; | ||
| try { | ||
| const response = await fetch(url); | ||
| if (!response.ok) { | ||
| throw new Error(); | ||
| } | ||
| return await response.json(); | ||
| } catch (err) { | ||
| console.error(err); | ||
| return null; | ||
| } | ||
| }; | ||
|
|
||
| export default fetchBoard; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
타입스크립트 관련해서 질문있습니다.
Comment 인터페이스의 타입을 전부 사용안했는데 오류가 나지않는 이유가 뭘까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript는 타입을 선언하는 것만으로는 오류를 발생시키지 않습니다.
즉, 타입이 정의되어 있지만 사용되지 않았다고 해서 TypeScript가 이를 강제하지는 않습니다.