반응형

나만의 칵테일을 만들고 내가 가진 재료로 칵테일을 검색하는 서비스입니다.

  • 관리자와 유저로나누어 각각 다른 페이지로 접속하게 됩니다.
  • 관리자는 앱 공식칵테일과, 재료들을 등록할 수 있습니다. 
  • 사용자는 사용자사이트로 접속해 칵테일을 만들고 필요한 임시재료를 등록할수있습니다.

기획 배경 동기

평소에 음식이나 마시는 음료 쪽에 관심이 많고 최근에 위스키나 주류시장에 대한 관심은 높아지는 반면에 

칵테일에 대한 관심은 아직 높지 않고 바 문화보다는 여전히 소주나 맥주문화가 큰 부분에 아쉬움을 느끼게 되었습니다

그래서 일반인들이 칵테일 레시피를 더 간단하게 찾을 수 있고 더 다양한 조합을 서로 공유해서 비싼 바문화를 좀 더 가볍게 집에서 친구와 같이 즐길 수 있도록 하고 싶었습니다. 

이 서비스를 통해서 더 가볍게 빠르게 칵테일에 접근할 수 있게 도와주고 싶습니다.

 

개발 기록

 

플로우 차트

 

주요 기능

관리자

 

로그인 

ADMIN 역할을 가진 유저의 로그인, 관리자 페이지는 관리자만 로그인이 가능합니다.

 

칵테일, 재료, 유저 조회

등록된 칵테일, 재료, 유저정보를 조회할 수 있습니다.

 

유저 등록, 삭제

가입시킬 유저의 정보를 등록할 수 있습니다.

 

칵테일 저장, 수정, 삭제

칵테일의 정보를 입력하고 입력한 칵테일정보를 저장할 수 있습니다. 

 

재료 저장, 수정, 삭제

재료의 정보를 입력하고 입력한 재료의 정보를 저장할 수 있습니다.

 

유저 

 

유저 로그인 

회원가입을 통해 가입한 이메일과 비밀번호로 로그인할 수 있습니다.

* 간편 로그인 기능 추가

 

칵테일 조회 

등록된 칵테일을 조회할 수 있고 칵테일을 클릭하면 칵테일의 상세한 정보와 필요한 재료를 볼 수 있습니다.

 

재료 조회 

등록된 재료들의 목록을 조회할 수 있고 클릭하면 해당 재료가 사용되는 칵테일과 재료의 정보를 볼 수 있습니다.

 

나의 재료

재료리스트에서 내가 가진 재료를 클릭해서 등록할 수 있고 검색을 누르면 해당하는 재료로 만들 수 있는 칵테일을 조회할 수 있습니다. 각 칵테일 별로 어떤 재료가 부족한지 나오고 모든 재료를 가지고 있으면 베스트 매치로 표시됩니다.

 

* 추가할 기능 : 로그인 후 추가한 재료는 사용자정보와 같이 등록되고 이후 다시 재료등록 시 한번 등록된 재료들이 나오도록 처리. 

 

 

반응형
반응형

 

트러블

클라이언트쪽에서 원래 보내던 데이터에 추가해서 객체가들어간 배열을 보내줄일이 생겼다.

처음에는 formData에 배열을 바로 직렬화해서 보냈는데 서버에서 데이터를 배열로받을수가없었다.

javaScript코드

const getIngredientsData = () => {
    const ingredientData = [];
    Array.from(ingredientRows.children).forEach((row) => {
        const ingredientName = row.children[0].value;
        const volume = row.children[1].value;
        const unit = row.children[2].value;

        ingredientData.push({
            name: ingredientName,
            volume: volume,
            unit: unit
        });
    });
    return ingredientData;
} //배열을만들고 요소를모아서 객체를만들어 배열에 push
// 만든 배열을 return해주는 함수

formData.append(`ingredients`, JSON.stringify(ingredientData[i]));

 

이렇게 클라이언트에서 보내주면 서버에서는 ingredients 필드에서 받아야하는데 

