ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,61 @@
+.Login {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100vh;
+
+  main {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-around;
+    width: 350px;
+    height: 380px;
+    padding: 40px;
+    border: 1px solid #ccc;
+
+    header {
+      h1 {
+        font-family: 'Lobster', cursive;
+        text-align: center;
+      }
+    }
+
+    .loginInputBox {
+      form {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+
+        input {
+          margin-bottom: 5px;
+          padding: 9px 8px 7px;
+          background-color: rgb(250, 250, 250);
+          border: 1px solid rgb(38, 38, 38);
+          border-radius: 3px;
+        }
+
+        .loginBtn {
+          margin-top: 10px;
+          padding: 9px 8px 7px;
+          border: none;
+          border-radius: 3px;
+          color: #fff;
+          background-color: #0096f6;
+          &:disabled {
+            background-color: #c0dffd;
+          }
+        }
+      }
+    }
+
+    footer {
+      .findPassword {
+        display: block;
+        margin-top: 50px;
+        text-align: center;
+        color: #00376b;
+        font-size: 14px;
+      }
+    }
+  }
+}

리뷰: 이건 왜 주석으로 되있나요???
@@ -0,0 +1,134 @@
+[
+  {
+    "id": 1,
+    "userName": "eessoo__",
+    "src": "../images/soojeongLee/user2.jpg",
+    "feedText": "💟",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "soojeonglee",
+        "content": "Hi there.",
+        "commnetLike": false
+      },
+      {
+        "id": 3,
+        "userName": "jaehyunlee",
+        "content": "Hey.",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "gyeongminlee",
+        "content": "Hi.",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  },
+  {
+    "id": 2,
+    "userName": "zz_ing94",
+    "src": "../../images/soojeongLee/user3.jpg",
+    "feedText": "Toy story 💚",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "jisuoh",
+        "content": "✨",
+        "commnetLike": true
+      },
+      {
+        "id": 3,
+        "userName": "jungjunsung",
+        "content": "coffee",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "somihwang",
+        "content": "포키",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  },
+  {
+    "id": 3,
+    "userName": "hwayoonci",
+    "src": "../../images/soojeongLee/user4.jpg",
+    "feedText": "오늘의 일기",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "yunkyunglee",
+        "content": "귀여운 스티커",
+        "commnetLike": true
+      },
+      {
+        "id": 3,
+        "userName": "summer",
+        "content": "🐶",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "uiyeonlee",
+        "content": "👍🏻",
+        "commnetLike": true
+      }
+    ],
+    "isLike": true
+  },
+  {
+    "id": 4,
+    "userName": "cosz_zy",
+    "src": "../../images/soojeongLee/user5.jpg",
+    "feedText": "1일 화가 🎨 ",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "soojeonglee",
+        "content": "Hi there.",
+        "commnetLike": false
+      },
+      {
+        "id": 3,
+        "userName": "jaehyunlee",
+        "content": "Hey.",
+        "commnetLike": true
+      },
+      {
+        "id": 4,
+        "userName": "gyeongminlee",
+        "content": "Hi.",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  }
+]

