ETC -

moonbucks-menu 스탭2 회고

  • -

moonbucks-menu 스탭2 중간 회고

안녕하세요 TriplexLab 입니다. 
오늘은 moonbucks-menu 스탭1을 이어서 스탭2 회고를 작성해보겠습니다.

 

moonbucks-menu 스탭1 회고

moonbucks-menu 스탭 1 회고 안녕하세요 TriplexLab 입니다. blackcoffee study라는 프론트 앤드 개발자 스터디를 최근에 알게 되어서 그곳에서 들은 내용들을 적어 보겠습니다. 블랙커피를 소개합니다. 훌

triplexlab.tistory.com

moonbucks-menu 스탭1 회고 참고해주세요. 👍👍

👉 스탭 2 중간즘 에서 얻은 인사이트

1. 상태값이 중요한 이유는 사용자에게 입력 받은 정보(상태)를 저장하고, 불러와줘야 동적인 웹페이지를 만들수가 있습니다. 
 - (EX) 채팅창으로 예시로 들면 A라는 채팅방,B라는 채팅방,C라는 채팅방들을 각각 동립적인 채팅방을 만들기 위해서는 상태값이 중요합니다.(여기서 각각 채팅방을 인스턴스로 동적으로 생성할수 있습)

// Step2
// TODO localStorage Read & Write
// - [x] localStorage에 데이터를 저장한다.
//  - [x] 메뉴를 추가할 때
//  - [x] 메뉴를 수정할 때
//  - [x] 메뉴를 삭제할 때
// - [x] localStorage에 있는 데이터를 읽어온다.

// TODO 카테고리별 메뉴판 관리
// - [x] 에스프레소 메뉴판 관리
// - [x] 프라푸치노 메뉴판 관리
// - [x] 블렌디드 메뉴판 관리
// - [x] 티바나 메뉴판 관리
// - [x] 디저트 메뉴판 관리

// TODO 페이지 접근시 최초 데이터 Read & Rendering
// - [x] 최초로 로딩될때 localStorage에 에스프레소 메뉴를 읽어온다.
// - [x] 에스프레소 메뉴를 페이지에 그려준다.

// TODO 품절 상태 관리
// - [] 품절 상태인 경우를 보여줄 수 있게, 품절 버튼을 추가하고 sold-out class를 추가하여 상태를 변경한다.
// - [] 품절 버튼을 추가한다.
// - [] 품절 버튼을 클릭하면 localStorage에 상태값이 저장된다.
// - [] 클릭이벤트에서 가장가까운 li태그에 class속성 값이 sold-out을 추가한다.

const $ = element => document.querySelector(element);

const store = {
    setLocalStorage(menu) {
        localStorage.setItem("menu", JSON.stringify(menu));
    },
    getLocalStorage() {
        return JSON.parse(localStorage.getItem("menu"));
    }
}

