[UMC 4th 해커톤] Sync thon

안지수·2023년 7월 3일
0

🔶 해커톤 과정

🎈 키워드 : '자유로움', '플레이그라운드', '트러블 슈팅'

🎈 해커톤 진행 과정

  • 일시: 2023.07.03 12:00PM~ 2023.07.04 10:00AM
    무박 2일로 진행되었다.
  • 과정:
    ~5:30 아이디어 기획
    ~6:30 저녁 식사
    ~끝 계속 개발....

-> 팀은 도착해서 랜덤으로 배정되었고, 나는 Web 프로젝트에 프론트엔드 개발자로 참여하였고, 한 팀에 8명 정도로 총 10팀이 참여하였다.

🎈 협업 툴

-> 처음에 카카오톡 방을 만들고, 그 곳에서 협업 툴 링크들을 공유하여 진행

  • figma (디자인)
  • 깃허브 (프론트, 백엔드 각각)
  • 노션 (각종 정보들 정리)
  • 카카오톡 (에러 메시지, 링크들 공유)

🔶 해커톤 주제와 디벨롭 과정

: 4시간 정도의 아이디어 도출과 기획할 수 있는 시간이 주어졌다.

"sync thon 개발자들 협업 환경 세팅 헬핑 서비스"

😀 주제 도출 과정

1. 키워드와 관련된 주제를 각자 생각

2. 돌아가면서 아이디어 공유와 투표

😀 내가 제안했던 주제

: '키워드에 집중해보았고, 대충 2개의 주제를 생각해보았음

1. 환경 보호와 관련된 지속 가능한 제품 추천 플랫폼

: 사용자의 쇼핑 습관과 기호를 분석하여 환경에 친화적인 제품을 추천
: 해당 제품의 재활용 및 친환경 사용 방법에 대한 정보도 제공
-> 자유로움, 플레이그라운드를 반영하고자 함
-> 사용자도 자유롭게 환경보호에 참여할 수 있으며, 그 결과 환경오염으로 인해 피해보는 생명체들도 자유로움을 느낄 수 있게 될 것임

2. 화장품 성분 분석 및 개인 맞춤 화장품 추천

: 피부 스트레스나 이런 것으로부터 자유로워짐
: 화장품마다 성분 정보 제공해주고
: 자신에게 맞는 성분의 화장품, 맞지 않는 화장품 등록할 수 있게
-> 추천해주기
-> 사용자 리뷰
-> 피부 관리 가이드

--> 해커톤 주제로 선정되진 않았지만, 다음 프로젝트 주제로 선정해도 좋을 듯하다.

😀 이외 제안된 아이디어들

  1. 장애인 대상 여행지 추천
  2. 주식 정보 제공
  3. 협업 시스템 구축
  4. 초등학생? 중학생 커뮤니티
  5. 콘서트 웹
  6. 블로그 꾸미기
    -> 각자 아이디어 생각 후, 투표로 아이디어를 선정하고, 각 아이디어를 각자 디벨롭하는 시간을 가진 후 다시 논의 를 해보았다.

🔶 해커톤 목적과 target 층

😀 키워드

"트러블 슈팅"

😀 목적

: 협업의 시작(setting)을 용이하게
-> 이번 해커톤에서 어떤 협업 툴을 이용 할지, 어떻게 그것들을 공유할 지 혼란스러웠던 경험을 반영한 주제 선정

-> 초반 프로젝트 시작 시, 협업 툴 공유나 데이터베이스, 원격 저장소 등을 정하는 데 겪었던 혼란을 반영
-> 중구난방으로 링크들 공유하고 하는 것이 아닌, 협업 정보들 공유를 한 번에 할 수 있도록! 효율성!

😀 대상

: 협업을 하려는 누구나 온라인 & 오프라인 모두 가능

🔶 디자인, IA, WIREFRAME

https://turquoise-epoch-97b.notion.site/735f1410d98c494c8b4dedaab1edec4d
-> 위 링크에 IA, WIREFRAME, UI/UX 를 참고해주세요!

-> 협업 공간 그리드를 이런 느낌으로 제공하고자 함

🔶 MVP

  • 링크 한 번에 공유 (링크 공유 번잡스러움 해결)
  • 협업 개발 방식 단순화 (프레임워크, 데이터베이스 etc 입력받기)

PM:

  • 협업 공간 생성
  • 한 페이지에 모든 협업 정보 생성 (각종 링크들)

참여자:

  • 팀원들은 그 협업 공간 입성 시, '이름, 파트, 깃허브 링크, 파트' 선택
  • 파트에 따라 투표 화면으로 넘어감 (어떤 언어, DB, 프레임 워크 쓸 지 정하는 과정)

-> 링크 공유나 협업 툴, 프레임 워크 등등을 정하는 과정을 한 번에 해결하도록 함!