리뷰: 제이슨 파일도 있었군요!
@@ -0,0 +1,128 @@
+@import '../../../../styles/variables.scss';
+
+article {
+  margin-bottom: 20px;
+  background-color: #fff;
+  border-radius: 3px;
+  border: 1px solid $border-color;
+
+  header {
+    @include flex-center;
+    justify-content: space-between;
+    align-content: center;
+    padding: 10px;
+
+    h1 {
+      @include flex-center;
+
+      .contentHeader {
+        @include userProfile;
+        margin-right: 10px;
+        background-image: url('http://localhost:3000/images/soojeongLee/userImage.jpg');
+        background-size: cover;
+      }
+      .userName {
+        font-size: 16px;
+        font-weight: 600;
+      }
+    }
+
+    .ellipsis {
+      @include button;
+      font-size: 22px;
+      .ellipsisIcon {
+        font-weight: 400;
+      }
+    }
+  }
+
+  .feedContent {
+    img {
+      width: 100%;
+    }
+
+    .reactionsBox {
+      @include flex-center;
+      justify-content: space-between;
+      padding: 5px 10px;
+
+      .reactionsLeft {
+        display: flex;
+
+        .leftButton {
+          @include button;
+          font-size: 22px;
+          margin-right: 10px;
+
+          .fa-external-link-alt {
+            font-size: 20px;
+          }
+        }
+      }
+
+      .reactionsRight {
+        .rightButton {
+          @include button;
+          font-size: 22px;
+        }
+      }
+    }
+
+    h2 {
+      display: flex;
+      align-items: center;
+      padding: 0 10px 10px;
+      font-size: 16px;
+      font-weight: normal;
+
+      .feedConUser {
+        @include userProfile;
+        margin-right: 5px;
+        background-image: url('http://localhost:3000/images/soojeongLee/user7.jpg');
+        background-size: cover;
+      }
+
+      .likeCount {
+        @include button;
+        margin-left: 4px;
+        font-size: 16px;
+      }
+    }
+
+    .feedText {
+      margin-bottom: 10px;
+      padding: 0 10px;
+
+      .postTime {
+        @include postTime;
+        margin-top: 5px;
+        font-size: 14px;
+        font-weight: bold;
+      }
+    }
+  }
+
+  .feedFooter {
+    background-color: #fff;
+    border-top: 1px solid $border-color;
+
+    .inputBox {
+      display: flex;
+      padding: 10px;
+
+      .comment {
+        flex: 9;
+        border: none;
+        outline: none;
+      }
+
+      .commentSubmit {
+        @include button;
+        flex: 1;
+        &:hover {
+          color: $summit-color;
+        }
+      }
+    }
+  }
+}

리뷰: 이런 scss 기능 저는 헷갈려서 잘 못하겠던데 잘하시네요..
@@ -0,0 +1,23 @@
+//라이브러리
+import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+//컴포넌트
+import { FOOTLIST } from '../FootLists/footData';
+
+// css
+import './FootLists.scss';
+
+export class FootLists extends Component {
+  render() {
+    return FOOTLIST.map(footlists => {
+      return (
+        <Link to="" className="listDot" key={footlists.id}>
+          {footlists.footlist}
+        </Link>
+      );
+    });
+  }
+}
+
+export default FootLists;

리뷰: 댓글 프랍스!
@@ -0,0 +1,46 @@
+export const FOOTLIST = [
+  {
+    id: 1,
+    footlist: '소개',
+  },
+  {
+    id: 2,
+    footlist: '도움말',
+  },
+  {
+    id: 3,
+    footlist: '홍보 센터',
+  },
+  {
+    id: 4,
+    footlist: 'API',
+  },
+  {
+    id: 5,
+    footlist: '채용 정보',
+  },
+  {
+    id: 6,
+    footlist: '개인정보처리방침',
+  },
+  {
+    id: 7,
+    footlist: '약관',
+  },
+  {
+    id: 8,
+    footlist: '위치',
+  },
+  {
+    id: 9,
+    footlist: '인기 계정',
+  },
+  {
+    id: 10,
+    footlist: '해시태그',
+  },
+  {
+    id: 11,
+    footlist: '언어',
+  },
+];

