Hazel Han
Midnight In Coding
Hazel Han
전체 방문자
오늘
어제
  • 분류 전체보기 (46)
    • Back-end (6)
      • java (0)
      • spring frameworks (6)
      • spring boot (0)
    • Front-end (29)
      • React (7)
      • Javascript (0)
      • html (7)
      • css (15)
    • DB (0)
    • Algorithms (2)
    • 회고록 (9)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 프로그래밍
  • 회고록
  • 스프링
  • Java
  • 저스트코드
  • justcode
  • 자바
  • 남궁성
  • 스프링프레임워크
  • coding
  • 리액트
  • Spring
  • css
  • springframeworks
  • React
  • 코딩
  • 자바의정석
  • 기술블로그
  • 개발자
  • HTML

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Hazel Han

Midnight In Coding

회고록

[JUSTCODE] 2차 프로젝트 회고

2022. 11. 29. 16:12

※이 프로젝트는 사이트의 디자인만을 차용하고,
모든 코드는 COPY한 것이 아니라 설계부터 자체적으로 하였음을 명시합니다.

 

 

프로젝트 기간

2022.11.14~2022.11.24 (2weeks)

 

 

점핏 사이트를 모델링 사이트로 선정한 이유

우리팀은 1차 프로젝트보다 더 다양한 기능이 있고, 개발자로 성장하는 데에 도움이 될 수 있는 사이트를 선정하는 것을 목적으로 두었다. 또한, 사용자의 입장에서 볼 때 UI가 깔끔하고, 앞으로 우리가 자주 이용할 채용 사이트에 대해서 미리 분석할 수 있을거라 기대하여 점핏 사이트를 선정하게 되었다.

 

 

사이트의 성격

다양한 조건에 따라 정리되어 있는 채용 정보를 얻을 수 있고, 원하는 필터를 적용하여 채용정보를 찾아, 작성한 이력서를 바탕으로 지원할 수 있다.

 

 

팀원소개

Front-end
한혜선, 송기민, 박성아, 강희진

Back-end
이우령, 김시아, 김지수

 

 

기술 stack

Front-end : React, Sass

Back-end : Node Express, Mysql

 

 

시연영상

 

 

협업방식

Notion에서 칸반보드와 타임라인을 이용하여 티켓으로 일정 관리

Daily stand up meeting(AM 10:00) : 어제 작업한 사항, 오늘 해야할 사항 공유

디스코드 : 공지사항 전달

Slack : 상시 소통

vscode liveshare : 실시간 코드 공유 및 피드백

 

 

내가 담당한 부분

메인 페이지(카드리스트 컴포넌트 포함), 헤더, 로그인/회원가입 모달창 레이아웃, 로그인 시 이메일 유효성검사

 

 

메인페이지(헤더 포함)


메인페이지의 레이아웃을 구현한 뒤, 각각의 카드들은 컴포넌트화하여 사용하였다.

그런데 카드의 형태가 긴 것도 있고, 짧은 것도 있어서 이것을 어떻게 하나의 컴포넌트에서 분리하여 사용할까?하는 고민이 생겼다.
카드의 형태가 다르니까 무언가를 기준으로 분리해야할텐데..그렇다면, type을 이용하여 분리해보자!(프로퍼티 이름은 type이 아니어도 상관은 없다).

type을 사용하기 위해 back-end에서 받아올 수 있게 요청드렸고, 그 type을 메인페이지(부모)에서 카드리스트 컴포넌트(자식)로 props로 넘겨와 받았다. 그 후 type을 이용하여 className을 분리하였고, className에 따라 다른 css가 적용되게 만들었다. 해당 코드는 아래와 같다.


import React from 'react';
import { useNavigate } from 'react-router-dom';
import './MainCardList.scss';
import StackList from './StackList/StackList';

