├── images
├── FFIV.jpg
├── SOTN.jpg
├── Blackthorne.jpg
├── background.png
├── Demons-Crest.jpg
├── Super-Mario-World.jpg
├── Super_Metroid_capa.png
├── Donkey Kong Country.jpg
├── Super Castlevania IV.jpg
├── snes_mega_manX_front.jpg
├── chrono-trigger-snes-manual.jpg
├── ninja-gaiden-nes-front-cover.jpg
└── Ghouls_and_Ghosts_sales_flyer.png
├── src
├── components
│ ├── utils
│ │ ├── paginate.js
│ │ ├── pagination.css
│ │ └── pagination.jsx
│ ├── header.css
│ ├── header.jsx
│ ├── games.css
│ └── games.jsx
├── App.js
├── index.js
├── App.css
├── registerServiceWorker.js
└── services
│ └── GameService.js
├── README.md
├── public
├── manifest.json
└── index.html
├── .gitignore
└── package.json
/images/FFIV.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/FFIV.jpg
--------------------------------------------------------------------------------
/images/SOTN.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/SOTN.jpg
--------------------------------------------------------------------------------
/images/Blackthorne.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Blackthorne.jpg
--------------------------------------------------------------------------------
/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/background.png
--------------------------------------------------------------------------------
/images/Demons-Crest.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Demons-Crest.jpg
--------------------------------------------------------------------------------
/images/Super-Mario-World.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Super-Mario-World.jpg
--------------------------------------------------------------------------------
/images/Super_Metroid_capa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Super_Metroid_capa.png
--------------------------------------------------------------------------------
/images/Donkey Kong Country.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Donkey Kong Country.jpg
--------------------------------------------------------------------------------
/images/Super Castlevania IV.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Super Castlevania IV.jpg
--------------------------------------------------------------------------------
/images/snes_mega_manX_front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/snes_mega_manX_front.jpg
--------------------------------------------------------------------------------
/images/chrono-trigger-snes-manual.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/chrono-trigger-snes-manual.jpg
--------------------------------------------------------------------------------
/images/ninja-gaiden-nes-front-cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/ninja-gaiden-nes-front-cover.jpg
--------------------------------------------------------------------------------
/images/Ghouls_and_Ghosts_sales_flyer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/the-akira/react-games/master/images/Ghouls_and_Ghosts_sales_flyer.png
--------------------------------------------------------------------------------
/src/components/utils/paginate.js:
--------------------------------------------------------------------------------
1 | export function paginate(items, pageNumber, pageSize) {
2 | const startIndex = (pageNumber - 1) * pageSize;
3 | return items.slice(startIndex, startIndex + pageSize);
4 | }
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Games from "./components/games";
3 | import './App.css'
4 |
5 | class App extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | );
12 | }
13 | }
14 |
15 | export default App;
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import App from "./App";
4 | import registerServiceWorker from "./registerServiceWorker";
5 | import "bootstrap/dist/css/bootstrap.css";
6 | import "font-awesome/css/font-awesome.css";
7 |
8 | ReactDOM.render(, document.getElementById("root"));
9 | registerServiceWorker();
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | A Simple Games App made with ReactJS
4 |
5 | `git clone https://github.com/the-akira/react-games.git`
6 |
7 | ### Available Scripts
8 |
9 | In the project directory, you can run:
10 |
11 | - `npm install`
12 | - `npm start`
13 | - `npm run build`
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | body{
2 | background-image: url(https://raw.githubusercontent.com/the-akira/react-games/master/images/background.png);
3 | }
4 |
5 | .container{
6 | border: 2.5px solid #a8b0bf;
7 | color: #a8b0bf;
8 | border-radius: 10px;
9 | padding: 23px;
10 | background-color: black;
11 | margin: auto;
12 | margin-top: 50px;
13 | margin-bottom: 50px;
14 | text-align: center;
15 | opacity: 0.959;
16 | }
--------------------------------------------------------------------------------
/.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 |
25 |
--------------------------------------------------------------------------------
/src/components/header.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap');
2 |
3 | .main-title{
4 | font-family: 'Press Start 2P', cursive;
5 | margin: 6px 6px 12px 10px;
6 | font-size: 2.3rem;
7 | }
8 |
9 | .icons{
10 | margin-bottom: 13px;
11 | margin-top: 13px;
12 | }
13 |
14 | i{
15 | margin-right: 15px;
16 | color: #a8b0bf;
17 | }
18 |
19 | i:hover{
20 | opacity: 0.8;
21 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vidly",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "bootstrap": "^4.4.1",
7 | "font-awesome": "^4.7.0",
8 | "lodash": "^4.17.21",
9 | "react": "^16.4.1",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "1.1.4"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test --env=jsdom",
17 | "eject": "react-scripts eject"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React Games App
9 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/components/utils/pagination.css:
--------------------------------------------------------------------------------
1 | .page-item {
2 | list-style: none;
3 | display: inline-block;
4 | margin-right: 5px;
5 | }
6 |
7 | .page-item button {
8 | padding: 5px 10px;
9 | border: 1px solid #a8b0bf;
10 | cursor: pointer;
11 | color: #a8b0bf;
12 | background-color: #202328;
13 | border-radius: 2.5px;
14 | font: inherit;
15 | }
16 |
17 | .page-item button:hover {
18 | opacity: 0.8;
19 | }
20 |
21 | .page-item button:focus {
22 | outline: none;
23 | box-shadow: none;
24 | }
25 |
26 | .page-item.active button {
27 | color: black !important;
28 | background-color: #a8b0bf !important;
29 | opacity: 0.87;
30 | border: 1px solid #202328 !important;
31 | }
--------------------------------------------------------------------------------
/src/components/header.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./header.css"
3 |
4 | const Header = () => {
5 | return (
6 |
7 |
React Games App
8 |
16 |
17 | );
18 | }
19 |
20 | export default Header;
--------------------------------------------------------------------------------
/src/components/utils/pagination.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./pagination.css";
3 |
4 | const Pagination = ({ itemsCount, pageSize, currentPage, onPageChange }) => {
5 | const pagesCount = Math.ceil(itemsCount / pageSize);
6 | if (pagesCount === 1) return null;
7 |
8 | const pages = Array.from({ length: pagesCount }, (_, index) => index + 1);
9 |
10 | return (
11 |
28 | );
29 | };
30 |
31 | export default Pagination;
--------------------------------------------------------------------------------
/src/components/games.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Nanum+Pen+Script&display=swap');
2 | @import url('https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap');
3 |
4 | .games-container{
5 | margin-left: 0;
6 | display: grid;
7 | grid-template-columns: repeat(auto-fill, minmax(450px,1fr));
8 | grid-template-rows: auto;
9 | grid-row-gap: 13px;
10 | justify-content: space-evenly;
11 | padding: 0 35px 35px 35px;
12 | overflow-x: hidden;
13 | text-align: center;
14 | }
15 |
16 | .game-container{
17 | display: block;
18 | width: 88%;
19 | padding: 26px;
20 | margin: auto;
21 | margin-top: 10px;
22 | opacity: 0.79;
23 | border-radius: 3px;
24 | border: 1px solid #a8b0bf;
25 | box-shadow: 2.1px 2.1px 1.3px #a8b0bf;
26 | background-color: #252930;
27 | }
28 |
29 | .game-container > p:last-child {
30 | margin-bottom: 0px;
31 | }
32 |
33 | .info {
34 | margin-bottom: 5px;
35 | }
36 |
37 | .capa{
38 | width: 188px;
39 | height: 280px;
40 | border: 1.4px solid #a8b0bf;
41 | margin-bottom: 15px;
42 | border-radius: 10px;
43 | }
44 |
45 | .title{
46 | font-family: 'Nanum Pen Script', cursive;
47 | font-size: 1.932rem;
48 | margin-bottom: 15px;
49 | text-shadow: 2px 1.5px 1px black;
50 | }
51 |
52 | nav > ul {
53 | margin-bottom: 6px;
54 | }
55 |
56 | .pesquisa{
57 | margin-top: 12px;
58 | margin-bottom: 25px;
59 | width: 58%;
60 | height: 42px;
61 | background-color: #252930;
62 | color: #a8b0bf;
63 | border: 1.5px solid #a8b0bf;
64 | border-radius: 3px;
65 | font-size: 14px;
66 | font-family: 'Press Start 2P', cursive;
67 | }
68 |
69 | @media only screen and (max-width: 850px) {
70 | .game-container{
71 | width: 70%;
72 | }
73 | }
--------------------------------------------------------------------------------
/src/components/games.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { getGames } from "../services/GameService";
3 | import Header from "./header";
4 | import Pagination from "./utils/pagination";
5 | import { paginate } from "./utils/paginate";
6 | import "./games.css";
7 |
8 | class Games extends Component {
9 | state = {
10 | games: [],
11 | currentPage: 1,
12 | pageSize: 4,
13 | filter: "",
14 | };
15 |
16 | componentDidMount() {
17 | this.setState({ games: getGames() });
18 | }
19 |
20 | handlePageChange = page => {
21 | this.setState({ currentPage: page });
22 | };
23 |
24 | handleChange = event => {
25 | this.setState({ filter: event.target.value, currentPage: 1 }); // Reset currentPage to 1 when filtering
26 | };
27 |
28 | render() {
29 | const { length: count } = this.state.games;
30 | const { pageSize, currentPage, games: allGames, filter } = this.state;
31 |
32 | if (count === 0) return There are no games in the database.
;
33 |
34 | const lowercasedFilter = filter.toLowerCase();
35 |
36 | const filteredGames = allGames.filter(item => {
37 | return Object.keys(item).some(key =>
38 | typeof item[key] === "string" && item[key].toLowerCase().includes(lowercasedFilter)
39 | );
40 | });
41 |
42 | const games = paginate(filteredGames, currentPage, pageSize);
43 |
44 | return (
45 |
46 |
47 |
48 | Showing {filteredGames.length} game's in the database.
49 |
50 |
51 |
57 |
58 |
59 | {games.map(game => (
60 |
61 |
{game.title}
62 |

63 |
Genre: {game.genre.name}
64 |
Publisher: {game.publisher}
65 |
Director: {game.director}
66 |
67 | ))}
68 |
69 |
70 |
76 |
77 | );
78 | }
79 | }
80 |
81 | export default Games;
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | const isLocalhost = Boolean(
2 | window.location.hostname === 'localhost' ||
3 | // [::1] is the IPv6 localhost address.
4 | window.location.hostname === '[::1]' ||
5 | // 127.0.0.1/8 is considered localhost for IPv4.
6 | window.location.hostname.match(
7 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
8 | )
9 | );
10 |
11 | export default function register() {
12 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
13 | // The URL constructor is available in all browsers that support SW.
14 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
15 | if (publicUrl.origin !== window.location.origin) {
16 | // Our service worker won't work if PUBLIC_URL is on a different origin
17 | // from what our page is served on. This might happen if a CDN is used to
18 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
19 | return;
20 | }
21 |
22 | window.addEventListener('load', () => {
23 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
24 |
25 | if (isLocalhost) {
26 | // This is running on localhost. Lets check if a service worker still exists or not.
27 | checkValidServiceWorker(swUrl);
28 |
29 | // Add some additional logging to localhost, pointing developers to the
30 | // service worker/PWA documentation.
31 | navigator.serviceWorker.ready.then(() => {
32 | console.log(
33 | 'This web app is being served cache-first by a service ' +
34 | 'worker. To learn more, visit https://goo.gl/SC7cgQ'
35 | );
36 | });
37 | } else {
38 | // Is not local host. Just register service worker
39 | registerValidSW(swUrl);
40 | }
41 | });
42 | }
43 | }
44 |
45 | function registerValidSW(swUrl) {
46 | navigator.serviceWorker
47 | .register(swUrl)
48 | .then(registration => {
49 | registration.onupdatefound = () => {
50 | const installingWorker = registration.installing;
51 | installingWorker.onstatechange = () => {
52 | if (installingWorker.state === 'installed') {
53 | if (navigator.serviceWorker.controller) {
54 | // At this point, the old content will have been purged and
55 | // the fresh content will have been added to the cache.
56 | // It's the perfect time to display a "New content is
57 | // available; please refresh." message in your web app.
58 | console.log('New content is available; please refresh.');
59 | } else {
60 | // At this point, everything has been precached.
61 | // It's the perfect time to display a
62 | // "Content is cached for offline use." message.
63 | console.log('Content is cached for offline use.');
64 | }
65 | }
66 | };
67 | };
68 | })
69 | .catch(error => {
70 | console.error('Error during service worker registration:', error);
71 | });
72 | }
73 |
74 | function checkValidServiceWorker(swUrl) {
75 | // Check if the service worker can be found. If it can't reload the page.
76 | fetch(swUrl)
77 | .then(response => {
78 | // Ensure service worker exists, and that we really are getting a JS file.
79 | if (
80 | response.status === 404 ||
81 | response.headers.get('content-type').indexOf('javascript') === -1
82 | ) {
83 | // No service worker found. Probably a different app. Reload the page.
84 | navigator.serviceWorker.ready.then(registration => {
85 | registration.unregister().then(() => {
86 | window.location.reload();
87 | });
88 | });
89 | } else {
90 | // Service worker found. Proceed as normal.
91 | registerValidSW(swUrl);
92 | }
93 | })
94 | .catch(() => {
95 | console.log(
96 | 'No internet connection found. App is running in offline mode.'
97 | );
98 | });
99 | }
100 |
101 | export function unregister() {
102 | if ('serviceWorker' in navigator) {
103 | navigator.serviceWorker.ready.then(registration => {
104 | registration.unregister();
105 | });
106 | }
107 | }
--------------------------------------------------------------------------------
/src/services/GameService.js:
--------------------------------------------------------------------------------
1 | const games = [
2 | {
3 | _id: "5b21ca3eeb7f6fbccd471815",
4 | title: "Castlevania: Symphony of the Night",
5 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
6 | publisher: "Konami",
7 | director: "Koji Igarashi",
8 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/SOTN.jpg" }
9 | },
10 | {
11 | _id: "5b21ca3eeb7f6fbccd471816",
12 | title: "Super Mario World",
13 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
14 | publisher: "Nintendo",
15 | director: "Takashi Tezuka",
16 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Super-Mario-World.jpg" }
17 | },
18 | {
19 | _id: "5b21ca3eeb7f6fbccd471817",
20 | title: "Super Castlevania IV",
21 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
22 | publisher: "Konami",
23 | director: "Masahiro Ueno",
24 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Super%20Castlevania%20IV.jpg" }
25 | },
26 | {
27 | _id: "5b21ca3eeb7f6fbccd471819",
28 | title: "Super Metroid",
29 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
30 | publisher: "Nintendo",
31 | director: "Yoshio Sakamoto",
32 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Super_Metroid_capa.png" }
33 | },
34 | {
35 | _id: "5b21ca3eeb7f6fbccd47181a",
36 | title: "Donkey Kong Country",
37 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
38 | publisher: "Nintendo",
39 | director: "Tim Stamper",
40 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Donkey%20Kong%20Country.jpg" }
41 | },
42 | {
43 | _id: "5b21ca3eeb7f6fbccd47181b",
44 | title: "Ninja Gaiden",
45 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
46 | publisher: "Sega",
47 | director: "Kouji Inokuchi",
48 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/ninja-gaiden-nes-front-cover.jpg" }
49 | },
50 | {
51 | _id: "5b21ca3eeb7f6fbccd47181e",
52 | title: "Blackthorne",
53 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
54 | publisher: "Blizzard",
55 | director: "Matthew Findley",
56 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Blackthorne.jpg" }
57 | },
58 | {
59 | _id: "5b21ca3eeb7f6fbccd47181f",
60 | title: "Mega Man X",
61 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
62 | publisher: "Capcom",
63 | director: "Yoshinori Takenaka",
64 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/snes_mega_manX_front.jpg" }
65 | },
66 | {
67 | _id: "5b21ca3eeb7f6fbccd471821qw",
68 | title: "Demon's Crest",
69 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
70 | publisher: "Capcom",
71 | director: "Tokuro Fujiwara",
72 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Demons-Crest.jpg" }
73 | },
74 | {
75 | _id: "5b21ca3eeb7f6fbccd471821mw",
76 | title: "Ghouls 'n Ghosts",
77 | genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Platform-adventure" },
78 | publisher: "Capcom",
79 | director: "Tokuro Fujiwara",
80 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/Ghouls_and_Ghosts_sales_flyer.png" }
81 | },
82 | {
83 | _id: "5b21ca3eeb7f6fbccd471821rw",
84 | title: "Final Fantasy IV",
85 | genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "RPG" },
86 | publisher: "Square",
87 | director: "Hironobu Sakaguchi",
88 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/FFIV.jpg" }
89 | },
90 | {
91 | _id: "5b21ca3eeb7f6fbccd471821sx",
92 | title: "Chrono Trigger",
93 | genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "RPG" },
94 | publisher: "Square",
95 | director: "Takashi Tokita",
96 | image: { url: "https://raw.githubusercontent.com/the-akira/react-games/master/images/chrono-trigger-snes-manual.jpg" }
97 | }
98 | ];
99 |
100 | export function getGames() {
101 | return games;
102 | }
103 |
104 | export function getGame(id) {
105 | return games.find(g => g._id === id);
106 | }
--------------------------------------------------------------------------------