@Data
@Builder
public class CockTailRequest {
    private List<CocktailIngredientRequest> ingredients;
}

@Data
public class  CocktailIngredientRequest {
    private String name;
    private Integer volume;
    private String unit;
}

에러가 발생한다 String을 List타입으로 컨버트할수없다는에러가..

 

해결

그래서 찾아보니 formData에서 배열을 보내는방법이있었다. 같은필드이름에 인덱스를 달아서 보내주면 

자동으로 배열로 넘어간다고 한다.

그래서 클라이언트쪽 코드를 변경해줬다. 

const getIngredientsData = () => {
    const ingredientData = [];
    Array.from(ingredientRows.children).forEach((row) => {
        const ingredientName = row.children[0].value;
        const volume = row.children[1].value;
        const unit = row.children[2].value;

        ingredientData.push({
            name: ingredientName,
            volume: volume,
            unit: unit
        });
    });
    return ingredientData;
} //배열을만들고 요소를모아서 객체를만들어 배열에 push
// 만든 배열을 return해주는 함수

const ingredientData = getIngredientsData();
    for(let i=0;i<ingredientData.length;i++){
        formData.append(`ingredients[${i}]`, JSON.stringify(ingredientData[i]));
    }

배열을 반복문으로 돌려서 필드에 인덱스를 붙여주는 방법으로 보내도록 변경했다.

 

문제는 이렇게 해도 서버에서 List<String> 형태로는받아지는데

배열 내부의 객체인 CocktailIngredientRequest로는 컨버팅이 되지않았다.

이것저것 시도해보다가 시간만 너무날려서 문자열 배열로 받고 내부에서 컨버팅해줄수있게 함수를 추가해줬다.

@Builder
@Data
@Getter
    private List<String> ingredients;
   
   public List<CocktailIngredientRequest> getListIngredients() {
        ObjectMapper objectMapper = new ObjectMapper();

        return this.ingredients.stream().map(json -> {
            try {
                return objectMapper.readValue(json, CocktailIngredientRequest.class);
            } catch (JsonProcessingException e) {
                throw new RuntimeException("Error parsing JSON: " + e.getMessage());
            }
        }).collect(Collectors.toList());
    }
}

ingredients 배열내에는 Json문자열이있고 해당 Json문자열을 objectmapper로 convert해주도록 메서드를 만들었다.

 

트러블슈팅은못한것같고 트러블 회피정도는 되는듯한 해결방법이다. 

추후에 더 알아보면 클라이언트에서 객체배열을 보내고 서버에서 한번에 컨버팅해서 받는방법을 알아낼수있겠지 그때되면 이부분은 업데이트 해보겠다.

반응형
반응형

이전에 팀프로젝트로 만든 파일을  로컬에서만 쓰다가 오늘 호스팅 하는 방법을 배워서

호스팅 하는 방법을 올려보려고 한다.

 

리액트파일과 서버파일이 있어서 두곳에 따로따로 호스팅 해줘야 한다. 

 

Node.js 서버 호스팅

HEROKU

https://dashboard.heroku.com/apps

 

Heroku

 

dashboard.heroku.com

위의 사이트에 들어가서 가입을 해줘야한다.

가입을 하면 로그인을 하고 create new app으로 들어가 준다

 

이제 여기서 이름을 설정해 주고 Create app을 누르면 깃허브리포지터리 같은 게 만들어진다.

 

만들고 나면 이런 창으로 이동하게 되는데 깃허브처럼 파일을 여기로 보내주면 된다

heroku로 push 하기 위해서는 heroku를 설치해줘야 한다. 

https://devcenter.heroku.com/articles/heroku-cli

 

The Heroku CLI | Heroku Dev Center

Last updated January 17, 2023 The Heroku Command Line Interface (CLI) lets you create and manage Heroku apps directly from the terminal. It’s an essential part of using Heroku. Install the Heroku CLI Pre-requisites The Heroku CLI requires Git, the popula

devcenter.heroku.com

링크로 들어가서 해당하는 운영체제와 옵션에 따라 설치해주면 된다.

 