const MainCardList = ({
  images,
  company_name,
  title,
  tech_stacks,
  location,
  career_max,
  career_min,
  view,
  id,
  type,
}) => {
  const navigate = useNavigate();
  const moveDetail = () => {
    navigate(`/detail/${id}`);
  };

  return (
    <div className={'main-cardList-wrapper ' + type} onClick={moveDetail}>
      <div className="image-area-wrapper">
        <img src={images[0].image} alt="" />
        <span className="view">{view}</span>
      </div>
      <div className="text-area-wrapper">
        <div className="company-name">{company_name}</div>
        <div className="title">{title}</div>
        <div className="stack">
          {tech_stacks &&
            tech_stacks.map(stack => {
              return <StackList key={stack.id} stack_name={stack.tech_stack} />;
            })}
        </div>
        <span className="company-location">{location}</span>
        <div>
          <span className="company-career">
            경력 {career_min}~{career_max} 년
          </span>
        </div>
      </div>
    </div>
  );
};
export default MainCardList;

라이브러리를 사용해볼까?

메인페이지에는 슬라이더가 2개 존재하는데 이것을 자체적으로 구현해볼까 라이브러리를 사용해볼까 하다가 현업에서도 라이브러리를 많이 사용하기 때문에 이번 기회에 연습해보고싶어 slick-slider 라이브러리를 사용하여 구현하였다.

라이브러리를 사용해보는 것은 처음이라 css를 어떻게 수정해야할지, settings가 의미하는 것인지 많이 헷갈렸지만, 구글링을 적절히 활용하여 각각의 요소가 의미하는 것을 알아냈고, 문제를 해결하였다.

또한, 나의 경우 초기세팅에 나와있는 slider를 그대로 사용하여 이미지만 넣는 것이 아니라 슬라이더 안에 back-end에서 가져온 데이터를 카드리스트 안에서 map을 돌려야했기 때문에 return 안을 어떻게 작성해야할지 고민을 많이했었는데, 팀원과 함께 map을 return문 안에도 넣어보고, 밖에도 넣어보고 이리저리 옮기면서 해결할 수 있었다.

이 과정을 통해 라이브러리를 적절히 커스텀하여 사용하는 방법에 대해 배울 수 있었다. 해당 코드는 아래와 같다.


import React, { useEffect, useState } from 'react';
import Slider from 'react-slick';
import '../../slick.scss';
import '../../slick-theme.scss';
import MainCardList from '../MainCardList/MainCardList';

const SimpleSlider = () => {
  let settings = {
    dots: false,
    infinite: true,
    speed: 500,
    slidesToShow: 2,
    slidesToScroll: 2,
  };

  const [cardList, setCardList] = useState([]); //카드리스트 데이터
  //롱 카드리스트 fetch
  useEffect(() => {
    fetch('http://localhost:8000/')
      .then(res => res.json())
      .then(res => setCardList(res.responseFastCompany));
  }, []);

  return (
    <div>
      <Slider {...settings}>
        {cardList.map(cardList => {
          return (
            <MainCardList
              key={cardList.id}
              id={cardList.id}
              images={cardList.images}
              company_name={cardList.company_name}
              title={cardList.title}
              tech_stacks={cardList.tech_stacks}
              location={cardList.location}
              career_min={cardList.career_min}
              career_max={cardList.career_max}
              type={cardList.type}
            />
          );
        })}
      </Slider>
    </div>
  );
};

export default SimpleSlider;

 

 

로그인/회원가입 모달창

 const emailValue = useRef(); //이메일 input에 입력한 값
  const passwordValue = useRef();
  const [disabled, setDisabled] = useState(false); //회원가입 버튼 활성화, 비활성화

  //이메일 유효성검사
  const handleEmail = e => {
    e.preventDefault();
    var regExp =
      /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;
    if (regExp.test(emailValue.current.value)) {
      setDisabled(true);
    } else {
      setDisabled(false);
    }
  };
<div className="email-title">이메일</div>
<input
  type="text"
  placeholder="이메일을 입력해 주세요."
  ref={emailValue}
  onChange={handleEmail}
/>
{disabled == false && (
  <div className="signUp-vali-check">
    올바른 이메일을 입력해주세요.
  </div>
)}
</div>

정규식을 이용한 유효성 검사

메인에서 회원가입/로그인 버튼을 누르면 위와 같은 모달창이 나타나게 된다.

