├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.js
├── data.js
├── index.css
└── index.js
/.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 | # react-projects-7-slider
2 |
3 | #### IN ACTION
4 |
5 | [Gatsby-Airtable Project](https://gatsby-airtable-design-project.netlify.app/)
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reminder",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.5.0",
8 | "@testing-library/user-event": "^7.2.1",
9 | "react": "^16.13.1",
10 | "react-dom": "^16.13.1",
11 | "react-icons": "^3.11.0",
12 | "react-scripts": "3.4.3"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "CI= react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/john-smilga/react-projects-7-slider/abc8e9041b9e9fc701bd342a75789cfd185931bc/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Slider Complete
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/john-smilga/react-projects-7-slider/abc8e9041b9e9fc701bd342a75789cfd185931bc/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/john-smilga/react-projects-7-slider/abc8e9041b9e9fc701bd342a75789cfd185931bc/public/logo512.png
--------------------------------------------------------------------------------
/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { FiChevronRight, FiChevronLeft } from 'react-icons/fi';
3 | import { FaQuoteRight } from 'react-icons/fa';
4 | import data from './data';
5 | function App() {
6 | const [people, setPeople] = useState(data);
7 | const [index, setIndex] = React.useState(0);
8 |
9 | useEffect(() => {
10 | const lastIndex = people.length - 1;
11 | if (index < 0) {
12 | setIndex(lastIndex);
13 | }
14 | if (index > lastIndex) {
15 | setIndex(0);
16 | }
17 | }, [index, people]);
18 |
19 | useEffect(() => {
20 | let slider = setInterval(() => {
21 | setIndex(index + 1);
22 | }, 5000);
23 | return () => {
24 | clearInterval(slider);
25 | };
26 | }, [index]);
27 |
28 | return (
29 |
30 |
31 |
32 | /reviews
33 |
34 |
35 |
36 | {people.map((person, personIndex) => {
37 | const { id, image, name, title, quote } = person;
38 |
39 | let position = 'nextSlide';
40 | if (personIndex === index) {
41 | position = 'activeSlide';
42 | }
43 | if (
44 | personIndex === index - 1 ||
45 | (index === 0 && personIndex === people.length - 1)
46 | ) {
47 | position = 'lastSlide';
48 | }
49 |
50 | return (
51 |
52 |
53 | {name}
54 | {title}
55 | {quote}
56 |
57 |
58 | );
59 | })}
60 |
63 |
66 |
67 |
68 | );
69 | }
70 |
71 | export default App;
72 |
--------------------------------------------------------------------------------
/src/data.js:
--------------------------------------------------------------------------------
1 | const people = [
2 | {
3 | id: 1,
4 | image: 'https://www.course-api.com/images/people/person-1.jpeg',
5 | name: 'maria ferguson',
6 | title: 'office manager',
7 | quote:
8 | 'Fingerstache umami squid, kinfolk subway tile selvage tumblr man braid viral kombucha gentrify fanny pack raclette pok pok mustache.',
9 | },
10 | {
11 | id: 2,
12 | image: 'https://www.course-api.com/images/people/person-4.jpeg',
13 | name: 'john doe',
14 | title: 'regular guy',
15 | quote:
16 | 'Gastropub sustainable tousled prism occupy. Viral XOXO roof party brunch actually, chambray listicle microdosing put a bird on it paleo subway tile squid umami.',
17 | },
18 | {
19 | id: 3,
20 | image: 'https://www.course-api.com/images/people/person-3.jpeg',
21 | name: 'peter smith',
22 | title: 'product designer',
23 | quote:
24 | 'Drinking vinegar polaroid street art echo park, actually semiotics next level butcher master cleanse hammock flexitarian ethical paleo.',
25 | },
26 | {
27 | id: 4,
28 | image: 'https://www.course-api.com/images/people/person-2.jpeg',
29 | name: 'susan andersen',
30 | title: 'the boss',
31 | quote:
32 | 'Marfa af yr 3 wolf moon kogi, readymade distillery asymmetrical seitan kale chips fingerstache cloud bread mustache twee messenger bag. ',
33 | },
34 | ];
35 |
36 | export default people;
37 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | /*
2 | ===============
3 | Variables
4 | ===============
5 | */
6 |
7 | :root {
8 | /* dark shades of primary color*/
9 | --clr-primary-1: hsl(21, 91%, 17%);
10 | --clr-primary-2: hsl(21, 84%, 25%);
11 | --clr-primary-3: hsl(21, 81%, 29%);
12 | --clr-primary-4: hsl(21, 77%, 34%);
13 | --clr-primary-5: hsl(21, 62%, 45%);
14 | --clr-primary-6: hsl(21, 57%, 50%);
15 | --clr-primary-7: hsl(21, 65%, 59%);
16 | --clr-primary-8: hsl(21, 80%, 74%);
17 | --clr-primary-9: hsl(21, 94%, 87%);
18 | --clr-primary-10: hsl(21, 100%, 94%);
19 | /* darkest grey - used for headings */
20 | --clr-grey-1: hsl(209, 61%, 16%);
21 | --clr-grey-2: hsl(211, 39%, 23%);
22 | --clr-grey-3: hsl(209, 34%, 30%);
23 | --clr-grey-4: hsl(209, 28%, 39%);
24 | /* grey used for paragraphs */
25 | --clr-grey-5: hsl(210, 22%, 49%);
26 | --clr-grey-6: hsl(209, 23%, 60%);
27 | --clr-grey-7: hsl(211, 27%, 70%);
28 | --clr-grey-8: hsl(210, 31%, 80%);
29 | --clr-grey-9: hsl(212, 33%, 89%);
30 | --clr-grey-10: hsl(210, 36%, 96%);
31 | --clr-white: #fff;
32 | --clr-red-dark: hsl(360, 67%, 44%);
33 | --clr-red-light: hsl(360, 71%, 66%);
34 | --clr-green-dark: hsl(125, 67%, 44%);
35 | --clr-green-light: hsl(125, 71%, 66%);
36 | --clr-black: #222;
37 | --transition: all 0.3s linear;
38 | --spacing: 0.1rem;
39 | --radius: 0.25rem;
40 | --light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
41 | --dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
42 | --max-width: 1170px;
43 | --fixed-width: 620px;
44 | }
45 | /*
46 | ===============
47 | Global Styles
48 | ===============
49 | */
50 |
51 | *,
52 | ::after,
53 | ::before {
54 | margin: 0;
55 | padding: 0;
56 | box-sizing: border-box;
57 | }
58 | body {
59 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
60 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
61 | background: var(--clr-grey-10);
62 | color: var(--clr-grey-1);
63 | line-height: 1.5;
64 | font-size: 0.875rem;
65 | }
66 | ul {
67 | list-style-type: none;
68 | }
69 | a {
70 | text-decoration: none;
71 | }
72 | h1,
73 | h2,
74 | h3,
75 | h4 {
76 | letter-spacing: var(--spacing);
77 | text-transform: capitalize;
78 | line-height: 1.25;
79 | margin-bottom: 0.75rem;
80 | }
81 | h1 {
82 | font-size: 3rem;
83 | }
84 | h2 {
85 | font-size: 2rem;
86 | }
87 | h3 {
88 | font-size: 1.25rem;
89 | }
90 | h4 {
91 | font-size: 0.875rem;
92 | }
93 | p {
94 | margin-bottom: 1.25rem;
95 | color: var(--clr-grey-5);
96 | }
97 | @media screen and (min-width: 800px) {
98 | h1 {
99 | font-size: 4rem;
100 | }
101 | h2 {
102 | font-size: 2.5rem;
103 | }
104 | h3 {
105 | font-size: 1.75rem;
106 | }
107 | h4 {
108 | font-size: 1rem;
109 | }
110 | body {
111 | font-size: 1rem;
112 | }
113 | h1,
114 | h2,
115 | h3,
116 | h4 {
117 | line-height: 1;
118 | }
119 | }
120 | /* global classes */
121 |
122 | /* section */
123 | .section {
124 | width: 90vw;
125 | margin: 5rem auto;
126 | max-width: var(--max-width);
127 | }
128 |
129 | @media screen and (min-width: 992px) {
130 | .section {
131 | width: 95vw;
132 | }
133 | }
134 | /*
135 | ===============
136 | Slider
137 | ===============
138 | */
139 | .title {
140 | text-align: center;
141 | margin-bottom: 2rem;
142 | }
143 | .title h2 {
144 | display: flex;
145 | align-items: center;
146 | justify-content: center;
147 | font-weight: 500;
148 | }
149 | .title span {
150 | font-size: 0.85em;
151 | color: var(--clr-primary-5);
152 | margin-right: 1rem;
153 | font-weight: 700;
154 | }
155 | .section-center {
156 | margin: 0 auto;
157 | margin-top: 4rem;
158 | width: 80vw;
159 | height: 450px;
160 | max-width: 800px;
161 | text-align: center;
162 | position: relative;
163 | display: flex;
164 | overflow: hidden;
165 | }
166 | .person-img {
167 | border-radius: 50%;
168 | margin-bottom: 1rem;
169 | width: 150px;
170 | height: 150px;
171 | object-fit: cover;
172 | border: 4px solid var(--clr-grey-8);
173 | box-shadow: var(--dark-shadow);
174 | }
175 | article h4 {
176 | text-transform: uppercase;
177 | color: var(--clr-primary-5);
178 | margin-bottom: 0.25rem;
179 | }
180 | .title {
181 | text-transform: capitalize;
182 | margin-bottom: 0.75rem;
183 | color: var(--clr-grey-3);
184 | }
185 | .text {
186 | max-width: 35em;
187 | margin: 0 auto;
188 | margin-top: 2rem;
189 | line-height: 2;
190 | color: var(--clr-grey-5);
191 | }
192 | .icon {
193 | font-size: 3rem;
194 | margin-top: 1rem;
195 | color: var(--clr-primary-5);
196 | }
197 | .prev,
198 | .next {
199 | position: absolute;
200 | top: 200px;
201 | transform: translateY(-50%);
202 | background: var(--clr-grey-5);
203 | color: var(--clr-white);
204 | width: 1.25rem;
205 | height: 1.25rem;
206 | display: grid;
207 | place-items: center;
208 | border-color: transparent;
209 | font-size: 1rem;
210 | border-radius: var(--radius);
211 | cursor: pointer;
212 | transition: var(--transition);
213 | }
214 | .prev:hover,
215 | .next:hover {
216 | background: var(--clr-primary-5);
217 | }
218 | .prev {
219 | left: 0;
220 | }
221 | .next {
222 | right: 0;
223 | }
224 | @media (min-width: 800px) {
225 | .text {
226 | max-width: 45em;
227 | }
228 | .prev,
229 | .next {
230 | width: 2rem;
231 | height: 2rem;
232 | font-size: 1.5rem;
233 | }
234 | }
235 | article {
236 | position: absolute;
237 | top: 0;
238 | left: 0;
239 | width: 100%;
240 | height: 100%;
241 | opacity: 0;
242 | transition: var(--transition);
243 | }
244 | article.activeSlide {
245 | opacity: 1;
246 | transform: translateX(0);
247 | }
248 | article.lastSlide {
249 | transform: translateX(-100%);
250 | }
251 | article.nextSlide {
252 | transform: translateX(100%);
253 | }
254 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | );
12 |
--------------------------------------------------------------------------------