diff --git a/.gitignore b/.gitignore index 49b960da7..356a301c1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ db.json # test file cypress/fixtures/ -cypress/videos/ \ No newline at end of file +cypress/videos/ +cypress/screenshots/ \ No newline at end of file diff --git a/src/css/global.css b/src/css/global.css index 5db220250..fb41b5919 100644 --- a/src/css/global.css +++ b/src/css/global.css @@ -10,4 +10,7 @@ --button-hover-color: rgba(0, 188, 212, 0.16); --primary-text-color: rgba(0, 0, 0, 0.87); --list-border-color: #dcdcdc; + --snackbar-bg-color: #333; + --snackbar-text-color: #fff; + --snackbar-error-bg-color: rgb(177, 28, 28); } diff --git a/src/css/index.css b/src/css/index.css index 605226ee4..10130682e 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -15,6 +15,15 @@ a { text-decoration: none; } +li { + list-style-type: none; + text-align: center; + font-style: normal; + display: flex; + justify-content: center; + border-bottom: 1px solid var(--list-border-color); +} + #app { width: 40%; min-width: 465px; @@ -165,10 +174,6 @@ input:focus { height: 35px; } -.single-input { - width: 300px; -} - .single-input-container { margin: auto; } @@ -206,7 +211,9 @@ h4 { align-items: center; width: 100%; } -#product-list-wrapper ul { + +#product-list-wrapper ul, +#change-list-wrapper ul { padding: 0; } @@ -217,19 +224,6 @@ h4 { width: 100%; } -#change-list-wrapper ul { - padding: 0; -} - -li { - list-style-type: none; - text-align: center; - font-style: normal; - display: flex; - justify-content: center; - border-bottom: 1px solid var(--list-border-color); -} - #product-list { width: 100%; } @@ -279,7 +273,8 @@ li { margin-top: -8px; } -#change-list li { +#change-list li, +.single-input { width: 300px; } diff --git a/src/css/snackbar.css b/src/css/snackbar.css index d651cfdbf..bae63ce8c 100644 --- a/src/css/snackbar.css +++ b/src/css/snackbar.css @@ -12,8 +12,8 @@ visibility: hidden; min-width: 250px; max-width: 300px; - background-color: #333; - color: #fff; + background-color: var(--snackbar-bg-color); + color: var(--snackbar-text-color); text-align: center; border-radius: 2px; padding: 16px; @@ -22,7 +22,7 @@ } .error { - background-color: rgb(177, 28, 28); + background-color: var(--snackbar-error-bg-color); } .show { diff --git a/src/js/__test__/vendingMachine.test.js b/src/js/__test__/vendingMachine.test.js index 6cc56799f..9ee37ea02 100644 --- a/src/js/__test__/vendingMachine.test.js +++ b/src/js/__test__/vendingMachine.test.js @@ -1,5 +1,5 @@ import { ERROR_MESSAGE } from '../constants'; -import vendingMachine from '../model/VendingMachine'; +import vendingMachine from '../model/vendingMachine_Test'; describe('자판기 기본 기능 테스트', () => { describe('자판기 상품 추가 기능 테스트', () => { diff --git a/src/js/api/requestLogin.ts b/src/js/api/requestLogin.ts index 148223b7e..7e1597dd3 100644 --- a/src/js/api/requestLogin.ts +++ b/src/js/api/requestLogin.ts @@ -1,17 +1,14 @@ -import { ALERT_MESSAGE, ERROR_MESSAGE, SERVER_URL } from '../constants'; +import { ERROR_MESSAGE } from '../constants'; +import { LoginSuccess } from '../interfaces/apiStatus.interface'; +import ApiWrapper from '../utils/ApiWrapper'; -const requestLogin = async (accountData: Object) => { - const response = await fetch(SERVER_URL + '/login', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(accountData), - }); +const apiWrapper = new ApiWrapper(); - const dataResult = await response.json(); +const requestLogin = async (accountData: Object) => { + const response = await apiWrapper.post('/login', accountData); + const dataResult: LoginSuccess | string = await response.json(); - if (!response.ok) { + if (typeof dataResult === 'string') { switch (dataResult) { case 'Cannot find user': throw new Error(ERROR_MESSAGE.USER_IS_NOT_EXIST); @@ -21,9 +18,7 @@ const requestLogin = async (accountData: Object) => { throw new Error(dataResult); } - localStorage.setItem('accessToken', dataResult.accessToken); - localStorage.setItem('user', JSON.stringify(dataResult.user)); - return ALERT_MESSAGE.LOGIN_SUCCESS(dataResult.user.name); + return dataResult; }; export default requestLogin; diff --git a/src/js/api/requestModifyUserData.ts b/src/js/api/requestModifyUserData.ts index 2cc2a01ba..0dc851075 100644 --- a/src/js/api/requestModifyUserData.ts +++ b/src/js/api/requestModifyUserData.ts @@ -1,18 +1,14 @@ -import { ALERT_MESSAGE, ERROR_MESSAGE, SERVER_URL } from '../constants'; +import { ERROR_MESSAGE } from '../constants'; import { User } from '../interfaces/UserData.interface'; +import ApiWrapper from '../utils/ApiWrapper'; -const requestModifyUserData = async (userData: User) => { - const response = await fetch(SERVER_URL + `/users/${userData.id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(userData), - }); +const apiWrapper = new ApiWrapper(); - const dataResult = await response.json(); +const requestModifyUserData = async (userData: User) => { + const response = await apiWrapper.put(`/users/${userData.id}`, userData); + const dataResult: User | string = await response.json(); - if (!response.ok) { + if (typeof dataResult === 'string') { switch (dataResult) { case 'Password is too short': throw new Error(ERROR_MESSAGE.PASSWORD_IS_TOO_SHORT); @@ -20,14 +16,7 @@ const requestModifyUserData = async (userData: User) => { throw new Error(dataResult); } - const updatedInfo = { - email: dataResult.email, - name: dataResult.name, - id: dataResult.id, - }; - - localStorage.setItem('user', JSON.stringify(updatedInfo)); - return ALERT_MESSAGE.USER_INFO_MODIFY_SUCCESS; + return dataResult; }; export default requestModifyUserData; diff --git a/src/js/api/requestRegister.ts b/src/js/api/requestRegister.ts index 396a8064d..a4236a0cf 100644 --- a/src/js/api/requestRegister.ts +++ b/src/js/api/requestRegister.ts @@ -1,14 +1,11 @@ -import { ALERT_MESSAGE, ERROR_MESSAGE, SERVER_URL } from '../constants'; +import { ERROR_MESSAGE } from '../constants'; import { User } from '../interfaces/UserData.interface'; +import ApiWrapper from '../utils/ApiWrapper'; + +const apiWrapper = new ApiWrapper(); const requestRegister = async (userData: User) => { - const response = await fetch(SERVER_URL + '/users', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(userData), - }); + const response = await apiWrapper.post('/users', userData); if (!response.ok) { const errorMessage = await response.json(); @@ -21,7 +18,7 @@ const requestRegister = async (userData: User) => { throw new Error(errorMessage); } - return ALERT_MESSAGE.REGISTER_SUCCESS; + return true; }; export default requestRegister; diff --git a/src/js/components/AddChangeComponent.ts b/src/js/components/AddChangeComponent.ts index dea2532d8..ef8efca24 100644 --- a/src/js/components/AddChangeComponent.ts +++ b/src/js/components/AddChangeComponent.ts @@ -1,18 +1,21 @@ +import coinModel from '../model/CoinModel'; import vendingMachine from '../model/VendingMachine'; import throwableFunctionHandler from '../utils/throwableFunctionHandler'; +import * as Component from './abstractComponents/Component'; -class AddChangeComponent { +class AddChangeComponent extends Component.DynamicComponent { $changeAddForm: HTMLElement; $totalChange: HTMLElement; noticeStateChanged: Function; parentElement: HTMLElement; constructor(parentElement: HTMLElement, noticeStateChanged: Function) { + super(); this.parentElement = parentElement; this.noticeStateChanged = noticeStateChanged; } - private bindEventAndElement = () => { + protected bindEventAndElement = () => { this.$totalChange = document.querySelector('#total-change'); this.$changeAddForm = document.querySelector('#change-add-form'); this.$changeAddForm.addEventListener('submit', this.onSubmitChangeAdd); @@ -28,7 +31,7 @@ class AddChangeComponent { }; refreshChange = () => { - this.$totalChange.textContent = vendingMachine.getTotalMoney().toString(); + this.$totalChange.textContent = coinModel.getCoinsValue(vendingMachine.getVendingMachineMoney()).toString(); }; render = () => { @@ -36,8 +39,8 @@ class AddChangeComponent { this.bindEventAndElement(); }; - private template = () => ` -
자판기가 보유할 금액을 입력해주세요