diff --git a/packages/xianeml/src/components/MenuItem.ts b/packages/xianeml/src/components/MenuItem.ts
index 9da783e..6a0fcc5 100644
--- a/packages/xianeml/src/components/MenuItem.ts
+++ b/packages/xianeml/src/components/MenuItem.ts
@@ -1,13 +1,9 @@
import { Tstate } from '../types/store.js';
-import { getCategoryMenus } from '../utils/helper.js';
-const MenuItem = (state: Tstate) => {
- const { menus, currentTab } = state;
- const categoryMenus = getCategoryMenus(menus, currentTab);
-
- return categoryMenus
+const MenuItem = ({ menus }: Tstate) => {
+ return menus
.map(
- menu =>
+ (menu) =>
`
`,
+`
)
.join('');
};
diff --git a/packages/xianeml/src/js/events.ts b/packages/xianeml/src/js/events.ts
index cc3a26a..0ddb4e7 100644
--- a/packages/xianeml/src/js/events.ts
+++ b/packages/xianeml/src/js/events.ts
@@ -15,13 +15,15 @@ export const handleNavigation = (store: Tstore) => (e: Event) => {
store.dispatch(setCurrentTab(categoryId));
};
-export const handleSubmitMenuForm = (store: Tstore) => (e: Event) => {
+export const handleSubmitMenuForm = (store: Tstore) => async (e: Event) => {
e.preventDefault();
const $menuInput = $('#espresso-menu-name') as HTMLInputElement;
if (!$menuInput.value) return;
- const { menus, currentTab } = store.getState();
+ const state = await store.getState();
+ const { menus, currentTab } = state;
+
if (menus && menus.length === 20) {
return alert('메뉴는 20개까지 추가 가능합니다.');
}
@@ -29,7 +31,7 @@ export const handleSubmitMenuForm = (store: Tstore) => (e: Event) => {
$menuInput.value = '';
};
-export const handleMenuList = (e: Event, store: Tstore) => {
+export const handleMenuList = (store: Tstore) => (e: Event) => {
const target = e.target as HTMLElement;
const targetMenuId = (target.parentElement as HTMLElement).id;
diff --git a/packages/xianeml/src/js/renderViews.ts b/packages/xianeml/src/js/renderViews.ts
index a524bca..77e7a87 100644
--- a/packages/xianeml/src/js/renderViews.ts
+++ b/packages/xianeml/src/js/renderViews.ts
@@ -3,13 +3,13 @@ import layoutView from '../components/layout/index.js';
import { Tstore } from '../types/store.js';
import { handleNavigation, handleSubmitMenuForm, handleMenuList } from './events.js';
-export const renderViews = (store: Tstore) => {
- const state = store.getState();
+export const renderViews = async (store: Tstore) => {
+ const state = await store.getState();
$('#app').innerHTML = layoutView(state);
const $menuForm = $('#espresso-menu-form');
const $menuList = $('#espresso-menu-list');
$('nav').addEventListener('click', handleNavigation(store));
$menuForm.addEventListener('submit', handleSubmitMenuForm(store));
- $menuList.addEventListener('click', (e: Event) => handleMenuList(e, store));
+ $menuList.addEventListener('click', handleMenuList(store));
};
diff --git a/packages/xianeml/src/store/helper.ts b/packages/xianeml/src/store/helper.ts
index a735825..4c696d5 100644
--- a/packages/xianeml/src/store/helper.ts
+++ b/packages/xianeml/src/store/helper.ts
@@ -1,4 +1,5 @@
import { Treducer, TmenuAction, Tlistener, Tstate, Tstore } from '../types/store.js';
+import { getMenus } from '../api/menu.js';
export const createStore = (reducer: Treducer): Tstore => {
const initialState: Tstate = {
@@ -15,19 +16,15 @@ export const createStore = (reducer: Treducer): Tstore => {
const listeners: Tlistener[] = [];
- const getState = () => {
- return JSON.parse(localStorage.getItem('state') || '{}') as Tstate;
+ const getState = async () => {
+ const menus = await getMenus(initialState.currentTab.id);
+ const state = { ...initialState, menus };
+
+ return state;
};
const dispatch = (action: TmenuAction) => {
- const storageState = JSON.parse(localStorage.getItem('state') || '{}');
-
- if (!storageState) {
- localStorage.setItem('state', JSON.stringify(initialState));
- } else {
- const newState = reducer(storageState, action);
- localStorage.setItem('state', JSON.stringify(newState));
- }
+ reducer(initialState, action);
publish();
};
diff --git a/packages/xianeml/src/store/menu.ts b/packages/xianeml/src/store/menu.ts
index b37203b..56d046b 100644
--- a/packages/xianeml/src/store/menu.ts
+++ b/packages/xianeml/src/store/menu.ts
@@ -1,5 +1,6 @@
import { Tcategory, TmenuAction } from '../types/store.js';
import { Tstate } from '../types/store.js';
+import { createMenu } from '../api/menu.js';
/* 액션 타입 정의 */
const CREATE_MENU = 'CREATE_MENU' as const;
@@ -47,24 +48,18 @@ export const setCurrentTab = (categoryId: string) => ({
});
// 리듀서는 새로운 상태를 생성하는 함수.
-export default function reducer(state: Tstate, action: TmenuAction) {
+export default async function reducer(state: Tstate, action: TmenuAction) {
const { type, payload } = action;
const { categoryId = '', menuId = '', menuName = '' } = payload;
const { menus, categories } = state;
switch (type) {
case CREATE_MENU: {
- const categoryMenus = menus.filter(menu => {
- return menu.categoryId === categoryId;
- });
- // TODO: 중복 가능성 의심, UUID 적용
- const id = `${categoryId}-menu-id-${categoryMenus.length}`;
- const newMenu = { id, categoryId, menuName, inStock: true };
- const newMenuList = [...menus, newMenu];
- return { ...state, menus: newMenuList };
+ await createMenu({ category: categoryId, name: menuName });
+ break;
}
case EDIT_MENU: {
- const newMenuList = menus.map(menu => {
+ const newMenuList = menus.map((menu) => {
if (menu.id === menuId) {
menu.menuName = menuName;
}
@@ -73,11 +68,11 @@ export default function reducer(state: Tstate, action: TmenuAction) {
return { ...state, menus: newMenuList };
}
case REMOVE_MENU: {
- const newMenuList = menus.filter(menu => menu.id !== menuId);
+ const newMenuList = menus.filter((menu) => menu.id !== menuId);
return { ...state, menus: newMenuList };
}
case SOLD_OUT_MENU: {
- const newMenuList = menus.map(menu => {
+ const newMenuList = menus.map((menu) => {
if (menu.id === menuId) {
menu.inStock = false;
}
diff --git a/packages/xianeml/src/types/api.ts b/packages/xianeml/src/types/api.ts
index 7702729..426ba74 100644
--- a/packages/xianeml/src/types/api.ts
+++ b/packages/xianeml/src/types/api.ts
@@ -1,5 +1,17 @@
export type Tparams = {
- category: string;
+ category?: string;
menuId?: string;
name?: string;
};
+
+export type TmenuResponse = {
+ menuId: string;
+ name: string;
+ isSoldOut: boolean;
+};
+
+export type TrequestConfig = {
+ url: string;
+ method: string;
+ data?: { name?: string };
+};
diff --git a/packages/xianeml/src/types/store.ts b/packages/xianeml/src/types/store.ts
index c3f7faa..4c1989f 100644
--- a/packages/xianeml/src/types/store.ts
+++ b/packages/xianeml/src/types/store.ts
@@ -1,7 +1,7 @@
-export type Treducer = (state: Tstate, action: TmenuAction) => Tstate;
+export type Treducer = (state: Tstate, action: TmenuAction) => Promise;
export type Tstore = {
- getState: () => Tstate;
+ getState: () => Promise;
dispatch: (action: TmenuAction) => void;
subscribe: (callback: Tlistener) => void;
};
@@ -23,7 +23,6 @@ export type TmenuAction = {
export type Tmenu = {
id: string;
- categoryId: string;
menuName: string;
inStock: boolean;
};
diff --git a/packages/xianeml/src/utils/request.ts b/packages/xianeml/src/utils/request.ts
index cbd261f..f3be841 100644
--- a/packages/xianeml/src/utils/request.ts
+++ b/packages/xianeml/src/utils/request.ts
@@ -1,26 +1,33 @@
import { SERVER_URL } from '../utils/constants/env.js';
+import { TmenuResponse, TrequestConfig } from '../types/api.js';
+import { Tmenu } from '../types/store.js';
-type Tconfig = {
- url: string;
- method: string;
- data?: { name?: string };
-};
-
-export default async (config: Tconfig) => {
+export default async (config: TrequestConfig) => {
const { url, method, data } = config;
const requestUrl = SERVER_URL + url;
+ const headers = {
+ 'Content-Type': 'application/json',
+ };
+
+ try {
+ const response = await fetch(requestUrl, {
+ method,
+ headers,
+ body: JSON.stringify(data),
+ });
+
+ if (response.status !== 200) throw Error('요청 에러');
+ if (method !== 'GET') return;
- const response = await fetch(requestUrl, {
- method,
- body: JSON.stringify(data),
- });
- console.log('요청정보? >>>> ', response);
- const resData = await response.json();
+ const resData = await response.json();
- if (response.status === 200) {
- return resData;
- } else {
- throw new Error('서버요청 에러!!');
+ return resData.map((data: TmenuResponse) => ({
+ id: data.menuId,
+ menuName: data.name,
+ inStock: !data.isSoldOut,
+ })) as Tmenu[];
+ } catch (e) {
+ console.error(e);
}
};