이 때 로그인 모달창에서 이메일을 입력할 때, 정규식을 이용하여 유효성검사를 진행하여 해당 양식에 맞지 않으면 올바른 이메일을 입력해주세요. 라는 글귀가 나타나게 하였고, 유효성검사를 통과해야만 버튼이 활성화 될 수 있도록 하였다.

국비학원을 다닐 때 유효성 검사를 진행해 본 적이 있었는데, 그 때까지만해도 나는 정규식이 하나의 양식으로만 정해져있는 것인줄 알았다. 하지만 이번 기회에 구글링을 해보며 정규식을 내가 원하는대로 커스텀할 수 있다는 사실을 알게되었다. 다음에 유효성검사를 진행한다면 기획에 맞게 좀 더 까다롭게, 혹은 여유있게 정규식을 작성해 보아야겠다.


//이메일, 이름, 비밀번호를 모두 입력했을 때
useEffect(() => {
    if (email && name && password) {
      setDisabled(true);
    } else {
      setDisabled(false);
    }
}, [email, name, password]);

회원가입 모달창에서는 이메일, 이름, 비밀번호를 모두 입력하여야 버튼이 활성화 되게 하였다.

시간이 조금 더 있었더라면, 위 조건에 동의 체크를 모두 완료해야만 버튼이 활성화 되게 하는 조건까지 넣고 싶었는데, 아쉬움이 남는다. 다음에 기회가 된다면 구현해봐야겠다.


2차 프로젝트를 통하여 나는,

건강이 최우선이다!

2차 프로젝트를 진행하는 중간에 몸이 크게 아프게 되어 절반은 참여를 하지 못하게 되었다. 따라서 프로젝트의 흐름도 놓쳤고, 내 역할의 일부(로그인/회원가입 기능)를 팀원들에게 부탁할 수 밖에 없었다.

이 때문에 로그인/회원가입 기능을 전체적으로 모두 구현해보고 성장하고 싶었던 나의 목표를 이루지 못하여 너무 아쉬웠고, 팀원들에게 짐이 된 것 같아 죄송하기도 했다.

우리는 종종 건강을 안일하게 생각하지만, 건강하지 못한다면 손해보는 것이 참 많다.

나는 이번 프로젝트를 통해 건강 관리에 대한 중요성을 절실히 깨닫게 되었다.

이제부터는 팀을 위해, 또 나의 목표를 위해, 평소에 하고있던 운동도 더 열심히하고, 건강한 음식을 섭취하며 프로젝트에 차질없는 건강한 개발자가 될 것 이다.

 

다양한 툴을 경험해보자

1차 프로젝트에서는 Slack과 zoom, google meet등을 통하여 소통하였는데 이번 프로젝트에서는 디스코드를 사용하였다. 새로운 툴을 사용하는 것이기에 처음에는 적응이 필요했지만, 이내 디스코드의 장점도 보이기 시작했다.

자신에게 익숙한 하나의 툴을 계속 사용하는 것도 좋지만, 어느 회사에 혹은 어느 팀에 들어가냐에 따라 사용하게 될 툴이 다를 수 있다. 따라서 여러 툴에 대해 익숙해지고 능숙하게 사용할 수 있는 것도 중요한 요소인 것 같다.

저작자표시 (새창열림)

'회고록' 카테고리의 다른 글

[JUSTCODE] PHOTOFOLIO renewal 프로젝트 회고록  (0) 2022.12.26
[JUSTCODE] 1, 2차 프로젝트 리팩토링  (2) 2022.11.29
[JUSTCODE] 1차 프로젝트 회고  (3) 2022.11.14
[JUSTCODE] 1개월차 회고  (0) 2022.11.13
[JUSTCODE] pre-course 2주차 회고  (2) 2022.10.15
    '회고록' 카테고리의 다른 글
    • [JUSTCODE] PHOTOFOLIO renewal 프로젝트 회고록
    • [JUSTCODE] 1, 2차 프로젝트 리팩토링
    • [JUSTCODE] 1차 프로젝트 회고
    • [JUSTCODE] 1개월차 회고
    Hazel Han
    Hazel Han

    티스토리툴바