├── public ├── _redirects ├── favicon.ico ├── robots.txt └── index.html ├── src ├── components │ └── App.js ├── utils │ ├── helpers.js │ ├── api.js │ └── _DATA.js ├── index.js └── index.css ├── .gitignore ├── package.json └── README.md /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uidotdev/redux-course-2/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/components/App.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default function App() { 4 | return ( 5 |
6 |
7 |
31 |
32 | ### Project Preview
33 |
34 | 
35 |
36 | 
37 |
38 | 
39 |
40 | 
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @import url("https://use.typekit.net/wrw1rqc.css");
2 |
3 | :root {
4 | --black: #000;
5 | --white: #fff;
6 | --red: #f32827;
7 | --purple: #a42ce9;
8 | --blue: #2d7fea;
9 | --yellow: #f4f73e;
10 | --pink: #eb30c1;
11 | --gold: #ffd500;
12 | --aqua: #2febd2;
13 | --gray: #282c35;
14 | }
15 |
16 | *,
17 | *:before,
18 | *:after {
19 | box-sizing: inherit;
20 | }
21 |
22 | html {
23 | font-family: proxima-nova, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
24 | text-rendering: optimizeLegibility;
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | box-sizing: border-box;
28 | font-size: 18px;
29 | }
30 |
31 | body {
32 | margin: 0;
33 | padding: 0;
34 | min-height: 100vh;
35 | background: var(--black);
36 | color: var(--white);
37 | }
38 |
39 | a {
40 | color: var(--gold);
41 | text-decoration: none;
42 | }
43 |
44 | li {
45 | list-style-type: none;
46 | }
47 |
48 | .border-container {
49 | padding: 0;
50 | margin: 0;
51 | display: flex;
52 | }
53 |
54 | .border-item {
55 | width: 20vw;
56 | height: 12px;
57 | }
58 |
59 | .container {
60 | position: relative;
61 | max-width: 1000px;
62 | min-width: 280px;
63 | margin: 0 auto;
64 | padding: 20px;
65 | }
66 |
67 | .loading {
68 | margin: 0 auto;
69 | }
70 |
71 | .option {
72 | border: 1px solid var(--white);
73 | margin: 10px;
74 | border-radius: 2px;
75 | }
76 |
77 | .option:hover {
78 | border: 2px solid var(--pink);
79 | cursor: pointer;
80 | }
81 |
82 | .chosen {
83 | border: 2px solid var(--aqua);
84 | }
85 |
86 | .result {
87 | display: flex;
88 | justify-content: space-between;
89 | }
90 |
91 | .poll-author {
92 | display: flex;
93 | justify-content: center;
94 | align-items: center;
95 | font-weight: bold;
96 | text-transform: uppercase;
97 | }
98 |
99 | .poll-author img {
100 | width: 40px;
101 | height: 40px;
102 | border-radius: 20px;
103 | margin: 0 10px;
104 | }
105 |
106 | .btn {
107 | text-transform: uppercase;
108 | margin: 35px auto;
109 | padding: 10px;
110 | border: 1px solid rgba(0,0,0,.29);
111 | cursor: pointer;
112 | background: #fff;
113 | font-size: 16px;
114 | width: 250px;
115 | position: relative;
116 | }
117 |
118 | .btn:hover {
119 | border-color: rgba(0,0,0,.5);
120 | text-decoration: none;
121 | }
122 |
123 | .btn:focus {
124 | outline: 0;
125 | font-weight: 700;
126 | border-width: 2px;
127 | }
128 |
129 | .center {
130 | text-align: center;
131 | }
132 |
133 | .active {
134 | font-weight: 900;
135 | }
136 |
137 | .nav {
138 | margin: 30px 0;
139 | }
140 |
141 | .nav a {
142 | margin: 5px 10px;
143 | }
144 |
145 | .nav:first-child {
146 | padding-left: 0;
147 | }
148 |
149 | ul {
150 | padding-left: 0;
151 | }
152 |
153 | li {
154 | list-style-type: none;
155 | padding: 10px;
156 | text-decoration: none;
157 | }
158 |
159 | .dashboard-toggle {
160 | display: flex;
161 | justify-content: center;
162 | align-items: center;
163 | font-size: 22px;
164 | margin-bottom: 30px;
165 | }
166 |
167 | .dashboard-toggle button {
168 | border: none;
169 | background: transparent;
170 | font-size: 22px;
171 | color: var(--gold);
172 | }
173 |
174 | .dashboard-list {
175 | font-size: 22px;
176 | letter-spacing: .4px;
177 | font-weight: 700;
178 | }
179 |
180 | .dashboard-list li {
181 | margin: 10px 0;
182 | }
183 |
184 | .dashboard-list a {
185 | color: var(--white);
186 | }
187 |
188 | .dashboard-list a:hover {
189 | font-weight: 900;
190 | }
191 |
192 | .add-poll-container {
193 | display: flex;
194 | flex-direction: column;
195 | align-items: center;
196 | }
197 |
198 | .poll-container {
199 | width: 60%;
200 | margin: 0px auto;
201 | display: flex;
202 | flex-direction: column;
203 | }
204 |
205 | .question {
206 | font-size: 30px;
207 | text-align: center;
208 | }
209 |
210 | .avatar {
211 | width: 40px;
212 | height: 40px;
213 | border-radius: 20px;
214 | margin-top: 10px;
215 | }
216 |
217 | .user {
218 | display: flex;
219 | }
220 |
221 | .user h1 {
222 | margin: 0;
223 | font-size: 30px;
224 | }
225 |
226 | .user img {
227 | width: 40px;
228 | height: 40px;
229 | border-radius: 20px;
230 | margin-right: 20px;
231 | }
232 |
233 | .user p {
234 | margin-top: 6px;
235 | margin-bottom: 6px;
236 | }
237 |
238 | @media (max-width: 500px) {
239 | .poll-container {
240 | width: 95%;
241 | flex-direction: column;
242 | }
243 | }
244 |
245 | .add-form {
246 | margin: 0 auto;
247 | width: 600px;
248 | }
249 |
250 | input {
251 | display: block;
252 | box-sizing: border-box;
253 | width: 100%;
254 | outline: none;
255 | border: none;
256 | border-radius: 0;
257 | appearance: none;
258 | margin-bottom: 20px;
259 | }
260 |
261 | .btn {
262 | max-width: 240px;
263 | min-width: 150px;
264 | padding: 10px;
265 | border: 2px solid black;
266 | color: var(--white);
267 | text-align: center;
268 | background: var(--pink);
269 | font-weight: 900;
270 | font-size: 15px;
271 | }
272 |
273 | .btn:hover {
274 | cursor: pointer;
275 | }
276 |
277 | .label {
278 | display: block;
279 | margin-bottom: 0.25em;
280 | font-size: 20px;
281 | }
282 |
283 | .input {
284 | padding: 5px;
285 | border-width: 1px;
286 | border-style: solid;
287 | border-color: lightgray;
288 | background-color: white;
289 | font-size: 18px;
290 | }
291 | .input:focus {
292 | border-color: gray;
293 | }
294 |
--------------------------------------------------------------------------------
/src/utils/_DATA.js:
--------------------------------------------------------------------------------
1 | let users = {
2 | sarah_edo: {
3 | id: 'sarah_edo',
4 | name: 'Sarah Drasner',
5 | avatarURL: 'https://tylermcginnis.com/would-you-rather/sarah.jpg',
6 | answers: {
7 | "8xf0y6ziyjabvozdd253nd": 'a',
8 | "6ni6ok3ym7mf1p33lnez": 'a',
9 | "am8ehyc8byjqgar0jgpub9": 'b',
10 | "loxhs1bqm25b708cmbf3g": 'd'
11 | },
12 | polls: ['8xf0y6ziyjabvozdd253nd', 'am8ehyc8byjqgar0jgpub9']
13 | },
14 | tylermcginnis: {
15 | id: 'tylermcginnis',
16 | name: 'Tyler McGinnis',
17 | avatarURL: 'https://tylermcginnis.com/would-you-rather/tyler.jpg',
18 | answers: {
19 | "vthrdm985a262al8qx3do": 'a',
20 | "xj352vofupe1dqz9emx13r": 'a',
21 | },
22 | polls: ['loxhs1bqm25b708cmbf3g', 'vthrdm985a262al8qx3do'],
23 | },
24 | dan_abramov: {
25 | id: 'dan_abramov',
26 | name: 'Dan Abramov',
27 | avatarURL: 'https://tylermcginnis.com/would-you-rather/dan.jpg',
28 | answers: {
29 | "xj352vofupe1dqz9emx13r": 'a',
30 | "vthrdm985a262al8qx3do": 'd',
31 | "6ni6ok3ym7mf1p33lnez": 'd'
32 | },
33 | polls: ['6ni6ok3ym7mf1p33lnez', 'xj352vofupe1dqz9emx13r'],
34 | }
35 | }
36 |
37 | let polls = {
38 | "8xf0y6ziyjabvozdd253nd": {
39 | id: '8xf0y6ziyjabvozdd253nd',
40 | question: "Who is the best basketball player to ever live?",
41 | author: 'sarah_edo',
42 | timestamp: 1467166872634,
43 | a: {
44 | text: 'Michael Jordan',
45 | votes: ['sarah_edo'],
46 | },
47 | b: {
48 | text: 'Jimmer Fredette',
49 | votes: [],
50 | },
51 | c: {
52 | text: 'Lebron James',
53 | votes: [],
54 | },
55 | d: {
56 | text: 'Kobe Bryant',
57 | votes: [],
58 | }
59 | },
60 | "6ni6ok3ym7mf1p33lnez": {
61 | id: '6ni6ok3ym7mf1p33lnez',
62 | question: "How will we build UIs in 2019?",
63 | author: 'dan_abramov',
64 | timestamp: 1468479767190,
65 | a: {
66 | text: 'React.js',
67 | votes: ['sarah_edo'],
68 | },
69 | b: {
70 | text: 'ReasonML',
71 | votes: [],
72 | },
73 | c: {
74 | text: 'Vue.js',
75 | votes: [],
76 | },
77 | d: {
78 | text: 'Angular.js',
79 | votes: ['dan_abramov'],
80 | }
81 | },
82 | "am8ehyc8byjqgar0jgpub9": {
83 | id: 'am8ehyc8byjqgar0jgpub9',
84 | question: "What is your favorite book?",
85 | author: 'sarah_edo',
86 | timestamp: 1488579767190,
87 | a: {
88 | text: 'Harry Potter',
89 | votes: [],
90 | },
91 | b: {
92 | text: 'Lord of the Rings',
93 | votes: ['sarah_edo'],
94 | },
95 | c: {
96 | text: 'To Kill a Mockingbird',
97 | votes: [],
98 | },
99 | d: {
100 | text: 'Other',
101 | votes: [],
102 | }
103 | },
104 | "loxhs1bqm25b708cmbf3g": {
105 | id: 'loxhs1bqm25b708cmbf3g',
106 | question: "Which artist do you prefer?",
107 | author: 'tylermcginnis',
108 | timestamp: 1482579767190,
109 | a: {
110 | text: 'Chance the Rapper',
111 | votes: [],
112 | },
113 | b: {
114 | text: 'Anderson .Paak',
115 | votes: [],
116 | },
117 | c: {
118 | text: 'Childish Gambino',
119 | votes: [],
120 | },
121 | d: {
122 | text: 'Kanye West',
123 | votes: ['sarah_edo'],
124 | }
125 | },
126 | "vthrdm985a262al8qx3do": {
127 | id: 'vthrdm985a262al8qx3do',
128 | question: "Where is the best place to live?",
129 | author: 'tylermcginnis',
130 | timestamp: 1489579767190,
131 | a: {
132 | text: 'Eden, Utah',
133 | votes: ['tylermcginnis'],
134 | },
135 | b: {
136 | text: 'Kauai, HI',
137 | votes: [],
138 | },
139 | c: {
140 | text: 'San Francisco, CA',
141 | votes: [],
142 | },
143 | d: {
144 | text: 'Other',
145 | votes: ['dan_abramov'],
146 | }
147 | },
148 | "xj352vofupe1dqz9emx13r": {
149 | id: 'xj352vofupe1dqz9emx13r',
150 | question: "Who will win the election in 2020?",
151 | author: 'dan_abramov',
152 | timestamp: 1493579767190,
153 | a: {
154 | text: 'Kanye West',
155 | votes: ['dan_abramov'],
156 | },
157 | b: {
158 | text: 'Donald Trump',
159 | votes: [],
160 | },
161 | c: {
162 | text: 'Oprah Winfrey',
163 | votes: ['tylermcginnis'],
164 | },
165 | d: {
166 | text: 'Dwayne Johnson',
167 | votes: [],
168 | }
169 | },
170 | }
171 |
172 | function generateUID () {
173 | return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
174 | }
175 |
176 | export function _getUsers () {
177 | return new Promise((res, rej) => {
178 | setTimeout(() => res({...users}), 1000)
179 | })
180 | }
181 |
182 | export function _getPolls () {
183 | return new Promise((res, rej) => {
184 | setTimeout(() => res({...polls}), 1000)
185 | })
186 | }
187 |
188 | function formatPoll (poll) {
189 | return {
190 | ...poll,
191 | id: generateUID(),
192 | timestamp: Date.now(),
193 | a: {
194 | text: poll.a,
195 | votes: [],
196 | },
197 | b: {
198 | text: poll.b,
199 | votes: [],
200 | },
201 | c: {
202 | text: poll.c,
203 | votes: [],
204 | },
205 | d: {
206 | text: poll.d,
207 | votes: [],
208 | },
209 | }
210 | }
211 |
212 | export function _savePoll (poll) {
213 | return new Promise((res, rej) => {
214 | const formattedPoll = formatPoll(poll)
215 |
216 | setTimeout(() => {
217 | polls = {
218 | ...polls,
219 | [formattedPoll.id]: formattedPoll,
220 | }
221 |
222 | res(formattedPoll)
223 | }, 1000)
224 | })
225 | }
226 |
227 | export function _savePollAnswer ({ authedUser, id, answer }) {
228 | return new Promise((res, rej) => {
229 | setTimeout(() => {
230 | const user = users[authedUser]
231 | const poll = polls[id]
232 |
233 | users = {
234 | ...users,
235 | [authedUser]: {
236 | ...user,
237 | answers: {
238 | ...user.answers,
239 | [id]: answer
240 | }
241 | }
242 | }
243 |
244 | polls = {
245 | ...polls,
246 | [id]: {
247 | ...poll,
248 | [answer]: {
249 | ...poll[answer],
250 | votes: poll[answer].votes.concat([authedUser])
251 | }
252 | }
253 | }
254 |
255 | res()
256 | }, 500)
257 | })
258 | }
--------------------------------------------------------------------------------