function App(){
    // 상태를 변하는 데이터, 이 앱에서 변하는 것이 무엇인가 - 메뉴명
    this.menu = {
        espresso: new Array(),
        frappuccino: new Array(),
        blended: new Array(),
        teavana: new Array(),
        desert: new Array()
    };
    this.currentCategory = 'espresso';

    const render = () => {
        const template = this.menu[this.currentCategory].map((menuItem, idx) => {
            return `<li data-menu-id="${idx}" class="menu-list-item d-flex items-center py-2">
                <span class="w-100 pl-2 menu-name">${menuItem.name}</span>
                <button type="button" class="bg-gray-50 text-gray-500 text-sm mr-1 menu-edit-button">
                    수정
                </button>
                <button type="button" class="bg-gray-50 text-gray-500 text-sm menu-remove-button">
                    삭제
                </button>
            </li>`
        }).join(''); //배열객체에 있는 li항목 들을 하나로 합쳐주는 join역할

        $('#menu-list').innerHTML = template
        updateMenuCount();
    };

    const updateMenuCount = () => {
        const mentCount = $('#menu-list').querySelectorAll('li').length;
        $('.menu-count').innerText = `총 ${mentCount}개`;
    };

    const addMenuName = () => {
        if($('#menu-name').value === ''){
            alert('값을 입력해주세요.');
            return;
        }
        const menuName = $('#menu-name').value;
        this.menu[this.currentCategory].push({ name: menuName });
        store.setLocalStorage(this.menu); //상태가 변하는 시졈에 localStorage에 데이터를 저장한다.
        render();
        $('#menu-name').value = '';
    };

    const updateMenuName = (e) => {
        const menuId = e.target.closest('li').dataset.menuId;
        const $menuName = e.target.closest('li').querySelector('.menu-name');
        const updateedMenuName = prompt('메뉴명을 수정하세요', $menuName.innerText);
        this.menu[this.currentCategory][menuId].name = updateedMenuName; //기존에 있던 this.menu 배열에 수정하여 저장한다.
        store.setLocalStorage(this.menu); //그리고 다시 localStorage에 데어터를 저장한다.
        $menuName.innerText = updateedMenuName;
    };

    const removeMenuName = (e) => {
        if(confirm('정말 삭제하시겠습니까?')){
            const menuId = e.target.closest('li').dataset.menuId;
            this.menu[this.currentCategory].splice(menuId, 1);
            store.setLocalStorage(this.menu);
            e.target.closest('li').remove();
            updateMenuCount();
        }
    }

    $("#menu-list").addEventListener("click", (e) => {
        if(e.target.classList.contains('menu-edit-button')) {
            updateMenuName(e);
        }

        if(e.target.classList.contains('menu-remove-button')){
            removeMenuName(e);
        }
    });

    $('#menu-form').addEventListener('submit', (e) => {
        e.preventDefault();
    });

    $('#menu-name').addEventListener('keypress', (e) => {
        if(e.key !== 'Enter') return;
        addMenuName();
    });

    $('#menu-submit-button').addEventListener('click', addMenuName);

    $('nav').addEventListener('click', (e) => {
        const isCategoryButton = e.target.classList.contains('cafe-category-name');
        if(isCategoryButton){
            const categoryName = e.target.dataset.categoryName;
            this.currentCategory = categoryName;
            $('#category-title').innerText = `${e.target.innerText} 메뉴 관리`;
            render();
        }
    });

    this.init = () => {
        if(store.getLocalStorage()){
            this.menu = store.getLocalStorage()
            render();
        }
    };
}
const app = new App();
app.init();

 

여기까지 중간즘 진행한 작업 파일을 공유합니다.
아래파일을 참고하세요~ 👍👍 

moonbucks-menu.zip
0.29MB


moonbucks-menu 스탭2 회고

👉 스탭 2에서 얻은 인사이트

1. 카테고리 메뉴 추가할때 아래처럼 this.menu를 객체를 만들어서 각각의 카테로기 별로 데이터를 관리할수 있는 형태를 사용할수 있어서 신기했다. 그리고 현재카테로기명을 초기화를 해서 사용

2. undefined은 기본적으로 Falsy한 값을 가지고 있어서 앞에 느낌표를 붙여주면 true 로전환됩니다.

this.menu = {
	espresso: new Array(),
	frappuccino: new Array(),
	blended: new Array(),
	teavana: new Array(),
	desert: new Array()
};
this.currentCategory = 'espresso';

this.init = (name) => {
	const message = store.getLocalStorage(name)
	if(message){ //localStorage에 값이 있을때만
		this.menu = message; // 값을 this.menu에 할당한다.
	}
	render();
};
 const soldOutMenu = (e) => {
 	const menuId = parseInt(e.target.closest('li').dataset.menuId);
	this.menu[this.currentCategory].forEach((el, idx) => {
		if(this.menu[this.currentCategory][idx].id === menuId){
		 	this.menu[this.currentCategory][idx].soldOut = !this.menu[this.currentCategory][idx].soldOut; //undefined(기본적으로 Falsy한 값)에 느낌표를 붙여주면 true 로전환됩니다.그래서 토글기능이 가능해집니다.
 		}
 	});
 	store.setLocalStorage('menu',this.menu);
	render();
}

 

여기까지 진행한 작업 파일을 공유합니다~
아래파일을 참고하세요 👨‍💻👨‍💻

moonbucks-menu.zip
0.29MB

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.