ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -1,7 +1,17 @@
 @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap');
 
-
 * {
   box-sizing: border-box;
   font-family: 'Noto Sans KR', sans-serif;
-}
\ No newline at end of file
+}
+body {
+  width: 100vw;
+  height: 100vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+button {
+  cursor: pointer;
+}

리뷰: 공용 파일을 수정해서 올려주셨는데, 공용 파일의 수정은

1. 팀원과의 충분한 상의 후에
2. 해당 파일만 수정하는 내용의 PR

을 올려주셔야 합니다!
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: 멘토리뷰 반영 완료
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: 멘토 리뷰 반영 완료
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: 멘토 리뷰 반영완료
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: alt 속성은 화면에 이미지가 표시되지 않을때 사용자가 알 수 있도록 대체 텍스트를 제공하는 역할을 하기 떄문에 alt 값에 userPicture를 넣겠읍니다..
@@ -0,0 +1,79 @@
+.userBox {
+  margin: 20px;
+  gap: 0 24px;
+  display: flex;
+  justify-content: center;
+  flex-direction: column;
+
+  .userWrap {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+
+    .user {
+      width: 50px;
+      height: 50px;
+      border-radius: 50%;
+    }
+
+    .contentBox {
+      display: flex;
+      flex-direction: column;
+      gap: 10px;
+      margin-left: 20px;
+
+      .userName {
+        font-size: 20px;
+        font-weight: 700;
+      }
+
+      .textArea {
+        padding: 10px;
+        border-radius: 6px;
+        border: 1px solid var(--grey-88, #e0e0e0);
+        background: var(--white, #fff);
+        resize: none;
+        transition: border-color 0.3s;
+        outline: none;
+      }
+      .textArea:hover {
+        border-color: var(--gray, #999999);
+      }
+
+      .buttonWrap {
+        justify-content: space-between;
+        display: flex;
+
+        .customButton {
+          width: 120px;
+          height: 50px;
+          border-radius: 6px;
+        }
+
+        .cancelButton {
+          border: 1px solid var(--blue, #2d71f7);
+          background: var(--white, #fff);
+          color: var(--blue, #2d71f7);
+          cursor: pointer;
+        }
+        .cancelButton:hover {
+          border: 1px solid var(--navy, #083e7f);
+          background: var(--white, #fff);
+          color: var(--navy, #083e7f);
+        }
+
+        .addButton {
+          border: none;
+          background: var(--white, #2d71f7);
+          color: var(--white, #fff);
+          cursor: pointer;
+        }
+        .addButton:hover {
+          border: none;
+          background: var(--blue, #083e7f);
+          color: var(--white, #fff);
+        }
+      }
+    }
+  }
+}

리뷰: 멘토 리뷰 반영 완료
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: 넵!
@@ -1,14 +1,77 @@
-import React from "react";
-import "./PostAdd.scss";
+import React, { useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import './PostAdd.scss';
+import { Button } from '../PostAdd/components/Post.jsx';
 
 const PostAdd = () => {
+  const [comment, setComment] = useState('');
 
-return(
-  <div className="postAdd">
-    <div>로그인</div>
-  </div>
-);
+  const navigate = useNavigate();
 
-};
+  const handleText = value => {
+    setComment(value);
+  };
+  console.log(handleText);
+
+  const cancel = () => {
+    const confirmed = window.confirm(
+      '적으신 글을 취소하고 post-list로 넘어가겠습니까?',
+    );
+    if (confirmed) {
+      navigate('/post-list');
+    }
+  };
+
+  const posting = () => {
+    if (comment.length >= 1) {
+      navigate('/post-list');
 
-export default PostAdd;
\ No newline at end of file
+      fetch({
+        method: 'POST',
+        headers: {
+          'Content-Type': 'application/json;charset=utf-8',
+        },
+        body: JSON.stringify({
+          content: '유저가 작성한 글',
+        }),
+      })
+        .then(response => response.json)
+        .then(data => console.log(data));
+    } else {
+      alert('내용을 작성주세요.');
+    }
+  };
+
+  return (
+    <div className="userBox">
+      <div className="userWrap">
+        <img className="user" src="/images/user.png" alt="userPicture" />
+        <div className="contentBox">
+          <div className="userName">NAME</div>
+          <textarea
+            onChange={event => handleText(event.target.value)}
+            className="textArea"
+            cols="80"
+            rows="30"
+            type="text"
+            value={comment}
+          />
+
+          <div className="buttonWrap">
+            <Button
+              className="customButton cancelButton"
+              buttonName="취소"
+              active={cancel}
+            />
+            <Button
+              className="customButton addButton"
+              buttonName="게시"
+              active={posting}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+export default PostAdd;

리뷰: 멘토 리뷰 반영 완료(?)
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
 import styled from "@emotion/styled";
 import { css, Theme } from "@emotion/react";
 import CheckIcon from "components/inputs/TextInput/CheckIcon";
-import { TConditionCheck } from "./types/TConditionCheck";
+import { TConditionCheck } from "components/inputs/TextInput/types/TConditionCheck";
 
 interface Props {
   name?: string;
@@ -12,6 +12,7 @@ interface Props {
   conditionList?: string[];
   conditionCheckList?: TConditionCheck[];
   multiline?: boolean;
+  height?: string;
   onTextChange?: (value: string, isValid: boolean) => void;
 }
 
@@ -23,6 +24,7 @@ const TextInput: React.FC<Props> = ({
   conditionList,
   conditionCheckList,
   multiline = false,
+  height,
   onTextChange,
 }) => {
   const [status, setStatus] = useState(value === "" ? "default" : "success"); // default / success / invalid / focus
@@ -76,7 +78,7 @@ const TextInput: React.FC<Props> = ({
   }, [enteredValue, status, onTextChange]);
 
   return (
-    <EmotionWrapper>
+    <EmotionWrapper height={height}>
       {label && <span className="label">{label}</span>}
       {conditionList && (
         <div className="spanList">
@@ -179,6 +181,7 @@ const EmotionWrapper = styled.div<Props>`
     ${({ theme }) => commonStyles(theme)};
     position: relative;
     resize: none;
+    height: ${({ height }) => height ?? "auto"};
   }
 `;
 

리뷰: 사소하지만 `height ?? "auto"` 도 괜찮을 것 같아요!
@@ -0,0 +1,120 @@
+import styled from "@emotion/styled";
+import Image from "next/image";
+import { useState } from "react";
+import Rating from "components/rating/Rating";
+import IconEditFilledWhite from "components/icons/IconEditFilledWhite";
+import Link from "next/link";
+import dayjs from "dayjs";
+
+interface Props {
+  restaurantId: string;
+  reviewId: number;
+  userId: number;
+  score: number;
+  content: string;
+  createdAt: Date;
+}
+
+const ReviewItem: React.FC<Props> = ({
+  restaurantId,
+  reviewId,
+  userId,
+  score,
+  content,
+  createdAt,
+}) => {
+  const [isExpanded, setIsExpanded] = useState(false);
+
+  const toggleExpansion = () => {
+    setIsExpanded((isExpanded) => !isExpanded);
+  };
+
+  const editLink = `/restaurants/${restaurantId}/review/${reviewId}/edit`;
+  const displayContent =
+    content.length > 100 && !isExpanded ? content.slice(0, 100) + "..." : content;
+
+  /**
+   * TODO 1: userId로 userInfo 불러오기
+   */
+  const userName = "홍길동";
+  const ImgSrc = "/images/profile-image-default-1.png";
+
+  /**
+   * TODO 2: 현재 로그인된 유저 아이디 가져오기 (리뷰 수정 권한 확인용)
+   */
+  const currentUserId = 1;
+
+  return (
+    <EmotionWrapper>
+      <div className="user-info-score-div">
+        <div className="user-info-div">
+          <Image src={ImgSrc} alt={"유저 프로필 이미지"} width={30} height={30} />
+          <span className="user-name">{userName}</span>
+          <span className="date">{dayjs(createdAt).format("YY/MM/DD")}</span>
+          {currentUserId === userId && (
+            <Link href={editLink}>
+              <IconEditFilledWhite />
+            </Link>
+          )}
+        </div>
+        <Rating value={score} />
+      </div>
+      <div className="content-div">
+        <span>{displayContent}</span>
+        {content.length > 100 && (
+          <button onClick={toggleExpansion}>{isExpanded ? "접기" : "더 보기"}</button>
+        )}
+      </div>
+    </EmotionWrapper>
+  );
+};
+
+export default ReviewItem;
+
+const EmotionWrapper = styled.div`
+  display: flex;
+  flex-direction: column;
+  min-height: 90px;
+  width: 100%;
+  background-color: ${({ theme }) => theme.color.white};
+  border-radius: 6px;
+
+  padding: 10px;
+
+  .user-info-score-div {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .user-info-div {
+      display: flex;
+      gap: 8px;
+      justify-content: center;
+      align-items: center;
+
+      span.user-name {
+        font-size: 16px;
+        font-weight: 600;
+        color: ${({ theme }) => theme.color.gray700};
+      }
+      span.date {
+        font-size: 12px;
+        font-weight: 300;
+        color: ${({ theme }) => theme.color.gray300};
+      }
+    }
+  }
+
+  .content-div {
+    span {
+      line-height: 1.5;
+      color: ${({ theme }) => theme.color.gray400};
+      flex-grow: 1;
+      margin-right: 8px;
+    }
+
+    button {
+      color: ${({ theme }) => theme.color.gray300};
+    }
+  }
+`;

리뷰: 오..! 저희가 `dayjs` 도 쓰고 있어서 활용해보시는 것도 좋을 것 같습니다!

이런 경우 

```tsx
import dayjs from 'dayjs';

const formattedDate= dayjs(date).format("YY/MM/DD") 
```

이렇게 활용해볼 수도 있을 것 같습니다~
@@ -0,0 +1,120 @@
+import styled from "@emotion/styled";
+import Image from "next/image";
+import { useState } from "react";
+import Rating from "components/rating/Rating";
+import IconEditFilledWhite from "components/icons/IconEditFilledWhite";
+import Link from "next/link";
+import dayjs from "dayjs";
+
+interface Props {
+  restaurantId: string;
+  reviewId: number;
+  userId: number;
+  score: number;
+  content: string;
+  createdAt: Date;
+}
+
+const ReviewItem: React.FC<Props> = ({
+  restaurantId,
+  reviewId,
+  userId,
+  score,
+  content,
+  createdAt,
+}) => {
+  const [isExpanded, setIsExpanded] = useState(false);
+
+  const toggleExpansion = () => {
+    setIsExpanded((isExpanded) => !isExpanded);
+  };
+
+  const editLink = `/restaurants/${restaurantId}/review/${reviewId}/edit`;
+  const displayContent =
+    content.length > 100 && !isExpanded ? content.slice(0, 100) + "..." : content;
+
+  /**
+   * TODO 1: userId로 userInfo 불러오기
+   */
+  const userName = "홍길동";
+  const ImgSrc = "/images/profile-image-default-1.png";
+
+  /**
+   * TODO 2: 현재 로그인된 유저 아이디 가져오기 (리뷰 수정 권한 확인용)
+   */
+  const currentUserId = 1;
+
+  return (
+    <EmotionWrapper>
+      <div className="user-info-score-div">
+        <div className="user-info-div">
+          <Image src={ImgSrc} alt={"유저 프로필 이미지"} width={30} height={30} />
+          <span className="user-name">{userName}</span>
+          <span className="date">{dayjs(createdAt).format("YY/MM/DD")}</span>
+          {currentUserId === userId && (
+            <Link href={editLink}>
+              <IconEditFilledWhite />
+            </Link>
+          )}
+        </div>
+        <Rating value={score} />
+      </div>
+      <div className="content-div">
+        <span>{displayContent}</span>
+        {content.length > 100 && (
+          <button onClick={toggleExpansion}>{isExpanded ? "접기" : "더 보기"}</button>
+        )}
+      </div>
+    </EmotionWrapper>
+  );
+};
+
+export default ReviewItem;
+
+const EmotionWrapper = styled.div`
+  display: flex;
+  flex-direction: column;
+  min-height: 90px;
+  width: 100%;
+  background-color: ${({ theme }) => theme.color.white};
+  border-radius: 6px;
+
+  padding: 10px;
+
+  .user-info-score-div {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .user-info-div {
+      display: flex;
+      gap: 8px;
+      justify-content: center;
+      align-items: center;
+
+      span.user-name {
+        font-size: 16px;
+        font-weight: 600;
+        color: ${({ theme }) => theme.color.gray700};
+      }
+      span.date {
+        font-size: 12px;
+        font-weight: 300;
+        color: ${({ theme }) => theme.color.gray300};
+      }
+    }
+  }
+
+  .content-div {
+    span {
+      line-height: 1.5;
+      color: ${({ theme }) => theme.color.gray400};
+      flex-grow: 1;
+      margin-right: 8px;
+    }
+
+    button {
+      color: ${({ theme }) => theme.color.gray300};
+    }
+  }
+`;

리뷰: `className` 은 따로 컨벤션이 있는 것은 아니지만 대부분 kebab case 를 적용하고 있어 `user-info-score-div` 이런 식은 어떨까요~?