🔶 기술 스택

😀 FRONT-END

  • Framework: React
  • CSS: tailwind, styled-components, post-css

😀 BACK-END

  • Framework: Node.js
  • database: Mysql

❤️ 나의 역할

😀 역할1: 메인화면 구현 (Main.jsx)

: 팀 구성, 프로젝트 생성 선택 화면

1. 텍스트 가운데 정렬

: 그 텍스트를 포함하는 태그에 아래처럼 스타일을 적용시켜준다.

2. 2개의 상자 일정 비율로 띄우는 방법


: 2개의 상자를 감싸는 것에 위와 같이 justify-content: space-between을 적용시켜준다., display: flex를 적용시켜준다.
: 그리고 각 상자에는 'flex-basis: 비율'을 적용시켜준다.

3. 상자 내의 각 요소들 세로로 정렬

: 안의 요소들을 묶는 각 상자에 flex-direction: column; 스타일 요소 넣어준다.

4. 커서 가져갔을 때, 색상 변화하도록


😀 역할2: Home.jsx

: 팀 구성 눌렀을 때

1. 아이콘 받아오는 법(돋보기 아이콘)

: npm install react-icons --save

-> 검색해서 클릭하면 복사됨. 그러면 코드에 태그 사이에 넣어주고, import해주면 됨.

돋보기를 input창에 넣는 것에서 어려움을 느낌.

-> input창과 아이콘을 묶는 input_group 클래스를 하나더 만들어줌.

-> input 창에 아이콘 넣으려면, 복붙하면 됨.

2. 백엔드와 통신: api가져오는 법

-> api 명세에 따라, '도메인주소+uri' 가져와서!


-> 내가 이용할 것은 3번이므로 '도메인주소/board'로 METHOD인 GET에 따라 받아오면 된다. React에서는 axios를 이용하여 GET해올 수 있음!!

3. 입력값에 따라 데이터 필터링 하기

: 백엔드 쪽에서 데이터 필터링하는 부분을 구현하여서, 그 api를 GET해오는 방식을 이용하였다.

-> 여기서는 2번을 이용할 것이므로, '도메인주소/board/serach?name={}'로 GET방식으로 가져오면 된다. name의 중괄호에는 검색 시 input에서 받아오는 string값을 넣어주면 되는 것!!

-> 이런 식으로 받아오면 된다!

import axios from 'axios';
import React, { useEffect, useState } from 'react';
import { AiOutlineSearch } from 'react-icons/ai';
import api from "../apis/axios";
import { Link } from 'react-router-dom';

export default function Home() {
  const [data, setData] = useState([]);
  const [filtered, setFiltered] = useState([]);
  const [searchValue, setSearchValue] = useState("");

  const handleSearch = async () => {
    try {
      const response = await api.get(`/board/search?name=${searchValue}`);
      setFiltered(response.data);
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    api.get('/board')
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  const handleInputChange = (e) => {
    setSearchValue(e.target.value);
  };

  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      handleSearch();
    }
  };

  return (
    <div className="container">
      <div className="header">
        <div className="image-container">
          <img src="/images/logo.png" alt="project logo" />
        </div>
        <div className="search-container">
          <div className="input-group">
            <div className="search-icon">
              <AiOutlineSearch className="text-white" />
            </div>
            <input
              type="text"
              onChange={handleInputChange}
              onKeyPress={handleKeyPress}
              placeholder="팀 이름을 입력해주세요."
            />
          </div>
        </div>
      </div>

      <style>
        {`
          body {
            background-color: black;
          }
          .container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
          }

          .header {
            margin-top: 100px;
            margin-bottom: 30px;
            display: flex;
            flex-direction: column;
            align-items: center;
          }

          .image-container {
            margin-bottom: 30px;
          }

          .search-container {
            display: flex;
            align-items: center;
          }

          .input-group {
            display: flex;
            align-items: center;
            border: 3px solid #14AE81;
            border-radius: 20px;
            padding: 10px;
          }

          .input-group:hover{
            background-color: #303D2F;
          }

          .search-icon {
            margin-right: 10px;
          }

          .search-container input[type="text"] {
            width: 500px;
            outline: none;
            background-color: transparent;
            color: white;
            border: none;
          }

          .grid-container {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            grid-gap: 20px;
            margin-top: 30px;
            margin-bottom: 100px;
          }

          .grid {
            color: white;
            background-color: #2A2A2A;
            border-radius: 10px;
            padding: 30px;
            border: 3px solid #14AE81;
            border-radius: 20px;
            width: 260px;
            height: 200px;
          }
          
          .grid h3{
            font-size: 25px;
            font-weight: 700;
          }

          .grid p{
            font-size: 17px;
            font-weight: 400;
            color: #B4B1B1;
          }

          .grid:hover{
            background-color: #303D2F;
          }
        `}
      </style>

      <div className="grid-container">
        {(filtered.length > 0 ? filtered : data).map((item, index) => (
          <Link to={`/signup/${item.id}`} key={index}>
            <div className="grid">
              <h3>{item.board_name}</h3>
              <p>{item.explanation}</p>
            </div>
          </Link>
        ))}
      </div>
    </div>
  );
}

