├── .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 | [![DigitalOcean Referral Badge](https://web-platforms.sfo2.digitaloceanspaces.com/WWW/Badge%203.svg)](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 |
15 | Mantido por 16 | 22 | React Avançado 23 | 24 |
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 = () => Won Games; 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 | 31 | 32 |

Total: <%= payment.total %>

33 | 34 |
35 | 36 |

Games

37 | 38 | 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 --------------------------------------------------------------------------------