설치하면 이제 호스팅 할준비가 끝났다 호스팅할 파일들도 준비를 좀 해줘 야한다

 

1. 호스팅 할 서버 파일이름을 index.js로 변경 

2. 호스팅 하는 파일의 port번호 변경

const port = process.env.PORT || 8080;
//지정해주는 포트번호가있다면 지정번호를사용하고 없다면 8080포트 사용

3.package.json 변경

 

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },

 

이렇게 해준 뒤에 이제 깃허브에 push 하는 것과 똑같이 해주면 된다 

cmd 나 터미널을 이용해 주자

서버폴더위치에서 입력해줘야 한다.

 

주의사항*

서버를 깃허브에서 클론 해온 경우 node.module이 설치되어 있는지 확인 

없다면 npm install로 설치

 

. git 폴더를 지우고 처음부터 git init 하기 

 

업로드 전 서버를 실행시켜 보고 잘 실행되는지 확인!

 

json의 scripts.start 부분이 서버의 파일이름과 일치하는지 확인!!!

 

 

터미널에 입력

$ cd 프로젝트 위치
$ git init
$ git add .
$ git commit -m "heroku deploy" //커밋은 넣고싶은메모를 넣으면된다
$ heroku git:remote -a app name //이부분은 deploy에 쓰여있으니 복붙!
 --> 예시 $ heroku git:remote -a zzang9ha

$ git push heroku main //현재브랜치이름을 넣어주자 브랜치변경을 하지않았다면 master일수도 있다

 

push 까지 해 주고 오른쪽상단에 있는 open App을 눌러서 이런 창이 뜨면 성공이다 다른 에러창이 뜬다면 

json파일과 포트번호 그리고 모듈들이 잘 설치되어 있는지 다시 확인해 보고 리포지터리를 삭제한 다음 다시 만들어서 호스팅을 시도해야 한다..

 

서버의 데이터를 요청하는 주소로 이동하니 데이터를 잘 보내주는 걸 볼 수 있다! 이제 서버 끝 

 

 

React.js 호스팅

 

Vercel 가입하기

 

https://vercel.com/

 

Vercel: Develop. Preview. Ship. For the best frontend teams

Vercel is the platform for frontend developers, providing the speed and reliability innovators need to create at the moment of inspiration.

vercel.com

위 사이트를 통해서 github를 연결해서 바로 호스팅 할 수 있다.

깃허브로 회원가입이 가능하니 깃허브로 가입하고 빠르게 진행할 수 있다.

 

vercel에 리액트 파일을 호스팅 하기 전에 리액트 파일의 서버주소를

호스팅 된 노드서버주소로 변경해 준 다음 npm start로 실행해 보자.

리액트프로젝트의 서버주소 변경

나는 서버주소를 apiurl.js에서 변수로 선언해서 사용하고 있어서 여기 주소만 변경해 주겠다. 뒤에 / 가 필요하면 붙여주고 필요 없으면 때 주면 된다 서버에 요청을 어떻게 하는지 확인하자.

 

이제 다시 vecel로 돌아가서 

 

Add new에 project를 클릭하고 들어가서

깃허브를 연결해 주고 호스팅 하고 싶은 파일을 import 해주면 된다.

이제 이 화면에서 Deploy 해주고 기다리면 호스팅이 끝난다.

 

여기서는 수정할 부분이 있으면 로컬파일을 수정해서 다시 깃허브에 push 해주면

vercel에서 다시 호스팅 해준다.

 

https://team-project-thenadlee.vercel.app/

 

React App

 

team-project-thenadlee.vercel.app

호스팅 된 팀프로젝트.

반응형
반응형

저번 팀플을 끝내고 바로 시작한 혼자하는 리액트 프로젝트는 

카페의 사이트를 만드는 프로젝트이다. 친구가 카페사장님이라 사진이나 필요한 니즈도 알아내기 쉬울것같아서 카페사이트를 만들어 보기로 했다. 나도 예전에는 빵을 만들었어서 이런기능들이 있으면 좋겠다 싶었던것들을 넣어볼려고 한다.

 

