Skip to content

Commit ba05784

Browse files
committed
add: 랜덤 명언 뽑기 UI 완성
1 parent 7a31a1a commit ba05784

File tree

7 files changed

+172
-0
lines changed

7 files changed

+172
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>랜덤 명언 뽑기</title>
8+
<link rel="stylesheet" href="./src/style.css" />
9+
</head>
10+
<body>
11+
<main id="app"></main>
12+
<script src="./src/main.js" type="module"></script>
13+
</body>
14+
</html>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { request } from "./api.js";
2+
import Button from "./Button.js";
3+
import QuoteBox from "./QuoteBox.js";
4+
5+
export default function App({ $target }) {
6+
const quoteBox = new QuoteBox({ $target });
7+
new Button({
8+
$target,
9+
onClick: async () => {
10+
const generatedQuoteSet = await request();
11+
const quote = `"${generatedQuoteSet.quote.replace("\uFFFD", "'")}"`;
12+
const author = generatedQuoteSet.author
13+
? `- ${generatedQuoteSet.author}`
14+
: ``;
15+
16+
quoteBox.setState({
17+
...quoteBox.state,
18+
quote,
19+
author,
20+
});
21+
},
22+
});
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default function Button({ $target, onClick }) {
2+
const $button = document.createElement("button");
3+
$target.append($button);
4+
$button.textContent = "Generate Quote";
5+
6+
$button.addEventListener("click", (e) => {
7+
onClick();
8+
});
9+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default function QuoteBox({ $target }) {
2+
const $box = document.createElement("div");
3+
$target.append($box);
4+
$box.className = "quoteContainer";
5+
6+
this.state = {
7+
quote: "",
8+
author: "",
9+
};
10+
11+
this.setState = (nextState) => {
12+
this.state = nextState;
13+
this.render();
14+
};
15+
16+
this.render = () => {
17+
const { quote, author } = this.state;
18+
$box.innerHTML = /* html */ `
19+
<p class="quoteArea">${quote}</p>
20+
<p class="authorArea">${author}</p>
21+
`;
22+
};
23+
24+
this.render();
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const API_END_POINT = "https://free-quotes-api.herokuapp.com/";
2+
3+
export const request = async () => {
4+
try {
5+
const res = await fetch(API_END_POINT);
6+
7+
if (!res.ok) {
8+
throw new Error("API 호출 에러");
9+
}
10+
return await res.json();
11+
} catch (e) {
12+
console.error(e.message);
13+
}
14+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import App from "./App.js";
2+
3+
const $app = document.querySelector("#app");
4+
5+
new App({ $target: $app });
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Caveat&family=Dancing+Script&display=swap");
2+
3+
* {
4+
margin: 0;
5+
padding: 0;
6+
}
7+
8+
:root {
9+
--background-gradient: radial-gradient(#2b8fb4, #67489f);
10+
--box-border-color: #06bdc1;
11+
--button-color: #17a2b8;
12+
--button-hover-color: #138496;
13+
--button-font-color: white;
14+
--button-border-color: #117a8b;
15+
--font-quote: "Caveat", cursive;
16+
--font-author: "Dancing Script", cursive;
17+
}
18+
19+
#app {
20+
display: flex;
21+
flex-direction: column;
22+
justify-content: center;
23+
align-items: center;
24+
height: 100vh;
25+
background: var(--background-gradient);
26+
}
27+
28+
#app .quoteContainer {
29+
display: flex;
30+
flex-direction: column;
31+
justify-content: center;
32+
align-items: center;
33+
width: 700px;
34+
min-height: 350px;
35+
padding: 50px;
36+
box-sizing: border-box;
37+
background-color: white;
38+
margin-bottom: 30px;
39+
border: 10px solid var(--box-border-color);
40+
border-radius: 10px;
41+
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.9);
42+
}
43+
44+
#app .quoteContainer .quoteArea {
45+
font-family: var(--font-quote);
46+
font-size: 1.8rem;
47+
text-align: center;
48+
margin-bottom: 30px;
49+
}
50+
51+
#app .quoteContainer .authorArea {
52+
font-family: var(--font-author);
53+
font-size: 2rem;
54+
}
55+
56+
button {
57+
padding: 10px 15px;
58+
background-color: var(--button-color);
59+
border-radius: 5px;
60+
cursor: pointer;
61+
outline: 0;
62+
color: var(--button-font-color);
63+
font-size: 1rem;
64+
border: 1px solid var(--button-border-color);
65+
transition: all 0.2s;
66+
}
67+
68+
button:hover {
69+
color: white;
70+
font-weight: 500;
71+
background-color: var(--button-hover-color);
72+
}
73+
74+
@media screen and (max-width: 1000px) {
75+
#app {
76+
padding: 0 100px;
77+
}
78+
79+
#app .quoteContainer {
80+
width: 100%;
81+
}
82+
}

0 commit comments

Comments
 (0)