├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── akun.png
├── component
├── 404not.js
├── a.js
├── anime.js
├── backdrop-card.js
├── backdrop-page.js
├── banner.js
├── cast-card.js
├── cast-rekomend-card.js
├── cast-rekomend-tv.js
├── footer.js
├── full.jpg
├── genre-content.js
├── genre-page.js
├── header.js
├── home.js
├── img
│ ├── PngItem_6391407.png
│ └── header.js
├── left-sidebar.js
├── media-backgdrop.js
├── media-poster.js
├── media-video.js
├── modal-item.js
├── modal-video.js
├── movie-all.js
├── movie-detail-card.js
├── moviecard.js
├── moviecontainer.js
├── moviedetail.js
├── people-card.js
├── people-detail.js
├── people-movie-credit.js
├── popular-people.js
├── poster-card.js
├── poster-page.js
├── profile-card.js
├── rekomen-card.js
├── review-card.js
├── review-page.js
├── review.js
├── search-content.js
├── search-page.js
├── slider.js
├── trending-card.js
├── tv-all.js
├── tv-detail-card.js
├── tv-detail.js
├── tv-recomend-card.js
└── video-card.js
├── detail.css
├── empty.png
├── github.png
├── header.css
├── index.css
├── index.js
├── logo.svg
├── logos.png
├── next.png
├── prev.png
├── reportWebVitals.js
├── setupTests.js
├── star.png
└── tmdb-logo.svg
/.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 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "homepage": "https://bay-s.github.io",
3 | "name": "movie-info-app",
4 | "version": "0.1.0",
5 | "private": true,
6 | "dependencies": {
7 | "@testing-library/jest-dom": "^5.16.4",
8 | "@testing-library/react": "^13.2.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "react": "^18.1.0",
11 | "react-dom": "^18.1.0",
12 | "react-router-dom": "^6.3.0",
13 | "react-scripts": "5.0.1",
14 | "web-vitals": "^2.1.4"
15 | },
16 | "scripts": {
17 | "predeploy": "npm run build",
18 | "deploy": "gh-pages -b master -d build",
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": [
26 | "react-app",
27 | "react-app/jest"
28 | ]
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | },
42 | "devDependencies": {
43 | "gh-pages": "^4.0.0"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/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.css:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | div,
4 | span,
5 | applet,
6 | object,
7 | iframe,
8 | h1,
9 | h2,
10 | h3,
11 | h4,
12 | h5,
13 | h6,
14 | p,
15 | blockquote,
16 | pre,
17 | a,
18 | abbr,
19 | acronym,
20 | address,
21 | big,
22 | cite,
23 | code,
24 | del,
25 | dfn,
26 | em,
27 | img,
28 | ins,
29 | kbd,
30 | q,
31 | s,
32 | samp,
33 | small,
34 | strike,
35 | strong,
36 | sub,
37 | sup,
38 | tt,
39 | var,
40 | b,
41 | u,
42 | i,
43 | center,
44 | dl,
45 | dt,
46 | dd,
47 | ol,
48 | ul,
49 | li,
50 | fieldset,
51 | form,
52 | label,
53 | legend,
54 | table,
55 | caption,
56 | tbody,
57 | tfoot,
58 | thead,
59 | tr,
60 | th,
61 | td,
62 | article,
63 | aside,
64 | canvas,
65 | details,
66 | embed,
67 | figure,
68 | figcaption,
69 | footer,
70 | header,
71 | hgroup,
72 | menu,
73 | nav,
74 | output,
75 | ruby,
76 | section,
77 | summary,
78 | time,
79 | mark,
80 | audio,
81 | video {
82 | margin: 0;
83 | padding: 0;
84 | border: 0;
85 | font-size: 100%;
86 | font: inherit;
87 | vertical-align: baseline;
88 | }
89 |
90 | a{
91 | text-decoration: none;
92 | }
93 | /* HTML5 display-role reset for older browsers */
94 | article,
95 | aside,
96 | details,
97 | figcaption,
98 | figure,
99 | footer,
100 | header,
101 | hgroup,
102 | menu,
103 | nav,
104 | section {
105 | display: block;
106 | }
107 |
108 | body {
109 | line-height: 1;
110 | }
111 |
112 | ol,
113 | ul {
114 | list-style: none;
115 | }
116 |
117 | blockquote,
118 | q {
119 | quotes: none;
120 | }
121 |
122 | blockquote:before,
123 | blockquote:after,
124 | q:before,
125 | q:after {
126 | content: '';
127 | content: none;
128 | }
129 |
130 | table {
131 | border-collapse: collapse;
132 | border-spacing: 0;
133 | }
134 |
135 | button {
136 | cursor: pointer;
137 | }
138 |
139 | :root {
140 | --green: #20B2AA;
141 | --tmdbDarkBlue: 3, 37, 65;
142 | }
143 |
144 | .App {
145 | display: flex;
146 | flex-direction: row;
147 | min-height: 100%;
148 | gap: 20px;
149 | margin: 70px 100px;
150 | }
151 |
152 |
153 | .not-found {
154 | display: flex;
155 | flex-direction: column;
156 | gap: 10px;
157 | margin: 250px auto;
158 | text-align: center;
159 | font-weight: bold;
160 | font-style: italic;
161 | color: black;
162 | }
163 |
164 | .not-found h1 {
165 | font-size: 50px;
166 |
167 | }
168 |
169 | body {
170 | background-color: rgba(0, 0, 0, 0.055);
171 | font-family: 'Outfit', sans-serif;
172 | /* background-color: #16151D; */
173 | }
174 |
175 |
176 | /* BANNER */
177 |
178 | /* .banner{
179 | object-fit: cover;
180 | max-width: 100%;
181 | height: 400px;
182 | margin: 57px 0;
183 | opacity: 0.75;
184 | display: -webkit-box;
185 | display: -ms-flexbox;
186 | display: flex;
187 | -webkit-box-orient: vertical;
188 | -webkit-box-direction: normal;
189 | -ms-flex-direction: column;
190 | flex-direction: column;
191 | gap: 50px;
192 | -webkit-box-align: center;
193 | -ms-flex-align: center;
194 | align-items: center;
195 | background-position: center -100px;
196 | background-repeat: no-repeat;
197 | background-size: cover;
198 | }
199 |
200 | */
201 |
202 | .banner {
203 | display: flex;
204 | height: 400px;
205 | }
206 |
207 | .dot-container{
208 | position: absolute;
209 | bottom: 55px;
210 | left: 25%;
211 | display: flex;
212 | gap: 10px;
213 | z-index: 10;
214 | }
215 |
216 | .dot-container .dot{
217 | padding: 5px;
218 | background-color:rgba(255, 255, 255, 0.363);
219 | color: red;
220 | border-radius: 50%;
221 | cursor: pointer;
222 | }
223 |
224 | .dot-active{
225 | background-color:yellow;
226 | padding: 5px;
227 | border-radius: 50%;
228 | cursor: pointer;
229 | }
230 |
231 | .banner .slides {
232 | /* width: 820px; */
233 | width: 835px;
234 | transition: 500ms;
235 | /* margin:57px auto; */
236 | -webkit-box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
237 | box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
238 | background-size: cover;
239 | background-position: center, center;
240 | color: white;
241 | opacity: 2;
242 | -webkit-box-sizing: border-box;
243 | box-sizing: border-box;
244 | font-family: Arial, Helvetica, sans-serif;
245 | filter: brightness(1.1);
246 | }
247 |
248 | .shows{
249 | animation: fade 500ms;
250 | display: block;
251 | width: 820px;
252 | transition: 500ms;
253 | -webkit-box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
254 | box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
255 | background-size: cover;
256 | background-position: center, center;
257 | color: white;
258 | opacity: 2;
259 | -webkit-box-sizing: border-box;
260 | box-sizing: border-box;
261 | font-family: Arial, Helvetica, sans-serif;
262 | filter: brightness(1.1);
263 | }
264 |
265 | .slides .rights {
266 | order: 2;
267 | }
268 |
269 | .slides .rights img {
270 | border-radius: 5px;
271 | width: 150px;
272 | height: 250px;
273 | object-fit: cover;
274 | }
275 |
276 |
277 | .slide-detail-inner {
278 | width: 90%;
279 | display: -webkit-box;
280 | display: -ms-flexbox;
281 | display: flex;
282 | margin: 50px 30px;
283 | flex-direction: column;
284 | }
285 |
286 | .slide-detail-info {
287 | display: flex;
288 | flex-direction: column;
289 | gap: 15px;
290 | }
291 |
292 | .slide-judul {
293 | display: flex;
294 | align-items: flex-start;
295 | gap: 50px;
296 | }
297 |
298 | .slide-judul-inner{
299 | display: flex;
300 | flex-direction: column;
301 | gap: 10px;
302 | }
303 |
304 | .slide-judul-inner .genre a{
305 | color: white;
306 | font-size: 15px;
307 | }
308 |
309 | .slide-detail-inner .overview {
310 | display: flex;
311 | flex-direction: column;
312 | gap: 10px;
313 | align-items: flex-start;
314 | }
315 |
316 | .slide-detail-inner .tag-title {
317 | font-size: 19px;
318 | }
319 |
320 | .slide-detail-inner .tagline {
321 | line-height: 19px;
322 | font-size: 13px;
323 | display: -webkit-box;
324 | -webkit-line-clamp: 2;
325 | -webkit-box-orient: vertical;
326 | -o-text-overflow: ellipsis;
327 | text-overflow: ellipsis;
328 | overflow: hidden;
329 | }
330 |
331 | .slide-judul .judul-inner {
332 | display: flex;
333 | flex-direction: column;
334 | gap: 10px;
335 | }
336 |
337 | .slide-judul .stars {
338 | display: flex;
339 | justify-content: space-between;
340 | gap: 10px;
341 | align-items: center;
342 | }
343 |
344 | .stars img {
345 | width: 70px;
346 | order: -1;
347 | }
348 |
349 | .stars-container{
350 | display: flex;
351 | gap: 10px;
352 | }
353 |
354 | .stars {
355 | position: relative;
356 | }
357 |
358 | .stars .slide-rate {
359 | position: absolute;
360 | top: 28px;
361 | left: 22px;
362 | color: black;
363 | font-weight: bold;
364 | font-size: 18px;
365 | }
366 |
367 | .slide-judul .jdl a {
368 | font-size: 22px;
369 | font-weight: bold;
370 | color: white;
371 | text-decoration: none;
372 | text-overflow: ellipsis;
373 | }
374 |
375 | .slide-detail-info .genre a{
376 | color: white;
377 | }
378 | .slide-judul .images a {
379 | font-size: 14px;
380 | color: white;
381 | text-decoration: none;
382 | }
383 |
384 | /* BANNER */
385 |
386 | /* MAIN */
387 |
388 | .content {
389 | flex: 2;
390 | -ms-grid-row: 2;
391 | -ms-grid-column: 1;
392 | -ms-grid-column-span: 3;
393 | display: -webkit-box;
394 | display: -ms-flexbox;
395 | display: flex;
396 | -webkit-box-orient: vertical;
397 | -webkit-box-direction: normal;
398 | -ms-flex-direction: column;
399 | flex-direction: column;
400 | gap: 20px;
401 | font-family: Arial, Helvetica, sans-serif;
402 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
403 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
404 | position: relative;
405 | overflow: hidden;
406 | height: 100%;
407 | }
408 |
409 |
410 | .title {
411 | font-size: 20px;
412 | font-weight: bold;
413 | padding: 12px;
414 | color: black;
415 | padding: 10px;
416 | margin: 5px 0;
417 | grid-column-end: 1;
418 | grid-column-start: -1;
419 | /* background-color: black; */
420 | /* background-color: var(--green); */
421 | }
422 |
423 | .judul-container{
424 | display: flex;
425 | justify-content: space-between;
426 | align-items: center;
427 | margin: 5px 5px;
428 | }
429 |
430 | .judul-container a{
431 | color: #0b6dff;
432 | padding-right: 5px;
433 | }
434 | .detail-title {
435 | font-size: 20px;
436 | font-weight: bold;
437 | color: white;
438 | grid-column-start: 1;
439 | grid-column-end: -1;
440 | }
441 |
442 | .sub-title {
443 | font-size: 17px;
444 | font-weight: bold;
445 | color: white;
446 | background-color: #333333;
447 | padding: 10px;
448 | border-radius: 2px;
449 | }
450 |
451 | .judul-flex {
452 | display: flex;
453 | align-items: center;
454 | gap: 20px;
455 | }
456 |
457 | .tittle-inner {
458 | display: flex;
459 | align-items: center;
460 | gap: 10px;
461 | border: 1px solid #031d33;
462 | border-radius: 15px;
463 | }
464 |
465 | .tittle-inner a {
466 | text-decoration: none;
467 | font-size: 13px;
468 | font-weight: bold;
469 | padding: 10px 20px;
470 | color: black;
471 | transition: 250ms;
472 | }
473 |
474 | .tittle-inner .actives {
475 | background-color: #031d33;
476 | color: #20f0e5;
477 | border-radius: 15px;
478 | transition: 500ms;
479 | }
480 |
481 | .test {
482 | background: linear-gradient(to right, rgba(var(--tmdbDarkBlue), 0.75) 0%, rgba(var(--tmdbDarkBlue), 0.75) 100%);
483 | }
484 |
485 | .populer-container {
486 | position: relative;
487 | overflow: hidden;
488 | transition: 500ms;
489 | animation: fade 500ms;
490 | }
491 |
492 |
493 | .review-container {
494 | border-top: 2px solid rgba(0, 0, 0, 0.397);
495 | border-bottom: 2px solid rgba(0, 0, 0, 0.397);
496 | padding: 30px 0;
497 | }
498 |
499 | .reviews-container{
500 | margin: 100px 50px;
501 | }
502 |
503 | .reviews-inner{
504 | display: flex;
505 | flex-direction: column;
506 | gap: 35px;
507 | margin: 0 100px;
508 | }
509 |
510 | .review-content {
511 | display: flex;
512 | flex-direction: column;
513 | gap: 20px;
514 | }
515 |
516 | .review-card {
517 | display: flex;
518 | flex-direction: column;
519 | gap: 10px;
520 | background-color: white;
521 | border-radius: 5px;
522 | padding: 20px;
523 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
524 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
525 | }
526 |
527 | .review-card .review-title {
528 | font-size: 20px;
529 | font-weight: bold;
530 | color: black;
531 | }
532 |
533 | .author .datez{
534 | font-style: italic;
535 | }
536 | .review-card .paraf {
537 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
538 | word-spacing: 5px;
539 | line-height: 29px;
540 | text-align: left;
541 | letter-spacing:1px;
542 | font-size: 15px;
543 | font-weight: 450;
544 | }
545 |
546 | .parafs{
547 | display: -webkit-box;
548 | -webkit-line-clamp: 2;
549 | -webkit-box-orient: vertical;
550 | -o-text-overflow: ellipsis;
551 | text-overflow: ellipsis;
552 | overflow: hidden;
553 | }
554 | .review-card .author {
555 | display: flex;
556 | flex-direction: column;
557 | align-items: flex-start;
558 | gap: 10px;
559 | }
560 |
561 | .review-card .profil {
562 | display: flex;
563 | gap: 20px;
564 | align-items: flex-start;
565 | }
566 |
567 | .review-card .profil img {
568 | width: 64px;
569 | height: 64px;
570 | border-radius: 50%;
571 | }
572 |
573 | .review-card .profil-info {
574 | display: flex;
575 | flex-direction: column;
576 | gap: 25px;
577 | align-items: flex-start;
578 | }
579 |
580 | .load{
581 | color: black;
582 | font-weight: bold;
583 | padding: 10px;
584 | font-size: 17px;
585 | display: block;
586 | }
587 |
588 | .hide{
589 | display: none;
590 | }
591 |
592 | .reviews {
593 | position: relative;
594 | text-decoration: none;
595 | color: black;
596 | font-weight: bold;
597 | }
598 |
599 | .reviews::after {
600 | content: " ";
601 | position: absolute;
602 | width: 100%;
603 | top: 17px;
604 | left: 0;
605 | font-weight: bold;
606 | border-bottom: 4px solid black;
607 | border-radius: 4px;
608 | }
609 |
610 | .tittle-inners {
611 | display: flex;
612 | align-items: center;
613 | gap: 600px;
614 | }
615 |
616 | .tittle-inners ul{
617 | display: flex;
618 | align-items: center;
619 | gap: 20px;
620 | }
621 |
622 | .tittle-inners a {
623 | text-decoration: none;
624 | font-weight: bold;
625 | font-size: 16px;
626 | color: black;
627 | transition: 250ms;
628 | }
629 |
630 |
631 | .populer-inner {
632 | display: -webkit-box;
633 | display: -ms-flexbox;
634 | display: flex;
635 | gap: 20px;
636 | padding: 10px 0 10px 0;
637 | -webkit-transition: 500ms;
638 | -o-transition: 500ms;
639 | transition: 500ms;
640 | }
641 |
642 | .detail-inner {
643 | display: -webkit-box;
644 | display: -ms-flexbox;
645 | display: flex;
646 | gap: 20px;
647 | padding: 10px 0 10px 0;
648 | -webkit-transition: 500ms;
649 | -o-transition: 500ms;
650 | transition: 500ms;
651 | overflow-x: scroll;
652 | }
653 |
654 | .tombol-top {
655 | display: -webkit-box;
656 | display: -ms-flexbox;
657 | display: flex;
658 | font-size: 80px;
659 | color: blue;
660 | font-weight: 900;
661 | font-family: Arial, Helvetica, sans-serif;
662 | cursor: pointer;
663 | }
664 |
665 | .tombol-butt {
666 | display: -webkit-box;
667 | display: -ms-flexbox;
668 | display: flex;
669 | font-size: 80px;
670 | color: blue;
671 | font-weight: 900;
672 | font-family: Arial, Helvetica, sans-serif;
673 | cursor: pointer;
674 | }
675 |
676 | .kiri {
677 | display: none;
678 | width: 57px;
679 | height: 93px;
680 | background-image: url(prev.png);
681 | position: absolute;
682 | background-repeat: no-repeat;
683 | top: 37%;
684 | left: -1%;
685 | -webkit-filter: brightness(0.8);
686 | filter: brightness(0.8);
687 | z-index: 10;
688 | }
689 |
690 | .kanan {
691 | z-index: 10;
692 | width: 57px;
693 | height: 93px;
694 | background-image: url(next.png);
695 | position: absolute;
696 | background-repeat: no-repeat;
697 | top: 37%;
698 | right: -1%;
699 | -webkit-filter: brightness(0.8);
700 | filter: brightness(0.8);
701 | }
702 |
703 | .kiri:hover {
704 | -webkit-filter: brightness(1.5);
705 | filter: brightness(1.5);
706 | }
707 |
708 | .kanan:hover {
709 | -webkit-filter: brightness(1.5);
710 | filter: brightness(1.5);
711 | }
712 |
713 | .card {
714 | background-color: white;
715 | border-radius: 5px;
716 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
717 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
718 | font-family: Arial, Helvetica, sans-serif;
719 | width: 150px;
720 | -webkit-transition: 500ms;
721 | -o-transition: 500ms;
722 | transition: 500ms;
723 | position: relative;
724 | animation: fade 500ms;
725 | }
726 |
727 | .card a {
728 | text-decoration: none;
729 | color: black;
730 | transition: 500ms;
731 | }
732 |
733 | .card a:hover {
734 | color: rgb(0, 153, 255);
735 | }
736 |
737 | .card .thumb {
738 | -webkit-transition: 500ms;
739 | -o-transition: 500ms;
740 | transition: 500ms;
741 | width: 150px;
742 | border-radius: 5px;
743 | cursor: pointer;
744 | }
745 |
746 |
747 | .card .info {
748 | display: -webkit-box;
749 | display: -ms-flexbox;
750 | display: flex;
751 | -webkit-box-orient: vertical;
752 | -webkit-box-direction: normal;
753 | -ms-flex-direction: column;
754 | flex-direction: column;
755 | -webkit-box-align: center;
756 | -ms-flex-align: center;
757 | align-items: center;
758 | text-align: center;
759 | margin: 20px auto;
760 | gap: 15px;
761 | }
762 |
763 | .card .info .judul {
764 | font-size: 17px;
765 | font-weight: 550;
766 | display: -webkit-box;
767 | -webkit-line-clamp: 2;
768 | -webkit-box-orient: vertical;
769 | -o-text-overflow: ellipsis;
770 | text-overflow: ellipsis;
771 | overflow: hidden;
772 | }
773 |
774 | .card .info .date {
775 | font-size: 14px;
776 | }
777 |
778 |
779 | /* END MAIN*/
780 |
781 | /* LEFT MENU */
782 |
783 | .left-sidebar {
784 | order: 2;
785 | flex: 0;
786 | flex-grow: 0.7;
787 | grid-area: left;
788 | display: flex;
789 | flex-direction: column;
790 | gap: 40px;
791 | /* -webkit-box-shadow: #333333 0px 3px 8px;
792 | box-shadow: #333333 0px 3px 8px; */
793 | /* background-color: #16151D; */
794 | /* border: 2px solid #333333; */
795 | }
796 |
797 | .left-list {
798 | display: flex;
799 | flex-direction: column;
800 | gap: 20px;
801 | /* background-color: #333333; */
802 | background-color: white;
803 | box-shadow: 1px 3px 8px rgb(49 49 49 / 10%);
804 | border-radius: 3px;
805 | }
806 |
807 | .inner-list {
808 | display: flex;
809 | flex-direction: column;
810 | gap: 15px;
811 | }
812 |
813 | .inner-list a {
814 | font-size: 17px;
815 | color: white;
816 | text-decoration: none;
817 | font-weight: bold;
818 | }
819 |
820 |
821 | .genre-list {
822 | display: flex;
823 | flex-wrap: wrap;
824 | gap: 5px;
825 | justify-content: space-around;
826 | font-size: inherit;
827 | }
828 |
829 | .genre-list li {
830 | width: 40%;
831 | padding: 5px 10px;
832 | background-color: #333333;
833 | list-style: none;
834 | border-radius: 3px;
835 | margin: auto;
836 | padding-left: 2px;
837 | line-height: 25px;
838 | transition: 200ms;
839 | text-align: center;
840 | }
841 |
842 | .genre-button {
843 | text-align: center;
844 | color: white;
845 | font-weight: bold;
846 | font-size: 12px;
847 | text-decoration: none;
848 | transition: 250ms;
849 | }
850 |
851 | .genre-list li:hover {
852 | background-color: rgba(0, 0, 0, 0.644);
853 | color: black;
854 | }
855 |
856 | .sidebar-content {
857 | display: flex;
858 | flex-direction: column;
859 | gap: 10px;
860 | margin: 5px 10px;
861 | }
862 |
863 | .sidebar-card {
864 | display: flex;
865 | align-items: center;
866 | gap: 15px;
867 | color: black;
868 | padding: 5px;
869 | border-bottom: 1px solid #ececec;
870 | transition: 500ms;
871 | animation: fade 500ms;
872 | }
873 |
874 | .sidebar-card .thumbs {
875 | width: 50px;
876 | }
877 |
878 | .trending-option ul {
879 | display: flex;
880 | justify-content: center;
881 | gap: 20px;
882 | }
883 |
884 | .trending-option {
885 | background-color: #333333;
886 | padding: 10px;
887 | border-radius: 5px;
888 | }
889 |
890 | .trending-option ul a {
891 | color: white;
892 | text-decoration: none;
893 | font-weight: bold;
894 | font-size: 13px;
895 | }
896 |
897 | .active {
898 | background-color: var(--green);
899 | padding: 5px 15px;
900 | border-radius: 2px;
901 | transition: 100ms;
902 | }
903 |
904 | .genres {
905 | font-size: 12px;
906 | display: flex;
907 | gap: 5px;
908 | flex-wrap: wrap;
909 | color: rgba(49, 44, 44, 0.712);
910 | }
911 |
912 | .card-genre {
913 | font-size: 12px;
914 | color: black;
915 | text-decoration: none;
916 | }
917 |
918 | .index span {
919 | font-size: 14px;
920 | padding: 5px 5px;
921 | border: 1px solid rgba(0, 0, 0, 0.479);
922 | border-radius: 3px;
923 | }
924 |
925 | .sidebar-info {
926 | display: flex;
927 | flex-direction: column;
928 | gap: 8px;
929 | }
930 |
931 | .sidebar-info .judul a {
932 | font-size: 16px;
933 | font-weight: bold;
934 | text-decoration: none;
935 | color: black;
936 | }
937 |
938 | /* END LEFT MENU */
939 |
940 | /* VIDEO */
941 |
942 | .video-container .title {
943 | font-size: 30px;
944 | font-weight: bold;
945 | padding: 20px;
946 | color: white;
947 | }
948 |
949 | .video-container {
950 | margin: 25px 0;
951 | position: relative;
952 | padding: 30px 0 30px 0;
953 | -webkit-transition: 1500ms;
954 | -o-transition: 1500ms;
955 | transition: 1500ms;
956 | width: 100%;
957 | background: rgba(3, 37, 65);
958 | overflow: hidden;
959 | color: white;
960 | background: linear-gradient(to right, rgba(var(--tmdbDarkBlue), 0.75) 0%, rgba(var(--tmdbDarkBlue), 0.75) 100%);
961 | }
962 |
963 | .video-container-inner {
964 | display: -webkit-box;
965 | display: -ms-flexbox;
966 | display: flex;
967 | overflow: hidden;
968 | gap: 15px;
969 | -webkit-transition: 500ms;
970 | -o-transition: 500ms;
971 | transition: 500ms;
972 | }
973 |
974 | .container-videos {
975 | -webkit-transition: 500ms;
976 | -o-transition: 500ms;
977 | transition: 500ms;
978 | display: -webkit-box;
979 | display: -ms-flexbox;
980 | display: flex;
981 | -webkit-box-orient: vertical;
982 | -webkit-box-direction: normal;
983 | -ms-flex-direction: column;
984 | flex-direction: column;
985 | -webkit-box-pack: center;
986 | -ms-flex-pack: center;
987 | justify-content: center;
988 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
989 | background-color: white
990 | }
991 |
992 | .container-videos .info {
993 | display: -webkit-box;
994 | display: -ms-flexbox;
995 | display: flex;
996 | -webkit-box-orient: vertical;
997 | -webkit-box-direction: normal;
998 | -ms-flex-direction: column;
999 | flex-direction: column;
1000 | gap: 10px;
1001 | -webkit-filter: brightness(2);
1002 | filter: brightness(2);
1003 | }
1004 |
1005 | .container-videos .info .trailer {
1006 | color: black;
1007 | font-size: 17px;
1008 | font-weight: bold;
1009 | text-align: center;
1010 | }
1011 |
1012 | .container-videos .info .trailer-judul {
1013 | color: black;
1014 | font-size: 16px;
1015 | text-align: center;
1016 | }
1017 |
1018 | .image-wrappers{
1019 | animation: fade 500ms;
1020 | }
1021 |
1022 | .image-wrappers img{
1023 | height: 281px;
1024 | object-fit: contain;
1025 | }
1026 |
1027 | .view-all a{
1028 | color:#0b75ff;
1029 | }
1030 |
1031 | .container-videos .play {
1032 | text-decoration: none;
1033 | position: absolute;
1034 | top: 35%;
1035 | left: 44%;
1036 | width: 50px;
1037 | color: white;
1038 | z-index: 5;
1039 | }
1040 |
1041 | .container-videos .play .play-img {
1042 | width: 50px;
1043 | }
1044 |
1045 | .container-videos .image-wrapper {
1046 | width: 300px;
1047 | height: 250px;
1048 | position: relative;
1049 | -webkit-box-sizing: border-box;
1050 | box-sizing: border-box;
1051 | overflow: hidden;
1052 | -webkit-transition: 500ms;
1053 | -o-transition: 500ms;
1054 | transition: 500ms;
1055 | }
1056 |
1057 | .image-wrapper:hover img {
1058 | -webkit-transform: scale(1.1);
1059 | -ms-transform: scale(1.1);
1060 | transform: scale(1.1);
1061 | -webkit-transition: 500ms;
1062 | -o-transition: 500ms;
1063 | transition: 500ms;
1064 | }
1065 |
1066 | .container-videos .image-wrapper img {
1067 | width: 300px;
1068 | }
1069 |
1070 | /* Then style the iframe to fit in the container div with full height and width */
1071 |
1072 | /* END VIDEO */
1073 |
1074 | /* MODAL */
1075 |
1076 | .modal-video.modals {
1077 | -webkit-transition: 500ms;
1078 | -o-transition: 500ms;
1079 | transition: 500ms;
1080 | position: fixed;
1081 | top: 0;
1082 | left: 0;
1083 | bottom: 0;
1084 | right: 0;
1085 | background-color: rgba(0, 0, 0, 0.521);
1086 | z-index: 5555;
1087 | width: 100%;
1088 | height: 100%;
1089 | -webkit-transition: 250ms;
1090 | -o-transition: 250ms;
1091 | transition: 250ms;
1092 | opacity: 1;
1093 | height: 100%;
1094 | }
1095 |
1096 | .box-video {
1097 | width: 900px;
1098 | height: 600px;
1099 | margin: 35px auto;
1100 | display: -webkit-box;
1101 | display: -ms-flexbox;
1102 | display: flex;
1103 | }
1104 |
1105 | .show {
1106 | display: none;
1107 | }
1108 |
1109 | .containers {
1110 | position: relative;
1111 | overflow: hidden;
1112 | width: 100%;
1113 | padding-top: 56.25%;
1114 | /* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */
1115 | }
1116 |
1117 | .responsive-iframe {
1118 | position: absolute;
1119 | top: 0;
1120 | left: 0;
1121 | bottom: 0;
1122 | right: 0;
1123 | width: 100%;
1124 | height: 100%;
1125 | }
1126 |
1127 | /* END MODAL */
1128 |
1129 |
1130 | /* FOOTER */
1131 | .footers {
1132 | -ms-grid-row: 3;
1133 | -ms-grid-column: 1;
1134 | -ms-grid-column-span: 3;
1135 | /* width: 100%; */
1136 | grid-area: butt;
1137 | background-color: #031d33;
1138 | padding: 30px;
1139 | color: white;
1140 | }
1141 |
1142 | .footer-info {
1143 | text-align: center;
1144 | display: -webkit-box;
1145 | display: -ms-flexbox;
1146 | display: flex;
1147 | -webkit-box-orient: vertical;
1148 | -webkit-box-direction: normal;
1149 | gap: 25px;
1150 | font-size: 17px;
1151 | font-weight: bold;
1152 | -webkit-box-align: center;
1153 | -ms-flex-align: center;
1154 | justify-content: center;
1155 | align-items: center;
1156 | }
1157 |
1158 | .footer-info img {
1159 | width: 250px;
1160 | }
1161 |
1162 | .footer-info .git {
1163 | width: 70px;
1164 | }
1165 | /* end footer */
1166 |
1167 | .modals {
1168 | position: fixed;
1169 | top: 0;
1170 | left: 0;
1171 | bottom: 0;
1172 | right: 0;
1173 | z-index: 100;
1174 | background-color: rgba(0, 0, 0, 0.473);
1175 | animation: fade 500ms;
1176 | transition: 250ms;
1177 | }
1178 |
1179 | @keyframes fade {
1180 | 0% {
1181 | opacity: 0;
1182 | }
1183 |
1184 | 100% {
1185 | opacity: 1;
1186 | }
1187 | }
1188 |
1189 | .image-wrap {
1190 | margin: 70px 50px;
1191 | display: flex;
1192 | justify-content: center;
1193 | position: relative;
1194 | }
1195 |
1196 | .image-wrap img {
1197 | width: 700px;
1198 | height: 500px;
1199 | object-fit: contain;
1200 | }
1201 |
1202 | /* LOADING */
1203 |
1204 | .loader-wrapper .hidden {
1205 | display: none;
1206 | }
1207 |
1208 | .loader-wrapper {
1209 | width: 100%;
1210 | height: 100%;
1211 | position: fixed;
1212 | top: 0;
1213 | left: 0;
1214 | background-color: #242f3f;
1215 | display: -webkit-box;
1216 | display: -ms-flexbox;
1217 | display: flex;
1218 | -webkit-box-pack: center;
1219 | -ms-flex-pack: center;
1220 | justify-content: center;
1221 | -webkit-box-align: center;
1222 | -ms-flex-align: center;
1223 | align-items: center;
1224 | z-index: 10;
1225 | }
1226 |
1227 | .loader {
1228 | display: inline-block;
1229 | width: 30px;
1230 | height: 30px;
1231 | position: relative;
1232 | border: 4px solid #Fff;
1233 | -webkit-animation: loader 2s infinite ease;
1234 | animation: loader 2s infinite ease;
1235 | }
1236 |
1237 | .loader-inner {
1238 | vertical-align: top;
1239 | display: inline-block;
1240 | width: 100%;
1241 | background-color: #fff;
1242 | -webkit-animation: loader-inner 2s infinite ease-in;
1243 | animation: loader-inner 2s infinite ease-in;
1244 | }
1245 |
1246 | @-webkit-keyframes loader {
1247 | 0% {
1248 | -webkit-transform: rotate(0deg);
1249 | transform: rotate(0deg);
1250 | }
1251 |
1252 | 25% {
1253 | -webkit-transform: rotate(180deg);
1254 | transform: rotate(180deg);
1255 | }
1256 |
1257 | 50% {
1258 | -webkit-transform: rotate(180deg);
1259 | transform: rotate(180deg);
1260 | }
1261 |
1262 | 75% {
1263 | -webkit-transform: rotate(360deg);
1264 | transform: rotate(360deg);
1265 | }
1266 |
1267 | 100% {
1268 | -webkit-transform: rotate(360deg);
1269 | transform: rotate(360deg);
1270 | }
1271 | }
1272 |
1273 | @keyframes loader {
1274 | 0% {
1275 | -webkit-transform: rotate(0deg);
1276 | transform: rotate(0deg);
1277 | }
1278 |
1279 | 25% {
1280 | -webkit-transform: rotate(180deg);
1281 | transform: rotate(180deg);
1282 | }
1283 |
1284 | 50% {
1285 | -webkit-transform: rotate(180deg);
1286 | transform: rotate(180deg);
1287 | }
1288 |
1289 | 75% {
1290 | -webkit-transform: rotate(360deg);
1291 | transform: rotate(360deg);
1292 | }
1293 |
1294 | 100% {
1295 | -webkit-transform: rotate(360deg);
1296 | transform: rotate(360deg);
1297 | }
1298 | }
1299 |
1300 | @-webkit-keyframes loader-inner {
1301 | 0% {
1302 | height: 0%;
1303 | }
1304 |
1305 | 25% {
1306 | height: 0%;
1307 | }
1308 |
1309 | 50% {
1310 | height: 100%;
1311 | }
1312 |
1313 | 75% {
1314 | height: 100%;
1315 | }
1316 |
1317 | 100% {
1318 | height: 0%;
1319 | }
1320 | }
1321 |
1322 | @keyframes loader-inner {
1323 | 0% {
1324 | height: 0%;
1325 | }
1326 |
1327 | 25% {
1328 | height: 0%;
1329 | }
1330 |
1331 | 50% {
1332 | height: 100%;
1333 | }
1334 |
1335 | 75% {
1336 | height: 100%;
1337 | }
1338 |
1339 | 100% {
1340 | height: 0%;
1341 | }
1342 | }
1343 |
1344 |
1345 |
1346 | .lds-facebook {
1347 | display: inline-block;
1348 | position: relative;
1349 | width: 80px;
1350 | height: 80px;
1351 | left: 30%;
1352 | margin: 100px 0;
1353 | }
1354 |
1355 | .lds-facebook div {
1356 | display: inline-block;
1357 | position: absolute;
1358 | left: 8px;
1359 | width: 16px;
1360 | background: black;
1361 | animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
1362 | }
1363 |
1364 | .lds-facebook div:nth-child(1) {
1365 | left: 8px;
1366 | animation-delay: -0.24s;
1367 | }
1368 |
1369 | .lds-facebook div:nth-child(2) {
1370 | left: 32px;
1371 | animation-delay: -0.12s;
1372 | }
1373 |
1374 | .lds-facebook div:nth-child(3) {
1375 | left: 56px;
1376 | animation-delay: 0;
1377 | }
1378 |
1379 | @keyframes lds-facebook {
1380 | 0% {
1381 | top: 8px;
1382 | height: 64px;
1383 | }
1384 |
1385 | 50%,
1386 | 100% {
1387 | top: 24px;
1388 | height: 32px;
1389 | }
1390 | }
1391 |
1392 | /* END LOADING */
1393 |
1394 |
1395 |
1396 |
1397 | /* RESPONSIVE */
1398 |
1399 | @media (max-width:1200px) {
1400 | .App {
1401 | margin: 20px 10px;
1402 | }
1403 |
1404 | .reviews-container{
1405 | margin: 100px 20px;
1406 | }
1407 |
1408 | .reviews-inner{
1409 | margin: 0 10px;
1410 | }
1411 | }
1412 |
1413 | @media (max-width:1050px) {
1414 | .App {
1415 | margin: 75px 10px;
1416 | }
1417 |
1418 | .banner .slides {
1419 | width: 670px;
1420 | }
1421 | }
1422 |
1423 | @media (max-width:950px) {
1424 | .App {
1425 | margin: 70px 0;
1426 | flex-direction: column;
1427 | }
1428 |
1429 | .banner .slides {
1430 | width: 950px;
1431 | }
1432 |
1433 | .content {
1434 | margin: 0 10px;
1435 | }
1436 |
1437 | .box-video {
1438 | width: 850px;
1439 | height: 450px;
1440 | margin: 85px auto;
1441 | display: -webkit-box;
1442 | display: -ms-flexbox;
1443 | display: flex;
1444 | }
1445 |
1446 | }
1447 |
1448 | @media (max-width:900px) {
1449 | .banner .slides {
1450 | width:850px;
1451 | }
1452 | .slide-detail-inner {
1453 | margin:50px 50px;
1454 | }
1455 |
1456 | .slide-judul .jdl a {
1457 | text-overflow: ellipsis;
1458 | }
1459 |
1460 | .reviews-container{
1461 | margin: 100px 10px;
1462 | }
1463 |
1464 | .reviews-inner{
1465 | margin: 0 10px;
1466 | }
1467 |
1468 | .review-card .profil {
1469 | flex-direction: column;
1470 | padding: 25px;
1471 | }
1472 |
1473 | .review-card .paraf{
1474 | font-size: 14px;
1475 | }
1476 | }
1477 |
1478 | @media (max-width:850px) {
1479 | .banner .slides {
1480 | width:805px;
1481 | }
1482 | .slide-detail-inner {
1483 | margin:50px 50px;
1484 | }
1485 | .slide-judul-inner{
1486 | gap: 20px;
1487 | align-items: flex-start;
1488 | }
1489 | .slide-judul .jdl a {
1490 | text-overflow: ellipsis;
1491 | }
1492 |
1493 | .review-card .profil {
1494 | flex-direction: column;
1495 | padding: 25px;
1496 | }
1497 |
1498 | .review-card .paraf{
1499 | word-break: break-word;
1500 | overflow-wrap: break-word;
1501 | }
1502 | }
1503 |
1504 |
1505 | @media (max-width:800px) {
1506 | .tittle-inners {
1507 | gap: 120px;
1508 | }
1509 |
1510 | .tittle-inners a{
1511 | font-size: 14px;
1512 | }
1513 |
1514 |
1515 | .banner .slides {
1516 | width:750px;
1517 | }
1518 | .slide-detail-inner {
1519 | margin:50px 50px;
1520 | }
1521 |
1522 | .slide-judul .jdl a {
1523 | text-overflow: ellipsis;
1524 | }
1525 |
1526 | .slide-judul .jdl a {
1527 | text-overflow: ellipsis;
1528 | }
1529 |
1530 | .slide-judul-inner{
1531 | gap: 20px;
1532 | align-items: flex-start;
1533 | }
1534 |
1535 | .slides .rights img {
1536 | border-radius: 5px;
1537 | width: 170px;
1538 | height: 280px;
1539 | object-fit: cover;
1540 | }
1541 |
1542 | .slide-detail-inner .overview {
1543 | display: flex;
1544 | flex-direction: column;
1545 | gap: 10px;
1546 | align-items: flex-start;
1547 | }
1548 |
1549 | .slide-detail-info {
1550 | display: flex;
1551 | flex-direction: column;
1552 | gap: 25px;
1553 | margin: 0 50px 0 15px;
1554 | }
1555 | .slide-detail-inner .tagline {
1556 | line-height: 19px;
1557 | font-size: 13px;
1558 | }
1559 |
1560 | .box-video {
1561 | width: 740px;
1562 | height: 450px;
1563 | margin: 85px auto;
1564 | display: -webkit-box;
1565 | display: -ms-flexbox;
1566 | display: flex;
1567 | }
1568 |
1569 | }
1570 |
1571 | @media (max-width:750px) {
1572 | .banner .slides {
1573 | width:700px;
1574 | }
1575 | .slide-detail-inner {
1576 | margin:50px 50px;
1577 | }
1578 | .slide-judul-inner{
1579 | gap: 20px;
1580 | align-items: flex-start;
1581 | }
1582 |
1583 | .slide-judul .jdl a {
1584 | text-overflow: ellipsis;
1585 | }
1586 |
1587 | .box-video {
1588 | width: 650px;
1589 | height: 450px;
1590 | margin: 85px auto;
1591 | }
1592 |
1593 | }
1594 |
1595 |
1596 | @media (max-width:675px) {
1597 | .banner .slides {
1598 | width:635px;
1599 | }
1600 | .slide-detail-inner {
1601 | margin:50px 50px;
1602 | }
1603 | .slide-judul-inner{
1604 | gap: 20px;
1605 | align-items: flex-start;
1606 | }
1607 |
1608 | .slide-judul .jdl a {
1609 | text-overflow: ellipsis;
1610 | }
1611 |
1612 | .box-video {
1613 | width: 600px;
1614 | height: 450px;
1615 | margin: 85px auto;
1616 | }
1617 |
1618 |
1619 | }
1620 |
1621 | @media (max-width:600px) {
1622 | .banner .slides {
1623 | width: 553px;
1624 | }
1625 |
1626 | .slide-detail-inner {
1627 | margin: 75px 35px 45px 20px;
1628 | gap: 60px;
1629 | }
1630 |
1631 | .slide-detail-info {
1632 | display: flex;
1633 | flex-direction: column;
1634 | gap: 5px;
1635 | }
1636 | .slides .rights img {
1637 | border-radius: 5px;
1638 | width: 150px;
1639 | height: 200px;
1640 | object-fit: cover;
1641 | }
1642 |
1643 | .images img {
1644 | width: 55px;
1645 | order: -1;
1646 | }
1647 |
1648 | .images .genre a{
1649 | font-size: 13px;
1650 | }
1651 |
1652 | .images .genre{
1653 | display: flex;
1654 | flex-wrap: wrap;
1655 | }
1656 | .stars {
1657 | position: relative;
1658 | }
1659 |
1660 | .images .slide-rate {
1661 | position: absolute;
1662 | top: 23px;
1663 | left: 18px;
1664 | color: black;
1665 | font-weight: bold;
1666 | font-size: 14px;
1667 | }
1668 |
1669 |
1670 | .slide-detail-inner .overview {
1671 | gap: 20px;
1672 | }
1673 |
1674 | .dot-container{
1675 | bottom: 55px;
1676 | left: 10%;
1677 | gap: 10px;
1678 | }
1679 |
1680 | .box-video {
1681 | width: 550px;
1682 | height: 400px;
1683 | margin: 85px auto;
1684 | }
1685 |
1686 |
1687 | }
1688 |
1689 | @media (max-width:500px) {
1690 |
1691 | .box-video {
1692 | width: 450px;
1693 | height: 350px;
1694 | margin: 85px auto;
1695 | }
1696 |
1697 | .banner .slides {
1698 | width: 460px;
1699 | }
1700 |
1701 | .slide-detail-info {
1702 | display: flex;
1703 | flex-direction: column;
1704 | gap: 5px;
1705 | }
1706 | .slides .rights img {
1707 | border-radius: 5px;
1708 | width: 120px;
1709 | height: 200px;
1710 | object-fit: cover;
1711 | }
1712 |
1713 | .stars img {
1714 | width: 55px;
1715 | order: -1;
1716 | }
1717 |
1718 | .slide-judul-inner .genre a{
1719 | font-size: 14px;
1720 | }
1721 |
1722 | .images .genre{
1723 | display: flex;
1724 | flex-wrap: wrap;
1725 | }
1726 | .stars {
1727 | position: relative;
1728 | }
1729 |
1730 | .images .slide-rate {
1731 | position: absolute;
1732 | top: 23px;
1733 | left: 18px;
1734 | color: black;
1735 | font-weight: bold;
1736 | font-size: 14px;
1737 | }
1738 |
1739 | .slide-judul .judul-inner{
1740 | align-items: center;
1741 | }
1742 | .slide-judul .jdl a {
1743 | font-size: 15px;
1744 | }
1745 |
1746 | .slide-detail-inner .overview {
1747 | gap: 25px;
1748 | }
1749 | .slide-detail-inner .overview .tagline{
1750 | display: -webkit-box;
1751 | -webkit-line-clamp: 2;
1752 | -webkit-box-orient: vertical;
1753 | -o-text-overflow: ellipsis;
1754 | text-overflow: ellipsis;
1755 | overflow: hidden;
1756 | }
1757 |
1758 | .detil{
1759 | margin-top: 20px;
1760 | }
1761 | }
1762 |
1763 |
1764 |
1765 | /* MOBILE */
1766 |
1767 | @media (max-width:360px) {
1768 | .banner .slides {
1769 | width: 283px;
1770 | }
1771 |
1772 |
1773 | .slide-detail-info {
1774 | display: flex;
1775 | flex-direction: column;
1776 | gap: 5px;
1777 | }
1778 |
1779 |
1780 | .slide-detail-inner {
1781 | margin:30px 20px;
1782 | }
1783 | .stars img {
1784 | width: 55px;
1785 | order: -1;
1786 | }
1787 |
1788 | .slide-judul{
1789 | gap: 5px;
1790 | }
1791 |
1792 | .slide-judul-inner .genre a{
1793 | font-size: 14px;
1794 | }
1795 |
1796 | .stars img {
1797 | width: 35px;
1798 | order: -1;
1799 | }
1800 |
1801 | .slide-judul .jdl a {
1802 | font-size: 15px;
1803 | }
1804 | .slides .rights img {
1805 | border-radius: 5px;
1806 | width: 80px;
1807 | height: 120px;
1808 | object-fit: contain;
1809 | }
1810 |
1811 |
1812 | .stars .slide-rate {
1813 | position: absolute;
1814 | top: 23px;
1815 | left: 18px;
1816 | color: black;
1817 | font-weight: bold;
1818 | font-size: 14px;
1819 | }
1820 |
1821 | .slide-detail-info .overview .tagline{
1822 | word-wrap: break-word;
1823 | overflow-wrap: break-word;
1824 | }
1825 | .judul-inner .date{
1826 | font-size: 12px;
1827 | }
1828 |
1829 | .dot-container{
1830 | position: absolute;
1831 | bottom: 25px;
1832 | left: 5%;
1833 | gap: 5px;
1834 | z-index: 10;
1835 | }
1836 |
1837 | .dot-container .dot{
1838 | padding: 4px;
1839 | background-color:rgba(255, 255, 255, 0.363);
1840 | border-radius: 50%;
1841 | cursor: pointer;
1842 | }
1843 |
1844 | .tittle-inner a {
1845 | font-size: 12px;
1846 | padding: 10px 18px;
1847 | }
1848 |
1849 | .box-video {
1850 | width: 310px;
1851 | height: 300px;
1852 | margin: 85px auto;
1853 | }
1854 |
1855 |
1856 | .footer-info {
1857 | gap: 10px;
1858 | }
1859 |
1860 | .footer-info img {
1861 | width: 150px;
1862 | }
1863 |
1864 | .footer-info .git {
1865 | width: 50px;
1866 | }
1867 |
1868 | }
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Header from './component/header'
3 | import './App.css';
4 | import { Navigate } from 'react-router-dom';
5 | import { BrowserRouter as Router, Switch, Route ,Routes} from 'react-router-dom';
6 | import Home from './component/home'
7 | import NotFound from './component/404not'
8 | import TvDetail from './component/tv-detail';
9 | import MovieDetail from './component/moviedetail';
10 | import SearchPage from './component/search-page'
11 | import Footer from './component/footer';
12 | import PeopleDetail from './component/people-detail'
13 | import PopularPeople from './component/popular-people';
14 | import GenrePage from './component/genre-page';
15 | import MoviePopuler from './component/movie-all';
16 | import AnimePopuler from './component/anime'
17 | import ReviewPage from './component/review-page';
18 | import PosterPage from './component/poster-page';
19 | import BackdropPage from './component/backdrop-page';
20 | import TvPopuler from './component/tv-all';
21 |
22 | class App extends React.Component {
23 |
24 | constructor(){
25 | super()
26 | this.state = {
27 | search:''
28 | }
29 | }
30 |
31 |
32 | render(){
33 |
34 | return (
35 |
36 |
37 |
38 | } exact/>
39 | } />
40 | } />
41 | } />
42 | } />
43 | } />
44 | } />
45 | } />
46 | } />
47 | } />
48 | } />
49 | } />
50 | } />
51 | } />
52 |
53 |
54 |
55 | )
56 | }
57 | }
58 |
59 | export default App;
60 |
61 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/src/akun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/akun.png
--------------------------------------------------------------------------------
/src/component/404not.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 |
4 | class NotFound extends React.Component{
5 |
6 | render(){
7 | return(
8 | <>
9 |
10 |
PAGE NOT FOUND
11 | BACK TO HOME
12 |
13 | >
14 | )
15 | }
16 | }
17 |
18 | export default NotFound;
--------------------------------------------------------------------------------
/src/component/a.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link} from 'react-router-dom'
3 |
4 |
5 | class BannerDetail extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | isLoad:true,
10 | movie:[],
11 | id:this.props.id
12 | }
13 | }
14 |
15 | async componentDidMount(){
16 | const popular = await fetch(
17 | `https://api.themoviedb.org/3/movie/${this.state.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
18 | )
19 | const respon = await popular.json()
20 | const movies = respon.results
21 | console.log(movies);
22 | if (respon) {
23 | this.setState(prev => {
24 | return{
25 | isLoad:prev.isLoad = false,
26 | movie:prev.movie = movies
27 | }
28 | })
29 | }
30 | }
31 |
32 | render(){
33 | // const img = []
34 | // const image = this.state.movie.forEach(m => {
35 | // img.push(m.poster_path)
36 | // })
37 |
38 | // const styles = {
39 | // backgroundImage: `url(https://image.tmdb.org/t/p/w1280/${img[0]})`
40 | // }
41 | return(
42 |
43 |
44 |
45 |
46 |
${detil.title}
47 |
${detil.tagline}
48 |
Genres:
49 |
Runtime: ${detil.runtime}m
50 |
Status: ${detil.status}
51 |
Release Date: ${detil.release_date}
52 |
53 |
Overview
54 |
${detil.overview}
55 |
56 |
57 |
58 |
59 |
60 |
61 | )
62 | }
63 | }
64 |
65 |
66 | export default BannerDetail;
--------------------------------------------------------------------------------
/src/component/anime.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import LeftSidebar from './left-sidebar'
3 | import MovieCard from './moviecard'
4 |
5 |
6 | class AnimePopuler extends React.Component{
7 | constructor(){
8 | super()
9 | this.state = {
10 | aniMovi:[],
11 | aniTv:[],
12 | loading:true,
13 | pages:1
14 | }
15 | }
16 |
17 | async componentDidMount(){
18 | const animeTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=1&with_keywords=210024|222243`)
19 |
20 | const animeMovie = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=1&with_keywords=210024|222243`)
21 |
22 | const aniMovRes = await animeMovie.json()
23 | const aniTvRes = await animeTv.json()
24 | if(aniMovRes){
25 | this.setState(prev => {
26 | return{
27 | aniMovi:prev.aniMovi = aniMovRes.results,
28 | aniTv:prev.aniTv = aniTvRes.results,
29 | loading:prev.loading = false
30 | }
31 | })
32 | }
33 | }
34 |
35 | async componentDidUpdate(){
36 | const animeTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
37 |
38 | const animeMovie = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
39 |
40 | const aniMovRes = await animeMovie.json()
41 | const aniTvRes = await animeTv.json()
42 | if(aniMovRes){
43 | this.setState(prev => {
44 | return{
45 | aniMovi:prev.aniMovi = aniMovRes.results,
46 | aniTv:prev.aniTv = aniTvRes.results,
47 | loading:prev.loading = false
48 | }
49 | })
50 | }
51 | }
52 |
53 | paginationNext = async (e) => {
54 |
55 | this.setState({
56 | pages:this.state.page = this.state.pages + 1,
57 | loading:this.loading = true
58 | })
59 | }
60 |
61 | paginationPrev = async (e) => {
62 | this.setState({
63 | pages:this.state.page = this.state.pages - 1,
64 | loading:this.loading = true
65 | })
66 |
67 | }
68 |
69 | render(){
70 | const movies = this.state.aniMovi.length < 1 ? "" : this.state.aniMovi.map(m => {
71 | const date = new Date(m.release_date);
72 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={date} />
73 | })
74 |
75 | const tivis = this.state.aniTv.length < 1 ? "" : this.state.aniTv.map(m => {
76 | const dates = new Date(m.first_air_date);
77 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={dates} />
78 | })
79 |
80 | return(
81 |
82 |
83 | {this.state.loading ?
84 |
85 |
: " "}
86 | {movies}
87 | {tivis}
88 | {this.state.loading ? "" :
89 | {this.state.pages > 1 ? Previous : ""}
90 | Next
91 |
}
92 |
93 |
94 |
95 | )
96 | }
97 | }
98 |
99 |
100 | export default AnimePopuler;
--------------------------------------------------------------------------------
/src/component/backdrop-card.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | class BackdropCards extends React.Component{
5 | constructor(){
6 | super()
7 | this.state = {
8 | backdrop:[],
9 | backdropTv:[],
10 | dataMovie:[],
11 | dataTv:[],
12 | }
13 | }
14 |
15 | async componentDidMount() {
16 | try{
17 |
18 | const movieDetail = await fetch(
19 | `https://api.themoviedb.org/3/movie/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
20 | )
21 | const tvDetail = await fetch(
22 | `https://api.themoviedb.org/3/tv/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
23 | )
24 | const poster = await fetch(
25 | `https://api.themoviedb.org/3/movie/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
26 | )
27 | const tvPoster = await fetch(
28 | `https://api.themoviedb.org/3/tv/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
29 | )
30 |
31 | const posters = await poster.json()
32 | const backdropsTv = await tvPoster.json()
33 | const backdrops = posters.backdrops
34 | const backdropz = backdropsTv.backdrops
35 | const respon = await movieDetail.json()
36 | const responTv = await tvDetail.json()
37 | console.log(responTv);
38 | console.log(respon);
39 | if (posters) {
40 | this.setState({
41 | dataMovie:this.state.dataMovie = respon,
42 | dataTv:this.state.dataTv = responTv,
43 | backdrop:this.state.backdrop = backdrops,
44 | backdropTv:this.state.backdropTv = backdropz
45 | })
46 | }
47 | }catch(error){
48 | console.log(error);
49 | }
50 |
51 | }
52 |
53 | render(){
54 |
55 | const ID = this.state.dataTv.type ? `/tv-detail/${this.props.id}` : `/movie-detail/${this.props.id}`
56 | const date = this.state.dataTv.type ? new Date(this.state.dataTv.first_air_date) : new Date(this.state.dataMovie.release_date)
57 | console.log(this.state.dataMovie);
58 | return(
59 | <>
60 |
61 |
62 |
63 | {this.state.dataTv.type ?
64 | :
65 | }
66 |
67 | {this.state.dataTv.type ? <>
{this.state.dataTv.name} ({date.getFullYear()})
68 | Back> : <> {this.state.dataMovie.title} ({date.getFullYear()})
69 | Back>}
70 |
71 |
72 |
73 | {this.state.dataTv.type ? this.state.backdropTv.map(pos => {
74 | const img = `https://image.tmdb.org/t/p/original/${pos.file_path}`;
75 | return
76 |
77 |
78 |
Info
79 |
80 |
81 | Size
82 | {pos.height}x{pos.width}
83 |
84 |
85 |
86 |
87 | }) :
88 | this.state.backdrop.map(pos => {
89 | const img = `https://image.tmdb.org/t/p/original/${pos.file_path}`;
90 | return
91 |
92 |
93 |
Info
94 |
95 |
96 | Size
97 | {pos.height}x{pos.width}
98 |
99 |
100 |
101 |
102 | })
103 | }
104 | >
105 | )
106 | }
107 | }
108 |
109 | export default BackdropCards;
110 |
--------------------------------------------------------------------------------
/src/component/backdrop-page.js:
--------------------------------------------------------------------------------
1 |
2 | import React from "react";
3 | import { useParams } from "react-router-dom";
4 | import BackdropCards from "./backdrop-card";
5 |
6 | function BackdropPage (){
7 | const {id }= useParams()
8 | return(
9 |
10 |
11 |
12 | )
13 | }
14 |
15 | export default BackdropPage;
--------------------------------------------------------------------------------
/src/component/banner.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link} from 'react-router-dom'
3 | import SliderImage from './slider'
4 |
5 |
6 | class Banner extends React.Component{
7 | constructor(){
8 | super()
9 | this.state = {
10 | isLoad:true,
11 | movie:[],
12 | index:0,
13 | intervalId: setInterval(() => {},1000)
14 | }
15 | }
16 |
17 | async componentDidMount(){
18 | this.state.intervalId = setInterval(() => {
19 | this.setState({index:this.state.index + 1})
20 | return () => clearInterval(this.state.intervalId );
21 | }, 10000);
22 |
23 | const popular = await fetch(
24 | "https://api.themoviedb.org/3/movie/popular?api_key=0ccbee0a69447c2b1bd0090bf76b0358"
25 | )
26 | const respon = await popular.json()
27 | const movies = respon.results
28 | if(!Array.isArray(movies) || movies.length <= 0){
29 | return null;
30 | }
31 | if (respon) {
32 | this.setState(prev => {
33 | return{
34 | isLoad:prev.isLoad = false,
35 | movie:prev.movie = movies
36 | }
37 | })
38 | }
39 | }
40 |
41 | componentWillUnmount(){
42 | clearInterval(this.state.intervalId);
43 | }
44 |
45 | nextSlide = (e) => {
46 | e.preventDefault()
47 | const length = this.state.movie.length
48 | this.setState({index:this.state.index = this.state.index + 1})
49 | }
50 |
51 | prevSlide = (e) => {
52 | e.preventDefault()
53 | const length = this.state.movie.length
54 | this.setState({index:this.state.index = this.state.index - 1})
55 | }
56 |
57 | dotsClick = (e) => {
58 | const targets = parseFloat(e.target.dataset.length)
59 | console.log(targets);
60 | this.setState({index:this.state.index = targets})
61 | console.log(this.state.index);
62 | }
63 | render(){
64 | if (this.state.index > 19) {
65 | this.setState({index:this.state.index = 0})
66 | }
67 |
68 | const Slide = this.state.movie.map(m => {
69 | const dates = [new Date(m.release_date)]
70 | return
71 | })
72 | let length = -1;
73 |
74 | const dots = this.state.movie.map(m => {
75 | length++
76 | return
77 | })
78 | return(
79 |
87 |
88 | )
89 | }
90 | }
91 |
92 |
93 | export default Banner;
94 |
95 |
--------------------------------------------------------------------------------
/src/component/cast-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 |
4 | function CastCard (props){
5 |
6 | const ID = `/person-detail/${props.id}`
7 | return(
8 |
9 |
10 |
11 |
12 |
13 |
{props.name}
14 | {props.chara}
15 |
16 |
17 | )
18 | }
19 |
20 | export default CastCard;
21 |
22 |
--------------------------------------------------------------------------------
/src/component/cast-rekomend-card.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import CastCard from "./cast-card";
3 | import RecomCard from "./rekomen-card";
4 | import akun from '../akun.png'
5 | import ReviewCard from "./review-card";
6 | import { Link } from "react-router-dom";
7 | import MediaVideo from "./media-video";
8 | import MediaBackdrop from "./media-backgdrop";
9 | import MediaPoster from "./media-poster";
10 |
11 |
12 | class CastDanRekomen extends React.Component {
13 | constructor() {
14 | super()
15 | this.state = {
16 | cast: [],
17 | rekomen: [],
18 | loading: true,
19 | review: [],
20 | poster:[],
21 | backdrop:[],
22 | video:[],
23 | option:'Populer'
24 | }
25 | }
26 |
27 | async componentDidMount() {
28 | try{
29 | const poster = await fetch(
30 | `https://api.themoviedb.org/3/movie/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
31 | )
32 | if (!poster.ok) {
33 | throw Error(poster.statusText);
34 | }
35 | const rekomen = await fetch(
36 | `https://api.themoviedb.org/3/movie/${this.props.id}/recommendations?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
37 | )
38 | const Cast = await fetch(
39 | `https://api.themoviedb.org/3/movie/${this.props.id}/credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
40 | )
41 | const review = await fetch(
42 | `https://api.themoviedb.org/3/movie/${this.props.id}/reviews?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
43 | )
44 | const Video = await fetch(
45 | `https://api.themoviedb.org/3/movie/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
46 | )
47 |
48 |
49 | const videos = await Video.json()
50 | const posters = await poster.json()
51 | const vid = videos.results
52 | const castRes = await Cast.json();
53 | const rekRes = await rekomen.json();
54 | const revs = await review.json();
55 | const cazt = castRes.cast;
56 | const rec = rekRes.results;
57 | const revResults = revs.results;
58 | const posterz = posters.posters
59 | const backdrops = posters.backdrops
60 | console.log(posters);
61 | if (castRes) {
62 | this.setState((prev) => {
63 | return {
64 | loading: (prev.loading = false),
65 | cast: (prev.cast = cazt),
66 | rekomen: (prev.rekomen = rec),
67 | review: (prev.review = revResults),
68 | poster:prev.poster = posterz,
69 | backdrop:prev.backdrop = backdrops,
70 | video:prev.video = vid
71 | };
72 | });
73 | }
74 | }catch(error){
75 | console.log(error);
76 | }
77 |
78 | }
79 |
80 | async componentDidUpdate() {
81 | const rekomen = await fetch(
82 | `https://api.themoviedb.org/3/movie/${this.props.id}/recommendations?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
83 | );
84 | const Cast = await fetch(
85 | `https://api.themoviedb.org/3/movie/${this.props.id}/credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
86 | );
87 |
88 | const castRes = await Cast.json();
89 | const rekRes = await rekomen.json();
90 | const cazt = castRes.cast;
91 | const rec = rekRes.results;
92 | if (castRes) {
93 | this.setState((prev) => {
94 | return {
95 | loading: (prev.loading = false),
96 | cast: (prev.cast = cazt),
97 | rekomen: (prev.rekomen = rec),
98 | };
99 | });
100 | }
101 | }
102 |
103 | mediaClick = async (e) => {
104 | e.preventDefault()
105 | const id = e.target.dataset.id
106 |
107 | if (id === 'Trailer') {
108 | const Video = await fetch(
109 | `https://api.themoviedb.org/3/movie/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
110 | )
111 | const videos = await Video.json()
112 | const vid = videos.results
113 | if (videos) {
114 | this.setState({
115 | video:this.state.video = vid,
116 | option:this.state.option = id
117 | })
118 | }
119 | }
120 | if (id === 'Backdrop') {
121 | const poster = await fetch(
122 | `https://api.themoviedb.org/3/movie/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
123 | )
124 | const posters = await poster.json()
125 | const backdrops = posters.backdrops
126 | if (posters) {
127 | this.setState({
128 | backdrop:this.state.backdrop = backdrops,
129 | option:this.state.option = id
130 | })
131 | }
132 | }
133 | if (id === 'Poster') {
134 |
135 | const poster = await fetch(
136 | `https://api.themoviedb.org/3/movie/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
137 | )
138 | const posters = await poster.json()
139 | const posterz = posters.posters
140 | if (posters) {
141 | this.setState({
142 | poster:this.state.poster = posterz,
143 | option:this.state.option = id
144 | })
145 | }
146 | }
147 | }
148 |
149 | render() {
150 | const cast = this.state.cast.map((cazt) => {
151 | const imgUrl = `https://image.tmdb.org/t/p/w300/${cazt.profile_path}`;
152 | return (
153 |
160 | );
161 | });
162 |
163 | const Recomend = this.state.rekomen.map((rec) => {
164 | const imgUrl = `https://image.tmdb.org/t/p/w300/${rec.poster_path}`;
165 | return (
166 |
174 | );
175 | });
176 |
177 | const ReviewCards = this.state.review.slice(0,1).map((rev) => {
178 | const img = `https://image.tmdb.org/t/p/w185/${rev.author_details.avatar_path}`;
179 | return
180 | })
181 |
182 | const ID = `/review/${this.props.id}`
183 | const posterID = `/poster-page/${this.props.id}`
184 | const backID = `/backdrop-page/${this.props.id}`
185 | return (
186 | <>
187 | {this.state.loading ? (
188 |
189 |
190 |
191 |
192 |
193 | ) : (
194 | ""
195 | )}
196 |
197 |
Top Cast
198 |
{cast}
199 |
200 |
201 |
202 |
208 |
209 |
210 | {ReviewCards}
211 | 1 ?"load" : "hide"}>Load More
212 |
213 |
214 |
215 |
216 |
217 |
Media
218 |
219 |
241 | {this.state.option === "Backdrop" ?
242 | View All
243 |
: ""}
244 | {this.state.option === "Poster" ?
245 | View All
246 |
: ""}
247 |
248 |
249 |
250 |
251 |
252 |
253 | {this.state.option === "Populer" ? : ""}
254 | {this.state.option === "Trailer" ? : ""}
255 | {this.state.option === "Backdrop" ? : ""}
256 | {this.state.option === "Poster" ? : ""}
257 |
258 |
259 |
260 |
261 |
Recommendations
262 |
263 | {this.state.rekomen.length === 0
264 | ? "We don't have enough data to suggest about this Movie."
265 | : Recomend}
266 |
267 |
268 | >
269 | );
270 | }
271 | }
272 |
273 | export default CastDanRekomen;
274 |
--------------------------------------------------------------------------------
/src/component/cast-rekomend-tv.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom'
3 | import CastCard from './cast-card'
4 | import ReviewCard from './review-card'
5 | import TvRecomCard from './tv-recomend-card'
6 | import MediaVideo from "./media-video";
7 | import MediaBackdrop from "./media-backgdrop";
8 | import MediaPoster from "./media-poster";
9 |
10 |
11 | class CastDanRekomenTV extends React.Component{
12 | constructor(){
13 | super()
14 | this.state = {
15 | tvCast:[],
16 | tv:[],
17 | loading:true,
18 | review: [],
19 | poster:[],
20 | backdrop:[],
21 | video:[],
22 | option:'Populer'
23 | }
24 | }
25 |
26 | async componentDidMount() {
27 | try{
28 | const poster = await fetch(
29 | `https://api.themoviedb.org/3/tv/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
30 | )
31 | if (!poster.ok) {
32 | throw Error(poster.statusText);
33 | }
34 | const recTv = await fetch(
35 | `https://api.themoviedb.org/3/tv/${this.props.id}/recommendations?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
36 | )
37 | const CAST_TV = await fetch(
38 | `https://api.themoviedb.org/3/tv/${this.props.id}/credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
39 | )
40 | const review = await fetch(
41 | `https://api.themoviedb.org/3/tv/${this.props.id}/reviews?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
42 | )
43 | const Video = await fetch(
44 | `https://api.themoviedb.org/3/tv/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
45 | )
46 |
47 |
48 | const videos = await Video.json()
49 | const posters = await poster.json()
50 | const vid = videos.results
51 | const revs = await review.json();
52 | const castTv = await CAST_TV.json()
53 | const TvRes = await recTv.json()
54 | const tv = TvRes.results
55 | const caztTv = castTv.cast
56 | const revResults = revs.results;
57 | const posterz = posters.posters
58 | const backdrops = posters.backdrops
59 | if (TvRes) {
60 | this.setState((prev) => {
61 | return {
62 | loading: (prev.loading = false),
63 | tv:prev.tv = tv,
64 | tvCast:prev.tvCast = caztTv,
65 | review: (prev.review = revResults),
66 | poster:prev.poster = posterz,
67 | backdrop:prev.backdrop = backdrops,
68 | video:prev.video = vid
69 | };
70 | });
71 | }
72 | }catch(error){
73 | console.log(error);
74 | }
75 |
76 | }
77 |
78 | async componentDidUpdate() {
79 | const recTv = await fetch(
80 | `https://api.themoviedb.org/3/tv/${this.props.id}/recommendations?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
81 | )
82 | const CAST_TV = await fetch(
83 | `https://api.themoviedb.org/3/tv/${this.props.id}/credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
84 | )
85 | const castTv = await CAST_TV.json()
86 | const TvRes = await recTv.json()
87 | const tv = TvRes.results
88 | const caztTv = castTv.cast
89 | if (castTv) {
90 |
91 | this.setState(prev => {
92 | return{
93 | loading:prev.loading = false,
94 | tv:prev.tv = tv,
95 | tvCast:prev.tvCast = caztTv
96 | }
97 | })
98 | }
99 | }
100 |
101 | mediaClick = async (e) => {
102 | e.preventDefault()
103 | const id = e.target.dataset.id
104 |
105 | if (id === 'Trailer') {
106 | const Video = await fetch(
107 | `https://api.themoviedb.org/3/tv/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
108 | )
109 | const videos = await Video.json()
110 | const vid = videos.results
111 | if (videos) {
112 | this.setState({
113 | video:this.state.video = vid,
114 | option:this.state.option = id
115 | })
116 | }
117 | }
118 | if (id === 'Backdrop') {
119 | const poster = await fetch(
120 | `https://api.themoviedb.org/3/tv/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
121 | )
122 | const posters = await poster.json()
123 | const backdrops = posters.backdrops
124 | if (posters) {
125 | this.setState({
126 | backdrop:this.state.backdrop = backdrops,
127 | option:this.state.option = id
128 | })
129 | }
130 | }
131 | if (id === 'Poster') {
132 |
133 | const poster = await fetch(
134 | `https://api.themoviedb.org/3/tv/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
135 | )
136 | const posters = await poster.json()
137 | const posterz = posters.posters
138 | if (posters) {
139 | this.setState({
140 | poster:this.state.poster = posterz,
141 | option:this.state.option = id
142 | })
143 | }
144 | }
145 | }
146 |
147 | render(){
148 | const cast = this.state.tvCast.length === 0 ? "We don't have enough data Cast about this TV shows." : this.state.tvCast.map(cazt => {
149 | const imgUrl = `https://image.tmdb.org/t/p/w300/${cazt.profile_path}`
150 | return
151 | })
152 |
153 | const Recomend = this.state.tv.length === 0 ? "We don't have enough data to suggest suggest about this TV shows." : this.state.tv.map(rec => {
154 | const imgUrl = `https://image.tmdb.org/t/p/w300/${rec.poster_path}`
155 | return
156 | })
157 |
158 | const ReviewCards = this.state.review.slice(0,1).map((rev) => {
159 | const img = `https://image.tmdb.org/t/p/w185/${rev.author_details.avatar_path}`;
160 | return
161 | })
162 |
163 | const ID = `/review/${this.props.id}`
164 | const posterID = `/poster-page/${this.props.id}`
165 | const backID = `/backdrop-page/${this.props.id}`
166 | return(
167 | <>
168 | {this.state.loading ?
169 |
170 |
: ""}
171 |
172 |
Cast
173 |
174 | {cast}
175 |
176 |
177 |
178 |
179 |
183 |
184 | {this.state.review.length < 1 ? `We don't have any reviews for ${this.props.judul}.` : ReviewCards}
185 | 1 ?"load" : "hide"} >Load More
186 |
187 |
188 |
189 |
190 |
191 |
Media
192 |
193 |
215 | {this.state.option === "Backdrop" ?
216 | View All
217 |
: ""}
218 | {this.state.option === "Poster" ?
219 | View All
220 |
: ""}
221 |
222 |
223 |
224 |
225 |
226 | {this.state.option === "Populer" ? : ""}
227 | {this.state.option === "Trailer" ? : ""}
228 | {this.state.option === "Backdrop" ? : ""}
229 | {this.state.option === "Poster" ? : ""}
230 |
231 |
232 |
233 |
234 |
235 |
Recommendations
236 |
237 | {Recomend}
238 |
239 |
240 |
241 | >
242 | )
243 | }
244 | }
245 |
246 | export default CastDanRekomenTV;
--------------------------------------------------------------------------------
/src/component/footer.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import logo from '../tmdb-logo.svg';
3 | import github from '../github.png'
4 | function Footer(){
5 | return(
6 |
16 | )
17 | }
18 |
19 | export default Footer;
--------------------------------------------------------------------------------
/src/component/full.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/component/full.jpg
--------------------------------------------------------------------------------
/src/component/genre-content.js:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react'
3 | import { Link } from 'react-router-dom'
4 | import LeftSidebar from './left-sidebar';
5 | class GenreContent extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | result:[],
10 | tvRes:[],
11 | isLoad:true,
12 | pages:1,
13 | names:''
14 | }
15 | }
16 |
17 | async componentDidMount(){
18 | const movieGenre = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&with_genres=${this.props.id}`)
19 | const tvGenre = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&with_genres=${this.props.id}`)
20 |
21 | const searchResult = await movieGenre.json()
22 | const tvResult = await tvGenre.json()
23 | const results = searchResult.results
24 | if (searchResult) {
25 | this.setState(prev => {
26 | return{
27 | isLoad:prev.isLoad = false,
28 | result:prev.result = results,
29 | tvRes:prev.tvRes = tvResult.results
30 | }
31 | })
32 | }
33 |
34 | }
35 |
36 |
37 | async componentDidUpdate(){
38 | const pageResult = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&with_genres=${this.props.id}&page=${this.state.pages}`)
39 | const TvPage = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&with_genres=${this.props.id}&page=${this.state.pages}`)
40 | const tvJson = await TvPage.json()
41 | const pageJson = await pageResult.json()
42 | if (pageJson) {
43 | this.setState(prev => {
44 | return{
45 | isLoad:prev.isLoad = false,
46 | result:prev.result = pageJson.results,
47 | tvRes:prev.tvRes = tvJson.results
48 | }
49 | })
50 |
51 | }
52 |
53 | }
54 |
55 | clickFetch = async (e) => {
56 | const namae = e.target.textContent
57 | const movieGenre = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&with_genres=${this.props.id}`)
58 | const searchResult = await movieGenre.json()
59 | const results = searchResult.results
60 |
61 | if (searchResult) {
62 | this.setState(prev => {
63 | return{
64 | isLoad:prev.isLoad = false,
65 | result:prev.result = results,
66 | names:prev.names = namae
67 | }
68 | })
69 | }
70 | }
71 |
72 |
73 | paginationNext = async (e) => {
74 |
75 | this.setState({
76 | pages:this.state.page = this.state.pages + 1,
77 | isLoad:this.isLoad = true
78 | })
79 | }
80 |
81 | paginationPrev = async (e) => {
82 | this.setState({
83 | pages:this.state.page = this.state.pages - 1,
84 | isLoad:this.isLoad = true
85 | })
86 |
87 | }
88 |
89 | render(){
90 |
91 | return(
92 |
93 | {this.state.isLoad ?
94 |
95 |
: " "}
96 |
97 |
98 | {
99 | this.state.result.map(srch => {
100 | const img = `https://image.tmdb.org/t/p/w185/${srch.poster_path}`
101 | const ID = `/movie-detail/${srch.id}`
102 | return
103 |
104 |
105 |
106 |
107 |
108 |
{srch.title}
109 |
110 | {srch.release_date}
111 | {srch.overview}
112 |
113 |
114 | })
115 | }
116 |
117 | {
118 | this.state.tvRes.map(srch => {
119 | const img = `https://image.tmdb.org/t/p/w185/${srch.poster_path}`
120 | const ID = `/tv-detail/${srch.id}`
121 | return
122 |
123 |
124 |
125 |
126 |
127 |
{srch.name}
128 |
129 | {srch.first_air_date}
130 | {srch.overview}
131 |
132 |
133 | })
134 | }
135 | {this.state.isLoad ? "" :
136 | {this.state.pages > 1 ? Previous : ""}
137 | Next
138 |
}
139 |
140 |
141 |
142 |
143 | )
144 | }
145 | }
146 |
147 |
148 | export default GenreContent;
149 |
150 |
151 |
--------------------------------------------------------------------------------
/src/component/genre-page.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useLocation, useParams } from 'react-router-dom';
3 | import GenreContent from './genre-content';
4 | import LeftSidebar from './left-sidebar';
5 |
6 | function GenrePage(){
7 | const{ id}= useParams();
8 | const query = new URLSearchParams(useLocation().search)
9 | console.log(query);
10 | return(
11 |
12 | )
13 | }
14 |
15 | export default GenrePage;
--------------------------------------------------------------------------------
/src/component/header.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link} from 'react-router-dom'
3 | import '../header.css';
4 | import Banner from './banner'
5 | class Navbar extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | refs:React.createRef(),
10 | navbar:React.createRef(),
11 | y:window.scrollX,
12 | search:'',
13 | dropDown:true
14 | }
15 | }
16 |
17 | componentDidMount(){
18 | window.addEventListener('scroll',this.scrolls)
19 | }
20 |
21 | scrolls = (e) => {
22 | let x = window.scrollY;
23 | const header = this.state.refs.current
24 |
25 | if (x > this.state.y) {
26 | header.classList.add("fixed-header");
27 | }else {
28 | header.classList.remove("fixed-header");
29 | }
30 |
31 | this.setState({y:x})
32 | }
33 |
34 | handlerChange = (e) => {
35 | const {name,value} = e.target
36 | this.setState({
37 | search:value
38 | })
39 | }
40 |
41 | searchFetch = (e) => {
42 | e.preventDefault()
43 | const data = this.props.data
44 | this.setState(prev => {
45 | return{
46 | data:prev.search = this.state.search
47 | }
48 | })
49 | window.location.reload()
50 | }
51 |
52 | dropDown = (e) => {
53 | e.preventDefault()
54 | const showMenu = this.state.navbar.current
55 | showMenu.classList.toggle('opens')
56 | // console.log("Tes");
57 | // spin[i].classList.toggle('open')
58 | }
59 |
60 | render(){
61 | const ID = `/movie-search/${this.state.search}`
62 | return(
63 | <>
64 |
65 |
76 |
77 |
78 | Home
79 | Movie
80 | TV Series
81 | Anime
82 | People
83 |
86 |
87 |
88 |
92 |
93 |
94 |
95 | >
96 | )
97 | }
98 | }
99 |
100 | export default Navbar;
--------------------------------------------------------------------------------
/src/component/home.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Footer from './footer';
3 | import MovieContainer from './moviecontainer';
4 | import MovieDetail from './moviedetail';
5 | import Banner from './banner';
6 | import LeftSidebar from './left-sidebar';
7 |
8 |
9 |
10 | class Home extends React.Component{
11 |
12 | render(){
13 | return(
14 |
15 |
16 |
17 |
18 | )
19 | }
20 | }
21 |
22 | export default Home;
--------------------------------------------------------------------------------
/src/component/img/PngItem_6391407.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/component/img/PngItem_6391407.png
--------------------------------------------------------------------------------
/src/component/img/header.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {Link} from 'react-router-dom'
3 | import '../header.css';
4 | import logo from '../logos.png'
5 |
6 | class Header extends React.Component{
7 | constructor(){
8 | super()
9 | this.state = {
10 | search:'',
11 | srchValue:[]
12 | }
13 | }
14 |
15 | handlerChange = (e) => {
16 | const {name,value} = e.target
17 | this.setState({
18 | search:value
19 | })
20 | }
21 |
22 | searchFetch = (e) => {
23 | e.preventDefault()
24 | const data = this.props.data
25 | this.setState(prev => {
26 | return{
27 | data:prev.search = this.state.search
28 | }
29 | })
30 | window.location.reload()
31 | }
32 |
33 |
34 | render(){
35 | const ID = `/movie-search/${this.state.search}`
36 | return(
37 | <>
38 |
39 |
40 |
41 |
45 |
51 |
52 |
53 |
54 | >
55 | )
56 | }
57 | }
58 |
59 | export default Header;
--------------------------------------------------------------------------------
/src/component/left-sidebar.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom'
3 | import TrendingCard from './trending-card'
4 |
5 |
6 | class LeftSidebar extends React.Component{
7 | constructor(){
8 | super()
9 | this.state ={
10 | option:'day',
11 | search:'',
12 | srchValue:[],
13 | genre:[],
14 | tvGenres:[],
15 | trending:[]
16 | }
17 | }
18 |
19 | async componentDidMount(){
20 | const genreRes = await fetch("https://api.themoviedb.org/3/genre/movie/list?api_key=0ccbee0a69447c2b1bd0090bf76b0358")
21 | const genreTv = await fetch("https://api.themoviedb.org/3/genre/tv/list?api_key=0ccbee0a69447c2b1bd0090bf76b0358")
22 | const trending = await fetch(
23 | "https://api.themoviedb.org/3/trending/tv/day?api_key=0ccbee0a69447c2b1bd0090bf76b0358"
24 | )
25 | const trendRes = await trending.json()
26 | const tvGenre = await genreTv.json()
27 | const genrez = await genreRes.json()
28 | if(genrez){
29 | const trends = []
30 | for (let i = 0; i < 10; i++) {
31 | trends.push(trendRes.results[i])
32 | }
33 | this.setState(prev => {
34 | return{
35 | genre:prev.genre = genrez.genres,
36 | tvGenres:prev.tvGenres = tvGenre.genres,
37 | trending:prev.trending = trends
38 | }
39 | })
40 | }
41 | }
42 |
43 |
44 | trendingClick = async (e) => {
45 | e.preventDefault()
46 | const id = e.target.dataset.id
47 | const trending = await fetch(
48 | ` https://api.themoviedb.org/3/trending/tv/${id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
49 | )
50 | const trendRes = await trending.json()
51 | if (trendRes) {
52 | const trends = []
53 | for (let i = 0; i < 10; i++) {
54 | trends.push(trendRes.results[i])
55 | }
56 | this.setState({trending:trends,option:id})
57 | this.setState({ trending:trends,option:id})
58 | }
59 | }
60 |
61 |
62 | render(){
63 |
64 | let length = 1
65 | const trending = this.state.trending.map(tren => {
66 | const dates = [new Date(tren.first_air_date)]
67 | return
68 | })
69 | const ID = `/movie-search/${this.state.search}`
70 | return(
71 |
72 |
73 |
Trending
74 |
80 |
81 | {trending }
82 |
83 |
84 |
85 |
Genre
86 |
87 | {
88 | this.state.genre.map(gen => {
89 | const genId = `/genre/${gen.id}`
90 | return {gen.name}
91 | })
92 | }
93 | {
94 | this.state.tvGenres.map(gen => {
95 | const genId = `/genre/${gen.id}`
96 | return {gen.name}
97 | })
98 | }
99 |
100 |
101 |
102 |
103 | )
104 | }
105 | }
106 |
107 | export default LeftSidebar;
--------------------------------------------------------------------------------
/src/component/media-backgdrop.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function MediaBackdrop(props){
4 |
5 | return(
6 | props.poster.length < 1 ? `We don't have any backdrop for ${props.judul}.`: props.poster.slice(0,20).map(pos => {
7 | const img = `https://image.tmdb.org/t/p/w500/${pos.file_path}`;
8 | return
9 |
10 |
11 | })
12 | )
13 | }
14 |
15 | export default MediaBackdrop;
--------------------------------------------------------------------------------
/src/component/media-poster.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function MediaPoster(props){
4 | return(
5 | props.poster.length < 1 ? `We don't have any backdrop for ${props.judul}.`: props.poster.slice(0,20).map(pos => {
6 | const img = `https://image.tmdb.org/t/p/w500/${pos.file_path}`;
7 | return
8 |
9 |
10 | })
11 | )
12 | }
13 |
14 | export default MediaPoster;
--------------------------------------------------------------------------------
/src/component/media-video.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Logo from './img/PngItem_6391407.png'
3 |
4 | function MediaVideo(props){
5 |
6 | return(
7 | props.video.map(m => {
8 | const img = `http://i3.ytimg.com/vi/${m.key}/hqdefault.jpg`
9 | return
10 |
11 |
12 |
13 |
14 |
15 | })
16 | )
17 |
18 | }
19 |
20 | export default MediaVideo;
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/component/modal-item.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function ModalItem(props){
4 |
5 | return(
6 |
7 |
8 |
9 |
12 |
13 | )
14 | }
15 |
16 |
17 | export default ModalItem;
--------------------------------------------------------------------------------
/src/component/modal-video.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function ModalVideo(props) {
4 | const url = `https://www.youtube.com/embed/${props.VideoKey}`
5 |
6 | return(
7 |
12 | )
13 | }
14 |
15 | export default ModalVideo;
--------------------------------------------------------------------------------
/src/component/movie-all.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import LeftSidebar from "./left-sidebar";
3 | import MovieCard from "./moviecard";
4 |
5 | class MoviesPage extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | movie:[],
10 | tivi:[],
11 | loading:true,
12 | pages:1
13 | }
14 | }
15 |
16 | async componentDidMount(){
17 | const stream = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
18 |
19 | const streamTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
20 | const tvRes = await streamTv.json()
21 | const movieRes = await stream.json()
22 | if(movieRes ){
23 | this.setState(prev => {
24 | return{
25 | movie:prev.movie = movieRes.results,
26 | tivi:prev.tivi = tvRes.results,
27 | loading:prev.loading = false
28 | }
29 | })
30 | }
31 | }
32 |
33 | async componentDidUpdate(){
34 | const stream = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate&page=${this.state.pages}`)
35 |
36 | const streamTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate&page=${this.state.pages}`)
37 | const tvRes = await streamTv.json()
38 | const movieRes = await stream.json()
39 | if(movieRes ){
40 | this.setState(prev => {
41 | return{
42 | movie:prev.movie = movieRes.results,
43 | tivi:prev.tivi = tvRes.results,
44 | loading:prev.loading = false
45 | }
46 | })
47 | }
48 | }
49 |
50 | paginationNext = async (e) => {
51 |
52 | this.setState({
53 | pages:this.state.page = this.state.pages + 1,
54 | loading:this.loading = true
55 | })
56 | }
57 |
58 | paginationPrev = async (e) => {
59 | this.setState({
60 | pages:this.state.page = this.state.pages - 1,
61 | loading:this.loading = true
62 | })
63 |
64 | }
65 | render(){
66 | const movies = this.state.movie.length < 1 ? "" : this.state.movie.map(m => {
67 | const date = new Date(m.release_date);
68 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={date} />
69 | })
70 |
71 | const tivis = this.state.tivi.length < 1 ? "" : this.state.tivi.map(m => {
72 | const dates = new Date(m.first_air_date);
73 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={dates} />
74 | })
75 |
76 | return(
77 |
78 |
79 | {this.state.loading ?
80 |
81 |
: " "}
82 | {movies}
83 | {tivis}
84 | {this.state.loading ? "" :
85 | {this.state.pages > 1 ? Previous : ""}
86 | Next
87 |
}
88 |
89 |
90 |
91 | )
92 | }
93 | }
94 |
95 | export default MoviesPage;
--------------------------------------------------------------------------------
/src/component/movie-detail-card.js:
--------------------------------------------------------------------------------
1 | import { Link } from 'react-router-dom';
2 | import React from 'react'
3 | import '../detail.css';
4 | import star from '../star.png'
5 | import ModalVideo from './modal-video';
6 | import Logo from './img/PngItem_6391407.png'
7 | import CastDanRekomen from './cast-rekomend-card';
8 |
9 | class MovieDetailCard extends React.Component{
10 | constructor(){
11 | super()
12 | this.state = {
13 | data:[],
14 | genre:[],
15 | video:[],
16 | videoSrc:'',
17 | modal:false
18 | }
19 | }
20 |
21 |
22 | async componentDidMount(){
23 | const movieDetail = await fetch(
24 | `https://api.themoviedb.org/3/movie/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
25 | )
26 | const Video = await fetch(
27 | `https://api.themoviedb.org/3/movie/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
28 | )
29 |
30 | const videos = await Video.json()
31 | const vid = videos.results[0]
32 | const respon = await movieDetail.json()
33 | console.log(videos);
34 | if (respon) {
35 | this.setState(prev => {
36 | return{
37 | data:prev.data = respon,
38 | genre:prev.data = respon.genres,
39 | video:prev.video = vid
40 | }
41 | })
42 | }
43 |
44 | }
45 |
46 | playVideo = (e) => {
47 | e.preventDefault()
48 | const id = e.target.dataset.mykey
49 | this.setState({
50 | videoSrc:this.state.videoSrc = id,
51 | modal:!this.state.modal
52 | })
53 | console.log(this.state.modal);
54 | }
55 |
56 | removeModal = (e) =>{
57 | e.preventDefault()
58 | this.setState({ modal:!this.state.modal})
59 | }
60 | render(){
61 | const movi = this.state.data
62 | console.log(movi);
63 | const styles = {
64 | backgroundImage: `url(https://image.tmdb.org/t/p/w1280/${movi.backdrop_path})`
65 | }
66 |
67 | const imgUrl = `https://image.tmdb.org/t/p/w300/${movi.poster_path}`
68 | const maps = this.state.genre.map(gen => {
69 | const ID = `/genre/${gen.id}`
70 | return {gen.name} ,
71 | });
72 | console.log(this.state.video);
73 | return(
74 | <>
75 |
76 |
77 |
78 |
79 |
80 |
{movi.title}
81 |
{movi.tagline}
82 |
Genres: {maps}
83 |
84 |
85 |
86 |
{movi.vote_average}
87 |
88 |
91 |
92 |
Runtime: {movi.runtime}m
93 |
Status: {movi.status}
94 |
Release Date: {movi.release_date}
95 |
96 |
Overview
97 |
{movi.overview}
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | {this.state.modal ? : ""}
107 |
108 |
109 |
110 |
111 | >
112 | )
113 | }
114 | }
115 |
116 | export default MovieDetailCard;
117 |
118 |
119 |
--------------------------------------------------------------------------------
/src/component/moviecard.js:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react'
3 | import { Link } from 'react-router-dom';
4 |
5 |
6 | class MovieCard extends React.Component{
7 |
8 | render(){
9 |
10 | const url = `https://image.tmdb.org/t/p/w185/${this.props.img}`
11 | const ID = this.props.data.title ? `/movie-detail/${this.props.id}` : `/tv-detail/${this.props.id}`
12 | const month = [
13 | "Jan",
14 | "Feb",
15 | "Mar",
16 | "Apr",
17 | "May",
18 | "June",
19 | "July",
20 | "Aug",
21 | "Sept",
22 | "Oct",
23 | "Nov",
24 | "Dec",
25 | ];
26 | const date = this.props.Date
27 | const dates = new Date(this.props.data.first_air_date)
28 |
29 | const style = {
30 | transform:`translateX(-${this.props.index * 100}%)`
31 | }
32 |
33 | return(
34 |
35 |
36 |
37 |
38 |
39 |
40 |
{this.props.data.title}
41 | {this.props.data.name}
42 |
43 |
44 | { this.props.data.title ? {`${month[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} `} :
45 | {`${month[dates.getMonth()]} ${dates.getDate()} ${dates.getFullYear()} `} }
46 |
47 |
48 |
49 |
50 | )
51 | }
52 | }
53 |
54 | export default MovieCard;
55 |
56 |
57 | {/*
58 |
59 | {this.props.data.title ?
{this.props.data.title} :
60 | {this.props.data.name} }
61 |
62 |
63 | { this.props.data.title ? {`${month[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} `} :
64 | {`${month[dates.getMonth()]} ${dates.getDate()} ${dates.getFullYear()} `} }
65 |
66 | */}
--------------------------------------------------------------------------------
/src/component/moviecontainer.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 | import Banner from './banner';
4 | import ModalVideo from './modal-video';
5 | import MovieCard from './moviecard';
6 | import VideoCard from './video-card';
7 |
8 |
9 | class MovieContainer extends React.Component{
10 | constructor(){
11 | super()
12 | this.state = {
13 | movie:[],
14 | tivi:[],
15 | aniTv:[],
16 | aniMovi:[],
17 | option:'Streaming',
18 | index:0,
19 | indexVid:0,
20 | loading:true,
21 | modal:false,
22 | videoSrc:'',
23 | pages:1
24 | }
25 | }
26 |
27 | async componentDidMount(){
28 | const animeTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
29 |
30 | const animeMovie = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
31 |
32 | const aniMovRes = await animeMovie.json()
33 | const aniTvRes = await animeTv.json()
34 | const stream = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
35 | const streamTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
36 | const tvRes = await streamTv.json()
37 | const movieRes = await stream.json()
38 | if(movieRes ){
39 | this.setState(prev => {
40 | return{
41 | movie:prev.movie = movieRes.results,
42 | tivi:prev.tivi = tvRes.results,
43 | loading:prev.loading = false,
44 | aniMovi:prev.aniMovi = aniMovRes.results,
45 | aniTv:prev.aniTv = aniTvRes.results
46 | }
47 | })
48 | }
49 | }
50 |
51 | async componentDidUpdate(){
52 | const animeTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
53 |
54 | const animeMovie = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&language=en-US&sort_by=popularity.desc&page=${this.state.pages}&with_keywords=210024|222243`)
55 |
56 | const aniMovRes = await animeMovie.json()
57 | const aniTvRes = await animeTv.json()
58 | if(aniMovRes){
59 | this.setState(prev => {
60 | return{
61 | aniMovi:prev.aniMovi = aniMovRes.results,
62 | aniTv:prev.aniTv = aniTvRes.results,
63 | loading:prev.loading = false
64 | }
65 | })
66 | }
67 | }
68 |
69 | nextSlide = (e) => {
70 | e.preventDefault()
71 | this.setState({index:this.state.index = this.state.index + 1})
72 | }
73 |
74 | prevSlide = (e) => {
75 | e.preventDefault()
76 | this.setState({index:this.state.index = this.state.index - 1})
77 | }
78 |
79 | nextSlideVid = (e) => {
80 | e.preventDefault()
81 | this.setState({indexVid :this.state.indexVid = this.state.indexVid + 1})
82 | console.log(this.state.indexVid );
83 | }
84 |
85 | prevSlideVid = (e) => {
86 | e.preventDefault()
87 | this.setState({indexVid:this.state.indexVid = this.state.indexVid - 1})
88 | }
89 |
90 |
91 | clickOption = async (e) => {
92 | e.preventDefault()
93 | const id = e.target.dataset.id
94 | if (id === 'Streaming') {
95 | const stream = await fetch(`https://api.themoviedb.org/3/discover/movie?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
96 |
97 | const streamTv = await fetch(`https://api.themoviedb.org/3/discover/tv?api_key=0ccbee0a69447c2b1bd0090bf76b0358&watch_region=US&with_watch_monetization_types=flatrate`)
98 | const tvRes = await streamTv.json()
99 | const movieRes = await stream.json()
100 | if(movieRes){
101 | this.setState(prev => {
102 | return{
103 | option:prev.option = id,
104 | movie:prev.movie = movieRes.results,
105 | tivi:prev.tivi = tvRes.results
106 | }
107 | })
108 |
109 | }
110 | }else{
111 | const opt = await fetch(
112 | `https://api.themoviedb.org/3/discover/${id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358®ion=ID&with_release_type=3|2`
113 | )
114 |
115 | const result = await opt.json()
116 | if(result){
117 | this.setState({
118 | option:this.state.option = id,
119 | movie:this.state.movie = result.results,
120 | tivi:this.state.tivi = ''
121 | })
122 |
123 | }
124 | }
125 |
126 | }
127 |
128 | playVideo = (e) => {
129 | e.preventDefault()
130 | const id = e.target.dataset.mykey
131 | this.setState({
132 | videoSrc:this.state.videoSrc = id,
133 | modal:!this.state.modal
134 | })
135 | console.log(this.state.modal);
136 | }
137 |
138 | removeModal = (e) =>{
139 | e.preventDefault()
140 | this.setState({ modal:!this.state.modal})
141 | }
142 |
143 | paginationNext = async (e) => {
144 |
145 | this.setState({
146 | pages:this.state.page = this.state.pages + 1,
147 | loading:this.loading = true
148 | })
149 | }
150 |
151 | paginationPrev = async (e) => {
152 | this.setState({
153 | pages:this.state.page = this.state.pages - 1,
154 | loading:this.loading = true
155 | })
156 |
157 | }
158 |
159 | render(){
160 |
161 | const movies = this.state.movie.length < 1 ? "" : this.state.movie.map(m => {
162 | const date = new Date(m.release_date);
163 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={date} />
164 | })
165 |
166 | const tivis = this.state.tivi.length < 1 ? "" : this.state.tivi.map(m => {
167 |
168 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} />
169 | })
170 |
171 | const Videos = this.state.movie.map(m => {
172 | return
173 | })
174 |
175 | const animMovi = this.state.aniMovi.length < 1 ? "" : this.state.aniMovi.slice(0,10).map(m => {
176 | const date = new Date(m.release_date);
177 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={date} />
178 | })
179 |
180 | const animTv = this.state.aniTv.length < 1 ? "" : this.state.aniTv.slice(0,10).map(m => {
181 | const dates = new Date(m.first_air_date);
182 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={dates} />
183 | })
184 |
185 |
186 | return(
187 |
188 |
193 |
194 |
195 |
196 |
Popular
197 |
202 |
203 |
204 | {movies}
205 | {tivis}
206 |
207 |
211 |
212 |
213 |
214 |
Trailer
215 |
216 | {Videos}
217 |
218 |
222 |
223 |
224 | {this.state.modal ? : ""}
225 |
226 |
227 |
228 | {this.state.loading ?
: " "}
229 |
230 |
Anime
231 | View All
232 |
233 |
234 | {animMovi}
235 | {animTv}
236 | {this.state.loading ? "" :
237 | {this.state.pages > 1 ? Previous : ""}
238 | Next
239 |
}
240 |
241 |
242 |
243 |
244 | )
245 | }
246 | }
247 |
248 | export default MovieContainer;
--------------------------------------------------------------------------------
/src/component/moviedetail.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react'
2 | import { useLocation, useParams } from 'react-router-dom'
3 | import MovieDetailCard from './movie-detail-card'
4 | import CastDanRekomen from './cast-rekomend-card'
5 | import Footer from './footer'
6 | import { useNavigate } from 'react-router-dom';
7 |
8 | function MovieDetail () {
9 |
10 | const{ id }= useParams();
11 | // console.log(useLocation());
12 | const navigate = useNavigate();
13 | console.log(id);
14 |
15 | useEffect(() => {
16 |
17 | if (id.length == 0) {
18 | navigate('/')
19 | console.log("tes");
20 | }else{
21 | console.log("do nothing");
22 | }
23 | },[id,navigate])
24 | return(
25 | <>
26 |
27 | >
28 | )
29 | }
30 |
31 | export default MovieDetail;
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/component/people-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ModalItem from './modal-item';
3 | import PeopleCredits from './people-movie-credit';
4 | import ProfileCard from './profile-card';
5 |
6 | class PeopleCard extends React.Component{
7 | constructor(){
8 | super()
9 | this.state = {
10 | loading:true,
11 | people:[],
12 | modal:false,
13 | image:''
14 | }
15 | }
16 |
17 | async componentDidMount(){
18 | const people = await fetch(
19 | `https://api.themoviedb.org/3/person/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
20 | );
21 | const peopleRes = await people.json()
22 | if(peopleRes){
23 | this.setState(prev => {
24 | return{
25 | loading:prev.loading = false,
26 | people:prev.people = peopleRes
27 | }
28 | })
29 | }
30 |
31 | }
32 |
33 | modalClick = (e) => {
34 | e.preventDefault()
35 | this.setState({
36 | modal:!this.state.modal,
37 | image:this.state.image = e.target.src
38 | })
39 | console.log(this.state.modal);
40 | console.log(e.target.src);
41 | }
42 |
43 | removeModal = (e) => {
44 | this.setState({
45 | modal:false
46 | })
47 |
48 | }
49 | render(){
50 |
51 | return(
52 |
53 |
54 | {this.state.loading ?
55 |
56 |
: ""
57 | }
58 |
61 |
62 |
63 | {/*
*/}
64 |
65 | {this.state.people.name}
66 |
67 |
Biography
68 |
{this.state.people.biography}
69 |
70 |
71 |
72 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | {this.state.modal ? : ""}
83 |
84 |
85 |
86 | )
87 | }
88 | }
89 |
90 | export default PeopleCard;
--------------------------------------------------------------------------------
/src/component/people-detail.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useParams } from 'react-router-dom'
3 | import PeopleCard from './people-card'
4 |
5 | function PeopleDetail(){
6 | const {id} = useParams()
7 |
8 | return(
9 |
10 |
11 | )
12 | }
13 |
14 | export default PeopleDetail;
--------------------------------------------------------------------------------
/src/component/people-movie-credit.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 |
4 | class PeopleCredits extends React.Component{
5 | constructor(){
6 | super()
7 | this.state = {
8 | movie:[],
9 | tivi:[],
10 | loading:true
11 | }
12 | }
13 |
14 | async componentDidMount(){
15 | const credits = await fetch(
16 | `https://api.themoviedb.org/3/person/${this.props.id}/movie_credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
17 | );
18 | const creditsTV = await fetch(
19 | `https://api.themoviedb.org/3/person/${this.props.id}/tv_credits?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
20 | );
21 | const result = await credits.json()
22 | const cast = result.cast
23 | const TV = await creditsTV.json()
24 | const TVcast = TV.cast
25 | if( result ){
26 |
27 | this.setState(prev => {
28 | return{
29 | loading:prev.loading = false,
30 | movie:prev.movie = cast,
31 | tivi:prev.tivi = TVcast
32 | }
33 | })
34 |
35 | }
36 |
37 | }
38 |
39 | render(){
40 |
41 | return(
42 | <>
43 | {
44 | this.state.movie.slice(0, 8).map(mov => {
45 | const img = `https://image.tmdb.org/t/p/w185/${mov.poster_path}`
46 | const ID = `/movie-detail/${mov.id}`
47 | return
48 |
49 |
50 |
51 |
52 |
{mov.title}
53 |
{mov.release_date}
54 |
55 |
56 | })
57 | }
58 |
59 | {
60 | this.state.tivi.slice(0, 7).map(mov => {
61 | const img = `https://image.tmdb.org/t/p/w185/${mov.poster_path}`
62 | const ID = `/tv-detail/${mov.id}`
63 |
64 | return
65 |
66 |
67 |
68 |
69 |
{mov.name}
70 |
{mov.first_air_date}
71 |
72 |
73 | })
74 | }
75 | >
76 | )
77 | }
78 | }
79 |
80 | export default PeopleCredits;
--------------------------------------------------------------------------------
/src/component/popular-people.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom'
3 |
4 | class PopularPeople extends React.Component{
5 | constructor(){
6 | super()
7 | this.state ={
8 | loading:true,
9 | people:[],
10 | pages:1
11 | }
12 | }
13 |
14 | async componentDidMount(){
15 | const peopleRes = await fetch(
16 | `https://api.themoviedb.org/3/person/popular?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
17 | )
18 |
19 | const result = await peopleRes.json()
20 | const results = result.results
21 | if(results){
22 | this.setState(prev => {
23 | return{
24 | loading:prev.loading = false,
25 | people:prev.people = results
26 | }
27 | })
28 | }
29 | }
30 |
31 | async componentDidUpdate(){
32 | const peopleRes = await fetch(
33 | `https://api.themoviedb.org/3/person/popular?api_key=0ccbee0a69447c2b1bd0090bf76b0358&page=${this.state.pages}`
34 | )
35 |
36 | const result = await peopleRes.json()
37 | const results = result.results
38 | if(results){
39 | this.setState(prev => {
40 | return{
41 | loading:prev.loading = false,
42 | people:prev.people = results
43 | }
44 | })
45 | }
46 | }
47 |
48 | paginationNext = async (e) => {
49 |
50 | this.setState({
51 | pages:this.state.page = this.state.pages + 1,
52 | loading:this.state.loading = true
53 | })
54 | }
55 |
56 | paginationPrev = async (e) => {
57 | this.setState({
58 | pages:this.state.page = this.state.pages - 1,
59 | loading:this.state.loading = true
60 | })
61 |
62 | }
63 |
64 | render(){
65 | return(
66 |
67 |
68 |
69 |
Popular People
70 |
71 | {this.state.loading ?
72 |
73 |
: " "}
74 | {this.state.people.map(ppl => {
75 | const ID = `/person-detail/${ppl.id}`
76 | const img = `https://image.tmdb.org/t/p/w300/${ppl.profile_path}`
77 | return
78 |
79 |
80 |
81 |
82 |
{ppl.name}
83 |
84 |
85 |
86 | })}
87 |
88 |
89 | {this.state.pages > 1 ? Previous : ""}
90 | Next
91 |
92 |
93 |
94 | )
95 | }
96 | }
97 |
98 | export default PopularPeople;
--------------------------------------------------------------------------------
/src/component/poster-card.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | class PosterCards extends React.Component{
5 | constructor(){
6 | super()
7 | this.state = {
8 | poster:[],
9 | posterTv:[],
10 | data:[],
11 | dataTv:[],
12 | }
13 | }
14 |
15 | async componentDidMount() {
16 | try{
17 |
18 | const movieDetail = await fetch(
19 | `https://api.themoviedb.org/3/movie/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
20 | )
21 | const tvDetail = await fetch(
22 | `https://api.themoviedb.org/3/tv/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
23 | )
24 | const poster = await fetch(
25 | `https://api.themoviedb.org/3/movie/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
26 | )
27 | const tvPoster = await fetch(
28 | `https://api.themoviedb.org/3/tv/${this.props.id}/images?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
29 | )
30 |
31 | const posters = await poster.json()
32 | const posTv = await tvPoster.json()
33 | const posterz = posters.posters
34 | const PostersTv = posTv.posters
35 | const respon = await movieDetail.json()
36 | const responTv = await tvDetail.json()
37 | console.log(responTv);
38 | console.log(respon);
39 | if (posters) {
40 | this.setState({
41 | data:this.state.data = respon,
42 | dataTv:this.state.dataTv = responTv,
43 | poster:this.state.poster = posterz,
44 | posterTv:this.state.posterTv = PostersTv
45 | })
46 |
47 | }
48 | }catch(error){
49 | console.log(error);
50 | }
51 |
52 | }
53 |
54 | render(){
55 | const ID = this.state.dataTv.type ? `/tv-detail/${this.props.id}` : `/movie-detail/${this.props.id}`
56 | const date = this.state.dataTv.type ? new Date(this.state.dataTv.first_air_date) : new Date(this.state.data.release_date)
57 |
58 | return(
59 | <>
60 |
61 |
62 |
63 | {this.state.dataTv.type ?
64 | :
65 | }
66 |
67 | {this.state.dataTv.type ? <>
{this.state.dataTv.name} ({date.getFullYear()})
68 | Back> : <> {this.state.data.title} ({date.getFullYear()})
69 | Back>}
70 |
71 |
72 |
73 | {this.state.dataTv.type ? this.state.posterTv.map(pos => {
74 | const img = `https://image.tmdb.org/t/p/original/${pos.file_path}`;
75 | return
76 |
77 |
78 |
Info
79 |
80 |
81 | Size
82 | {pos.height}x{pos.width}
83 |
84 |
85 |
86 |
87 | }) : this.state.poster.map(pos => {
88 | const img = `https://image.tmdb.org/t/p/original/${pos.file_path}`;
89 | return
90 |
91 |
92 |
Info
93 |
94 |
95 | Size
96 | {pos.height}x{pos.width}
97 |
98 |
99 |
100 |
101 | })
102 |
103 | }
104 |
105 | >
106 | )
107 | }
108 | }
109 |
110 | export default PosterCards;
111 |
--------------------------------------------------------------------------------
/src/component/poster-page.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useParams } from "react-router-dom";
3 | import PosterCards from "./poster-card";
4 |
5 | function PosterPage (){
6 | const {id }= useParams()
7 | return(
8 |
11 | )
12 | }
13 |
14 | export default PosterPage;
--------------------------------------------------------------------------------
/src/component/profile-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function ProfileCard(props){
4 |
5 | const img = `https://image.tmdb.org/t/p/h632/${props.profil.profile_path}`
6 | const waktu = new Date(props.profil.birthday);
7 | const today = new Date();
8 | const todayY = today.getFullYear();
9 | const birthY = waktu.getFullYear();
10 | const alias = [...new Set(props.alias)];
11 | return(
12 | <>
13 |
14 |
15 |
16 |
17 | Personal Info
18 |
19 |
20 |
Known For
21 |
{props.profil.known_for_department}
22 |
23 |
24 |
Gender
25 |
{props.profil.gender > 1 ? "Male" : "Female"}
26 |
27 |
28 |
Birthday
29 |
{props.profil.birthday} ({todayY - birthY - 1} years old)
30 |
31 |
32 |
Place of birth
33 |
{props.profil.place_of_birth}
34 |
35 |
36 |
37 | {alias.length == 0 ? "" :
Also Known As
}
38 |
39 | {alias.map(name => {
40 | return
{name}
41 | })}
42 |
43 |
44 |
45 |
46 |
47 | >
48 | )
49 | }
50 |
51 | export default ProfileCard;
--------------------------------------------------------------------------------
/src/component/rekomen-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 | function RecomCard (props){
4 | const ID = `/movie-detail/${props.id}`
5 | return(
6 |
7 |
8 |
9 |
10 |
11 |
{props.name}
12 | {props.date}
13 |
14 |
15 | )
16 | }
17 |
18 | export default RecomCard;
19 |
20 |
--------------------------------------------------------------------------------
/src/component/review-card.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import akun from '../akun.png'
3 |
4 | function ReviewCard(props){
5 |
6 | const img = `https://image.tmdb.org/t/p/w185/${props.data.author_details.avatar_path}`;
7 | return(
8 |
9 |
10 |
11 |
12 |
13 |
Review by {props.data.author_details.username}
14 |
Written by {props.data.author_details.username} {props.data.created_at}
15 |
16 | {/*
{props.data.content}
*/}
17 |
{props.data.content}
18 |
19 |
20 |
21 | )
22 | }
23 |
24 | export default ReviewCard;
--------------------------------------------------------------------------------
/src/component/review-page.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useLocation, useParams } from 'react-router-dom'
3 | import Review from './review';
4 |
5 | function ReviewPage() {
6 |
7 | const{ id }= useParams();
8 | return(
9 | <>
10 |
11 | >
12 | )
13 | }
14 |
15 | export default ReviewPage;
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/component/review.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReviewCard from "./review-card";
3 |
4 | class Review extends React.Component{
5 | constructor() {
6 | super();
7 | this.state = {
8 | review: []
9 | };
10 | }
11 |
12 | async componentDidMount() {
13 |
14 | const review = await fetch(
15 | `https://api.themoviedb.org/3/movie/${this.props.id}/reviews?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
16 | );
17 |
18 | const revs = await review.json();
19 | const revResults = revs.results;
20 | if (revs) {
21 | this.setState({review:this.state.review = revResults})
22 | }
23 | }
24 |
25 | render(){
26 | return(
27 |
28 |
29 |
30 |
31 | {this.state.review.map((rev) => {
32 |
33 | const img = `https://image.tmdb.org/t/p/w185/${rev.author_details.avatar_path}`;
34 | return
35 | })}
36 |
37 |
38 | )
39 | }
40 | }
41 |
42 | export default Review;
--------------------------------------------------------------------------------
/src/component/search-content.js:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react'
3 | import { Link } from 'react-router-dom'
4 | import LeftSidebar from './left-sidebar'
5 | import empty from '../empty.png'
6 |
7 | class SearchContent extends React.Component{
8 | constructor(){
9 | super()
10 | this.state = {
11 | search:[],
12 | isLoad:true,
13 | pages:1
14 | }
15 | }
16 |
17 | async componentDidMount(){
18 |
19 | const srch = await fetch(
20 | `https://api.themoviedb.org/3/search/multi?api_key=0ccbee0a69447c2b1bd0090bf76b0358&query=${this.props.id}`
21 | )
22 | const searchResult = await srch.json()
23 | const results = searchResult.results
24 | if (searchResult) {
25 | this.setState(prev => {
26 | return{
27 | isLoad:prev.isLoad = false,
28 | search:prev.search = results
29 | }
30 | })
31 | }
32 |
33 | }
34 |
35 | async componentDidUpdate(){
36 |
37 | const srch = await fetch(
38 | `https://api.themoviedb.org/3/search/multi?api_key=0ccbee0a69447c2b1bd0090bf76b0358&query=${this.props.id}`
39 | )
40 | const searchPage = await fetch(`https://api.themoviedb.org/3/search/multi?api_key=0ccbee0a69447c2b1bd0090bf76b0358&query=${this.props.id}&page=${this.state.pages}`)
41 | const searchResult = await srch.json()
42 | const pageResult = await searchPage.json()
43 | const results = searchResult.results
44 | if (searchResult) {
45 | this.setState(prev => {
46 | return{
47 | isLoad:prev.isLoad = false,
48 | search:prev.search = results,
49 | search:prev.search = pageResult.results
50 | }
51 | })
52 |
53 | }
54 |
55 | }
56 |
57 |
58 | paginationNext = async (e) => {
59 |
60 | this.setState({
61 | pages:this.state.page = this.state.pages + 1,
62 | isLoad:this.isLoad = true
63 | })
64 | }
65 |
66 | paginationPrev = async (e) => {
67 | this.setState({
68 | pages:this.state.page = this.state.pages - 1,
69 | isLoad:this.isLoad = true
70 | })
71 |
72 | }
73 |
74 | render(){
75 |
76 | return(
77 |
78 | {this.state.isLoad ?
: " "}
79 |
80 |
81 |
Search '{this.props.id}'
82 |
83 | { this.state.search.map(srch => {
84 | const img = `https://image.tmdb.org/t/p/w185/${srch.poster_path}`
85 | const person =`https://image.tmdb.org/t/p/w185/${srch.profile_path}`
86 | const ID = `/${srch.media_type}-detail/${srch.id}`
87 | return
88 |
89 | {srch.poster_path ? <>
90 |
91 |
92 | > :
}
93 |
94 |
95 |
96 |
97 |
{srch.title}
98 |
99 |
100 | {srch.name}
101 |
102 | {srch.release_date}
103 | {srch.first_air_date}
104 | {srch.known_for_department}
105 | {/* {srch.overview} */}
106 |
107 |
108 | })}
109 | {this.state.isLoad ? "" :
110 | {this.state.pages > 1 ? Previous : ""}
111 | Next
112 |
}
113 |
114 |
115 |
116 | )
117 | }
118 | }
119 |
120 |
121 | export default SearchContent;
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/src/component/search-page.js:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react'
3 | import { useParams } from 'react-router-dom';
4 | import LeftSidebar from './left-sidebar';
5 | import SearchContent from './search-content';
6 |
7 | function SearchPage (){
8 | const{ id}= useParams();
9 | return(
10 |
11 | )
12 | }
13 |
14 | export default SearchPage;
--------------------------------------------------------------------------------
/src/component/slider.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom'
3 | import star from '../star.png'
4 |
5 | class SliderImage extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | data:[],
10 | genre:[]
11 | }
12 | }
13 |
14 | async componentDidMount(){
15 | const movieDetail = await fetch(
16 | `https://api.themoviedb.org/3/movie/${this.props.data}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
17 | )
18 | const respon = await movieDetail.json()
19 | if (respon) {
20 | this.setState(prev => {
21 | return{
22 | data:prev.data = respon,
23 | genre:prev.data = respon.genres
24 | }
25 | })
26 | }
27 |
28 | }
29 |
30 | render(){
31 | const Detil = this.state.data
32 | const img = `https://image.tmdb.org/t/p/w300/${Detil.poster_path}`
33 | const style = {
34 | transform:`translateX(-${this.props.index * 100}%)`,
35 | backgroundImage: `url(https://image.tmdb.org/t/p/w1280/${Detil.backdrop_path})`
36 | }
37 | const genre = this.state.genre.map(gen => {
38 | const ID = `/genre/${gen.id}`
39 | return {gen.name} ,
40 | });
41 | const ID = `movie-detail/${Detil.id}`
42 | return(
43 | <>
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
{Detil.vote_average}
54 |
55 |
56 |
{ Detil.title}
57 | { Detil.release_date}
58 |
59 |
60 |
{genre}
61 |
62 |
63 |
Summary
64 | {Detil.overview}
65 |
66 |
Status: {Detil.status}
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | >
77 | )
78 | }
79 | }
80 |
81 | export default SliderImage;
82 |
83 |
84 |
85 |
86 |
87 | {/*
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
{Detil.vote_average}
96 |
97 |
98 |
{ Detil.title}
99 | { Detil.release_date}
100 |
101 |
102 |
{genre}
103 |
104 |
Summary
105 | {Detil.overview}
106 |
107 |
Status: {Detil.status}
108 |
109 |
110 |
*/}
--------------------------------------------------------------------------------
/src/component/trending-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 |
4 | class TrendingCard extends React.Component{
5 | constructor(){
6 | super()
7 | this.state = {
8 | genre:[],
9 | data:[]
10 | }
11 | }
12 |
13 | async componentDidMount(){
14 | const movieDetail = await fetch(
15 | `https://api.themoviedb.org/3/tv/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
16 | )
17 | const respon = await movieDetail.json()
18 | if (respon) {
19 | this.setState(prev => {
20 | return{
21 | data:prev.data = respon,
22 | genre:prev.data = respon.genres
23 | }
24 | })
25 | }
26 |
27 | }
28 | render(){
29 | const data = this.state.data
30 | const url = `https://image.tmdb.org/t/p/w185/${data.poster_path}`
31 | const ID = `/tv-detail/${data.id}`
32 |
33 | const style = {
34 | transform:`translateX(-${this.props.index * 100}%)`
35 | }
36 | const genre = this.state.genre.map(gen => {
37 | const ID = `/genre/${gen.id}`
38 | return {gen.name},
39 | })
40 |
41 | return(
42 |
43 |
44 | {this.props.length}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | {this.props.title}
54 |
55 |
56 | Genres: {genre}
57 |
58 |
{this.props.rating}
59 |
60 |
61 |
62 | )
63 | }
64 | }
65 |
66 |
67 | export default TrendingCard ;
68 |
69 |
70 |
71 | //
72 | //
73 | //
74 | //
75 | //
76 | //
{this.props.title}
77 | //
78 | // {`${month[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} `}
79 | //
80 | //
81 | //
82 |
--------------------------------------------------------------------------------
/src/component/tv-all.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import LeftSidebar from "./left-sidebar";
3 | import MovieCard from "./moviecard";
4 |
5 | class TvPage extends React.Component{
6 | constructor(){
7 | super()
8 | this.state = {
9 | movie:[],
10 | tivi:[],
11 | loading:true,
12 | pages:1
13 | }
14 | }
15 |
16 | async componentDidMount(){
17 | const stream = await fetch(
18 | "https://api.themoviedb.org/3/trending/tv/week?api_key=0ccbee0a69447c2b1bd0090bf76b0358"
19 | )
20 |
21 | const streamTv = await fetch(
22 | `https://api.themoviedb.org/3/tv/popular?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
23 | )
24 |
25 | const tvRes = await streamTv.json()
26 | const movieRes = await stream.json()
27 | if(movieRes ){
28 | this.setState(prev => {
29 | return{
30 | movie:prev.movie = movieRes.results,
31 | tivi:prev.tivi = tvRes.results,
32 | loading:prev.loading = false
33 | }
34 | })
35 | }
36 | }
37 |
38 | async componentDidUpdate(){
39 | const stream = await fetch(
40 | "https://api.themoviedb.org/3/trending/tv/week?api_key=0ccbee0a69447c2b1bd0090bf76b0358&page=${this.state.pages}"
41 | )
42 |
43 | const streamTv = await fetch(
44 | `https://api.themoviedb.org/3/tv/popular?api_key=0ccbee0a69447c2b1bd0090bf76b0358&page=${this.state.pages}`
45 | )
46 |
47 | const tvRes = await streamTv.json()
48 | const movieRes = await stream.json()
49 | if(movieRes ){
50 | this.setState(prev => {
51 | return{
52 | movie:prev.movie = movieRes.results,
53 | tivi:prev.tivi = tvRes.results,
54 | loading:prev.loading = false
55 | }
56 | })
57 | }
58 | }
59 |
60 | paginationNext = async (e) => {
61 |
62 | this.setState({
63 | pages:this.state.page = this.state.pages + 1,
64 | loading:this.loading = true
65 | })
66 | }
67 |
68 | paginationPrev = async (e) => {
69 | this.setState({
70 | pages:this.state.page = this.state.pages - 1,
71 | loading:this.loading = true
72 | })
73 |
74 | }
75 | render(){
76 | const movies = !this.state.movie ? "" : this.state.movie.map(m => {
77 | const date = new Date(m.release_date);
78 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={date} />
79 | })
80 |
81 | const tivis = !this.state.tivi.length ? "" : this.state.tivi.map(m => {
82 | const dates = new Date(m.first_air_date);
83 | return < MovieCard img={m.poster_path} data={m} id={m.id} index={this.state.index} Date={dates} />
84 | })
85 | return(
86 |
87 |
88 | {this.state.loading ?
89 |
90 |
: " "}
91 | {movies}
92 | {tivis}
93 | {this.state.loading ? "" :
94 | {this.state.pages > 1 ? Previous : ""}
95 | Next
96 |
}
97 |
98 |
99 |
100 | )
101 | }
102 | }
103 |
104 | export default TvPage;
--------------------------------------------------------------------------------
/src/component/tv-detail-card.js:
--------------------------------------------------------------------------------
1 | import { Link } from 'react-router-dom';
2 | import React from 'react'
3 | import '../detail.css';
4 | import star from '../star.png'
5 | import ModalVideo from './modal-video';
6 | import Logo from './img/PngItem_6391407.png'
7 | import CastDanRekomenTV from './cast-rekomend-tv'
8 |
9 | class TvDetailCard extends React.Component{
10 | constructor(){
11 | super()
12 | this.state = {
13 | data:[],
14 | genre:[],
15 | video:[],
16 | videoSrc:'',
17 | modal:false
18 | }
19 | }
20 |
21 |
22 | async componentDidMount(){
23 | const movieDetail = await fetch(
24 | `https://api.themoviedb.org/3/tv/${this.props.id}?api_key=0ccbee0a69447c2b1bd0090bf76b0358`
25 | )
26 | const Video = await fetch(
27 | `https://api.themoviedb.org/3/tv/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
28 | )
29 |
30 | const videos = await Video.json()
31 | const vid = videos.results[0]
32 | const respon = await movieDetail.json()
33 | if (respon) {
34 | this.setState(prev => {
35 | return{
36 | data:prev.data = respon,
37 | genre:prev.data = respon.genres,
38 | video:prev.video = vid
39 | }
40 | })
41 | }
42 |
43 | }
44 |
45 | playVideo = (e) => {
46 | e.preventDefault()
47 | const id = e.target.dataset.mykey
48 | this.setState({
49 | videoSrc:this.state.videoSrc = id,
50 | modal:!this.state.modal
51 | })
52 | console.log(this.state.modal);
53 | }
54 |
55 | removeModal = (e) =>{
56 | e.preventDefault()
57 | this.setState({ modal:!this.state.modal})
58 | }
59 | render(){
60 | const movi = this.state.data
61 | const styles = {
62 | backgroundImage: `url(https://image.tmdb.org/t/p/w1280/${movi.backdrop_path})`
63 | }
64 | const imgUrl = `https://image.tmdb.org/t/p/w300/${movi.poster_path}`
65 | const maps = this.state.genre.map(gen => {
66 | const ID = `/genre/${gen.id}`
67 | return {gen.name} ,
68 | });
69 |
70 | return(
71 | <>
72 |
73 |
74 |
75 |
76 |
{movi.name}
77 |
{movi.tagline}
78 |
Genres: {maps}
79 |
80 |
81 |
82 |
{movi.vote_average}
83 |
84 |
87 |
88 |
Runtime: {movi.episode_run_time}m
89 |
Status: {movi.status}
90 |
Release Date: {movi.first_air_date}
91 |
92 |
Overview
93 |
{movi.overview}
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | {this.state.modal ? : ""}
103 |
104 |
105 |
106 |
107 | >
108 | )
109 | }
110 | }
111 |
112 | export default TvDetailCard;
113 |
114 |
115 |
--------------------------------------------------------------------------------
/src/component/tv-detail.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useLocation, useParams } from 'react-router-dom'
3 | import TvDetailCard from './tv-detail-card'
4 | import Footer from './footer'
5 | function TvDetail () {
6 |
7 | const{ id }= useParams();
8 | return(
9 | <>
10 |
11 |
12 | >
13 | )
14 | }
15 |
16 | export default TvDetail;
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/component/tv-recomend-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom';
3 |
4 | function TvRecomCard (props){
5 | const ID = `/tv-detail/${props.id}`
6 | const style = {
7 | transform:`translateX(-${props.index * 100}%)`
8 | }
9 |
10 | return(
11 |
12 |
13 |
14 |
15 |
16 |
{props.name}
17 | {props.date}
18 |
19 |
20 | )
21 | }
22 |
23 | export default TvRecomCard ;
24 |
25 |
--------------------------------------------------------------------------------
/src/component/video-card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Logo from './img/PngItem_6391407.png'
3 |
4 | class VideoCard extends React.Component{
5 | constructor(){
6 | super()
7 | this.state = {
8 | video:[],
9 | loading:true
10 | }
11 | }
12 |
13 | async componentDidMount(){
14 | const Video = await fetch(
15 | `https://api.themoviedb.org/3/movie/${this.props.id}/videos?api_key=0ccbee0a69447c2b1bd0090bf76b0358&append_to_response=videos`
16 | )
17 | const videos = await Video.json()
18 | const vid = videos.results[0]
19 |
20 | if(vid){
21 | this.setState(prev => {
22 | return{
23 | loading:prev.loading = false,
24 | video:prev.video = vid
25 | }
26 | })
27 | }
28 | }
29 |
30 | render(){
31 | const video = this.state.video
32 | const img = `http://i3.ytimg.com/vi/${video.key}/hqdefault.jpg`
33 | const style = {
34 | transform:`translateX(-${this.props.index * 100}%)`
35 | }
36 |
37 | return(
38 |
39 |
40 |
41 |
42 |
43 |
44 | {video.name}
45 | {this.props.judul}
46 |
47 |
48 | )
49 | }
50 |
51 | }
52 |
53 | export default VideoCard;
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/detail.css:
--------------------------------------------------------------------------------
1 |
2 | .test{
3 | color: white;
4 | margin: 250px auto;
5 | font-size: 50px;
6 | }
7 |
8 | /* BANNER */
9 |
10 | .banner-detail{
11 | margin: 66px auto;
12 | -webkit-box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
13 | box-shadow: inset 0 0 0 100vw rgb(0 0 0 / 70%);
14 | background-size: cover;
15 | background-position: center, center;
16 | color: white;
17 | opacity: 2;
18 | background-repeat: no-repeat;
19 | -webkit-box-sizing: border-box;
20 | box-sizing: border-box;
21 | font-family: Arial, Helvetica, sans-serif;
22 |
23 | }
24 |
25 | .banner-detail-inner{
26 | display: -webkit-box;
27 | display: -ms-flexbox;
28 | display: flex;
29 | -webkit-box-pack:justify;
30 | -ms-flex-pack:justify;
31 | justify-content:space-between;
32 | margin:25px 55px;
33 | gap: 50px;
34 | background-repeat: no-repeat;
35 | background-size: cover;
36 | background-position: center;
37 | padding: 30px;
38 | }
39 |
40 | .banner-detail-inner .img{
41 | border-radius: 5px;
42 | width: 5000px;
43 | }
44 |
45 |
46 | .banner-detail-info{
47 | margin: 30px 0;
48 | display: -webkit-box;
49 | display: -ms-flexbox;
50 | display: flex;
51 | -webkit-box-orient: vertical;
52 | -webkit-box-direction: normal;
53 | -ms-flex-direction: column;
54 | flex-direction: column;
55 | gap: 20px;
56 |
57 | }
58 |
59 |
60 | .banner-detail-info .jdl{
61 | font-size: 30px;
62 | font-weight: bold;
63 | }
64 |
65 | .banner-detail .title{
66 | font-family: Arial, Helvetica, sans-serif;
67 | font-size: 17px;
68 | font-weight: bold;
69 | }
70 | .banner-detail .genre{
71 | font-family: Arial, Helvetica, sans-serif;
72 | font-size: 17px;
73 | font-weight: bold;
74 | }
75 |
76 | .banner-detail .genre a{
77 | color: white;
78 | text-decoration: none;
79 | }
80 | .banner-detail .tagline{
81 | font-family:Roboto;
82 | font-style: italic;
83 | font-weight: 300;
84 | font-size: 17px;
85 | font-weight: bold;
86 | }
87 |
88 | .banner-detail .overview p{
89 | padding-top: 10px;
90 | font-size: 16px;
91 | font-family: Arial, Helvetica, sans-serif;
92 | font-weight: 400;
93 | word-spacing: 5px;
94 | line-height: 20px
95 | }
96 |
97 | .banner-detail-info .stars img{
98 | width: 70px;
99 | }
100 |
101 | .rating-container{
102 | position: absolute;
103 | top: 28px;
104 | left: 22px;
105 | color: black;
106 | font-weight: bold;
107 | font-size: 18px;
108 | }
109 |
110 | .banner-detail-info .play img{
111 | width: 25px;
112 | }
113 |
114 | .banner-detail-info .play{
115 | display: flex;
116 | align-items: center;
117 | gap: 20px;
118 | text-decoration: none;
119 | color: white;
120 | font-weight: bold;
121 | }
122 | /* END BANNER */
123 |
124 |
125 | /* CONTENT */
126 | .content-detail{
127 | display:-webkit-box;
128 | display:-ms-flexbox;
129 | display:flex;
130 | gap: 20px;
131 | -webkit-box-orient:vertical;
132 | -webkit-box-direction:normal;
133 | -ms-flex-direction:column;
134 | flex-direction:column;
135 | margin: 0 50px 30px 50px;
136 | }
137 |
138 | .content-poster{
139 | margin: 100px 100px;
140 | display: grid;
141 | height: 100%;
142 | grid-template-columns: repeat(auto-fit,minmax(200px,1fr));
143 | gap: 30px;
144 | }
145 |
146 | .poster{
147 | display: flex;
148 | flex-direction: column;
149 | background-color: white;
150 | box-shadow: rgb(0 0 0 / 24%) 0px 3px 8px;
151 | }
152 |
153 | .poster-info{
154 | display: flex;
155 | flex-direction: column;
156 | gap: 10px;
157 | }
158 |
159 | .poster-info .poster-judul{
160 | font-size: 16px;
161 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
162 | font-weight: 500;
163 | padding: 8px;
164 | }
165 |
166 | .poster-info ul{
167 | border-top: 2px solid rgba(0, 0, 0, 0.13);
168 | padding: 10px 0;
169 | }
170 | .poster-info li{
171 | display: flex;
172 | flex-direction: column;
173 | gap: 10px;
174 | padding: 10px;
175 | }
176 |
177 | .poster img{
178 | width: 100%;
179 | height: 100%;
180 | border-radius:10px ;
181 | }
182 |
183 | .poster-header{
184 | grid-column-end: 1;
185 | grid-column-start: -1;
186 | margin: 20px 0;
187 | background-color: rgba(31.5, 52.5, 94.5, 1);
188 | color: white;
189 | padding: 15px;
190 | }
191 |
192 | .poster-inner{
193 | display: flex;
194 | gap: 25px;
195 | align-items: center;
196 | }
197 |
198 | .poster-inner h3 a{
199 | font-size: 35px;
200 | font-weight: bold;
201 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
202 | }
203 |
204 | .poster-title{
205 | display: flex;
206 | flex-direction: column;
207 | gap: 15px;
208 | align-items: flex-start;
209 | }
210 |
211 | .poster-title a{
212 | color: white;
213 | }
214 |
215 | .poster-inner img{
216 | width: 75px;
217 | border-radius: 7px;
218 | }
219 | .content-detail .title{
220 | -ms-grid-row-span: -2;
221 | grid-row-end: -1;
222 | -ms-grid-row: 1;
223 | grid-row-start: 1;
224 | -ms-grid-column: 1;
225 | grid-column-start: 1;
226 | -ms-grid-column-span: -2;
227 | grid-column-end: -1;
228 | font-size: 23px;
229 | font-weight: bold;
230 | }
231 |
232 | .rekomen-container{
233 | display: -ms-grid;
234 | display: grid;
235 | grid-template-columns: repeat(auto-fit,minmax(150px,1fr));
236 | gap: 15px;
237 | margin: 50px 50px;
238 | }
239 |
240 | .info{
241 | display: -webkit-box;
242 | display: -ms-flexbox;
243 | display: flex;
244 | -webkit-box-orient: vertical;
245 | -webkit-box-direction: normal;
246 | -ms-flex-direction: column;
247 | flex-direction: column;
248 | padding: 5px;
249 | -webkit-box-pack: justify;
250 | -ms-flex-pack: justify;
251 | justify-content: space-between;
252 | gap: 5px;
253 | text-align: center;
254 | -o-text-overflow: ellipsis;
255 | text-overflow: ellipsis;
256 | }
257 | .info .name{
258 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
259 | font-size: 16px;
260 | font-weight: 500;
261 | word-wrap: break-word;
262 | -o-text-overflow: ellipsis;
263 | text-overflow: ellipsis;
264 | }
265 | .info .chara{
266 | font-size: 14px;
267 | }
268 |
269 | .info .date {
270 | font-size: 14px;
271 | }
272 |
273 | /* END CONTENT */
274 |
275 |
276 | /* SEARCH CONTENT */
277 |
278 | .search-container{
279 | display: flex;
280 | flex-direction: row;
281 | gap: 20px;
282 | margin: 80px 100px;
283 | }
284 |
285 | .result{
286 | grid-column-end: -1;
287 | grid-column-start: 1;
288 | background-color: #031d33;
289 | padding: 20px;
290 | color: white;
291 | font-weight: bold;
292 | }
293 |
294 | .search-content{
295 | flex: 2;
296 | display: grid;
297 | grid-template-columns: repeat(auto-fit,minmax(150px,1fr));
298 | gap: 20px;
299 | height: 100%;
300 | }
301 |
302 | .anime-content{
303 | display: grid;
304 | grid-template-columns: repeat(auto-fit,minmax(150px,1fr));
305 | gap: 20px;
306 | height: 100%;
307 | }
308 |
309 | .search-content .card{
310 | background-color: white;
311 | border-radius: 5px;
312 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
313 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
314 | font-family: Arial, Helvetica, sans-serif;
315 | -webkit-transition: 500ms;
316 | -o-transition: 500ms;
317 | transition: 500ms;
318 | animation: fade 500ms;
319 | }
320 |
321 | .search-content .rilis{
322 | color: rgba(0, 0, 0, 0.363);
323 | font-size: 16px;
324 | }
325 | .search-content .info{
326 | display: -webkit-box;
327 | display: -ms-flexbox;
328 | display: flex;
329 | -webkit-box-orient: vertical;
330 | -webkit-box-direction: normal;
331 | -ms-flex-direction: column;
332 | flex-direction: column;
333 | padding: 10px;
334 | gap: 5px;
335 | }
336 |
337 | .search-content .card .review{
338 | margin-top: 10px;
339 | font-size: 14px;
340 | display: -webkit-box;
341 | -webkit-line-clamp: 2;
342 | -webkit-box-orient: vertical;
343 | -o-text-overflow: ellipsis;
344 | text-overflow: ellipsis;
345 | overflow: hidden;
346 | }
347 |
348 | .search-content .search-inner {
349 | margin: 10px 0;
350 | text-align: center;
351 | display: flex;
352 | flex-direction: column;
353 | gap: 5px;
354 | }
355 | .search-content .search-inner .judul{
356 | font-size: 17px;
357 | font-weight: 550;
358 | }
359 | .search-content .search-inner .date{
360 | font-size: 14px;
361 | }
362 |
363 | .search-content .card .thumb{
364 | width: 100%;
365 | border-top-left-radius: 5px;
366 | border-bottom-left-radius: 5px;
367 | cursor: pointer;
368 | }
369 |
370 | /* END SEARCH */
371 |
372 | .people-container{
373 | display: grid;
374 | grid-template-areas:
375 | "left main main"
376 | "left main main"
377 | "left main main"
378 | ;
379 | gap: 20px;
380 | grid-template-columns: 250px 1fr;
381 | margin: 100px 50px;
382 | }
383 |
384 |
385 | /* LEFT MENU */
386 | .titles{
387 | font-size: 20px;
388 | font-weight: bold;
389 | padding: 12px;
390 | color:black;
391 | padding:10px;
392 | margin: 5px 0;
393 | grid-column-start: 1;
394 | grid-column-end: -1;
395 | }
396 |
397 | .sub-titles{
398 | font-size: 15px;
399 | font-weight: 600;
400 | color: black;
401 | }
402 | .left-menu{
403 | background-color: white;
404 | grid-area: left;
405 | display: flex;
406 | flex-direction: column;
407 | gap: 20px;
408 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
409 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
410 | }
411 |
412 | .profil-pic img{
413 | width: 100%;
414 | border-radius: 10px;
415 | cursor: pointer;
416 | transition: 250ms;
417 | }
418 |
419 | .profil-pic:hover{
420 | transition: 250ms;
421 | filter: brightness(0.6);
422 | }
423 |
424 | .left-menu .person-info{
425 | display: flex;
426 | flex-direction: column;
427 | gap: 15px;
428 | padding: 10px;
429 | }
430 |
431 | .left-menu .person-info .info-column{
432 | display: flex;
433 | flex-direction: column;
434 | gap: 5px;
435 | }
436 |
437 |
438 | .left-menu .person-info .info-name{
439 | display: flex;
440 | flex-direction: column;
441 | gap: 8px;
442 | }
443 | .info-column .info-text{
444 | font-weight: 400;
445 | font-size: 17px;
446 | }
447 |
448 | /* END LEFT MENU */
449 | /* MAIN */
450 |
451 | .main{
452 | grid-area: main;
453 | background-color: white;
454 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
455 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
456 | padding: 10px;
457 | }
458 |
459 | .content-top{
460 | display: flex;
461 | flex-direction: column;
462 | gap: 35px;
463 | }
464 |
465 | .content-top .title-top{
466 | font-size: 35px;
467 | font-weight: bold;
468 | }
469 |
470 | .content-top .title{
471 | font-size: 20px;
472 | font-weight: 600;
473 | }
474 |
475 | .content-top .overview .paraf{
476 | font-family: Arial, Helvetica, sans-serif;
477 | word-spacing: 5px;
478 | line-height: 23px;
479 | font-size: 15px;
480 | font-weight: 500;
481 | padding: 10px;
482 | }
483 |
484 | .content-top .overview{
485 | display: flex;
486 | flex-direction: column;
487 | gap: 15px;
488 | }
489 | /* POPULER */
490 |
491 |
492 |
493 | .main .content-card{
494 | display: grid;
495 | grid-template-columns: repeat(auto-fit,minmax(150px,1fr));
496 | gap: 20px;
497 | padding: 10px;
498 | overflow: hidden;
499 | }
500 |
501 | .main .content-card .title{
502 | font-weight: bold;
503 | font-size: 25px;
504 | grid-column-end: -1;
505 | grid-column-start: 1;
506 | }
507 |
508 |
509 | .main .content-card .thumb{
510 | -webkit-transition: 500ms;
511 | -o-transition: 500ms;
512 | transition: 500ms;
513 | border-radius: 5px;
514 | cursor: pointer;
515 | width:100%;
516 | }
517 |
518 | .main .box {
519 | border-radius: 5px;
520 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
521 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
522 | font-family: Arial, Helvetica, sans-serif;
523 | -webkit-transition: 500ms;
524 | -o-transition: 500ms;
525 | transition: 500ms;
526 | position: relative;
527 | }
528 |
529 | .content .info{
530 | padding: 10px;
531 | margin: auto;
532 | }
533 | .content .info .judul {
534 | font-size: 16px;
535 | font-weight: 550;
536 | text-align: center;
537 | }
538 | .content .info .judul a{
539 | text-decoration: none;
540 | color: gray;
541 | }
542 |
543 | .content .info .judul a:hover{
544 | color: rgb(0, 132, 255);
545 | }
546 |
547 |
548 | .container-people{
549 | margin: 100px 50px;
550 | }
551 |
552 | .content-people{
553 | display: grid;
554 | grid-template-columns: repeat(auto-fit,minmax(200px,1fr));
555 | gap: 25px;
556 | }
557 |
558 | .container-people .title{
559 | font-size: 30px;
560 | font-weight: bold;
561 | padding: 10px;
562 | }
563 | .people-card{
564 | background-color: white;
565 | border-radius: 5px;
566 | -webkit-box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
567 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
568 | font-family: Arial, Helvetica, sans-serif;
569 | -webkit-transition: 500ms;
570 | -o-transition: 500ms;
571 | transition: 500ms;
572 | position: relative;
573 | }
574 |
575 | .people-card .thumb{
576 | -webkit-transition: 500ms;
577 | -o-transition: 500ms;
578 | transition: 500ms;
579 | border-radius: 5px;
580 | cursor: pointer;
581 | width:100%;
582 | }
583 |
584 | .people-card .judul {
585 | font-size: 17px;
586 | font-weight: 550;
587 | }
588 |
589 | .people-card .judul a{
590 | color: black;
591 | text-decoration: none;
592 | }
593 |
594 | .pagination{
595 | display: flex;
596 | justify-content: center;
597 | margin: 50px 0;
598 | grid-column-end: 1;
599 | grid-column-start: -1;
600 | }
601 | .pagination button{
602 | color: white;
603 | font-weight: bold;
604 | background-color: #333333;
605 | border-radius: 3px;
606 | margin: 2px;
607 | line-height: 25px;
608 | transition: 200ms;
609 | text-align: center;
610 | width: 100px;
611 | padding:5px;
612 | }
613 | /* PEOPLE DETAIL */
614 |
615 |
616 | /* END PEOPLE DETAIL */
617 |
618 | .heads{
619 | background-color: white;
620 | padding: 10px;
621 | }
622 |
623 | .navbar ul{
624 | display: flex;
625 | align-items: center;
626 | gap: 20px;
627 | }
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 | /* RESPONSIVE */
636 |
637 | @media (max-width:1200px){
638 | .search-container{
639 | margin: 100px 10px;
640 | }
641 | }
642 |
643 | @media (max-width:950px){
644 | .search-container{
645 | flex-direction: column;
646 | }
647 |
648 | }
649 |
650 | @media (max-width:850px){
651 | .judul-flex{
652 | gap: 20px;
653 | }
654 |
655 | .tittle-inners {
656 | display: flex;
657 | align-items: center;
658 | gap: 150px;
659 | }
660 | }
661 |
662 |
663 | @media (max-width:800px){
664 | .banner-detail{
665 | margin: 66px 0;
666 | }
667 | .banner-detail-inner {
668 | flex-direction: column;
669 | margin: 25px 55px;
670 | gap: 50px;
671 | }
672 | }
673 |
674 |
675 | @media (max-width:800px){
676 |
677 | .people-container{
678 | display: grid;
679 | grid-template-areas:
680 | "left left left"
681 | "left left left"
682 | "main main main"
683 | ;
684 | margin: 80px 20px;
685 | }
686 |
687 | .content-detail{
688 | margin: 5px 20px;
689 | }
690 |
691 | .judul-flex{
692 | gap: 5px;
693 | flex-wrap: wrap;
694 | }
695 |
696 |
697 | .tittle-inners{
698 | gap: 50px;
699 | }
700 |
701 |
702 | .tittle-inners ul {
703 | gap: 10px;
704 | }
705 |
706 | .tittle-inners a{
707 | font-size: 14px;
708 | }
709 |
710 | }
711 |
712 |
713 | @media (max-width:700px) {
714 | .search-content{
715 | grid-template-columns: repeat(auto-fit,minmax(120px,1fr));
716 | gap: 15px;
717 | }
718 |
719 | }
720 |
721 | @media (max-width:600px){
722 | .search-content{
723 | gap:25px;
724 | margin: 0 5px;
725 | }
726 |
727 | .judul-flex{
728 | gap: 5px;
729 | flex-wrap: wrap;
730 | }
731 |
732 |
733 | .tittle-inners{
734 | gap: 20px;
735 | }
736 |
737 |
738 | .tittle-inners ul {
739 | gap: 10px;
740 | }
741 |
742 | .tittle-inners a{
743 | font-size: 14px;
744 | }
745 |
746 | }
747 |
748 | /* 500PX */
749 |
750 | @media (max-width:500px){
751 |
752 | .judul-flex{
753 | gap: 5px;
754 | flex-wrap: wrap;
755 | }
756 |
757 |
758 | .tittle-inners{
759 | gap: 10px;
760 | }
761 |
762 |
763 | .tittle-inners ul {
764 | gap: 10px;
765 | }
766 |
767 | .tittle-inners a{
768 | font-size: 13px;
769 | }
770 |
771 | }
772 |
773 |
774 | /* MOBILE */
775 |
776 | @media (max-width:360px) {
777 |
778 | .banner-detail{
779 | margin: 59px 0;
780 | }
781 |
782 | .banner-detail-inner {
783 | flex-direction: column;
784 | margin: 25px 10px;
785 | gap: 5px;
786 | }
787 |
788 | .content-detail{
789 | margin: 5px 10px;
790 | }
791 |
792 | .judul-flex{
793 | gap: 5px;
794 | flex-wrap: wrap;
795 | }
796 |
797 | .content-detail .title {
798 | font-size: 17px;
799 | }
800 |
801 | .banner-detail-info .stars img{
802 | width: 50px;
803 | }
804 |
805 | .rating-container{
806 | position: absolute;
807 | top: 20px;
808 | left: 15px;
809 | color: black;
810 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
811 | font-weight: bold;
812 | font-size: 14px;
813 | }
814 |
815 | .banner-detail-info .play img{
816 | width: 15px;
817 | }
818 |
819 | .review-card .paraf{
820 | display: -webkit-box;
821 | -webkit-line-clamp: 2;
822 | -webkit-box-orient: vertical;
823 | -o-text-overflow: ellipsis;
824 | text-overflow: ellipsis;
825 | overflow: hidden;
826 | }
827 |
828 |
829 | .tittle-inners{
830 | gap: 10px;
831 | }
832 |
833 | .tittle-inners ul {
834 | gap: 10px;
835 | }
836 |
837 | .tittle-inners a{
838 | font-size: 12px;
839 | }
840 | }
841 |
842 |
843 | @media (max-width:340px) {
844 | .search-content{
845 | grid-template-columns: repeat(auto-fit,minmax(90px,1fr));
846 | margin-right: 15px;
847 | gap: 20px;
848 | }
849 | }
850 |
851 |
852 |
853 | @media (max-width:320px) {
854 | .search-content{
855 | grid-template-columns: repeat(auto-fit,minmax(100px,1fr));
856 | margin: 1px 1px;
857 | gap: 25px;
858 | }
859 |
860 | .search-containe{
861 | margin: 1px 1px;
862 | }
863 | }
--------------------------------------------------------------------------------
/src/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/empty.png
--------------------------------------------------------------------------------
/src/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/github.png
--------------------------------------------------------------------------------
/src/header.css:
--------------------------------------------------------------------------------
1 | /* NAVBAR DROPDOWN */
2 | .navbars{
3 | display: -webkit-box;
4 | display: -ms-flexbox;
5 | display: flex;
6 | -webkit-box-align: center;
7 | -ms-flex-align: center;
8 | align-items: center;
9 | -webkit-box-pack: justify;
10 | -ms-flex-pack: justify;
11 | justify-content: space-between;
12 | margin: 0 100px;
13 | transition: 500ms;
14 | display: none;
15 | }
16 |
17 | .navbars .list{
18 | display: -webkit-box;
19 | display: -ms-flexbox;
20 | display: flex;
21 | -webkit-box-align: center;
22 | -ms-flex-align: center;
23 | align-items: center;
24 | gap: 20px;
25 | }
26 |
27 | .navbars .list li a {
28 | color: white;
29 | font-weight: bold;
30 | text-decoration: none;
31 | font-size: 14px;
32 | text-transform: uppercase;
33 | }
34 |
35 | /* END NAVBAR DROP DOWN */
36 |
37 |
38 |
39 | /* HEADER */
40 |
41 |
42 | .logos{
43 | width: 100px;
44 | cursor: pointer;
45 | }
46 |
47 | .header{
48 | background-color: #031d33;
49 | /* background-color: #031d33; */
50 | padding: 15px;
51 | color: white;
52 | font-family: Arial, Helvetica, sans-serif;
53 | -webkit-transition: 500ms;
54 | -o-transition: 500ms;
55 | transition: 500ms;
56 | position: fixed;
57 | width: 100%;
58 | top: 0;
59 | z-index: 20;
60 | /* border-bottom: 3px solid #20B2AA; */
61 | }
62 |
63 | .header .title{
64 | font-size: 30px;
65 | font-weight: bold;
66 | cursor: pointer;
67 | color: white;
68 | text-decoration: none;
69 | }
70 |
71 | .fixed-header {
72 | transform: translateY(-75px);
73 | }
74 |
75 | .header .navbar{
76 | display: -webkit-box;
77 | display: -ms-flexbox;
78 | display: flex;
79 | -webkit-box-align: center;
80 | -ms-flex-align: center;
81 | align-items: center;
82 | -webkit-box-pack: justify;
83 | -ms-flex-pack: justify;
84 | justify-content: space-between;
85 | margin: 0 100px;
86 | transition: 500ms;
87 | }
88 |
89 | .header h1{
90 | font-weight: bold;
91 | }
92 |
93 | .navbar .list{
94 | display: -webkit-box;
95 | display: -ms-flexbox;
96 | display: flex;
97 | -webkit-box-align: center;
98 | -ms-flex-align: center;
99 | align-items: center;
100 | gap: 20px;
101 | }
102 |
103 | .navbar .list li a {
104 | color: white;
105 | font-weight: bold;
106 | text-decoration: none;
107 | font-size: 14px;
108 | text-transform: uppercase;
109 | }
110 |
111 | .dropdown .drop-list{
112 | background-color: white;
113 | display: -webkit-box;
114 | display: -ms-flexbox;
115 | display: flex;
116 | -webkit-box-orient: vertical;
117 | -webkit-box-direction: normal;
118 | -ms-flex-direction: column;
119 | flex-direction: column;
120 | gap:5px;
121 | border-radius: 5px;
122 | margin-top: 10px;
123 | /* top: 40px; */
124 | position: absolute;
125 | opacity:0;
126 | visibility: hidden;
127 | -webkit-transition:visibility 0.3s linear,opacity 0.3s linear;
128 | -o-transition:visibility 0.3s linear,opacity 0.3s linear;
129 | transition:visibility 0.3s linear,opacity 0.3s linear;
130 | -webkit-transition: 500ms;
131 | -o-transition: 500ms;
132 | transition: 500ms;
133 | z-index: 10;
134 | }
135 |
136 |
137 | .dropdown-tv .tv-list{
138 | background-color: white;
139 | display: -webkit-box;
140 | display: -ms-flexbox;
141 | display: flex;
142 | -webkit-box-orient: vertical;
143 | -webkit-box-direction: normal;
144 | -ms-flex-direction: column;
145 | flex-direction: column;
146 | gap:5px;
147 | border-radius: 5px;
148 | margin-top: 10px;
149 | /* top: 40px; */
150 | position: absolute;
151 | opacity:0;
152 | visibility: hidden;
153 | -webkit-transition:visibility 0.3s linear,opacity 0.3s linear;
154 | -o-transition:visibility 0.3s linear,opacity 0.3s linear;
155 | transition:visibility 0.3s linear,opacity 0.3s linear;
156 | -webkit-transition: 500ms;
157 | -o-transition: 500ms;
158 | transition: 500ms;
159 | }
160 |
161 | .people-list{
162 | background-color: white;
163 | display: -webkit-box;
164 | display: -ms-flexbox;
165 | display: flex;
166 | -webkit-box-orient: vertical;
167 | -webkit-box-direction: normal;
168 | -ms-flex-direction: column;
169 | flex-direction: column;
170 | gap:5px;
171 | border-radius: 5px;
172 | margin-top: 10px;
173 | /* top: 40px; */
174 | position: absolute;
175 | opacity:0;
176 | visibility: hidden;
177 | -webkit-transition:visibility 0.3s linear,opacity 0.3s linear;
178 | -o-transition:visibility 0.3s linear,opacity 0.3s linear;
179 | transition:visibility 0.3s linear,opacity 0.3s linear;
180 | -webkit-transition: 500ms;
181 | -o-transition: 500ms;
182 | transition: 500ms;
183 | }
184 |
185 | .drop-list li a{
186 | color: black !important;
187 | font-weight: bold;
188 | text-decoration: none;
189 | padding: 10px;
190 | }
191 |
192 | .drop-list li{
193 | padding: 10px;
194 | }
195 |
196 | .tv-list li a{
197 | color: black !important;
198 | font-weight: bold;
199 | text-decoration: none;
200 | padding: 10px;
201 | }
202 |
203 | .tv-list li{
204 | padding: 10px;
205 | }
206 |
207 | .people-list li a{
208 | color: black !important;
209 | font-weight: bold;
210 | text-decoration: none;
211 | padding: 10px;
212 | }
213 |
214 | .people-list li{
215 | padding: 10px;
216 | }
217 |
218 | .list li:hover{
219 | background-color: rgba(228, 226, 226, 0.521);
220 | -webkit-transition: 500ms;
221 | -o-transition: 500ms;
222 | transition: 500ms;
223 | }
224 |
225 | li:hover .drop-list {
226 | visibility:visible;
227 | -webkit-transition: 500ms;
228 | -o-transition: 500ms;
229 | transition: 500ms;
230 | opacity:1;
231 | -webkit-transform: translateY(0);
232 | -ms-transform: translateY(0);
233 | transform: translateY(0);
234 | }
235 |
236 | li:hover .tv-list {
237 | visibility:visible;
238 | -webkit-transition: 500ms;
239 | -o-transition: 500ms;
240 | transition: 500ms;
241 | opacity:1;
242 | -webkit-transform: translateY(0);
243 | -ms-transform: translateY(0);
244 | transform: translateY(0);
245 | }
246 |
247 | li:hover .people-list {
248 | visibility:visible;
249 | -webkit-transition: 500ms;
250 | -o-transition: 500ms;
251 | transition: 500ms;
252 | opacity:1;
253 | -webkit-transform: translateY(0);
254 | -ms-transform: translateY(0);
255 | transform: translateY(0);
256 | }
257 |
258 |
259 | .form input{
260 | padding: 10px;
261 | border: none;
262 | outline: none;
263 | background-color: white;
264 | color: black;
265 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
266 | }
267 |
268 | .form .buton{
269 | border-radius: 5px;
270 | padding: 10px;
271 | background: #0c70de;
272 | border: none;
273 | outline: none;
274 | color: white;
275 | font-weight: bold;
276 | }
277 |
278 |
279 |
280 | .forms input{
281 | padding: 10px;
282 | border: none;
283 | outline: none;
284 | background-color: white;
285 | color: black;
286 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
287 | }
288 |
289 | .forms{
290 | display: none;
291 | }
292 |
293 |
294 | .forms .buton {
295 | border-radius: 5px;
296 | padding: 10px;
297 | background: #0c70de;
298 | border: none;
299 | outline: none;
300 | color: white;
301 | font-weight: bold;
302 | }
303 |
304 |
305 | .header .baton {
306 | border-radius: 5px;
307 | padding: 5px 10px;
308 | background-color: rgb(38, 95, 219);
309 | border: none;
310 | outline: none;
311 | color: white;
312 | font-weight: bold;
313 | }
314 |
315 | .hide {
316 | -webkit-transform: translateY(-70px);
317 | -ms-transform: translateY(-70px);
318 | transform: translateY(-70px);
319 | -webkit-transition: 500ms;
320 | -o-transition: 500ms;
321 | transition: 500ms;
322 | }
323 |
324 | /* END HEADER */
325 |
326 |
327 | /* HAMBURGER */
328 |
329 | /* spinner */
330 |
331 | .spinner{
332 | -webkit-transition: all 0.3s;
333 | -o-transition: all 0.3s;
334 | transition: all 0.3s;
335 | -webkit-box-sizing: border-box;
336 | box-sizing: border-box;
337 | position: absolute;
338 | height: 3px;
339 | width: 100%;
340 | background-color: white;
341 | }
342 |
343 | .spinner{
344 | -webkit-transition: all 0.3s;
345 | -o-transition: all 0.3s;
346 | transition: all 0.3s;
347 | -webkit-box-sizing: border-box;
348 | box-sizing: border-box;
349 | position: absolute;
350 | height: 3px;
351 | width: 100%;
352 | background-color: white;
353 | }
354 |
355 | .horizontal {
356 | -webkit-transition: all 0.3s;
357 | -o-transition: all 0.3s;
358 | transition: all 0.3s;
359 | -webkit-box-sizing: border-box;
360 | box-sizing: border-box;
361 | position: relative;
362 | float: left;
363 | margin-top: 3px;
364 | }
365 |
366 | .diagonal.part-1 {
367 | position: relative;
368 | -webkit-transition: all 0.3s;
369 | -o-transition: all 0.3s;
370 | transition: all 0.3s;
371 | -webkit-box-sizing: border-box;
372 | box-sizing: border-box;
373 | float: left;
374 | }
375 |
376 | .diagonal.part-2 {
377 | -webkit-transition: all 0.3s;
378 | -o-transition: all 0.3s;
379 | transition: all 0.3s;
380 | -webkit-box-sizing: border-box;
381 | box-sizing: border-box;
382 | position: relative;
383 | float: left;
384 | margin-top: 3px;
385 | }
386 |
387 | .hamburger{
388 | display: none;
389 | margin-top: 7px;
390 | width: 22px;
391 | height: 22px;
392 | -webkit-box-sizing: border-box;
393 | box-sizing: border-box;
394 | z-index: 22;
395 | cursor: pointer;
396 | position:fixed;
397 | top: 20px;
398 | left: 50px;
399 | }
400 |
401 | /* click class */
402 | .open.horizontal {
403 | -webkit-transition: all 0.3s;
404 | -o-transition: all 0.3s;
405 | transition: all 0.3s;
406 | -webkit-box-sizing: border-box;
407 | box-sizing: border-box;
408 | opacity: 0;
409 | }
410 |
411 | .open.diagonal.part-2{
412 | -webkit-transition: all 0.3s;
413 | -o-transition: all 0.3s;
414 | transition: all 0.3s;
415 | -webkit-box-sizing: border-box;
416 | box-sizing: border-box;
417 | -webkit-transform: rotate(-135deg);
418 | -ms-transform: rotate(-135deg);
419 | transform: rotate(-135deg);
420 | margin-top: -9px;
421 | }
422 |
423 | .open.diagonal.part-1 {
424 | -webkit-transition: all 0.3s;
425 | -o-transition: all 0.3s;
426 | transition: all 0.3s;
427 | -webkit-box-sizing: border-box;
428 | box-sizing: border-box;
429 | -webkit-transform: rotate(135deg);
430 | -ms-transform: rotate(135deg);
431 | transform: rotate(135deg);
432 | margin-top: 8px;
433 |
434 | }
435 |
436 | /* END HAMBURGER */
437 |
438 | /* RESPONSIVE */
439 |
440 | @media (max-width:950px){
441 | .header .navbar{
442 | margin: 0 50px;
443 | }
444 |
445 | }
446 |
447 | @media (max-width:715px){
448 | .hamburger-container{
449 | display: flex;
450 | gap: 20px;
451 | }
452 |
453 | .header .navbar{
454 | position: absolute;
455 | transform: translateY(-270px);
456 | width: 100%;
457 | padding: 10px;
458 | background-color: #031d33;
459 | }
460 |
461 | .hamburger{
462 | display: block;
463 | top: 23px;
464 | left: 35px;
465 | }
466 |
467 | .header{
468 | transition: 500ms;
469 | display: flex;
470 | flex-direction: column;
471 | gap: 25px;
472 | align-items: center;
473 | padding:20px;
474 | }
475 |
476 | .navbar .list{
477 | gap: 30px;
478 | align-items: center;
479 | margin: auto;
480 | }
481 |
482 | .forms{
483 | display: block;
484 | }
485 |
486 | .forms input{
487 | width: 330px;
488 | }
489 |
490 | .form{
491 | display: none;
492 | }
493 |
494 | .navbar.opens{
495 | -o-transition: 500ms;
496 | transition: 500ms;
497 | transform: translateY(0);
498 | }
499 |
500 | .navbar .list{
501 | flex-direction: column;
502 | padding: 10px;
503 | }
504 |
505 | .navbar .list li a {
506 | color: white;
507 | }
508 |
509 | }
510 |
511 |
512 | @media (max-width:660px){
513 | .forms input{
514 | width: 330px;
515 | }
516 |
517 | }
518 |
519 | @media (max-width:520px){
520 | .forms input{
521 | width: 300px;
522 | }
523 | }
524 |
525 | @media (max-width:500px){
526 | .forms input{
527 | width: 250px;
528 | }
529 | .hamburger{
530 | display: block;
531 | top: 23px;
532 | left: 20px;
533 | }
534 |
535 | }
536 |
537 | @media (max-width:400px){
538 | .forms input{
539 | width: 220px;
540 | }
541 | .hamburger{
542 | display: block;
543 | top: 23px;
544 | left: 15px;
545 | }
546 |
547 | }
548 |
549 | @media (max-width:360px){
550 | .hamburger{
551 | display: block;
552 | top: 20px;
553 | left: 15px;
554 | }
555 |
556 |
557 | .forms input{
558 | width: 150px;
559 | padding: 8px;
560 | }
561 |
562 | .forms .buton{
563 | padding: 8px;
564 | }
565 |
566 | .navbar .list{
567 | padding-right: 50px;
568 | }
569 | }
570 |
571 |
--------------------------------------------------------------------------------
/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 ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 |
6 | const root = ReactDOM.createRoot(document.getElementById('root'));
7 | root.render(
8 |
9 |
10 |
11 | );
12 |
13 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/logos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/logos.png
--------------------------------------------------------------------------------
/src/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/next.png
--------------------------------------------------------------------------------
/src/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/prev.png
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/src/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bay-s/react-movie-app/8c4c3d3af26beea97631401a8cff12514230c092/src/star.png
--------------------------------------------------------------------------------
/src/tmdb-logo.svg:
--------------------------------------------------------------------------------
1 | Asset 5
--------------------------------------------------------------------------------