넣고싶은기능

상품목록 페이지

상품디테일 페이지

예약기능 (픽업시간 날짜설정)

포스팅 슬라이더, 포스팅 디테일 페이지

 

관리자용기능

포스팅 등록(이미지,타이틀,해시태그)

메인배너의 이미지를 관리자가 변경할수있도록만들기

일 예약금액의 총합 볼수있는 페이지

고객관리(회원가입한 고객의 이름과 번호)

예약확인.

 

사용하는 라이브러리

react-router-dom

antd

react-icons

styled-components

react-datepicker

axios

 

넣고싶은 기능들을 모두 넣을수있을지는 모르겠지만 일단은 시간이되는데로 해보려고한다.. dev-Matching도 접수해놔서 학원에서는 데브매칭공부하고 집에오면,, 그거복습하고 포트폴리오 할시간이 정말 너무 모자라다.. 타입스크립트도 복습을 좀 해놔야 써먹을 수있을것같은데 해야할건 너무 많은데.. 잠도모자라고 몸도모자라고 어찌되었는 쥐어짜내서 학원의 마지막달을 아름답게 마무리 했으면 한다. 취업하면 이거보다 더 힘들테니 적응한다고생각해보자ㅎ

 

 

반응형
반응형

마지막으로 글을쓴게 2월2일인데 마무리하고 정리하고 올리려니까 벌써 21일이 되버렸다.. 

원래는 중간중간 진행상황같은걸 정리해서 올려보고싶었는데 프로젝트를 진행하는데만 힘을너무쏟아서 블로그쪽은 생각도 안하고있었다.. 멀티가 이렇게나 안되다니.. 

프로젝트 끝난것도 저번주 월요일인데 프로젝트 끝나고 일요일에 정처기 필기시험이있어서 공부하느라 또 정리를 못하고 결국 22일이 되어버렸다.

 

그래도 어떤방법으로 만들었고 어떤걸 만들고싶었었는지 다시한번 정리해놔야 나중에 어떻게만들었는지

기억이 날것같아서 정리를 해볼려고한다.

 

 

프로젝트이름

The나들이

(떠나자 나들이 라는 의미로 만들었다)

 

기능

설정되있는 여행지 중에서 사용자가 선택하고 추천해주는 여행지중에서 여행 경로를 확인하고 관련한  정보를 얻을수있는 사이트

 

사용한라이브러리

@react-google-maps/api   구글지도기능을 이용하기위해 설치

redux-devtools/extension   redux상태를 파악할수있는 미들웨어 

html2/canvas                     화면을 캡쳐할수있게 해주는 라이브러리

antd                                    만들어진 스타일을 이용할수있는 라이브러리

node-sass                          scss를 이용해서 스타일을 적용하기위해 사용

axios                                   get,post요청을 하기위해서 사용.

react-cookie                        로그인 정보를 쿠키로 저장하기위해서 사용.

react-datepicker                  캘린더를 만들어주는 라이브러리

react-router-dom                라우터로 컴포넌트를 마운트시키는 라이브러리

react-redux                          리덕스로 상태값을 관리하는 라이브러리

react-icons                           아이콘을 만드는 라이브러리

styled-components             스타일이 적용된 컴포넌트를 만들어주는 라이브러리

 

필요할때마다 하나씩 설치를 하다보니 꽤 많은 라이브러리를 사용하게 됐다.. 점점 용량이 커지고 npm install 할때 걸리는 시간이 늘어나는게 이게 성능적으로 문제가 없나 싶었다.

꼭 필요한 라이브러리만 설치해서 사용하는게 좋은것같다.

(scss랑 styled-components 같이쓴건 좀 오바였지 싶다..)

 

데이터베이스

City 테이블 :각 나라별 위치좌표,이름,구글맵스에서 사용할 확대값 ,관련 블로그포스팅주소 , 월별 여행관련정보

SpotPlace 테이블: 나라의 추천관광지 이름,좌표,추천관광시간,이미지주소,추천경로순서

