├── .all-contributorsrc ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .vscode └── settings.json ├── CODETOUR.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── components ├── Breadcrumb │ ├── Breadcrumb.js │ └── index.js ├── Carousel │ ├── Carousel.js │ └── index.js ├── Icons │ ├── Arrow.js │ ├── Bookmark.js │ ├── Chevron.js │ ├── Cog.js │ ├── Hamburger.js │ ├── Heart.js │ ├── Rupee.js │ ├── Save.js │ ├── Search.js │ ├── Share.js │ └── User.js ├── Item │ ├── Item.js │ ├── README.md │ ├── __tests__ │ │ ├── Item.test.js │ │ └── __snapshots__ │ │ │ └── Item.test.js.snap │ └── index.js ├── NavBar │ ├── NavBar.js │ ├── README.md │ ├── __tests__ │ │ ├── Navbar.test.js │ │ └── __snapshots__ │ │ │ └── Navbar.test.js.snap │ └── index.js ├── ProductInfo │ ├── ProductInfo.js │ └── index.js └── QuantityButton │ ├── QuantityButton.js │ └── index.js ├── constants └── links.js ├── jest.setup.js ├── now.json ├── package-lock.json ├── package.json ├── pages ├── _document.js ├── about.js ├── index.js └── product.js ├── public └── images │ ├── logo.png │ ├── placeholder.png │ └── upay.png ├── server ├── api │ └── index.js ├── config.js └── index.js └── styleguide.config.js /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "Upay", 3 | "projectOwner": "GirlScriptSummerOfCode", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": [ 7 | "README.md" 8 | ], 9 | "imageSize": 100, 10 | "commit": true, 11 | "contributors": [ 12 | { 13 | "login": "MadhavBahlMD", 14 | "name": "MADHAV BAHL", 15 | "avatar_url": "https://avatars2.githubusercontent.com/u/26179770?v=4", 16 | "profile": "http://madhavbahl.tech/", 17 | "contributions": [ 18 | "code" 19 | ] 20 | }, 21 | { 22 | "login": "kryptokinght", 23 | "name": "Minanshu Singh", 24 | "avatar_url": "https://avatars2.githubusercontent.com/u/21311242?v=4", 25 | "profile": "https://github.com/kryptokinght", 26 | "contributions": [ 27 | "code" 28 | ] 29 | }, 30 | { 31 | "login": "sambhav2612", 32 | "name": "Sambhav Jain", 33 | "avatar_url": "https://avatars3.githubusercontent.com/u/19583619?v=4", 34 | "profile": "https://sourcerer.io/sambhav2612", 35 | "contributions": [ 36 | "doc" 37 | ] 38 | }, 39 | { 40 | "login": "SakshiShreya", 41 | "name": "Sakshi Shreya", 42 | "avatar_url": "https://avatars2.githubusercontent.com/u/15413534?v=4", 43 | "profile": "https://github.com/SakshiShreya", 44 | "contributions": [ 45 | "code" 46 | ] 47 | }, 48 | { 49 | "login": "adarshlilha", 50 | "name": "Adarsh Lilha", 51 | "avatar_url": "https://avatars1.githubusercontent.com/u/13575704?v=4", 52 | "profile": "https://github.com/adarshlilha", 53 | "contributions": [ 54 | "code" 55 | ] 56 | }, 57 | { 58 | "login": "Nshul", 59 | "name": "Anshul Mittal", 60 | "avatar_url": "https://avatars3.githubusercontent.com/u/26252118?v=4", 61 | "profile": "https://github.com/Nshul", 62 | "contributions": [ 63 | "code" 64 | ] 65 | }, 66 | { 67 | "login": "twishasaraiya", 68 | "name": "Twisha", 69 | "avatar_url": "https://avatars2.githubusercontent.com/u/24837027?v=4", 70 | "profile": "https://twishasaraiya.github.io/", 71 | "contributions": [ 72 | "code" 73 | ] 74 | }, 75 | { 76 | "login": "bogas04", 77 | "name": "Divjot Singh", 78 | "avatar_url": "https://avatars3.githubusercontent.com/u/6177621?v=4", 79 | "profile": "http://bogas04.github.io", 80 | "contributions": [ 81 | "code" 82 | ] 83 | } 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: true, 5 | es6: true, 6 | node: true, 7 | }, 8 | extends: 'eslint:recommended', 9 | parser: 'babel-eslint', 10 | parserOptions: { 11 | sourceType: 'module', 12 | ecmaVersion: 2018, 13 | ecmaFeatures: { 14 | jsx: true, 15 | }, 16 | }, 17 | plugins: ['react'], 18 | rules: { 19 | indent: ['error', 2, { SwitchCase: 1 }], 20 | 'linebreak-style': ['error', 'unix'], 21 | quotes: ['error', 'single', { allowTemplateLiterals: true }], 22 | semi: ['error', 'always'], 23 | 'react/jsx-uses-vars': 1, 24 | 'react/jsx-uses-react': 1, 25 | 'spaced-comment': ['error', 'always', { exceptions: ['-', '+'] }], 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## GITATTRIBUTES FOR WEB PROJECTS 2 | # 3 | # These settings are for any web project. 4 | # 5 | # Details per file setting: 6 | # text These files should be normalized (i.e. convert CRLF to LF). 7 | # binary These files are binary and should be left untouched. 8 | # 9 | # Note that binary is a macro for -text -diff. 10 | ###################################################################### 11 | 12 | ## AUTO-DETECT 13 | ## Handle line endings automatically for files detected as 14 | ## text and leave all files detected as binary untouched. 15 | ## This will handle all files NOT defined below. 16 | * text=auto 17 | 18 | ## SOURCE CODE 19 | *.bat text eol=crlf 20 | *.coffee text 21 | *.css text eol=lf 22 | *.htm text 23 | *.html text eol=lf 24 | *.inc text 25 | *.ini text 26 | *.js text eol=lf 27 | *.json text eol=lf 28 | *.jsx text eol=lf 29 | *.less text 30 | *.od text 31 | *.onlydata text 32 | *.php text 33 | *.pl text 34 | *.py text 35 | *.rb text 36 | *.sass text 37 | *.scm text 38 | *.scss text 39 | *.sh text eol=lf 40 | *.sql text 41 | *.styl text 42 | *.tag text 43 | *.ts text eol=lf 44 | *.tsx text eol=lf 45 | *.xml text 46 | *.xhtml text 47 | 48 | ## DOCKER 49 | *.dockerignore text 50 | Dockerfile text 51 | 52 | ## DOCUMENTATION 53 | *.markdown text 54 | *.md text 55 | *.mdwn text 56 | *.mdown text 57 | *.mkd text 58 | *.mkdn text 59 | *.mdtxt text 60 | *.mdtext text 61 | *.txt text 62 | AUTHORS text 63 | CHANGELOG text 64 | CHANGES text 65 | CONTRIBUTING text 66 | COPYING text 67 | copyright text 68 | *COPYRIGHT* text 69 | INSTALL text 70 | license text 71 | LICENSE text 72 | NEWS text 73 | readme text 74 | *README* text 75 | TODO text 76 | 77 | ## TEMPLATES 78 | *.dot text 79 | *.ejs text 80 | *.haml text 81 | *.handlebars text 82 | *.hbs text 83 | *.hbt text 84 | *.jade text 85 | *.latte text 86 | *.mustache text 87 | *.njk text 88 | *.phtml text 89 | *.tmpl text 90 | *.tpl text 91 | *.twig text 92 | 93 | ## LINTERS 94 | .csslintrc text 95 | .eslintrc text 96 | .htmlhintrc text 97 | .jscsrc text 98 | .jshintrc text 99 | .jshintignore text 100 | .stylelintrc text 101 | 102 | ## CONFIGS 103 | *.bowerrc text 104 | *.cnf text 105 | *.conf text 106 | *.config text 107 | .browserslistrc text 108 | .editorconfig text 109 | .gitattributes text 110 | .gitconfig text 111 | .htaccess text 112 | *.npmignore text 113 | *.yaml text 114 | *.yml text 115 | browserslist text 116 | Makefile text 117 | makefile text 118 | 119 | ## HEROKU 120 | Procfile text 121 | .slugignore text 122 | 123 | ## GRAPHICS 124 | *.ai binary 125 | *.bmp binary 126 | *.eps binary 127 | *.gif binary 128 | *.ico binary 129 | *.jng binary 130 | *.jp2 binary 131 | *.jpg binary 132 | *.jpeg binary 133 | *.jpx binary 134 | *.jxr binary 135 | *.pdf binary 136 | *.png binary 137 | *.psb binary 138 | *.psd binary 139 | *.svg text 140 | *.svgz binary 141 | *.tif binary 142 | *.tiff binary 143 | *.wbmp binary 144 | *.webp binary 145 | 146 | ## AUDIO 147 | *.kar binary 148 | *.m4a binary 149 | *.mid binary 150 | *.midi binary 151 | *.mp3 binary 152 | *.ogg binary 153 | *.ra binary 154 | 155 | ## VIDEO 156 | *.3gpp binary 157 | *.3gp binary 158 | *.as binary 159 | *.asf binary 160 | *.asx binary 161 | *.fla binary 162 | *.flv binary 163 | *.m4v binary 164 | *.mng binary 165 | *.mov binary 166 | *.mp4 binary 167 | *.mpeg binary 168 | *.mpg binary 169 | *.ogv binary 170 | *.swc binary 171 | *.swf binary 172 | *.webm binary 173 | 174 | ## ARCHIVES 175 | *.7z binary 176 | *.gz binary 177 | *.jar binary 178 | *.rar binary 179 | *.tar binary 180 | *.zip binary 181 | 182 | ## FONTS 183 | *.ttf binary 184 | *.eot binary 185 | *.otf binary 186 | *.woff binary 187 | *.woff2 binary 188 | 189 | ## EXECUTABLES 190 | *.exe binary 191 | *.pyc binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - 10.5.0 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /CODETOUR.md: -------------------------------------------------------------------------------- 1 | # Code Tour 2 | 3 | A quick introduction to the folders and files in this repo. 4 | 5 | ## Project anatomy 6 | 7 | The website is split into two parts, [`server`](server/index.js) and client, which is further organized in individual folders. Current server is an implementation of [Express](https://expressjs.com/) server. Its a very simple server that makes use of a dummy [`API`](server/api/index.js) and lets all other routes to be handled by [`Next.js`](https://nextjs.org/). When you run `npm run dev`, you are actually running this file [`index.js`](server/index.js). 8 | 9 | [`Next.js`](https://nextjs.org/) is our framework of choice, which acts as a thin glue between [ReactJS](https://reactjs.org/) and our [Express](https://expressjs.com/) server together. It will take care of Server Side Rendering, Routing, etc. It also covers [Webpack](https://webpack.js.org/) and [Babel](https://babeljs.io/) configuration, and comes with [style-jsx](https://github.com/zeit/styled-jsx), their [CSS-in-JS](https://hackernoon.com/all-you-need-to-know-about-css-in-js-984a72d48ebc) solution that would remind you of old days or how [Vue](https://vuejs.org/v2/guide/single-file-components.html) components are styled today. 10 | 11 | ## Source Organisation 12 | 13 | To keep things modular, the resources are divided into folders namely `/components`, `/constants`, `/pages`, `/public` and `/server`. We can obviously introduce more as required. 14 | 15 | ### [`pages`](pages/): Different pages of our website 16 | 17 | Contains all the pages a user can see or navigate to. This is a Next.js feature. For example; 18 | 19 | - [`index.js`](pages/index.js): Home page (`/`). The home page of our website. 20 | - [`about.js`](pages/about.js): About page (`/about`). About page. 21 | 22 | ### [`public`](public/): Serves static files like images, SVGs, videos, fonts, etc. 23 | 24 | - [`public/images`](public/images/): Serves images for our website 25 | 26 | ### [`components`](components/): Contains the different React components used in the site. 27 | 28 | You can check the component library in an interactive way using `npm run styleguide`. [styleguidist](https://react-styleguidist.js.org/) powers the same. 29 | 30 | For example; 31 | 32 | - [`components/NavBar`](components/NavBar/): Contains code for implementing `` component 33 | - [`components/Item`](components/Item/): Contains code for implementing `` component 34 | 35 | ### [`server`](server/): Contains our express server and dummy API 36 | 37 | - [`server/index.js`](server/index.js/): A simple server implementation using express 38 | - [`server/api/index.js`](server/api/index.js): Our dummy API 39 | 40 | ## Testing 41 | 42 | The [`jest`](https://facebook.github.io/jest/) framework is used for testing the Javascript code, along with airbnb's [Enzyme](https://github.com/airbnb/enzyme) for testing React components. 43 | 44 | In the folder of the file (`xyz.js`) you want to test, create `__tests__` folder with a `xyz.test.js` file, that would include tests for `xyz.js` file. This way all our tests will be contained in `__tests__` folder, and would still be colocated with the source code. Naming the test file as `*.test.js` helps us to quickly find the test of using Command P on your editor. 45 | 46 | ## Config files/folders 47 | 48 | - [`package.json`](package.json): npm config file. It also includes several scripts for running/building the server, testing etc. 49 | - [`package-lock.json`](package-lock.json): npm config file (genertaed alongwith package.json). This shouldn't be modified unless you're adding new dependencies or updating them. 50 | - [`jest.setup.js`](jest.setup.js): Jest config file 51 | - [`.eslintrc.js`](.eslintrc.js): ESLint config file 52 | - [`.now.json`](.now.json): [now](https://zeit.co/now) deployment configuration 53 | - [`.vscode/settings.json`](.vscode/settings.json): [VSCode](https://code.visualstudio.com/docs/getstarted/settings) project settings 54 | - [`.all-contributorsrc`](.all-contributorsrc): Source file to store all contributors 55 | - [`styleguide.config.js`](styleguide.config.js): [styleguidist](https://react-styleguidist.js.org/) configuration 56 | 57 | ## Others 58 | 59 | - [`.gitignore`](.gitignore): Contains a list of files and folders to be ignored by git. [More about gitignore..](https://medium.com/@haydar_ai/learning-how-to-git-ignoring-files-and-folders-using-gitignore-177556afdbe3) 60 | - [`LICENSE`](LICENSE): license file. A software license tells others what they can and can't do with your source code. The most common licenses for open source projects are MIT, Apache, GNU... licenses. The license used in this project is the MIT license. 61 | 62 | ### MARKDOWNS 63 | 64 | - [`README.md`](CONTRIBUTING.md): Introduction to this project alongwith instructions to build and contribute to this project. 65 | 66 | - [`CONTRIBUTING.md`](CONTRIBUTING.md): Deatiled instructions on contributing to this project. 67 | 68 | - [`CODETOUR.md`](CODETOUR.md): A tour through all the files and folders of this project. 69 | 70 | Please feel free to make changes to the above documentation :) 71 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the mentors/admin of this repository before making a change. 4 | 5 | Please follow the mentioned code of conduct which will ensure the health and longevity of this community. 6 | 7 | ## Issue "Assign" Process 8 | 9 | - **Claim** an issue before working on it. Either comment there or ask your mentors. If no one's working on that, they'll assign you. Start working only once you're **assigned** 10 | 11 | - Participants **cannot** claim more than one issue at a time, in a project. 12 | 13 | - Admins and mentors can specify a **time limit** for participants to complete the issue according to difficulty. They **can** unassign you if you fail to give updates in given time limit. If you need more time & working on it, **ask** them before deadline. 14 | 15 | ## Pull Request Process 16 | 17 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. 18 | 19 | 2. Ensure that the tests are passing. 20 | 21 | 3. Check that there are no conflicts. 22 | 23 | 4. Give the description of the issue that you want to resolve in the pull request message. The format of the commit message to be fixed - Fixes #[issue number] [Description of the issue] 24 | 25 | 5. Wait for the maintainers to review your pull request and do the changes if requested. 26 | 27 | ## Code of Conduct 28 | 29 | - Exercise consideration and respect in your speech and actions. 30 | 31 | - Attempt collaboration before conflict. 32 | 33 | - Refrain from demeaning, discriminatory, or harassing behavior and speech. 34 | 35 | - Be mindful of your surroundings and of your fellow participants. 36 | 37 | - Alert the trust committee if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. 38 | 39 | - If you witness any such behavior feel free to report to the organizing team. 40 | 41 | ### Our Pledge 42 | 43 | In the interest of fostering an open and welcoming environment, we as 44 | contributors and maintainers pledge to making participation in our project and 45 | our community a harassment-free experience for everyone, regardless of age, body 46 | size, disability, ethnicity, gender identity and expression, level of experience, 47 | nationality, personal appearance, race, religion, or sexual identity and 48 | orientation. 49 | 50 | ### Our Standards 51 | 52 | Examples of behavior that contributes to creating a positive environment 53 | include: 54 | 55 | * Using welcoming and inclusive language 56 | * Being respectful of differing viewpoints and experiences 57 | * Gracefully accepting constructive criticism 58 | * Focusing on what is best for the community 59 | * Showing empathy towards other community members 60 | 61 | Examples of unacceptable behavior by participants include: 62 | 63 | * The use of sexualized language or imagery and unwelcome sexual attention or 64 | advances 65 | * Trolling, insulting/derogatory comments, and personal or political attacks 66 | * Public or private harassment 67 | * Publishing others' private information, such as a physical or electronic 68 | address, without explicit permission 69 | * Other conduct which could reasonably be considered inappropriate in a 70 | professional setting 71 | 72 | ### Our Responsibilities 73 | 74 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 75 | 76 | Project maintainers have the right and responsibility to remove, edit, or 77 | reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 GirlScript Summer Of Code 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Upay 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors) 4 | [![Fork on github](https://img.shields.io/github/forks/GirlScriptSummerOfCode/Upay.svg) ](https://github.com/GirlScriptSummerOfCode/Upay/network/members) 5 | [![Issues on github](https://img.shields.io/github/issues/GirlScriptSummerOfCode/Upay.svg) ](https://github.com/GirlScriptSummerOfCode/Upay/issues) 6 | [![Stars on github](https://img.shields.io/github/stars/GirlScriptSummerOfCode/Upay.svg) ](https://github.com/GirlScriptSummerOfCode/Upay/stargazers) 7 | [![Watchers on github](https://img.shields.io/github/watchers/GirlScriptSummerOfCode/Upay.svg) ](https://github.com/GirlScriptSummerOfCode/Upay/watchers) 8 | [![MIT license](https://img.shields.io/github/license/GirlScriptSummerOfCode/Upay.svg)](LICENSE) 9 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/GirlScriptSummerOfCode/Upay/pulls) 10 | 11 | The foundation of development for every society is the education of its youth. Keeping this in mind, an NGO UPAY (**U**nder **P**rivileged **A**dvancement by **Y**outh), was established in May 2010 by a group of young engineers from IITs and NITs. It mainly aims to provide opportunities to underprivileged children and bring some sunshine in those deprived lives. 12 | 13 | Ever since it's dawn, UPAY Team has been working wholeheartedly in achieving this aim. Its success story can be culminated by the mere fact that where children were unable to do basic arithmetic calculations are now, not just producing excellent academic results but also bringing laurels to these underprivileged areas. The main vision of UPAY is overcome disparities in education so that every child gets an opportunity to Learn, Grow and Succeed. 14 | 15 | Tech Stack: [Next.js](https://nextjs.org/) (NodeJS, ReactJS), ExpressJS server. 16 | 17 | **Admin**: Shagufta Gurmukhdas 18 | 19 | **Mentors**: Nupur Baghel, Sambhav Jain, Divjot Singh, Gaurav Sitlani, Bhavin Jawade 20 | 21 | - [Upay](#upay) 22 | - [Building](#building) 23 | - [Contribution](#contribution) 24 | - [Contributors](#contributors) 25 | 26 | ## Building 27 | 28 | Make sure you've NodeJS 8 and NPM 5.7 or above. 29 | 30 | ```bash 31 | # install dependencies using npm 32 | npm ci 33 | 34 | # start project in development mode 35 | npm run dev 36 | 37 | # start styleguidist for /components directory documentation 38 | npm run styleguide 39 | 40 | # build project 41 | npm run build 42 | 43 | # start project in production mode (after build) 44 | npm start 45 | 46 | # test project 47 | npm run test 48 | ``` 49 | 50 | ## Contribution 51 | 52 | - Use `npx all-contributors-cli add ` to add yourself in the Contributor list below. The project follows [all-contributors](https://github.com/kentcdodds/all-contributors) format. 53 | - [VSCode](https://code.visualstudio.com/) is recommended as the editor for this project. 54 | - Please install [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode), [eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), [jest](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest) [plugins](https://marketplace.visualstudio.com/) for VSCode for improved developer experience. 55 | - Please follow [JSDoc](http://usejsdoc.org/) for your submitted code. Use [DocumentThis](https://marketplace.visualstudio.com/items?itemName=joelday.docthis) plugin if required. 56 | - Use [`CODETOUR.md`](CODETOUR.md) to get an understanding of the project folder structure. 57 | - Write tests for complicated components and modules. 58 | 59 | ## Contributors 60 | 61 | Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): 62 | 63 | 64 | 65 | 66 | | [
MADHAV BAHL](http://madhavbahl.tech/)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=MadhavBahlMD "Code") | [
Minanshu Singh](https://github.com/kryptokinght)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=kryptokinght "Code") | [
Sambhav Jain](https://sourcerer.io/sambhav2612)
[📖](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=sambhav2612 "Documentation") | [
Sakshi Shreya](https://github.com/SakshiShreya)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=SakshiShreya "Code") | [
Adarsh Lilha](https://github.com/adarshlilha)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=adarshlilha "Code") | [
Divjot Singh](http://bogas04.github.io)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=bogas04 "Code") | [
Anshul Mittal](https://github.com/Nshul)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=Nshul "Code") | 67 | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | 68 | | [
Twisha](https://twishasaraiya.github.io/)
[💻](https://github.com/GirlScriptSummerOfCode/Upay/commits?author=twishasaraiya "Code") | 69 | 70 | 71 | 72 | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! 73 | 74 | ## License 75 | 76 | (c) GSSoC and Upay Contributors under MIT License 77 | -------------------------------------------------------------------------------- /components/Breadcrumb/Breadcrumb.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class Breadcrumb extends React.Component { 5 | static propTypes = { 6 | path: PropTypes.string, 7 | }; 8 | 9 | render() { 10 | const { path } = this.props; 11 | return ( 12 | 13 | 18 |
19 | Home 20 | {path.replace(/%20/g, ' ')} 21 |
22 |
23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /components/Breadcrumb/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Breadcrumb'; 2 | -------------------------------------------------------------------------------- /components/Carousel/Carousel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class Carousel extends React.PureComponent { 5 | constructor(props){ 6 | super(props); 7 | this.displayImage = React.createRef(); 8 | } 9 | static propTypes = { 10 | imageUrls: PropTypes.array, 11 | }; 12 | 13 | changeImage = e => { 14 | this.displayImage.current.src = e.target.src; 15 | }; 16 | 17 | render() { 18 | const { imageUrls } = this.props; 19 | return ( 20 | 21 | 41 |
42 | 47 |
48 | {imageUrls.map((src,i) => ( 49 | 50 | ) 51 | )} 52 |
53 |
54 |
55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /components/Carousel/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Carousel'; 2 | -------------------------------------------------------------------------------- /components/Icons/Arrow.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Arrow = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Arrow; 10 | -------------------------------------------------------------------------------- /components/Icons/Bookmark.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Bookmark = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Bookmark; 10 | -------------------------------------------------------------------------------- /components/Icons/Chevron.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const getStyle = direction => { 5 | const { TOP, LEFT, RIGHT, BOTTOM } = Chevron.DIRECTIONS; 6 | let transform = ''; 7 | switch (direction) { 8 | case TOP: { 9 | transform = 'rotate(0deg)'; 10 | break; 11 | } 12 | case LEFT: { 13 | transform = 'rotate(-90deg)'; 14 | break; 15 | } 16 | case RIGHT: { 17 | transform = 'rotate(90deg)'; 18 | break; 19 | } 20 | case BOTTOM: { 21 | transform = 'rotate(180deg)'; 22 | break; 23 | } 24 | } 25 | 26 | return { 27 | OTransform: transform, 28 | WebKitTransform: transform, 29 | MozTransform: transform, 30 | transform, 31 | }; 32 | }; 33 | 34 | const Chevron = props => ( 35 | 44 | 45 | 46 | ); 47 | 48 | Chevron.DIRECTIONS = { 49 | TOP: 0, 50 | RIGHT: 1, 51 | BOTTOM: 2, 52 | LEFT: 3, 53 | }; 54 | 55 | Chevron.propTypes = { 56 | direction: PropTypes.oneOf([0, 1, 2, 3]), 57 | }; 58 | export default Chevron; 59 | -------------------------------------------------------------------------------- /components/Icons/Cog.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Cog = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Cog; 10 | -------------------------------------------------------------------------------- /components/Icons/Hamburger.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Hamburger = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Hamburger; 10 | -------------------------------------------------------------------------------- /components/Icons/Heart.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Heart = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Heart; 10 | -------------------------------------------------------------------------------- /components/Icons/Rupee.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Rupee = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Rupee; 10 | -------------------------------------------------------------------------------- /components/Icons/Save.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Save = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Save; 10 | -------------------------------------------------------------------------------- /components/Icons/Search.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Search = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Search; 10 | -------------------------------------------------------------------------------- /components/Icons/Share.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Share = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default Share; 10 | -------------------------------------------------------------------------------- /components/Icons/User.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const User = props => ( 4 | 5 | 6 | 7 | ); 8 | 9 | export default User; 10 | -------------------------------------------------------------------------------- /components/Item/Item.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Link from 'next/link'; 3 | import Rupee from '../Icons/Rupee'; 4 | import PropTypes from 'prop-types'; 5 | 6 | const Item = props => ( 7 | 8 | 82 |
  • 83 | 84 | {props.name} 85 | 86 |
    87 |
    88 | {props.name} 89 |
    90 |
    91 | {/* This code handles price. */} 92 | {/* If discounted price is available, it displays discounted price and strikes-through original price. */} 93 | {/* If discounted price is not available, it displays original price. */} 94 | {props.discountedPrice && ( 95 | 96 | 97 | {props.discountedPrice}    98 | 99 | )} 100 | {props.discountedPrice ? ( 101 | 102 | 103 | {props.originalPrice} 104 | 105 | ) : ( 106 | 107 | 108 | {props.originalPrice} 109 | 110 | )} 111 |
    112 |
    113 |
    114 | {/* Add the buttons later */} 115 |
    Add
    116 |
    SaveForLater
    117 |
    118 |
  • 119 |
    120 | ); 121 | 122 | Item.propTypes = { 123 | id: PropTypes.number, 124 | name: PropTypes.string, 125 | originalPrice: PropTypes.number, 126 | discountedPrice: PropTypes.number, 127 | imageUrls: PropTypes.arrayOf(PropTypes.string), 128 | }; 129 | export default Item; 130 | -------------------------------------------------------------------------------- /components/Item/README.md: -------------------------------------------------------------------------------- 1 | # Item 2 | 3 | Each item is an element from the list of items. 4 | 5 | ## Item call: 6 | 7 | ``` 8 | 15 | ``` 16 | -------------------------------------------------------------------------------- /components/Item/__tests__/Item.test.js: -------------------------------------------------------------------------------- 1 | /* globals describe, it, expect */ 2 | import React from 'react'; 3 | import { mount } from 'enzyme'; 4 | import Item from '../Item'; 5 | 6 | describe('', () => { 7 | it('renders correctly', () => { 8 | const wrapper = mount(); 9 | expect(wrapper).toMatchSnapshot(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /components/Item/__tests__/__snapshots__/Item.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` renders correctly 1`] = ` 4 | 13 | 17 |
  • 20 | 23 | Item one 30 | 31 |
    34 | 44 |
    47 | 50 | 53 | 58 | 61 | 62 | 63 | 64 |
    65 |
    66 |
    69 |
    72 | Add 73 |
    74 |
    77 | SaveForLater 78 |
    79 |
    80 |
  • 81 |
    82 | `; 83 | -------------------------------------------------------------------------------- /components/Item/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Item'; 2 | -------------------------------------------------------------------------------- /components/NavBar/NavBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Link from 'next/link'; 4 | 5 | /** 6 | * 7 | * 8 | * @export 9 | * @class NavBar 10 | * @augments {React.PureComponent} 11 | */ 12 | export default class NavBar extends React.PureComponent { 13 | /** 14 | * @typedef {object} NavBarProps 15 | * @property {array} links 16 | * 17 | * @static 18 | * @memberof NavBar 19 | */ 20 | static propTypes = { 21 | /** Links Array */ 22 | links: PropTypes.arrayOf( 23 | PropTypes.shape({ 24 | /** Link URL */ 25 | url: PropTypes.string, 26 | /** Link Title */ 27 | title: PropTypes.string, 28 | }) 29 | ).isRequired, 30 | }; 31 | 32 | render() { 33 | return ( 34 | 35 | 53 | 64 | 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /components/NavBar/README.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 | NavBar showing two links 4 | 5 | ```jsx 6 | 14 | ``` 15 | -------------------------------------------------------------------------------- /components/NavBar/__tests__/Navbar.test.js: -------------------------------------------------------------------------------- 1 | /* globals describe, it, expect */ 2 | import React from 'react'; 3 | import { mount } from 'enzyme'; 4 | import { shallowToJson } from 'enzyme-to-json'; // removes unnecessary JSON from snapshot 5 | import Navbar from '../'; 6 | import links from '../../../constants/links'; 7 | 8 | describe('', () => { 9 | it('renders correctly', () => { 10 | const wrapper = mount(); 11 | expect(shallowToJson(wrapper)).toMatchSnapshot(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /components/NavBar/__tests__/__snapshots__/Navbar.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` renders correctly 1`] = ` 4 | 18 | 22 | 62 | 63 | `; 64 | -------------------------------------------------------------------------------- /components/NavBar/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './NavBar'; 2 | -------------------------------------------------------------------------------- /components/ProductInfo/ProductInfo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Rupee from '../Icons/Rupee'; 4 | 5 | export default class ProductInfo extends React.PureComponent { 6 | static propTypes = { 7 | name: PropTypes.string, 8 | originalPrice: PropTypes.number, 9 | discountedPrice: PropTypes.number, 10 | description: PropTypes.string, 11 | }; 12 | static defaultProps = { 13 | description: 'No description available', 14 | }; 15 | render() { 16 | const { name, originalPrice, discountedPrice, description } = this.props; 17 | return ( 18 | 19 |
    20 |

    {name}

    21 | {originalPrice ? ( 22 | 23 | 24 | {originalPrice} 25 | 26 | ) : ( 27 | 28 | 29 | {originalPrice} 30 | 31 | )} 32 | {discountedPrice && ( 33 | 34 | 35 | {discountedPrice} 36 | 37 | )} 38 |

    {description}

    39 |
    40 |
    41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /components/ProductInfo/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './ProductInfo'; 2 | -------------------------------------------------------------------------------- /components/QuantityButton/QuantityButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class QuantityButton extends React.Component { 5 | static propTypes = { 6 | qty: PropTypes.number, 7 | increment: PropTypes.func, 8 | decrement: PropTypes.func, 9 | }; 10 | 11 | render() { 12 | const { qty, increment, decrement } = this.props; 13 | return ( 14 | 15 | 43 |
    44 | 47 |
    {this.props.qty}
    48 | 55 |
    56 |
    57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /components/QuantityButton/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './QuantityButton'; 2 | -------------------------------------------------------------------------------- /constants/links.js: -------------------------------------------------------------------------------- 1 | export default [{ title: 'Upay', url: '/' }, { title: 'About', url: '/about' }]; 2 | -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias": ["upay-website"], 3 | "name": "upay-website", 4 | "public": true 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upay-website", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "babel-core": "7.0.0-bridge.0", 6 | "babel-jest": "22.4.3", 7 | "express": "^4.16.3", 8 | "isomorphic-unfetch": "^2.0.0", 9 | "next": "^6.0.3", 10 | "prop-types": "^15.6.2", 11 | "react": "^16.4.1", 12 | "react-dom": "^16.4.1" 13 | }, 14 | "devDependencies": { 15 | "babel-eslint": "^8.2.3", 16 | "cross-env": "^5.2.0", 17 | "enzyme": "3.2.0", 18 | "enzyme-adapter-react-16": "1.1.1", 19 | "enzyme-to-json": "^3.3.4", 20 | "eslint": "^4.19.1", 21 | "eslint-plugin-react": "^7.10.0", 22 | "husky": "^0.14.3", 23 | "jest": "^22.0.1", 24 | "lint-staged": "^7.2.0", 25 | "npm-run-all": "^4.1.3", 26 | "react-addons-test-utils": "15.6.2", 27 | "react-styleguidist": "^7.0.19", 28 | "react-test-renderer": "16.2.0" 29 | }, 30 | "scripts": { 31 | "prepush": "npm test", 32 | "test": "npm-run-all test:* --parallel", 33 | "test:lint": "eslint ./", 34 | "test:unit": "cross-env NODE_ENV=test jest", 35 | "watch": "npm-run-all watch:* --parallel", 36 | "watch:test": "npm run test:unit -- --watch", 37 | "dev": "node server", 38 | "build": "next build", 39 | "start": "cross-env NODE_ENV=production node server", 40 | "styleguide": "styleguidist server" 41 | }, 42 | "babel": { 43 | "env": { 44 | "development": { 45 | "presets": [ 46 | "next/babel" 47 | ] 48 | }, 49 | "production": { 50 | "presets": [ 51 | "next/babel" 52 | ] 53 | }, 54 | "test": { 55 | "presets": [ 56 | [ 57 | "next/babel", 58 | { 59 | "preset-env": { 60 | "modules": "commonjs" 61 | } 62 | } 63 | ] 64 | ] 65 | } 66 | } 67 | }, 68 | "jest": { 69 | "setupFiles": [ 70 | "/jest.setup.js" 71 | ], 72 | "testPathIgnorePatterns": [ 73 | "/.next/", 74 | "/node_modules/" 75 | ], 76 | "snapshotSerializers": [ 77 | "enzyme-to-json/serializer" 78 | ] 79 | }, 80 | "prettier": { 81 | "trailingComma": "es5", 82 | "singleQuote": true, 83 | "tabWidth": 2, 84 | "useTabs": false 85 | }, 86 | "description": "[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors)", 87 | "repository": { 88 | "type": "git", 89 | "url": "git+https://github.com/GirlScriptSummerOfCode/Upay.git" 90 | }, 91 | "keywords": [ 92 | "upay", 93 | "website" 94 | ], 95 | "author": "GSSoC and Upay Contributors", 96 | "license": "MIT", 97 | "bugs": { 98 | "url": "https://github.com/GirlScriptSummerOfCode/Upay/issues" 99 | }, 100 | "homepage": "https://github.com/GirlScriptSummerOfCode/Upay#readme" 101 | } 102 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import Document, { Head, Main, NextScript } from 'next/document'; 2 | import links from '../constants/links'; 3 | import NavBar from '../components/NavBar'; 4 | 5 | export default class MyDocument extends Document { 6 | static async getInitialProps(ctx) { 7 | const initialProps = await Document.getInitialProps(ctx); 8 | return { ...initialProps }; 9 | } 10 | 11 | render() { 12 | return ( 13 | 14 | 15 | 19 | 20 | 31 | 32 | 33 | 34 |
    35 | 36 | 37 | 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pages/about.js: -------------------------------------------------------------------------------- 1 | /** 2 | * About page 3 | * @returns {React.ReactElement} 4 | */ 5 | export default () => ( 6 |
    7 |

    About Page

    8 |
    9 | It mainly aims to provide opportunities to underprivileged children and 10 | bring some sunshine in those deprived lives. Ever since it's dawn, UPAY 11 | Team has been working wholeheartedly in achieving this aim. Its success 12 | story can be culminated by the mere fact that where children were unable 13 | to do basic arithmetic calculations are now, not just producing excellent 14 | academic results but also bringing laurels to these underprivileged areas. 15 | The main vision of UPAY is overcome disparities in education so that every 16 | child gets an opportunity to Learn, Grow and Succeed. 17 |
    18 |
    19 | ); 20 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Item from '../components/Item'; 3 | import Arrow from '../components/Icons/Arrow'; 4 | import Bookmark from '../components/Icons/Bookmark'; 5 | import Cog from '../components/Icons/Cog'; 6 | import Hamburger from '../components/Icons/Hamburger'; 7 | import Heart from '../components/Icons/Heart'; 8 | import Rupee from '../components/Icons/Rupee'; 9 | import Save from '../components/Icons/Save'; 10 | import Search from '../components/Icons/Search'; 11 | import Share from '../components/Icons/Share'; 12 | import User from '../components/Icons/User'; 13 | import Chevron from '../components/Icons/Chevron'; 14 | 15 | /** 16 | * Home page 17 | * 18 | * @export 19 | * @class IndexPage 20 | * @extends {React.PureComponent} 21 | */ 22 | export default class IndexPage extends React.PureComponent { 23 | state = { 24 | items: [], 25 | }; 26 | 27 | render() { 28 | return ( 29 | 30 | 35 |
    36 | Logo of Upay NGO 37 | 38 |
    39 | The foundation of development for every society is the education of 40 | its youth. Keeping this in mind, an 41 | 46 | {' NGO UPAY '} 47 | 48 | (Underprivileged Advancement by Youth), was established in May 2010 49 | by a group of young engineers from IITs and NITs. 50 |
    51 | 52 |

    Items

    53 |
      54 | {this.state.items.map( 55 | (item) => ( 56 | 60 | ) 61 | )} 62 |
    63 | 64 |
    65 |

    Icons

    66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
    78 |
    79 |
    80 | ); 81 | } 82 | 83 | /** 84 | * This is for demo purposes. 85 | * Once the component has mounted, we fetch items from our API and sets them to state. 86 | */ 87 | async componentDidMount() { 88 | const { data: items } = await fetch('/api/items').then(r => r.json()); 89 | this.setState({ items }); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /pages/product.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Error from 'next/error'; 4 | import Bookmark from '../components/Icons/Bookmark'; 5 | import QuantityButton from '../components/QuantityButton'; 6 | import Breadcrumb from '../components/Breadcrumb'; 7 | import Carousel from '../components/Carousel'; 8 | import ProductInfo from '../components/ProductInfo'; 9 | import { withRouter } from 'next/router'; 10 | import fetch from 'isomorphic-unfetch'; 11 | import { server } from '../server/config'; 12 | 13 | /** 14 | * Product Details Page 15 | * 16 | * @export 17 | * @class ProductPage 18 | * @extends {React.PureComponent} 19 | */ 20 | class ProductPage extends React.PureComponent { 21 | state = { 22 | qty: 0, 23 | }; 24 | 25 | static propTypes = { 26 | Item: PropTypes.shape({ 27 | id: PropTypes.number, 28 | name: PropTypes.string, 29 | imageUrls: PropTypes.array, 30 | originalPrice: PropTypes.number, 31 | discountedPrice: PropTypes.number, 32 | }), 33 | }; 34 | 35 | static getInitialProps = async ({ query, res }) => { 36 | const { id } = query; 37 | if (!id && res) { 38 | res.statusCode = 404; 39 | return { Item: null }; 40 | } 41 | const { data: Item } = await fetch(`${server}/api/items/${id}`).then(r => 42 | r.json() 43 | ); 44 | return { Item }; 45 | }; 46 | increment = () => { 47 | this.setState({ 48 | qty: this.state.qty + 1, 49 | }); 50 | }; 51 | decrement = () => { 52 | this.setState({ 53 | qty: this.state.qty - 1, 54 | }); 55 | }; 56 | render() { 57 | const { router, Item } = this.props; 58 | if (!Item) return ; 59 | return ( 60 |
    61 | 126 | 127 |
    128 | 129 |
    130 | 135 | 140 |
    141 |

    Delivery Options

    142 |
    143 |
    144 |
    145 | 146 | Save 147 |
    148 |
    Add To Cart
    149 |
    150 |
    151 |
    152 |
    153 | ); 154 | } 155 | } 156 | 157 | export default withRouter(ProductPage); 158 | -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GirlScriptSummerOfCode/Upay/353fd5a7ea4e8d8acb536436e383067e2ecac1d8/public/images/logo.png -------------------------------------------------------------------------------- /public/images/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GirlScriptSummerOfCode/Upay/353fd5a7ea4e8d8acb536436e383067e2ecac1d8/public/images/placeholder.png -------------------------------------------------------------------------------- /public/images/upay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GirlScriptSummerOfCode/Upay/353fd5a7ea4e8d8acb536436e383067e2ecac1d8/public/images/upay.png -------------------------------------------------------------------------------- /server/api/index.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express'); 2 | 3 | const items = [ 4 | { 5 | id: 1, 6 | name: 'Item 1', 7 | imageUrls: [ 8 | '/images/placeholder.png', 9 | '/images/placeholder.png', 10 | '/images/upay.png', 11 | '/images/placeholder.png', 12 | ], 13 | originalPrice: 100, 14 | discountedPrice: undefined, 15 | }, 16 | { 17 | id: 2, 18 | name: 'Item 2', 19 | imageUrls: [ 20 | '/images/placeholder.png', 21 | '/images/placeholder.png', 22 | '/images/upay.png', 23 | '/images/placeholder.png', 24 | ], 25 | originalPrice: 200, 26 | discountedPrice: 150, 27 | }, 28 | { 29 | id: 3, 30 | name: 'Item 3', 31 | imageUrls: [ 32 | '/images/placeholder.png', 33 | '/images/placeholder.png', 34 | '/images/upay.png', 35 | '/images/placeholder.png', 36 | ], 37 | originalPrice: 300, 38 | discountedPrice: 250, 39 | }, 40 | { 41 | id: 4, 42 | name: 'Item 4', 43 | imageUrls: [ 44 | '/images/placeholder.png', 45 | '/images/placeholder.png', 46 | '/images/upay.png', 47 | '/images/placeholder.png', 48 | ], 49 | originalPrice: 400, 50 | discountedPrice: undefined, 51 | }, 52 | { 53 | id: 5, 54 | name: 'Item 5', 55 | imageUrls: [ 56 | '/images/placeholder.png', 57 | '/images/placeholder.png', 58 | '/images/upay.png', 59 | '/images/placeholder.png', 60 | ], 61 | originalPrice: 500, 62 | discountedPrice: 450, 63 | }, 64 | { 65 | id: 6, 66 | name: 'Item 6', 67 | imageUrls: [ 68 | '/images/placeholder.png', 69 | '/images/placeholder.png', 70 | '/images/upay.png', 71 | '/images/placeholder.png', 72 | ], 73 | originalPrice: 600, 74 | discountedPrice: 550, 75 | }, 76 | ]; 77 | 78 | const api = Router(); 79 | 80 | /* Our demo API */ 81 | 82 | api 83 | .get('/items/:id', (req, res) => 84 | res.json({ data: items[req.params.id - 1] || null }) 85 | ) 86 | .get('/items', (req, res) => res.json({ data: items })); 87 | 88 | module.exports = api; 89 | -------------------------------------------------------------------------------- /server/config.js: -------------------------------------------------------------------------------- 1 | const dev = process.env.NODE_ENV !== 'production'; 2 | const PORT = parseInt(process.env.PORT, 10) || 3000; 3 | const NOWURL = process.env.NOW ? process.env.NOW_URL : ''; 4 | export const server = dev ? `http://localhost:${PORT}` : NOWURL; 5 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const next = require('next'); 3 | const path = require('path'); 4 | const api = require('./api'); 5 | 6 | const PORT = parseInt(process.env.PORT, 10) || 3000; 7 | const dev = process.env.NODE_ENV !== 'production'; 8 | const nextApp = next({ dev }); 9 | const handleNextPages = nextApp.getRequestHandler(); 10 | 11 | nextApp.prepare().then(() => { 12 | const expressServer = express(); 13 | 14 | /* Static assets are kept at /public folder */ 15 | 16 | expressServer.use(express.static(path.resolve(__dirname, '..', 'public'))); 17 | 18 | /* APIs go there */ 19 | expressServer.use('/api', api); 20 | 21 | /* Clean URL for rendering Product Information*/ 22 | expressServer.get('/product/:id', (req, res) => { 23 | nextApp.render(req, res, '/product', req.params); 24 | }); 25 | 26 | /* All website routes are automatically handled by next */ 27 | expressServer.get('*', handleNextPages); 28 | 29 | /* Listen to the server now */ 30 | expressServer.listen(PORT, err => { 31 | if (err) throw err; 32 | console.log(`> Ready on http://localhost:${PORT}`); // eslint-disable-line no-console 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /styleguide.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | components: 'components/**/[A-Z]*.js', 3 | webpackConfig: { 4 | module: { 5 | rules: [ 6 | { 7 | test: /\.js$/, 8 | exclude: /node_modules/, 9 | loader: 'babel-loader', 10 | }, 11 | ], 12 | }, 13 | }, 14 | }; 15 | --------------------------------------------------------------------------------