리뷰: 화이팅 푸터 만들어서 강의 부탁드려요
@@ -1,8 +1,79 @@
 import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+import './Login.scss';
 
 class Login extends Component {
+  constructor() {
+    super();
+    this.state = {
+      id: '',
+      pw: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/main-Soojeong#');
+  };
+
   render() {
-    return <div>로그인</div>;
+    const isValid =
+      this.state.id.includes('@') &&
+      this.state.id.length >= 5 &&
+      this.state.pw.length >= 8;
+
+    return (
+      <div className="Login">
+        <main>
+          <header>
+            <h1>Westagram</h1>
+          </header>
+
+          <section className="loginInputBox">
+            <h2 className="sr-only">login page</h2>
+            <form>
+              <input
+                name="id"
+                autoComplete="off"
+                onChange={this.handleInput}
+                type="text"
+                id="loginId"
+                value={this.state.id}
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+              <input
+                name="pw"
+                onChange={this.handleInput}
+                type="password"
+                value={this.state.pw}
+                placeholder="비밀번호"
+              />
+              <button
+                onClick={this.goToMain}
+                type="button"
+                className="loginBtn"
+                disabled={!isValid}
+              >
+                로그인
+              </button>
+            </form>
+          </section>
+
+          <footer>
+            <Link to="" className="findPassword">
+              비밀번호를 잊으셨나요?
+            </Link>
+          </footer>
+        </main>
+      </div>
+    );
   }
 }
 

리뷰: Boolean 데이터 타입 적용시켜보았아요. 잘 세웠던 코드가 작동되지 않을까 시도하기 어려웠는데 격려 감사합니당~
@@ -0,0 +1,61 @@
+.Login {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100vh;
+
+  main {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-around;
+    width: 350px;
+    height: 380px;
+    padding: 40px;
+    border: 1px solid #ccc;
+
+    header {
+      h1 {
+        font-family: 'Lobster', cursive;
+        text-align: center;
+      }
+    }
+
+    .loginInputBox {
+      form {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+
+        input {
+          margin-bottom: 5px;
+          padding: 9px 8px 7px;
+          background-color: rgb(250, 250, 250);
+          border: 1px solid rgb(38, 38, 38);
+          border-radius: 3px;
+        }
+
+        .loginBtn {
+          margin-top: 10px;
+          padding: 9px 8px 7px;
+          border: none;
+          border-radius: 3px;
+          color: #fff;
+          background-color: #0096f6;
+          &:disabled {
+            background-color: #c0dffd;
+          }
+        }
+      }
+    }
+
+    footer {
+      .findPassword {
+        display: block;
+        margin-top: 50px;
+        text-align: center;
+        color: #00376b;
+        font-size: 14px;
+      }
+    }
+  }
+}

리뷰: 기존 html 코드를 옮기다 보니 발생한 문제였어요 :) 해결되었답니당 !!
@@ -0,0 +1,134 @@
+[
+  {
+    "id": 1,
+    "userName": "eessoo__",
+    "src": "../images/soojeongLee/user2.jpg",
+    "feedText": "💟",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "soojeonglee",
+        "content": "Hi there.",
+        "commnetLike": false
+      },
+      {
+        "id": 3,
+        "userName": "jaehyunlee",
+        "content": "Hey.",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "gyeongminlee",
+        "content": "Hi.",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  },
+  {
+    "id": 2,
+    "userName": "zz_ing94",
+    "src": "../../images/soojeongLee/user3.jpg",
+    "feedText": "Toy story 💚",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "jisuoh",
+        "content": "✨",
+        "commnetLike": true
+      },
+      {
+        "id": 3,
+        "userName": "jungjunsung",
+        "content": "coffee",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "somihwang",
+        "content": "포키",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  },
+  {
+    "id": 3,
+    "userName": "hwayoonci",
+    "src": "../../images/soojeongLee/user4.jpg",
+    "feedText": "오늘의 일기",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "yunkyunglee",
+        "content": "귀여운 스티커",
+        "commnetLike": true
+      },
+      {
+        "id": 3,
+        "userName": "summer",
+        "content": "🐶",
+        "commnetLike": false
+      },
+      {
+        "id": 4,
+        "userName": "uiyeonlee",
+        "content": "👍🏻",
+        "commnetLike": true
+      }
+    ],
+    "isLike": true
+  },
+  {
+    "id": 4,
+    "userName": "cosz_zy",
+    "src": "../../images/soojeongLee/user5.jpg",
+    "feedText": "1일 화가 🎨 ",
+    "commentData": [
+      {
+        "id": 1,
+        "userName": "wecode",
+        "content": "Welcome to world best coding bootcamp!",
+        "commnetLike": false
+      },
+      {
+        "id": 2,
+        "userName": "soojeonglee",
+        "content": "Hi there.",
+        "commnetLike": false
+      },
+      {
+        "id": 3,
+        "userName": "jaehyunlee",
+        "content": "Hey.",
+        "commnetLike": true
+      },
+      {
+        "id": 4,
+        "userName": "gyeongminlee",
+        "content": "Hi.",
+        "commnetLike": true
+      }
+    ],
+    "isLike": false
+  }
+]