member 테이블: 회원가입관련자료: 유저코드,닉네임,비밀번호(암호화),이름,이메일

 

구현된 화면

팀원이 4명이고 다들 해외에서 살다오거나 연수경험이 있어서 각자 자기 지역을 담당해서

4개의 추천여행지를 만들었다

(캐나다,하얼빈,싱가포르:이건내가함!,제주도)

 

1200px 과 768px 에 반응형 디자인을 만들었다.

 

이제 실질적인 기능들이 모두 들어있는 일정만들기 페이지로 들어가보면.

기능이 좀 많은데 현재시간으로 제주도 날씨를 알려주고 (wheatherOnAPI를 이용했다)

달력으로 여행을할 기간을 찍으면 그 기간에 해당하는 여행팁을 알려준다.

오른쪽이 우리가 만들어놓은 추천 여행지인데 +를 눌러서 하나씩 일정을 추가시키면

오른쪽에서는 빠지고 왼쪽에 장소 추가되고 지도위에 마커가뜨고 마커들끼리 선으로 이어져서 동선을 쉽게 확인할수있다. (googlemapsAPI Marker , polyline 이용)

 

오른쪽 추천장소에 마우스를 올리면 해당장소로 지도의 포커스가 옮겨진다

(googlemaps 의 panTo기능을 이용)

아래 여행팁에 가려져있는 부분에 가고싶은 장소를 검색하면 해당장소로 포커스가 옮겨진다.

(구글지도의 자동완성기능사용 autocomplete)

 

지도위의 옵션버튼

 

여행기를 클릭하면 여행기블로그 포스팅이 연결된 팝업을 띄워준다.

<iframe> 태그를 이용해서 블로그 포스팅이있는 주소를 연결해서 보여줌

 

추천일정을 클릭하면 우리가 설정한 추천여행지와 추천코스 순서대로 보여준다

 

추천장소의 이미지가 슬라이더로 자동으로 넘어가고 아래 태그로 추천일정을 하나씩 선택하거나 모두선택버튼으로 모두선택할수있다. 선택하면 왼쪽에 장소가추가되고 지도에 마커와 경로가 그려진다.

장소들의 순서는 가장 좋다고생각하는 동선으로 순서를 정해서 하루정도에 돌아볼수있는 코스로 짜봤다.

 

 이제 일정을 모두 정하고 나면 일정생성버튼을 클릭하면 만든 경로의 이미지를 캡쳐해서 저장해준다.

 

기능들을 만들면서 좀 힘들었던 점이 많았는데 구글맵스 API가 자바스크립트로 사용하는 예시들은 인터넷에 많이 있는데 리액트라이브러리로 만드는 방법들은 예시가 많이 없어서 공식문서를 보고 여러가지 방법을 시도해서 만들었다. 사용된 예시가 많이 없어서 참고할만한게 별로없어서 힘들었다.

 

그리고 이미지를 주소에서 받아오다보니 이미지를 제대로 못받아와서 엑스박스가 뜨는경우가 있었다. 이런 문제를 처음봐서 당황했는데 이미지 태그에 옵션을 추가해주는걸로 해결할수있었다.

<img src={img} referrerpolicy="no-referrer" />

 

 

이미지를 캡쳐하는 라이브러리인  html2canvas도 처음사용해보는거라 어려웠는데 구글mapsAPI를 사용하니까  계속  CORS에러가 나서 이것도 열심히 구글링해서 구문한줄 추가해주니까 해결되었다.

html2canvas(document.getElementsByClassName('App')[0],{ useCORS: true }).then(canvas=>{
           onSaveAs(canvas.toDataURL('image/png'),'image-download.png')
})

 

 

 

페이지가많거나 내용이 많은 페이지는 아니었지만 기능적으로 새로운 api를 사용해보고 새로운걸 알아가면서 해야해서 시간이 좀 많이 걸렸던것같다.

API 관련한 부분은 선생님께 물어볼수도없어서 팀원들끼리 정말 열심히 찾아가면서 했던것같다. redux도 처음에 만들었던 reducer에서  2번정도는 구조를 바꾼것같다.