-> input창에 값을 입력하면, onChange에 의해 searchValue값을 input값으로 지정해준다. 그리고, enter키를 누르면 handleKeyPress에 의해서 handleSearch함수를 실행한다.
-> useEffect를 통해 board의 api를 불러오고, data에 저장한다. handleSearch 함수가 호출되었을 때에는, 그 전체 데이터 중에서 filter하는 api를 불러와서 필터링 진행한다.
-> 필터링된 경우에는 필터한 데이터를 setFiltered를 통해 저장을 하고, filtered에 값이 있으므로 그 필터된 값들만 띄어준다. 만약 input에 값을 입력해 엔터하지 않은 경우에는, filter된 값이 없으므로 모든 그리드를 보여준다.

api호출시 useEffect hook 사용됨
api호출 코드는 그냥 외워도 좋을 듯!

😀 역할3: Main.jsx에서 팀 구성 상자 누르면 Home.jsx 파일로 넘어감 (페이지 이동)

페이지 넘어가는 것 구현 방법

  1. Link(라우터)
  2. navigation(라우터)
    총 2가지가 있음(link와 navigation)
    -> 여기서는 link 이용

구현 방법:


-> link import 해주고, 눌렀을 때 어디로 이동할 지 태그로 아래서 넣어줘야 함. 그리고 index.js 파일에서 Home 주소로 이동했을 때, Home 컴포넌트를 실행해줄 것이라는 의미임.

❤️ 결과 및 완성도

😀 시연영상

https://youtu.be/8Bg1lPOQglk

😀 완성도

80%

-> 프론트 모두 구현
-> 백엔드 모두 구현
-> 프론트와 백엔드 연결 거의 구현 (하지만 해결하지 못한 몇 가지의 오류들이 있었음)

😀 추가로 디벨롭 해야할 부분

  • 참여자가 입성 시, PM이 등록한 비밀번호와 일치하게 입력한 경우에만 입성 가능하도록
  • 각 파트의 투표 결과를 받아와서 화면에 띄어주는 부분에서 계속 문제가 생겼음
  • UI/UX를 조금 더 깔끔하고, 일정하게 (디자이너가 없었음)
  • 각 화면의 라우터들 깔끔하게 (뒤로 돌아가는 거나)
  • 마지막 페이지에서 정보들 수정 가능하게 (링크 수정과 추가 등)
  • PM이 등록한 협업 공간 최신의 것이 첫 번째에 뜨게
  • 최종 페이지 이전에 팀원들의 정보 보여주는 화면 (또는 최종 페이지에서 멤버들의 정보 제공)
    etc

❤️ 배운 점

1. 깃허브 협업

: 내가 깃으로 협업하는 것을 잘 알고 있다고 생각했는데, 팀원 각각 브랜치 만들어서 main에 한번에 병합하는 과정은 잘 알지 못했다. (pull, merge, push)

😀 pull request를 이용한 협업 (하나의 브랜치)

  1. 팀 구성원이 동일한 브랜치(main, master..) 공유하고 협업
  2. 그 브랜치 repo 링크를 cmd에서 clone 해옴
    ----------- cmd창에서 진행 (프로젝트 가져오기) ----------------------
  • cd "프로젝트를 다운 받을 파일의 이름"
  • git clone "프로젝트 레파지토리 주소(복사)" "폴더 이름": 폴더 이름 안써주면 1의 폴더- 로 들어감
  • cd "폴더이름"
  • code .

  1. 로컬에서 작업 수행 후 변경사항 commit
  • git commit -m "커밋 이름"
  1. 변경 사항 push
  • git push origin "브랜치 이름"
  1. github 브랜치가 있는 웹에서 pull request 생성
    : 나 변경사항 커밋하고 푸쉬했으니까 봐줘
  2. 다른 팀원들이 확인 후 승인 시, 변경 사항이 브랜치에 merge 됨

😀 Feature branch를 이용 (여러 개의 브렌치 -> 하나의 브렌치로 병합)

  1. 1명이 repo 생성
  2. 작업 기능마다 별도의 브랜치 생성- 각 팀 구성원이 자신이 작업할 브랜치 생성
  3. git puu, git fetch를 통해 원격 저장소 최신 변경사항 가져옴
  4. 로컬에서 해당 브랜치로 이동하여 작업 수행하고 변경사항 커밋 & push
  • 자신의 브랜치로 커밋하고 push 해야함!!
  1. github 브랜치가 있는 웹에서 pull request 생성
    : 나 변경사항 커밋하고 푸쉬했으니까 봐줘
  2. 다른 팀원들이 확인 후 승인 시, 변경 사항이 main branch로 병합됨
    -> 각 브랜치에서 작업 후 커밋과 push하고, pull request가 승인 되면, main으로 merge됨!

