├── .env
├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── images
│ ├── misc
│ │ ├── dislike.png
│ │ ├── like.png
│ │ ├── logo.png
│ │ ├── messages.png
│ │ ├── rewind.png
│ │ ├── superlike.png
│ │ └── user.png
│ └── users
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ └── 7.jpg
├── index.html
└── manifest.json
├── src
├── App.css
├── App.js
├── components
│ ├── Actions.js
│ ├── Header.js
│ ├── LikedPerson.js
│ ├── Logo.js
│ ├── Lonely.js
│ ├── Person.js
│ └── actions
│ │ ├── Dislike.js
│ │ ├── Like.js
│ │ ├── Rewind.js
│ │ └── Superlike.js
├── data.json
├── index.css
└── index.js
├── tinder-preview.png
└── yarn.lock
/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Speed Coding Tinder in 60 Minutes | React
2 |
3 | Video: https://www.youtube.com/watch?v=wLGM04oi_wE
4 |
5 | Speed coding challenge for my YouTube channel. I used the standard create-react-app to build this. Feel free to contribute!
6 |
7 | Subscribe to my YouTube channel here: http://bit.ly/CognitiveSurge for more videos!
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tinder",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.8.6",
7 | "react-dom": "^16.8.6",
8 | "react-scripts": "3.0.1"
9 | },
10 | "scripts": {
11 | "start": "react-scripts start",
12 | "build": "react-scripts build",
13 | "test": "react-scripts test",
14 | "eject": "react-scripts eject"
15 | },
16 | "browserslist": {
17 | "production": [
18 | ">0.2%",
19 | "not dead",
20 | "not op_mini all"
21 | ],
22 | "development": [
23 | "last 1 chrome version",
24 | "last 1 firefox version",
25 | "last 1 safari version"
26 | ]
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/misc/dislike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/dislike.png
--------------------------------------------------------------------------------
/public/images/misc/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/like.png
--------------------------------------------------------------------------------
/public/images/misc/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/logo.png
--------------------------------------------------------------------------------
/public/images/misc/messages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/messages.png
--------------------------------------------------------------------------------
/public/images/misc/rewind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/rewind.png
--------------------------------------------------------------------------------
/public/images/misc/superlike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/superlike.png
--------------------------------------------------------------------------------
/public/images/misc/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/misc/user.png
--------------------------------------------------------------------------------
/public/images/users/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/1.jpg
--------------------------------------------------------------------------------
/public/images/users/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/2.jpg
--------------------------------------------------------------------------------
/public/images/users/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/3.jpg
--------------------------------------------------------------------------------
/public/images/users/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/4.jpg
--------------------------------------------------------------------------------
/public/images/users/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/5.jpg
--------------------------------------------------------------------------------
/public/images/users/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/6.jpg
--------------------------------------------------------------------------------
/public/images/users/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/public/images/users/7.jpg
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Tinder
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Roboto:400,700,900');
2 |
3 | body {
4 | margin: 0;
5 | padding: 0;
6 | font-family: 'Roboto', sans-serif;
7 | font-size: 20px;
8 | line-height: 1;
9 | background-color: #f7f7f7;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
14 | ol, ul {
15 | list-style: none;
16 | }
17 |
18 | .app {
19 | text-align: center;
20 | max-width: 500px;
21 | margin: auto;
22 | }
23 |
24 | header {
25 | background-color: white;
26 | overflow: hidden;
27 | display: flex;
28 | }
29 |
30 | header {
31 | background-color: white;
32 | overflow: hidden;
33 | display: flex;
34 | align-items: center;
35 | justify-content: center;
36 | padding: 10px 5px;
37 | box-shadow: 0 2px 3px 0 rgba(0,0,0,0.1);
38 | }
39 |
40 | header button {
41 | background-color: transparent;
42 | border: 0;
43 | width: 50px;
44 | cursor: pointer;
45 | }
46 |
47 | header button img {
48 | width: 100%;
49 | }
50 |
51 | header .fl {
52 | float: left;
53 | width: 33%;
54 | }
55 |
56 | header .fl:first-child {
57 | text-align: left;
58 | }
59 |
60 | header .fl:last-child {
61 | text-align: right;
62 | }
63 |
64 | .person .person-photo {
65 | overflow: hidden;
66 | box-shadow: 0 2px 3px 0 rgba(0,0,0,0.3);
67 | }
68 |
69 | .person .person-description {
70 | text-align: left;
71 | padding: 20px;
72 | box-shadow: 0 2px 3px 0 rgba(0,0,0,0.1);
73 | border-radius: 1px;
74 | background-color: white;
75 | }
76 |
77 | .person .person-name-age {
78 | font-weight: bold;
79 | font-size: 30px;
80 | margin-bottom: 10px;
81 | margin-top: 0;
82 | }
83 |
84 | .person .person-info {
85 | margin-top: 0;
86 | margin-bottom: 0;
87 | font-size: 20px;
88 | }
89 |
90 | .person img {
91 | width: 500px;
92 | height: 700px;
93 | display: block;
94 | object-fit: cover;
95 | }
96 |
97 | #actions {
98 | padding-top: 10px;
99 | padding-bottom: 10px;
100 | display: flex;
101 | align-items: center;
102 | justify-content: center;
103 | margin-top: 10px;
104 | }
105 |
106 | #actions button {
107 | width: 50px;
108 | height: 50px;
109 | margin-right: 30px;
110 | padding: 12px;
111 | border: 0;
112 | border-radius: 50px;
113 | background-color: white;
114 | display: flex;
115 | align-items: center;
116 | justify-content: center;
117 | float: left;
118 | cursor: pointer;
119 | box-shadow: 0 2px 3px 0 rgba(0,0,0,0.1);
120 | }
121 |
122 | #actions button img {
123 | width: 100%;
124 | height: auto;
125 | }
126 |
127 | #actions button:nth-of-type(2),
128 | #actions button:nth-of-type(3) {
129 | width: 60px;
130 | height: 60px;
131 | padding: 15px;
132 | }
133 |
134 | #lonely {
135 | padding: 10px;
136 | border-radius: 1px;
137 | background-color: white;
138 | border-top: 1px solid #eee;
139 | }
140 |
141 | #liked-people {
142 | margin: auto;
143 | overflow: hidden;
144 | }
145 |
146 | #liked-people .liked-person {
147 | display: inline-block;
148 | width: 33%;
149 | margin-top: 10px;
150 | }
151 |
152 | #liked-people .liked-person-image {
153 | border-radius: 5px;
154 | }
155 |
156 | #liked-people .liked-person-image img {
157 | width: 140px;
158 | height: 100px;
159 | object-fit: cover;
160 | object-position: 50% 50%;
161 | }
162 |
163 | /* Stolen CSS */
164 | .pulse {
165 | margin: auto;
166 | width: 200px;
167 | height: 200px;
168 | border-radius: 50%;
169 | background: #FFDEDF;
170 | box-shadow: 0 0 0 rgba(204,169,44, 0.4);
171 | -webkit-animation: pulse 2s infinite;
172 | animation: pulse 2s infinite;
173 | margin-top: 50px;
174 | margin-bottom: 35px;
175 | border: 3px solid #F5C9CA;
176 | padding: 30px;
177 | display: flex;
178 | align-items: center;
179 | justify-content: center;
180 | }
181 |
182 | .pulse img {
183 | width: 70%;
184 | border-radius: 100px;
185 | border: 5px solid white;
186 | }
187 |
188 | .pulse:hover {
189 | animation: none;
190 | }
191 |
192 | @-webkit-keyframes pulse {
193 | 0% {
194 | -webkit-box-shadow: 0 0 0 0 rgba(241, 201, 202, 0.4);
195 | }
196 | 100% {
197 | -webkit-box-shadow: 0 0 0 35px rgba(241, 201, 202, 0);
198 | }
199 | }
200 |
201 | @keyframes pulse {
202 | 0% {
203 | -moz-box-shadow: 0 0 0 0 rgba(241, 201, 202, 0.4);
204 | box-shadow: 0 0 0 0 rgba(241, 201, 202, 0.4);
205 | }
206 | 100% {
207 | -moz-box-shadow: 0 0 35px 35px rgba(241, 201, 202, 0);
208 | box-shadow: 0 0 35px 35px rgba(241, 201, 202, 0);
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import './App.css';
3 | import Header from './components/Header';
4 | import Person from './components/Person';
5 | import Lonely from './components/Lonely';
6 | import data from './data.json';
7 |
8 | const App = () => {
9 | const [people, setPeople] = useState(data);
10 | const [likedUsers, setLikedUsers] = useState([]);
11 | const [superLikedUsers, setSuperLikedUsers] = useState([]);
12 | const [dislikedUsers, setDislikedUsers] = useState([]);
13 | const activeUser = 0;
14 |
15 | const removedPersonFromDataSrc = (peopleSource, userId) =>
16 | peopleSource.filter(user => user.id !== userId);
17 |
18 | const modifySuperficialChoices = (userId, action) => {
19 | const newPeople = [...people];
20 | const newLikedUsers = [...likedUsers];
21 | const newSuperLikedUsers = [...superLikedUsers];
22 | const newDislikedUsers = [...dislikedUsers];
23 |
24 | switch (action) {
25 | case 'ADD_TO_LIKED_USERS':
26 | if (!people[activeUser].likedUsers.includes(userId)) {
27 | newPeople[activeUser].likedUsers.push(userId);
28 | newLikedUsers.push(data[userId]);
29 |
30 | setLikedUsers(newLikedUsers);
31 | setPeople(removedPersonFromDataSrc(people, userId));
32 | }
33 | break;
34 | case 'ADD_TO_DISLIKED_USERS':
35 | if (!people[activeUser].dislikedUsers.includes(userId)) {
36 | newPeople[activeUser].dislikedUsers.push(userId);
37 | newDislikedUsers.push(data[userId]);
38 |
39 | setDislikedUsers(newLikedUsers);
40 | setPeople(removedPersonFromDataSrc(people, userId));
41 | }
42 | break;
43 | case 'ADD_TO_SUPERLIKED_USERS':
44 | if (!people[activeUser].superLikedUsers.includes(userId)) {
45 | newPeople[activeUser].superLikedUsers.push(userId);
46 | newSuperLikedUsers.push(data[userId]);
47 |
48 | setSuperLikedUsers(newSuperLikedUsers);
49 | setPeople(removedPersonFromDataSrc(people, userId));
50 | }
51 | break;
52 | default:
53 | return people;
54 | }
55 | };
56 |
57 | return (
58 |
59 |
60 | {people[1] ? (
61 |
67 | ) : (
68 |
73 | )}
74 |
75 | );
76 | };
77 |
78 | export default App;
79 |
--------------------------------------------------------------------------------
/src/components/Actions.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Rewind from './actions/Rewind';
3 | import Dislike from './actions/Dislike';
4 | import Like from './actions/Like';
5 | import Superlike from './actions/Superlike';
6 |
7 | const Actions = ({ person, modifySuperficialChoices }) => (
8 |
9 |
10 |
14 |
18 |
22 |
23 | );
24 |
25 | export default Actions;
26 |
--------------------------------------------------------------------------------
/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Logo from './Logo';
3 |
4 | const Header = () => (
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 | );
23 |
24 | export default Header;
25 |
--------------------------------------------------------------------------------
/src/components/LikedPerson.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const LikedPerson = ({ person }) => (
4 |
5 |
6 |

10 |
11 |
12 | );
13 |
14 | export default LikedPerson;
15 |
--------------------------------------------------------------------------------
/src/components/Logo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Logo = () => (
4 |
5 |

6 |
7 | );
8 |
9 | export default Logo;
10 |
--------------------------------------------------------------------------------
/src/components/Lonely.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import LikedPerson from './LikedPerson';
3 |
4 | const Lonely = ({ activeUserImage, likedUsers, superLikedUsers }) => (
5 |
6 |
There's no new around you.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | {likedUsers.length > 0
15 | ? "People you liked...let's hope they like you too!"
16 | : ''}
17 |
18 |
19 | {likedUsers.map(item => (
20 |
21 | ))}
22 |
23 |
{superLikedUsers.length > 0 ? 'People you super liked!' : ''}
24 |
25 | {superLikedUsers.map(item => (
26 |
27 | ))}
28 |
29 |
30 | );
31 |
32 | export default Lonely;
33 |
--------------------------------------------------------------------------------
/src/components/Person.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Actions from './Actions';
3 |
4 | const Person = ({ person, modifySuperficialChoices }) => {
5 | const { name, desc, age, image } = person;
6 |
7 | return (
8 | <>
9 |
10 |
11 |

12 |
13 |
14 |
15 |
16 | {name}, {age}
17 |
18 |
{desc}
19 |
20 |
21 |
22 |
26 | >
27 | );
28 | };
29 |
30 | export default Person;
31 |
--------------------------------------------------------------------------------
/src/components/actions/Dislike.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Dislike = ({ userId, modifySuperficialChoices }) => (
4 |
10 | );
11 |
12 | export default Dislike;
13 |
--------------------------------------------------------------------------------
/src/components/actions/Like.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Like = ({ userId, modifySuperficialChoices }) => (
4 |
10 | );
11 |
12 | export default Like;
13 |
--------------------------------------------------------------------------------
/src/components/actions/Rewind.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Rewind = () => (
4 |
7 | );
8 |
9 | export default Rewind;
10 |
--------------------------------------------------------------------------------
/src/components/actions/Superlike.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const SuperLike = ({ userId, modifySuperficialChoices }) => (
4 |
10 | );
11 |
12 | export default SuperLike;
13 |
--------------------------------------------------------------------------------
/src/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 0,
4 | "name": "Karl",
5 | "desc": "Developer",
6 | "age": 26,
7 | "image": "1.jpg",
8 | "likedUsers": [],
9 | "superLikedUsers": [],
10 | "dislikedUsers": [],
11 | "likedBy": []
12 | },
13 | {
14 | "id": 1,
15 | "name": "Martin",
16 | "desc": "Prisoner at Federal Correctional Institution",
17 | "age": 35,
18 | "image": "2.jpg",
19 | "likedUsers": [],
20 | "superLikedUsers": [],
21 | "dislikedUsers": [],
22 | "likedBy": []
23 | },
24 | {
25 | "id": 2,
26 | "name": "Emily",
27 | "desc": "Actress",
28 | "age": 35,
29 | "image": "3.jpg",
30 | "likedUsers": [],
31 | "superLikedUsers": [],
32 | "dislikedUsers": [],
33 | "likedBy": []
34 | },
35 | {
36 | "id": 3,
37 | "name": "Michael",
38 | "desc": "Manager",
39 | "age": 45,
40 | "image": "4.jpg",
41 | "likedUsers": [],
42 | "superLikedUsers": [],
43 | "dislikedUsers": [],
44 | "likedBy": []
45 | },
46 | {
47 | "id": 4,
48 | "name": "Dwight",
49 | "desc": "Sales",
50 | "age": 40,
51 | "image": "5.jpg",
52 | "likedUsers": [],
53 | "superLikedUsers": [],
54 | "dislikedUsers": [],
55 | "likedBy": []
56 | },
57 | {
58 | "id": 5,
59 | "name": "Jessica",
60 | "desc": "Actress",
61 | "age": 37,
62 | "image": "6.jpg",
63 | "likedUsers": [],
64 | "superLikedUsers": [],
65 | "dislikedUsers": [],
66 | "likedBy": []
67 | },
68 | {
69 | "id": 6,
70 | "name": "Alexandra",
71 | "desc": "Actress",
72 | "age": 32,
73 | "image": "7.jpg",
74 | "likedUsers": [],
75 | "superLikedUsers": [],
76 | "dislikedUsers": [],
77 | "likedBy": []
78 | }
79 | ]
80 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import App from './App';
4 |
5 | render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/tinder-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karlhadwen/tinder/d92c619f3df1b6cb2582f2aa8488406a7b341994/tinder-preview.png
--------------------------------------------------------------------------------