만들다보니 계속 막히는 부분이 생겨서 처음부터 제대로 다 구상을 해놓고 시작하면 이렇게 안해도될텐데 라는 생각을 계속했던것같다.. 사실 다 구상해놓고 만들수도 없지만..ㅠ 

 

4명이서 만들다보니 깃허브로 처음협업을해봤는데 종종 충돌이 생기고 머지가 안되는 상황이 종종 있었는데. 

이것도 찾아보면서 해결하다보니 확실히 팀으로 해보길 잘했다는 생각이 들었고 깃허브가 진짜 협업에 좋고 정신에 조금 해롭다는 걸 배웠다..

 

이제 개인프로젝트를 해야되는데 이번경험으로 리액트로 프로젝트만드는법에 조금 익숙해진것같아서 개인프로젝트는 조금 더 쉽게 할수있을것같은 생각이든다.

반응형
반응형

이제 3월 23일 수료가 2달 앞으로 다가오면서 슬슬 포트폴리오 압박이 들어오기 시작했다.. 

무조건 리액트로 만들어야하는데 아직 리액트로 엉성한 사이트도 제대로 만들어보지 못해서 걱정이 크다..

검색하다 보면 어떻게든 또 만들겠지 라는 생각으로 일단 함께할 팀원을 모아서 총 4명이서 여행코스를 만들어주는 사이트를 만들기로 했다. 각자 해외에 살다 온 경험이 있는 분들이라서 각 지역별로 추천관광지를 리스트업 하고 사용자가 추천관광지를 클릭하면 지도에 마크가 찍히고 서로 선으로 이어져서 여행동선을 한눈에 보기 편하게 만들어주는 사이트이다.

 

이걸 위해서 지도이미지와 마크 그리고 경로를 그려주는 기능이 필요했는데 마침 구글 maps API에서 모든 기능을 다 지원한다고 해서 일단 구글맵스를 공부하면서 어떻게 적용할지 고민하고 있다. 

 

리액트로 처음 페이지를만들면서 가장 고민되는 점은 어떤 변수들을 상태로 관리해야 하는지이다. 아직 해결은 못했지만 돌아가는 구성을 하나씩 맞춰보면서 사용자와 상호작용하면서 계속해서 변경되는 값들을 상태값으로 관리하려고 생각 중이다.

 

1. 메인페이지

1) 여행선택
2) 사이트소개
3) 이용방법

 

2. 로그인 페이지

 

3. 일정 만들기 페이지

1) 달력, 선택목록 컴포넌트
2) 멀티버튼 (지도 div위에 떠있게)
-- 이용방법, 여행기(블로그포스팅), 추천일정, 일정생성
3) 지도(googlemaps api)
3) 추천 여행지.

 

4. 일정생성 후 뜨는 페이지

일정저장, 이메일전송, 엑셀표출력


이렇게 어떤 페이지를 만들어야 하고 어떤 요소들이 들어가는지 미리 정리해두었고

 

각페이지 구조

각 페이지별로 배치를 어떻게 할지도 작성했다.

 

또 이번에는 제대로 협업을 해보기 위해서 github를 이용해서 collaborate에서

서로 코드리뷰를 하면서 코드를 계속 합쳐가면서 작업해보려고 한다.

(저번에는 그냥 구글드라이브에 각자 올려서 정리했더니 코드 합치는데만 반만년걸렸다..)

 

모든 게다 처음이지만 나중을 위해서 좋은 경험이 될 거라고 생각한다. 기능에 조금 욕심을 내고 싶지만

우선은 핵심기능부터 만들어보고 일정 안에 끝낼 수 있다면 다른 기능도 추가해서 넣어보려고 한다. 

요즘 chatGPT도 유행이던데 여행코스를 AI가 짜서 넣어준다던가.. 아니면 날씨를 API로 받아와서 일정별로 날씨를 알려준다던가 하는 추가적인 기능도 일단은 고려 중이다. 다 할 수 있으면 좋겠다..ㅎ

반응형

+ Recent posts