-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c225a17
commit 9bce1ba
Showing
20 changed files
with
12,245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"singleQuote": true, | ||
"semi": true, | ||
"useTabs": false, | ||
"tabWidth": 2, | ||
"trailingComma": "all", | ||
"printWidth": 80 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# fe-vm | ||
|
||
web vending machine project |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": "src" | ||
}, | ||
"includes": ["src"] | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
"name": "fe-vm", | ||
"version": "0.1.0", | ||
"private": true, | ||
"dependencies": { | ||
"@testing-library/jest-dom": "^5.16.4", | ||
"@testing-library/react": "^13.2.0", | ||
"@testing-library/user-event": "^13.5.0", | ||
"eslint-config-airbnb": "^19.0.4", | ||
"eslint-config-prettier": "^8.5.0", | ||
"react": "^18.1.0", | ||
"react-dom": "^18.1.0", | ||
"react-router-dom": "^6.3.0", | ||
"react-scripts": "5.0.1", | ||
"styled-components": "^5.3.5", | ||
"styled-reset": "^4.3.4", | ||
"web-vitals": "^2.1.4" | ||
}, | ||
"scripts": { | ||
"start": "react-scripts start", | ||
"build": "react-scripts build", | ||
"test": "react-scripts test", | ||
"eject": "react-scripts eject" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"airbnb", | ||
"prettier" | ||
], | ||
"rules": { | ||
"import/no-unresolved": "off", | ||
"react/prop-types": "off", | ||
"react/no-array-index-key": "off", | ||
"no-use-before-define": "off" | ||
}, | ||
"env": { | ||
"browser": true | ||
} | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="ko"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>웹 자판기</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# https://www.robotstxt.org/robotstxt.html | ||
User-agent: * | ||
Disallow: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* eslint-disable react/jsx-no-constructed-context-values */ | ||
import Home from 'pages/Home'; | ||
import Wallet from 'pages/Wallet'; | ||
import React, { useState } from 'react'; | ||
import { BrowserRouter, Link, Route, Routes } from 'react-router-dom'; | ||
import styled from 'styled-components'; | ||
import { delay } from 'utils'; | ||
|
||
export const MoneyContext = React.createContext(); | ||
|
||
const defaultMoney = 0; | ||
const defaultErrorMsg = ''; | ||
|
||
function App() { | ||
const [curMoney, setMoney] = useState(defaultMoney); | ||
const [errorMsg, setErrorMsg] = useState(defaultErrorMsg); | ||
|
||
return ( | ||
<MoneyContext.Provider value={{ curMoney, setMoney, showErrorMsg }}> | ||
<BrowserRouter> | ||
<Nav> | ||
<Link to="/">자판기</Link> | ||
<Link to="wallet">지갑</Link> | ||
</Nav> | ||
<Routes> | ||
<Route index path="/" element={<Home />} /> | ||
<Route path="wallet" element={<Wallet />} /> | ||
</Routes> | ||
<ErrorMsg>{errorMsg}</ErrorMsg> | ||
</BrowserRouter> | ||
</MoneyContext.Provider> | ||
); | ||
async function showErrorMsg(msg) { | ||
setErrorMsg(msg); | ||
const DELAY_MS = 3000; | ||
await delay(DELAY_MS); | ||
setErrorMsg(''); | ||
} | ||
} | ||
|
||
export default App; | ||
|
||
const Nav = styled.nav({ | ||
display: 'flex', | ||
gap: '10px', | ||
}); | ||
const ErrorMsg = styled.div({ | ||
padding: '10px', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React, { useContext, useState } from 'react'; | ||
import styled from 'styled-components'; | ||
import { MoneyContext } from 'components/App'; | ||
import MESSAGES from 'messages'; | ||
|
||
function Coin({ amount, cnt }) { | ||
const { curMoney, setMoney, showErrorMsg } = useContext(MoneyContext); | ||
const [moneyCnt, setMoneyCnt] = useState(cnt); | ||
return ( | ||
<Wrap> | ||
<Amount onClick={handleChargeMoney}>{amount}원</Amount> | ||
<Box>{moneyCnt}개</Box> | ||
</Wrap> | ||
); | ||
function handleChargeMoney() { | ||
const hasCoins = moneyCnt >= 1; | ||
if (!hasCoins) { | ||
showErrorMsg(MESSAGES.ERROR.NOT_ENOUGH_COINS); | ||
return; | ||
} | ||
setMoney(curMoney + amount); | ||
setMoneyCnt(moneyCnt - 1); | ||
} | ||
} | ||
|
||
export default Coin; | ||
|
||
const Wrap = styled.div({ | ||
display: 'flex', | ||
gap: '10px', | ||
}); | ||
const Box = styled.div({ | ||
width: '100px', | ||
height: '50px', | ||
textAlign: 'center', | ||
lineHeight: '50px', | ||
border: '1px solid black', | ||
}); | ||
const Amount = styled(Box)({ | ||
cursor: 'pointer', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React, { useContext } from 'react'; | ||
import styled from 'styled-components'; | ||
import { MoneyContext } from 'components/App'; | ||
|
||
function ControlPanel() { | ||
const { curMoney } = useContext(MoneyContext); | ||
return ( | ||
<Wrap> | ||
<Row> | ||
<Money value={curMoney} /> | ||
<span>원</span> | ||
</Row> | ||
<button type="button">반환하기</button> | ||
<EventLog /> | ||
</Wrap> | ||
); | ||
} | ||
|
||
export default ControlPanel; | ||
|
||
const Wrap = styled.div({ | ||
width: '300px', | ||
display: 'flex', | ||
flexDirection: 'column', | ||
padding: '20px', | ||
gap: '20px', | ||
}); | ||
const Row = styled.div({ | ||
display: 'flex', | ||
}); | ||
const Money = styled.input({ | ||
width: '100%', | ||
textAlign: 'right', | ||
}); | ||
const EventLog = styled.div({ | ||
border: '1px solid black', | ||
height: '100%', | ||
overflowY: 'auto', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { useContext } from 'react'; | ||
import styled from 'styled-components'; | ||
import { MoneyContext } from 'components/App'; | ||
import Coin from 'components/Coin'; | ||
import COINS from 'mock/coins'; | ||
|
||
function MoneyCharge() { | ||
const { curMoney } = useContext(MoneyContext); | ||
return ( | ||
<Wrap> | ||
<Coins /> | ||
<Total> | ||
<div>{curMoney}</div> | ||
<div>원</div> | ||
</Total> | ||
</Wrap> | ||
); | ||
} | ||
|
||
function Coins() { | ||
return COINS.map(({ AMOUNT, CNT }) => ( | ||
<Coin key={`${AMOUNT}`} amount={AMOUNT} cnt={CNT} /> | ||
)); | ||
} | ||
|
||
const Wrap = styled.div({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
width: '200px', | ||
gap: '20px', | ||
marginTop: '20px', | ||
}); | ||
const Total = styled.div({ | ||
width: '100%', | ||
textAlign: 'end', | ||
gridColumnStart: 'span 2', | ||
display: 'flex', | ||
border: '1px solid black', | ||
height: '50px', | ||
lineHeight: '50px', | ||
}); | ||
|
||
export default MoneyCharge; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
function Product({ name, price }) { | ||
return ( | ||
<Wrap> | ||
<Name>{name}</Name> | ||
<Price>{price}</Price> | ||
</Wrap> | ||
); | ||
} | ||
|
||
export default Product; | ||
|
||
const Wrap = styled.div({}); | ||
const Name = styled.div({ | ||
border: '1px solid black', | ||
height: '50px', | ||
textAlign: 'center', | ||
lineHeight: '50px', | ||
}); | ||
const Price = styled.div({ | ||
textAlign: 'center', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom/client'; | ||
import App from './components/App'; | ||
|
||
const root = ReactDOM.createRoot(document.getElementById('root')); | ||
root.render( | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode>, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const MESSAGES = { | ||
ERROR: { | ||
NOT_ENOUGH_COINS: | ||
'🚨 동전 또는 지폐의 개수가 0개 이하라서 충전에 실패했습니다. 🚨', | ||
NOT_ENOUGH_MONEY: '🚨 돈이 부족해서 상품을 선택할 수 없습니다. 🚨', | ||
}, | ||
}; | ||
|
||
export default MESSAGES; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { getRandomNumber } from 'utils'; | ||
|
||
const COINS = [ | ||
{ AMOUNT: 10, CNT: getNumber1to10() }, | ||
{ AMOUNT: 50, CNT: getNumber1to10() }, | ||
{ AMOUNT: 100, CNT: getNumber1to10() }, | ||
{ AMOUNT: 500, CNT: getNumber1to10() }, | ||
{ AMOUNT: 1000, CNT: getNumber1to10() }, | ||
{ AMOUNT: 5000, CNT: getNumber1to10() }, | ||
{ AMOUNT: 10000, CNT: getNumber1to10() }, | ||
]; | ||
|
||
function getNumber1to10() { | ||
return getRandomNumber({ min: 0, max: 10 }); | ||
} | ||
|
||
export default COINS; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const PRODUCTS = [ | ||
{ name: '콜라 1', price: '500' }, | ||
{ name: '콜라 2', price: '1000' }, | ||
{ name: '콜라 3', price: '1500' }, | ||
{ name: '콜라 4', price: '2000' }, | ||
{ name: '콜라 5', price: '2500' }, | ||
{ name: '콜라 6', price: '3000' }, | ||
{ name: '콜라 7', price: '3500' }, | ||
{ name: '콜라 8', price: '4000' }, | ||
{ name: '콜라 9', price: '4500' }, | ||
{ name: '콜라 10', price: '5000' }, | ||
{ name: '콜라 11', price: '5500' }, | ||
{ name: '콜라 12', price: '6000' }, | ||
{ name: '콜라 13', price: '6500' }, | ||
{ name: '콜라 14', price: '7000' }, | ||
{ name: '콜라 15', price: '7500' }, | ||
{ name: '콜라 16', price: '8000' }, | ||
{ name: '콜라 17', price: '8500' }, | ||
{ name: '콜라 18', price: '9000' }, | ||
{ name: '콜라 19', price: '9500' }, | ||
{ name: '콜라 20', price: '10000' }, | ||
]; | ||
|
||
export default PRODUCTS; |
Oops, something went wrong.