├── .eslintrc ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── content-check.yml ├── .gitignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── content ├── devs │ ├── adrian-rios.json │ ├── boone-raye-flores.json │ ├── carl-de-guia.json │ ├── christian-villamin.json │ ├── franrey-anthony-saycon.json │ ├── gian-faye-paguirigan.json │ ├── harvey-jay-sison.json │ ├── jayson-de-los-reyes.json │ ├── john-joseph-mendez.json │ ├── marjorie-martinez.json │ ├── mark-dino-pelonia.json │ ├── miguel-galace.json │ ├── nemuel-lim.json │ ├── oliver-jurgen-escoto.json │ ├── ralph-largo.json │ ├── rhaidzsal-ali.json │ ├── ryan-bautista.json │ └── terri-john-andoy.json └── projects │ ├── become-a-hooks-hero.json │ ├── fluid-system.json │ ├── reactjsph-website.json │ ├── rehackt-challenge-w1.json │ ├── stores-near-me.json │ └── street-bridge.json ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── package.json ├── scripts ├── add-dev-board.js ├── pre-commit.js └── pre-push.js ├── src ├── components │ ├── circleButton.js │ ├── contact.js │ ├── container.js │ ├── devBio.js │ ├── fbTokenRequiredBoundary.js │ ├── footer.js │ ├── header.js │ ├── hero.js │ ├── heroCanvas.js │ ├── image.js │ ├── layout.js │ ├── meetupEventCard.js │ ├── meetupSection.js │ ├── messageSentModal.js │ ├── missionSection.js │ ├── portal.js │ ├── projectCard.js │ ├── seo.js │ ├── starDivider.js │ ├── team.js │ ├── teamMember.js │ ├── teamPage.js │ └── visionSection.js ├── fonts │ ├── Avenir-Black.eot │ ├── Avenir-Black.svg │ ├── Avenir-Black.ttf │ ├── Avenir-Black.woff │ ├── Avenir-Black.woff2 │ ├── Avenir-Roman.eot │ ├── Avenir-Roman.svg │ ├── Avenir-Roman.ttf │ ├── Avenir-Roman.woff │ ├── Avenir-Roman.woff2 │ └── index.js ├── global.js ├── hooks │ ├── useDefaultThumbnail.js │ ├── useFacebookPageQuery.js │ └── useFacebookSdk.js ├── images │ ├── brandmark-path.js │ ├── brandmark.inline.svg │ ├── community-img.jpg │ ├── default-thumbnail.jpeg │ ├── divider.svg │ ├── favicon.svg │ ├── gatsby-astronaut.png │ ├── gatsby-icon.png │ ├── hero-img.jpg │ ├── icon.png │ ├── index.js │ ├── linkedin.svg │ ├── logo.inline.svg │ ├── meetup.svg │ ├── member-placeholder.jpg │ ├── messenger.svg │ ├── orbits.svg │ └── team │ │ ├── carl.jpg │ │ ├── christian.jpg │ │ ├── ericson.jpg │ │ ├── fran.jpg │ │ ├── gian.jpg │ │ ├── guigi.jpg │ │ ├── jayson.jpg │ │ ├── jedo.jpg │ │ ├── jerome.jpg │ │ ├── joe.jpg │ │ ├── marj.jpg │ │ ├── michael.jpg │ │ └── rem.jpg ├── pages │ ├── 404.js │ ├── dev-board.js │ ├── index.js │ └── projects.js ├── root-element.js ├── styles │ └── custom-shake.css ├── theme.js └── utils.js ├── static └── meta-image-cover.jpg └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true 4 | }, 5 | "extends": ["airbnb", "prettier", "prettier/react"], 6 | "plugins": ["prettier", "react-hooks"], 7 | "rules": { 8 | "react/jsx-filename-extension": [ 9 | 1, 10 | { 11 | "extensions": [".js", ".jsx"] 12 | } 13 | ], 14 | "react/prop-types": 0, 15 | "no-underscore-dangle": 0, 16 | "import/imports-first": ["error", "absolute-first"], 17 | "import/newline-after-import": "error", 18 | "react-hooks/rules-of-hooks": "error", 19 | "react-hooks/exhaustive-deps": "warn", 20 | "react/jsx-props-no-spreading": [ 21 | 0, 22 | { 23 | "exceptions": ["Box"] 24 | } 25 | ], 26 | "camelcase": "off", 27 | "import/prefer-default-export": "off" 28 | }, 29 | "globals": { 30 | "window": true, 31 | "document": true, 32 | "localStorage": true, 33 | "FormData": true, 34 | "FileReader": true, 35 | "Blob": true, 36 | "navigator": true 37 | }, 38 | "parser": "babel-eslint" 39 | } 40 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description** 2 | - Short description of what this PR implements or fixes 3 | 4 | **Summary of Changes** 5 | - Code/resources that have been added, updated or removed. Please provide rationale for changes whenever applicable 6 | 7 | **How to Test** 8 | - Link to dev/staging deployment and credentials whenever applicable 9 | - Steps for performing tests 10 | - Command line invocation to run automated tests 11 | 12 | **Screenshots** 13 | - Before and after screenshots whenever applicable 14 | 15 | **Notes** 16 | - Other things needs to be mentioned 17 | 18 | Closes #xx - issue number 19 | -------------------------------------------------------------------------------- /.github/workflows/content-check.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [12.x] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - run: yarn 20 | - run: yarn lint 21 | - run: node ./scripts/pre-push.js 22 | env: 23 | CI: true 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variables file 55 | .env 56 | .env.development 57 | 58 | # gatsby files 59 | .cache/ 60 | public 61 | 62 | # Mac files 63 | .DS_Store 64 | 65 | # Yarn 66 | yarn-error.log 67 | .pnp/ 68 | .pnp.js 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # use yarn instead of npm 73 | package-lock.json 74 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "singleQuote": false, 5 | "tabWidth": 2, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at reactjs.ph@yahoo.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Hello! 👋 4 | 5 | Thank you for contributing to this project. We are grateful for your contributions, and we are excited to welcome you aboard. 6 | 7 | Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. tl;dr Be nice. No harassment, trolling, or spamming. 8 | 9 | Happy contributing! 10 | 11 | ## Here are some ways you can help 12 | 13 | 1. Pick an unassigned [issue](https://github.com/reactph/reactjsph-website/issues) that you can work on 14 | 1. Found a typo or grammar error? Feel free correct them 15 | 1. Found a bug or just asking a question? Feel free to create an [issue](https://github.com/reactph/reactjsph-website/issues/new) 16 | 1. Contribute anything to help us improve this project 17 | 18 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). 19 | 20 | ## Requirements 21 | 22 | This project is built with [Gatsby](https://www.gatsbyjs.org/). 23 | 24 | Please make sure you have this installed on your machine: 25 | 26 | - [NodeJS](https://nodejs.org/en/) 27 | - [Yarn](https://yarnpkg.com/lang/en/) 28 | 29 | ## Here are the steps to begin contributing 30 | 31 | 1. **Fork this repo** 32 | 33 | 1. **Clone your forked repo** 34 | 35 | ```sh 36 | git clone https://github.com//reactjsph-website.git 37 | ``` 38 | 39 | 1. **Install dependencies** 40 | 41 | Navigate into the site’s directory and install dependencies. 42 | 43 | ```sh 44 | cd reactjsph-website/ 45 | yarn 46 | # or yarn install 47 | ``` 48 | 49 | 1. **Create your branch** 50 | 51 | ```sh 52 | git checkout -b 53 | ``` 54 | 55 | 1. **Start developing** 56 | 57 | ```sh 58 | yarn start 59 | # or yarn develop 60 | ``` 61 | 62 | Site is now running at `http://localhost:8000`! 63 | 64 | 1. **Open the source code and start editing!** 65 | 66 | If all things are good you can commit your changes and push them to your forked repo. 67 | 68 | 1. **Create a [pull request](https://github.com/reactph/reactjsph-website/pulls)** 69 | 70 | --- 71 | 72 | If you have some questions, message us at [Messenger](m.me/reactjsphilippines), if you haven't joined, join our [Facebook group](https://web.facebook.com/groups/875676539148789/). 73 | 74 | **Not on Facebook?** Join us on [Discord](https://discord.gg/J6eZNUG). 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ReactJS Philippines 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 |
2 | 3 | ReactJS Philippines 8 | 9 |