😀 fork와 clone 차이

  • fork: 복사본!! 다른 사람의 깃허브 저장소를 자신의 계정으로 복제. 원본 저장소의 변경사항이 반영되지 않음.
  • clone: 깃 저장소를 로컬 컴퓨터로 복제. 로컬 컴퓨터에서 수정하여 커밋하고 푸시 가능
    -> 즉, fork는 다른 깃허브 저장소의 코드를 내 계정의 저장소로 복제 해오는 복사본/
    clone은 깃 저장소의 코드를 내 로컬 컴퓨터로 복제
    -> '깃 크라켄'이라는 것을 이용하여 쉽게 pull, merge, push 가능!

2. 프로젝트 수행 시, 사용 가능한 꿀 사이트들

3. CSS 적용하는 법

  1. 라이브러리
    : getstarted에서 하라는 대로
  • tailwind
  • bootstrap
    -> 요즘엔 tailwind, material ui 많이 쓰임
  1. css: style 적용
  2. styled-component

-> 내가 작성한 코드에서 css적용 방식을 라이브러리 이용이나, post-css그런 거 적용해서 하는 것도 연습하면 좋을 듯!

4. 프론트 코딩 후, 서버와 통신하는 법

: API 받아와서 스타일 적용하기

❤️ 해커톤 후기

해커톤은 내가 UMC에 들어오며 가장 해보고 싶던 활동이며, 가장 긴장되었던 활동이다. 이 해커톤을 하기 전까지는 내 실력이 어느 정도인지 스스로 가늠할 수 없었던 것 같다. 혹시 가면 민폐가 되진 않을까..하는 생각에 신청하는 것도 망설였지만 일단 go!!라는 마인드로 신청했다. 다른 사람들과 함께하며 내 실력도 어느정도 가늠할 수 있게 된 것 같아 뜻깊은 시간이었다. 더불어 잘 하는 사람들도 많았기에, 여러 꿀팁들 정보들을 얻어간 것 같다. 또한, 프로젝트의 전반적인 흐름을 익힐 수 있어서 더욱 유익한 시간이었으며, 백엔드도 공부해보고 싶단 생각이 들어, 방학동안 공부해볼 예정이다. 또 대체 시간이 어떻게 흘러간 지 모르게 정말 빠르게 지나갔다. 무언가에 빡 집중할 수 있었던 시간이었고, 프로젝트 끝나자마자 잠이 엄청 몰려왔다 ㅎㅎ 가장 어려웠던 점은 디자이너가 없어서 우리가 직접 디자인까지 맡아서 해야했다는 것과 아이디어를 생각해내는 것이 어려웠던 것 같다. 개발을 하는 것에 있어서 디자인과 PM의 역할도 굉장히 큰 역할이라는 것을 몸소 느끼게 된 것 같다. 또, 함께했던 팀원분들이 좋아서 더 재밌었던 것 같다!! 기회가 된다면 또 이런 해커톤 대회에 참여하고 싶은 마음이 크다.

✔️ 링크 (피그마, 깃허브-프론트, 노션, 백엔드 api 명세, 백엔드 깃허브, 발표 자료

🔺FIGMA (디자인)

https://www.figma.com/file/khh9DBSB0qGJzSwLqmPZkZ/%ED%95%B4%EC%BB%A4%ED%86%A4-%EC%A3%BC%EC%A0%9C?type=design&node-id=0%3A1&mode=design&t=aG1YOtEdtwAlVuOe-1

🔺GITHUB (프론트)

https://github.com/bishoe01/UMC_HACKATHON/tree/main

🔺GITHUB (백엔드)

https://github.com/umc4thhackathon/backend

🔺API 명세 (백엔드)

https://www.notion.so/fc725c2fc23b40e7a6032dbe9b199375?v=cac64c270042452699777c15c8ccaf1e

🔺NOTION

https://turquoise-epoch-97b.notion.site/UMC-f861fd46a6bd488cbd57c66e9070fca3

우리가 사용했던, 정리해둔 각종 링크들을 첨부하며 글을 마무리한다.

🎁 api 가져오는 것, 가져온 정보들을 스타일 적용해서 띄어주는 것(그리드) 더 연습하고 배우자!!!!, useEffect와 같은 훅스 공부하기!! -> 졸업 프로젝트 벨로그에 기록하기!

profile
지수의 취준, 개발일기

0개의 댓글