├── .dockerignore
├── .editorconfig
├── .env.example
├── .eslintignore
├── .eslintrc
├── .github
└── workflows
│ └── push.yml
├── .gitignore
├── .nvmrc
├── .vscode
└── settings.json
├── Dockerfile
├── README.md
├── admin
└── src
│ ├── assets
│ └── images
│ │ ├── logo-won-dark.svg
│ │ └── logo-won.svg
│ ├── components
│ └── LeftMenu
│ │ ├── LeftMenuFooter
│ │ ├── Wrapper.js
│ │ └── index.js
│ │ ├── LeftMenuHeader
│ │ └── Wrapper.js
│ │ ├── LeftMenuLink
│ │ └── A.js
│ │ └── LeftMenuLinkSection
│ │ └── LeftMenuListLink.js
│ ├── config.js
│ ├── containers
│ ├── AuthPage
│ │ └── components
│ │ │ └── Logo
│ │ │ ├── Img.js
│ │ │ └── index.js
│ ├── HomePage
│ │ └── index.js
│ └── LeftMenu
│ │ └── Wrapper.js
│ ├── favicon.png
│ └── themes
│ ├── colors.js
│ ├── fontWeights.js
│ ├── index.js
│ └── sizes.js
├── api
├── .gitkeep
├── banner
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── banner.js
│ ├── models
│ │ ├── banner.js
│ │ └── banner.settings.json
│ └── services
│ │ └── banner.js
├── category
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── category.js
│ ├── models
│ │ ├── category.js
│ │ └── category.settings.json
│ └── services
│ │ └── category.js
├── developer
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── developer.js
│ ├── models
│ │ ├── developer.js
│ │ └── developer.settings.json
│ └── services
│ │ └── developer.js
├── game
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── game.js
│ ├── models
│ │ ├── game.js
│ │ └── game.settings.json
│ └── services
│ │ └── game.js
├── home
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── home.js
│ ├── models
│ │ ├── home.js
│ │ └── home.settings.json
│ └── services
│ │ └── home.js
├── order
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── order.js
│ ├── models
│ │ ├── order.js
│ │ └── order.settings.json
│ └── services
│ │ └── order.js
├── platform
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── platform.js
│ ├── models
│ │ ├── platform.js
│ │ └── platform.settings.json
│ └── services
│ │ └── platform.js
├── publisher
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── publisher.js
│ ├── models
│ │ ├── publisher.js
│ │ └── publisher.settings.json
│ └── services
│ │ └── publisher.js
├── recommended
│ ├── config
│ │ └── routes.json
│ ├── controllers
│ │ └── recommended.js
│ ├── models
│ │ ├── recommended.js
│ │ └── recommended.settings.json
│ └── services
│ │ └── recommended.js
└── wishlist
│ ├── config
│ └── routes.json
│ ├── controllers
│ └── wishlist.js
│ ├── models
│ ├── wishlist.js
│ └── wishlist.settings.json
│ └── services
│ └── wishlist.js
├── components
└── page
│ ├── button.json
│ ├── highlight.json
│ ├── popular-games.json
│ ├── ribbon.json
│ └── section.json
├── config
├── database.js
├── email-templates
│ └── order.js
├── env
│ ├── development
│ │ └── plugins.js
│ └── production
│ │ ├── database.js
│ │ ├── plugins.js
│ │ └── server.js
├── functions
│ ├── bootstrap.js
│ ├── cart.js
│ ├── cron.js
│ └── responses
│ │ └── 404.js
├── plugins.js
└── server.js
├── extensions
├── .gitkeep
└── users-permissions
│ ├── config
│ └── jwt.js
│ └── models
│ └── User.settings.json
├── favicon.ico
├── migrate-3.4.0.js
├── package.json
├── plugins
└── repositories
│ ├── .editorconfig
│ ├── .gitattributes
│ ├── .gitignore
│ ├── README.md
│ ├── admin
│ └── src
│ │ ├── containers
│ │ ├── App
│ │ │ └── index.js
│ │ ├── HomePage
│ │ │ └── index.js
│ │ └── Initializer
│ │ │ └── index.js
│ │ ├── index.js
│ │ ├── lifecycles.js
│ │ ├── pluginId.js
│ │ ├── translations
│ │ ├── ar.json
│ │ ├── cs.json
│ │ ├── de.json
│ │ ├── en.json
│ │ ├── es.json
│ │ ├── fr.json
│ │ ├── index.js
│ │ ├── it.json
│ │ ├── ko.json
│ │ ├── ms.json
│ │ ├── nl.json
│ │ ├── pl.json
│ │ ├── pt-BR.json
│ │ ├── pt.json
│ │ ├── ru.json
│ │ ├── sk.json
│ │ ├── tr.json
│ │ ├── uk.json
│ │ ├── vi.json
│ │ ├── zh-Hans.json
│ │ └── zh.json
│ │ └── utils
│ │ └── getTrad.js
│ ├── config
│ └── routes.json
│ ├── controllers
│ └── repositories.js
│ ├── package.json
│ └── services
│ └── repositories.js
├── public
├── robots.txt
└── uploads
│ └── .gitkeep
└── yarn.lock
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.DS_Store
2 | **/node_modules/
3 | *.sql
4 | .vscode*
5 | .dockerignore
6 | .env*
7 | .git*
8 | .idea
9 | .nvmrc
10 | .editorconfig
11 | migrage-*
12 | .gitignore
13 | .eslint*
14 | Dockerfile
15 | CHANGELOG.md
16 | LICENSE.md
17 | README.md
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [{package.json,*.yml}]
12 | indent_style = space
13 | indent_size = 2
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | HOST=0.0.0.0
2 | PORT=1337
3 | STRIPE_KEY=
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .cache
2 | build
3 | **/node_modules/**
4 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "eslint:recommended",
4 | "env": {
5 | "commonjs": true,
6 | "es6": true,
7 | "node": true,
8 | "browser": false
9 | },
10 | "parserOptions": {
11 | "ecmaFeatures": {
12 | "experimentalObjectRestSpread": true,
13 | "jsx": false
14 | },
15 | "sourceType": "module"
16 | },
17 | "globals": {
18 | "strapi": true
19 | },
20 | "rules": {
21 | "indent": ["error", 2, { "SwitchCase": 1 }],
22 | "linebreak-style": ["error", "unix"],
23 | "no-console": 0,
24 | "quotes": ["error", "single"],
25 | "semi": ["error", "always"]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.github/workflows/push.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on:
4 | push:
5 | branches:
6 | - 'master'
7 |
8 | jobs:
9 | docker:
10 | runs-on: ubuntu-latest
11 | steps:
12 | -
13 | name: Checkout
14 | uses: actions/checkout@v2
15 | -
16 | name: Set up QEMU
17 | uses: docker/setup-qemu-action@v1
18 | -
19 | name: Set up Docker Buildx
20 | uses: docker/setup-buildx-action@v1
21 | -
22 | name: Login to DockerHub
23 | uses: docker/login-action@v1
24 | with:
25 | username: ${{ secrets.DOCKERHUB_USERNAME }}
26 | password: ${{ secrets.DOCKERHUB_TOKEN }}
27 | -
28 | name: Build and push
29 | id: docker_build
30 | uses: docker/build-push-action@v2
31 | with:
32 | context: .
33 | push: true
34 | tags: wongames/api:latest
35 | -
36 | name: Image digest
37 | run: echo ${{ steps.docker_build.outputs.digest }}
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ############################
2 | # OS X
3 | ############################
4 |
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 | Icon
9 | .Spotlight-V100
10 | .Trashes
11 | ._*
12 |
13 |
14 | ############################
15 | # Linux
16 | ############################
17 |
18 | *~
19 |
20 |
21 | ############################
22 | # Windows
23 | ############################
24 |
25 | Thumbs.db
26 | ehthumbs.db
27 | Desktop.ini
28 | $RECYCLE.BIN/
29 | *.cab
30 | *.msi
31 | *.msm
32 | *.msp
33 |
34 |
35 | ############################
36 | # Packages
37 | ############################
38 |
39 | *.7z
40 | *.csv
41 | *.dat
42 | *.dmg
43 | *.gz
44 | *.iso
45 | *.jar
46 | *.rar
47 | *.tar
48 | *.zip
49 | *.com
50 | *.class
51 | *.dll
52 | *.exe
53 | *.o
54 | *.seed
55 | *.so
56 | *.swo
57 | *.swp
58 | *.swn
59 | *.swm
60 | *.out
61 | *.pid
62 |
63 |
64 | ############################
65 | # Logs and databases
66 | ############################
67 |
68 | .tmp
69 | *.log
70 | *.sqlite
71 | *.sqlite3
72 |
73 |
74 | ############################
75 | # Misc.
76 | ############################
77 |
78 | *#
79 | ssl
80 | .idea
81 | nbproject
82 | public/uploads/*
83 | !public/uploads/.gitkeep
84 |
85 | ############################
86 | # Node.js
87 | ############################
88 |
89 | lib-cov
90 | lcov.info
91 | pids
92 | logs
93 | results
94 | node_modules
95 | .node_history
96 |
97 |
98 | ############################
99 | # Tests
100 | ############################
101 |
102 | testApp
103 | coverage
104 |
105 | ############################
106 | # Strapi
107 | ############################
108 |
109 | .env
110 | license.txt
111 | exports
112 | .cache
113 | build
114 | .strapi-updater.json
115 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v14.14.0
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "window.zoomLevel": 1
3 | }
4 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM strapi/base:14
2 |
3 | WORKDIR /opt/app
4 |
5 | COPY ./package.json ./
6 | COPY ./yarn.lock ./
7 |
8 | RUN yarn install --prod
9 |
10 | RUN npx browserslist@latest --update-db
11 |
12 | COPY . .
13 |
14 | ENV NODE_ENV production
15 | ENV DATABASE_CLIENT=postgres
16 |
17 |
18 | RUN yarn build
19 |
20 | EXPOSE 1337
21 | CMD ["yarn", "start"]
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.digitalocean.com/?refcode=4c3eee0af56f&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge)
2 |
3 | # React Avançado - Won Games API
4 |
5 | This is the API to create the Won Games Store from [React Avançado course](https://reactavancado.com.br/).
6 |
7 | ## Requirements
8 |
9 | This project uses [PostgreSQL](https://www.postgresql.org/), so, in order to make it working, install in your local machine or use Docker.
10 |
11 | The configuration to the Database can be found on [config/database.js](config/database.js)
12 |
13 | ## Development
14 |
15 | After cloning this project, install the dependencies:
16 |
17 | ```
18 | yarn install
19 | ```
20 |
21 | And run using:
22 |
23 | ```
24 | yarn develop
25 | ```
26 |
27 | The urls to access are:
28 |
29 | - `http://localhost:1337/admin` - The Dashboard to create and populate data
30 | - `http://localhost:1337/graphql` - GraphQL Playground to test your queries
31 |
32 | The first time to access the Admin you'll need to create an user.
33 |
34 | ## Populate data
35 |
36 | This project uses a `/games/populate` route in order to populate the data via GoG site.
37 | In order to make it work, follow the steps:
38 |
39 | - Go to Roles & Permissions > Public and make sure `game:populate` route is public available and the upload as well
40 | - With Strapi running run the following comand in your console:
41 |
42 | ```bash
43 | $ curl -X POST http://localhost:1337/games/populate
44 |
45 | # you can pass query parameters like:
46 | $ curl -X POST http://localhost:1337/games/populate?page=2
47 | $ curl -X POST http://localhost:1337/games/populate?search=simcity
48 | $ curl -X POST http://localhost:1337/games/populate?sort=rating&price=free
49 | $ curl -X POST http://localhost:1337/games/populate?availability=coming&sort=popularity
50 | ```
51 |
52 | ## Using dump
53 |
54 | First of all, you need to download our [dump.sql](https://github.com/Won-Games/database/raw/master/dump.sql) from our [database repository](https://github.com/Won-Games/database).
55 |
56 | 1. Create a Postgres database and user:
57 |
58 | ```sh
59 | CREATE USER wongames WITH ENCRYPTED PASSWORD 'wongames123';
60 | CREATE DATABASE wongames OWNER wongames;
61 | ```
62 |
63 | 2. Populate the new database, using the following command (remember to point the place where you have the `dump.sql`):
64 |
65 | ```sh
66 | psql -h localhost -p 5432 -U wongames wongames < dump.sql
67 | ```
68 |
69 | And you can access `localhost:1337/admin` with the following credentials:
70 |
71 | ```sh
72 | email: wongames@wongames.com
73 | password: Wongames123
74 | ```
75 |
--------------------------------------------------------------------------------
/admin/src/assets/images/logo-won-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/admin/src/assets/images/logo-won.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/admin/src/components/LeftMenu/LeftMenuFooter/Wrapper.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 | import PropTypes from "prop-types";
3 |
4 | const Wrapper = styled.div`
5 | position: absolute;
6 | width: 100%;
7 | background: ${(props) => props.theme.main.colors.won.blue};
8 | bottom: 0;
9 | .poweredBy {
10 | width: 100%;
11 | bottom: 0;
12 | height: 3rem;
13 | padding-left: 15px;
14 | padding-right: 15px;
15 | line-height: 3rem;
16 | background-color: rgba(255, 255, 255, 0.02);
17 | font-size: 1rem;
18 | font-weight: 400;
19 | letter-spacing: 0.05rem;
20 | vertical-align: middle;
21 | color: ${({ theme }) => theme.main.colors.strapi["gray-light"]};
22 |
23 | a {
24 | color: ${({ theme }) => theme.main.colors.won.orange};
25 | }
26 | }
27 | `;
28 |
29 | Wrapper.defaultProps = {
30 | theme: {
31 | main: {
32 | colors: {
33 | strapi: {},
34 | },
35 | sizes: {
36 | header: {},
37 | leftMenu: {},
38 | },
39 | },
40 | },
41 | };
42 |
43 | Wrapper.propTypes = {
44 | theme: PropTypes.object,
45 | };
46 |
47 | export default Wrapper;
48 |
--------------------------------------------------------------------------------
/admin/src/components/LeftMenu/LeftMenuFooter/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * LeftMenuFooter
4 | *
5 | */
6 |
7 | import React from "react";
8 |
9 | import Wrapper from "./Wrapper";
10 |
11 | function LeftMenuFooter() {
12 | return (
13 |
14 |
25 |
26 | );
27 | }
28 |
29 | export default LeftMenuFooter;
30 |
--------------------------------------------------------------------------------
/admin/src/components/LeftMenu/LeftMenuHeader/Wrapper.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from "styled-components";
2 |
3 | import Logo from "../../../assets/images/logo-won.svg";
4 |
5 | const Wrapper = styled.div`
6 | ${({ theme }) => css`
7 | background-color: ${theme.main.colors.won.blue};
8 | height: ${theme.main.sizes.leftMenu.height};
9 |
10 | .projectName {
11 | display: block;
12 | height: ${theme.main.sizes.leftMenu.height};
13 | background-image: url(${Logo});
14 | background-repeat: no-repeat;
15 | background-position: center center;
16 | background-size: 12rem;
17 | }
18 | `}
19 | `;
20 |
21 | export default Wrapper;
22 |
--------------------------------------------------------------------------------
/admin/src/components/LeftMenu/LeftMenuLink/A.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const A = styled.a`
4 | position: relative;
5 | padding-top: 0.7rem;
6 | padding-bottom: 0.2rem;
7 | padding-left: 1.6rem;
8 | min-height: 3.6rem;
9 | border-left: 0.3rem solid transparent;
10 | cursor: pointer;
11 | color: ${(props) => props.theme.main.colors.leftMenu["link-color"]};
12 | text-decoration: none;
13 | display: block;
14 | -webkit-font-smoothing: antialiased;
15 |
16 | &:hover {
17 | color: ${(props) => props.theme.main.colors.white};
18 | background: ${(props) => props.theme.main.colors.won.blue};
19 |
20 | border-left: 0.3rem solid ${(props) => props.theme.main.colors.won.orange};
21 | text-decoration: none;
22 | }
23 |
24 | &:focus {
25 | color: ${(props) => props.theme.main.colors.white};
26 | text-decoration: none;
27 | }
28 |
29 | &:visited {
30 | color: ${(props) => props.theme.main.colors.leftMenu["link-color"]};
31 | }
32 |
33 | &.linkActive {
34 | color: white !important;
35 | border-left: 0.3rem solid ${(props) => props.theme.main.colors.won.orange};
36 | }
37 | `;
38 |
39 | export default A;
40 |
--------------------------------------------------------------------------------
/admin/src/components/LeftMenu/LeftMenuLinkSection/LeftMenuListLink.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const LeftMenuListLink = styled.div`
4 | max-height: 180px;
5 | margin-bottom: 19px;
6 | overflow: auto;
7 | `;
8 |
9 | export default LeftMenuListLink;
10 |
--------------------------------------------------------------------------------
/admin/src/config.js:
--------------------------------------------------------------------------------
1 | export const LOGIN_LOGO = null;
2 | export const SHOW_TUTORIALS = false;
3 | export const SETTINGS_BASE_URL = '/settings';
4 | export const STRAPI_UPDATE_NOTIF = false;
5 |
--------------------------------------------------------------------------------
/admin/src/containers/AuthPage/components/Logo/Img.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components";
2 |
3 | const Img = styled.img`
4 | height: 80px;
5 | `;
6 |
7 | export default Img;
8 |
--------------------------------------------------------------------------------
/admin/src/containers/AuthPage/components/Logo/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import LogoStrapi from "../../../../assets/images/logo-won-dark.svg";
3 | import Img from "./Img";
4 |
5 | const Logo = () =>
;
6 |
7 | export default Logo;
8 |
--------------------------------------------------------------------------------
/admin/src/containers/HomePage/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * HomePage
4 | *
5 | */
6 | /* eslint-disable */
7 | import React, { memo } from "react";
8 | import { FormattedMessage } from "react-intl";
9 | import PageTitle from "../../components/PageTitle";
10 |
11 | import {
12 | ALink,
13 | Block,
14 | Container,
15 | LinkWrapper,
16 | P,
17 | Separator,
18 | } from "./components";
19 | import SocialLink from "./SocialLink";
20 |
21 | const FIRST_BLOCK_LINKS = [
22 | {
23 | link:
24 | "https://strapi.io/documentation/v3.x/getting-started/quick-start.html#_4-create-a-category-content-type",
25 | contentId: "app.components.BlockLink.documentation.content",
26 | titleId: "app.components.BlockLink.documentation",
27 | },
28 | {
29 | link: "https://github.com/strapi/foodadvisor",
30 | contentId: "app.components.BlockLink.code.content",
31 | titleId: "app.components.BlockLink.code",
32 | },
33 | ];
34 |
35 | const SOCIAL_LINKS = [
36 | {
37 | name: "GitHub",
38 | link: "https://github.com/React-avancado/",
39 | },
40 | {
41 | name: "Slack",
42 | link: "https://bit.ly/will-slack",
43 | },
44 | {
45 | name: "Twitter",
46 | link: "https://twitter.com/Willian_Justen",
47 | },
48 | ];
49 |
50 | const HomePage = () => {
51 | return (
52 | <>
53 |
54 | {(title) => }
55 |
56 |
57 |
58 |
59 |
60 | Bem vindo a Won Games!
61 |
62 | Ao lado você pode inserir diferentes jogos, categorias e
63 | publishers para a nossa maravilhosa loja de jogos!{" "}
64 |
65 |
66 |
67 | {FIRST_BLOCK_LINKS.map((data, index) => {
68 | const type = index === 0 ? "doc" : "code";
69 |
70 | return (
71 |
77 |
78 | {(title) => {title}
}
79 |
80 |
81 | {(content) => {content}
}
82 |
83 |
84 | );
85 | })}
86 |
87 |
88 |
89 |
90 |
91 |
92 | Veja nossos links!
93 |
94 | Em caso de dúvidas e ou sugestões, só ir em algum de nossos
95 | links =)
96 |
97 |
102 | Veja o nosso planejamento de módulos
103 |
104 |
105 |
106 |
115 | {SOCIAL_LINKS.map((value, key) => (
116 |
117 | ))}
118 |
119 |
120 |
121 |
122 |
123 | >
124 | );
125 | };
126 |
127 | export default memo(HomePage);
128 |
--------------------------------------------------------------------------------
/admin/src/containers/LeftMenu/Wrapper.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from "styled-components";
2 |
3 | const Wrapper = styled.div`
4 | ${({ theme }) => css`
5 | position: fixed;
6 | float: left;
7 | top: 0;
8 | left: 0;
9 | height: 100vh;
10 | width: ${theme.main.sizes.leftMenu.width};
11 | background: ${theme.main.colors.won.blueLight};
12 |
13 | /* scrollbar overrides */
14 | * {
15 | ::-webkit-scrollbar {
16 | width: 7px;
17 | }
18 |
19 | ::-webkit-scrollbar-track,
20 | ::-webkit-scrollbar-track:hover {
21 | background-color: transparent;
22 | }
23 |
24 | ::-webkit-scrollbar-thumb {
25 | background-color: ${theme.main.colors.leftMenu["title-color"]};
26 | }
27 |
28 | ::-webkit-scrollbar-thumb:hover {
29 | background-color: ${theme.main.colors.leftMenu["link-color"]};
30 | }
31 |
32 | /* firefox */
33 | scrollbar-color: ${theme.main.colors.leftMenu["title-color"]} transparent;
34 | }
35 | `}
36 | `;
37 |
38 | export default Wrapper;
39 |
--------------------------------------------------------------------------------
/admin/src/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Won-Games/api/b69dbeaafa31dfddf77888fac1dcedabac798c6b/admin/src/favicon.png
--------------------------------------------------------------------------------
/admin/src/themes/colors.js:
--------------------------------------------------------------------------------
1 | const colors = {
2 | black: '#333740',
3 | white: '#ffffff',
4 | red: '#ff203c',
5 | orange: '#ff5d00',
6 | lightOrange: '#f64d0a',
7 | yellow: '#ffd500',
8 | green: '#6dbb1a',
9 | blue: '#0097f7',
10 | teal: '#5bc0de',
11 | pink: '#ff5b77',
12 | purple: '#613d7c',
13 | gray: '#464a4c',
14 | border: '#E3E9F3',
15 | 'gray-dark': '#292b2c',
16 | grayLight: '#636c72',
17 | 'gray-lighter': '#eceeef',
18 | 'gray-lightest': '#f7f7f9',
19 | brightGrey: '#f0f3f8',
20 | darkGrey: '#e3e9f3',
21 | lightGrey: '#fafafa',
22 | lightestGrey: '#fbfbfb',
23 | mediumGrey: '#F2F3F4',
24 | grey: '#9ea7b8',
25 | greyDark: '#292b2c',
26 | greyAlpha: 'rgba(227, 233, 243, 0.5)',
27 | lightBlue: '#E6F0FB',
28 | mediumBlue: '#007eff',
29 | darkBlue: '#AED4FB',
30 | content: {
31 | background: '#fafafb',
32 | 'background-alpha': 'rgba(14, 22, 34, 0.02)',
33 | },
34 | leftMenu: {
35 | 'link-hover': '#1c2431',
36 | 'link-color': '#919bae',
37 | 'title-color': '#5b626f',
38 | },
39 | strapi: {
40 | 'gray-light': '#eff3f6',
41 | gray: '#535f76',
42 | 'blue-darker': '#18202e',
43 | 'blue-dark': '#151c2e',
44 | blue: '#0097f7',
45 | },
46 | won: {
47 | blueLight: '#10132d',
48 | blue: '#0a0d27',
49 | blueDark: '#06081b',
50 | pink: '#f231a5',
51 | orange: '#f56161',
52 | }
53 | };
54 |
55 | export default colors;
56 |
--------------------------------------------------------------------------------
/admin/src/themes/fontWeights.js:
--------------------------------------------------------------------------------
1 | const fontWeights = {
2 | regular: 400,
3 | semiBold: 500,
4 | bold: 600,
5 | black: 900,
6 | };
7 |
8 | export default fontWeights;
9 |
--------------------------------------------------------------------------------
/admin/src/themes/index.js:
--------------------------------------------------------------------------------
1 | import colors from './colors';
2 | import fontWeights from './fontWeights';
3 | import sizes from './sizes';
4 |
5 | const theme = {
6 | main: {
7 | colors,
8 | fontWeights,
9 | sizes,
10 | },
11 | };
12 |
13 | export default theme;
14 |
--------------------------------------------------------------------------------
/admin/src/themes/sizes.js:
--------------------------------------------------------------------------------
1 | const sizes = {
2 | borderRadius: '2px',
3 | header: {
4 | height: '6rem',
5 | },
6 | leftMenu: {
7 | height: '6rem',
8 | width: '24rem',
9 | },
10 | margins: {
11 | // TODO:
12 | sm: '10px',
13 | },
14 | paddings: {
15 | // TODO
16 | xs: '5px',
17 | sm: '10px',
18 | smd: '20px',
19 | md: '30px',
20 | lg: '40px',
21 | },
22 | fonts: {
23 | xs: '11px',
24 | sm: '12px',
25 | md: '13px',
26 | lg: '18px',
27 | xl: '24px',
28 | },
29 | };
30 |
31 | export default sizes;
32 |
--------------------------------------------------------------------------------
/api/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Won-Games/api/b69dbeaafa31dfddf77888fac1dcedabac798c6b/api/.gitkeep
--------------------------------------------------------------------------------
/api/banner/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/banners",
6 | "handler": "banner.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/banners/count",
14 | "handler": "banner.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/banners/:id",
22 | "handler": "banner.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/banners",
30 | "handler": "banner.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/banners/:id",
38 | "handler": "banner.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/banners/:id",
46 | "handler": "banner.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/banner/controllers/banner.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/banner/models/banner.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/banner/models/banner.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "banners",
4 | "info": {
5 | "name": "banner",
6 | "description": ""
7 | },
8 | "options": {
9 | "increments": true,
10 | "timestamps": true,
11 | "draftAndPublish": true
12 | },
13 | "attributes": {
14 | "image": {
15 | "model": "file",
16 | "via": "related",
17 | "allowedTypes": [
18 | "images"
19 | ],
20 | "plugin": "upload",
21 | "required": true
22 | },
23 | "title": {
24 | "type": "string",
25 | "required": true
26 | },
27 | "subtitle": {
28 | "type": "text",
29 | "required": true,
30 | "maxLength": 150
31 | },
32 | "button": {
33 | "type": "component",
34 | "repeatable": false,
35 | "component": "page.button",
36 | "required": true
37 | },
38 | "ribbon": {
39 | "type": "component",
40 | "repeatable": false,
41 | "component": "page.ribbon"
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/api/banner/services/banner.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/category/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/categories",
6 | "handler": "category.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/categories/count",
14 | "handler": "category.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/categories/:id",
22 | "handler": "category.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/categories",
30 | "handler": "category.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/categories/:id",
38 | "handler": "category.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/categories/:id",
46 | "handler": "category.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/category/controllers/category.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/category/models/category.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/category/models/category.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "categories",
4 | "info": {
5 | "name": "category"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true
10 | },
11 | "attributes": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "unique": true
16 | },
17 | "slug": {
18 | "type": "uid",
19 | "targetField": "name",
20 | "required": true
21 | },
22 | "games": {
23 | "via": "categories",
24 | "collection": "game"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/api/category/services/category.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/developer/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/developers",
6 | "handler": "developer.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/developers/count",
14 | "handler": "developer.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/developers/:id",
22 | "handler": "developer.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/developers",
30 | "handler": "developer.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/developers/:id",
38 | "handler": "developer.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/developers/:id",
46 | "handler": "developer.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/developer/controllers/developer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/developer/models/developer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/developer/models/developer.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "developers",
4 | "info": {
5 | "name": "developer"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true
10 | },
11 | "attributes": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "unique": true
16 | },
17 | "slug": {
18 | "type": "uid",
19 | "targetField": "name",
20 | "required": true
21 | },
22 | "games": {
23 | "via": "developers",
24 | "collection": "game"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/api/developer/services/developer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/game/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/games",
6 | "handler": "game.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/games/count",
14 | "handler": "game.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/games/:id",
22 | "handler": "game.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/games",
30 | "handler": "game.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/games/:id",
38 | "handler": "game.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/games/:id",
46 | "handler": "game.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | },
51 | {
52 | "method": "POST",
53 | "path": "/games/populate",
54 | "handler": "game.populate",
55 | "config": {
56 | "policies": []
57 | }
58 | }
59 | ]
60 | }
61 |
--------------------------------------------------------------------------------
/api/game/controllers/game.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {
9 | populate: async (ctx) => {
10 | console.log("Starting to populate...");
11 |
12 | const options = {
13 | sort: "popularity",
14 | page: "1",
15 | ...ctx.query,
16 | };
17 |
18 | await strapi.services.game.populate(options);
19 |
20 | ctx.send("Finished populating!");
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/api/game/models/game.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/game/models/game.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "games",
4 | "info": {
5 | "name": "game"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true
10 | },
11 | "attributes": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "unique": true
16 | },
17 | "slug": {
18 | "type": "uid",
19 | "targetField": "name",
20 | "required": true
21 | },
22 | "short_description": {
23 | "type": "text",
24 | "required": true,
25 | "maxLength": 160
26 | },
27 | "description": {
28 | "type": "richtext",
29 | "required": true
30 | },
31 | "price": {
32 | "type": "decimal",
33 | "required": true,
34 | "default": 0
35 | },
36 | "release_date": {
37 | "type": "date"
38 | },
39 | "rating": {
40 | "type": "enumeration",
41 | "enum": [
42 | "BR0",
43 | "BR10",
44 | "BR12",
45 | "BR14",
46 | "BR16",
47 | "BR18"
48 | ]
49 | },
50 | "cover": {
51 | "model": "file",
52 | "via": "related",
53 | "allowedTypes": [
54 | "images"
55 | ],
56 | "plugin": "upload",
57 | "required": false
58 | },
59 | "gallery": {
60 | "collection": "file",
61 | "via": "related",
62 | "allowedTypes": [
63 | "images"
64 | ],
65 | "plugin": "upload",
66 | "required": false
67 | },
68 | "categories": {
69 | "collection": "category",
70 | "via": "games",
71 | "dominant": true
72 | },
73 | "developers": {
74 | "collection": "developer",
75 | "via": "games",
76 | "dominant": true
77 | },
78 | "platforms": {
79 | "collection": "platform",
80 | "via": "games",
81 | "dominant": true
82 | },
83 | "publisher": {
84 | "model": "publisher",
85 | "via": "games"
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/api/game/services/game.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | const axios = require("axios");
9 | const slugify = require("slugify");
10 | const qs = require("querystring");
11 |
12 | function Exception(e) {
13 | return { e, data: e.data && e.data.errors && e.data.errors };
14 | }
15 |
16 | function timeout(ms) {
17 | return new Promise((resolve) => setTimeout(resolve, ms));
18 | }
19 |
20 | async function getGameInfo(slug) {
21 | try {
22 | const jsdom = require("jsdom");
23 | const { JSDOM } = jsdom;
24 | const body = await axios.get(`https://www.gog.com/game/${slug}`);
25 | const dom = new JSDOM(body.data);
26 |
27 | const description = dom.window.document.querySelector(".description");
28 |
29 | return {
30 | rating: "BR0",
31 | short_description: description.textContent.trim().slice(0, 160),
32 | description: description.innerHTML,
33 | };
34 | } catch (e) {
35 | console.log("getGameInfo", Exception(e));
36 | }
37 | }
38 |
39 | async function getByName(name, entityName) {
40 | const item = await strapi.services[entityName].find({ name });
41 | return item.length ? item[0] : null;
42 | }
43 |
44 | async function create(name, entityName) {
45 | const item = await getByName(name, entityName);
46 |
47 | if (!item) {
48 | return await strapi.services[entityName].create({
49 | name,
50 | slug: slugify(name, { strict: true, lower: true }),
51 | });
52 | }
53 | }
54 |
55 | async function createManyToManyData(products) {
56 | const developers = new Set();
57 | const publishers = new Set();
58 | const categories = new Set();
59 | const platforms = new Set();
60 |
61 | products.forEach((product) => {
62 | const { developer, publisher, genres, supportedOperatingSystems } = product;
63 |
64 | genres?.forEach((item) => {
65 | categories.add(item);
66 | });
67 |
68 | supportedOperatingSystems?.forEach((item) => {
69 | platforms.add(item);
70 | });
71 |
72 | developers.add(developer);
73 | publishers.add(publisher);
74 | });
75 |
76 | const createCall = (set, entityName) => Array.from(set).map((name) => create(name, entityName));
77 |
78 | return Promise.all([
79 | ...createCall(developers, "developer"),
80 | ...createCall(publishers, "publisher"),
81 | ...createCall(categories, "category"),
82 | ...createCall(platforms, "platform"),
83 | ]);
84 | }
85 |
86 | async function setImage({ image, game, field = "cover" }) {
87 | try {
88 | const url = `https:${image}.jpg`;
89 | const { data } = await axios.get(url, { responseType: "arraybuffer" });
90 | const buffer = Buffer.from(data, "base64");
91 |
92 | const FormData = require("form-data");
93 | const formData = new FormData();
94 |
95 | formData.append("refId", game.id);
96 | formData.append("ref", "game");
97 | formData.append("field", field);
98 | formData.append("files", buffer, { filename: `${game.slug}.jpg` });
99 |
100 | console.info(`Uploading ${field} image: ${game.slug}.jpg`);
101 |
102 | await axios({
103 | method: "POST",
104 | url: `http://${strapi.config.host}:${strapi.config.port}/upload`,
105 | data: formData,
106 | headers: {
107 | "Content-Type": `multipart/form-data; boundary=${formData._boundary}`,
108 | },
109 | });
110 | } catch (e) {
111 | console.log("setImage", Exception(e));
112 | }
113 | }
114 |
115 | async function createGames(products) {
116 | await Promise.all(
117 | products.map(async (product) => {
118 | const item = await getByName(product.title, "game");
119 |
120 | if (!item) {
121 | console.info(`Creating: ${product.title}...`);
122 |
123 | const game = await strapi.services.game.create({
124 | name: product.title,
125 | slug: product.slug.replace(/_/g, "-"),
126 | price: product.price.amount,
127 | release_date: new Date(
128 | Number(product.globalReleaseDate) * 1000
129 | ).toISOString(),
130 | categories: await Promise.all(
131 | product.genres.map((name) => getByName(name, "category"))
132 | ),
133 | platforms: await Promise.all(
134 | product.supportedOperatingSystems.map((name) =>
135 | getByName(name, "platform")
136 | )
137 | ),
138 | developers: [await getByName(product.developer, "developer")],
139 | publisher: await getByName(product.publisher, "publisher"),
140 | ...(await getGameInfo(product.slug)),
141 | });
142 |
143 | await setImage({ image: product.image, game });
144 | await Promise.all(
145 | product.gallery
146 | .slice(0, 5)
147 | .map((url) => setImage({ image: url, game, field: "gallery" }))
148 | );
149 |
150 | await timeout(2000);
151 |
152 | return game;
153 | }
154 | })
155 | );
156 | }
157 |
158 | module.exports = {
159 | populate: async (params) => {
160 | try {
161 | const gogApiUrl = `https://www.gog.com/games/ajax/filtered?mediaType=game&${qs.stringify(
162 | params
163 | )}`;
164 |
165 | const {
166 | data: { products },
167 | } = await axios.get(gogApiUrl);
168 |
169 | await createManyToManyData(products);
170 | await createGames(products);
171 | } catch (e) {
172 | console.log("populate", Exception(e));
173 | }
174 | },
175 | };
176 |
--------------------------------------------------------------------------------
/api/home/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/home",
6 | "handler": "home.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "PUT",
13 | "path": "/home",
14 | "handler": "home.update",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "DELETE",
21 | "path": "/home",
22 | "handler": "home.delete",
23 | "config": {
24 | "policies": []
25 | }
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/api/home/controllers/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/home/models/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/home/models/home.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "homes",
4 | "info": {
5 | "name": "home"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true,
10 | "draftAndPublish": true
11 | },
12 | "attributes": {
13 | "newGames": {
14 | "type": "component",
15 | "repeatable": false,
16 | "component": "page.section"
17 | },
18 | "upcomingGames": {
19 | "type": "component",
20 | "repeatable": false,
21 | "component": "page.section"
22 | },
23 | "freeGames": {
24 | "type": "component",
25 | "repeatable": false,
26 | "component": "page.section"
27 | },
28 | "popularGames": {
29 | "type": "component",
30 | "repeatable": false,
31 | "component": "page.popular-games"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/api/home/services/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/order/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/orders",
6 | "handler": "order.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/orders/count",
14 | "handler": "order.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/orders/:id",
22 | "handler": "order.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/orders/create-payment-intent",
30 | "handler": "order.createPaymentIntent",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "POST",
37 | "path": "/orders",
38 | "handler": "order.create",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "PUT",
45 | "path": "/orders/:id",
46 | "handler": "order.update",
47 | "config": {
48 | "policies": []
49 | }
50 | },
51 | {
52 | "method": "DELETE",
53 | "path": "/orders/:id",
54 | "handler": "order.delete",
55 | "config": {
56 | "policies": []
57 | }
58 | }
59 | ]
60 | }
61 |
--------------------------------------------------------------------------------
/api/order/controllers/order.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const stripe = require("stripe")(process.env.STRIPE_KEY);
4 | const { sanitizeEntity } = require("strapi-utils");
5 | const orderTemplate = require("../../../config/email-templates/order");
6 |
7 | module.exports = {
8 | createPaymentIntent: async (ctx) => {
9 | const { cart } = ctx.request.body;
10 |
11 | // simplify cart data
12 | const cartGamesIds = await strapi.config.functions.cart.cartGamesIds(cart);
13 |
14 | // get all games
15 | const games = await strapi.config.functions.cart.cartItems(cartGamesIds);
16 |
17 | if (!games.length) {
18 | ctx.response.status = 404;
19 | return {
20 | error: "No valid games found!",
21 | };
22 | }
23 |
24 | const total = await strapi.config.functions.cart.total(games);
25 |
26 | if (total === 0) {
27 | return {
28 | freeGames: true,
29 | };
30 | }
31 |
32 | try {
33 | const paymentIntent = await stripe.paymentIntents.create({
34 | amount: total,
35 | currency: "usd",
36 | metadata: { cart: JSON.stringify(cartGamesIds) },
37 | });
38 |
39 | return paymentIntent;
40 | } catch (err) {
41 | return {
42 | error: err.raw.message,
43 | };
44 | }
45 | },
46 |
47 | create: async (ctx) => {
48 | // pegar as informações do frontend
49 | const { cart, paymentIntentId, paymentMethod } = ctx.request.body;
50 |
51 | // pega o token
52 | const token = await strapi.plugins[
53 | "users-permissions"
54 | ].services.jwt.getToken(ctx);
55 |
56 | // pega o id do usuario
57 | const userId = token.id;
58 |
59 | // pegar as informações do usuário
60 | const userInfo = await strapi
61 | .query("user", "users-permissions")
62 | .findOne({ id: userId });
63 |
64 | // simplify cart data
65 | const cartGamesIds = await strapi.config.functions.cart.cartGamesIds(cart);
66 |
67 | // pegar os jogos
68 | const games = await strapi.config.functions.cart.cartItems(cartGamesIds);
69 |
70 | // pegar o total (saber se é free ou não)
71 | const total_in_cents = await strapi.config.functions.cart.total(games);
72 |
73 | // precisa pegar do frontend os valores do paymentMethod
74 | // e recuperar por aqui
75 | let paymentInfo;
76 | if (total_in_cents !== 0) {
77 | try {
78 | paymentInfo = await stripe.paymentMethods.retrieve(paymentMethod);
79 | } catch (err) {
80 | ctx.response.status = 402;
81 | return { error: err.message };
82 | }
83 | }
84 |
85 | // salvar no banco
86 | const entry = {
87 | total_in_cents,
88 | payment_intent_id: paymentIntentId,
89 | card_brand: paymentInfo?.card?.brand,
90 | card_last4: paymentInfo?.card?.last4,
91 | user: userInfo,
92 | games,
93 | };
94 |
95 | const entity = await strapi.services.order.create(entry);
96 |
97 | // enviar um email da compra para o usuário
98 | await strapi.plugins["email-designer"].services.email.sendTemplatedEmail(
99 | {
100 | to: userInfo.email,
101 | from: "no-reply@wongames.com",
102 | },
103 | {
104 | templateId: 1,
105 | },
106 | {
107 | user: userInfo,
108 | payment: {
109 | total: `$ ${total_in_cents / 100}`,
110 | card_brand: entry.card_brand,
111 | card_last4: entry.card_last4,
112 | },
113 | games,
114 | }
115 | );
116 |
117 | // retornando que foi salvo no banco
118 | return sanitizeEntity(entity, { model: strapi.models.order });
119 | },
120 | };
121 |
--------------------------------------------------------------------------------
/api/order/models/order.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/order/models/order.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "orders",
4 | "info": {
5 | "name": "Order",
6 | "description": ""
7 | },
8 | "options": {
9 | "increments": true,
10 | "timestamps": true,
11 | "draftAndPublish": false
12 | },
13 | "attributes": {
14 | "user": {
15 | "plugin": "users-permissions",
16 | "model": "user"
17 | },
18 | "games": {
19 | "collection": "game"
20 | },
21 | "payment_intent_id": {
22 | "type": "string"
23 | },
24 | "card_brand": {
25 | "type": "string"
26 | },
27 | "card_last4": {
28 | "type": "string"
29 | },
30 | "total_in_cents": {
31 | "type": "biginteger"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/api/order/services/order.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/platform/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/platforms",
6 | "handler": "platform.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/platforms/count",
14 | "handler": "platform.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/platforms/:id",
22 | "handler": "platform.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/platforms",
30 | "handler": "platform.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/platforms/:id",
38 | "handler": "platform.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/platforms/:id",
46 | "handler": "platform.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/platform/controllers/platform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/platform/models/platform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/platform/models/platform.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "platforms",
4 | "info": {
5 | "name": "platform"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true
10 | },
11 | "attributes": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "unique": true
16 | },
17 | "slug": {
18 | "type": "uid",
19 | "targetField": "name",
20 | "required": true
21 | },
22 | "games": {
23 | "via": "platforms",
24 | "collection": "game"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/api/platform/services/platform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/publisher/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/publishers",
6 | "handler": "publisher.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/publishers/count",
14 | "handler": "publisher.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/publishers/:id",
22 | "handler": "publisher.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/publishers",
30 | "handler": "publisher.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/publishers/:id",
38 | "handler": "publisher.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/publishers/:id",
46 | "handler": "publisher.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/publisher/controllers/publisher.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/publisher/models/publisher.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/publisher/models/publisher.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "publishers",
4 | "info": {
5 | "name": "publisher"
6 | },
7 | "options": {
8 | "increments": true,
9 | "timestamps": true
10 | },
11 | "attributes": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "unique": true
16 | },
17 | "slug": {
18 | "type": "uid",
19 | "targetField": "name",
20 | "required": true
21 | },
22 | "games": {
23 | "via": "publisher",
24 | "collection": "game"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/api/publisher/services/publisher.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/v3.x/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/recommended/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/recommended",
6 | "handler": "recommended.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "PUT",
13 | "path": "/recommended",
14 | "handler": "recommended.update",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "DELETE",
21 | "path": "/recommended",
22 | "handler": "recommended.delete",
23 | "config": {
24 | "policies": []
25 | }
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/api/recommended/controllers/recommended.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
5 | * to customize this controller
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/recommended/models/recommended.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/recommended/models/recommended.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "recommendeds",
4 | "info": {
5 | "name": "recommended",
6 | "description": ""
7 | },
8 | "options": {
9 | "increments": true,
10 | "timestamps": true,
11 | "draftAndPublish": false
12 | },
13 | "attributes": {
14 | "section": {
15 | "type": "component",
16 | "repeatable": false,
17 | "component": "page.popular-games",
18 | "required": true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/api/recommended/services/recommended.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/wishlist/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/wishlists",
6 | "handler": "wishlist.find",
7 | "config": {
8 | "policies": []
9 | }
10 | },
11 | {
12 | "method": "GET",
13 | "path": "/wishlists/count",
14 | "handler": "wishlist.count",
15 | "config": {
16 | "policies": []
17 | }
18 | },
19 | {
20 | "method": "GET",
21 | "path": "/wishlists/:id",
22 | "handler": "wishlist.findOne",
23 | "config": {
24 | "policies": []
25 | }
26 | },
27 | {
28 | "method": "POST",
29 | "path": "/wishlists",
30 | "handler": "wishlist.create",
31 | "config": {
32 | "policies": []
33 | }
34 | },
35 | {
36 | "method": "PUT",
37 | "path": "/wishlists/:id",
38 | "handler": "wishlist.update",
39 | "config": {
40 | "policies": []
41 | }
42 | },
43 | {
44 | "method": "DELETE",
45 | "path": "/wishlists/:id",
46 | "handler": "wishlist.delete",
47 | "config": {
48 | "policies": []
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/api/wishlist/controllers/wishlist.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const { sanitizeEntity } = require("strapi-utils");
4 |
5 | /**
6 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers)
7 | * to customize this controller
8 | */
9 |
10 | module.exports = {
11 | async create(ctx) {
12 | const token = await strapi.plugins[
13 | "users-permissions"
14 | ].services.jwt.getToken(ctx);
15 |
16 | const body = {
17 | ...ctx.request.body,
18 | user: token.id,
19 | };
20 |
21 | const entity = await strapi.services.wishlist.create(body);
22 | return sanitizeEntity(entity, { model: strapi.models.wishlist });
23 | },
24 |
25 | async update(ctx) {
26 | try {
27 | const entity = await strapi.services.wishlist.update(
28 | { id: ctx.params.id },
29 | ctx.request.body
30 | );
31 | return sanitizeEntity(entity, { model: strapi.models.wishlist });
32 | } catch (err) {
33 | throw strapi.errors.unauthorized(err);
34 | }
35 | },
36 | };
37 |
--------------------------------------------------------------------------------
/api/wishlist/models/wishlist.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/models.html#lifecycle-hooks)
5 | * to customize this model
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/api/wishlist/models/wishlist.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "wishlists",
4 | "info": {
5 | "name": "Wishlist",
6 | "description": ""
7 | },
8 | "options": {
9 | "increments": true,
10 | "timestamps": true,
11 | "draftAndPublish": false
12 | },
13 | "attributes": {
14 | "user": {
15 | "unique": true,
16 | "plugin": "users-permissions",
17 | "model": "user"
18 | },
19 | "games": {
20 | "collection": "game"
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/api/wishlist/services/wishlist.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/services.html#core-services)
5 | * to customize this service
6 | */
7 |
8 | module.exports = {};
9 |
--------------------------------------------------------------------------------
/components/page/button.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_page_buttons",
3 | "info": {
4 | "name": "button",
5 | "icon": "link"
6 | },
7 | "options": {},
8 | "attributes": {
9 | "label": {
10 | "type": "string",
11 | "required": true,
12 | "default": "Buy now"
13 | },
14 | "link": {
15 | "type": "string",
16 | "required": true
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/components/page/highlight.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_page_highlights",
3 | "info": {
4 | "name": "highlight",
5 | "icon": "star"
6 | },
7 | "options": {},
8 | "attributes": {
9 | "title": {
10 | "type": "string",
11 | "required": true
12 | },
13 | "subtitle": {
14 | "type": "text",
15 | "required": true
16 | },
17 | "background": {
18 | "model": "file",
19 | "via": "related",
20 | "allowedTypes": [
21 | "images"
22 | ],
23 | "plugin": "upload",
24 | "required": true
25 | },
26 | "floatImage": {
27 | "model": "file",
28 | "via": "related",
29 | "allowedTypes": [
30 | "images"
31 | ],
32 | "plugin": "upload",
33 | "required": false
34 | },
35 | "buttonLabel": {
36 | "type": "string",
37 | "required": true
38 | },
39 | "buttonLink": {
40 | "type": "string",
41 | "required": true
42 | },
43 | "alignment": {
44 | "type": "enumeration",
45 | "enum": [
46 | "right",
47 | "left"
48 | ],
49 | "default": "right"
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/components/page/popular-games.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_page_popular_games",
3 | "info": {
4 | "name": "popularGames",
5 | "icon": "star-of-life"
6 | },
7 | "options": {},
8 | "attributes": {
9 | "title": {
10 | "type": "string",
11 | "required": true
12 | },
13 | "highlight": {
14 | "type": "component",
15 | "repeatable": false,
16 | "component": "page.highlight"
17 | },
18 | "games": {
19 | "collection": "game"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/components/page/ribbon.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_page_ribbons",
3 | "info": {
4 | "name": "ribbon",
5 | "icon": "ribbon"
6 | },
7 | "options": {},
8 | "attributes": {
9 | "text": {
10 | "type": "string",
11 | "maxLength": 30
12 | },
13 | "color": {
14 | "type": "enumeration",
15 | "enum": [
16 | "primary",
17 | "secondary"
18 | ],
19 | "default": "primary"
20 | },
21 | "size": {
22 | "type": "enumeration",
23 | "enum": [
24 | "small",
25 | "normal"
26 | ],
27 | "default": "normal"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/components/page/section.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_page_sections",
3 | "info": {
4 | "name": "section",
5 | "icon": "align-justify"
6 | },
7 | "options": {},
8 | "attributes": {
9 | "title": {
10 | "type": "string"
11 | },
12 | "highlight": {
13 | "type": "component",
14 | "repeatable": false,
15 | "component": "page.highlight"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/config/database.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | defaultConnection: 'default',
3 | connections: {
4 | default: {
5 | connector: 'bookshelf',
6 | settings: {
7 | client: 'postgres',
8 | host: env('DATABASE_HOST', '127.0.0.1'),
9 | port: env.int('DATABASE_PORT', 5432),
10 | database: env('DATABASE_NAME', 'wongames'),
11 | username: env('DATABASE_USERNAME', 'wongames'),
12 | password: env('DATABASE_PASSWORD', 'wongames123'),
13 | ssl: env.bool('DATABASE_SSL', false),
14 | },
15 | options: {}
16 | },
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/config/email-templates/order.js:
--------------------------------------------------------------------------------
1 | const subject = "Order at Won Games";
2 |
3 | const text = `
4 | Hi <%= user.username %>, thanks for buying at Won Games!
5 | Follow the info of your order:
6 |
7 | Card Information:
8 |
9 | Card brand: <%= payment.card_brand %>
10 | Card number: **** **** **** <%= payment.card_last4 %>
11 |
12 | Total: <%= payment.total %>
13 |
14 | Games:
15 |
16 | <% _.forEach(games, function(game) { %>
17 | <%= game.name %> - Price: $<%= Number(game.price).toFixed(2) %>
18 | <% }); %>
19 | `;
20 |
21 | const html = `
22 |
Hi <%= user.username %>, thanks for buying at Won Games!
23 | Follow the info of your order:
24 |
25 | Card Information
26 |
27 |
28 | - Card brand: <%= payment.card_brand %>
29 | - Card number: **** **** **** <%= payment.card_last4 %>
30 |
31 |
32 | Total: <%= payment.total %>
33 |
34 |
35 |
36 | Games
37 |
38 |
39 | <% _.forEach(games, function(game) { %>
40 | - <%= game.name %> - Price: $<%= Number(game.price).toFixed(2) %>
41 | <% }); %>
42 |
43 | `;
44 |
45 | module.exports = {
46 | subject,
47 | text,
48 | html,
49 | };
50 |
--------------------------------------------------------------------------------
/config/env/development/plugins.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | email: {
3 | provider: "nodemailer",
4 | providerOptions: {
5 | host: "localhost",
6 | port: 1025,
7 | ignoreTLS: true,
8 | },
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/config/env/production/database.js:
--------------------------------------------------------------------------------
1 | const parse = require('pg-connection-string').parse;
2 | const config = parse(process.env.DATABASE_URL);
3 |
4 | module.exports = ({ env }) => ({
5 | defaultConnection: 'default',
6 | connections: {
7 | default: {
8 | connector: 'bookshelf',
9 | settings: {
10 | client: 'postgres',
11 | host: config.host,
12 | port: config.port,
13 | database: config.database,
14 | username: config.user,
15 | password: config.password,
16 | ssl: {
17 | rejectUnauthorized: false,
18 | },
19 | },
20 | options: {
21 | ssl: true,
22 | },
23 | },
24 | },
25 | });
26 |
--------------------------------------------------------------------------------
/config/env/production/plugins.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | email: {
3 | provider: "nodemailer",
4 | providerOptions: {
5 | host: env("SMTP_HOST", "smtp-relay.sendinblue.com"),
6 | port: env("SMTP_PORT", 587),
7 | auth: {
8 | user: env("SMTP_USERNAME"),
9 | pass: env("SMTP_PASSWORD"),
10 | },
11 | },
12 | settings: {
13 | defaultFrom: "wongames@gmail.com",
14 | defaultReplyTo: "contact@gmail.com",
15 | },
16 | },
17 | upload: {
18 | provider: "cloudinary",
19 | providerOptions: {
20 | cloud_name: env("CLOUDINARY_NAME"),
21 | api_key: env("CLOUDINARY_KEY"),
22 | api_secret: env("CLOUDINARY_SECRET"),
23 | },
24 | actionOptions: {
25 | upload: {},
26 | delete: {},
27 | },
28 | },
29 | });
30 |
--------------------------------------------------------------------------------
/config/env/production/server.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | url: env('MY_HEROKU_URL'),
3 | });
4 |
--------------------------------------------------------------------------------
/config/functions/bootstrap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * An asynchronous bootstrap function that runs before
5 | * your application gets started.
6 | *
7 | * This gives you an opportunity to set up your data model,
8 | * run jobs, or perform some special logic.
9 | *
10 | * See more details here: https://strapi.io/documentation/v3.x/concepts/configurations.html#bootstrap
11 | */
12 |
13 | module.exports = () => {};
14 |
--------------------------------------------------------------------------------
/config/functions/cart.js:
--------------------------------------------------------------------------------
1 | const cartGamesIds = async (cart) => {
2 | return await cart.map((game) => ({
3 | id: game.id,
4 | }));
5 | };
6 |
7 | const cartItems = async (cart) => {
8 | let games = [];
9 |
10 | await Promise.all(
11 | cart?.map(async (game) => {
12 | const validatedGame = await strapi.services.game.findOne({
13 | id: game.id,
14 | });
15 |
16 | if (validatedGame) {
17 | games.push(validatedGame);
18 | }
19 | })
20 | );
21 |
22 | return games;
23 | };
24 |
25 | const total = async (games) => {
26 | const amount = await games.reduce((acc, game) => {
27 | return acc + game.price;
28 | }, 0);
29 |
30 | return Number((amount * 100).toFixed(0));
31 | };
32 |
33 | module.exports = {
34 | cartGamesIds,
35 | cartItems,
36 | total,
37 | };
38 |
--------------------------------------------------------------------------------
/config/functions/cron.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Cron config that gives you an opportunity
5 | * to run scheduled jobs.
6 | *
7 | * The cron format consists of:
8 | * [SECOND (optional)] [MINUTE] [HOUR] [DAY OF MONTH] [MONTH OF YEAR] [DAY OF WEEK]
9 | *
10 | * See more details here: https://strapi.io/documentation/v3.x/concepts/configurations.html#cron-tasks
11 | */
12 |
13 | module.exports = {
14 | /**
15 | * Simple example.
16 | * Every monday at 1am.
17 | */
18 | // '0 1 * * 1': () => {
19 | //
20 | // }
21 | };
22 |
--------------------------------------------------------------------------------
/config/functions/responses/404.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = async (/* ctx */) => {
4 | // return ctx.notFound('My custom message 404');
5 | };
6 |
--------------------------------------------------------------------------------
/config/plugins.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | graphql: {
3 | endpoint: '/graphql',
4 | shadowCRUD: true,
5 | playgroundAlways: false,
6 | depthLimit: 7,
7 | amountLimit: 10000,
8 | disabledPlugins: [],
9 | disabledExtensions: [],
10 | apolloServer: {
11 | tracing: true,
12 | },
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/server.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | host: env('HOST', '0.0.0.0'),
3 | port: env.int('PORT', 1337),
4 | admin: {
5 | auth: {
6 | secret: env('ADMIN_JWT_SECRET', '9e6c3672861d765b7502ba0fa53c3aa2'),
7 | },
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/extensions/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Won-Games/api/b69dbeaafa31dfddf77888fac1dcedabac798c6b/extensions/.gitkeep
--------------------------------------------------------------------------------
/extensions/users-permissions/config/jwt.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | jwtSecret: process.env.JWT_SECRET || '7195cf73-24de-41eb-9a0c-304d31d16816'
3 | };
--------------------------------------------------------------------------------
/extensions/users-permissions/models/User.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "users-permissions_user",
4 | "info": {
5 | "name": "user",
6 | "description": ""
7 | },
8 | "options": {
9 | "draftAndPublish": false,
10 | "timestamps": true
11 | },
12 | "attributes": {
13 | "username": {
14 | "type": "string",
15 | "minLength": 3,
16 | "unique": true,
17 | "configurable": false,
18 | "required": true
19 | },
20 | "email": {
21 | "type": "email",
22 | "minLength": 6,
23 | "configurable": false,
24 | "required": true
25 | },
26 | "provider": {
27 | "type": "string",
28 | "configurable": false
29 | },
30 | "password": {
31 | "type": "password",
32 | "minLength": 6,
33 | "configurable": false,
34 | "private": true
35 | },
36 | "resetPasswordToken": {
37 | "type": "string",
38 | "configurable": false,
39 | "private": true
40 | },
41 | "confirmationToken": {
42 | "type": "string",
43 | "configurable": false,
44 | "private": true
45 | },
46 | "confirmed": {
47 | "type": "boolean",
48 | "default": false,
49 | "configurable": false
50 | },
51 | "blocked": {
52 | "type": "boolean",
53 | "default": false,
54 | "configurable": false
55 | },
56 | "role": {
57 | "model": "role",
58 | "via": "users",
59 | "plugin": "users-permissions",
60 | "configurable": false
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Won-Games/api/b69dbeaafa31dfddf77888fac1dcedabac798c6b/favicon.ico
--------------------------------------------------------------------------------
/migrate-3.4.0.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 |
4 | const ONE_RELATIONS = ['oneToOne', 'manyToOne', 'oneWay'];
5 |
6 | const createStrapiApp = async projectPath => {
7 | if (!projectPath) {
8 | throw new Error(`
9 | -> Path to strapi project is missing.
10 | -> Usage: node migrate-3.4.0.js [path]`);
11 | }
12 |
13 | let strapi;
14 | let app;
15 | try {
16 | strapi = require(require.resolve('strapi', { paths: [projectPath] }));
17 | const pkgJSON = require(path.resolve(projectPath, 'package.json'));
18 | if (!pkgJSON || !pkgJSON.dependencies || !pkgJSON.dependencies.strapi) {
19 | throw new Error();
20 | }
21 | } catch (e) {
22 | throw new Error(`
23 | -> Strapi lib couldn\'t be found. Are the node_modules installed?
24 | -> Fix: yarn install or npm install`);
25 | }
26 |
27 | try {
28 | app = await strapi({ dir: projectPath }).load();
29 | } catch (e) {
30 | throw new Error(`
31 | -> The migration couldn't be proceed because Strapi app couldn't start.
32 | -> ${e.message}`);
33 | }
34 |
35 | return app;
36 | };
37 |
38 | const isSortableRFAssoc = a =>
39 | ONE_RELATIONS.includes(a.nature) && !['created_by', 'updated_by'].includes(a.alias);
40 |
41 | const run = async () => {
42 | const projectPath = process.argv[2];
43 | const app = await createStrapiApp(projectPath);
44 |
45 | const contentTypeService = app.plugins['content-manager'].services['content-types'];
46 |
47 | for (const uid of Object.keys(app.contentTypes)) {
48 | const modelDef = app.getModel(uid);
49 | const manyRelationFields = modelDef.associations.filter(isSortableRFAssoc);
50 | if (manyRelationFields.length) {
51 | const conf = await contentTypeService.findConfiguration({ uid });
52 | manyRelationFields.forEach(assoc => {
53 | try {
54 | conf.metadatas[assoc.alias].list.sortable = true;
55 | } catch (e) {
56 | // silence
57 | }
58 | });
59 | await contentTypeService.updateConfiguration({ uid }, conf);
60 | }
61 | }
62 | };
63 |
64 | run()
65 | .catch(e => {
66 | console.error(e);
67 | process.exit(1);
68 | })
69 | .then(() => {
70 | console.log('Migration successfully finished! 🎉');
71 | process.exit(0);
72 | });
73 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "private": true,
4 | "version": "0.1.0",
5 | "description": "A Strapi application",
6 | "scripts": {
7 | "develop": "strapi develop",
8 | "start": "strapi start",
9 | "build": "strapi build",
10 | "strapi": "strapi"
11 | },
12 | "devDependencies": {},
13 | "dependencies": {
14 | "jsdom": "^16.5.3",
15 | "knex": "0.95.6",
16 | "pg": "^8.7.1",
17 | "pg-connection-string": "^2.5.0",
18 | "slugify": "^1.5.3",
19 | "strapi": "3.6.2",
20 | "strapi-admin": "3.6.2",
21 | "strapi-connector-bookshelf": "3.6.2",
22 | "strapi-plugin-ckeditor5": "^1.11.0",
23 | "strapi-plugin-content-manager": "3.6.2",
24 | "strapi-plugin-content-type-builder": "3.6.2",
25 | "strapi-plugin-email": "3.6.2",
26 | "strapi-plugin-email-designer": "^0.4.1",
27 | "strapi-plugin-entity-relationship-chart": "3.1.0",
28 | "strapi-plugin-graphql": "3.6.2",
29 | "strapi-plugin-sync-roles-permissions": "^0.4.2",
30 | "strapi-plugin-upload": "3.6.2",
31 | "strapi-plugin-users-permissions": "3.6.2",
32 | "strapi-provider-email-nodemailer": "^3.6.2",
33 | "strapi-provider-upload-cloudinary": "^3.6.2",
34 | "strapi-utils": "3.6.2",
35 | "stripe": "^8.148.0"
36 | },
37 | "author": {
38 | "name": "A Strapi developer"
39 | },
40 | "strapi": {
41 | "uuid": "d5828e28-e5df-4086-a82a-0d6c415cd518"
42 | },
43 | "engines": {
44 | "node": ">=10.16.0 <=14.x.x",
45 | "npm": ">=6.0.0"
46 | },
47 | "license": "MIT"
48 | }
49 |
--------------------------------------------------------------------------------
/plugins/repositories/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = false
6 | indent_style = space
7 | indent_size = 2
8 |
--------------------------------------------------------------------------------
/plugins/repositories/.gitattributes:
--------------------------------------------------------------------------------
1 | # From https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes
2 |
3 | # Handle line endings automatically for files detected as text
4 | # and leave all files detected as binary untouched.
5 | * text=auto
6 |
7 | #
8 | # The above will handle all files NOT found below
9 | #
10 |
11 | #
12 | ## These files are text and should be normalized (Convert crlf => lf)
13 | #
14 |
15 | # source code
16 | *.php text
17 | *.css text
18 | *.sass text
19 | *.scss text
20 | *.less text
21 | *.styl text
22 | *.js text eol=lf
23 | *.coffee text
24 | *.json text
25 | *.htm text
26 | *.html text
27 | *.xml text
28 | *.svg text
29 | *.txt text
30 | *.ini text
31 | *.inc text
32 | *.pl text
33 | *.rb text
34 | *.py text
35 | *.scm text
36 | *.sql text
37 | *.sh text
38 | *.bat text
39 |
40 | # templates
41 | *.ejs text
42 | *.hbt text
43 | *.jade text
44 | *.haml text
45 | *.hbs text
46 | *.dot text
47 | *.tmpl text
48 | *.phtml text
49 |
50 | # git config
51 | .gitattributes text
52 | .gitignore text
53 | .gitconfig text
54 |
55 | # code analysis config
56 | .jshintrc text
57 | .jscsrc text
58 | .jshintignore text
59 | .csslintrc text
60 |
61 | # misc config
62 | *.yaml text
63 | *.yml text
64 | .editorconfig text
65 |
66 | # build config
67 | *.npmignore text
68 | *.bowerrc text
69 |
70 | # Heroku
71 | Procfile text
72 | .slugignore text
73 |
74 | # Documentation
75 | *.md text
76 | LICENSE text
77 | AUTHORS text
78 |
79 |
80 | #
81 | ## These files are binary and should be left untouched
82 | #
83 |
84 | # (binary is a macro for -text -diff)
85 | *.png binary
86 | *.jpg binary
87 | *.jpeg binary
88 | *.gif binary
89 | *.ico binary
90 | *.mov binary
91 | *.mp4 binary
92 | *.mp3 binary
93 | *.flv binary
94 | *.fla binary
95 | *.swf binary
96 | *.gz binary
97 | *.zip binary
98 | *.7z binary
99 | *.ttf binary
100 | *.eot binary
101 | *.woff binary
102 | *.pyc binary
103 | *.pdf binary
104 |
--------------------------------------------------------------------------------
/plugins/repositories/.gitignore:
--------------------------------------------------------------------------------
1 | # Don't check auto-generated stuff into git
2 | coverage
3 | node_modules
4 | stats.json
5 | package-lock.json
6 |
7 | # Cruft
8 | .DS_Store
9 | npm-debug.log
10 | .idea
11 |
--------------------------------------------------------------------------------
/plugins/repositories/README.md:
--------------------------------------------------------------------------------
1 | # Strapi plugin repositories
2 |
3 | A quick description of repositories.
4 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/containers/App/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * This component is the skeleton around the actual pages, and should only
4 | * contain code that should be seen on all pages. (e.g. navigation bar)
5 | *
6 | */
7 |
8 | import React from 'react';
9 | import { Switch, Route } from 'react-router-dom';
10 | import { NotFound } from 'strapi-helper-plugin';
11 | // Utils
12 | import pluginId from '../../pluginId';
13 | // Containers
14 | import HomePage from '../HomePage';
15 |
16 | const App = () => {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | };
26 |
27 | export default App;
28 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/containers/HomePage/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, memo } from "react";
2 | import { Header } from "@buffetjs/custom";
3 | import { Table } from "@buffetjs/core";
4 | import styled from "styled-components";
5 | import axios from "axios";
6 |
7 | const Wrapper = styled.div`
8 | padding: 18px 30px;
9 |
10 | p {
11 | margin-top: 1rem;
12 | }
13 | `;
14 |
15 | const HomePage = () => {
16 | const [rows, setRows] = useState([]);
17 |
18 | useEffect(() => {
19 | axios
20 | .get("https://api.github.com/users/React-avancado/repos")
21 | .then((res) => setRows(res.data))
22 | .catch((e) => strapi.notification.error(`Ops...github API error, ${e}`));
23 | }, []);
24 |
25 | const headers = [
26 | {
27 | name: "Name",
28 | value: "name",
29 | },
30 | {
31 | name: "Description",
32 | value: "description",
33 | },
34 | {
35 | name: "Url",
36 | value: "html_url",
37 | },
38 | ];
39 |
40 | return (
41 |
42 |
46 | window.open(data.html_url, "_blank")}
50 | />
51 |
52 | );
53 | };
54 |
55 | export default memo(HomePage);
56 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/containers/Initializer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Initializer
4 | *
5 | */
6 |
7 | import { useEffect, useRef } from 'react';
8 | import PropTypes from 'prop-types';
9 | import pluginId from '../../pluginId';
10 |
11 | const Initializer = ({ updatePlugin }) => {
12 | const ref = useRef();
13 | ref.current = updatePlugin;
14 |
15 | useEffect(() => {
16 | ref.current(pluginId, 'isReady', true);
17 | }, []);
18 |
19 | return null;
20 | };
21 |
22 | Initializer.propTypes = {
23 | updatePlugin: PropTypes.func.isRequired,
24 | };
25 |
26 | export default Initializer;
27 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/index.js:
--------------------------------------------------------------------------------
1 | import pluginPkg from '../../package.json';
2 | import pluginId from './pluginId';
3 | import App from './containers/App';
4 | import Initializer from './containers/Initializer';
5 | import lifecycles from './lifecycles';
6 | import trads from './translations';
7 |
8 | export default strapi => {
9 | const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
10 | const icon = pluginPkg.strapi.icon;
11 | const name = pluginPkg.strapi.name;
12 |
13 | const plugin = {
14 | blockerComponent: null,
15 | blockerComponentProps: {},
16 | description: pluginDescription,
17 | icon,
18 | id: pluginId,
19 | initializer: Initializer,
20 | injectedComponents: [],
21 | isReady: false,
22 | isRequired: pluginPkg.strapi.required || false,
23 | layout: null,
24 | lifecycles,
25 | mainComponent: App,
26 | name,
27 | preventComponentRendering: false,
28 | trads,
29 | menu: {
30 | pluginsSectionLinks: [
31 | {
32 | destination: `/plugins/${pluginId}`,
33 | icon,
34 | label: {
35 | id: `${pluginId}.plugin.name`,
36 | defaultMessage: name,
37 | },
38 | name,
39 | permissions: [
40 | // Uncomment to set the permissions of the plugin here
41 | // {
42 | // action: '', // the action name should be plugins::plugin-name.actionType
43 | // subject: null,
44 | // },
45 | ],
46 | },
47 | ],
48 | },
49 | };
50 |
51 | return strapi.registerPlugin(plugin);
52 | };
53 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/lifecycles.js:
--------------------------------------------------------------------------------
1 | function lifecycles() {}
2 |
3 | export default lifecycles;
4 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/pluginId.js:
--------------------------------------------------------------------------------
1 | const pluginPkg = require('../../package.json');
2 | const pluginId = pluginPkg.name.replace(
3 | /^strapi-plugin-/i,
4 | ''
5 | );
6 |
7 | module.exports = pluginId;
8 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/ar.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/cs.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/de.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/en.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/es.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/fr.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/index.js:
--------------------------------------------------------------------------------
1 | import ar from './ar.json';
2 | import cs from './cs.json';
3 | import de from './de.json';
4 | import en from './en.json';
5 | import es from './es.json';
6 | import fr from './fr.json';
7 | import it from './it.json';
8 | import ko from './ko.json';
9 | import ms from './ms.json';
10 | import nl from './nl.json';
11 | import pl from './pl.json';
12 | import ptBR from './pt-BR.json';
13 | import pt from './pt.json';
14 | import ru from './ru.json';
15 | import tr from './tr.json';
16 | import uk from './uk.json';
17 | import vi from './vi.json';
18 | import zhHans from './zh-Hans.json';
19 | import zh from './zh.json';
20 | import sk from './sk.json';
21 |
22 | const trads = {
23 | ar,
24 | cs,
25 | de,
26 | en,
27 | es,
28 | fr,
29 | it,
30 | ko,
31 | ms,
32 | nl,
33 | pl,
34 | 'pt-BR': ptBR,
35 | pt,
36 | ru,
37 | tr,
38 | uk,
39 | vi,
40 | 'zh-Hans': zhHans,
41 | zh,
42 | sk,
43 | };
44 |
45 | export default trads;
46 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/it.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/ko.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/ms.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/nl.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/pl.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/pt-BR.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/pt.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/ru.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/sk.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/tr.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/uk.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/vi.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/zh-Hans.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/translations/zh.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/plugins/repositories/admin/src/utils/getTrad.js:
--------------------------------------------------------------------------------
1 | import pluginId from '../pluginId';
2 |
3 | const getTrad = id => `${pluginId}.${id}`;
4 |
5 | export default getTrad;
6 |
--------------------------------------------------------------------------------
/plugins/repositories/config/routes.json:
--------------------------------------------------------------------------------
1 | {
2 | "routes": [
3 | {
4 | "method": "GET",
5 | "path": "/",
6 | "handler": "repositories.index",
7 | "config": {
8 | "policies": []
9 | }
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/plugins/repositories/controllers/repositories.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * repositories.js controller
5 | *
6 | * @description: A set of functions called "actions" of the `repositories` plugin.
7 | */
8 |
9 | module.exports = {
10 |
11 | /**
12 | * Default action.
13 | *
14 | * @return {Object}
15 | */
16 |
17 | index: async (ctx) => {
18 | // Add your own logic here.
19 |
20 | // Send 200 `ok`
21 | ctx.send({
22 | message: 'ok'
23 | });
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/plugins/repositories/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "strapi-plugin-repositories",
3 | "version": "0.0.0",
4 | "description": "A list of our repositories in React Avançado course.",
5 | "strapi": {
6 | "name": "Repositories",
7 | "icon": "code",
8 | "description": "A list of our repositories in React Avançado course."
9 | },
10 | "dependencies": {},
11 | "author": {
12 | "name": "A Strapi developer",
13 | "email": "",
14 | "url": ""
15 | },
16 | "maintainers": [
17 | {
18 | "name": "A Strapi developer",
19 | "email": "",
20 | "url": ""
21 | }
22 | ],
23 | "engines": {
24 | "node": ">=10.0.0",
25 | "npm": ">=6.0.0"
26 | },
27 | "license": "MIT"
28 | }
29 |
--------------------------------------------------------------------------------
/plugins/repositories/services/repositories.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * repositories.js service
5 | *
6 | * @description: A set of functions similar to controller's actions to avoid code duplication.
7 | */
8 |
9 | module.exports = {
10 |
11 | };
12 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines:
2 | # User-Agent: *
3 | # Disallow: /
4 |
--------------------------------------------------------------------------------
/public/uploads/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Won-Games/api/b69dbeaafa31dfddf77888fac1dcedabac798c6b/public/uploads/.gitkeep
--------------------------------------------------------------------------------