We are a group of Filipino developers dedicated to nation-building through our community and shared enthusiasm for React and for excellence overall.

10 |
11 | 12 | --- 13 | 14 | [![Netlify Status](https://api.netlify.com/api/v1/badges/cd5d6330-1628-4d0e-aac1-84f8cf4b7863/deploy-status)](https://app.netlify.com/sites/reactjs-ph-website/deploys) 15 | 16 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) 17 | [![GitHub issues](https://img.shields.io/github/issues/reactph/reactjsph-website)](https://github.com/reactph/reactjsph-website/issues) 18 | [![GitHub license](https://img.shields.io/github/license/reactph/reactjsph-website)](https://github.com/reactph/reactjsph-website/blob/master/LICENSE) 19 | [![Code of Conduct](https://img.shields.io/badge/code%20of-conduct-ff69b4.svg)](https://github.com/reactph/reactjsph-website/blob/master/CODE_OF_CONDUCT.md) 20 | 21 | [![Facebook Group](https://img.shields.io/badge/join_the_community-on_facebook-1877F2?logo=facebook)][facebook-group] 22 | [![Discord](https://img.shields.io/badge/join_the_community-on_discord-7289DA?logo=discord)][discord] 23 | 24 | --- 25 | 26 | ## 🚀 Quick start 27 | 28 | 1. **Fork and clone this repo** 29 | 30 | 2. **Install dependencies** 31 | 32 | Navigate into the site’s directory and install dependencies. 33 | 34 | ```sh 35 | cd reactjsph-website/ 36 | yarn 37 | # or yarn install 38 | ``` 39 | 40 | 3. **Start developing** 41 | 42 | ```sh 43 | yarn start 44 | # or yarn develop 45 | ``` 46 | 47 | 4. **Open the source code and start editing!** 48 | 49 | Your site is now running at `http://localhost:8000`! 50 | 51 | _Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._ 52 | 53 | Open the `reactjsph-website` directory in your code editor of choice and start developing. Save your changes and the browser will update in real time! 54 | 55 | More for information about how you can contribute to this project, check our [contributing guidelines](https://github.com/reactph/reactjsph-website/blob/master/CODE_OF_CONDUCT.md). 56 | 57 | ## 📋 Enlisting in the Dev Board 58 | 59 | Run `yarn enlist` to enlist using the CLI or create a JSON file by following the steps below. 60 | 61 | 1. Add a JSON file to the [`content/devs`](https://github.com/reactph/reactjsph-website/blob/master/content/devs) folder with filename `firstname-lastname.json` (all lowercase, separated by `-`), e.g., `juan-dela-cruz.json`. 62 | 63 | 2. Within that file, define an object describing yourself given the format below. Here's an [example](https://github.com/reactph/reactjsph-website/blob/master/content/devs/franrey-anthony-saycon.json). 64 | 65 | | Key | Description || 66 | |-|-|-| 67 | | `avatar` | An external URL to an image of yourself | | 68 | | `name` | Your name | | 69 | | `title` | Your current job title | | 70 | | `company` | Your current employer | | 71 | | `blurb` | Short bio describing yourself | | 72 | | `skills` | String array of your skills/technologies that you would like to promote | | 73 | | `contacts` | Object array of contact information where each item has a `type` and a `url` | | 74 | 75 | 3. Commit your changes with the message `[DEV BOARD] {YOUR_NAME}` and open a pull request with the same title, following the template below: 76 | 77 | ``` 78 | I have read and verified the following upon opening this pull request to add my information to the ReactJS Philippines Dev Board: 79 | 80 | - [ ] My `avatar` is a square image 81 | - [ ] My `avatar` is below 80 kB 82 | - [ ] My `blurb` is no longer than 140 characters 83 | - [ ] I understand that only the first 5 `skills` I list will be shown on the site 84 | ``` 85 | 86 | ## 🗂 Contributing to the Project Board 87 | 88 | > We 💙 all projects, but for personal websites, consider listing them under your name through the Dev Board above instead! 89 | 90 | 1. Create a JSON file in the [`content/projects`](https://github.com/reactph/reactjsph-website/blob/master/content/projects.json) folder with filename `project-name.json` (all lowercase, separated by `-`), e.g., `reactjsph-website`. 91 | 92 | 2. Within that file, define an object describing your project given the format below: 93 | 94 | | Key | Description || 95 | |-|-|-| 96 | | `name` | The name of your project | | 97 | | `author` | Your name | | 98 | | `description` | A description of your project | | 99 | | `homepage` | Your project's homepage | | 100 | | `tags` | String array of keywords related to your project | | 101 | 102 | 3. Commit your changes with the message `[PROJECT BOARD] {YOUR_NAME}`, then open a pull request with the same title. 103 | 104 | ## 🎉 Join the community 105 | 106 | - [Facebook Group][facebook-group] 107 | - [Discord][discord] 108 | - [Meetup][meetup] 109 | 110 | [facebook-group]: https://web.facebook.com/groups/875676539148789/ 111 | [discord]: https://discord.gg/J6eZNUG 112 | [meetup]: https://www.meetup.com/ReactJS-Philippines/ 113 | -------------------------------------------------------------------------------- /content/devs/adrian-rios.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/k3KVxqK/me2-min.jpg", 3 | "name": "Adrian Rios", 4 | "title": "Front-End Developer", 5 | "company": "PLDT Global", 6 | "blurb": "Hi, you can call me Pips, a web developer from Nueva Ecija. I love building and customizing Gunpla Models and playing video games.", 7 | "skills": [ 8 | "Javascript", 9 | "React", 10 | "Angular", 11 | "PHP", 12 | "MongoDB", 13 | "PostgreSQL", 14 | "MySQL" 15 | ], 16 | "contacts": [ 17 | { 18 | "type": "github", 19 | "url": "https://github.com/adrianrios25" 20 | }, 21 | { 22 | "type": "linkedin", 23 | "url": "https://www.linkedin.com/in/adrianrios13/" 24 | }, 25 | { 26 | "type": "email", 27 | "url": "mailto:pipsrios25@gmail.com" 28 | }, 29 | { 30 | "type": "website", 31 | "url": "http://adrianriosweb.com/" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /content/devs/boone-raye-flores.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/YNDH5K8/avatar-2-1.jpg", 3 | "name": "Boone Raye Flores", 4 | "title": "Web Developer", 5 | "company": "Gate Distribution Ent., Inc.,", 6 | "blurb": "Hello Everyone! I'm Boone, I am a career shifter and currently working as web developer and IT Admin Support. Happy coding!", 7 | "skills": [ 8 | "Javascript", 9 | "React", 10 | "PHP", 11 | "MySQL", 12 | "Adobe XD" 13 | ], 14 | "contacts": [ 15 | { 16 | "type": "github", 17 | "url": "https://github.com/booneraye" 18 | }, 19 | { 20 | "type": "linkedin", 21 | "url": "https://www.linkedin.com/in/booneraye/" 22 | }, 23 | { 24 | "type": "email", 25 | "url": "mailto:booneraye@gmail.com" 26 | }, 27 | { 28 | "type": "website", 29 | "url": "http://www.booneraye.online/" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /content/devs/carl-de-guia.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Carl de Guia", 3 | "avatar": "https://i.ibb.co/RTSHmfm/20181205-142824-01.jpg", 4 | "title": "Software Engineer", 5 | "blurb": "Hey I'm Carl, a full-stack engineer, UI/UX designer, frustrated AI guy and an amateur cruciverbalist.", 6 | "skills": [ 7 | "React", 8 | "Typescript", 9 | "NodeJS", 10 | "NextJS", 11 | "MongoDB", 12 | "Angular", 13 | "Python", 14 | "GraphQL", 15 | "Figma" 16 | ], 17 | "contacts": [ 18 | { 19 | "type": "email", 20 | "url": "mailto:carl@carldegs.com" 21 | }, 22 | { 23 | "type": "github", 24 | "url": "https://github.com/carldegs" 25 | }, 26 | { 27 | "type": "linkedin", 28 | "url": "https://www.linkedin.com/in/carl-justin-de-guia-b40a1b97/" 29 | }, 30 | { 31 | "type": "twitter", 32 | "url": "https://twitter.com/carldegs" 33 | }, 34 | { 35 | "type": "website", 36 | "url": "https://carldegs.com" 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /content/devs/christian-villamin.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/QDvNvJ8/51011835-1-1.jpg", 3 | "name": "Christian Villamin", 4 | "title": "Software Engineer", 5 | "company": "High Output Ventures", 6 | "blurb": "Hi! I have a thing for optimization and solving problems. Always tinkering and excited in ever-growing tech. I also animate stuff.", 7 | "skills": [ 8 | "React", 9 | "TypeScript", 10 | "GraphQL", 11 | "Linux", 12 | "Framer Motion", 13 | "ApolloGQL", 14 | "NextJS", 15 | "GatsbyJS", 16 | "MongoDB", 17 | "PostgreSQL", 18 | "Prisma/Nexus" 19 | ], 20 | "contacts": [ 21 | { 22 | "type": "website", 23 | "url": "https://codekcv.now.sh/" 24 | }, 25 | { 26 | "type": "github", 27 | "url": "https://github.com/codekcv" 28 | }, 29 | { 30 | "type": "linkedin", 31 | "url": "https://linkedin.com/in/codekcv/" 32 | }, 33 | { 34 | "type": "email", 35 | "url": "mailto:codekcv31@gmail.com" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /content/devs/franrey-anthony-saycon.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/SygwPLn/117541609-2597101977203314-6463376874809931253-n-Cropped-1.jpg", 3 | "name": "Franrey Anthony S. Saycon", 4 | "title": "Engineering Team Lead", 5 | "company": "Phitopolis International Corp.", 6 | "blurb": "Python and Javascript junkie. I love architecting solutions, learn a lot of tech, and mentor.", 7 | "skills": [ 8 | "React", 9 | "Flask", 10 | "Typescript", 11 | "Docker", 12 | "GraphQL", 13 | "Angular", 14 | "Javascript", 15 | "MongoDB", 16 | "PostgreSQL", 17 | "Linux", 18 | "MySQL" 19 | ], 20 | "contacts": [ 21 | { 22 | "type": "website", 23 | "url": "https://fsaycon.dev" 24 | }, 25 | { 26 | "type": "github", 27 | "url": "https://github.com/franreysaycon" 28 | }, 29 | { 30 | "type": "linkedin", 31 | "url": "https://linkedin.com/in/fssaycon/" 32 | }, 33 | { 34 | "type": "email", 35 | "url": "mailto:me@fsaycon.dev" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /content/devs/gian-faye-paguirigan.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.imgur.com/YTpMxSa.jpg", 3 | "name": "Gian Faye Paguirigan", 4 | "title": "Frontend Engineer", 5 | "blurb": "I've been designing and building user interfaces since 2010.", 6 | "skills": [ 7 | "React", 8 | "TypeScript", 9 | "Gatsby", 10 | "GraphQL", 11 | "Redux", 12 | "HTML5", 13 | "CSS3", 14 | "SCSS", 15 | "JavaScript", 16 | "ES6", 17 | "Node.js", 18 | "Express", 19 | "Python", 20 | "Selenium", 21 | "Arduino", 22 | "UX Design", 23 | "UI Design" 24 | ], 25 | "contacts": [ 26 | { 27 | "type": "website", 28 | "url": "https://gianfaye.com" 29 | }, 30 | { 31 | "type": "github", 32 | "url": "https://github.com/gianfaye" 33 | }, 34 | { 35 | "type": "linkedin", 36 | "url": "https://www.linkedin.com/in/gianfaye" 37 | }, 38 | { 39 | "type": "email", 40 | "url": "mailto:contact@gianfaye.com" 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /content/devs/harvey-jay-sison.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.imgur.com/LXw7ryd.jpg", 3 | "name": "Harvey Jay M. Sison", 4 | "title": "Platform Engineer", 5 | "company": "Exora Technologies Incorporated", 6 | "blurb": "Hi! 🙌🏼 I'm a full stack software engineer 💻, a UX/UI designer🎨, and an aspiring technopreneur 👨🏽‍💼 from Quezon City, Philippines", 7 | "skills": [ 8 | "ReactJS", 9 | "NodeJS", 10 | "Express", 11 | "TypeScript", 12 | "React Native", 13 | "PostgreSQL", 14 | "MongoDB", 15 | "GatsbyJS", 16 | "NextJS", 17 | "Flutter", 18 | "Django" 19 | ], 20 | "contacts": [ 21 | { 22 | "type": "github", 23 | "url": "httpshttps://github.com/Hjkun77" 24 | }, 25 | { 26 | "type": "linkedin", 27 | "url": "https://linkedin.com/in/harveyjaysison/" 28 | }, 29 | { 30 | "type": "email", 31 | "url": "mailto:harveyjaysison@gmail.com" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /content/devs/jayson-de-los-reyes.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/3RzqhDz/60616167-144000396725182-5973974152078426112-o.jpg", 3 | "name": "Jayson De los Reyes", 4 | "title": "Frontend Developer", 5 | "company": "Orange and Crane Innovations, Inc.", 6 | "blurb": "I'm Jayson. Web and Mobile Developer. Casual Gamer. Hobbyist Cosplayer. Furdaddy.", 7 | "skills": ["React", "React-Native", "GraphQL", "NextJS", "GatsbyJS"], 8 | "contacts": [ 9 | { 10 | "type": "github", 11 | "url": "https://github.com/jisundr" 12 | }, 13 | { 14 | "type": "linkedin", 15 | "url": "https://linkedin.com/in/jisundr/" 16 | }, 17 | { 18 | "type": "email", 19 | "url": "mailto:jisun.delosreyes@gmail.com" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /content/devs/john-joseph-mendez.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/w41V8ZG/Resized-Jay.jpg", 3 | "name": "John Joseph Mendez", 4 | "title": "Software Engineer", 5 | "company": "Mastt", 6 | "blurb": "I'm Jay, a Software Engineer and i just love everything about tech", 7 | "skills": [ 8 | "React", 9 | "Typescript", 10 | "GraphQL", 11 | "Arduino", 12 | "React Native", 13 | "Python", 14 | "php", 15 | "ApolloGQL", 16 | "Javascript" 17 | ], 18 | "contacts": [ 19 | { 20 | "type": "github", 21 | "url": "https://github.com/jaymendez" 22 | }, 23 | { 24 | "type": "linkedin", 25 | "url": "https://www.linkedin.com/in/jaymndz/" 26 | }, 27 | { 28 | "type": "email", 29 | "url": "mailto:jayemndz@gmail.com" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /content/devs/marjorie-martinez.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/cD2CnB8/marj.png", 3 | "name": "Marjorie J. Martinez", 4 | "title": "Software Engineer", 5 | "company": "Phitopolis International Corp.", 6 | "blurb": "Hi Marj here! Software Engineer enthusiast. Frustrated freediver and certified dog mom.", 7 | "skills": [ 8 | "React", 9 | "GraphQL", 10 | "NextJS", 11 | "Javascript", 12 | "PostgreSQL", 13 | "MongoDB", 14 | "GatsbyJS" 15 | ], 16 | "contacts": [ 17 | { 18 | "type": "github", 19 | "url": "https://github.com/marjmartinezz" 20 | }, 21 | { 22 | "type": "linkedin", 23 | "url": "https://www.linkedin.com/in/marjorie-martinez/" 24 | }, 25 | { 26 | "type": "email", 27 | "url": "mailto:marjoriemartinezdev@gmail.com" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /content/devs/mark-dino-pelonia.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://avatars1.githubusercontent.com/u/36836488?s=460&u=3bad90fad66e85a12ff90883ea54e2d3ba8f7fe7&v=4", 3 | "name": "Mark Dino Pelonia", 4 | "title": "Junior Software Engineer", 5 | "company": "Damstra Technology/Shore360", 6 | "blurb": "Hi, I'm a JavaScript & React enthusiast, have an eye for design, convert mock design to a live website, and naturally curious.", 7 | "skills": [ 8 | "JavaScript", 9 | "React", 10 | "Gatsby", 11 | "NodeJS", 12 | "MongoDB", 13 | "GraphQL", 14 | "Git" 15 | ], 16 | "contacts": [ 17 | { 18 | "type": "website", 19 | "url": "https://www.markdino.com" 20 | }, 21 | { 22 | "type": "github", 23 | "url": "https://github.com/markdino" 24 | }, 25 | { 26 | "type": "linkedin", 27 | "url": "https://linkedin.com/in/markdinopelonia" 28 | }, 29 | { 30 | "type": "email", 31 | "url": "mailto:markdinopelonia447@gmail.com" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /content/devs/miguel-galace.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://res.cloudinary.com/galacemiguel/image/upload/c_fit,dpr_3.0,f_auto,q_auto,w_100/v1576307468/galacemiguel.com/20190103_074056", 3 | "name": "Miguel N. Galace", 4 | "title": "Software Engineer", 5 | "company": "Quipper", 6 | "blurb": "I'm Miguel and I obsess over web design. My mission is to elevate the standard of web design and development in the Philippines.", 7 | "skills": ["React", "Rails", "TypeScript"], 8 | "contacts": [ 9 | { 10 | "type": "website", 11 | "url": "https://galacemiguel.com" 12 | }, 13 | { 14 | "type": "github", 15 | "url": "https://github.com/galacemiguel" 16 | }, 17 | { 18 | "type": "linkedin", 19 | "url": "https://linkedin.com/in/galacemiguel/" 20 | }, 21 | { 22 | "type": "email", 23 | "url": "mailto:galacemiguel@gmail.com" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /content/devs/nemuel-lim.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.imgur.com/JjBvTHW.jpg", 3 | "name": "Nemuel Lim", 4 | "title": "Software Engineer - Frontend", 5 | "blurb": "Im Nem! Former software engineer from Talon Amadeo Cavite. I love playing sports, mobile and pc games.", 6 | "skills": [ 7 | "Angular", 8 | "Vue", 9 | "React", 10 | "Javascript", 11 | "TypeScript", 12 | "Graphql", 13 | "Basic Electron", 14 | "Basic Nodejs" 15 | ], 16 | "contacts": [ 17 | { 18 | "type": "website", 19 | "url": "https://nemuel.pb.online" 20 | }, 21 | { 22 | "type": "linkedin", 23 | "url": "https://www.linkedin.com/in/nemuel-lim-4092791a1/" 24 | }, 25 | { 26 | "type": "github", 27 | "url": "https://github.com/limnemuel22" 28 | }, 29 | { 30 | "type": "email", 31 | "url": "mailto:lim.nemuel.22@gmail.com" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /content/devs/oliver-jurgen-escoto.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/GW5Ntkc/test2-resize.jpg", 3 | "name": "Oliver Jurgen Escoto", 4 | "title": "Software Engineer - Frontend", 5 | "company": "High Output Ventures", 6 | "blurb": "I'm Oliver. A self taught developer, relentless Learning Machine and an obsessive compulsive Problem Solver.", 7 | "skills": ["React", "Typescript", "GraphQL", "Python"], 8 | "contacts": [ 9 | { 10 | "type": "github", 11 | "url": "https://github.com/oliverJurgen" 12 | }, 13 | { 14 | "type": "linkedin", 15 | "url": "https://www.linkedin.com/in/oliverEscoto/" 16 | }, 17 | { 18 | "type": "email", 19 | "url": "mailto:oliver.jurgen90@gmail.com" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /content/devs/ralph-largo.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://largs.s3.amazonaws.com/2x2.jpg", 3 | "name": "Ralph Largo", 4 | "title": "Software Engineer", 5 | "blurb": "Im Largs! A home-based software engineer from Olongapo. I love Memes and Dota 2.", 6 | "skills": ["React", "NextJS", "Electron", "TypeScript", "Graphql"], 7 | "contacts": [ 8 | { 9 | "type": "website", 10 | "url": "https://ralphlargo.com" 11 | }, 12 | { 13 | "type": "linkedin", 14 | "url": "https://www.linkedin.com/in/devlargs/" 15 | }, 16 | { 17 | "type": "github", 18 | "url": "https://github.com/devlargs" 19 | }, 20 | { 21 | "type": "email", 22 | "url": "mailto:devlargs@gmail.com" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /content/devs/rhaidzsal-ali.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/0fGg44G/IMG-5i4gyw-1.jpg", 3 | "name": "Rhaidzsal Ali", 4 | "title": "Software Engineer", 5 | "company": "High Output Ventures", 6 | "blurb": "I'm Rhaidz and I make things on the web.", 7 | "skills": ["React", "Typescript", "GraphQL"], 8 | "contacts": [ 9 | { 10 | "type": "website", 11 | "url": "https://rhaicode.netlify.com" 12 | }, 13 | { 14 | "type": "github", 15 | "url": "https://github.com/rhaicode" 16 | }, 17 | { 18 | "type": "linkedin", 19 | "url": "https://www.linkedin.com/in/rhaicode" 20 | }, 21 | { 22 | "type": "email", 23 | "url": "mailto:rhaidzsal.ali@gmail.com" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /content/devs/ryan-bautista.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://ryan3sg.github.io/images/rye-ayan.jpg", 3 | "name": "Ryan Bautista", 4 | "title": "Frontend Developer", 5 | "blurb": "My career mostly driven by my passion in UI. I have been part of building web apps for several years. I make great ideas happen.", 6 | "skills": ["React", "Gatsby", "Mobx", "TypeScript", "VueJS"], 7 | "contacts": [ 8 | { 9 | "type": "website", 10 | "url": "https://ryan3sg.github.io/" 11 | }, 12 | { 13 | "type": "linkedin", 14 | "url": "https://www.linkedin.com/in/ryan3sg/" 15 | }, 16 | { 17 | "type": "github", 18 | "url": "https://github.com/ryan3sg" 19 | }, 20 | { 21 | "type": "email", 22 | "url": "mailto:ryan3sg@yahoo.com" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /content/devs/terri-john-andoy.json: -------------------------------------------------------------------------------- 1 | { 2 | "avatar": "https://i.ibb.co/gymcmtV/terri-dev-pic-1.png", 3 | "name": "Terri John P. Andoy, CpE", 4 | "title": "Software / DevOps Engineer", 5 | "company": "White Cloak Technologies, Inc.", 6 | "blurb": "What's up, I'm TJ! I like technology, web-dev stuff and anime!", 7 | "skills": [ 8 | "React", 9 | "Go", 10 | "TypeScript", 11 | "MongoDB", 12 | "Arduino", 13 | "JavaScript", 14 | "Terraform", 15 | "Ansible" 16 | ], 17 | "contacts": [ 18 | { 19 | "type": "github", 20 | "url": "https://github.com/tjandoy" 21 | }, 22 | { 23 | "type": "linkedin", 24 | "url": "https://www.linkedin.com/in/tjandoy/" 25 | }, 26 | { 27 | "type": "email", 28 | "url": "mailto:tj.andoy@gmail.com" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /content/projects/become-a-hooks-hero.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Become a Hooks Hero", 3 | "author": "Franrey Anthony S. Saycon", 4 | "description": "A repository with full commented explanations on how to use the different hooks of the new Hook API of React.", 5 | "homepage": "https://github.com/franreysaycon/become-a-hooks-hero", 6 | "tags": ["reactjs", "philippines"] 7 | } 8 | -------------------------------------------------------------------------------- /content/projects/fluid-system.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Fluid System", 3 | "author": "Miguel N. Galace", 4 | "description": "Fluid System is a style props function transformer for generating fluid styles. 💦", 5 | "homepage": "https://github.com/galacemiguel/fluid-system", 6 | "tags": [ 7 | "typography", 8 | "fluid", 9 | "styled-system", 10 | "styled-components", 11 | "emotion" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /content/projects/reactjsph-website.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactJS Philippines Website", 3 | "author": "ReactJS Philippines Core Team", 4 | "description": "Official website of ReactJS Philippines", 5 | "homepage": "https://reactjs.org.ph", 6 | "tags": ["reactjs", "philippines"] 7 | } 8 | -------------------------------------------------------------------------------- /content/projects/rehackt-challenge-w1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Rehackt Challenge #1 - Turn It Up", 3 | "author": "ReactJS Philippines", 4 | "description": "The brief is simple. Design the worst (or best) volume control UI imaginable!", 5 | "homepage": "https://rehackt-challenge-week-one.netlify.app/", 6 | "tags": ["reactjs philippines", "rehackt"], 7 | "pinned": true 8 | } 9 | -------------------------------------------------------------------------------- /content/projects/stores-near-me.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Stores Near Me", 3 | "author": "Franrey Anthony S. Saycon", 4 | "description": "Find convenience stores near you in a click of a button.", 5 | "homepage": "https://github.com/franreysaycon/cra-stores-near-me", 6 | "tags": ["reactjs", "google api", "philippines"] 7 | } 8 | -------------------------------------------------------------------------------- /content/projects/street-bridge.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Street Bridge", 3 | "author": "Carl de Guia", 4 | "description": "Not your grandma's Bridge game", 5 | "homepage": "https://street-bridge.web.app/", 6 | "tags": ["reactjs", "bridge", "typescript", "firebase"] 7 | } 8 | -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import RootElement from "./src/root-element" 3 | 4 | export const wrapRootElement = ({ element }) => ( 5 | {element} 6 | ) 7 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: `ReactJS Philippines`, 4 | description: `We are a group of Filipino developers dedicated to nation-building through our community and shared enthusiasm for React and for excellence overall.`, 5 | author: `ReactJS PH`, 6 | email: `core.reactjsph@gmail.com`, 7 | cover: `/meta-image-cover.jpg`, 8 | url: `https://reactjs.org.ph`, 9 | social: { 10 | facebook: `https://www.facebook.com/reactjsphilippines/`, 11 | messenger: `https://m.me/reactjsphilippines`, 12 | meetup: `https://www.meetup.com/ReactJS-Philippines/`, 13 | linkedin: `https://www.linkedin.com/company/reactjs-philippines/`, 14 | discord: `https://discord.gg/J6eZNUG`, 15 | }, 16 | }, 17 | pathPrefix: `/reactjsph-website`, 18 | plugins: [ 19 | `gatsby-plugin-react-helmet`, 20 | `gatsby-transformer-json`, 21 | { 22 | resolve: `gatsby-source-filesystem`, 23 | options: { 24 | name: `images`, 25 | path: `${__dirname}/src/images`, 26 | }, 27 | }, 28 | { 29 | resolve: `gatsby-source-filesystem`, 30 | options: { 31 | name: `devs`, 32 | path: `${__dirname}/content/devs`, 33 | }, 34 | }, 35 | { 36 | resolve: `gatsby-source-filesystem`, 37 | options: { 38 | path: `${__dirname}/content/projects`, 39 | }, 40 | }, 41 | `gatsby-transformer-sharp`, 42 | `gatsby-plugin-sharp`, 43 | { 44 | resolve: `gatsby-plugin-manifest`, 45 | options: { 46 | name: `ReactJS Philippines`, 47 | short_name: `ReactJS PH`, 48 | description: `We are a group of Filipino developers dedicated to nation-building through our community's shared enthusiasm for React and for excellence overall.`, 49 | start_url: `/`, 50 | background_color: `#0c1d60`, 51 | theme_color: `#0c1d60`, 52 | display: `minimal-ui`, 53 | icon: `src/images/favicon.svg`, // This path is relative to the root of the site. 54 | }, 55 | }, 56 | `gatsby-plugin-emotion`, 57 | { 58 | resolve: `gatsby-plugin-env-variables`, 59 | options: { 60 | allowList: [`FACEBOOK_GRAPH_TOKEN`], 61 | }, 62 | }, 63 | { 64 | resolve: `gatsby-plugin-react-svg`, 65 | options: { 66 | rule: { 67 | include: /\.inline\.svg$/, 68 | }, 69 | }, 70 | }, 71 | ], 72 | } 73 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | exports.onCreateWebpackConfig = ({ actions }) => { 2 | actions.setWebpackConfig({ 3 | target: "node", 4 | externals: { canvas: "commonjs canvas" }, 5 | }) 6 | } 7 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import RootElement from "./src/root-element" 3 | 4 | export const wrapRootElement = ({ element }) => ( 5 | {element} 6 | ) 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactjsph-website", 3 | "private": true, 4 | "description": "ReactJS PH website", 5 | "version": "0.1.0", 6 | "author": "ReactJS PH ", 7 | "dependencies": { 8 | "@emotion/core": "^10.0.16", 9 | "@emotion/styled": "^10.0.15", 10 | "@fortawesome/fontawesome-svg-core": "^1.2.22", 11 | "@fortawesome/free-brands-svg-icons": "^5.10.2", 12 | "@fortawesome/free-solid-svg-icons": "^5.10.2", 13 | "@fortawesome/react-fontawesome": "^0.1.4", 14 | "@reach/dialog": "^0.8.6", 15 | "@react-hook/intersection-observer": "^2.0.10", 16 | "@rebass/preset": "^4.0.3", 17 | "babel-eslint": "^10.1.0", 18 | "csshake": "^1.5.3", 19 | "date-fns": "^2.10.0", 20 | "emotion-reset": "^2.0.2", 21 | "emotion-theming": "^10.0.14", 22 | "fabric": "3.6.2", 23 | "formik": "^2.1.3", 24 | "gatsby": "^2.24.80", 25 | "gatsby-image": "^2.1.2", 26 | "gatsby-plugin-emotion": "^4.1.2", 27 | "gatsby-plugin-env-variables": "^2.0.0", 28 | "gatsby-plugin-manifest": "^2.1.1", 29 | "gatsby-plugin-offline": "^2.1.1", 30 | "gatsby-plugin-react-helmet": "^3.0.12", 31 | "gatsby-plugin-react-svg": "^3.0.0", 32 | "gatsby-plugin-sharp": "^2.1.3", 33 | "gatsby-source-filesystem": "^2.0.38", 34 | "gatsby-transformer-json": "2.11.0", 35 | "gatsby-transformer-sharp": "^2.1.21", 36 | "lodash.debounce": "^4.0.8", 37 | "prop-types": "^15.7.2", 38 | "react": "^16.9.0", 39 | "react-dom": "^16.9.0", 40 | "react-error-boundary": "^3.0.2", 41 | "react-google-recaptcha": "^2.0.1", 42 | "react-helmet": "^5.2.1", 43 | "rebass": "^4.0.3", 44 | "yup": "^0.28.1" 45 | }, 46 | "devDependencies": { 47 | "eslint": "6.2.0", 48 | "eslint-config-airbnb": "^18.0.1", 49 | "eslint-config-prettier": "^6.1.0", 50 | "eslint-plugin-import": "^2.18.2", 51 | "eslint-plugin-jsx-a11y": "^6.2.3", 52 | "eslint-plugin-prettier": "^3.1.0", 53 | "eslint-plugin-react": "^7.14.3", 54 | "eslint-plugin-react-hooks": "^1.7.0", 55 | "gh-pages": "^2.1.1", 56 | "husky": "^3.0.4", 57 | "inquirer": "^8.2.0", 58 | "joi": "^17.2.1", 59 | "lint-staged": "^9.2.3", 60 | "prettier": "^1.17.1", 61 | "prettier-eslint-cli": "^5.0.0" 62 | }, 63 | "license": "MIT", 64 | "scripts": { 65 | "build": "gatsby build", 66 | "develop": "gatsby develop", 67 | "format": "prettier --write 'src/**/*.{js,jsx,css,scss}'", 68 | "start": "yarn run develop", 69 | "serve": "gatsby serve", 70 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\"", 71 | "lint": "eslint \"src/**/*.{js,jsx}\" --fix", 72 | "deploy": "gatsby build --prefix-paths && gh-pages -d public", 73 | "validate": "lint-staged", 74 | "enlist": "node scripts/add-dev-board.js" 75 | }, 76 | "repository": { 77 | "type": "git", 78 | "url": "https://github.com/reactph/reactjsph-website" 79 | }, 80 | "bugs": { 81 | "url": "https://github.com/reactph/reactjsph-website/issues" 82 | }, 83 | "lint-staged": { 84 | "**/*.js": [ 85 | "eslint --fix", 86 | "prettier-eslint --write", 87 | "git add" 88 | ] 89 | }, 90 | "husky": { 91 | "hooks": { 92 | "pre-commit": "node ./scripts/pre-commit", 93 | "pre-push": "node ./scripts/pre-push" 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /scripts/add-dev-board.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const inquirer = require("inquirer") 3 | const { promises: fs } = require("fs") 4 | const path = require("path") 5 | 6 | const CONTACT_TYPES = [ 7 | "behance", 8 | "email", 9 | "github", 10 | "linkedin", 11 | "twitter", 12 | "website", 13 | ] 14 | 15 | const FIELD_EMPTY_MESSAGE = "Field Required." 16 | const FIELD_INVALID_URL = "Invalid URL." 17 | const FIELD_MAX_LENGTH = "Field must be 140 characters or less" 18 | 19 | const isFieldEmpty = input => !input?.length 20 | const isFieldURL = input => 21 | new RegExp( 22 | /[(http(s)?)://(www.)?a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/ 23 | ).test(input) 24 | const isFieldMaxLength = input => input.length > 140 25 | 26 | const askSkills = async (skills = []) => { 27 | let newSkills = [...skills] 28 | const answers = await inquirer.prompt([ 29 | { 30 | type: "input", 31 | name: "skill", 32 | message: `Add skill/technology #${newSkills.length + 1}`, 33 | }, 34 | ]) 35 | 36 | if (answers.skill?.length) { 37 | newSkills = [...newSkills, answers.skill] 38 | return askSkills(newSkills) 39 | } 40 | 41 | return newSkills 42 | } 43 | 44 | const askContacts = async (contacts = []) => { 45 | const { type } = await inquirer.prompt([ 46 | { 47 | type: "list", 48 | name: "type", 49 | choices: [ 50 | ...CONTACT_TYPES, 51 | `I don't want to add ${contacts?.length ? "another" : "a"} contact`, 52 | ], 53 | message: `Choose${contacts?.length ? " another" : ""} type`, 54 | default: 0, 55 | }, 56 | ]) 57 | 58 | if (type.includes("I don't want to add")) { 59 | return contacts 60 | } 61 | 62 | const { url } = await inquirer.prompt([ 63 | { 64 | type: "input", 65 | name: "url", 66 | message: 67 | "URL (leave empty if you want to cancel adding this contact type)", 68 | validate: input => { 69 | if (isFieldEmpty(input)) { 70 | return true 71 | } 72 | 73 | if (!isFieldURL(input)) { 74 | return FIELD_INVALID_URL 75 | } 76 | 77 | return true 78 | }, 79 | }, 80 | ]) 81 | 82 | if (!url?.length) { 83 | return contacts 84 | } 85 | 86 | return askContacts([...contacts, { type, url }]) 87 | } 88 | 89 | const addToDevBoard = async () => { 90 | let data = {} 91 | 92 | const answers = await inquirer.prompt([ 93 | { 94 | type: "input", 95 | name: "name", 96 | message: "Full Name", 97 | validate: input => !isFieldEmpty(input) || FIELD_EMPTY_MESSAGE, 98 | }, 99 | { 100 | type: "input", 101 | name: "avatar", 102 | message: 103 | "An external URL to an image of yourself (Must be a square image and less than 80 kB)", 104 | validate: input => { 105 | if (isFieldEmpty(input)) { 106 | return FIELD_EMPTY_MESSAGE 107 | } 108 | 109 | if (!isFieldURL(input)) { 110 | return FIELD_INVALID_URL 111 | } 112 | 113 | return true 114 | }, 115 | }, 116 | { 117 | type: "input", 118 | name: "title", 119 | message: "Current job title", 120 | validate: input => !isFieldEmpty(input) || FIELD_EMPTY_MESSAGE, 121 | }, 122 | { 123 | type: "input", 124 | name: "company", 125 | message: "Your current employer (optional)", 126 | }, 127 | { 128 | type: "input", 129 | name: "blurb", 130 | message: "Short bio describing yourself (140 characters or less)", 131 | validate: input => { 132 | if (isFieldEmpty(input)) { 133 | return FIELD_EMPTY_MESSAGE 134 | } 135 | 136 | if (isFieldMaxLength(input)) { 137 | return `${FIELD_MAX_LENGTH} (${input.length} chars.)` 138 | } 139 | 140 | return true 141 | }, 142 | }, 143 | ]) 144 | 145 | console.log(` 146 | Add skills/technologies that you would like to promote 147 | * Only the first 5 will be listed, but feel free to add as many as you like as we plan to allow devs to be filtered by skills in the future 148 | * Leave blank if you're done adding items 149 | `) 150 | 151 | const skills = await askSkills() 152 | 153 | console.log("\nAdd contact information\n") 154 | 155 | const contacts = await askContacts() 156 | 157 | data = { 158 | ...answers, 159 | skills, 160 | contacts: contacts.map(contact => { 161 | if (contact.type === "email" && !contact.url.includes("mailto:")) { 162 | return { 163 | ...contact, 164 | url: `mailto:${contact.url}`, 165 | } 166 | } 167 | 168 | return contact 169 | }), 170 | company: answers.company?.length ? answers.company : undefined, 171 | } 172 | 173 | const fileName = `${answers.name 174 | .toLowerCase() 175 | .split(".") 176 | .join("") 177 | .split(" ") 178 | .join("-")}.json` 179 | const filePath = path.join(__dirname, `../content/devs/${fileName}`) 180 | console.log(`\n\nCreating JSON file ${fileName} with content`) 181 | console.log(data) 182 | 183 | try { 184 | await fs.stat(filePath) 185 | 186 | const { confirm } = await inquirer.prompt([ 187 | { 188 | name: "confirm", 189 | type: "confirm", 190 | message: `A file with name ${fileName} already exists. Do you want to overwrite this file?`, 191 | default: false, 192 | }, 193 | ]) 194 | 195 | if (confirm) { 196 | await fs.unlink(filePath) 197 | } 198 | } catch (err) { 199 | if (err.code !== "ENOENT") { 200 | console.error(err) 201 | return 202 | } 203 | } 204 | 205 | try { 206 | await fs.writeFile(filePath, JSON.stringify(data, null, 2)) 207 | console.log(`${answers.name} successfully added to the Dev Board`) 208 | } catch (err) { 209 | console.error(err) 210 | } 211 | } 212 | 213 | addToDevBoard() 214 | -------------------------------------------------------------------------------- /scripts/pre-commit.js: -------------------------------------------------------------------------------- 1 | const { spawnSync } = require("child_process") 2 | 3 | const result = spawnSync("yarn validate", { stdio: "inherit", shell: true }) 4 | 5 | if (result.status !== 0) { 6 | process.exit(result.status) 7 | } 8 | -------------------------------------------------------------------------------- /scripts/pre-push.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | /* eslint-disable no-console */ 3 | const fs = require("fs") 4 | const Joi = require("joi") 5 | const { spawnSync } = require("child_process") 6 | 7 | const result = spawnSync("yarn lint", { stdio: "inherit", shell: true }) 8 | 9 | if (result.status !== 0) { 10 | process.exit(result.status) 11 | } 12 | 13 | const validateJson = (dir, schema) => { 14 | fs.readdir(dir, (err, files) => { 15 | if (err) { 16 | throw err 17 | } 18 | 19 | files.forEach(async file => { 20 | const json = JSON.parse(fs.readFileSync(`${dir}${file}`, "utf8")) 21 | 22 | try { 23 | await schema.validateAsync(json) 24 | } catch (error) { 25 | console.log(`${file} has invalid details`) 26 | console.log(error.details) 27 | process.exit(1) 28 | } 29 | }) 30 | }) 31 | } 32 | 33 | const contentJsons = [ 34 | { 35 | dir: `${__dirname}/../content/devs/`, 36 | schema: Joi.object({ 37 | avatar: Joi.string() 38 | .uri() 39 | .required(), 40 | name: Joi.string() 41 | .max(50) 42 | .required(), 43 | title: Joi.string() 44 | .max(50) 45 | .required(), 46 | company: Joi.string() 47 | .max(50) 48 | .optional(), 49 | blurb: Joi.string() 50 | .max(140) 51 | .required(), 52 | skills: Joi.array() 53 | .items(Joi.string().max(15)) 54 | .min(1) 55 | .required(), 56 | contacts: Joi.array().items( 57 | Joi.object().keys({ 58 | type: Joi.string() 59 | .valid( 60 | "website", 61 | "github", 62 | "linkedin", 63 | "email", 64 | "behance", 65 | "twitter" 66 | ) 67 | .required(), 68 | url: Joi.string() 69 | .uri() 70 | .required(), 71 | }) 72 | ), 73 | }), 74 | }, 75 | { 76 | dir: `${__dirname}/../content/projects/`, 77 | schema: Joi.object({ 78 | name: Joi.string() 79 | .max(50) 80 | .required(), 81 | author: Joi.string() 82 | .max(50) 83 | .required(), 84 | description: Joi.string() 85 | .max(280) 86 | .required(), 87 | homepage: Joi.string() 88 | .uri() 89 | .required(), 90 | tags: Joi.array() 91 | .items(Joi.string().max(50)) 92 | .min(1) 93 | .optional(), 94 | pinned: Joi.boolean().optional(), 95 | }), 96 | }, 97 | ] 98 | 99 | contentJsons.map(({ dir, schema }) => validateJson(dir, schema)) 100 | -------------------------------------------------------------------------------- /src/components/circleButton.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import { Flex, Text } from "rebass" 4 | 5 | const CircleButton = ({ children, ...props }) => ( 6 | 41 | 42 | {children} 43 | 44 | 45 | ) 46 | 47 | export default CircleButton 48 | -------------------------------------------------------------------------------- /src/components/contact.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState } from "react" 2 | import PropTypes from "prop-types" 3 | import { Box, Text, Button } from "rebass" 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 5 | import { faCircleNotch } from "@fortawesome/free-solid-svg-icons" 6 | import { Formik } from "formik" 7 | import * as yup from "yup" 8 | // import Recaptcha from "react-google-recaptcha" 9 | import useIntersectionObserver from "@react-hook/intersection-observer" 10 | import Container from "./container" 11 | import MessageSentModal from "./messageSentModal" 12 | import { generate3dShadow } from "../utils" 13 | 14 | // const RECAPTCHA_KEY = process.env.GATSBY_SITE_RECAPTCHA_KEY 15 | 16 | const contactFormValidationSchema = yup.object().shape({ 17 | name: yup.string().required("Please enter your name."), 18 | email: yup 19 | .string() 20 | .required("Please enter your email address.") 21 | .email("Please enter a valid email address."), 22 | message: yup.string().required("Please enter your message."), 23 | }) 24 | 25 | const encode = data => { 26 | return Object.keys(data) 27 | .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`) 28 | .join("&") 29 | } 30 | 31 | const Contact = () => { 32 | // const recaptchaRef = useRef(null) 33 | const formikRef = useRef(null) 34 | const [showModal, setShowModal] = useState(false) 35 | const [submitting, setSubmitting] = useState(false) 36 | const [entry, observerRef] = useIntersectionObserver({ 37 | threshold: 0.5, 38 | }) 39 | 40 | const handleFormSubmit = values => { 41 | setSubmitting(true) 42 | // recaptchaRef.current.execute() 43 | // const recaptchaValue = 44 | // (recaptchaRef && 45 | // recaptchaRef.current && 46 | // recaptchaRef.current.getValue()) || 47 | // null 48 | 49 | const data = { 50 | "form-name": "contact", 51 | // "g-recaptcha-response": recaptchaValue, 52 | ...values, 53 | } 54 | 55 | fetch("/", { 56 | method: "POST", 57 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, 58 | body: encode(data), 59 | }) 60 | .then(() => { 61 | // recaptchaRef.current.reset() 62 | formikRef.current.resetForm({ 63 | name: "", 64 | email: "", 65 | message: "", 66 | }) 67 | 68 | setShowModal(true) 69 | }) 70 | .catch(() => {}) 71 | .finally(() => { 72 | setSubmitting(false) 73 | }) 74 | } 75 | 76 | const closeModal = () => setShowModal(false) 77 | 78 | return ( 79 | 80 | 81 | 91 | Sponsor a meet-up 92 | 93 | or just get in touch. 94 | 95 | 96 | 97 | 107 | {({ values, handleSubmit, handleChange, touched, errors }) => ( 108 |
115 | 116 | 119 | 129 | 130 | 138 | 139 | 140 | 148 | 149 | 152 | 160 | 161 | 162 | 163 | 164 | 171 | 172 | 173 | 178 | {/* */} 183 | 184 |
185 | )} 186 |
187 |
188 | 189 |
190 | ) 191 | } 192 | 193 | const FormInput = ({ name, label, type, value, onChange, error }) => ( 194 | generate3dShadow(5, theme.colors.white), 208 | boxSizing: "border-box", 209 | color: "white", 210 | fontFamily: "body", 211 | fontSize: 1, 212 | padding: 1, 213 | cursor: "pointer", 214 | transition: "200ms border-color, 200ms background-color", 215 | ":focus, :hover": { 216 | borderColor: "lightBlue", 217 | backgroundColor: "transparent", 218 | }, 219 | ":focus, :active": { 220 | boxShadow: theme => generate3dShadow(2, theme.colors.white), 221 | transform: "translate(3px, 3px)", 222 | }, 223 | }, 224 | 225 | textarea: { 226 | height: "14.8rem", 227 | resize: "none", 228 | }, 229 | }} 230 | > 231 |