리뷰: fetching 을 연습해보려고 만들어보았어요
@@ -0,0 +1,23 @@
+//라이브러리
+import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+//컴포넌트
+import { FOOTLIST } from '../FootLists/footData';
+
+// css
+import './FootLists.scss';
+
+export class FootLists extends Component {
+  render() {
+    return FOOTLIST.map(footlists => {
+      return (
+        <Link to="" className="listDot" key={footlists.id}>
+          {footlists.footlist}
+        </Link>
+      );
+    });
+  }
+}
+
+export default FootLists;

리뷰: 꼭 풋 리스트를... 컴포넌트화해보겠어요...!!!!
@@ -1,8 +1,79 @@
 import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+import './Login.scss';
 
 class Login extends Component {
+  constructor() {
+    super();
+    this.state = {
+      id: '',
+      pw: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/main-Soojeong#');
+  };
+
   render() {
-    return <div>로그인</div>;
+    const isValid =
+      this.state.id.includes('@') &&
+      this.state.id.length >= 5 &&
+      this.state.pw.length >= 8;
+
+    return (
+      <div className="Login">
+        <main>
+          <header>
+            <h1>Westagram</h1>
+          </header>
+
+          <section className="loginInputBox">
+            <h2 className="sr-only">login page</h2>
+            <form>
+              <input
+                name="id"
+                autoComplete="off"
+                onChange={this.handleInput}
+                type="text"
+                id="loginId"
+                value={this.state.id}
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+              <input
+                name="pw"
+                onChange={this.handleInput}
+                type="password"
+                value={this.state.pw}
+                placeholder="비밀번호"
+              />
+              <button
+                onClick={this.goToMain}
+                type="button"
+                className="loginBtn"
+                disabled={!isValid}
+              >
+                로그인
+              </button>
+            </form>
+          </section>
+
+          <footer>
+            <Link to="" className="findPassword">
+              비밀번호를 잊으셨나요?
+            </Link>
+          </footer>
+        </main>
+      </div>
+    );
   }
 }
 

리뷰: 계산된속성명 굿
@@ -1,8 +1,79 @@
 import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+import './Login.scss';
 
 class Login extends Component {
+  constructor() {
+    super();
+    this.state = {
+      id: '',
+      pw: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/main-Soojeong#');
+  };
+
   render() {
-    return <div>로그인</div>;
+    const isValid =
+      this.state.id.includes('@') &&
+      this.state.id.length >= 5 &&
+      this.state.pw.length >= 8;
+
+    return (
+      <div className="Login">
+        <main>
+          <header>
+            <h1>Westagram</h1>
+          </header>
+
+          <section className="loginInputBox">
+            <h2 className="sr-only">login page</h2>
+            <form>
+              <input
+                name="id"
+                autoComplete="off"
+                onChange={this.handleInput}
+                type="text"
+                id="loginId"
+                value={this.state.id}
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+              <input
+                name="pw"
+                onChange={this.handleInput}
+                type="password"
+                value={this.state.pw}
+                placeholder="비밀번호"
+              />
+              <button
+                onClick={this.goToMain}
+                type="button"
+                className="loginBtn"
+                disabled={!isValid}
+              >
+                로그인
+              </button>
+            </form>
+          </section>
+
+          <footer>
+            <Link to="" className="findPassword">
+              비밀번호를 잊으셨나요?
+            </Link>
+          </footer>
+        </main>
+      </div>
+    );
   }
 }
 

리뷰: 이런 주석들은 불필요하니까 삭제해주시는게 좋아보입니다!
@@ -1,8 +1,79 @@
 import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+import './Login.scss';
 
 class Login extends Component {
+  constructor() {
+    super();
+    this.state = {
+      id: '',
+      pw: '',
+    };
+  }
+
+  handleInput = event => {
+    const { name, value } = event.target;
+    this.setState({
+      [name]: value,
+    });
+  };
+
+  goToMain = () => {
+    this.props.history.push('/main-Soojeong#');
+  };
+
   render() {
-    return <div>로그인</div>;
+    const isValid =
+      this.state.id.includes('@') &&
+      this.state.id.length >= 5 &&
+      this.state.pw.length >= 8;
+
+    return (
+      <div className="Login">
+        <main>
+          <header>
+            <h1>Westagram</h1>
+          </header>
+
+          <section className="loginInputBox">
+            <h2 className="sr-only">login page</h2>
+            <form>
+              <input
+                name="id"
+                autoComplete="off"
+                onChange={this.handleInput}
+                type="text"
+                id="loginId"
+                value={this.state.id}
+                placeholder="전화번호, 사용자 이름 또는 이메일"
+              />
+              <input
+                name="pw"
+                onChange={this.handleInput}
+                type="password"
+                value={this.state.pw}
+                placeholder="비밀번호"
+              />
+              <button
+                onClick={this.goToMain}
+                type="button"
+                className="loginBtn"
+                disabled={!isValid}
+              >
+                로그인
+              </button>
+            </form>
+          </section>
+
+          <footer>
+            <Link to="" className="findPassword">
+              비밀번호를 잊으셨나요?
+            </Link>
+          </footer>
+        </main>
+      </div>
+    );
   }
 }
 

리뷰: event.target 반복되고 있는데 구조분해해서 활용해볼 수 있겠네요!
```const {name,value} = event.target;```
@@ -0,0 +1,45 @@
+package com.example.momogum.repository.redisRepository;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.time.Duration;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Repository
+@RequiredArgsConstructor
+public class RedisRepository {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+
+    // 사용자가 조회한 postId 저장
+    public void addViewedPost(String userId, String postId) {
+        String key = generateKey(userId);
+        redisTemplate.opsForSet().add(key, postId);
+    }
+
+    // 사용자가 조회한 postId 목록 조회
+    public Set<Long> getViewedPosts(String userId) {
+        String key = generateKey(userId);
+
+        return Objects.requireNonNull(redisTemplate.opsForSet().members(key)).stream()
+                .map(Object::toString)
+                .map(Long::valueOf)
+                .collect(Collectors.toSet());
+    }
+
+    // Redis Key 생성
+    private String generateKey(String userId) {
+        return "user:" + userId + ":viewed";
+    }
+
+    //  세션 만료 시간 설정
+    public void setSessionTimeout(String userId, long timeoutMinutes) {
+        String key = generateKey(userId);
+        redisTemplate.expire(key, Duration.ofMinutes(timeoutMinutes));
+    }
+}

리뷰: redis template를 이해하고 사용하신 것 같네요

확실히 이해만 잘 할 수 있다면 crudRepository보다 template구현하는게 의도를 더 잘 담을 수 있어서 좋은 것 같습니다. 고생하셨어요!
@@ -2,11 +2,24 @@
 
 import com.example.momogum.domain.MealDiary;
 import com.example.momogum.domain.UserEntity;
+import com.example.momogum.domain.common.enums.IsRevisit;
+import io.lettuce.core.dynamic.annotation.Param;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 
 public interface MealDiaryRepository extends JpaRepository<MealDiary,Long> {
 
     List<MealDiary> findByUserEntity(UserEntity userEntity);
+
+    @Query("SELECT m.id FROM MealDiary m WHERE m.isRevisit = :isRevisit AND m.userEntity.Id!= :userId ORDER BY m.likesCount DESC")
+    List<Long> findAllByIsRevisit(@Param("isRevisit") IsRevisit isRevisit, @Param("userId")Long userId);
+
+    @Query("SELECT m.id FROM MealDiary m WHERE m.foodCategory = :foodCategory AND m.userEntity.Id != :userId ORDER BY m.likesCount DESC")
+    List<Long> findAllByFoodCategory(@Param("foodCategory") String foodCategory, @Param("userId")Long userId);
+
+
+    List<MealDiary> findByIdIn(List<Long> ids);
+
 }

리뷰: 동적 쿼리가 많은 경우 queryDsl도 괜찮아보입니다. 여견상 도입할 수 있으면 하면 좋을 것 같습니다!