Compare commits

...

64 Commits

Author SHA1 Message Date
Rahul Jain 8899046e5e remove files 2021-10-31 16:50:30 +05:30
Rahul Jain a0e34df02d Merge pull request #496 from rahuldkjain/enhancement/issue-495
Enhancement/issue 495
2021-10-31 15:49:44 +05:30
Rahul Jain 9ba8ccff66 fix: eslinting 2021-10-31 15:43:03 +05:30
Rahul Jain 004401a8d1 intial eslint pre-commit setup 2021-10-31 12:51:09 +05:30
Rahul Jain fb6389f569 Merge pull request #493 from rahuldkjain/enhancement/fix-warnings
fix: few ESLint warnings
2021-10-31 12:23:18 +05:30
Rahul Jain d33d139590 make node version 14 2021-10-31 12:18:45 +05:30
Rahul Jain 1bffabd8bb add before script in travis.yml 2021-10-31 12:14:27 +05:30
Rahul Jain 6ff29bcf87 fix node version 2021-10-31 10:51:51 +05:30
Rahul Jain 8c84e917c9 fix: npm version in .yml 2021-10-31 10:48:54 +05:30
Rahul Jain f04dc760e2 fix: few ESLint warnings 2021-10-31 10:36:41 +05:30
Rahul Jain 938a8a9d43 Merge pull request #484 from ajvideira/nextjs-logo-fix
fix: nextjs broken logo url
2021-10-28 13:16:53 +05:30
Jonathan Alba Videira 2109192d72 Fix nextjs broken logo url 2021-10-21 07:43:57 -03:00
Rahul Jain 793513dc21 Merge pull request #465 from chandrikadeb7/kafka-svg-fix
Kafka svg fix
2021-10-21 08:55:14 +05:30
Rahul Jain bf62cec45f Merge pull request #463 from pranansh-s/master
[add]: Nim-Programming language
2021-10-21 08:54:03 +05:30
Rahul Jain 646c0804b9 Merge pull request #464 from mehabhalodiya/patch1
Adds "pandas" and "seaborn" in AI/ML
2021-10-21 08:53:32 +05:30
Rahul Jain b406f4d181 Merge pull request #460 from BerniWittmann/master
feat: add ifttt to automation
2021-10-21 08:50:56 +05:30
Rahul Jain ededb4b8a5 Merge pull request #458 from MrDoomy/feat/better-checkboxes
Using toggle switches instead of checkboxes
2021-10-21 08:49:14 +05:30
Rahul Jain 63347fc8b5 Merge pull request #456 from RetiFier/valdate_json_upload
Add Validation JSON Upload Under Config options
2021-10-21 08:46:58 +05:30
Rahul Jain 1c7bcb7d6b Merge pull request #454 from MrDoomy/feat/backend-development-nestjs
[add]: NestJS Option
2021-10-21 08:46:02 +05:30
Rahul Jain edbaa47c40 Merge pull request #439 from gargipandkar/support-bugfix
Fix #423 - support field not saved/restored
2021-10-21 08:37:43 +05:30
Damien Chazoule e084c9e775 Using redesigned checkboxes on addons section 2021-10-06 19:56:06 +02:00
Chandrika Deb 91bdf52f58 Add files via upload 2021-10-06 22:24:46 +05:30
Chandrika Deb 0823cd43ce Delete kafka.svg 2021-10-06 22:24:03 +05:30
Damien Chazoule 7a93ebeae1 Using redesigned checkboxes rather than toggle switches 2021-10-06 13:18:31 +02:00
mehabhalodiya 46d3751b91 Add pandas and seaborn 2021-10-06 14:38:35 +05:30
Pranansh Singh 6a7a6575b7 Updated icon with a better visibility one 2021-10-06 03:00:16 +05:30
Pranansh Singh 61b8362a55 Added Nim-Programming language 2021-10-06 02:54:21 +05:30
Bernhard Wittmann 68bfa23dff feat: add ifttt to automation 2021-10-04 20:06:34 +02:00
Damien Chazoule f0a9d02f26 Adding unit tests 2021-10-04 10:08:00 +02:00
Damien Chazoule 20b47a9c3d Using toggle switches instead of checkboxes 2021-10-03 23:00:56 +02:00
Damien Chazoule 9432f7d88d Using Devicons SVG + Adding NestJS Link 2021-10-03 21:32:38 +02:00
Reti Fier 15c63a347a Add Validation JSON Upload Under Config options 2021-10-04 01:13:16 +06:30
Damien Chazoule fc1ecf5ab6 Added NestJS Option 2021-10-03 20:04:50 +02:00
Rahul Jain 0194c38eb6 Merge pull request #450 from chandrikadeb7/chandrikadeb7-svg
fix #444: add theme neutral social icons
2021-10-03 09:48:07 +05:30
Chandrika Deb be0234927d SVG social icons added 2021-10-02 16:19:33 +05:30
Rahul Jain 0253d1b5bb Merge pull request #441 from wweverma1/feature/add-kofi-button
issue #424: add Ko-fi donation option
2021-10-02 13:38:17 +05:30
Rahul Jain c7fc859f0c Merge pull request #443 from chandrikadeb7/chandrikadeb7-devlogo
fix #345: dev-dot-to logo
2021-10-02 13:31:49 +05:30
Chandrika Deb f21bbf2af7 Dev logo svg neutral icon added 2021-10-02 13:25:34 +05:30
wweverma1 bbf6cf6018 Added Ko-fi donation option 2021-10-01 17:23:32 +05:30
gargipandkar ccdd09db3f Merge branch 'rahuldkjain:master' into support-bugfix 2021-09-27 14:55:43 +08:00
Rahul Jain 9eb2ab1260 Merge pull request #437 from rahuldkjain/dependabot/npm_and_yarn/color-string-1.6.0
Bump color-string from 1.5.3 to 1.6.0
2021-09-26 20:00:56 +05:30
dependabot[bot] 36076a1fe9 Bump color-string from 1.5.3 to 1.6.0
Bumps [color-string](https://github.com/Qix-/color-string) from 1.5.3 to 1.6.0.
- [Release notes](https://github.com/Qix-/color-string/releases)
- [Changelog](https://github.com/Qix-/color-string/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Qix-/color-string/commits/1.6.0)

---
updated-dependencies:
- dependency-name: color-string
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-26 14:09:31 +00:00
Rahul Jain e92300198d Merge pull request #432 from rahuldkjain/dependabot/npm_and_yarn/tmpl-1.0.5
Bump tmpl from 1.0.4 to 1.0.5
2021-09-26 19:38:04 +05:30
Rahul Jain 25a970c5aa Merge pull request #429 from rahuldkjain/dependabot/npm_and_yarn/object-path-0.11.8
Bump object-path from 0.11.4 to 0.11.8
2021-09-26 19:37:54 +05:30
Rahul Jain 0038d17908 Merge pull request #428 from rahuldkjain/dependabot/npm_and_yarn/prismjs-1.25.0
Bump prismjs from 1.20.0 to 1.25.0
2021-09-26 19:37:44 +05:30
dependabot[bot] 742a7d5d53 Bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-22 08:50:59 +00:00
dependabot[bot] 45f8ca0c9b Bump object-path from 0.11.4 to 0.11.8
Bumps [object-path](https://github.com/mariocasciaro/object-path) from 0.11.4 to 0.11.8.
- [Release notes](https://github.com/mariocasciaro/object-path/releases)
- [Commits](https://github.com/mariocasciaro/object-path/commits)

---
updated-dependencies:
- dependency-name: object-path
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-21 18:10:32 +00:00
dependabot[bot] 131f4b00bf Bump prismjs from 1.20.0 to 1.25.0
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.20.0 to 1.25.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.20.0...v1.25.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-20 22:42:50 +00:00
gargipandkar f8b2c5d9d4 Fix save/restore/reset of support fields 2021-08-15 16:08:53 +08:00
Rahul Jain e0c08558d8 [fix]: mssql, matlab icon 2021-06-04 17:08:16 +05:30
Rahul Jain 70d473ca91 Merge pull request #387 from Shrestha7/master
[fix]: social icons url
2021-06-04 09:20:55 +05:30
Rahul Jain 3d2510ac71 Merge pull request #394 from AdrianArtiles/fix-typos
[fix]: readme typos
2021-06-04 09:11:26 +05:30
Adrian Artiles fe35dcea9a docs: fix typos 2021-06-03 15:18:04 -07:00
Savitha Gollamudi 22064237dc Merge pull request #370 from aravindvnair99/typo-fixes
Fixes #369 - incorrect spelling
2021-05-10 12:12:58 +05:30
Savitha Gollamudi 704df3681f Merge pull request #374 from frntnd93/feature/angular-icon-link
Add Angular 2+ icon, link
2021-05-10 12:08:14 +05:30
swastik shrestha d8139bc7e2 fixed social icons 2021-05-10 11:57:33 +05:45
Savitha Gollamudi 6253936f99 Merge pull request #384 from PuneetGopinath/patch-1
Fix social icons base link
2021-05-01 16:29:04 +05:30
Puneet Gopinath a5389b6646 Fix social icons base link 2021-04-26 09:55:03 +03:00
Rahul Jain 4a1846e7df Merge pull request #380 from rahuldkjain/rahul_hotfix_paypal-icon
[fix]: paypal-icon
2021-04-18 12:59:06 +05:30
Dzhanik Marupov 9e323b9157 Update src/constants/skills.js
Co-authored-by: Aravind V. Nair <22199259+aravindvnair99@users.noreply.github.com>
2021-03-31 12:51:52 +03:00
Aravind V Nair 29a0db0aad Remove unnecessary spaces
Signed-off-by: Aravind V Nair <22199259+aravindvnair99@users.noreply.github.com>
2021-03-31 12:35:55 +05:30
Aravind V Nair e53c7321b6 Merge branch 'master' of https://github.com/rahuldkjain/github-profile-readme-generator into typo-fixes 2021-03-28 14:55:56 +05:30
Dzhanik 49552b7c42 [add] Angular 2+ icon, link 2021-03-03 14:51:11 +03:00
Aravind V Nair fb1b92b0a2 Fix spelling of "regularly"
Signed-off-by: Aravind V Nair <22199259+aravindvnair99@users.noreply.github.com>
2021-03-01 15:59:35 +05:30
97 changed files with 7132 additions and 6115 deletions
+1
View File
@@ -0,0 +1 @@
node_modules/**
+18
View File
@@ -0,0 +1,18 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["plugin:react/recommended", "airbnb", "prettier"],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {
"react/forbid-prop-types": 0
}
}
+2 -3
View File
@@ -1,9 +1,9 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: "" title: ''
labels: bug labels: bug
assignees: "" assignees: ''
--- ---
**Describe the bug** **Describe the bug**
@@ -39,7 +39,6 @@ If applicable, add screenshots to help explain your problem.
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.
Join the **Discord Server** for further discussions. Join the **Discord Server** for further discussions.
<a href="https://discord.gg/HHMs7Eg"> <a href="https://discord.gg/HHMs7Eg">
@@ -1,9 +1,9 @@
--- ---
name: Feature/Enhancement request name: Feature/Enhancement request
about: Suggest an idea for this project about: Suggest an idea for this project
title: "" title: ''
labels: enhancement, hacktoberfest labels: enhancement, hacktoberfest
assignees: "" assignees: ''
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
-1
View File
@@ -40,4 +40,3 @@ as any relevant images for UI changes._
## Added to documentation? ## Added to documentation?
- [ ] readme - [ ] readme
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install lint-staged
+7 -2
View File
@@ -1,4 +1,9 @@
{ {
"arrowParens": "avoid", "singleQuote": true,
"semi": false "jsxSingleQuote": false,
"tabWidth": 2,
"printWidth": 480,
"trailingComma": "all",
"semi": true,
"exclude": ["node_modules", "codepipeline"]
} }
+1 -1
View File
@@ -1,6 +1,6 @@
language: node_js language: node_js
node_js: node_js:
- "stable" - "14"
cache: cache:
directories: directories:
- "node_modules" - "node_modules"
+13 -13
View File
@@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment Examples of behavior that contributes to creating a positive environment
include: include:
* Using welcoming and inclusive language - Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences - Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism - Gracefully accepting constructive criticism
* Focusing on what is best for the community - Focusing on what is best for the community
* Showing empathy towards other community members - Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or - The use of sexualized language or imagery and unwelcome sexual attention or
advances advances
* Trolling, insulting/derogatory comments, and personal or political attacks - Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or electronic - Publishing others' private information, such as a physical or electronic
address, without explicit permission address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Our Responsibilities ## Our Responsibilities
+57 -51
View File
@@ -3,28 +3,29 @@
## File Layout (`src/components/*.js`) ## File Layout (`src/components/*.js`)
1. Imports 1. Imports
2. Reusabe components needed for the main component 2. Reusable components needed for the main component
3. Main component (Eg: Addons in addons.js) 3. Main component (Eg: Addons in addons.js)
4. export default \<MainComponent\>; 4. export default \<MainComponent\>;
## Reusable components ## Reusable components
* Do not make a new file for smaller components. - Do not make a new file for smaller components.
* Smaller, reusable components neeeded in the main components should be added **above** the main component, **not** inside it. - Smaller, reusable components needed in the main components should be added **above** the main component, **not** inside it.
* Use ES6 arrow functions for defining components. - Use ES6 arrow functions for defining components.
## Spacing ## Spacing
1. **JS:** 1. **JS:**
* Use a space after `if`, `for`, `while`, `switch`. - Use a space after `if`, `for`, `while`, `switch`.
* Do not use a space after the opening `(` and before the closing `)`. - Do not use a space after the opening `(` and before the closing `)`.
* Use a space before and after destructuring objects. - Use a space before and after destructuring objects.
```js ```js
//good //good
const { apple, mangoes } = fruits; const { apple, mangoes } = fruits;
//bad //bad
const {apple, mangoes} = fruits; const { apple, mangoes } = fruits;
```
//Same for destructuring props: //Same for destructuring props:
@@ -36,56 +37,61 @@
``` ```
2. **JSX:** 2. **JSX:**
* Use a space before the forward slash (`/`) of a self-closing tag
```js
//good
<Foo />
//bad - Use a space before the forward slash (`/`) of a self-closing tag
<Foo/>
```
* Do **not** use spaces for JSX curly braces
```js
//good
<Foo bar={baz} />
//bad ```js
<Foo bar={ baz } /> //good
``` <Foo />
//bad
<Foo/>
```
- Do **not** use spaces for JSX curly braces
```js
//good
<Foo bar={baz} />
//bad
<Foo bar={ baz } />
```
## **Props:** ## **Props:**
* Use camelCase for prop names, or PascalCase if the prop value is a React component. - Use camelCase for prop names, or PascalCase if the prop value is a React component.
* Use new lines when props do not fit on the same line. - Use new lines when props do not fit on the same line.
```js
//good
<Foo
prop1={value1}
prop2={value2}
prop3={value3}
/>
//bad ```js
<Foo prop1={value1} prop2={value2} prop3={value3} /> //good
``` <Foo
prop1={value1}
prop2={value2}
prop3={value3}
/>
//bad
<Foo prop1={value1} prop2={value2} prop3={value3} />
```
## **Best practices:** ## **Best practices:**
* **Always** add semicolons after a line. - **Always** add semicolons after a line.
* Use ES6 arrow functions. - Use ES6 arrow functions.
* Keep the indentation in your code correct. - Keep the indentation in your code correct.
* Use 4 spaces for tabs. - Use 4 spaces for tabs.
* Don't Repeat Yourself. If you think you're repeating too much code, make a smaller component, or a function. - Don't Repeat Yourself. If you think you're repeating too much code, make a smaller component, or a function.
* **Always** add alt prop to `img` tags. - **Always** add alt prop to `img` tags.
* Add `rel="noopener"` for `a` tags which has `target="_blank"`. - Add `rel="noopener"` for `a` tags which has `target="_blank"`.
* Don't do `outline: none` on user input elements. If you do not want outline, give them faint, visible background on focus. This is for accessibility. - Don't do `outline: none` on user input elements. If you do not want outline, give them faint, visible background on focus. This is for accessibility.
### Other things to note ### Other things to note
* We are using [octicons](https://primer.style/octicons/) for icons. Use this if you need to add icons. Do **not** add a new library for icons. - We are using [octicons](https://primer.style/octicons/) for icons. Use this if you need to add icons. Do **not** add a new library for icons.
* Try to not commit changes in `package.json`, `package-lock.json`. - Try to not commit changes in `package.json`, `package-lock.json`.
* Disscuss with contributors on discord if you're planning to add/remove a package. - Discuss with contributors on discord if you're planning to add/remove a package.
## Further reading: ## Further reading:
This guide is based on [airbnb's react guide](https://github.com/airbnb/javascript/tree/master/react). You can read all the best practices there. This guide is based on [airbnb's react guide](https://github.com/airbnb/javascript/tree/master/react). You can read all the best practices there.
+3 -5
View File
@@ -9,7 +9,7 @@
<p align="center"> <p align="center">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/blob/master/LICENSE" target="blank"> <a href="https://github.com/rahuldkjain/github-profile-readme-generator/blob/master/LICENSE" target="blank">
<img src="https://img.shields.io/github/license/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator licence" /> <img src="https://img.shields.io/github/license/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator license" />
</a> </a>
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/fork" target="blank"> <a href="https://github.com/rahuldkjain/github-profile-readme-generator/fork" target="blank">
<img src="https://img.shields.io/github/forks/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator forks"/> <img src="https://img.shields.io/github/forks/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator forks"/>
@@ -54,8 +54,8 @@
This tool provides an easy way to create a GitHub profile readme with the latest add-ons such as `visitors count`, `github stats`, etc. This tool provides an easy way to create a GitHub profile readme with the latest add-ons such as `visitors count`, `github stats`, etc.
## 🚀 Demo
## 🚀 Demo
<a href="https://rahuldkjain.github.io/gh-profile-readme-generator" target="blank"> <a href="https://rahuldkjain.github.io/gh-profile-readme-generator" target="blank">
<img src="https://img.shields.io/website?url=https%3A%2F%2Frahuldkjain.github.io%2Fgh-profile-readme-generator&logo=github&style=flat-square" /> <img src="https://img.shields.io/website?url=https%3A%2F%2Frahuldkjain.github.io%2Fgh-profile-readme-generator&logo=github&style=flat-square" />
</a> </a>
@@ -126,11 +126,11 @@ Please contribute using [GitHub Flow](https://guides.github.com/introduction/flo
Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md), and the process for submitting pull requests to us. Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.
## 💻 Built with ## 💻 Built with
- [Gatsby](https://www.gatsbyjs.com/) - [Gatsby](https://www.gatsbyjs.com/)
- [Tailwind CSS](https://tailwindcss.com/): for styling - [Tailwind CSS](https://tailwindcss.com/): for styling
- [GSAP](https://greensock.com/gsap/): for small SVG Animations - [GSAP](https://greensock.com/gsap/): for small SVG Animations
## 🙇 Special Thanks ## 🙇 Special Thanks
- [Anurag Hazra](https://github.com/anuraghazra) for amazing [github-readme-stats](https://github.com/anuraghazra/github-readme-stats) - [Anurag Hazra](https://github.com/anuraghazra) for amazing [github-readme-stats](https://github.com/anuraghazra/github-readme-stats)
@@ -146,7 +146,6 @@ Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDU
- [Aadit Kamat](https://github.com/aaditkamat) find the tool useful and showed support with his donation. A big thanks to him. - [Aadit Kamat](https://github.com/aaditkamat) find the tool useful and showed support with his donation. A big thanks to him.
- [Jean-Michel Fayard](https://github.com/jmfayard) used the generator to create his GitHub Profile README and he loved it. Thanks to him for showing support to the tool with the donation. - [Jean-Michel Fayard](https://github.com/jmfayard) used the generator to create his GitHub Profile README and he loved it. Thanks to him for showing support to the tool with the donation.
## 🙏 Support ## 🙏 Support
<p align="left"> <p align="left">
@@ -163,7 +162,6 @@ Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDU
<a href="https://www.buymeacoffee.com/rahuldkjain" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="23" width="100" style="border-radius:2px" /> <a href="https://www.buymeacoffee.com/rahuldkjain" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="23" width="100" style="border-radius:2px" />
</p> </p>
<hr> <hr>
<p align="center"> <p align="center">
Developed with ❤️ in India 🇮🇳 Developed with ❤️ in India 🇮🇳
+1 -1
View File
@@ -1 +1 @@
module.exports = "test-file-stub" module.exports = 'test-file-stub';
+5 -15
View File
@@ -1,27 +1,17 @@
const React = require("react") const React = require('react');
const gatsby = jest.requireActual("gatsby") const gatsby = jest.requireActual('gatsby');
module.exports = { module.exports = {
...gatsby, ...gatsby,
graphql: jest.fn(), graphql: jest.fn(),
Link: jest.fn().mockImplementation( Link: jest.fn().mockImplementation(
// these props are invalid for an `a` tag // these props are invalid for an `a` tag
({ ({ activeClassName, activeStyle, getProps, innerRef, partiallyActive, ref, replace, to, ...rest }) =>
activeClassName, React.createElement('a', {
activeStyle,
getProps,
innerRef,
partiallyActive,
ref,
replace,
to,
...rest
}) =>
React.createElement("a", {
...rest, ...rest,
href: to, href: to,
}) })
), ),
StaticQuery: jest.fn(), StaticQuery: jest.fn(),
useStaticQuery: jest.fn(), useStaticQuery: jest.fn(),
} };
+2 -2
View File
@@ -1,2 +1,2 @@
import "./src/styles/tailwind.css" import './src/styles/tailwind.css';
require("prismjs/themes/prism-okaidia.css") require('prismjs/themes/prism-okaidia.css');
+3 -3
View File
@@ -44,7 +44,7 @@ module.exports = {
{ {
resolve: `gatsby-plugin-google-analytics`, resolve: `gatsby-plugin-google-analytics`,
options: { options: {
trackingId: "UA-168596085-3", trackingId: 'UA-168596085-3',
// this option places the tracking script into the head of the DOM // this option places the tracking script into the head of the DOM
head: true, head: true,
// other options // other options
@@ -53,7 +53,7 @@ module.exports = {
{ {
resolve: `gatsby-plugin-postcss`, resolve: `gatsby-plugin-postcss`,
options: { options: {
postCssPlugins: [require("tailwindcss")], postCssPlugins: [require('tailwindcss')],
}, },
}, },
{ {
@@ -69,4 +69,4 @@ module.exports = {
// this (optional) plugin enables Progressive Web App + Offline functionality // this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline // To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`, // `gatsby-plugin-offline`,
} };
+9 -12
View File
@@ -1,14 +1,11 @@
exports.createPages = async ({ actions, graphql, reporter }) => { exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions const { createPage } = actions;
const blogPostTemplate = require.resolve(`./src/templates/blogTemplate.js`) const blogPostTemplate = require.resolve(`./src/templates/blogTemplate.js`);
const result = await graphql(` const result = await graphql(`
{ {
allMarkdownRemark( allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }, limit: 1000) {
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges { edges {
node { node {
frontmatter { frontmatter {
@@ -18,12 +15,12 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
} }
} }
} }
`) `);
// Handle errors // Handle errors
if (result.errors) { if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`) reporter.panicOnBuild(`Error while running GraphQL query.`);
return return;
} }
result.data.allMarkdownRemark.edges.forEach(({ node }) => { result.data.allMarkdownRemark.edges.forEach(({ node }) => {
@@ -34,6 +31,6 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
// additional data can be passed via context // additional data can be passed via context
slug: node.frontmatter.slug, slug: node.frontmatter.slug,
}, },
}) });
}) });
} };
+3 -3
View File
@@ -1,5 +1,5 @@
const babelOptions = { const babelOptions = {
presets: ["babel-preset-gatsby"], presets: ['babel-preset-gatsby'],
} };
module.exports = require("babel-jest").createTransformer(babelOptions) module.exports = require('babel-jest').createTransformer(babelOptions);
+7 -7
View File
@@ -1,20 +1,20 @@
module.exports = { module.exports = {
transform: { transform: {
"^.+\\.jsx?$": `<rootDir>/jest-preprocess.js`, '^.+\\.jsx?$': `<rootDir>/jest-preprocess.js`,
}, },
moduleNameMapper: { moduleNameMapper: {
".+\\.(css|styl|less|sass|scss)$": `identity-obj-proxy`, '.+\\.(css|styl|less|sass|scss)$': `identity-obj-proxy`,
".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": `<rootDir>/__mocks__/file-mock.js`, '.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': `<rootDir>/__mocks__/file-mock.js`,
}, },
testPathIgnorePatterns: [`node_modules`, `\\.cache`, `<rootDir>.*/public`], testPathIgnorePatterns: [`node_modules`, `\\.cache`, `<rootDir>.*/public`],
transformIgnorePatterns: [`node_modules/(?!(gatsby)/)`], transformIgnorePatterns: [`node_modules/(?!(gatsby)/)`],
globals: { globals: {
__PATH_PREFIX__: ``, __PATH_PREFIX__: ``,
__BASE_PATH__: ``, __BASE_PATH__: ``,
}, },
setupFiles: [`<rootDir>/loadershim.js`], setupFiles: [`<rootDir>/loadershim.js`],
setupFilesAfterEnv: ["<rootDir>/setupTests.js"], setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
snapshotSerializers: ["enzyme-to-json/serializer"], snapshotSerializers: ['enzyme-to-json/serializer'],
coverageThreshold: { coverageThreshold: {
global: { global: {
branches: 0, branches: 0,
@@ -23,4 +23,4 @@ module.exports = {
statements: 68, statements: 68,
}, },
}, },
} };
+1 -1
View File
@@ -1,3 +1,3 @@
global.___loader = { global.___loader = {
enqueue: jest.fn(), enqueue: jest.fn(),
} };
+1799 -416
View File
File diff suppressed because it is too large Load Diff
+28 -2
View File
@@ -4,12 +4,28 @@
"description": "A simple react app to generate beautiful github profile readme in md(markdown)", "description": "A simple react app to generate beautiful github profile readme in md(markdown)",
"version": "1.2.0", "version": "1.2.0",
"author": "Rahul Jain <rahuldkjain@gmail.com>", "author": "Rahul Jain <rahuldkjain@gmail.com>",
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,jsx}": [
"prettier --write",
"eslint --fix",
"git add"
],
"*.{html,css,less,ejs}": [
"prettier --write",
"git add"
]
},
"dependencies": { "dependencies": {
"@primer/octicons-react": "^10.0.0", "@primer/octicons-react": "^10.0.0",
"axios": "^0.24.0",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5", "enzyme-adapter-react-16": "^1.15.5",
"enzyme-to-json": "^3.6.1", "enzyme-to-json": "^3.6.1",
"eslint": "^7.17.0",
"gatsby": "^2.23.12", "gatsby": "^2.23.12",
"gatsby-image": "^2.4.9", "gatsby-image": "^2.4.9",
"gatsby-plugin-google-analytics": "^2.3.11", "gatsby-plugin-google-analytics": "^2.3.11",
@@ -22,7 +38,7 @@
"gatsby-transformer-remark": "^2.8.27", "gatsby-transformer-remark": "^2.8.27",
"gatsby-transformer-sharp": "^2.5.7", "gatsby-transformer-sharp": "^2.5.7",
"gsap": "^3.4.0", "gsap": "^3.4.0",
"prismjs": "^1.20.0", "prismjs": "^1.25.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^16.12.0", "react": "^16.12.0",
"react-dom": "^16.12.0", "react-dom": "^16.12.0",
@@ -31,13 +47,23 @@
"devDependencies": { "devDependencies": {
"babel-jest": "26.3.0", "babel-jest": "26.3.0",
"babel-preset-gatsby": "0.5.11", "babel-preset-gatsby": "0.5.11",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"gatsby-plugin-postcss": "^2.3.11", "gatsby-plugin-postcss": "^2.3.11",
"gatsby-plugin-purgecss": "^5.0.0", "gatsby-plugin-purgecss": "^5.0.0",
"gatsby-plugin-twitter": "^2.3.10", "gatsby-plugin-twitter": "^2.3.10",
"gatsby-remark-embedder": "^3.0.0", "gatsby-remark-embedder": "^3.0.0",
"gh-pages": "^3.1.0", "gh-pages": "^3.1.0",
"husky": "^7.0.4",
"identity-obj-proxy": "3.0.0", "identity-obj-proxy": "3.0.0",
"jest": "26.4.2", "jest": "26.4.2",
"lint-staged": "^11.2.6",
"prettier": "2.0.5", "prettier": "2.0.5",
"tailwindcss": "^1.7.6" "tailwindcss": "^1.7.6"
}, },
+3 -3
View File
@@ -1,4 +1,4 @@
import { configure } from "enzyme" import { configure } from 'enzyme';
import Adapter from "enzyme-adapter-react-16" import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() }) configure({ adapter: new Adapter() });
@@ -99,6 +99,24 @@ exports[`Addons renders correctly 1`] = `
> >
display top skills display top skills
</AddonsItem> </AddonsItem>
<AddonsItem
Options={
<CustomizeOptions
CustomizationOptions={
<CustomizeStreakStats
onUpdate={[Function]}
options={Object {}}
prefix="streak-stats"
/>
}
title="Customize Streak Stats Card"
/>
}
inputId="streak-stats"
onInputChange={[Function]}
>
display github streak stats
</AddonsItem>
<AddonsItem <AddonsItem
inputChecked={false} inputChecked={false}
inputId="twitter-badge" inputId="twitter-badge"
@@ -339,15 +357,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="visitors-count" htmlFor="visitors-count"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="visitors-count" id="visitors-count"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -510,15 +532,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-profile-trophy" htmlFor="github-profile-trophy"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-profile-trophy" id="github-profile-trophy"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -558,15 +584,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-stats" htmlFor="github-stats"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-stats" id="github-stats"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -644,15 +674,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="top-languages" htmlFor="top-languages"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="top-languages" id="top-languages"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -699,6 +733,84 @@ exports[`Addons should render Customize Badges 1`] = `
</button> </button>
</div> </div>
</AddonsItem> </AddonsItem>
<AddonsItem
Options={
<CustomizeOptions
CustomizationOptions={
<CustomizeStreakStats
onUpdate={[Function]}
options={Object {}}
prefix="streak-stats"
/>
}
title="Customize Streak Stats Card"
/>
}
inputId="streak-stats"
onInputChange={[Function]}
>
<div
className="py-2 flex justify-start items-center text-sm sm:text-lg"
>
<label
className="checkbox-label flex items-center"
htmlFor="streak-stats"
>
<input
className="checkbox-label__input"
id="streak-stats"
onChange={[Function]}
type="checkbox"
/>
<span
class="checkbox-label__control"
/>
<span
className="pl-4"
>
display github streak stats
</span>
</label>
<button
className="flex ml-3 focus:bg-gray-400"
id="streak-stats-open-btn"
onClick={[Function]}
style={
Object {
"outline": "none",
}
}
>
<ToolsIcon
className="transform scale-100 md:scale-125"
size={16}
verticalAlign="text-bottom"
>
<svg
aria-hidden="true"
className="transform scale-100 md:scale-125"
dangerouslySetInnerHTML={
Object {
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
}
}
fill="currentColor"
height={16}
role="img"
style={
Object {
"display": "inline-block",
"userSelect": "none",
"verticalAlign": "text-bottom",
}
}
viewBox="0 0 16 16"
width={16}
/>
</ToolsIcon>
</button>
</div>
</AddonsItem>
<AddonsItem <AddonsItem
inputChecked={false} inputChecked={false}
inputId="twitter-badge" inputId="twitter-badge"
@@ -708,15 +820,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="twitter-badge" htmlFor="twitter-badge"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="twitter-badge" id="twitter-badge"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -734,15 +850,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="dev-dynamic-blogs" htmlFor="dev-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="dev-dynamic-blogs" id="dev-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -760,15 +880,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="medium-dynamic-blogs" htmlFor="medium-dynamic-blogs"
> >
<input <input
checked="some-medium-blogs-value" checked="some-medium-blogs-value"
className="checkbox-label__input"
id="medium-dynamic-blogs" id="medium-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -786,15 +910,19 @@ exports[`Addons should render Customize Badges 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="rss-dynamic-blogs" htmlFor="rss-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="rss-dynamic-blogs" id="rss-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -931,15 +1059,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="visitors-count" htmlFor="visitors-count"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="visitors-count" id="visitors-count"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -995,15 +1127,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-profile-trophy" htmlFor="github-profile-trophy"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-profile-trophy" id="github-profile-trophy"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1043,15 +1179,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-stats" htmlFor="github-stats"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-stats" id="github-stats"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1254,15 +1394,20 @@ exports[`Addons should render Customize Github stats card 1`] = `
/> />
</label> </label>
<label <label
className="checkbox-label"
htmlFor="stats-hide-border" htmlFor="stats-hide-border"
> >
Hide border:  Hide border: 
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="stats-hide-border" id="stats-hide-border"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
</label> </label>
<label <label
htmlFor="stats-cache-seconds" htmlFor="stats-cache-seconds"
@@ -1327,15 +1472,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="top-languages" htmlFor="top-languages"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="top-languages" id="top-languages"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1382,6 +1531,84 @@ exports[`Addons should render Customize Github stats card 1`] = `
</button> </button>
</div> </div>
</AddonsItem> </AddonsItem>
<AddonsItem
Options={
<CustomizeOptions
CustomizationOptions={
<CustomizeStreakStats
onUpdate={[Function]}
options={Object {}}
prefix="streak-stats"
/>
}
title="Customize Streak Stats Card"
/>
}
inputId="streak-stats"
onInputChange={[Function]}
>
<div
className="py-2 flex justify-start items-center text-sm sm:text-lg"
>
<label
className="checkbox-label flex items-center"
htmlFor="streak-stats"
>
<input
className="checkbox-label__input"
id="streak-stats"
onChange={[Function]}
type="checkbox"
/>
<span
class="checkbox-label__control"
/>
<span
className="pl-4"
>
display github streak stats
</span>
</label>
<button
className="flex ml-3 focus:bg-gray-400"
id="streak-stats-open-btn"
onClick={[Function]}
style={
Object {
"outline": "none",
}
}
>
<ToolsIcon
className="transform scale-100 md:scale-125"
size={16}
verticalAlign="text-bottom"
>
<svg
aria-hidden="true"
className="transform scale-100 md:scale-125"
dangerouslySetInnerHTML={
Object {
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
}
}
fill="currentColor"
height={16}
role="img"
style={
Object {
"display": "inline-block",
"userSelect": "none",
"verticalAlign": "text-bottom",
}
}
viewBox="0 0 16 16"
width={16}
/>
</ToolsIcon>
</button>
</div>
</AddonsItem>
<AddonsItem <AddonsItem
inputChecked={false} inputChecked={false}
inputId="twitter-badge" inputId="twitter-badge"
@@ -1391,15 +1618,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="twitter-badge" htmlFor="twitter-badge"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="twitter-badge" id="twitter-badge"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1417,15 +1648,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="dev-dynamic-blogs" htmlFor="dev-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="dev-dynamic-blogs" id="dev-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1443,15 +1678,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="medium-dynamic-blogs" htmlFor="medium-dynamic-blogs"
> >
<input <input
checked="some-medium-blogs-value" checked="some-medium-blogs-value"
className="checkbox-label__input"
id="medium-dynamic-blogs" id="medium-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1469,15 +1708,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="rss-dynamic-blogs" htmlFor="rss-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="rss-dynamic-blogs" id="rss-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1614,15 +1857,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="visitors-count" htmlFor="visitors-count"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="visitors-count" id="visitors-count"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1678,15 +1925,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-profile-trophy" htmlFor="github-profile-trophy"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-profile-trophy" id="github-profile-trophy"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1726,15 +1977,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="github-stats" htmlFor="github-stats"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="github-stats" id="github-stats"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -1812,15 +2067,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="top-languages" htmlFor="top-languages"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="top-languages" id="top-languages"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -2023,15 +2282,20 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
/> />
</label> </label>
<label <label
className="checkbox-label"
htmlFor="top-lang-hide-border" htmlFor="top-lang-hide-border"
> >
Hide border:  Hide border: 
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="top-lang-hide-border" id="top-lang-hide-border"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
</label> </label>
<label <label
htmlFor="top-lang-cache-seconds" htmlFor="top-lang-cache-seconds"
@@ -2065,6 +2329,84 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
</div> </div>
</CustomizeOptions> </CustomizeOptions>
</AddonsItem> </AddonsItem>
<AddonsItem
Options={
<CustomizeOptions
CustomizationOptions={
<CustomizeStreakStats
onUpdate={[Function]}
options={Object {}}
prefix="streak-stats"
/>
}
title="Customize Streak Stats Card"
/>
}
inputId="streak-stats"
onInputChange={[Function]}
>
<div
className="py-2 flex justify-start items-center text-sm sm:text-lg"
>
<label
className="checkbox-label flex items-center"
htmlFor="streak-stats"
>
<input
className="checkbox-label__input"
id="streak-stats"
onChange={[Function]}
type="checkbox"
/>
<span
class="checkbox-label__control"
/>
<span
className="pl-4"
>
display github streak stats
</span>
</label>
<button
className="flex ml-3 focus:bg-gray-400"
id="streak-stats-open-btn"
onClick={[Function]}
style={
Object {
"outline": "none",
}
}
>
<ToolsIcon
className="transform scale-100 md:scale-125"
size={16}
verticalAlign="text-bottom"
>
<svg
aria-hidden="true"
className="transform scale-100 md:scale-125"
dangerouslySetInnerHTML={
Object {
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
}
}
fill="currentColor"
height={16}
role="img"
style={
Object {
"display": "inline-block",
"userSelect": "none",
"verticalAlign": "text-bottom",
}
}
viewBox="0 0 16 16"
width={16}
/>
</ToolsIcon>
</button>
</div>
</AddonsItem>
<AddonsItem <AddonsItem
inputChecked={false} inputChecked={false}
inputId="twitter-badge" inputId="twitter-badge"
@@ -2074,15 +2416,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="twitter-badge" htmlFor="twitter-badge"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="twitter-badge" id="twitter-badge"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -2100,15 +2446,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="dev-dynamic-blogs" htmlFor="dev-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="dev-dynamic-blogs" id="dev-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -2126,15 +2476,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="medium-dynamic-blogs" htmlFor="medium-dynamic-blogs"
> >
<input <input
checked="some-medium-blogs-value" checked="some-medium-blogs-value"
className="checkbox-label__input"
id="medium-dynamic-blogs" id="medium-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -2152,15 +2506,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
className="py-2 flex justify-start items-center text-sm sm:text-lg" className="py-2 flex justify-start items-center text-sm sm:text-lg"
> >
<label <label
className="cursor-pointer flex items-center" className="checkbox-label flex items-center"
htmlFor="rss-dynamic-blogs" htmlFor="rss-dynamic-blogs"
> >
<input <input
checked={false} checked={false}
className="checkbox-label__input"
id="rss-dynamic-blogs" id="rss-dynamic-blogs"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<span <span
className="pl-4" className="pl-4"
> >
@@ -71,17 +71,16 @@ exports[`Donate renders correctly 1`] = `
Buy me a ko-fi Buy me a ko-fi
</a> </a>
<a <a
className="flex items-center justify-evenly bg-blue-500 text-white py-2 px-4 my-2" className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid"
href="https://www.paypal.me/rahuldkjain/10" href="https://www.paypal.me/rahuldkjain/10"
rel="noreferrer" rel="noreferrer"
target="_blank" target="_blank"
> >
<img <img
alt="Donate rahuldkjain via paypal" alt="Donate rahuldkjain via paypal"
className="w-6 h-6 mr-2" className="w-32 h-4"
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg" src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg"
/> />
Paypal
</a> </a>
<a <a
className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2" className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2"
@@ -157,7 +157,7 @@ exports[`Footer component renders correctly 1`] = `
</strong> </strong>
</div> </div>
<div <div
class="ml-2 sm:ml-0" className="ml-2 sm:ml-0"
> >
<a <a
aria-label="Discord of the community" aria-label="Discord of the community"
File diff suppressed because it is too large Load Diff
@@ -182,7 +182,7 @@ exports[`Markdown Preview renders correctly 1`] = `
}, },
"prefix": Object { "prefix": Object {
"ama": "💬 Ask me about", "ama": "💬 Ask me about",
"blog": "📝 I regulary write articles on", "blog": "📝 I regularly write articles on",
"collaborateOn": "👯 Im looking to collaborate on", "collaborateOn": "👯 Im looking to collaborate on",
"contact": "📫 How to reach me", "contact": "📫 How to reach me",
"currentLearn": "🌱 Im currently learning", "currentLearn": "🌱 Im currently learning",
@@ -254,6 +254,7 @@ exports[`Markdown Preview renders correctly 1`] = `
<SkillsPreview <SkillsPreview
skills={Object {}} skills={Object {}}
/> />
<SupportPreview />
<div <div
className="block sm:flex sm:justify-center sm:items-start" className="block sm:flex sm:justify-center sm:items-start"
> >
@@ -287,6 +288,9 @@ exports[`Markdown Preview renders correctly 1`] = `
} }
show={false} show={false}
/> />
<StreakStatsPreview
github=""
/>
</div> </div>
</div> </div>
`; `;
@@ -313,13 +317,13 @@ exports[`Skills Preview renders correctly 1`] = `
/> />
<a <a
href="https://unity.com/" href="https://unity.com/"
key="unity"
rel="noreferrer" rel="noreferrer"
target="_blank" target="_blank"
> >
<img <img
alt="unity" alt="unity"
className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10" className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10"
key="unity"
src="https://www.vectorlogo.zone/logos/unity3d/unity3d-icon.svg" src="https://www.vectorlogo.zone/logos/unity3d/unity3d-icon.svg"
/> />
</a> </a>
@@ -338,112 +342,112 @@ exports[`Social Preview renders correctly 1`] = `
/> />
<DisplaySocial <DisplaySocial
base="https://codepen.io" base="https://codepen.io"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codepen.svg"
username="dummy" username="dummy"
/> />
<DisplaySocial <DisplaySocial
base="https://dev.to" base="https://dev.to"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/devto.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://twitter.com" base="https://twitter.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/twitter.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/twitter.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://linkedin.com/in" base="https://linkedin.com/in"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/linked-in-alt.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://stackoverflow.com/users" base="https://stackoverflow.com/users"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/stack-overflow.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://codesandbox.com" base="https://codesandbox.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codesandbox.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://kaggle.com" base="https://kaggle.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/kaggle.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://fb.com" base="https://fb.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/facebook.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://instagram.com" base="https://instagram.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/instagram.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://dribbble.com" base="https://dribbble.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dribbble.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/dribbble.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://www.behance.net" base="https://www.behance.net"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/behance.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/behance.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://medium.com" base="https://medium.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/medium.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/medium.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://www.youtube.com/c" base="https://www.youtube.com/c"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/youtube.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/youtube.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://www.codechef.com/users" base="https://www.codechef.com/users"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codechef.svg" icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
username=""
/>
<DisplaySocial
base="https://codeforces.com/profile"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://www.hackerrank.com" base="https://www.hackerrank.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/hackerrank.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerrank.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://auth.geeksforgeeks.org/user" base="https://codeforces.com/profile"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/geeksforgeeks.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codeforces.svg"
username=""
/>
<DisplaySocial
base="https://www.hackerearth.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/hackerearth.svg"
username=""
/>
<DisplaySocial
base="https://www.topcoder.com/members"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://www.leetcode.com" base="https://www.leetcode.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/leetcode.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/leet-code.svg"
username=""
/>
<DisplaySocial
base="https://www.hackerearth.com"
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerearth.svg"
username=""
/>
<DisplaySocial
base="https://auth.geeksforgeeks.org/user"
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/geeks-for-geeks.svg"
username=""
/>
<DisplaySocial
base="https://www.topcoder.com/members"
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/topcoder.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="https://discord.gg" base="https://discord.gg"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/discord.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/discord.svg"
username="" username=""
/> />
<DisplaySocial <DisplaySocial
base="" base=""
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/rss.svg" icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/rss.svg"
username="" username=""
/> />
</div> </div>
@@ -560,7 +564,7 @@ exports[`Work Preview renders correctly 1`] = `
/> />
<DisplayWork <DisplayWork
link="" link=""
prefix="📝 I regulary write articles on" prefix="📝 I regularly write articles on"
/> />
<DisplayWork <DisplayWork
link="" link=""
@@ -50,15 +50,19 @@ exports[`Skills renders correctly 1`] = `
key="javascript" key="javascript"
> >
<label <label
className="skillCheckboxLabel cursor-pointer flex items-center justify-start" className="checkbox-label flex items-center justify-start"
htmlFor="javascript" htmlFor="javascript"
> >
<input <input
checked={true} checked={true}
className="checkbox-label__input"
id="javascript" id="javascript"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<img <img
alt="javascript" alt="javascript"
className="ml-4 w-8 h-8 sm:w-10 sm:h-10" className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
@@ -90,14 +94,18 @@ exports[`Skills renders correctly 1`] = `
key="react" key="react"
> >
<label <label
className="skillCheckboxLabel cursor-pointer flex items-center justify-start" className="checkbox-label flex items-center justify-start"
htmlFor="react" htmlFor="react"
> >
<input <input
className="checkbox-label__input"
id="react" id="react"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<img <img
alt="react" alt="react"
className="ml-4 w-8 h-8 sm:w-10 sm:h-10" className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
@@ -115,14 +123,18 @@ exports[`Skills renders correctly 1`] = `
key="svelte" key="svelte"
> >
<label <label
className="skillCheckboxLabel cursor-pointer flex items-center justify-start" className="checkbox-label flex items-center justify-start"
htmlFor="svelte" htmlFor="svelte"
> >
<input <input
className="checkbox-label__input"
id="svelte" id="svelte"
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
/> />
<span
class="checkbox-label__control"
/>
<img <img
alt="svelte" alt="svelte"
className="ml-4 w-8 h-8 sm:w-10 sm:h-10" className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -1,12 +1,12 @@
import React from "react" import React from 'react';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import Donate from "../donate" import Donate from '../donate';
describe("Donate", () => { describe('Donate', () => {
it("renders correctly", () => { it('renders correctly', () => {
const component = shallow(<Donate />) const component = shallow(<Donate />);
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+10 -10
View File
@@ -1,13 +1,13 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Footer from "../footer" import Footer from '../footer';
describe("Footer component", () => { describe('Footer component', () => {
const component = shallow(<Footer />) const component = shallow(<Footer />);
it("renders correctly", () => { it('renders correctly', () => {
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+10 -10
View File
@@ -1,13 +1,13 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Header from "../header" import Header from '../header';
describe("Header", () => { describe('Header', () => {
const component = shallow(<Header heading="heading" />) const component = shallow(<Header heading="heading" />);
it("renders correctly", () => { it('renders correctly', () => {
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+10 -10
View File
@@ -1,13 +1,13 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Loader from "../loader" import Loader from '../loader';
describe("Loader", () => { describe('Loader', () => {
const component = shallow(<Loader />) const component = shallow(<Loader />);
it("renders correctly", () => { it('renders correctly', () => {
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+122 -123
View File
@@ -1,10 +1,10 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Markdown from "../markdown" import Markdown from '../markdown';
describe("Markdown", () => { describe('Markdown', () => {
const props = { const props = {
data: { data: {
ama: '', ama: '',
@@ -56,7 +56,7 @@ describe("Markdown", () => {
}, },
prefix: { prefix: {
ama: '💬 Ask me about', ama: '💬 Ask me about',
blog: '📝 I regulary write articles on', blog: '📝 I regularly write articles on',
collaborateOn: '👯 Im looking to collaborate on', collaborateOn: '👯 Im looking to collaborate on',
contact: '📫 How to reach me', contact: '📫 How to reach me',
currentLearn: '🌱 Im currently learning', currentLearn: '🌱 Im currently learning',
@@ -77,139 +77,138 @@ describe("Markdown", () => {
}, },
}; };
it('renders without subtitle', () => {
it("renders without subtitle", () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
subtitle: '', subtitle: '',
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders without prefix.title and data.title", () => { it('renders without prefix.title and data.title', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
title: '', title: '',
}} }}
prefix={{ prefix={{
...props.prefix, ...props.prefix,
title: '', title: '',
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders topLanguages is true", () => { it('renders topLanguages is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
topLanguages: true, topLanguages: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders topLanguages is true and githubStats is true", () => { it('renders topLanguages is true and githubStats is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
topLanguages: true, topLanguages: true,
githubStats: true, githubStats: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders devDynamicBlogs is true", () => { it('renders devDynamicBlogs is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
devDynamicBlogs: true, devDynamicBlogs: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders without link.currentWork", () => { it('renders without link.currentWork', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
link={{ link={{
...props.data, ...props.data,
currentWork: '', currentWork: '',
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders visitorsBadge is true", () => { it('renders visitorsBadge is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
visitorsBadge: true, visitorsBadge: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders twitterBadge is true", () => { it('renders twitterBadge is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
twitterBadge: true, twitterBadge: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders githubProfileTrophy is true", () => { it('renders githubProfileTrophy is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
githubProfileTrophy: true, githubProfileTrophy: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("renders githubProfileTrophy is true", () => { it('renders githubProfileTrophy is true', () => {
const component = shallow( const component = shallow(
<Markdown <Markdown
{...props} {...props}
data={{ data={{
...props.data, ...props.data,
githubProfileTrophy: true, githubProfileTrophy: true,
}} }}
/> />
) );
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+389 -400
View File
@@ -1,415 +1,404 @@
import React from "react"; import React from 'react';
import { shallow, configure } from 'enzyme'; import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16'; import Adapter from 'enzyme-adapter-react-16';
import MarkdownPreview, { GithubProfileTrophyPreview, GitHubStatsPreview, SkillsPreview, SocialPreview, SubTitlePreview, TitlePreview, TopLanguagesPreview, TwitterBadgePreview, VisitorsBadgePreview, WorkPreview, SectionTitle, DisplayWork, DisplaySocial } from "../markdownPreview" import MarkdownPreview, {
GithubProfileTrophyPreview,
GitHubStatsPreview,
SkillsPreview,
SocialPreview,
SubTitlePreview,
TitlePreview,
TopLanguagesPreview,
TwitterBadgePreview,
VisitorsBadgePreview,
WorkPreview,
SectionTitle,
DisplayWork,
DisplaySocial,
} from '../markdownPreview';
configure({ adapter: new Adapter() }); configure({ adapter: new Adapter() });
const DEFAULT_PREFIX = { const DEFAULT_PREFIX = {
title: "Hi 👋, I'm", title: "Hi 👋, I'm",
currentWork: "🔭 Im currently working on", currentWork: '🔭 Im currently working on',
currentLearn: "🌱 Im currently learning", currentLearn: '🌱 Im currently learning',
collaborateOn: "👯 Im looking to collaborate on", collaborateOn: '👯 Im looking to collaborate on',
helpWith: "🤝 Im looking for help with", helpWith: '🤝 Im looking for help with',
ama: "💬 Ask me about", ama: '💬 Ask me about',
contact: "📫 How to reach me", contact: '📫 How to reach me',
resume: "📄 Know about my experiences", resume: '📄 Know about my experiences',
funFact: "⚡ Fun fact", funFact: '⚡ Fun fact',
portfolio: "👨‍💻 All of my projects are available at", portfolio: '👨‍💻 All of my projects are available at',
blog: "📝 I regulary write articles on", blog: '📝 I regularly write articles on',
} };
const DEFAULT_DATA = { const DEFAULT_DATA = {
title: "dummy", title: 'dummy',
subtitle: "A passionate frontend developer from India", subtitle: 'A passionate frontend developer from India',
currentWork: "readme-generator", currentWork: 'readme-generator',
currentLearn: "", currentLearn: '',
collaborateOn: "", collaborateOn: '',
helpWith: "", helpWith: '',
ama: "", ama: '',
contact: "", contact: '',
funFact: "", funFact: '',
twitterBadge: false, twitterBadge: false,
visitorsBadge: false, visitorsBadge: false,
badgeStyle: "flat", badgeStyle: 'flat',
badgeColor: "0e75b6", badgeColor: '0e75b6',
badgeLabel: "Profile views", badgeLabel: 'Profile views',
githubProfileTrophy: false, githubProfileTrophy: false,
githubStats: false, githubStats: false,
githubStatsOptions: { githubStatsOptions: {
theme: "", theme: '',
titleColor: "", titleColor: '',
textColor: "", textColor: '',
bgColor: "", bgColor: '',
hideBorder: false, hideBorder: false,
cacheSeconds: null, cacheSeconds: null,
locale: "en", locale: 'en',
}, },
topLanguages: false, topLanguages: false,
topLanguagesOptions: { topLanguagesOptions: {
theme: "", theme: '',
titleColor: "", titleColor: '',
textColor: "", textColor: '',
bgColor: "", bgColor: '',
hideBorder: false, hideBorder: false,
cacheSeconds: null, cacheSeconds: null,
locale: "en", locale: 'en',
}, },
devDynamicBlogs: false, devDynamicBlogs: false,
mediumDynamicBlogs: false, mediumDynamicBlogs: false,
rssDynamicBlogs: false, rssDynamicBlogs: false,
} };
const DEFAULT_LINK = { const DEFAULT_LINK = {
currentWork: "https://dummy.com", currentWork: 'https://dummy.com',
collaborateOn: "", collaborateOn: '',
helpWith: "", helpWith: '',
portfolio: "", portfolio: '',
blog: "", blog: '',
resume: "", resume: '',
} };
const DEFAULT_SOCIAL = { const DEFAULT_SOCIAL = {
github: "", github: '',
dev: "", dev: '',
linkedin: "", linkedin: '',
codepen: "dummy", codepen: 'dummy',
stackoverflow: "", stackoverflow: '',
kaggle: "", kaggle: '',
codesandbox: "", codesandbox: '',
fb: "", fb: '',
instagram: "", instagram: '',
twitter: "", twitter: '',
dribbble: "", dribbble: '',
behance: "", behance: '',
medium: "", medium: '',
youtube: "", youtube: '',
codechef: "", codechef: '',
hackerrank: "", hackerrank: '',
codeforces: "", codeforces: '',
leetcode: "", leetcode: '',
topcoder: "", topcoder: '',
hackerearth: "", hackerearth: '',
geeks_for_geeks: "", geeks_for_geeks: '',
discord: "", discord: '',
rssurl: "", rssurl: '',
} };
const DUMMY_SKILLS = { const DUMMY_SKILLS = {
skills: { skills: {
unity: true, unity: true,
android: false, android: false,
angularjs: false, angularjs: false,
apachecordova: false, apachecordova: false,
} },
} };
describe("Markdown Preview", () => { describe('Markdown Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
let link = DEFAULT_LINK; let link = DEFAULT_LINK;
let social = DEFAULT_SOCIAL; let social = DEFAULT_SOCIAL;
let skills = {} let skills = {};
const tree = shallow(<MarkdownPreview const tree = shallow(<MarkdownPreview prefix={prefix} data={data} link={link} social={social} skills={skills} />);
prefix={prefix}
data={data} expect(tree).toMatchSnapshot();
link={link} });
social={social} });
skills={skills} />) describe('Title Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() let prefix = DEFAULT_PREFIX;
}) let data = DEFAULT_DATA;
}) const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />);
describe("Title Preview", () => {
it("renders correctly", () => { expect(tree).toMatchSnapshot();
let prefix = DEFAULT_PREFIX; });
let data = DEFAULT_DATA; it('renders correctly with no prefix', () => {
const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />) let prefix = DEFAULT_PREFIX;
const tree = shallow(<TitlePreview prefix={prefix.title} title={''} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
it("renders correctly with no prefix", () => { });
let prefix = DEFAULT_PREFIX; it('renders correctly with no title', () => {
const tree = shallow(<TitlePreview prefix={prefix.title} title={""} />) let data = DEFAULT_DATA;
const tree = shallow(<TitlePreview title={data.title} prefix={''} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
it("renders correctly with no title", () => { });
let data = DEFAULT_DATA; it('renders correctly with no title and prefix', () => {
const tree = shallow(<TitlePreview title={data.title} prefix={""} />) const tree = shallow(<TitlePreview />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no title and prefix", () => { });
const tree = shallow(<TitlePreview />) describe('SubTitle Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() let data = DEFAULT_DATA;
}) const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />);
})
describe("SubTitle Preview", () => { expect(tree).toMatchSnapshot();
it("renders correctly", () => { });
let data = DEFAULT_DATA; it('renders correctly with no subtitle', () => {
const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />) const tree = shallow(<SubTitlePreview subtitle={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no subtitle", () => { });
const tree = shallow(<SubTitlePreview subtitle={""} />) describe('SectionTitle Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() const tree = shallow(<SectionTitle visible={true} label={'dummy'} />);
})
}) expect(tree).toMatchSnapshot();
describe("SectionTitle Preview", () => { });
it("renders correctly", () => { it('renders correctly with no label', () => {
const tree = shallow(<SectionTitle visible={true} label={"dummy"} />) const tree = shallow(<SectionTitle visible={true} label={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no label", () => { it('renders correctly with visible false', () => {
const tree = shallow(<SectionTitle visible={true} label={""} />) const tree = shallow(<SectionTitle visible={false} label={'dummy'} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with visible false", () => { });
const tree = shallow(<SectionTitle visible={false} label={"dummy"} />) describe('DisplayWork Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() let prefix = DEFAULT_PREFIX;
}) let data = DEFAULT_DATA;
}) let link = DEFAULT_LINK;
describe("DisplayWork Preview", () => { const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />);
it("renders correctly", () => {
let prefix = DEFAULT_PREFIX; expect(tree).toMatchSnapshot();
let data = DEFAULT_DATA; });
let link = DEFAULT_LINK; it('renders correctly with no prefix, link and project', () => {
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />) const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no prefix, link and project", () => { it('renders correctly with no prefix', () => {
const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />) let data = DEFAULT_DATA;
let link = DEFAULT_LINK;
expect(tree).toMatchSnapshot() const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />);
})
it("renders correctly with no prefix", () => { expect(tree).toMatchSnapshot();
let data = DEFAULT_DATA; });
let link = DEFAULT_LINK; it('renders correctly with no project', () => {
const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />) let prefix = DEFAULT_PREFIX;
let link = DEFAULT_LINK;
expect(tree).toMatchSnapshot() const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />);
})
it("renders correctly with no project", () => { expect(tree).toMatchSnapshot();
let prefix = DEFAULT_PREFIX; });
let link = DEFAULT_LINK; it('renders correctly with no link', () => {
const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />) let prefix = DEFAULT_PREFIX;
let data = DEFAULT_DATA;
expect(tree).toMatchSnapshot() const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined} />);
})
it("renders correctly with no link", () => { expect(tree).toMatchSnapshot();
let prefix = DEFAULT_PREFIX; });
let data = DEFAULT_DATA; it('renders correctly with no prefix and link', () => {
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined}/>) let data = DEFAULT_DATA;
const tree = shallow(<DisplayWork project={data.currentWork} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
it("renders correctly with no prefix and link", () => { });
let data = DEFAULT_DATA; it('renders correctly with no project and link', () => {
const tree = shallow(<DisplayWork project={data.currentWork} />) let prefix = DEFAULT_PREFIX;
const tree = shallow(<DisplayWork prefix={prefix} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
it("renders correctly with no project and link", () => { });
let prefix = DEFAULT_PREFIX; it('renders correctly with no project and prefix', () => {
const tree = shallow(<DisplayWork prefix={prefix} />) let link = DEFAULT_LINK;
const tree = shallow(<DisplayWork link={link.currentWork} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
it("renders correctly with no project and prefix", () => { });
let link = DEFAULT_LINK; });
const tree = shallow(<DisplayWork link={link.currentWork} />) describe('DisplaySocial Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() let social = DEFAULT_SOCIAL;
}) const tree = shallow(
}) <DisplaySocial
describe("DisplaySocial Preview", () => { base="https://codepen.io"
it("renders correctly", () => { icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
let social = DEFAULT_SOCIAL; username={social.codepen}
const tree = shallow(<DisplaySocial />
base="https://codepen.io" );
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
username={social.codepen} expect(tree).toMatchSnapshot();
/> });
) it('renders correctly with no username', () => {
const tree = shallow(
expect(tree).toMatchSnapshot() <DisplaySocial
}) base="https://codepen.io"
it("renders correctly with no username", () => { icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
const tree = shallow(<DisplaySocial username={''}
base="https://codepen.io" />
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" );
username={""}
/> expect(tree).toMatchSnapshot();
) });
});
expect(tree).toMatchSnapshot() describe('VisitorsBadge Preview', () => {
}) it('renders correctly', () => {
}) let data = DEFAULT_DATA;
describe("VisitorsBadge Preview", () => { let social = DEFAULT_SOCIAL;
it("renders correctly", () => { const tree = shallow(
let data = DEFAULT_DATA; <VisitorsBadgePreview
let social = DEFAULT_SOCIAL; show={data.visitorsBadge}
const tree = shallow(<VisitorsBadgePreview github={social.github}
show={data.visitorsBadge} badgeOptions={{
github={social.github} badgeLabel: encodeURI(data.badgeLabel),
badgeOptions={{ badgeColor: data.badgeColor,
badgeLabel: encodeURI(data.badgeLabel), badgeStyle: data.badgeStyle,
badgeColor: data.badgeColor, }}
badgeStyle: data.badgeStyle, />
}} );
/>
) expect(tree).toMatchSnapshot();
});
expect(tree).toMatchSnapshot() it('renders correctly with show true', () => {
}) let data = DEFAULT_DATA;
it("renders correctly with show true", () => { let social = DEFAULT_SOCIAL;
let data = DEFAULT_DATA; const tree = shallow(
let social = DEFAULT_SOCIAL; <VisitorsBadgePreview
const tree = shallow(<VisitorsBadgePreview show={true}
show={true} github={social.github}
github={social.github} badgeOptions={{
badgeOptions={{ badgeLabel: encodeURI(data.badgeLabel),
badgeLabel: encodeURI(data.badgeLabel), badgeColor: data.badgeColor,
badgeColor: data.badgeColor, badgeStyle: data.badgeStyle,
badgeStyle: data.badgeStyle, }}
}} />
/> );
)
expect(tree).toMatchSnapshot();
expect(tree).toMatchSnapshot() });
}) });
}) describe('GithubProfileTrophy Preview', () => {
describe("GithubProfileTrophy Preview", () => { it('renders correctly', () => {
it("renders correctly", () => { let data = DEFAULT_DATA;
let data = DEFAULT_DATA; let social = DEFAULT_SOCIAL;
let social = DEFAULT_SOCIAL; const tree = shallow(<GithubProfileTrophyPreview show={data.githubProfileTrophy} github={social.github} />);
const tree = shallow(<GithubProfileTrophyPreview
show={data.githubProfileTrophy} expect(tree).toMatchSnapshot();
github={social.github} });
/>) it('renders correctly with show true', () => {
let data = DEFAULT_DATA;
expect(tree).toMatchSnapshot() let social = DEFAULT_SOCIAL;
}) const tree = shallow(<GithubProfileTrophyPreview show={true} github={social.github} />);
it("renders correctly with show true", () => {
let data = DEFAULT_DATA; expect(tree).toMatchSnapshot();
let social = DEFAULT_SOCIAL; });
const tree = shallow(<GithubProfileTrophyPreview });
show={true} describe('TwitterBadgePreview Preview', () => {
github={social.github} it('renders correctly', () => {
/>) let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
expect(tree).toMatchSnapshot() const tree = shallow(<TwitterBadgePreview show={data.twitterBadge} twitter={social.twitter} />);
})
}) expect(tree).toMatchSnapshot();
describe("TwitterBadgePreview Preview", () => { });
it("renders correctly", () => { it('renders correctly with show true', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL; let social = DEFAULT_SOCIAL;
const tree = shallow(<TwitterBadgePreview const tree = shallow(<TwitterBadgePreview show={true} twitter={social.twitter} />);
show={data.twitterBadge}
twitter={social.twitter} expect(tree).toMatchSnapshot();
/>) });
});
expect(tree).toMatchSnapshot() describe('Work Preview', () => {
}) it('renders correctly', () => {
it("renders correctly with show true", () => { let data = DEFAULT_DATA;
let data = DEFAULT_DATA; let prefix = DEFAULT_PREFIX;
let social = DEFAULT_SOCIAL; let link = DEFAULT_LINK;
const tree = shallow(<TwitterBadgePreview let props = { data: data, prefix: prefix, link: link };
show={true} const tree = shallow(<WorkPreview work={props} />);
twitter={social.twitter}
/>) expect(tree).toMatchSnapshot();
});
expect(tree).toMatchSnapshot() });
}) describe('Social Preview', () => {
}) it('renders correctly', () => {
describe("Work Preview", () => { let social = DEFAULT_SOCIAL;
it("renders correctly", () => { const tree = shallow(<SocialPreview social={social} />);
let data = DEFAULT_DATA;
let prefix = DEFAULT_PREFIX; expect(tree).toMatchSnapshot();
let link = DEFAULT_LINK; });
let props = { data: data, prefix: prefix, link: link } });
const tree = shallow(<WorkPreview work={props} />) describe('Skills Preview', () => {
it('renders correctly', () => {
expect(tree).toMatchSnapshot() let skills = DUMMY_SKILLS.skills;
}) const tree = shallow(<SkillsPreview skills={skills} />);
})
describe("Social Preview", () => { expect(tree).toMatchSnapshot();
it("renders correctly", () => { });
let social = DEFAULT_SOCIAL; it('renders correctly with no skills', () => {
const tree = shallow(<SocialPreview social={social} />) let skills = {};
const tree = shallow(<SkillsPreview skills={skills} />);
expect(tree).toMatchSnapshot()
}) expect(tree).toMatchSnapshot();
}) });
describe("Skills Preview", () => { });
it("renders correctly", () => { describe('TopLanguages Preview', () => {
let skills = DUMMY_SKILLS.skills it('renders correctly', () => {
const tree = shallow(<SkillsPreview skills={skills} />) let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
expect(tree).toMatchSnapshot() const tree = shallow(
}) <TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
it("renders correctly with no skills", () => { );
let skills = {}
const tree = shallow(<SkillsPreview skills={skills} />) expect(tree).toMatchSnapshot();
});
expect(tree).toMatchSnapshot() it('renders correctly with show true', () => {
}) let data = DEFAULT_DATA;
}) let social = DEFAULT_SOCIAL;
describe("TopLanguages Preview", () => { const tree = shallow(<TopLanguagesPreview show={true} github={social.github} options={data.topLanguagesOptions} />);
it("renders correctly", () => {
let data = DEFAULT_DATA; expect(tree).toMatchSnapshot();
let social = DEFAULT_SOCIAL; });
const tree = shallow(<TopLanguagesPreview });
show={data.topLanguages} describe('GitHubStats Preview', () => {
github={social.github} it('renders correctly', () => {
options={data.topLanguagesOptions} let data = DEFAULT_DATA;
/>) let social = DEFAULT_SOCIAL;
const tree = shallow(
expect(tree).toMatchSnapshot() <GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
}) );
it("renders correctly with show true", () => {
let data = DEFAULT_DATA; expect(tree).toMatchSnapshot();
let social = DEFAULT_SOCIAL; });
const tree = shallow(<TopLanguagesPreview it('renders correctly', () => {
show={true} let data = DEFAULT_DATA;
github={social.github} let social = DEFAULT_SOCIAL;
options={data.topLanguagesOptions} const tree = shallow(<GitHubStatsPreview show={true} github={social.github} options={data.githubStatsOptions} />);
/>)
expect(tree).toMatchSnapshot();
expect(tree).toMatchSnapshot() });
}) });
})
describe("GitHubStats Preview", () => {
it("renders correctly", () => {
let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
const tree = shallow(<GitHubStatsPreview
show={data.githubStats}
github={social.github}
options={data.githubStatsOptions}
/>)
expect(tree).toMatchSnapshot()
})
it("renders correctly", () => {
let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
const tree = shallow(<GitHubStatsPreview
show={true}
github={social.github}
options={data.githubStatsOptions}
/>)
expect(tree).toMatchSnapshot()
})
})
+25 -27
View File
@@ -1,42 +1,40 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Skills from "../skills" import Skills from '../skills';
jest.mock("../../constants/skills", () => ({ jest.mock('../../constants/skills', () => ({
__esModule: true, __esModule: true,
categorizedSkills: { categorizedSkills: {
language: { language: {
title: "Programming Languages", title: 'Programming Languages',
skills: ["javascript"], skills: ['javascript'],
}, },
frontend_dev: { frontend_dev: {
title: "Frontend Development", title: 'Frontend Development',
skills: ["react", "svelte"], skills: ['react', 'svelte'],
}, },
}, },
icons: { icons: {
javascript: "javascript.svg", javascript: 'javascript.svg',
react: "react.svg", react: 'react.svg',
svelte: "svelte.svg", svelte: 'svelte.svg',
}, },
})) }));
describe("Skills", () => { describe('Skills', () => {
it("renders correctly", () => { it('renders correctly', () => {
const component = shallow(<Skills skills={{ javascript: true }} />) const component = shallow(<Skills skills={{ javascript: true }} />);
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("calls handleSkillsChange prop when a skill is clicked", () => { it('calls handleSkillsChange prop when a skill is clicked', () => {
const mockFn = jest.fn() const mockFn = jest.fn();
const component = shallow( const component = shallow(<Skills skills={{ javascript: true }} handleSkillsChange={mockFn} />);
<Skills skills={{ javascript: true }} handleSkillsChange={mockFn} />
)
component.find("#javascript").simulate("change") component.find('#javascript').simulate('change');
expect(mockFn).toHaveBeenCalledTimes(1) expect(mockFn).toHaveBeenCalledTimes(1);
}) });
}) });
+37 -37
View File
@@ -1,44 +1,44 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Social from "../social" import Social from '../social';
describe("Social", () => { describe('Social', () => {
const mockEvent = { target: { value: "This is a mock event" } } const mockEvent = { target: { value: 'This is a mock event' } };
const props = { const props = {
social: { social: {
github: "github ", github: 'github ',
twitter: "twitter", twitter: 'twitter',
dev: "dev", dev: 'dev',
codepen: "codepen", codepen: 'codepen',
codesandbox: "codesandbodx", codesandbox: 'codesandbodx',
stackoverflow: "stackoverflow", stackoverflow: 'stackoverflow',
linkedin: "linkedin", linkedin: 'linkedin',
kaggle: "kaggle", kaggle: 'kaggle',
fb: "fb", fb: 'fb',
instagram: "instagram", instagram: 'instagram',
dribble: "dribble", dribble: 'dribble',
behance: "behance", behance: 'behance',
medium: "medium", medium: 'medium',
youtube: "youtube", youtube: 'youtube',
codechef: "codechef", codechef: 'codechef',
hackerrack: "hackerranck", hackerrack: 'hackerranck',
codeforces: "codeforces", codeforces: 'codeforces',
leetcode: "leetcode", leetcode: 'leetcode',
topcoder: "topcoder", topcoder: 'topcoder',
hackerearth: "@hackerearth", hackerearth: '@hackerearth',
geeks_for_geeks: "geeks_for_geeks", geeks_for_geeks: 'geeks_for_geeks',
discord: "discord", discord: 'discord',
rssurl: "rssurl", rssurl: 'rssurl',
}, },
handleSocialChange: jest.fn().mockReturnValue({}), handleSocialChange: jest.fn().mockReturnValue({}),
} };
it("renders correctly", () => { it('renders correctly', () => {
const component = shallow(<Social {...props} />) const component = shallow(<Social {...props} />);
for (let i = 0; i < component.find("input").length; i++) { for (let i = 0; i < component.find('input').length; i++) {
component.find("input").at(i).simulate("change", mockEvent) component.find('input').at(i).simulate('change', mockEvent);
} }
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+17 -17
View File
@@ -1,26 +1,26 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Subtitle from "../subtitle" import Subtitle from '../subtitle';
describe("Subtitle", () => { describe('Subtitle', () => {
const mockEvent = { target: { value: "This is a mock event" } } const mockEvent = { target: { value: 'This is a mock event' } };
const props = { const props = {
data: { data: {
subtitle: "A frontend developer", subtitle: 'A frontend developer',
}, },
handleDataChange: jest.fn().mockReturnValue({}), handleDataChange: jest.fn().mockReturnValue({}),
} };
const component = shallow(<Subtitle {...props} />) const component = shallow(<Subtitle {...props} />);
it("renders correctly", () => { it('renders correctly', () => {
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
it("calls onChange", () => { it('calls onChange', () => {
component.find("input").at(0).simulate("change", mockEvent) component.find('input').at(0).simulate('change', mockEvent);
expect(props.handleDataChange).toBeCalledWith("subtitle", mockEvent) expect(props.handleDataChange).toBeCalledWith('subtitle', mockEvent);
}) });
}) });
+18 -18
View File
@@ -1,27 +1,27 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Title from "../title" import Title from '../title';
describe("Title", () => { describe('Title', () => {
const mockEvent = { target: { value: "This is a mock event" } } const mockEvent = { target: { value: 'This is a mock event' } };
const props = { const props = {
prefix: { prefix: {
title: "test_title", title: 'test_title',
currentWork: "test_currentwork", currentWork: 'test_currentwork',
}, },
data: { title: "test_data" }, data: { title: 'test_data' },
link: { currentWork: "test_currentwork" }, link: { currentWork: 'test_currentwork' },
handlePrefixChange: jest.fn().mockReturnValue({}), handlePrefixChange: jest.fn().mockReturnValue({}),
handleLinkChange: jest.fn().mockReturnValue({}), handleLinkChange: jest.fn().mockReturnValue({}),
handleDataChange: jest.fn().mockReturnValue({}), handleDataChange: jest.fn().mockReturnValue({}),
} };
it("renders title component correctly", () => { it('renders title component correctly', () => {
const component = shallow(<Title {...props} />) const component = shallow(<Title {...props} />);
component.find("input").at(0).simulate("change", mockEvent) component.find('input').at(0).simulate('change', mockEvent);
component.find("input").at(1).simulate("change", mockEvent) component.find('input').at(1).simulate('change', mockEvent);
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
+18 -18
View File
@@ -1,28 +1,28 @@
import React from "react" import React from 'react';
import { shallow } from "enzyme" import { shallow } from 'enzyme';
import toJson from "enzyme-to-json" import toJson from 'enzyme-to-json';
import Work from "../work" import Work from '../work';
describe("Work", () => { describe('Work', () => {
const mockEvent = { target: { value: "This is a mock event" } } const mockEvent = { target: { value: 'This is a mock event' } };
const props = { const props = {
prefix: { prefix: {
title: "test_title", title: 'test_title',
currentWork: "test_currentwork", currentWork: 'test_currentwork',
}, },
data: { title: "test_data" }, data: { title: 'test_data' },
link: { currentWork: "test_currentwork" }, link: { currentWork: 'test_currentwork' },
handlePrefixChange: jest.fn().mockReturnValue({}), handlePrefixChange: jest.fn().mockReturnValue({}),
handleLinkChange: jest.fn().mockReturnValue({}), handleLinkChange: jest.fn().mockReturnValue({}),
handleDataChange: jest.fn().mockReturnValue({}), handleDataChange: jest.fn().mockReturnValue({}),
} };
it("renders work component correctly", () => { it('renders work component correctly', () => {
const component = shallow(<Work {...props} />) const component = shallow(<Work {...props} />);
for (let i = 0; i < component.find("input").length; i++) { for (let i = 0; i < component.find('input').length; i++) {
component.find("input").at(i).simulate("change", mockEvent) component.find('input').at(i).simulate('change', mockEvent);
} }
expect(toJson(component)).toMatchSnapshot() expect(toJson(component)).toMatchSnapshot();
}) });
}) });
-451
View File
@@ -1,451 +0,0 @@
import React, { useState, useEffect } from "react"
import { withPrefix } from "gatsby"
import { latestBlogs } from "../utils/workflows"
import links from "../constants/page-links"
import { isMediumUsernameValid, isGitHubUsernameValid } from "../utils/validation"
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react";
const AddonsItem = ({ inputId, inputChecked, onInputChange, Options, onIconClick, ...props }) => {
const [open, setOpen] = useState(false);
const Icon = open ? XCircleIcon : ToolsIcon;
return (
<>
<div className="py-2 flex justify-start items-center text-sm sm:text-lg">
<label htmlFor={inputId} className="cursor-pointer flex items-center">
<input
type="checkbox"
id={inputId}
checked={inputChecked}
onChange={onInputChange}
/>
<span className="pl-4">{props.children}</span>
</label>
{Options && (
<button
id={`${inputId}-open-btn`}
onClick={() => setOpen(!open)}
className="flex ml-3 focus:bg-gray-400"
style={{ outline: "none" }}
>
<Icon className="transform scale-100 md:scale-125" />
</button>
)}
</div>
{Options && open && Options}
</>
);
};
const CustomizeOptions = ({ title, CustomizationOptions }) => (
<div
className={`border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8`}
style={{ maxWidth: "21rem" }}
>
<header className="text-base sm:text-lg">{title}</header>
<hr className="border-gray-500" />
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">
{CustomizationOptions}
</div>
</div>
);
const CustomizeBadge = ({githubName, badgeOptions, onBadgeUpdate}) => {
return (
<>
<label htmlFor="badge-style">Style:&nbsp;
<select
id="badge-style"
onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)}
value = {badgeOptions.badgeStyle}
>
<option value="flat">Flat</option>
<option value="flat-square">Flat Square</option>
<option value="plastic">Plastic</option>
</select>
</label>
<label htmlFor="badge-color">Color:&nbsp;
<input
type="color"
id="badge-color"
defaultValue={`#${badgeOptions.badgeColor}`}
className="w-6"
onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor="badge-label-text">Label Text:&nbsp;
<input
type="text"
id="badge-label-text"
placeholder="Profile views"
className="w-2/4 bg-gray-300 pl-2"
onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())}
defaultValue={badgeOptions.badgeLabel}
/>
</label>
<span className="mt-2 flex items-center">
Preview:&nbsp;
{
isGitHubUsernameValid(githubName)?
<img
src={`https://komarev.com/ghpvc/`
+ `?username=${githubName}`
+ `&label=${encodeURI(badgeOptions.badgeLabel)}`
+ `&color=${badgeOptions.badgeColor}`
+ `&style=${badgeOptions.badgeStyle}`
}
/>
: <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>
}
</span>
</>
)
}
const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) =>
<>
<label htmlFor={`${prefix}-theme`}>Theme:&nbsp;
<select
id={`${prefix}-theme`}
onChange={({target: { value }}) => onUpdate("theme", value)}
defaultValue={options.theme}
>
<option value="none">none</option>
<option value="dark">Dark</option>
<option value="radical">Radical</option>
<option value="merko">Merko</option>
<option value="gruvbox">Gruvbox</option>
<option value="tokyonight">Tokyonight</option>
<option value="onedark">Onedark</option>
<option value="cobalt">Cobalt</option>
<option value="synthwave">Synthwave</option>
<option value="highcontrast">Highcontrast</option>
<option value="dracula">Dracula</option>
</select>
</label>
<label htmlFor={`${prefix}-title-color`}>Title Color:&nbsp;
<input
type="color"
id={`${prefix}-title-color`}
defaultValue={`#${options.titleColor}`}
className="w-6"
onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-text-color`}>Text Color:&nbsp;
<input
type="color"
id={`${prefix}-text-color`}
defaultValue={`#${options.textColor}`}
className="w-6"
onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-bg-color`}>Background Color:&nbsp;
<input
type="color"
id={`${prefix}-bg-color`}
defaultValue={`#${options.bgColor}`}
className="w-6"
onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-hide-border`}>Hide border:&nbsp;
<input
id={`${prefix}-hide-border`}
type="checkbox"
checked={options.hideBorder}
onChange={(e) => onUpdate('hideBorder', e.target.checked)}
/>
</label>
<label htmlFor={`${prefix}-cache-seconds`}>Cache Seconds:&nbsp;
<input
id={`${prefix}-cache-seconds`}
type="number"
min={1800}
max={86400}
placeholder={1800}
defaultValue={options.cacheSeconds}
onChange={(e) => onUpdate('cacheSeconds', e.target.value)}
/>
</label>
<label htmlFor={`${prefix}-locale`}>Locale:&nbsp;
<input
id={`${prefix}-locale`}
type="text"
placeholder="en"
defaultValue={options.locale}
onChange={(e) => onUpdate('locale', e.target.value)}
size="2"
/>
</label>
</>
const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
<>
<label htmlFor={`${prefix}-theme`}>
Theme:&nbsp;
<select
id={`${prefix}-theme`}
onChange={({ target: { value } }) => onUpdate("theme", value)}
defaultValue={options.theme}
>
<option value="default">default</option>
<option value="dark">dark</option>
<option value="highcontrast">highcontrast</option>
</select>
</label>
</>
)
const Addons = props => {
const [debounce, setDebounce] = useState(undefined);
const [badgeOptions, setBadgeOptions] = useState({
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel
});
useEffect(() => {
setBadgeOptions({
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel
})
}, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel])
const [githubStatsOptions, setGithubStatsOptions] = useState({
...props.data.githubStatsOptions,
});
useEffect(() => {
setGithubStatsOptions({
...props.data.githubStatsOptions
})
}, [props.data.githubStatsOptions])
const [topLanguagesOptions, setTopLanguagesOptions] = useState({
...props.data.topLanguagesOptions,
});
useEffect(() => {
setTopLanguagesOptions({
...props.data.topLanguagesOptions
})
}, [props.data.topLanguagesOptions])
const [streakStatsOptions, setStreakStatsOptions] = useState({
...props.data.streakStatsOptions,
});
useEffect(() => {
setStreakStatsOptions({
...props.data.streakStatsOptions
})
}, [props.data.streakStatsOptions])
const blogPostPorkflow = () => {
let payload = {
dev: {
show: props.data.devDynamicBlogs,
username: props.social.dev,
},
medium: {
show: props.data.mediumDynamicBlogs,
username: props.social.medium,
},
rssurl: {
show: props.data.rssDynamicBlogs,
username: props.social.rssurl,
},
}
var actionContent = latestBlogs(payload)
var tempElement = document.createElement("a")
tempElement.setAttribute(
"href",
"data:text/yaml;charset=utf-8," + encodeURIComponent(actionContent)
)
tempElement.setAttribute("download", "blog-post-workflow.yml")
tempElement.style.display = "none"
document.body.appendChild(tempElement)
tempElement.click()
document.body.removeChild(tempElement)
}
const onBadgeUpdate = (option, value) => {
const callback = () => {
let newVal = (option==='badgeLabel' && value==='')?'Profile views':value;
setBadgeOptions({...badgeOptions, [option]: newVal});
props.handleDataChange(option, {target: {value: newVal}})
}
clearTimeout(debounce);
setDebounce(setTimeout(callback, 300));
}
const onStatsUpdate = (option, value) => {
const newStatsOptions = {...githubStatsOptions, [option]: value}
setGithubStatsOptions(newStatsOptions)
props.handleDataChange("githubStatsOptions", {target: {value: newStatsOptions}})
}
const onTopLangUpdate = (option, value) => {
const newLangOptions = {...topLanguagesOptions, [option]: value}
setTopLanguagesOptions(newLangOptions)
props.handleDataChange("topLanguagesOptions", {target: {value: newLangOptions}})
}
const onStreakStatsUpdate = (option, value) => {
const newStreakStatsOptions = {...streakStatsOptions, [option]: value}
setStreakStatsOptions(newStreakStatsOptions)
props.handleDataChange("streakStatsOptions", {target: {value: newStreakStatsOptions}})
}
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Add-ons
</div>
<AddonsItem
inputId="visitors-count"
inputChecked={props.data.visitorsBadge}
onInputChange={() => props.handleCheckChange("visitorsBadge")}
Options={
<CustomizeOptions
title="Customize Badge"
CustomizationOptions={
<CustomizeBadge
githubName={props.social.github}
badgeOptions={badgeOptions}
onBadgeUpdate={onBadgeUpdate}
/>
}
/>
}
>
display visitors count badge
</AddonsItem>
<AddonsItem
inputId="github-profile-trophy"
inputChecked={props.data.githubProfileTrophy}
onInputChange={() => props.handleCheckChange("githubProfileTrophy")}
>
display github trophy
</AddonsItem>
<AddonsItem
inputId="github-stats"
inputChecked={props.data.githubStats}
onInputChange={() => props.handleCheckChange("githubStats")}
Options={
<CustomizeOptions
title="Customize Github Stats Card"
CustomizationOptions={
<CustomizeGithubStatsBase prefix="stats" options={githubStatsOptions} onUpdate={onStatsUpdate}/>
}
/>
}
>
display github profile stats card
</AddonsItem>
<AddonsItem
inputId="top-languages"
inputChecked={props.data.topLanguages}
onInputChange={() => props.handleCheckChange("topLanguages")}
Options={
<CustomizeOptions
title="Customize Top Skills Card"
CustomizationOptions={
<CustomizeGithubStatsBase prefix="top-lang" options={topLanguagesOptions} onUpdate={onTopLangUpdate}/>
}
/>
}
>
display top skills
</AddonsItem>
<AddonsItem
inputId="streak-stats"
inputChecked={props.data.streakStats}
onInputChange={() => props.handleCheckChange("streakStats")}
Options={
<CustomizeOptions
title="Customize Streak Stats Card"
CustomizationOptions={
<CustomizeStreakStats prefix="streak-stats" options={streakStatsOptions} onUpdate={onStreakStatsUpdate}/>
}
/>
}
>
display github streak stats
</AddonsItem>
<AddonsItem
inputId="twitter-badge"
inputChecked={props.data.twitterBadge}
onInputChange={() => props.handleCheckChange("twitterBadge")}
>
display twitter badge
</AddonsItem>
<AddonsItem
inputId="dev-dynamic-blogs"
inputChecked={props.data.devDynamicBlogs}
onInputChange={() => props.handleCheckChange("devDynamicBlogs")}
>
display latest dev.to blogs dynamically (GitHub Action)
</AddonsItem>
<AddonsItem
inputId="medium-dynamic-blogs"
inputChecked={props.data.mediumDynamicBlogs}
onInputChange={() => props.handleCheckChange("mediumDynamicBlogs")}
>
display latest medium blogs dynamically (GitHub Action)
</AddonsItem>
<AddonsItem
inputId="rss-dynamic-blogs"
inputChecked={props.data.rssDynamicBlogs}
onInputChange={() => props.handleCheckChange("rssDynamicBlogs")}
>
display latest blogs from your personal blog dynamically (GitHub Action)
</AddonsItem>
{(props.data.devDynamicBlogs && props.social.dev) ||
(props.data.rssDynamicBlogs && props.social.rssurl) ||
(props.data.mediumDynamicBlogs &&
props.social.medium &&
isMediumUsernameValid(props.social.medium)) ? (
<div className="workflow">
<div>
download
<span
id="blog-post-worklow-span"
onClick={blogPostPorkflow}
onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()}
role="button"
tabIndex="0"
style={{ cursor: "pointer", color: "#002ead" }}
>
{" "}
blog-post-workflow.yml
</span>{" "}
file(learn
<a
href={withPrefix(links.addons)}
target="blank"
style={{ color: "#002ead" }}
>
{" "}
how to setup
</a>
)
</div>
</div>
) : (
""
)}
</div>
)
}
export default Addons
+320
View File
@@ -0,0 +1,320 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { withPrefix } from 'gatsby';
import { ToolsIcon, XCircleIcon } from '@primer/octicons-react';
import latestBlogs from '../utils/workflows';
import links from '../constants/page-links';
import { isMediumUsernameValid, isGitHubUsernameValid } from '../utils/validation';
const AddonsItem = (props) => {
const { inputId, inputChecked, onInputChange, Options, children } = props;
const [open, setOpen] = useState(false);
const Icon = open ? XCircleIcon : ToolsIcon;
return (
<>
<div className="py-2 flex justify-start items-center text-sm sm:text-lg">
<label htmlFor={inputId} className="checkbox-label flex items-center">
<input id={inputId} type="checkbox" className="checkbox-label__input" checked={inputChecked} onChange={onInputChange} />
<span className="checkbox-label__control" />
<span className="pl-4">{children}</span>
</label>
{Options && (
<button type="button" id={`${inputId}-open-btn`} onClick={() => setOpen(!open)} className="flex ml-3 focus:bg-gray-400" style={{ outline: 'none' }}>
<Icon className="transform scale-100 md:scale-125" />
</button>
)}
</div>
{Options && open && Options}
</>
);
};
AddonsItem.propTypes = {
inputId: PropTypes.string.isRequired,
inputChecked: PropTypes.bool.isRequired,
onInputChange: PropTypes.func.isRequired,
Options: PropTypes.element.isRequired,
children: PropTypes.element.isRequired,
};
const CustomizeOptions = ({ title, CustomizationOptions }) => (
<div className="border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8" style={{ maxWidth: '21rem' }}>
<header className="text-base sm:text-lg">{title}</header>
<hr className="border-gray-500" />
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">{CustomizationOptions}</div>
</div>
);
CustomizeOptions.propTypes = {
title: PropTypes.string.isRequired,
CustomizationOptions: PropTypes.element.isRequired,
};
const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => (
<>
<label htmlFor="badge-style">
Style:&nbsp;
<select id="badge-style" onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)} value={badgeOptions.badgeStyle}>
<option value="flat">Flat</option>
<option value="flat-square">Flat Square</option>
<option value="plastic">Plastic</option>
</select>
</label>
<label htmlFor="badge-color">
Color:&nbsp;
<input type="color" id="badge-color" defaultValue={`#${badgeOptions.badgeColor}`} className="w-6" onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))} />
</label>
<label htmlFor="badge-label-text">
Label Text:&nbsp;
<input type="text" id="badge-label-text" placeholder="Profile views" className="w-2/4 bg-gray-300 pl-2" onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())} defaultValue={badgeOptions.badgeLabel} />
</label>
<span className="mt-2 flex items-center">
Preview:&nbsp;
{isGitHubUsernameValid(githubName) ? <img src={`https://komarev.com/ghpvc/?username=${githubName}&label=${encodeURI(badgeOptions.badgeLabel)}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`} alt="profile-visitors-count" /> : <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>}
</span>
</>
);
CustomizeBadge.propTypes = {
githubName: PropTypes.string.isRequired,
badgeOptions: PropTypes.object.isRequired,
onBadgeUpdate: PropTypes.func.isRequired,
};
const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
<>
<label htmlFor={`${prefix}-theme`}>
Theme:&nbsp;
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.theme}>
<option value="none">none</option>
<option value="dark">Dark</option>
<option value="radical">Radical</option>
<option value="merko">Merko</option>
<option value="gruvbox">Gruvbox</option>
<option value="tokyonight">Tokyonight</option>
<option value="onedark">Onedark</option>
<option value="cobalt">Cobalt</option>
<option value="synthwave">Synthwave</option>
<option value="highcontrast">Highcontrast</option>
<option value="dracula">Dracula</option>
</select>
</label>
<label htmlFor={`${prefix}-title-color`}>
Title Color:&nbsp;
<input type="color" id={`${prefix}-title-color`} defaultValue={`#${options.titleColor}`} className="w-6" onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))} />
</label>
<label htmlFor={`${prefix}-text-color`}>
Text Color:&nbsp;
<input type="color" id={`${prefix}-text-color`} defaultValue={`#${options.textColor}`} className="w-6" onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))} />
</label>
<label htmlFor={`${prefix}-bg-color`}>
Background Color:&nbsp;
<input type="color" id={`${prefix}-bg-color`} defaultValue={`#${options.bgColor}`} className="w-6" onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))} />
</label>
<label htmlFor={`${prefix}-hide-border`} className="checkbox-label">
Hide border:&nbsp;
<input id={`${prefix}-hide-border`} type="checkbox" className="checkbox-label__input" checked={options.hideBorder} onChange={(e) => onUpdate('hideBorder', e.target.checked)} />
<span className="checkbox-label__control" />
</label>
<label htmlFor={`${prefix}-cache-seconds`}>
Cache Seconds:&nbsp;
<input id={`${prefix}-cache-seconds`} type="number" min={1800} max={86400} placeholder={1800} defaultValue={options.cacheSeconds} onChange={(e) => onUpdate('cacheSeconds', e.target.value)} />
</label>
<label htmlFor={`${prefix}-locale`}>
Locale:&nbsp;
<input id={`${prefix}-locale`} type="text" placeholder="en" defaultValue={options.locale} onChange={(e) => onUpdate('locale', e.target.value)} size="2" />
</label>
</>
);
CustomizeGithubStatsBase.propTypes = {
prefix: PropTypes.string.isRequired,
options: PropTypes.object.isRequired,
onUpdate: PropTypes.func.isRequired,
};
const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
<>
<label htmlFor={`${prefix}-theme`}>
Theme:&nbsp;
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.theme}>
<option value="default">default</option>
<option value="dark">dark</option>
<option value="highcontrast">highcontrast</option>
</select>
</label>
</>
);
CustomizeStreakStats.propTypes = {
prefix: PropTypes.string.isRequired,
options: PropTypes.object.isRequired,
onUpdate: PropTypes.func.isRequired,
};
const Addons = (props) => {
const { data, social, handleDataChange, handleCheckChange } = props;
const [debounce, setDebounce] = useState(undefined);
const [badgeOptions, setBadgeOptions] = useState({
badgeStyle: data.badgeStyle,
badgeColor: data.badgeColor,
badgeLabel: data.badgeLabel,
});
useEffect(() => {
setBadgeOptions({
badgeStyle: data.badgeStyle,
badgeColor: data.badgeColor,
badgeLabel: data.badgeLabel,
});
}, [data.badgeStyle, data.badgeColor, data.badgeLabel]);
const [githubStatsOptions, setGithubStatsOptions] = useState({
...data.githubStatsOptions,
});
useEffect(() => {
setGithubStatsOptions({
...data.githubStatsOptions,
});
}, [data.githubStatsOptions]);
const [topLanguagesOptions, setTopLanguagesOptions] = useState({
...data.topLanguagesOptions,
});
useEffect(() => {
setTopLanguagesOptions({
...data.topLanguagesOptions,
});
}, [data.topLanguagesOptions]);
const [streakStatsOptions, setStreakStatsOptions] = useState({
...data.streakStatsOptions,
});
useEffect(() => {
setStreakStatsOptions({
...data.streakStatsOptions,
});
}, [data.streakStatsOptions]);
const blogPostPorkflow = () => {
const payload = {
dev: {
show: data.devDynamicBlogs,
username: social.dev,
},
medium: {
show: data.mediumDynamicBlogs,
username: social.medium,
},
rssurl: {
show: data.rssDynamicBlogs,
username: social.rssurl,
},
};
const actionContent = latestBlogs(payload);
const tempElement = document.createElement('a');
tempElement.setAttribute('href', `data:text/yaml;charset=utf-8,${encodeURIComponent(actionContent)}`);
tempElement.setAttribute('download', 'blog-post-workflow.yml');
tempElement.style.display = 'none';
document.body.appendChild(tempElement);
tempElement.click();
document.body.removeChild(tempElement);
};
const onBadgeUpdate = (option, value) => {
const callback = () => {
const newVal = option === 'badgeLabel' && value === '' ? 'Profile views' : value;
setBadgeOptions({ ...badgeOptions, [option]: newVal });
handleDataChange(option, { target: { value: newVal } });
};
clearTimeout(debounce);
setDebounce(setTimeout(callback, 300));
};
const onStatsUpdate = (option, value) => {
const newStatsOptions = { ...githubStatsOptions, [option]: value };
setGithubStatsOptions(newStatsOptions);
handleDataChange('githubStatsOptions', {
target: { value: newStatsOptions },
});
};
const onTopLangUpdate = (option, value) => {
const newLangOptions = { ...topLanguagesOptions, [option]: value };
setTopLanguagesOptions(newLangOptions);
handleDataChange('topLanguagesOptions', {
target: { value: newLangOptions },
});
};
const onStreakStatsUpdate = (option, value) => {
const newStreakStatsOptions = { ...streakStatsOptions, [option]: value };
setStreakStatsOptions(newStreakStatsOptions);
handleDataChange('streakStatsOptions', {
target: { value: newStreakStatsOptions },
});
};
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Add-ons</div>
<AddonsItem inputId="visitors-count" inputChecked={data.visitorsBadge} onInputChange={() => handleCheckChange('visitorsBadge')} Options={<CustomizeOptions title="Customize Badge" CustomizationOptions={<CustomizeBadge githubName={social.github} badgeOptions={badgeOptions} onBadgeUpdate={onBadgeUpdate} />} />}>
display visitors count badge
</AddonsItem>
<AddonsItem inputId="github-profile-trophy" inputChecked={data.githubProfileTrophy} onInputChange={() => handleCheckChange('githubProfileTrophy')}>
display github trophy
</AddonsItem>
<AddonsItem inputId="github-stats" inputChecked={data.githubStats} onInputChange={() => handleCheckChange('githubStats')} Options={<CustomizeOptions title="Customize Github Stats Card" CustomizationOptions={<CustomizeGithubStatsBase prefix="stats" options={githubStatsOptions} onUpdate={onStatsUpdate} />} />}>
display github profile stats card
</AddonsItem>
<AddonsItem inputId="top-languages" inputChecked={data.topLanguages} onInputChange={() => handleCheckChange('topLanguages')} Options={<CustomizeOptions title="Customize Top Skills Card" CustomizationOptions={<CustomizeGithubStatsBase prefix="top-lang" options={topLanguagesOptions} onUpdate={onTopLangUpdate} />} />}>
display top skills
</AddonsItem>
<AddonsItem inputId="streak-stats" inputChecked={data.streakStats} onInputChange={() => handleCheckChange('streakStats')} Options={<CustomizeOptions title="Customize Streak Stats Card" CustomizationOptions={<CustomizeStreakStats prefix="streak-stats" options={streakStatsOptions} onUpdate={onStreakStatsUpdate} />} />}>
display github streak stats
</AddonsItem>
<AddonsItem inputId="twitter-badge" inputChecked={data.twitterBadge} onInputChange={() => handleCheckChange('twitterBadge')}>
display twitter badge
</AddonsItem>
<AddonsItem inputId="dev-dynamic-blogs" inputChecked={data.devDynamicBlogs} onInputChange={() => handleCheckChange('devDynamicBlogs')}>
display latest dev.to blogs dynamically (GitHub Action)
</AddonsItem>
<AddonsItem inputId="medium-dynamic-blogs" inputChecked={data.mediumDynamicBlogs} onInputChange={() => handleCheckChange('mediumDynamicBlogs')}>
display latest medium blogs dynamically (GitHub Action)
</AddonsItem>
<AddonsItem inputId="rss-dynamic-blogs" inputChecked={data.rssDynamicBlogs} onInputChange={() => handleCheckChange('rssDynamicBlogs')}>
display latest blogs from your personal blog dynamically (GitHub Action)
</AddonsItem>
{(data.devDynamicBlogs && social.dev) || (data.rssDynamicBlogs && social.rssurl) || (data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium)) ? (
<div className="workflow">
<div>
download
<span id="blog-post-worklow-span" onClick={blogPostPorkflow} onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()} role="button" tabIndex="0" style={{ cursor: 'pointer', color: '#002ead' }}>
{' '}
blog-post-workflow.yml
</span>{' '}
file(learn
<a href={withPrefix(links.addons)} target="blank" style={{ color: '#002ead' }}>
{' '}
how to setup
</a>
)
</div>
</div>
) : (
''
)}
</div>
);
};
export default Addons;
Addons.propTypes = {
data: PropTypes.object.isRequired,
social: PropTypes.object.isRequired,
handleDataChange: PropTypes.func.isRequired,
handleCheckChange: PropTypes.func.isRequired,
};
-87
View File
@@ -1,87 +0,0 @@
import React from "react"
const Donate = () => {
return (
<>
<div className="text-center text-4xl my-2">Support&nbsp;
<span role="img" aria-label="praying hand emoji">🙏</span>
</div>
<div className="flex flex-col sm:flex-row items-start justify-between">
<div className="w-full sm:w-2/3">
<div className="text-2xl mb-2">
Are you using the tool and happy with it to create your GitHub
Profile?
</div>
<div className="text-lg">
Your kind support keeps open-source tools like this free for others.
</div>
<div className="mt-4">
<a
className="flex items-center justify-start w-20"
href="https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator"
>
<img
className="w-20"
src="https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator"
alt="tweet github profile readme generator"
/>
</a>
Let the world know how you feel using this tool. Share with others
on twitter.
</div>
</div>
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center">
<span>Tip<span role="img" aria-label="Dollar medal">💰</span></span>
{/* Ko-Fi */}
<a
href="https://ko-fi.com/A0A81XXSX"
className="flex items-center justify-evenly bg-red-500 text-white py-2 px-4 my-2"
target="_blank"
rel="noreferrer"
>
<img
className="w-6 h-6 mr-2"
src="https://www.vectorlogo.zone/logos/ko-fi/ko-fi-icon.svg"
alt="Buy ko-fi for rahuldkjain"
/>
Buy me a ko-fi
</a>
{/* Paypal */}
<a
href="https://www.paypal.me/rahuldkjain/10"
className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid"
target="_blank"
rel="noreferrer"
>
<img
className="w-32 h-4"
src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg"
alt="Donate rahuldkjain via paypal"
/>
{/* <img
className="w-6 h-6 mr-2"
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg"
alt="Donate rahuldkjain via paypal"
/>
Paypal */}
</a>
{/* BuyMeACoffee */}
<a
href="https://www.buymeacoffee.com/rahuldkjain"
className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2"
target="_blank"
rel="noreferrer"
>
<img
className="w-6 h-6 mr-2"
src="https://www.vectorlogo.zone/logos/buymeacoffee/buymeacoffee-icon.svg"
alt="Buy rahuldkjain A Coffee"
/>
Buy me a coffee
</a>
</div>
</div>
</>
)
}
export default Donate
+54
View File
@@ -0,0 +1,54 @@
import React from 'react';
const Donate = () => (
<>
<div className="text-center text-4xl my-2">
Support&nbsp;
<span role="img" aria-label="praying hand emoji">
🙏
</span>
</div>
<div className="flex flex-col sm:flex-row items-start justify-between">
<div className="w-full sm:w-2/3">
<div className="text-2xl mb-2">Are you using the tool and happy with it to create your GitHub Profile?</div>
<div className="text-lg">Your kind support keeps open-source tools like this free for others.</div>
<div className="mt-4">
<a className="flex items-center justify-start w-20" href="https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator">
<img className="w-20" src="https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator" alt="tweet github profile readme generator" />
</a>
Let the world know how you feel using this tool. Share with others on twitter.
</div>
</div>
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center">
<span>
Tip
<span role="img" aria-label="Dollar medal">
💰
</span>
</span>
{/* Ko-Fi */}
<a href="https://ko-fi.com/A0A81XXSX" className="flex items-center justify-evenly bg-red-500 text-white py-2 px-4 my-2" target="_blank" rel="noreferrer">
<img className="w-6 h-6 mr-2" src="https://www.vectorlogo.zone/logos/ko-fi/ko-fi-icon.svg" alt="Buy ko-fi for rahuldkjain" />
Buy me a ko-fi
</a>
{/* Paypal */}
<a href="https://www.paypal.me/rahuldkjain/10" className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid" target="_blank" rel="noreferrer">
<img className="w-32 h-4" src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg" alt="Donate rahuldkjain via paypal" />
{/* <img
className="w-6 h-6 mr-2"
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg"
alt="Donate rahuldkjain via paypal"
/>
Paypal */}
</a>
{/* BuyMeACoffee */}
<a href="https://www.buymeacoffee.com/rahuldkjain" className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2" target="_blank" rel="noreferrer">
<img className="w-6 h-6 mr-2" src="https://www.vectorlogo.zone/logos/buymeacoffee/buymeacoffee-icon.svg" alt="Buy rahuldkjain A Coffee" />
Buy me a coffee
</a>
</div>
</div>
</>
);
export default Donate;
-120
View File
@@ -1,120 +0,0 @@
import React from "react"
import links from "../constants/page-links"
import logo from "../images/mdg.png"
import discord from "../images/Discord-Logo.png"
import { Link } from "gatsby"
const Footer = () => {
return (
<div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2">
<div className="w-full flex flex-col sm:flex-row justify-evenly py-2">
<div className="sm:ml-0 sm:mr-6 order-last sm:order-none flex">
<h1 className="text-base font-bold font-title text-xl sm:text-2xl mt-3 sm:mt-0">
<div className="flex sm:flex-col items-start mb-3 sm:mb-0">
<img
src={logo}
className="hidden sm:block h-24"
alt="github profile markdown generator logo"
/>
<div className="mr-2 sm:mr-0">
GitHub Profile{" "}
<img
src={logo}
className="inline sm:hidden h-12"
alt="github profile markdown generator logo"
/>
<span className="block sm:inline">README Generator</span>
</div>
</div>
</h1>
</div>
<div className="text-xl sm:text-base font-light sm:font-normal">
<div className="font-title font-bold mb-4 sm:mb-2">
<strong>Pages</strong>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.addons} activeStyle={{ color: "#002ead" }}>
Addons
</Link>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.support} activeStyle={{ color: "#002ead" }}>
Support
</Link>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.about} activeStyle={{ color: "#002ead" }}>
About
</Link>
</div>
</div>
<div className="text-xl sm:text-base font-light sm:font-normal">
<div className="font-title font-bold my-4 sm:my-0 sm:mb-2">
<strong>More</strong>
</div>
<div className="ml-2 sm:ml-0">
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator"
aria-label="Github rahuldkjain/github-profile-readme-generator"
target="blank"
>
Github
</a>
</div>
<div className="ml-2 sm:ml-0">
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator/releases"
aria-label="Releases on Github rahuldkjain/github-profile-readme-generator"
target="blank"
>
Releases
</a>
</div>
<div className="ml-2 sm:ml-0">
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator/issues"
aria-label="Issues in rahuldkjain/github-profile-readme-generator"
target="blank"
>
Issues
</a>
</div>
<div className="ml-2 sm:ml-0">
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator/pulls"
aria-label="Pull Requests in rahuldkjain/github-profile-readme-generator"
target="blank"
>
Pull Requests
</a>
</div>
</div>
<div>
<div className="font-title font-bold text-xl sm:text-base my-4 sm:my-0 sm:mb-2">
<strong>Join Community</strong>
</div>
<div className="ml-2 sm:ml-0">
<a
href="https://discord.gg/HHMs7Eg"
aria-label="Discord of the community"
target="blank"
>
<img
src={discord}
className="h-12"
alt="Discord of the community"
/>
</a>
</div>
</div>
</div>
<div className="py-2 mt-2">
Developed in India{" "}
<span role="img" aria-label="india">
{" "}
🇮🇳
</span>
</div>
</div>
)
}
export default Footer
+86
View File
@@ -0,0 +1,86 @@
import React from 'react';
import { Link } from 'gatsby';
import links from '../constants/page-links';
import logo from '../images/mdg.png';
import discord from '../images/Discord-Logo.png';
const Footer = () => (
<div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2">
<div className="w-full flex flex-col sm:flex-row justify-evenly py-2">
<div className="sm:ml-0 sm:mr-6 order-last sm:order-none flex">
<h1 className="text-base font-bold font-title text-xl sm:text-2xl mt-3 sm:mt-0">
<div className="flex sm:flex-col items-start mb-3 sm:mb-0">
<img src={logo} className="hidden sm:block h-24" alt="github profile markdown generator logo" />
<div className="mr-2 sm:mr-0">
GitHub Profile <img src={logo} className="inline sm:hidden h-12" alt="github profile markdown generator logo" />
<span className="block sm:inline">README Generator</span>
</div>
</div>
</h1>
</div>
<div className="text-xl sm:text-base font-light sm:font-normal">
<div className="font-title font-bold mb-4 sm:mb-2">
<strong>Pages</strong>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.addons} activeStyle={{ color: '#002ead' }}>
Addons
</Link>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.support} activeStyle={{ color: '#002ead' }}>
Support
</Link>
</div>
<div className="ml-2 sm:ml-0">
<Link to={links.about} activeStyle={{ color: '#002ead' }}>
About
</Link>
</div>
</div>
<div className="text-xl sm:text-base font-light sm:font-normal">
<div className="font-title font-bold my-4 sm:my-0 sm:mb-2">
<strong>More</strong>
</div>
<div className="ml-2 sm:ml-0">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator" aria-label="Github rahuldkjain/github-profile-readme-generator" target="blank">
Github
</a>
</div>
<div className="ml-2 sm:ml-0">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/releases" aria-label="Releases on Github rahuldkjain/github-profile-readme-generator" target="blank">
Releases
</a>
</div>
<div className="ml-2 sm:ml-0">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/issues" aria-label="Issues in rahuldkjain/github-profile-readme-generator" target="blank">
Issues
</a>
</div>
<div className="ml-2 sm:ml-0">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/pulls" aria-label="Pull Requests in rahuldkjain/github-profile-readme-generator" target="blank">
Pull Requests
</a>
</div>
</div>
<div>
<div className="font-title font-bold text-xl sm:text-base my-4 sm:my-0 sm:mb-2">
<strong>Join Community</strong>
</div>
<div className="ml-2 sm:ml-0">
<a href="https://discord.gg/HHMs7Eg" aria-label="Discord of the community" target="blank">
<img src={discord} className="h-12" alt="Discord of the community" />
</a>
</div>
</div>
</div>
<div className="py-2 mt-2">
Developed in India{' '}
<span role="img" aria-label="india">
{' '}
🇮🇳
</span>
</div>
</div>
);
export default Footer;
-105
View File
@@ -1,105 +0,0 @@
import React, { useEffect, useState } from "react"
import { StarIcon, RepoForkedIcon } from "@primer/octicons-react"
import logo from "../images/mdg.png"
import links from "../constants/page-links"
import gsap from "gsap"
import axios from "axios"
import { Link } from "gatsby"
import { act } from "react-dom/test-utils"
const Header = props => {
const shouldRequestStats = () => {
const isFirstRequest = stats.starsCount === 0
const isVisible = window.document.visibilityState === 'visible'
const hasFocus = window.document.hasFocus()
return isFirstRequest || isVisible && hasFocus
}
const fetchData = async () => {
if (shouldRequestStats()) {
var response = await axios.get(
"https://api.github.com/repos/rahuldkjain/github-profile-readme-generator"
)
const { stargazers_count, forks_count } = response.data
act(() =>
setstats({
starsCount: stargazers_count,
forksCount: forks_count,
})
)
}
}
const [stats, setstats] = useState({
starsCount: 0,
forksCount: 0,
})
useEffect(() => {
fetchData()
setInterval(fetchData, 60000)
gsap.set(".star, .fork", {
transformOrigin: "center",
})
gsap.to(".star, .fork", {
rotateZ: "360",
duration: 2,
ease: "elastic.inOut",
repeat: -1,
yoyo: true,
})
}, [])
return (
<div className="shadow flex items-center justify-center flex-col mb-2 py-2">
<Link to={links.home}>
<h1 className="text-base font-bold font-title sm:text-2xl font-medium text-blue-800 flex justify-center items-center flex-col">
<img
src={logo}
className="w-12 h-12"
alt="github profile markdown generator logo"
/>
<div>{props.heading}</div>
</h1>
</Link>
<div className="flex justify-center items-center">
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator"
aria-label="Star rahuldkjain/github-profile-readme-generator on GitHub"
target="blank"
className="mr-2"
>
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
<StarIcon size={16} id="star-icon" className="px-1 w-6 star" />
Star this repo
<span className="github-count px-1 sm:px-2">
{stats.starsCount}
</span>
</div>
</a>
<a
href="https://github.com/rahuldkjain/github-profile-readme-generator/fork"
aria-label="Fork rahuldkjain/github-profile-readme-generator on GitHub"
target="blank"
>
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
<RepoForkedIcon
size={16}
id="fork-icon"
className="px-1 w-6 fork"
/>
Fork on GitHub
<span className="github-count px-1 sm:px-2">
{stats.forksCount}
</span>
</div>
</a>
</div>
</div>
)
}
export default Header
+86
View File
@@ -0,0 +1,86 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { StarIcon, RepoForkedIcon } from '@primer/octicons-react';
import gsap from 'gsap';
import axios from 'axios';
import { Link } from 'gatsby';
import { act } from 'react-dom/test-utils';
import links from '../constants/page-links';
import logo from '../images/mdg.png';
const Header = (props) => {
const { heading } = props;
const [stats, setstats] = useState({
starsCount: 0,
forksCount: 0,
});
const shouldRequestStats = () => {
const isFirstRequest = stats.starsCount === 0;
const isVisible = window.document.visibilityState === 'visible';
const hasFocus = window.document.hasFocus();
return isFirstRequest || (isVisible && hasFocus);
};
const fetchData = async () => {
if (shouldRequestStats()) {
const response = await axios.get('https://api.github.com/repos/rahuldkjain/github-profile-readme-generator');
const { stargazers_count: stargazersCount, forks_count: forksCount } = response.data;
act(() =>
setstats({
starsCount: stargazersCount,
forksCount,
}),
);
}
};
useEffect(() => {
fetchData();
setInterval(fetchData, 60000);
gsap.set('.star, .fork', {
transformOrigin: 'center',
});
gsap.to('.star, .fork', {
rotateZ: '360',
duration: 2,
ease: 'elastic.inOut',
repeat: -1,
yoyo: true,
});
}, []);
return (
<div className="shadow flex items-center justify-center flex-col mb-2 py-2">
<Link to={links.home}>
<h1 className="text-base font-bold font-title sm:text-2xl font-medium text-blue-800 flex justify-center items-center flex-col">
<img src={logo} className="w-12 h-12" alt="github profile markdown generator logo" />
<div>{heading}</div>
</h1>
</Link>
<div className="flex justify-center items-center">
<a href="https://github.com/rahuldkjain/github-profile-readme-generator" aria-label="Star rahuldkjain/github-profile-readme-generator on GitHub" target="blank" className="mr-2">
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
<StarIcon size={16} id="star-icon" className="px-1 w-6 star" />
Star this repo
<span className="github-count px-1 sm:px-2">{stats.starsCount}</span>
</div>
</a>
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/fork" aria-label="Fork rahuldkjain/github-profile-readme-generator on GitHub" target="blank">
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
<RepoForkedIcon size={16} id="fork-icon" className="px-1 w-6 fork" />
Fork on GitHub
<span className="github-count px-1 sm:px-2">{stats.forksCount}</span>
</div>
</a>
</div>
</div>
);
};
export default Header;
Header.propTypes = {
heading: PropTypes.string.isRequired,
};
-18
View File
@@ -1,18 +0,0 @@
import React from "react"
import Header from "./header"
import Footer from "./footer"
const Layout = ({ children }) => {
return (
<div className="flex flex-col min-h-screen">
<header>
<Header heading="GitHub Profile README Generator" />
</header>
<main className="flex-grow">{children}</main>
<footer>
<Footer />
</footer>
</div>
)
}
export default Layout
+25
View File
@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import Header from './header';
import Footer from './footer';
const Layout = ({ children }) => (
<div className="flex flex-col min-h-screen">
<header>
<Header heading="GitHub Profile README Generator" />
</header>
<main className="flex-grow">{children}</main>
<footer>
<Footer />
</footer>
</div>
);
export default Layout;
Layout.defaultProps = {
children: '',
};
Layout.propTypes = {
children: PropTypes.element,
};
-49
View File
@@ -1,49 +0,0 @@
import React, { useRef, useEffect } from "react"
import gsap from "gsap"
const Loader = () => {
let arrow = useRef([])
useEffect(() => {
var tl = new gsap.timeline({ repeat: -1 })
tl.fromTo(
arrow.current,
{
y: 0,
color: "#3b3b4f",
},
{
y: -50,
color: "#d0d0d5",
stagger: 0.1,
duration: 0.5,
ease: "Linear.easeNone",
}
)
tl.add("cp")
tl.fromTo(
arrow.current,
{
y: -50,
color: "#d0d0d5",
},
{
y: 0,
color: "#3b3b4f",
stagger: 0.1,
duration: 0.5,
ease: "Linear.easeNone",
},
"cp-=0.3"
)
})
return (
<div className="loader">
<span ref={el => (arrow.current[0] = el)}></span>
<span ref={el => (arrow.current[1] = el)}></span>
<span ref={el => (arrow.current[2] = el)}></span>
<span ref={el => (arrow.current[3] = el)}></span>
<span ref={el => (arrow.current[4] = el)}></span>
</div>
)
}
export default Loader
+80
View File
@@ -0,0 +1,80 @@
import React, { useRef, useEffect } from 'react';
import gsap from 'gsap';
const Loader = () => {
const arrow = useRef([]);
useEffect(() => {
const tl = gsap.timeline({ repeat: -1 });
tl.fromTo(
arrow.current,
{
y: 0,
color: '#3b3b4f',
},
{
y: -50,
color: '#d0d0d5',
stagger: 0.1,
duration: 0.5,
ease: 'Linear.easeNone',
},
);
tl.add('cp');
tl.fromTo(
arrow.current,
{
y: -50,
color: '#d0d0d5',
},
{
y: 0,
color: '#3b3b4f',
stagger: 0.1,
duration: 0.5,
ease: 'Linear.easeNone',
},
'cp-=0.3',
);
});
return (
<div className="loader">
<span
ref={(el) => {
arrow.current[0] = el;
}}
>
</span>
<span
ref={(el) => {
arrow.current[1] = el;
}}
>
</span>
<span
ref={(el) => {
arrow.current[2] = el;
}}
>
</span>
<span
ref={(el) => {
arrow.current[3] = el;
}}
>
</span>
<span
ref={(el) => {
arrow.current[4] = el;
}}
>
</span>
</div>
);
};
export default Loader;
-579
View File
@@ -1,579 +0,0 @@
import React from "react"
import { isMediumUsernameValid } from "../utils/validation"
import { icons, skills, skillWebsites } from "../constants/skills"
import {
githubStatsLinkGenerator,
topLanguagesLinkGenerator,
streakStatsLinkGenerator,
} from "../utils/link-generators"
const Title = props => {
if (props.prefix && props.title) {
return (
<>
{`<h1 align="center">${props.prefix + " " + props.title}</h1>`}
<br />
</>
)
}
return ""
}
const SubTitle = props => {
if (props.subtitle) {
return (
<>
{`<h3 align="center">${props.subtitle}</h3>`}
<br />
<br />
</>
)
}
return ""
}
const SectionTitle = props => {
if (props.label) {
return (
<>
{`<h3 align="left">${props.label}</h3>`}
<br />
</>
)
}
return ""
}
const DisplayWork = props => {
if (props.prefix && props.project) {
if (props.link) {
return (
<>
{`- ${props.prefix} [${props.project}](${props.link})`}
<br />
<br />
</>
)
} else {
return (
<>
{`- ${props.prefix} **${props.project}**`}
<br />
<br />
</>
)
}
}
if (props.prefix && props.link) {
return (
<>
{`- ${props.prefix} [${props.link}](${props.link})`}
<br />
<br />
</>
)
}
return ""
}
const DisplaySocial = props => {
if (props.username) {
return (
<>
{`<a href="${props.base}/${props.username}" target="blank"><img align="center" src="${props.icon}" alt="${props.username}" height="30" width="40" /></a>`}
<br />
</>
)
}
return ""
}
const VisitorsBadge = props => {
let link =
"https://komarev.com/ghpvc/?username=" +
props.github +
`&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}`
if (props.show) {
return (
<>
{`<p align="left"> <img src="${link}" alt="${props.github}" /> </p>`}
<br />
<br />
</>
)
}
return ""
}
const TwitterBadge = props => {
let link =
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) {
return (
<>
{`<p align="left"> <a href="${props.base}/${props.twitter}" target="blank"><img src="${link}" alt="${props.twitter}" /></a> </p>`}
<br />
<br />
</>
)
}
return ""
}
const GithubProfileTrophy = props => {
let link =
"https://github-profile-trophy.vercel.app/?username=" + props.github
if (props.show) {
return (
<>
{`<p align="left"> <a href="https://github.com/ryo-ma/github-profile-trophy"><img src="${link}" alt="${props.github}" /></a> </p>`}
<br />
<br />
</>
)
}
return ""
}
const GitHubStats = ({ show, github, options }) => {
if (show) {
return (
<>
{`<p>&nbsp;<img align="center" src="${githubStatsLinkGenerator({
github: github,
options,
})}" alt="${github}" /></p>`}
<br />
<br />
</>
)
}
return ""
}
const isSocial = social => {
return (
social.dev ||
social.twitter ||
social.codepen ||
social.codesandbox ||
social.stackoverflow ||
social.linkedin ||
social.kaggle ||
social.instagram ||
social.fb ||
social.dribbble ||
social.behance ||
social.medium ||
social.youtube ||
social.codechef ||
social.hackerrank ||
social.codeforces ||
social.leetcode ||
social.topcoder ||
social.hackerearth ||
social.geeks_for_geeks ||
social.discord ||
social.rssurl
)
}
const DisplaySkills = props => {
const listChosenSkills = []
skills.forEach(skill => {
if (props.skills[skill]) {
listChosenSkills.push(
`
<a href="${skillWebsites[skill]}" target="_blank">
<img src="${icons[skill]}" alt="${skill}" width="40" height="40"/>
</a>
`
)
}
})
return listChosenSkills.length > 0 ? (
<>
<SectionTitle label="Languages and Tools:" />
{`<p align="left">${listChosenSkills.join(" ")}</p>`}
<br />
<br />
</>
) : (
""
)
}
const DisplayDynamicBlogs = props => {
if (props.show) {
return (
<>
{`### Blogs posts`}
<br />
{`<!-- BLOG-POST-LIST:START -->`}
<br />
{`<!-- BLOG-POST-LIST:END -->`}
<br /> <br />
</>
)
}
return ""
}
const DisplayTopLanguages = props => {
if (props.show) {
if (!props.showStats) {
return (
<>
{`<p><img align="center" src="${topLanguagesLinkGenerator({
github: props.github,
options: props.options,
})}" alt="${props.github}" /></p>`}
<br />
<br />
</>
)
}
return (
<>
{`<p><img align="left" src="${topLanguagesLinkGenerator({
github: props.github,
options: props.options,
})}" alt="${props.github}" /></p>`}
<br />
<br />
</>
)
}
return ""
}
const DisplayStreakStats = props => {
if (props.show) {
return (
<>
{`<p><img align="center" src="${streakStatsLinkGenerator({
github: props.github,
options: props.options,
})}" alt="${props.github}" /></p>`}
<br />
<br />
</>
)
}
return ""
}
const DisplaySupport = props => {
let viewSupport = false
Object.keys(props.support).forEach(key => {
if (props.support[key]) {
viewSupport = true
}
})
return viewSupport ? (
<div>
<SectionTitle label="Support:" />
{`<p>`}
{props.support.buyMeACoffee &&
`<a href="https://www.buymeacoffee.com/${props.support.buyMeACoffee}">
<img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="${props.support.buyMeACoffee}" /></a>`}
{`</p><br><br>`}
<br />
<br />
</div>
) : (
""
)
}
const Markdown = props => {
const icon_base_url =
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/neutral-icons/src/images/icons/Social/";
return (
<div id="markdown-content" className="break-words">
<>
<Title prefix={props.prefix.title} title={props.data.title} />
</>
<>
<SubTitle subtitle={props.data.subtitle} />
</>
<>
<VisitorsBadge
show={props.data.visitorsBadge}
github={props.social.github}
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle,
}}
/>
</>
<>
<GithubProfileTrophy
show={props.data.githubProfileTrophy}
github={props.social.github}
/>
<TwitterBadge
base="https://twitter.com"
show={props.data.twitterBadge}
twitter={props.social.twitter}
/>
</>
<>
<DisplayWork
prefix={props.prefix.currentWork}
project={props.data.currentWork}
link={props.link.currentWork}
/>
</>
<>
<DisplayWork
prefix={props.prefix.currentLearn}
project={props.data.currentLearn}
/>
</>
<>
<DisplayWork
prefix={props.prefix.collaborateOn}
project={props.data.collaborateOn}
link={props.link.collaborateOn}
/>
</>
<>
<DisplayWork
prefix={props.prefix.helpWith}
project={props.data.helpWith}
link={props.link.helpWith}
/>
</>
<>
<DisplayWork
prefix={props.prefix.portfolio}
link={props.link.portfolio}
/>
</>
<>
<DisplayWork prefix={props.prefix.blog} link={props.link.blog} />
</>
<>
<DisplayWork prefix={props.prefix.ama} project={props.data.ama} />
</>
<>
<DisplayWork
prefix={props.prefix.contact}
project={props.data.contact}
/>
</>
<>
<DisplayWork prefix={props.prefix.resume} link={props.link.resume} />
</>
<>
<DisplayWork
prefix={props.prefix.funFact}
project={props.data.funFact}
/>
</>
<>
<DisplayDynamicBlogs
show={
(props.data.devDynamicBlogs && props.social.dev) ||
(props.data.rssDynamicBlogs && props.social.rssurl) ||
(props.data.mediumDynamicBlogs &&
props.social.medium &&
isMediumUsernameValid(props.social.medium))
}
/>
</>
{isSocial(props.social) ? (
<>
<SectionTitle label="Connect with me:" />
{`<p align="left">`}
</>
) : (
""
)}
<br />
<>
<DisplaySocial
base="https://codepen.io"
icon={icon_base_url + "codepen.svg"}
username={props.social.codepen}
/>
</>
<>
<DisplaySocial
base="https://dev.to"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
username={props.social.dev}
/>
</>
<>
<DisplaySocial
base="https://twitter.com"
icon={icon_base_url + "twitter.svg"}
username={props.social.twitter}
/>
</>
<>
<DisplaySocial
base="https://linkedin.com/in"
icon={icon_base_url + "linked-in-alt.svg"}
username={props.social.linkedin}
/>
</>
<>
<DisplaySocial
base="https://stackoverflow.com/users"
icon={icon_base_url + "stack-overflow.svg"}
username={props.social.stackoverflow}
/>
</>
<>
<DisplaySocial
base="https://codesandbox.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
username={props.social.codesandbox}
/>
</>
<>
<DisplaySocial
base="https://kaggle.com"
icon={icon_base_url + "kaggle.svg"}
username={props.social.kaggle}
/>
</>
<>
<DisplaySocial
base="https://fb.com"
icon={icon_base_url + "facebook.svg"}
username={props.social.fb}
/>
</>
<>
<DisplaySocial
base="https://instagram.com"
icon={icon_base_url + "instagram.svg"}
username={props.social.instagram}
/>
</>
<>
<DisplaySocial
base="https://dribbble.com"
icon={icon_base_url + "dribbble.svg"}
username={props.social.dribbble}
/>
</>
<>
<DisplaySocial
base="https://www.behance.net"
icon={icon_base_url + "behance.svg"}
username={props.social.behance}
/>
</>
<>
<DisplaySocial
base="https://medium.com"
icon={icon_base_url + "medium.svg"}
username={props.social.medium}
/>
</>
<>
<DisplaySocial
base="https://www.youtube.com/c"
icon={icon_base_url + "youtube.svg"}
username={props.social.youtube}
/>
</>
<>
<DisplaySocial
base="https://www.codechef.com/users"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
username={props.social.codechef}
/>
</>
<>
<DisplaySocial
base="https://www.hackerrank.com"
icon={icon_base_url + "hackerrank.svg"}
username={props.social.hackerrank}
/>
</>
<>
<DisplaySocial
base="https://codeforces.com/profile"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
username={props.social.codeforces}
/>
</>
<>
<DisplaySocial
base="https://www.leetcode.com"
icon={icon_base_url+"leet-code.svg"}
username={props.social.leetcode}
/>
</>
<>
<DisplaySocial
base="https://www.hackerearth.com"
icon={icon_base_url+"hackerearth.svg"}
username={props.social.hackerearth}
/>
</>
<>
<DisplaySocial
base="https://auth.geeksforgeeks.org/user"
icon={icon_base_url + "geeks-for-geeks.svg"}
username={props.social.geeks_for_geeks}
/>
</>
<>
<DisplaySocial
base="https://www.topcoder.com/members"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
username={props.social.topcoder}
/>
</>
<>
<DisplaySocial
base="https://discord.gg"
icon={icon_base_url + "discord.svg"}
username={props.social.discord}
/>
</>
<>
<DisplaySocial
base=""
icon={icon_base_url + "rss.svg"}
username={props.social.rssurl}
/>
</>
{isSocial(props.social) ? (
<>
{`</p>`}
<br />
<br />
</>
) : (
""
)}
<>
<DisplaySkills skills={props.skills} />
</>
<>
<DisplaySupport support={props.support} />
</>
<>
<DisplayTopLanguages
show={props.data.topLanguages}
showStats={props.data.githubStats}
github={props.social.github}
options={props.data.topLanguagesOptions}
/>
</>
<>
<GitHubStats
show={props.data.githubStats}
github={props.social.github}
options={props.data.githubStatsOptions}
/>
</>
<>
<DisplayStreakStats
show={props.data.streakStats}
github={props.social.github}
options={props.data.streakStatsOptions}
/>
</>
</div>
)
}
export default Markdown
+685
View File
@@ -0,0 +1,685 @@
import React from 'react';
import PropTypes from 'prop-types';
import { isMediumUsernameValid } from '../utils/validation';
import { icons, skills as SKILLS, skillWebsites } from '../constants/skills';
import { githubStatsLinkGenerator, topLanguagesLinkGenerator, streakStatsLinkGenerator } from '../utils/link-generators';
import { DEFAULT_DATA, DEFAULT_LINK, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
const Title = (props) => {
const { prefix, title } = props;
if (prefix && title) {
return (
<>
{`<h1 align="center">${`${prefix} ${title}`}</h1>`}
<br />
</>
);
}
return '';
};
Title.propTypes = {
prefix: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};
const SubTitle = (props) => {
const { subtitle } = props;
if (subtitle) {
return (
<>
{`<h3 align="center">${subtitle}</h3>`}
<br />
<br />
</>
);
}
return '';
};
SubTitle.propTypes = {
subtitle: PropTypes.string.isRequired,
};
const SectionTitle = (props) => {
const { label } = props;
if (label) {
return (
<>
{`<h3 align="left">${label}</h3>`}
<br />
</>
);
}
return '';
};
SectionTitle.propTypes = {
label: PropTypes.string.isRequired,
};
const DisplayWork = (props) => {
const { prefix, project, link } = props;
if (prefix && project) {
if (link) {
return (
<>
{`- ${prefix} [${project}](${link})`}
<br />
<br />
</>
);
}
return (
<>
{`- ${prefix} **${project}**`}
<br />
<br />
</>
);
}
if (prefix && link) {
return (
<>
{`- ${prefix} [${link}](${link})`}
<br />
<br />
</>
);
}
return '';
};
DisplayWork.defaultProps = {
prefix: '',
project: '',
link: '',
};
DisplayWork.propTypes = {
prefix: PropTypes.string,
project: PropTypes.string,
link: PropTypes.string,
};
const DisplaySocial = (props) => {
const { username, base, icon } = props;
if (username) {
return (
<>
{`<a href="${base}/${username}" target="blank"><img align="center" src="${icon}" alt="${username}" height="30" width="40" /></a>`}
<br />
</>
);
}
return '';
};
DisplaySocial.propTypes = {
username: PropTypes.string.isRequired,
base: PropTypes.string.isRequired,
icon: PropTypes.string.isRequired,
};
const VisitorsBadge = (props) => {
const { github, badgeOptions, show } = props;
const link = `https://komarev.com/ghpvc/?username=${github}&label=${badgeOptions.badgeLabel}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`;
if (show) {
return (
<>
{`<p align="left"> <img src="${link}" alt="${github}" /> </p>`}
<br />
<br />
</>
);
}
return '';
};
VisitorsBadge.defaultProps = {
badgeOptions: {
badgeLabel: '',
badgeColor: '',
badgeStyle: '',
},
};
VisitorsBadge.propTypes = {
github: PropTypes.string.isRequired,
badgeOptions: {
badgeLabel: PropTypes.string.isRequired,
badgeColor: PropTypes.string.isRequired,
badgeStyle: PropTypes.string.isRequired,
},
show: PropTypes.bool.isRequired,
};
const TwitterBadge = (props) => {
const { twitter, show, base } = props;
const link = `https://img.shields.io/twitter/follow/${twitter}?logo=twitter&style=for-the-badge`;
if (show) {
return (
<>
{`<p align="left"> <a href="${base}/${twitter}" target="blank"><img src="${link}" alt="${twitter}" /></a> </p>`}
<br />
<br />
</>
);
}
return '';
};
TwitterBadge.propTypes = {
twitter: PropTypes.string.isRequired,
base: PropTypes.string.isRequired,
show: PropTypes.bool.isRequired,
};
const GithubProfileTrophy = (props) => {
const { show, github } = props;
const link = `https://github-profile-trophy.vercel.app/?username=${github}`;
if (show) {
return (
<>
{`<p align="left"> <a href="https://github.com/ryo-ma/github-profile-trophy"><img src="${link}" alt="${github}" /></a> </p>`}
<br />
<br />
</>
);
}
return '';
};
GithubProfileTrophy.propTypes = {
github: PropTypes.string.isRequired,
show: PropTypes.bool.isRequired,
};
const GitHubStats = (props) => {
const { show, github, options } = props;
if (show) {
return (
<>
{`<p>&nbsp;<img align="center" src="${githubStatsLinkGenerator({
github,
options,
})}" alt="${github}" /></p>`}
<br />
<br />
</>
);
}
return '';
};
GitHubStats.defaultProps = {
options: {
theme: '',
titleColor: '',
textColor: '',
bgColor: '',
hideBorder: '',
cacheSeconds: 0,
locale: '',
},
};
GitHubStats.propTypes = {
github: PropTypes.string.isRequired,
options: {
theme: PropTypes.string,
titleColor: PropTypes.string,
textColor: PropTypes.string,
bgColor: PropTypes.string,
hideBorder: PropTypes.string,
cacheSeconds: PropTypes.number,
locale: PropTypes.string,
},
show: PropTypes.bool.isRequired,
};
const isSocial = (social) => {
let status = false;
const SOCIAL_KEYS = Object.keys(DEFAULT_SOCIAL);
Object.keys(social).forEach((key) => {
if (SOCIAL_KEYS.includes(key)) {
status = true;
}
});
return status;
};
const DisplaySkills = (props) => {
const { skills } = props;
const listChosenSkills = [];
SKILLS.forEach((skill) => {
if (skills[skill]) {
listChosenSkills.push(
`
<a href="${skillWebsites[skill]}" target="_blank" rel="noreferrer">
<img src="${icons[skill]}" alt="${skill}" width="40" height="40"/>
</a>
`,
);
}
});
return listChosenSkills.length > 0 ? (
<>
<SectionTitle label="Languages and Tools:" />
{`<p align="left">${listChosenSkills.join(' ')}</p>`}
<br />
<br />
</>
) : (
''
);
};
DisplaySkills.defaultProps = {
skills: [],
};
DisplaySkills.propTypes = {
skills: [],
};
const DisplayDynamicBlogs = (props) => {
const { show } = props;
if (show) {
return (
<>
### Blogs posts
<br />
{'<!-- BLOG-POST-LIST:START -->'}
<br />
{'<!-- BLOG-POST-LIST:END -->'}
<br />
<br />
</>
);
}
return '';
};
DisplayDynamicBlogs.defaultProps = {
show: false,
};
DisplayDynamicBlogs.propTypes = {
show: PropTypes.bool,
};
const DisplayTopLanguages = (props) => {
const { show, showStats, github, options } = props;
if (show) {
if (!showStats) {
return (
<>
{`<p><img align="center" src="${topLanguagesLinkGenerator({
github,
options,
})}" alt="${github}" /></p>`}
<br />
<br />
</>
);
}
return (
<>
{`<p><img align="left" src="${topLanguagesLinkGenerator({
github,
options,
})}" alt="${github}" /></p>`}
<br />
<br />
</>
);
}
return '';
};
DisplayTopLanguages.defaultProps = {
options: {
theme: '',
titleColor: '',
textColor: '',
bgColor: '',
hideBorder: '',
cacheSeconds: '',
locale: '',
},
};
DisplayTopLanguages.propTypes = {
github: PropTypes.string.isRequired,
options: {
theme: PropTypes.string,
titleColor: PropTypes.string,
textColor: PropTypes.string,
bgColor: PropTypes.string,
hideBorder: PropTypes.string,
cacheSeconds: PropTypes.number,
locale: PropTypes.string,
},
show: PropTypes.bool.isRequired,
showStats: PropTypes.bool.isRequired,
};
const DisplayStreakStats = (props) => {
const { show, github, options } = props;
if (show) {
return (
<>
{`<p><img align="center" src="${streakStatsLinkGenerator({
github,
options,
})}" alt="${github}" /></p>`}
<br />
<br />
</>
);
}
return '';
};
DisplayStreakStats.defaultProps = {
options: {
theme: '',
titleColor: '',
textColor: '',
bgColor: '',
hideBorder: '',
cacheSeconds: '',
locale: '',
},
};
DisplayStreakStats.propTypes = {
github: PropTypes.string.isRequired,
options: {
theme: PropTypes.string,
titleColor: PropTypes.string,
textColor: PropTypes.string,
bgColor: PropTypes.string,
hideBorder: PropTypes.string,
cacheSeconds: PropTypes.number,
locale: PropTypes.string,
},
show: PropTypes.bool.isRequired,
};
const DisplaySupport = (props) => {
const { support } = props;
let viewSupport = false;
Object.keys(support).forEach((key) => {
if (support[key]) {
viewSupport = true;
}
});
return viewSupport ? (
<div>
<SectionTitle label="Support:" />
{'<p>'}
{support.buyMeACoffee &&
`<a href="https://www.buymeacoffee.com/${support.buyMeACoffee}">
<img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="${support.buyMeACoffee}" /></a>`}
{support.buyMeAKofi &&
`<a href="https://ko-fi.com/${support.buyMeAKofi}">
<img align="left" src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" height="50" width="210" alt="${support.buyMeAKofi}" /></a>`}
{'</p><br><br>'}
<br />
<br />
</div>
) : (
''
);
};
DisplaySupport.defaultProps = {
support: {
buyMeACoffee: '',
buyMeAKofi: '',
},
};
DisplaySupport.propTypes = {
support: {
buyMeACoffee: PropTypes.string,
buyMeAKofi: PropTypes.string,
},
};
const Markdown = (props) => {
const { prefix, data, link, social, skills, support } = props;
const iconBaseUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
return (
<div id="markdown-content" className="break-words">
<>
<Title prefix={prefix.title} title={data.title} />
</>
<>
<SubTitle subtitle={data.subtitle} />
</>
<>
<VisitorsBadge
show={data.visitorsBadge}
github={social.github}
badgeOptions={{
badgeLabel: encodeURI(data.badgeLabel),
badgeColor: data.badgeColor,
badgeStyle: data.badgeStyle,
}}
/>
</>
<>
<GithubProfileTrophy show={data.githubProfileTrophy} github={social.github} />
<TwitterBadge base="https://twitter.com" show={data.twitterBadge} twitter={social.twitter} />
</>
<>
<DisplayWork prefix={prefix.currentWork} project={data.currentWork} link={link.currentWork} />
</>
<>
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
</>
<>
<DisplayWork prefix={prefix.collaborateOn} project={data.collaborateOn} link={link.collaborateOn} />
</>
<>
<DisplayWork prefix={prefix.helpWith} project={data.helpWith} link={link.helpWith} />
</>
<>
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
</>
<>
<DisplayWork prefix={prefix.blog} link={link.blog} />
</>
<>
<DisplayWork prefix={prefix.ama} project={data.ama} />
</>
<>
<DisplayWork prefix={prefix.contact} project={data.contact} />
</>
<>
<DisplayWork prefix={prefix.resume} link={link.resume} />
</>
<>
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
</>
<>
<DisplayDynamicBlogs show={(data.devDynamicBlogs && social.dev) || (data.rssDynamicBlogs && social.rssurl) || (data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium))} />
</>
{isSocial(social) ? (
<>
<SectionTitle label="Connect with me:" />
{'<p align="left">'}
</>
) : (
''
)}
<br />
<>
<DisplaySocial base="https://codepen.io" icon={`${iconBaseUrl}codepen.svg`} username={social.codepen} />
</>
<>
<DisplaySocial base="https://dev.to" icon={`${iconBaseUrl}devto.svg`} username={social.dev} />
</>
<>
<DisplaySocial base="https://twitter.com" icon={`${iconBaseUrl}twitter.svg`} username={social.twitter} />
</>
<>
<DisplaySocial base="https://linkedin.com/in" icon={`${iconBaseUrl}linked-in-alt.svg`} username={social.linkedin} />
</>
<>
<DisplaySocial base="https://stackoverflow.com/users" icon={`${iconBaseUrl}stack-overflow.svg`} username={social.stackoverflow} />
</>
<>
<DisplaySocial base="https://codesandbox.com" icon={`${iconBaseUrl}codesandbox.svg`} username={social.codesandbox} />
</>
<>
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
</>
<>
<DisplaySocial base="https://fb.com" icon={`${iconBaseUrl}facebook.svg`} username={social.fb} />
</>
<>
<DisplaySocial base="https://instagram.com" icon={`${iconBaseUrl}instagram.svg`} username={social.instagram} />
</>
<>
<DisplaySocial base="https://dribbble.com" icon={`${iconBaseUrl}dribbble.svg`} username={social.dribbble} />
</>
<>
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
</>
<>
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
</>
<>
<DisplaySocial base="https://www.youtube.com/c" icon={`${iconBaseUrl}youtube.svg`} username={social.youtube} />
</>
<>
<DisplaySocial base="https://www.codechef.com/users" icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" username={social.codechef} />
</>
<>
<DisplaySocial base="https://www.hackerrank.com" icon={`${iconBaseUrl}hackerrank.svg`} username={social.hackerrank} />
</>
<>
<DisplaySocial base="https://codeforces.com/profile" icon={`${iconBaseUrl}codeforces.svg`} username={social.codeforces} />
</>
<>
<DisplaySocial base="https://www.leetcode.com" icon={`${iconBaseUrl}leet-code.svg`} username={social.leetcode} />
</>
<>
<DisplaySocial base="https://www.hackerearth.com" icon={`${iconBaseUrl}hackerearth.svg`} username={social.hackerearth} />
</>
<>
<DisplaySocial base="https://auth.geeksforgeeks.org/user" icon={`${iconBaseUrl}geeks-for-geeks.svg`} username={social.geeks_for_geeks} />
</>
<>
<DisplaySocial base="https://www.topcoder.com/members" icon={`${iconBaseUrl}topcoder.svg`} username={social.topcoder} />
</>
<>
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
</>
<>
<DisplaySocial base="" icon={`${iconBaseUrl}rss.svg`} username={social.rssurl} />
</>
{isSocial(social) ? (
<>
{'</p>'}
<br />
<br />
</>
) : (
''
)}
<>
<DisplaySkills skills={skills} />
</>
<>
<DisplaySupport support={support} />
</>
<>
<DisplayTopLanguages show={data.topLanguages} showStats={data.githubStats} github={social.github} options={data.topLanguagesOptions} />
</>
<>
<GitHubStats show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
</>
<>
<DisplayStreakStats show={data.streakStats} github={social.github} options={data.streakStatsOptions} />
</>
</div>
);
};
export default Markdown;
Markdown.defaultProps = {
prefix: DEFAULT_PREFIX,
data: DEFAULT_DATA,
link: DEFAULT_LINK,
social: DEFAULT_SOCIAL,
support: DEFAULT_SUPPORT,
skills: [],
};
Markdown.propTypes = {
prefix: {
title: PropTypes.string,
currentWork: PropTypes.string,
currentLearn: PropTypes.string,
collaborateOn: PropTypes.string,
helpWith: PropTypes.string,
ama: PropTypes.string,
contact: PropTypes.string,
resume: PropTypes.string,
funFact: PropTypes.string,
portfolio: PropTypes.string,
blog: PropTypes.string,
},
data: {
title: PropTypes.string,
subtitle: PropTypes.string,
currentWork: PropTypes.string,
currentLearn: PropTypes.string,
collaborateOn: PropTypes.string,
helpWith: PropTypes.string,
ama: PropTypes.string,
contact: PropTypes.string,
funFact: PropTypes.string,
twitterBadge: false,
visitorsBadge: false,
badgeStyle: PropTypes.string,
badgeColor: PropTypes.string,
badgeLabel: PropTypes.string,
githubProfileTrophy: false,
githubStats: false,
githubStatsOptions: {
theme: PropTypes.string,
titleColor: PropTypes.string,
textColor: PropTypes.string,
bgColor: PropTypes.string,
hideBorder: false,
cacheSeconds: null,
locale: PropTypes.string,
},
topLanguages: false,
topLanguagesOptions: {
theme: PropTypes.string,
titleColor: PropTypes.string,
textColor: PropTypes.string,
bgColor: PropTypes.string,
hideBorder: false,
cacheSeconds: null,
locale: PropTypes.string,
},
streakStats: false,
streakStatsOptions: {
theme: PropTypes.string,
},
devDynamicBlogs: false,
mediumDynamicBlogs: false,
rssDynamicBlogs: false,
},
link: {},
social: {},
skills: {},
support: {},
};
-484
View File
@@ -1,484 +0,0 @@
import React from "react"
import { icons, skills, skillWebsites } from "../constants/skills"
import {
githubStatsLinkGenerator,
topLanguagesLinkGenerator,
streakStatsLinkGenerator,
} from "../utils/link-generators"
export const TitlePreview = props => {
if (props.prefix && props.title) {
return (
<h1 className="text-center text-xl font-bold">
{props.prefix + " " + props.title}
</h1>
)
}
return null
}
export const SubTitlePreview = props => {
if (props.subtitle) {
return <h3 className="text-center font-medium">{props.subtitle}</h3>
}
return null
}
export const SectionTitle = props => {
if (!props.visible) return null
else if (props.label) {
return <h3 className="w-full text-lg sm:text-xl">{props.label}</h3>
}
return null
}
export const DisplayWork = props => {
if (props.prefix && props.project) {
if (props.link) {
return (
<div className="my-2">
{props.prefix + " "}
<a
href={props.link}
className="no-underline text-blue-700"
target="blank"
>
{props.project}
</a>
</div>
)
} else {
return (
<div className="my-2">
{props.prefix + " "}
<b>{props.project}</b>
</div>
)
}
}
if (props.prefix && props.link) {
return (
<div className="my-2">
{props.prefix + " "}
<a
href={props.link}
className="no-underline text-blue-700"
target="blank"
>
{props.link}
</a>
</div>
)
}
return null
}
export const WorkPreview = props => {
const prefix = props.work.prefix
const data = props.work.data
const link = props.work.link
return (
<>
<DisplayWork
prefix={prefix.currentWork}
project={data.currentWork}
link={link.currentWork}
/>
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
<DisplayWork
prefix={prefix.helpWith}
project={data.helpWith}
link={link.helpWith}
/>
<DisplayWork
prefix={prefix.collaborateOn}
project={data.collaborateOn}
link={link.collaborateOn}
/>
<DisplayWork prefix={prefix.ama} project={data.ama} />
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
<DisplayWork prefix={prefix.blog} link={link.blog} />
<DisplayWork prefix={prefix.resume} link={link.resume} />
<DisplayWork prefix={prefix.contact} project={data.contact} />
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
</>
)
}
export const DisplaySocial = props => {
if (props.username) {
return (
<a
className="no-underline text-blue-700 m-2"
href={props.base + "/" + props.username}
target="blank"
>
<img className="w-6 h-6" src={props.icon} alt="props.username" />
</a>
)
}
return null
}
export const SocialPreview = props => {
let viewSocial = false
const icon_base_url =
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/neutral-icons/src/images/icons/Social/";
Object.keys(props.social).forEach(key => {
if (props.social[key] && key != "github") viewSocial = true
})
return (
<div className="flex justify-start items-end flex-wrap">
<SectionTitle label="Connect with me:" visible={viewSocial} />
<>
<DisplaySocial
base="https://codepen.io"
icon={icon_base_url + "codepen.svg"}
username={props.social.codepen}
/>
</>
<>
<DisplaySocial
base="https://dev.to"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
username={props.social.dev}
/>
</>
<>
<DisplaySocial
base="https://twitter.com"
icon={icon_base_url + "twitter.svg"}
username={props.social.twitter}
/>
</>
<>
<DisplaySocial
base="https://linkedin.com/in"
icon={icon_base_url + "linked-in-alt.svg"}
username={props.social.linkedin}
/>
</>
<>
<DisplaySocial
base="https://stackoverflow.com/users"
icon={icon_base_url + "stack-overflow.svg"}
username={props.social.stackoverflow}
/>
</>
<>
<DisplaySocial
base="https://codesandbox.com"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
username={props.social.codesandbox}
/>
</>
<>
<DisplaySocial
base="https://kaggle.com"
icon={icon_base_url + "kaggle.svg"}
username={props.social.kaggle}
/>
</>
<>
<DisplaySocial
base="https://fb.com"
icon={icon_base_url + "facebook.svg"}
username={props.social.fb}
/>
</>
<>
<DisplaySocial
base="https://instagram.com"
icon={icon_base_url + "instagram.svg"}
username={props.social.instagram}
/>
</>
<>
<DisplaySocial
base="https://dribbble.com"
icon={icon_base_url + "dribbble.svg"}
username={props.social.dribbble}
/>
</>
<>
<DisplaySocial
base="https://www.behance.net"
icon={icon_base_url + "behance.svg"}
username={props.social.behance}
/>
</>
<>
<DisplaySocial
base="https://medium.com"
icon={icon_base_url + "medium.svg"}
username={props.social.medium}
/>
</>
<>
<DisplaySocial
base="https://www.youtube.com/c"
icon={icon_base_url + "youtube.svg"}
username={props.social.youtube}
/>
</>
<>
<DisplaySocial
base="https://www.codechef.com/users"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
username={props.social.codechef}
/>
</>
<>
<DisplaySocial
base="https://www.hackerrank.com"
icon={icon_base_url + "hackerrank.svg"}
username={props.social.hackerrank}
/>
</>
<>
<DisplaySocial
base="https://codeforces.com/profile"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
username={props.social.codeforces}
/>
</>
<>
<DisplaySocial
base="https://www.leetcode.com"
icon={icon_base_url+"leet-code.svg"}
username={props.social.leetcode}
/>
</>
<>
<DisplaySocial
base="https://www.hackerearth.com"
icon={icon_base_url+"hackerearth.svg"}
username={props.social.hackerearth}
/>
</>
<>
<DisplaySocial
base="https://auth.geeksforgeeks.org/user"
icon={icon_base_url + "geeks-for-geeks.svg"}
username={props.social.geeks_for_geeks}
/>
</>
<>
<DisplaySocial
base="https://www.topcoder.com/members"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
username={props.social.topcoder}
/>
</>
<>
<DisplaySocial
base="https://discord.gg"
icon={icon_base_url + "discord.svg"}
username={props.social.discord}
/>
</>
<>
<DisplaySocial
base=""
icon={icon_base_url + "rss.svg"}
username={props.social.rssurl}
/>
</>
</div>
)
}
export const VisitorsBadgePreview = props => {
let link =
"https://komarev.com/ghpvc/?username=" +
props.github +
`&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}`
if (props.show) {
return (
<div className="text-left my-2">
{" "}
<img className="h-4 sm:h-6" src={link} alt={props.github} />{" "}
</div>
)
}
return null
}
export const TwitterBadgePreview = props => {
let link =
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) {
return (
<div className="text-left my-2">
{" "}
<a href="https://twitter.com/${props.twitter}" target="blank">
<img className="h-4 sm:h-6" src={link} alt={props.twitter} />
</a>{" "}
</div>
)
}
return null
}
export const GithubProfileTrophyPreview = props => {
let link =
"https://github-profile-trophy.vercel.app/?username=" + props.github
if (props.show) {
return (
<div className="text-left my-2">
{" "}
<a href="https://github.com/ryo-ma/github-profile-trophy">
<img src={link} alt={props.github} />
</a>{" "}
</div>
)
}
return null
}
export const GitHubStatsPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img src={githubStatsLinkGenerator({ github, options })} alt={github} />
</div>
)
}
return null
}
export const TopLanguagesPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img
src={topLanguagesLinkGenerator({ github, options })}
alt={github}
/>
</div>
)
}
return <div className="text-center mx-4 mb-4"> &nbsp;</div>
}
export const StreakStatsPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img src={streakStatsLinkGenerator({ github, options })} alt={github} />
</div>
)
}
return null
}
export const SkillsPreview = props => {
var listSkills = []
skills.forEach(skill => {
if (props.skills[skill]) {
listSkills.push(
<a
href={skillWebsites[skill]}
key={skill}
target="_blank"
rel="noreferrer"
>
<img
className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10"
src={icons[skill]}
alt={skill}
/>
</a>
)
}
})
return listSkills.length > 0 ? (
<div className="flex flex-wrap justify-start items-center">
<SectionTitle label="Languages and Tools:" visible={true} />
{listSkills}
</div>
) : (
""
)
}
export const SupportPreview = props => {
let viewSupport = false
Object.keys(props.support).forEach(key => {
if (props.support[key]) {
viewSupport = true
}
})
return (
<div className="mb-4">
<SectionTitle label="Support:" visible={viewSupport} />
{props.support.buyMeACoffee && (
<div style={{ width: "210px" }}>
<a
href={`https://www.buymeacoffee.com/` + props.support.buyMeACoffee}
target="_blank"
>
<img
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png"
alt="Buy Me A Coffee"
className="w-36 h-8 sm:w-52 sm:h-12"
/>
</a>
</div>
)}
</div>
)
}
const MarkdownPreview = props => {
return (
<div id="markdown-preview">
<TitlePreview prefix={props.prefix.title} title={props.data.title} />
<SubTitlePreview subtitle={props.data.subtitle} />
<VisitorsBadgePreview
show={props.data.visitorsBadge}
github={props.social.github}
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle,
}}
/>
<GithubProfileTrophyPreview
show={props.data.githubProfileTrophy}
github={props.social.github}
/>
<TwitterBadgePreview
show={props.data.twitterBadge}
twitter={props.social.twitter}
/>
<WorkPreview work={props} />
<SocialPreview social={props.social} />
<SkillsPreview skills={props.skills} />
<SupportPreview support={props.support} />
<div className="block sm:flex sm:justify-center sm:items-start">
<TopLanguagesPreview
show={props.data.topLanguages}
github={props.social.github}
options={props.data.topLanguagesOptions}
/>
<GitHubStatsPreview
show={props.data.githubStats}
github={props.social.github}
options={props.data.githubStatsOptions}
/>
<StreakStatsPreview
show={props.data.streakStats}
github={props.social.github}
options={props.data.streakStatsOptions}
/>
</div>
</div>
)
}
export default MarkdownPreview
+454
View File
@@ -0,0 +1,454 @@
import React from 'react';
import PropTypes from 'prop-types';
import { icons, skills as SKILLS, skillWebsites } from '../constants/skills';
import { githubStatsLinkGenerator, topLanguagesLinkGenerator, streakStatsLinkGenerator } from '../utils/link-generators';
import { DEFAULT_DATA, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
export const TitlePreview = (props) => {
const { prefix, title } = props;
if (prefix && title) {
return <h1 className="text-center text-xl font-bold">{`${prefix} ${title}`}</h1>;
}
return null;
};
TitlePreview.propTypes = {
prefix: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};
export const SubTitlePreview = (props) => {
const { subtitle } = props;
if (subtitle) {
return <h3 className="text-center font-medium">{subtitle}</h3>;
}
return null;
};
SubTitlePreview.propTypes = {
subtitle: PropTypes.string.isRequired,
};
export const SectionTitle = (props) => {
const { visible, label } = props;
if (!visible) return null;
if (label) {
return <h3 className="w-full text-lg sm:text-xl">{label}</h3>;
}
return null;
};
SectionTitle.defaultProps = {
visible: false,
};
SectionTitle.propTypes = {
visible: PropTypes.bool,
label: PropTypes.string.isRequired,
};
export const DisplayWork = (props) => {
const { prefix, project, link } = props;
if (prefix && project) {
if (link) {
return (
<div className="my-2">
{`${prefix} `}
<a href={link} className="no-underline text-blue-700" target="blank">
{project}
</a>
</div>
);
}
return (
<div className="my-2">
{`${prefix} `}
<b>{project}</b>
</div>
);
}
if (prefix && link) {
return (
<div className="my-2">
{`${prefix} `}
<a href={link} className="no-underline text-blue-700" target="blank">
{link}
</a>
</div>
);
}
return null;
};
DisplayWork.defaultProps = {
prefix: '',
project: '',
link: '',
};
DisplayWork.propTypes = {
prefix: PropTypes.string,
project: PropTypes.string,
link: PropTypes.string,
};
export const WorkPreview = (props) => {
const { work } = props;
const { prefix, data, link } = work;
return (
<>
<DisplayWork prefix={prefix.currentWork} project={data.currentWork} link={link.currentWork} />
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
<DisplayWork prefix={prefix.helpWith} project={data.helpWith} link={link.helpWith} />
<DisplayWork prefix={prefix.collaborateOn} project={data.collaborateOn} link={link.collaborateOn} />
<DisplayWork prefix={prefix.ama} project={data.ama} />
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
<DisplayWork prefix={prefix.blog} link={link.blog} />
<DisplayWork prefix={prefix.resume} link={link.resume} />
<DisplayWork prefix={prefix.contact} project={data.contact} />
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
</>
);
};
WorkPreview.propTypes = {
work: PropTypes.object.isRequired,
};
export const DisplaySocial = (props) => {
const { username, base, icon } = props;
if (username) {
return (
<a className="no-underline text-blue-700 m-2" href={`${base}/${username}`} target="blank">
<img className="w-6 h-6" src={icon} alt="username" />
</a>
);
}
return null;
};
DisplaySocial.defaultProps = {
username: '',
base: '',
icon: '',
};
DisplaySocial.propTypes = {
username: PropTypes.string,
base: PropTypes.string,
icon: PropTypes.string,
};
export const SocialPreview = (props) => {
const { social } = props;
let viewSocial = false;
const iconBaseUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
Object.keys(social).forEach((key) => {
if (social[key] && key !== 'github') viewSocial = true;
});
return (
<div className="flex justify-start items-end flex-wrap">
<SectionTitle label="Connect with me:" visible={viewSocial} />
<>
<DisplaySocial base="https://codepen.io" icon={`${iconBaseUrl}codepen.svg`} username={social.codepen} />
</>
<>
<DisplaySocial base="https://dev.to" icon={`${iconBaseUrl}devto.svg`} username={social.dev} />
</>
<>
<DisplaySocial base="https://twitter.com" icon={`${iconBaseUrl}twitter.svg`} username={social.twitter} />
</>
<>
<DisplaySocial base="https://linkedin.com/in" icon={`${iconBaseUrl}linked-in-alt.svg`} username={social.linkedin} />
</>
<>
<DisplaySocial base="https://stackoverflow.com/users" icon={`${iconBaseUrl}stack-overflow.svg`} username={social.stackoverflow} />
</>
<>
<DisplaySocial base="https://codesandbox.com" icon={`${iconBaseUrl}codesandbox.svg`} username={social.codesandbox} />
</>
<>
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
</>
<>
<DisplaySocial base="https://fb.com" icon={`${iconBaseUrl}facebook.svg`} username={social.fb} />
</>
<>
<DisplaySocial base="https://instagram.com" icon={`${iconBaseUrl}instagram.svg`} username={social.instagram} />
</>
<>
<DisplaySocial base="https://dribbble.com" icon={`${iconBaseUrl}dribbble.svg`} username={social.dribbble} />
</>
<>
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
</>
<>
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
</>
<>
<DisplaySocial base="https://www.youtube.com/c" icon={`${iconBaseUrl}youtube.svg`} username={social.youtube} />
</>
<>
<DisplaySocial base="https://www.codechef.com/users" icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" username={social.codechef} />
</>
<>
<DisplaySocial base="https://www.hackerrank.com" icon={`${iconBaseUrl}hackerrank.svg`} username={social.hackerrank} />
</>
<>
<DisplaySocial base="https://codeforces.com/profile" icon={`${iconBaseUrl}codeforces.svg`} username={social.codeforces} />
</>
<>
<DisplaySocial base="https://www.leetcode.com" icon={`${iconBaseUrl}leet-code.svg`} username={social.leetcode} />
</>
<>
<DisplaySocial base="https://www.hackerearth.com" icon={`${iconBaseUrl}hackerearth.svg`} username={social.hackerearth} />
</>
<>
<DisplaySocial base="https://auth.geeksforgeeks.org/user" icon={`${iconBaseUrl}geeks-for-geeks.svg`} username={social.geeks_for_geeks} />
</>
<>
<DisplaySocial base="https://www.topcoder.com/members" icon={`${iconBaseUrl}topcoder.svg`} username={social.topcoder} />
</>
<>
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
</>
<>
<DisplaySocial base="" icon={`${iconBaseUrl}rss.svg`} username={social.rssurl} />
</>
</div>
);
};
SocialPreview.propTypes = {
social: PropTypes.object.isRequired,
};
export const VisitorsBadgePreview = (props) => {
const { github, show, badgeOptions } = props;
const link = `https://komarev.com/ghpvc/?username=${github}&label=${badgeOptions.badgeLabel}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`;
if (show) {
return (
<div className="text-left my-2">
{' '}
<img className="h-4 sm:h-6" src={link} alt={github} />{' '}
</div>
);
}
return null;
};
VisitorsBadgePreview.defaultProps = {
github: '',
show: false,
badgeOptions: {},
};
VisitorsBadgePreview.propTypes = {
github: PropTypes.string,
show: PropTypes.bool,
badgeOptions: PropTypes.object,
};
export const TwitterBadgePreview = (props) => {
const { twitter, show } = props;
const link = `https://img.shields.io/twitter/follow/${twitter}?logo=twitter&style=for-the-badge`;
if (show) {
return (
<div className="text-left my-2">
{' '}
<a href={`https://twitter.com/${twitter}`} target="_blank" rel="noreferrer">
<img className="h-4 sm:h-6" src={link} alt={twitter} />
</a>{' '}
</div>
);
}
return null;
};
TwitterBadgePreview.defaultProps = {
twitter: '',
show: false,
};
TwitterBadgePreview.propTypes = {
twitter: PropTypes.string,
show: PropTypes.bool,
};
export const GithubProfileTrophyPreview = (props) => {
const { github, show } = props;
const link = `https://github-profile-trophy.vercel.app/?username=${github}`;
if (show) {
return (
<div className="text-left my-2">
{' '}
<a href="https://github.com/ryo-ma/github-profile-trophy">
<img src={link} alt={github} />
</a>{' '}
</div>
);
}
return null;
};
GithubProfileTrophyPreview.defaultProps = {
github: '',
show: false,
};
GithubProfileTrophyPreview.propTypes = {
github: PropTypes.string,
show: PropTypes.bool,
};
export const GitHubStatsPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img src={githubStatsLinkGenerator({ github, options })} alt={github} />
</div>
);
}
return null;
};
GitHubStatsPreview.defaultProps = {
github: '',
options: {},
show: false,
};
GitHubStatsPreview.propTypes = {
github: PropTypes.string,
options: PropTypes.object,
show: PropTypes.bool,
};
export const TopLanguagesPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img src={topLanguagesLinkGenerator({ github, options })} alt={github} />
</div>
);
}
return <div className="text-center mx-4 mb-4"> &nbsp;</div>;
};
TopLanguagesPreview.defaultProps = {
github: '',
options: {},
show: false,
};
TopLanguagesPreview.propTypes = {
github: PropTypes.string,
options: PropTypes.object,
show: PropTypes.bool,
};
export const StreakStatsPreview = ({ github, options, show }) => {
if (show) {
return (
<div className="text-center mx-4 mb-4">
<img src={streakStatsLinkGenerator({ github, options })} alt={github} />
</div>
);
}
return null;
};
StreakStatsPreview.defaultProps = {
github: '',
options: {},
show: false,
};
StreakStatsPreview.propTypes = {
github: PropTypes.string,
options: PropTypes.object,
show: PropTypes.bool,
};
export const SkillsPreview = (props) => {
const { skills } = props;
const listSkills = [];
SKILLS.forEach((skill) => {
if (skills[skill]) {
listSkills.push(
<a href={skillWebsites[skill]} key={skill} target="_blank" rel="noreferrer">
<img className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10" src={icons[skill]} alt={skill} />
</a>,
);
}
});
return listSkills.length > 0 ? (
<div className="flex flex-wrap justify-start items-center">
<SectionTitle label="Languages and Tools:" visible />
{listSkills}
</div>
) : (
''
);
};
SkillsPreview.propTypes = {
skills: PropTypes.array.isRequired,
};
export const SupportPreview = (props) => {
const { support } = props;
let viewSupport = false;
Object.keys(support).forEach((key) => {
if (support[key]) {
viewSupport = true;
}
});
return support.buyMeACoffee || support.buyMeAKofi ? (
<div className="flex flex-wrap justify-start items-center">
<SectionTitle label="Support:" visible={viewSupport} />
{support.buyMeACoffee && (
<a href={`https://www.buymeacoffee.com/${support.buyMeACoffee}`} target="_blank" rel="noreferrer">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" className="mb-4 mr-4 w-36 h-8 sm:w-52 sm:h-12" />
</a>
)}
{support.buyMeAKofi && (
<a href={`https://ko-fi.com/${support.buyMeAKofi}`} target="_blank" rel="noreferrer">
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" alt="Buy Me A Ko-fi" className="mb-4 mr-4 w-36 h-8 sm:w-52 sm:h-12" />
</a>
)}
</div>
) : (
''
);
};
SupportPreview.propTypes = {
support: PropTypes.object.isRequired,
};
const MarkdownPreview = (props) => {
const { prefix, data, social, skills, support } = props;
return (
<div id="markdown-preview">
<TitlePreview prefix={prefix.title} title={data.title} />
<SubTitlePreview subtitle={data.subtitle} />
<VisitorsBadgePreview
show={data.visitorsBadge}
github={social.github}
badgeOptions={{
badgeLabel: encodeURI(data.badgeLabel),
badgeColor: data.badgeColor,
badgeStyle: data.badgeStyle,
}}
/>
<GithubProfileTrophyPreview show={data.githubProfileTrophy} github={social.github} />
<TwitterBadgePreview show={data.twitterBadge} twitter={social.twitter} />
<WorkPreview work={props} />
<SocialPreview social={social} />
<SkillsPreview skills={skills} />
<SupportPreview support={support} />
<div className="block sm:flex sm:justify-center sm:items-start">
<TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
<GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
<StreakStatsPreview show={data.streakStats} github={social.github} options={data.streakStatsOptions} />
</div>
</div>
);
};
export default MarkdownPreview;
MarkdownPreview.defaultProps = {
prefix: DEFAULT_PREFIX,
data: DEFAULT_DATA,
social: DEFAULT_SOCIAL,
support: DEFAULT_SUPPORT,
skills: [],
};
MarkdownPreview.propTypes = {
prefix: PropTypes.object,
data: PropTypes.object,
social: PropTypes.object,
skills: PropTypes.object,
support: PropTypes.object,
};
@@ -5,10 +5,10 @@
* See: https://www.gatsbyjs.org/docs/use-static-query/ * See: https://www.gatsbyjs.org/docs/use-static-query/
*/ */
import React from "react" import React from 'react';
import PropTypes from "prop-types" import PropTypes from 'prop-types';
import { Helmet } from "react-helmet" import { Helmet } from 'react-helmet';
import { useStaticQuery, graphql } from "gatsby" import { useStaticQuery, graphql } from 'gatsby';
function SEO({ description, lang, meta, title }) { function SEO({ description, lang, meta, title }) {
const { site } = useStaticQuery( const { site } = useStaticQuery(
@@ -22,10 +22,10 @@ function SEO({ description, lang, meta, title }) {
} }
} }
} }
` `,
) );
const metaDescription = description || site.siteMetadata.description const metaDescription = description || site.siteMetadata.description;
return ( return (
<Helmet <Helmet
@@ -69,20 +69,20 @@ function SEO({ description, lang, meta, title }) {
}, },
].concat(meta)} ].concat(meta)}
/> />
) );
} }
SEO.defaultProps = { SEO.defaultProps = {
lang: `en`, lang: `en`,
meta: [], meta: [],
description: ``, description: ``,
} };
SEO.propTypes = { SEO.propTypes = {
description: PropTypes.string, description: PropTypes.string,
lang: PropTypes.string, lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object), meta: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string.isRequired, title: PropTypes.string.isRequired,
} };
export default SEO export default SEO;
-104
View File
@@ -1,104 +0,0 @@
import React, {useState} from "react"
import { icons, categorizedSkills } from "../constants/skills"
import { SearchIcon, XIcon } from "@primer/octicons-react";
const Skills = props => {
const [search, setSearch] = useState('')
const [debounce, setDebounce] = useState(undefined);
const inputRef = React.createRef()
const createSkill = skill => {
return (
<div className="w-1/3 sm:w-1/4 my-6" key={skill}>
<label
htmlFor={skill}
className="skillCheckboxLabel cursor-pointer flex items-center justify-start"
>
<input
id={skill}
type="checkbox"
checked={props.skills[skill]}
onChange={event => props.handleSkillsChange(skill)}
/>
<img
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
src={icons[skill]}
alt={skill}
/>
<span className="tooltiptext">{skill}</span>
</label>
</div>
)
}
const onSearchChange = (value) => {
const callback = () => {
setSearch(value)
}
clearTimeout(debounce)
setDebounce(setTimeout(callback, 50))
}
return (
<div className="px-2 sm:px-6 mb-10 ">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-4 flex justify-between">
Skills
<div className="relative flex">
<input
type="text"
onChange={(e) => onSearchChange(e.target.value)}
className="leading:none text-xs my-0 py-1 px-2 pr-8 sm:text-xl border-2 border-gray-900 focus:border-blue-700 placeholder-gray-700"
placeholder="Search Skills"
ref = {inputRef}
/>
<span className="absolute" style={{right:"10px"}}>
{(search !== '')
?<button className="focus:outline-none" onClick={() => {
setSearch('')
inputRef.current.value = ''
}
}>
<XIcon size={16} className="mb-1 transform scale-100 md:scale-125"/>
</button>
:<SearchIcon size={16} className="mb-1 transform scale-100 md:scale-125"/>
}
</span>
</div>
</div>
{Object.keys(categorizedSkills)
.filter(key => {
let filtered = categorizedSkills[key].skills.filter(skill => {
return skill.includes(search.toLowerCase())
})
return filtered.length !== 0
})
.map(key => (
<div key={key} className="divide-y divide-gray-500">
<div className="text-sm sm:text-xl text-gray-900 text-left py-1">
{categorizedSkills[key].title}
</div>
<div className="flex justify-start items-center flex-wrap w-full mb-6 pl-4 sm:pl-10">
{categorizedSkills[key].skills
.filter(skill => {
return skill.includes(search.toLowerCase())
})
.map(skill => createSkill(skill))}
</div>
</div>
))}
<span className="flex justify-center text-gray-900">
{(Object.keys(categorizedSkills)
.filter(key => {
let filtered = categorizedSkills[key].skills.filter(skill => {
return skill.includes(search.toLowerCase())
})
return filtered.length !== 0
})
.length === 0)?"No Results Found":""}
</span>
</div>
)
}
export default Skills
+83
View File
@@ -0,0 +1,83 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { SearchIcon, XIcon } from '@primer/octicons-react';
import { icons, categorizedSkills } from '../constants/skills';
const Skills = (props) => {
const { skills, handleSkillsChange } = props;
const [search, setSearch] = useState('');
const [debounce, setDebounce] = useState(undefined);
const inputRef = React.createRef();
const createSkill = (skill) => (
<div className="w-1/3 sm:w-1/4 my-6" key={skill}>
<label htmlFor={skill} className="checkbox-label flex items-center justify-start">
<input id={skill} type="checkbox" className="checkbox-label__input" checked={skills[skill]} onChange={() => handleSkillsChange(skill)} />
<span className="checkbox-label__control" />
<img className="ml-4 w-8 h-8 sm:w-10 sm:h-10" src={icons[skill]} alt={skill} />
<span className="tooltiptext">{skill}</span>
</label>
</div>
);
const onSearchChange = (value) => {
const callback = () => {
setSearch(value);
};
clearTimeout(debounce);
setDebounce(setTimeout(callback, 50));
};
return (
<div className="px-2 sm:px-6 mb-10 ">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-4 flex justify-between">
Skills
<div className="relative flex">
<input type="text" onChange={(e) => onSearchChange(e.target.value)} className="leading:none text-xs my-0 py-1 px-2 pr-8 sm:text-xl border-2 border-gray-900 focus:border-blue-700 placeholder-gray-700" placeholder="Search Skills" ref={inputRef} />
<span className="absolute" style={{ right: '10px' }}>
{search !== '' ? (
<button
type="button"
className="focus:outline-none"
onClick={() => {
setSearch('');
inputRef.current.value = '';
}}
>
<XIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
</button>
) : (
<SearchIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
)}
</span>
</div>
</div>
{Object.keys(categorizedSkills)
.filter((key) => {
const filtered = categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase()));
return filtered.length !== 0;
})
.map((key) => (
<div key={key} className="divide-y divide-gray-500">
<div className="text-sm sm:text-xl text-gray-900 text-left py-1">{categorizedSkills[key].title}</div>
<div className="flex justify-start items-center flex-wrap w-full mb-6 pl-4 sm:pl-10">{categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase())).map((skill) => createSkill(skill))}</div>
</div>
))}
<span className="flex justify-center text-gray-900">
{Object.keys(categorizedSkills).filter((key) => {
const filtered = categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase()));
return filtered.length !== 0;
}).length === 0
? 'No Results Found'
: ''}
</span>
</div>
);
};
export default Skills;
Skills.propTypes = {
skills: PropTypes.array.isRequired,
handleSkillsChange: PropTypes.func.isRequired,
};
-339
View File
@@ -1,339 +0,0 @@
import React from "react"
const Social = props => {
return (
<div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Social
</div>
<div className="flex flex-wrap justify-center items-center">
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="github"
/>
<input
id="github"
placeholder="github username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 focus:border-blue-700"
value={props.social.github}
onChange={event => props.handleSocialChange("github", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/twitter.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="twitter"
/>
<input
id="twitter"
placeholder="twitter username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.twitter}
onChange={event => props.handleSocialChange("twitter", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="dev.to"
/>
<input
id="dev"
placeholder="dev.to username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.dev}
onChange={event => props.handleSocialChange("dev", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="codepen"
/>
<input
id="codepen"
placeholder="codepen username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.codepen}
onChange={event => props.handleSocialChange("codepen", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="codesandbox"
/>
<input
id="codesandbox"
placeholder="codesandbox username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.codesandbox}
onChange={event => props.handleSocialChange("codesandbox", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="stackoverflow"
/>
<input
id="stackoverflow"
placeholder="stackoverflow user ID"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.stackoverflow}
onChange={event => props.handleSocialChange("stackoverflow", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="linkedin"
/>
<input
id="linkedin"
placeholder="linkedin username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.linkedin}
onChange={event => props.handleSocialChange("linkedin", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="kaggle"
/>
<input
id="kaggle"
placeholder="kaggle username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.kaggle}
onChange={event => props.handleSocialChange("kaggle", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="facebook"
/>
<input
id="fb"
placeholder="facebook username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.fb}
onChange={event => props.handleSocialChange("fb", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="instagram"
/>
<input
id="instagram"
placeholder="instagram username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.instagram}
onChange={event => props.handleSocialChange("instagram", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/dribbble.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="dribbble"
/>
<input
id="dribbble"
placeholder="dribbble username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.dribbble}
onChange={event => props.handleSocialChange("dribbble", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/behance.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="behance"
/>
<input
id="behance"
placeholder="behance username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.behance}
onChange={event => props.handleSocialChange("behance", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/medium.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="medium"
/>
<input
id="medium"
placeholder="medium username (with @)"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.medium}
onChange={event => props.handleSocialChange("medium", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/youtube.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="youtube"
/>
<input
id="youtube"
placeholder="youtube channel name"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.youtube}
onChange={event => props.handleSocialChange("youtube", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="codechef"
/>
<input
id="codechef"
placeholder="codechef username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.codechef}
onChange={event => props.handleSocialChange("codechef", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerrank.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="hackerrank"
/>
<input
id="hackerrank"
placeholder="hackerrank username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.hackerrank}
onChange={event => props.handleSocialChange("hackerrank", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codeforces.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="codeforces"
/>
<input
id="codeforces"
placeholder="codeforces username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.codeforces}
onChange={event => props.handleSocialChange("codeforces", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/leetcode.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="leetcode"
/>
<input
id="leetcode"
placeholder="leetcode username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.leetcode}
onChange={event => props.handleSocialChange("leetcode", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/topcoder.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="topcoder"
/>
<input
id="topcoder"
placeholder="topcoder username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.topcoder}
onChange={event => props.handleSocialChange("topcoder", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerearth.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="hackerearth"
/>
<input
id="hackerearth"
placeholder="hackerearth user (with @)"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.hackerearth}
onChange={event => props.handleSocialChange("hackerearth", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/geeksforgeeks.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="geeksforgeeks"
/>
<input
id="geeksforgeeks"
placeholder="GFG (<username>/profile)"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.geeks_for_geeks}
onChange={event =>
props.handleSocialChange("geeks_for_geeks", event)
}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/discord.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="discord"
/>
<input
id="discord"
placeholder="discord invite (only code)"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.discord}
onChange={event => props.handleSocialChange("discord", event)}
/>
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/rss.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="rssfeed"
/>
<input
id="rssurl"
placeholder="RSS feed URL"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.social.rssurl}
onChange={event => props.handleSocialChange("rssurl", event)}
/>
</div>
</div>
</div>
)
}
export default Social
+111
View File
@@ -0,0 +1,111 @@
import React from 'react';
import PropTypes from 'prop-types';
const Social = (props) => {
const { social, handleSocialChange } = props;
return (
<div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Social</div>
<div className="flex flex-wrap justify-center items-center">
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="github" />
<input id="github" placeholder="github username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 focus:border-blue-700" value={social.github} onChange={(event) => handleSocialChange('github', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/twitter.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="twitter" />
<input id="twitter" placeholder="twitter username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.twitter} onChange={(event) => handleSocialChange('twitter', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="dev.to" />
<input id="dev" placeholder="dev.to username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.dev} onChange={(event) => handleSocialChange('dev', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codepen" />
<input id="codepen" placeholder="codepen username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codepen} onChange={(event) => handleSocialChange('codepen', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codesandbox" />
<input id="codesandbox" placeholder="codesandbox username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codesandbox} onChange={(event) => handleSocialChange('codesandbox', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="stackoverflow" />
<input id="stackoverflow" placeholder="stackoverflow user ID" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.stackoverflow} onChange={(event) => handleSocialChange('stackoverflow', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="linkedin" />
<input id="linkedin" placeholder="linkedin username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.linkedin} onChange={(event) => handleSocialChange('linkedin', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="kaggle" />
<input id="kaggle" placeholder="kaggle username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.kaggle} onChange={(event) => handleSocialChange('kaggle', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="facebook" />
<input id="fb" placeholder="facebook username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.fb} onChange={(event) => handleSocialChange('fb', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="instagram" />
<input id="instagram" placeholder="instagram username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.instagram} onChange={(event) => handleSocialChange('instagram', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/dribbble.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="dribbble" />
<input id="dribbble" placeholder="dribbble username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.dribbble} onChange={(event) => handleSocialChange('dribbble', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/behance.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="behance" />
<input id="behance" placeholder="behance username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.behance} onChange={(event) => handleSocialChange('behance', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/medium.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="medium" />
<input id="medium" placeholder="medium username (with @)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.medium} onChange={(event) => handleSocialChange('medium', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/youtube.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="youtube" />
<input id="youtube" placeholder="youtube channel name" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.youtube} onChange={(event) => handleSocialChange('youtube', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codechef" />
<input id="codechef" placeholder="codechef username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codechef} onChange={(event) => handleSocialChange('codechef', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerrank.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="hackerrank" />
<input id="hackerrank" placeholder="hackerrank username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.hackerrank} onChange={(event) => handleSocialChange('hackerrank', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codeforces.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codeforces" />
<input id="codeforces" placeholder="codeforces username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codeforces} onChange={(event) => handleSocialChange('codeforces', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/leetcode.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="leetcode" />
<input id="leetcode" placeholder="leetcode username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.leetcode} onChange={(event) => handleSocialChange('leetcode', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/topcoder.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="topcoder" />
<input id="topcoder" placeholder="topcoder username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.topcoder} onChange={(event) => handleSocialChange('topcoder', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerearth.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="hackerearth" />
<input id="hackerearth" placeholder="hackerearth user (with @)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.hackerearth} onChange={(event) => handleSocialChange('hackerearth', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/geeksforgeeks.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="geeksforgeeks" />
<input id="geeksforgeeks" placeholder="GFG (<username>/profile)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.geeks_for_geeks} onChange={(event) => handleSocialChange('geeks_for_geeks', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/discord.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="discord" />
<input id="discord" placeholder="discord invite (only code)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.discord} onChange={(event) => handleSocialChange('discord', event)} />
</div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/rss.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="rssfeed" />
<input id="rssurl" placeholder="RSS feed URL" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.rssurl} onChange={(event) => handleSocialChange('rssurl', event)} />
</div>
</div>
</div>
);
};
export default Social;
Social.propTypes = {
social: PropTypes.object.isRequired,
handleSocialChange: PropTypes.func.isRequired,
};
-19
View File
@@ -1,19 +0,0 @@
import React from "react"
const Subtitle = props => {
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Subtitle
</div>
<input
id="subtitle"
className="outline-none w-full text-xs sm:text-lg sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.subtitle}
onChange={event => props.handleDataChange("subtitle", event)}
/>
</div>
)
}
export default Subtitle
+18
View File
@@ -0,0 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
const Subtitle = (props) => {
const { data, handleDataChange } = props;
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Subtitle</div>
<input id="subtitle" className="outline-none w-full text-xs sm:text-lg sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.subtitle} onChange={(event) => handleDataChange('subtitle', event)} />
</div>
);
};
export default Subtitle;
Subtitle.propTypes = {
data: PropTypes.object.isRequired,
handleDataChange: PropTypes.func.isRequired,
};
-29
View File
@@ -1,29 +0,0 @@
import React from "react"
const Support = props => {
return (
<div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Support
</div>
<div className="flex flex-wrap justify-start items-center">
<div className="w-2/5 flex justify-between items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png"
className="w-36 h-8 sm:w-52 sm:h-12"
alt="buymeacoffee"
/>
<input
id="buy-me-a-coffee"
placeholder="buymeacoffee username"
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 ml-2 sm:ml-0 focus:border-blue-700"
value={props.support.buyMeACoffee || ""}
onChange={event => props.handleSupportChange("buyMeACoffee", event)}
/>
</div>
</div>
</div>
)
}
export default Support
+27
View File
@@ -0,0 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
const Support = (props) => {
const { support, handleSupportChange } = props;
return (
<div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Support</div>
<div className="flex flex-wrap justify-start items-center">
<div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" className="w-36 h-8 sm:w-52 sm:h-12 mr-1 sm:mr-4" alt="buymeacoffee" />
<input id="buy-me-a-coffee" placeholder="buymeacoffee username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 focus:border-blue-700" value={support.buyMeACoffee || ''} onChange={(event) => handleSupportChange('buyMeACoffee', event)} />
</div>
<div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" className="w-36 h-8 sm:w-52 sm:h-12 mr-1 sm:mr-4" alt="buymeakofi" />
<input id="buy-me-a-kofi" placeholder="Ko-fi username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 ml-2 sm:ml-0 focus:border-blue-700" value={support.buyMeAKofi || ''} onChange={(event) => handleSupportChange('buyMeAKofi', event)} />
</div>
</div>
</div>
);
};
export default Support;
Support.propTypes = {
support: PropTypes.object.isRequired,
handleSupportChange: PropTypes.func.isRequired,
};
-28
View File
@@ -1,28 +0,0 @@
import React from "react"
const Title = props => {
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Title
</div>
<div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg">
<input
id="title-prefix"
className="outline-none w-24 sm:w-40 mr-10 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix"
value={props.prefix.title}
onChange={event => props.handlePrefixChange("title", event)}
/>
<input
id="title-name"
placeholder="name"
className="outline-none placeholder-gray-700 w-1/2 sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.title}
onChange={event => props.handleDataChange("title", event)}
/>
</div>
</div>
)
}
export default Title
+23
View File
@@ -0,0 +1,23 @@
import React from 'react';
import PropTypes from 'prop-types';
const Title = (props) => {
const { data, prefix, handlePrefixChange, handleDataChange } = props;
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Title</div>
<div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg">
<input id="title-prefix" className="outline-none w-24 sm:w-40 mr-10 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix" value={prefix.title} onChange={(event) => handlePrefixChange('title', event)} />
<input id="title-name" placeholder="name" className="outline-none placeholder-gray-700 w-1/2 sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.title} onChange={(event) => handleDataChange('title', event)} />
</div>
</div>
);
};
export default Title;
Title.propTypes = {
prefix: PropTypes.object.isRequired,
data: PropTypes.object.isRequired,
handlePrefixChange: PropTypes.func.isRequired,
handleDataChange: PropTypes.func.isRequired,
};
-189
View File
@@ -1,189 +0,0 @@
import React from "react"
const Work = props => {
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
Work
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="currentWork-prefix"
placeholder="Hi, I'm "
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.currentWork}
onChange={event => props.handlePrefixChange("currentWork", event)}
/>
<input
id="currentWork"
placeholder="project name"
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.currentWork}
onChange={event => props.handleDataChange("currentWork", event)}
/>
<input
id="currentWork-link"
placeholder="project link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.currentWork}
onChange={event => props.handleLinkChange("currentWork", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="collaborateOn-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.collaborateOn}
onChange={event => props.handlePrefixChange("collaborateOn", event)}
/>
<input
id="collaborateOn"
placeholder="project name"
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.collaborateOn}
onChange={event => props.handleDataChange("collaborateOn", event)}
/>
<input
id="collaborateOn-link"
placeholder="project link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.collaborateOn}
onChange={event => props.handleLinkChange("collaborateOn", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="helpWith-prefix"
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.helpWith}
onChange={event => props.handlePrefixChange("helpWith", event)}
/>
<input
id="helpWith"
placeholder="project name"
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.helpWith}
onChange={event => props.handleDataChange("helpWith", event)}
/>
<input
id="helpWith-link"
placeholder="project link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.helpWith}
onChange={event => props.handleLinkChange("helpWith", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="currentLearn-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.currentLearn}
onChange={event => props.handlePrefixChange("currentLearn", event)}
/>
<input
id="currentLearn"
placeholder="Frameworks, courses etc."
className="outline-none placeholder-gray-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.currentLearn}
onChange={event => props.handleDataChange("currentLearn", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="ama-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.ama}
onChange={event => props.handlePrefixChange("ama", event)}
/>
<input
id="ama"
placeholder="react, vue and gsap"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.ama}
onChange={event => props.handleDataChange("ama", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="contact-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.contact}
onChange={event => props.handlePrefixChange("contact", event)}
/>
<input
id="contact"
placeholder="example@gmail.com"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.contact}
onChange={event => props.handleDataChange("contact", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="portfolio-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.portfolio}
onChange={event => props.handlePrefixChange("portfolio", event)}
/>
<input
id="portfolio"
placeholder="portfolio link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.portfolio}
onChange={event => props.handleLinkChange("portfolio", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="blog-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.blog}
onChange={event => props.handlePrefixChange("blog", event)}
/>
<input
id="blog"
placeholder="blog link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.blog}
onChange={event => props.handleLinkChange("blog", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="resume-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.resume}
onChange={event => props.handlePrefixChange("resume", event)}
/>
<input
id="resume"
placeholder="resume link"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.link.resume}
onChange={event => props.handleLinkChange("resume", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="funFact-prefix"
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.prefix.funFact}
onChange={event => props.handlePrefixChange("funFact", event)}
/>
<input
id="funFact"
placeholder="I think I am funny"
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
value={props.data.funFact}
onChange={event => props.handleDataChange("funFact", event)}
/>
</div>
</div>
)
}
export default Work
+68
View File
@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
const Work = (props) => {
const { prefix, handlePrefixChange, data, handleDataChange, link, handleLinkChange } = props;
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Work</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="currentWork-prefix" placeholder="Hi, I'm " className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.currentWork} onChange={(event) => handlePrefixChange('currentWork', event)} />
<input id="currentWork" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.currentWork} onChange={(event) => handleDataChange('currentWork', event)} />
<input id="currentWork-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.currentWork} onChange={(event) => handleLinkChange('currentWork', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="collaborateOn-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.collaborateOn} onChange={(event) => handlePrefixChange('collaborateOn', event)} />
<input id="collaborateOn" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.collaborateOn} onChange={(event) => handleDataChange('collaborateOn', event)} />
<input id="collaborateOn-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.collaborateOn} onChange={(event) => handleLinkChange('collaborateOn', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="helpWith-prefix" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.helpWith} onChange={(event) => handlePrefixChange('helpWith', event)} />
<input id="helpWith" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.helpWith} onChange={(event) => handleDataChange('helpWith', event)} />
<input id="helpWith-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.helpWith} onChange={(event) => handleLinkChange('helpWith', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="currentLearn-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.currentLearn} onChange={(event) => handlePrefixChange('currentLearn', event)} />
<input id="currentLearn" placeholder="Frameworks, courses etc." className="outline-none placeholder-gray-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.currentLearn} onChange={(event) => handleDataChange('currentLearn', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="ama-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.ama} onChange={(event) => handlePrefixChange('ama', event)} />
<input id="ama" placeholder="react, vue and gsap" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.ama} onChange={(event) => handleDataChange('ama', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="contact-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.contact} onChange={(event) => handlePrefixChange('contact', event)} />
<input id="contact" placeholder="example@gmail.com" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.contact} onChange={(event) => handleDataChange('contact', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="portfolio-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.portfolio} onChange={(event) => handlePrefixChange('portfolio', event)} />
<input id="portfolio" placeholder="portfolio link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.portfolio} onChange={(event) => handleLinkChange('portfolio', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="blog-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.blog} onChange={(event) => handlePrefixChange('blog', event)} />
<input id="blog" placeholder="blog link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.blog} onChange={(event) => handleLinkChange('blog', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="resume-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.resume} onChange={(event) => handlePrefixChange('resume', event)} />
<input id="resume" placeholder="resume link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.resume} onChange={(event) => handleLinkChange('resume', event)} />
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input id="funFact-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.funFact} onChange={(event) => handlePrefixChange('funFact', event)} />
<input id="funFact" placeholder="I think I am funny" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.funFact} onChange={(event) => handleDataChange('funFact', event)} />
</div>
</div>
);
};
export default Work;
Work.propTypes = {
prefix: PropTypes.object.isRequired,
data: PropTypes.object.isRequired,
link: PropTypes.object.isRequired,
handlePrefixChange: PropTypes.func.isRequired,
handleDataChange: PropTypes.func.isRequired,
handleLinkChange: PropTypes.func.isRequired,
};
+68 -68
View File
@@ -1,97 +1,97 @@
export const DEFAULT_PREFIX = { export const DEFAULT_PREFIX = {
title: "Hi 👋, I'm", title: "Hi 👋, I'm",
currentWork: "🔭 Im currently working on", currentWork: '🔭 Im currently working on',
currentLearn: "🌱 Im currently learning", currentLearn: '🌱 Im currently learning',
collaborateOn: "👯 Im looking to collaborate on", collaborateOn: '👯 Im looking to collaborate on',
helpWith: "🤝 Im looking for help with", helpWith: '🤝 Im looking for help with',
ama: "💬 Ask me about", ama: '💬 Ask me about',
contact: "📫 How to reach me", contact: '📫 How to reach me',
resume: "📄 Know about my experiences", resume: '📄 Know about my experiences',
funFact: "⚡ Fun fact", funFact: '⚡ Fun fact',
portfolio: "👨‍💻 All of my projects are available at", portfolio: '👨‍💻 All of my projects are available at',
blog: "📝 I regularly write articles on", blog: '📝 I regularly write articles on',
} };
export const DEFAULT_DATA = { export const DEFAULT_DATA = {
title: "", title: '',
subtitle: "A passionate frontend developer from India", subtitle: 'A passionate frontend developer from India',
currentWork: "", currentWork: '',
currentLearn: "", currentLearn: '',
collaborateOn: "", collaborateOn: '',
helpWith: "", helpWith: '',
ama: "", ama: '',
contact: "", contact: '',
funFact: "", funFact: '',
twitterBadge: false, twitterBadge: false,
visitorsBadge: false, visitorsBadge: false,
badgeStyle: "flat", badgeStyle: 'flat',
badgeColor: "0e75b6", badgeColor: '0e75b6',
badgeLabel: "Profile views", badgeLabel: 'Profile views',
githubProfileTrophy: false, githubProfileTrophy: false,
githubStats: false, githubStats: false,
githubStatsOptions: { githubStatsOptions: {
theme: "", theme: '',
titleColor: "", titleColor: '',
textColor: "", textColor: '',
bgColor: "", bgColor: '',
hideBorder: false, hideBorder: false,
cacheSeconds: null, cacheSeconds: null,
locale: "en", locale: 'en',
}, },
topLanguages: false, topLanguages: false,
topLanguagesOptions: { topLanguagesOptions: {
theme: "", theme: '',
titleColor: "", titleColor: '',
textColor: "", textColor: '',
bgColor: "", bgColor: '',
hideBorder: false, hideBorder: false,
cacheSeconds: null, cacheSeconds: null,
locale: "en", locale: 'en',
}, },
streakStats: false, streakStats: false,
streakStatsOptions: { streakStatsOptions: {
theme: "", theme: '',
}, },
devDynamicBlogs: false, devDynamicBlogs: false,
mediumDynamicBlogs: false, mediumDynamicBlogs: false,
rssDynamicBlogs: false, rssDynamicBlogs: false,
} };
export const DEFAULT_LINK = { export const DEFAULT_LINK = {
currentWork: "", currentWork: '',
collaborateOn: "", collaborateOn: '',
helpWith: "", helpWith: '',
portfolio: "", portfolio: '',
blog: "", blog: '',
resume: "", resume: '',
} };
export const DEFAULT_SOCIAL = { export const DEFAULT_SOCIAL = {
github: "", github: '',
dev: "", dev: '',
linkedin: "", linkedin: '',
codepen: "", codepen: '',
stackoverflow: "", stackoverflow: '',
kaggle: "", kaggle: '',
codesandbox: "", codesandbox: '',
fb: "", fb: '',
instagram: "", instagram: '',
twitter: "", twitter: '',
dribbble: "", dribbble: '',
behance: "", behance: '',
medium: "", medium: '',
youtube: "", youtube: '',
codechef: "", codechef: '',
hackerrank: "", hackerrank: '',
codeforces: "", codeforces: '',
leetcode: "", leetcode: '',
topcoder: "", topcoder: '',
hackerearth: "", hackerearth: '',
geeks_for_geeks: "", geeks_for_geeks: '',
discord: "", discord: '',
rssurl: "", rssurl: '',
} };
export const DEFAULT_SUPPORT = { export const DEFAULT_SUPPORT = {
buyMeACoffee: "" buyMeACoffee: '',
} };
+6 -6
View File
@@ -1,7 +1,7 @@
const links = { const links = {
home: "/", home: '/',
about: "/about", about: '/about',
addons: "/addons", addons: '/addons',
support: "/support", support: '/support',
} };
export default links export default links;
+432 -525
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 KiB

+6 -13
View File
@@ -1,5 +1,5 @@
import React from "react" import React from 'react';
import PropTypes from "prop-types" import PropTypes from 'prop-types';
export default function HTML(props) { export default function HTML(props) {
return ( return (
@@ -7,10 +7,7 @@ export default function HTML(props) {
<head> <head>
<meta charSet="utf-8" /> <meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" /> <meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents} {props.headComponents}
<script <script
data-name="BMC-Widget" data-name="BMC-Widget"
@@ -26,15 +23,11 @@ export default function HTML(props) {
</head> </head>
<body {...props.bodyAttributes}> <body {...props.bodyAttributes}>
{props.preBodyComponents} {props.preBodyComponents}
<div <div key={`body`} id="___gatsby" dangerouslySetInnerHTML={{ __html: props.body }} />
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents} {props.postBodyComponents}
</body> </body>
</html> </html>
) );
} }
HTML.propTypes = { HTML.propTypes = {
@@ -44,4 +37,4 @@ HTML.propTypes = {
preBodyComponents: PropTypes.array, preBodyComponents: PropTypes.array,
body: PropTypes.string, body: PropTypes.string,
postBodyComponents: PropTypes.array, postBodyComponents: PropTypes.array,
} };
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 12" style="enable-background:new 0 0 24 12;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF4A00;}
</style>
<path d="M.837 2.756h6.488v4.062H.837z" fill="#09f"/><path d="M.837 6.818H4.9v2.427H.837z" fill="#f1422a"/><path d="M4.9 6.818h2.427v2.427H4.9z" fill="#333"/><path d="M8.168 3.96h1.298v4.08H8.168zm7.418 0H13.36v1.298h.927V8.04h1.298V5.258h.927V3.96zm3.524 0h-2.226v1.298h.927V8.04H19.1V5.258h.927V3.96zm3.524 0h-2.226v1.298h.927V8.04h1.298V5.258h.927V3.96zM13 5.258V3.96h-2.967v4.08h1.298V6.927h1.113V5.63H11.32v-.37z" fill="#09f"/>
</svg>

After

Width:  |  Height:  |  Size: 839 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#DF234F" d="M75.4.3c-.9 0-1.8.2-2.6.5 1.7 1.1 2.6 2.6 3.1 4.3 0 .2.1.4.1.6 0 .2.1.4.1.6.1 2.9-.8 3.3-1.4 5-1 2.2-.7 4.6.5 6.5.1.2.2.5.4.7-1.3-8.4 5.7-9.6 7-12.2.1-2.3-1.8-3.8-3.3-4.9C77.8.5 76.6.3 75.4.3zm10.5 1.8c-.1.8 0 .6-.1 1 0 .3 0 .6-.1.9-.1.3-.1.5-.2.8-.1.3-.2.5-.3.8-.1.2-.2.4-.3.7-.1.1-.2.3-.3.4-.1.1-.1.2-.2.3-.2.2-.3.5-.5.7l-.6.6c-.2.2-.4.4-.6.5-.7.5-1.5.9-2.2 1.4-.2.2-.5.3-.7.5-.2.2-.4.3-.6.5l-.6.6c-.2.2-.4.4-.5.7-.2.2-.3.5-.5.7-.1.3-.2.5-.4.8-.1.3-.2.5-.3.8-.1.3-.2.6-.2.8 0 .1 0 .3-.1.4 0 .1 0 .3-.1.4v1.4c0 .3 0 .5.1.8 0 .3.1.5.2.8.1.3.2.5.3.8.1.2.2.3.2.5l-7.6-2.9c-1.3-.4-2.5-.7-3.8-1-.7-.2-1.4-.3-2.1-.5-2-.4-4-.7-6-.9h-.2c-2-.2-3.9-.3-5.9-.3-1.5 0-2.9.1-4.3.2-2 .1-4 .4-6 .7l-1.5.3c-1 .2-2 .4-3 .7-.5.1-1 .3-1.5.4-.5.2-1 .4-1.4.6-.4.2-.7.3-1.1.5-.1 0-.1 0-.2.1-.3.2-.6.3-.9.5-.1 0-.2.1-.2.1-.4.2-.7.4-1 .5-.2.1-.5.2-.7.3-.1.1-.2.1-.3.2-.3.2-.6.3-.9.5-.3.2-.6.3-.8.5-.2.2-.5.3-.7.5 0 0-.1 0-.1.1-.2.1-.4.3-.6.5l-.1.1c-.2.1-.3.3-.5.4-.1 0-.1.1-.2.1-.2.1-.3.3-.5.4 0 .1-.1.1-.1.1l-.6.6-.1.1-.6.6s0 .1-.1.1l-.5.5c-.1.1-.2.1-.2.2l-.6.6c0 .1-.1.1-.1.2l-.8.8-.1.1c-.5.6-1.1 1.1-1.7 1.6-.6.5-1.2 1-1.9 1.5s-1.3.9-2 1.3-1.4.7-2.1 1c-.7.3-1.4.6-2.1.8-1.4.3-2.8.9-4 1 0-.5-.3-.4-.6-.4-.3.1-.6.1-.8.2-.3.1-.5.2-.8.3-.3.1-.5.2-.8.4-.2.2-.5.3-.7.5-.2.2-.5.4-.7.6-.2.2-.5.4-.7.6-.2.2-.4.4-.6.7-.2.3-.4.5-.5.8-.2.2-.3.5-.5.8-.1.3-.3.6-.4.9l-.3.9c-.1.3-.1.5-.2.8v.1c-.1.3-.1.7-.1.9.1-.1.1.1.1.3v.4c0 .2.1.4.1.6.1.2.1.4.2.6.1.2.2.4.4.6.1.2.3.4.4.6.2.2.4.4.6.5.2.2.4.4.6.5.8.7 1 .9 2 1.5.2.1.3.2.5.3h.1v.2c0 .3.1.5.2.8.1.3.2.6.3.8l.3.6c0 .1.1.1.1.2.1.3.3.5.4.7.2.2.3.5.5.7l.6.6.6.6H8c.2.2.4.3.6.5.2.2.5.3.7.4.2.1.5.3.8.4.2.1.4.2.7.2 0 0 .1 0 .1.1.1 0 .3.1.4.1-.1 1.8-.1 3.5.1 4.1.3.7 1.8-1.4 3.2-3.7-.2 2.3-.3 5 0 5.8.4.8 2.3-1.8 4.1-4.6 23.4-5.4 44.8 10.8 47.1 33.7-.4-3.6-4.8-5.6-6.9-5.1-1 2.4-2.7 5.6-5.4 7.5.2-2.2.1-4.4-.3-6.6-.7 3-2.1 5.9-4.1 8.3-3.1.2-6.3-1.3-7.9-3.6-.1-.1-.2-.3-.3-.4-.1-.2-.2-.5-.3-.7-.1-.2-.2-.5-.2-.7v-.7-.5c0-.2.1-.5.2-.7.1-.2.1-.5.2-.7.1-.2.2-.5.4-.7.6-1.6.6-2.9-.5-3.6l-.6-.3c-.1 0-.3-.1-.4-.1-.1 0-.2-.1-.3-.1-.2-.1-.5-.1-.7-.2-.2-.1-.5-.1-.7-.1-.2 0-.5-.1-.7-.1h-.5c-.3 0-.5 0-.7.1-.2 0-.5.1-.7.1-.2.1-.5.1-.7.2-.2.1-.4.2-.7.3l-.6.3c-7.7 5-3.1 16.8 2.1 20.2-2 .4-4 .8-4.6 1.2l-.1.1c1.4.9 2.9 1.6 4.5 2.2 2.1.7 4.4 1.3 5.4 1.6 2.7.6 5.5.8 8.3.6 14.6-1 26.6-12.2 28.8-26.8.1.3.1.6.2.9.1.6.2 1.2.3 1.9.1.3.1.6.1.9v.1c0 .3.1.6.1.9 0 .4.1.7.1 1.1V91.6c0 .3-.1.5-.1.8v.3c0 .3-.1.6-.1 1-.1.3-.1.6-.2.9v.1c-.1.3-.1.6-.2.9v.1c-.1.3-.1.6-.2.9v.1l-.3.9v.1c-.1.3-.2.7-.3 1-.1.3-.2.6-.4 1-.1.3-.2.7-.4 1-.1.3-.3.6-.4 1-.1.3-.3.6-.4.9 0 .1-.1.2-.1.2s0 .1-.1.1c-2.1 4.3-5.3 8.1-9.3 11.1-.3.2-.5.4-.8.6-.1.1-.2.1-.2.2-.2.2-.5.3-.7.5l.1.2c.5-.1.9-.1 1.4-.2.9-.1 1.7-.3 2.6-.5.2 0 .5-.1.7-.2.2 0 .3-.1.5-.1s.5-.1.7-.1c.2-.1.4-.1.6-.2 3.3-.8 6.5-1.9 9.6-3.2-5.3 7.2-12.3 13-20.5 16.8 3.8-.3 7.6-.9 11.3-2 13.3-3.9 24.5-12.9 31.2-25-1.4 7.6-4.4 14.9-8.9 21.3 3.2-2.1 6.1-4.6 8.8-7.3 7.4-7.7 12.3-17.6 13.9-28.1 1.1 5.2 1.5 10.6 1 15.9 23.9-33.3 2-67.8-7.2-76.9 0-.1-.1-.1-.1-.2v0c0 .4 0 .8-.1 1.2-.1.8-.2 1.5-.3 2.2-.2.7-.4 1.5-.6 2.2-.2.7-.5 1.4-.8 2.1-.3.7-.6 1.4-1 2-.4.6-.8 1.3-1.2 1.9-.4.6-.9 1.2-1.4 1.8-.5.6-1 1.1-1.6 1.7-.3.3-.6.6-1 .8-.3.2-.5.4-.8.7-.6.5-1.2.9-1.9 1.3-.6.4-1.3.8-2 1.1l-2.1.9c-.7.3-1.4.5-2.1.7-.7.2-1.5.4-2.2.5-.8.1-1.5.2-2.2.3-.5 0-1.1.1-1.6.1-.8 0-1.5-.1-2.2-.1-.8-.1-1.5-.2-2.2-.3-.8-.1-1.5-.3-2.2-.6.7-.1 1.5-.1 2.2-.3.8-.1 1.5-.3 2.2-.5.7-.2 1.5-.4 2.1-.7l2.1-.9c.7-.3 1.3-.7 2-1.1.6-.4 1.3-.9 1.9-1.3.6-.5 1.2-1 1.7-1.5.6-.5 1.1-1.1 1.6-1.6.5-.6 1-1.2 1.4-1.8.1-.1.1-.2.2-.3.3-.5.7-1.1 1-1.6.4-.7.7-1.3 1-2 .3-.7.6-1.4.8-2.1l.6-2.1c.1-.8.3-1.5.3-2.2.1-.8.1-1.5.1-2.2 0-.5 0-1.1-.1-1.6-.1-.8-.2-1.5-.3-2.2-.1-.8-.3-1.5-.5-2.2-.2-.7-.5-1.4-.7-2.1-.3-.7-.6-1.4-.9-2-.4-.7-.7-1.3-1.1-2-.4-.6-.9-1.2-1.3-1.8-.5-.6-1-1.1-1.5-1.7-.3-.3-.6-.6-.9-.8-1.5-1.2-3-2.2-4.6-3.2-.2-.1-.4-.2-.7-.3-1.3-1.1-2.3-1.4-3.3-1.8z"/></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

+1
View File
@@ -0,0 +1 @@
<svg viewBox="0 0 235 234" xmlns="http://www.w3.org/2000/svg" class="rainbow-logo" preserveAspectRatio="xMinYMin meet"><g fill="none" fill-rule="evenodd"><path fill="#88AEDC" d="m234.04 175.67-75.69 58.28h47.18L234.04 212z"/><path d="m234.04 140.06-121.93 93.89h.02l121.91-93.87zM133.25.95.04 103.51v.02L133.27.95z"/><path fill="#F58F8E" fill-rule="nonzero" d="M.04.95v30.16L39.21.95z"/><path fill="#FEE18A" fill-rule="nonzero" d="M39.21.95.04 31.11v35.9L85.84.95z"/><path fill="#F3F095" fill-rule="nonzero" d="M85.84.95.04 67.01v36.5L133.25.95z"/><path fill="#55C1AE" fill-rule="nonzero" d="M133.27.95.04 103.53v35.59L179.49.95z"/><path fill="#F7B3CE" fill-rule="nonzero" d="M234.04.95h-7.37L.04 175.45v35.93l234-180.18z"/><path fill="#88AEDC" fill-rule="nonzero" d="M179.49.95.04 139.12v36.33L226.67.95z"/><path fill="#F58F8E" fill-rule="nonzero" d="M234.04 31.2.04 211.38v22.57h18.03l215.97-166.3z"/><path fill="#FEE18A" fill-rule="nonzero" d="M234.04 67.65 18.07 233.95H64.7l169.34-130.39z"/><path fill="#F3F095" fill-rule="nonzero" d="M234.04 103.56 64.7 233.95h47.41l121.93-93.89z"/><path fill="#55C1AE" fill-rule="nonzero" d="m234.04 140.08-121.91 93.87h46.22l75.69-58.28z"/><path fill="#F7B3CE" fill-rule="nonzero" d="m234.04 212-28.51 21.95h28.51z"/><g fill="#FFF"><path d="M65.2372 77.75c4.5139.95 7.774 2.8 11.1343 6.3 3.0595 3.2 4.9653 6.85 5.7678 10.95.652 3.45.652 40.55 0 44.05-1.7052 9.1-9.4792 16.2-19.109 17.45-2.0062.25-8.7269.5-14.8458.5H37V77h12.4384c8.8272 0 13.3412.2 15.7988.75ZM51.5449 117v25.6l5.166-.2c4.4637-.15 5.4167-.35 7.4228-1.5 3.9121-2.3 3.9623-2.45 3.9623-24.2 0-21.2 0-21.2-3.6613-23.6-1.8056-1.2-2.558-1.35-7.473-1.55l-5.4168-.15V117ZM130.7895 84.25v7.25h-25.579v18h15.548V124h-15.548l.1003 9.1.1505 9.15 12.6892.15 12.639.1V157h-14.7957c-16.4508 0-19.0087-.3-21.6167-2.6-3.6613-3.2-3.4607-1.15-3.6112-36.3-.1003-21.9.0502-32.25.4013-33.65.7021-2.6 3.6613-5.8 6.2693-6.7 1.5548-.55 5.467-.7 17.7047-.75h15.6483v7.25ZM162.4372 105.1c3.7114 14.25 6.821 25.6 6.9213 25.25.1505-.35 3.3102-12.4 7.0718-26.85l6.8712-26.25 7.8242-.15c5.9183-.1 7.8743.05 7.8743.5s-17.3536 66.2-18.3567 69.5c-.7021 2.3-4.4637 7-6.5702 8.25-2.6582 1.5-6.5703 1.75-8.9777.5-2.1567-1.1-5.0155-4.4-6.47-7.5-.9028-1.9-15.6483-56-19.0588-70l-.3511-1.35h7.8241c7.6737 0 7.8743 0 8.2756 1.1.2006.65 3.4105 12.8 7.122 27Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

+4 -4
View File
@@ -1,11 +1,11 @@
--- ---
slug: "/about" slug: '/about'
date: "2019-05-04" date: '2019-05-04'
title: "👨‍💻 About" title: '👨‍💻 About'
--- ---
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/blob/master/LICENSE" target="blank"> <a href="https://github.com/rahuldkjain/github-profile-readme-generator/blob/master/LICENSE" target="blank">
<img src="https://img.shields.io/github/license/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator licence" /> <img src="https://img.shields.io/github/license/rahuldkjain/github-profile-readme-generator?style=flat-square" alt="github-profile-readme-generator license" />
</a> </a>
**GitHub Profile README Generator** is an OSS(Open Source Software) that provides a cool interface to generate GitHub profile README in markdown. **GitHub Profile README Generator** is an OSS(Open Source Software) that provides a cool interface to generate GitHub profile README in markdown.
+5 -5
View File
@@ -1,7 +1,7 @@
--- ---
slug: "/addons" slug: '/addons'
date: "2019-05-04" date: '2019-05-04'
title: "🚀 Addons" title: '🚀 Addons'
--- ---
GitHub Profile README Generator tool uses few open-source addons developed by other developers. Including such features makes the tool useful. The developers of this tool is very grateful to use these awesome addons. GitHub Profile README Generator tool uses few open-source addons developed by other developers. Including such features makes the tool useful. The developers of this tool is very grateful to use these awesome addons.
@@ -80,7 +80,7 @@ name: Latest blog post workflow
on: on:
schedule: schedule:
# Runs every hour # Runs every hour
- cron: "0 * * * *" - cron: '0 * * * *'
jobs: jobs:
update-readme-with-blog: update-readme-with-blog:
name: Update this repo's README with latest blog posts name: Update this repo's README with latest blog posts
@@ -89,7 +89,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: gautamkrishnar/blog-post-workflow@master - uses: gautamkrishnar/blog-post-workflow@master
with: with:
feed_list: "https://dev.to/feed/rahuldkjain, https://medium.com/feed/@rahuldkjain" feed_list: 'https://dev.to/feed/rahuldkjain, https://medium.com/feed/@rahuldkjain'
``` ```
- Replace the above url list with your own rss feed urls. See [popular-sources](#popular-sources) for a list of common RSS feed urls. - Replace the above url list with your own rss feed urls. See [popular-sources](#popular-sources) for a list of common RSS feed urls.
+3 -3
View File
@@ -1,7 +1,7 @@
--- ---
slug: "/support" slug: '/support'
date: "2019-05-04" date: '2019-05-04'
title: "💵 Support OSS" title: '💵 Support OSS'
--- ---
> Think of giving not as a duty but as a privilege --John D. Rockefeller Hr. > Think of giving not as a duty but as a privilege --John D. Rockefeller Hr.
+4 -4
View File
@@ -1,5 +1,5 @@
import React from "react" import React from 'react';
import SEO from "../components/seo" import SEO from '../components/seo';
const NotFoundPage = () => ( const NotFoundPage = () => (
<div> <div>
@@ -7,6 +7,6 @@ const NotFoundPage = () => (
<h1>NOT FOUND</h1> <h1>NOT FOUND</h1>
<p>You just hit a route that doesn&#39;t exist... the sadness.</p> <p>You just hit a route that doesn&#39;t exist... the sadness.</p>
</div> </div>
) );
export default NotFoundPage export default NotFoundPage;
+43 -10
View File
@@ -1,5 +1,6 @@
@import url("https://fonts.googleapis.com/css2?family=Lato&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Lato&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400&display=swap");
:root { :root {
--grey-05: #f5f6f7; --grey-05: #f5f6f7;
--grey-10: #dfdfe2; --grey-10: #dfdfe2;
@@ -25,12 +26,46 @@ body {
color: var(--grey-90); color: var(--grey-90);
} }
[type="checkbox"] { input[type="checkbox"] {
-webkit-box-shadow: 0 1px 1px var(--grey-90) !important; box-sizing: border-box;
-moz-box-shadow: 0 1px 1px var(--grey-90) !important; padding: 0;
box-shadow: 0 1px 1px var(--grey-90) !important; }
.checkbox-label {
cursor: pointer; cursor: pointer;
border-radius: 0px !important; }
.checkbox-label:hover .tooltiptext {
visibility: visible;
}
.checkbox-label__input {
position: absolute;
opacity: 0;
}
.checkbox-label__control {
position: relative;
display: inline-flex;
flex-shrink: 0;
width: 24px;
height: 24px;
margin-right: 12px;
vertical-align: middle;
background-color: #f7fafc;
border: 2px solid var(--grey-90);
transform: scale(0.75);
}
.checkbox-label__input:checked + .checkbox-label__control:after {
position: absolute;
display: block;
content: "";
top: 5px;
left: 5px;
width: 10px;
height: 10px;
background-color: var(--dark-purple);
}
.checkbox-label__input:hover + .checkbox-label__control,
.checkbox-label__input:focus + .checkbox-label__control {
box-shadow: 0 0 0 10px rgba(10, 10, 35, .1);
} }
.section { .section {
@@ -79,11 +114,6 @@ a {
padding: 2% 5%; padding: 2% 5%;
font-size: 14px; font-size: 14px;
} }
.skillCheckboxLabel:hover .tooltiptext {
visibility: visible;
}
.tooltiptext::after { .tooltiptext::after {
content: " "; content: " ";
position: absolute; position: absolute;
@@ -95,6 +125,7 @@ a {
border-style: solid; border-style: solid;
border-color: transparent var(--grey-90) transparent transparent; border-color: transparent var(--grey-90) transparent transparent;
} }
.workflow { .workflow {
margin-left: 2%; margin-left: 2%;
padding: 1%; padding: 1%;
@@ -120,9 +151,11 @@ a {
.tooltiptext { .tooltiptext {
display: none; display: none;
} }
.warning { .warning {
font-size: 10px; font-size: 10px;
} }
.workflow { .workflow {
font-size: 12px; font-size: 12px;
} }
-695
View File
@@ -1,695 +0,0 @@
import React, { useState, useEffect } from "react"
import gsap from "gsap"
import MarkdownPreview from "../components/markdownPreview"
import Markdown from "../components/markdown"
import Title from "../components/title"
import Subtitle from "../components/subtitle"
import Work from "../components/work"
import Social from "../components/social"
import Addons from "../components/addons"
import Skills from "../components/skills"
import Donate from "../components/donate"
import Support from "../components/support"
import { initialSkillState } from "../constants/skills"
import Loader from "../components/loader"
import SEO from "../components/seo"
import Layout from "../components/layout"
import "./index.css"
import {
ArrowLeftIcon,
CopyIcon,
DownloadIcon,
EyeIcon,
CheckIcon,
MarkdownIcon,
FileCodeIcon,
} from "@primer/octicons-react"
import {
isGitHubUsernameValid,
isMediumUsernameValid,
isTwitterUsernameValid,
} from "../utils/validation"
import {
DEFAULT_PREFIX,
DEFAULT_DATA,
DEFAULT_LINK,
DEFAULT_SOCIAL,
DEFAULT_SUPPORT,
} from "../constants/defaults"
const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
useEffect(() => {
localStorage.setItem(
"cache",
JSON.stringify({
prefix,
data,
link,
social,
skills,
support,
})
)
}, [prefix, data, link, social, skills, support])
}
const DEFAULT_SKILLS = initialSkillState
const IndexPage = () => {
const [prefix, setPrefix] = useState(DEFAULT_PREFIX)
const [data, setData] = useState(DEFAULT_DATA)
const [link, setLink] = useState(DEFAULT_LINK)
const [social, setSocial] = useState(DEFAULT_SOCIAL)
const [skills, setSkills] = useState(DEFAULT_SKILLS)
const [support, setSupport] = useState(DEFAULT_SUPPORT)
const [restore, setRestore] = useState("")
const [generatePreview, setGeneratePreview] = useState(false)
const [generateMarkdown, setGenerateMarkdown] = useState(false)
const [displayLoader, setDisplayLoader] = useState(false)
const [showConfig, setShowConfig] = useState(true)
const [copyObj, setcopyObj] = useState({
isCopied: false,
copiedText: "copy-markdown",
})
const [previewMarkdown, setPreviewMarkdown] = useState({
isPreview: false,
buttonText: "preview",
})
const handleSkillsChange = field => {
let change = { ...skills }
change[field] = !change[field]
setSkills(change)
}
const handlePrefixChange = (field, e) => {
let change = { ...prefix }
change[field] = e.target.value
setPrefix(change)
}
const handleDataChange = (field, e) => {
let change = { ...data }
change[field] = e.target.value
setData(change)
}
const handleLinkChange = (field, e) => {
let change = { ...link }
change[field] = e.target.value
setLink(change)
}
const handleSocialChange = (field, e) => {
let change = { ...social }
change[field] =
field === "discord" ? e.target.value : e.target.value.toLowerCase()
setSocial(change)
}
const handleSupportChange = (field, e) => {
let change = { ...support }
change[field] = e.target.value
setSupport(change)
}
const handleCheckChange = field => {
let change = { ...data }
change[field] = !change[field]
setData(change)
}
const generate = () => {
setShowConfig(false)
var tl = new gsap.timeline()
tl.to(".generate", {
scale: 0,
duration: 0.5,
ease: "Linear.easeNone",
})
tl.set("#form", { display: "none" })
setDisplayLoader(true)
setTimeout(() => {
setDisplayLoader(false)
setGenerateMarkdown(!generateMarkdown)
gsap.fromTo(
"#markdown-box",
{
scale: 0.2,
},
{
scale: 1,
duration: 0.5,
ease: "Linear.easeNone",
}
)
gsap.fromTo(
"#support",
{
autoAlpha: 0,
},
{
autoAlpha: 1,
duration: 2,
ease: "Linear.easeNone",
}
)
document.body.scrollTop = 0 // For Safari
document.documentElement.scrollTop = 0 // For Chrome, Firefox, IE and Opera
}, 3000)
}
const trimDataValues = (item, setItem) => {
const dataObj = { ...item }
Object.keys(dataObj).forEach(k =>
typeof dataObj[k] === "string" ? (dataObj[k] = dataObj[k].trim()) : null
)
setItem(dataObj)
}
const handleGenerate = () => {
trimDataValues(data, setData)
trimDataValues(social, setSocial)
trimDataValues(link, setLink)
resetCopyMarkdownButton()
if (
data.visitorsBadge ||
data.githubProfileTrophy ||
data.githubStats ||
data.topLanguages ||
data.streakStats
) {
if (social.github && isGitHubUsernameValid(social.github)) {
generate()
}
} else if (data.twitterBadge) {
if (social.twitter && isTwitterUsernameValid(social.twitter)) {
generate()
}
} else if (social.github) {
if (isGitHubUsernameValid(social.github)) {
generate()
}
} else {
generate()
}
}
const handleGeneratePreview = () => {
setGenerateMarkdown(!generateMarkdown)
setGeneratePreview(!generatePreview)
if (!generatePreview) {
gsap.set("#copy-button, #download-md-button, #download-json-button", {
visibility: "hidden",
})
setPreviewMarkdown({
isPreview: true,
buttonText: "markdown",
})
} else {
gsap.set("#copy-button, #download-md-button, #download-json-button", {
visibility: "visible",
})
gsap.to("#copy-button", {
border: "2px solid #3b3b4f",
duration: 1,
})
setPreviewMarkdown({
isPreview: false,
buttonText: "preview",
})
resetCopyMarkdownButton()
}
}
const resetCopyMarkdownButton = () => {
var el = document.getElementById("copy-markdown")
if (el) {
gsap.set("#copy-markdown", {
color: "#0a0a23",
})
}
setcopyObj({
isCopied: false,
copiedText: "copy-markdown",
})
}
const setCopyMarkdownButton = () => {
var el = document.getElementById("copy-markdown")
if (el) {
gsap.set("#copy-markdown", {
color: "#00471b",
})
}
gsap.fromTo(
"#copy-button",
{
scale: 0.5,
},
{
scale: 1,
ease: "elastic.in",
border: "2px solid #00471b",
duration: 0.5,
}
)
setcopyObj({
isCopied: true,
copiedText: "copied",
})
}
const handleCopyToClipboard = () => {
var range = document.createRange()
range.selectNode(document.getElementById("markdown-content"))
window.getSelection().removeAllRanges() // clear current selection
window.getSelection().addRange(range) // to select text
document.execCommand("copy")
window.getSelection().removeAllRanges()
setCopyMarkdownButton()
}
const handleDownloadMarkdown = () => {
var markdownContent = document.getElementById("markdown-content")
var tempElement = document.createElement("a")
tempElement.setAttribute(
"href",
"data:text/markdown;charset=utf-8," +
encodeURIComponent(markdownContent.innerText)
)
tempElement.setAttribute("download", "README.md")
tempElement.style.display = "none"
document.body.appendChild(tempElement)
tempElement.click()
document.body.removeChild(tempElement)
}
const handleDownloadJson = () => {
var tempElement = document.createElement("a")
tempElement.setAttribute(
"href",
`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify({ prefix, data, link, social, skills })
)}`
)
tempElement.setAttribute("download", "data.json")
tempElement.style.display = "none"
document.body.appendChild(tempElement)
tempElement.click()
document.body.removeChild(tempElement)
}
const handleBackToEdit = () => {
setGeneratePreview(false)
setGenerateMarkdown(false)
setShowConfig(true)
gsap.set("#form", {
display: "",
})
gsap.to(".generate", {
scale: 1,
})
}
const setInitialValues = () => {
const cache = JSON.parse(localStorage.getItem("cache"))
if (!cache) {
return
}
setPrefix(
cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX
)
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA)
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK)
setSocial(
cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL
)
const cacheSkills = mergeDefaultWithNewDataSkills(
DEFAULT_SKILLS,
cache.skills
)
setSkills(cacheSkills || DEFAULT_SKILLS)
setSupport(
cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT
)
}
useEffect(() => {
gsap.fromTo(
".generate",
{
boxShadow: "0 0 0 0px rgba(59, 59, 79, 0.4)",
},
{
boxShadow: "0 0 0 10px rgba(59, 59, 79, 0)",
repeat: -1,
duration: 1,
}
)
// set initial values
setInitialValues()
}, [])
// keep cache updated
KeepCacheUpdated({ prefix, data, link, social, skills, support })
const handleResetForm = () => {
setPrefix(DEFAULT_PREFIX)
setData(DEFAULT_DATA)
setLink(DEFAULT_LINK)
setSocial(DEFAULT_SOCIAL)
setSkills(DEFAULT_SKILLS)
}
const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) => {
return Object.keys(defaultSkills).reduce((previous, currentKey) => {
let currentSelected = false
if (newSkills[currentKey]) {
currentSelected = true
}
return {
...previous,
[currentKey]: currentSelected,
}
}, {})
}
const handleRestore = () => {
try {
const restoreData = JSON.parse(restore)
if (!restoreData) {
return
}
setPrefix(restoreData.prefix || DEFAULT_PREFIX)
setData(restoreData.data || DEFAULT_DATA)
setLink(restoreData.link || DEFAULT_LINK)
setSocial(restoreData.social || DEFAULT_SOCIAL)
const restoreDataSkills = mergeDefaultWithNewDataSkills(
DEFAULT_SKILLS,
restoreData.skills
)
setSkills(restoreDataSkills || DEFAULT_SKILLS)
} catch (error) {
} finally {
setRestore("")
}
}
const handleFileInput = e => {
const file = e.target.files[0]
const reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onload = () => {
setRestore(reader.result)
}
}
return (
<Layout>
<div className="m-4 sm:p-4">
<SEO title="GitHub Profile Readme Generator" />
<div id="form">
<Title
data={data}
prefix={prefix}
handleDataChange={handleDataChange}
handlePrefixChange={handlePrefixChange}
/>
<Subtitle data={data} handleDataChange={handleDataChange} />
<Work
prefix={prefix}
data={data}
link={link}
handlePrefixChange={handlePrefixChange}
handleLinkChange={handleLinkChange}
handleDataChange={handleDataChange}
/>
<Skills skills={skills} handleSkillsChange={handleSkillsChange} />
<Social social={social} handleSocialChange={handleSocialChange} />
<Addons
data={data}
social={social}
handleCheckChange={handleCheckChange}
handleDataChange={handleDataChange}
/>
<Support
support={support}
handleSupportChange={handleSupportChange}
/>
<div className="section">
{(data.visitorsBadge ||
data.githubProfileTrophy ||
data.githubStats ||
data.topLanguages ||
data.streakStats) &&
!social.github ? (
<div className="warning">
* Please add github username to use these add-ons
</div>
) : (
""
)}
{social.github && !isGitHubUsernameValid(social.github) ? (
<div className="warning">
* GitHub username is invalid, please add a valid username
</div>
) : (
""
)}
{social.medium && !isMediumUsernameValid(social.medium) ? (
<div className="warning">
* Medium username is invalid, please add a valid username (with
@)
</div>
) : (
""
)}
{data.mediumDynamicBlogs && !social.medium ? (
<div className="warning">
* Please add medium username to display latest blogs dynamically
</div>
) : (
""
)}
{data.devDynamicBlogs && !social.dev ? (
<div className="warning">
* Please add dev.to username to display latest blogs dynamically
</div>
) : (
""
)}
{data.rssDynamicBlogs && !social.rssurl ? (
<div className="warning">
* Please add your rss feed url to display latest blogs
dynamically from your personal blog
</div>
) : (
""
)}
{data.twitterBadge && !social.twitter ? (
<div className="warning">
* Please add twitter username to use these add-ons
</div>
) : (
""
)}
{social.twitter && !isTwitterUsernameValid(social.twitter) ? (
<div className="warning">
* Twitter username is invalid, please add a valid username
</div>
) : (
""
)}
</div>
<div className="flex items-center justify-center w-full">
<div
className="text-xs sm:text-xl font-medium border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 sm:py-2 px-2 sm:px-4 generate"
tabIndex="0"
role="button"
onClick={handleGenerate}
onKeyDown={e => e.keyCode === 13 && handleGenerate()}
>
Generate README
</div>
</div>
</div>
{displayLoader ? <Loader /> : ""}
{generateMarkdown || generatePreview ? (
<div className="markdown-section p-4 sm:py-4 sm:px-10">
<div className="w-full flex justify-between items-center">
<button
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
onClick={handleBackToEdit}
>
<ArrowLeftIcon size={24} />
<span className="hidden sm:block"> back to edit</span>
</button>
<button
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
id="copy-button"
onClick={handleCopyToClipboard}
>
{copyObj.isCopied === true ? (
<CheckIcon size={24} />
) : (
<CopyIcon size={24} />
)}
<span className="hidden sm:block" id="copy-markdown">
{copyObj.copiedText}
</span>
</button>
<button
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
id="download-md-button"
onClick={handleDownloadMarkdown}
>
<DownloadIcon size={24} />
<span className="hidden sm:block" id="download-markdown">
download markdown
</span>
</button>
<button
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
id="download-json-button"
onClick={handleDownloadJson}
>
<FileCodeIcon size={24} />
<span className="hidden sm:block" id="download-json">
download backup
</span>
</button>
<button
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
onClick={handleGeneratePreview}
>
{previewMarkdown.isPreview ? (
<MarkdownIcon size={16} />
) : (
<EyeIcon size={16} />
)}
<span className="hidden sm:block ml-1" id="preview-markdown">
{previewMarkdown.buttonText}
</span>
</button>
</div>
<div className="w-full flex justify-center items-center">
<div
className="w-full text-sm text-gray-900 shadow-xl mt-2 p-4 bg-gray-100 border-2 border-solid border-gray-800"
id="markdown-box"
>
{generatePreview ? (
<MarkdownPreview
prefix={prefix}
data={data}
link={link}
social={social}
skills={skills}
support={support}
/>
) : (
""
)}
{generateMarkdown ? (
<Markdown
prefix={prefix}
data={data}
link={link}
social={social}
skills={skills}
support={support}
/>
) : (
""
)}
</div>
</div>
<div className="mt-10" id="support">
<Donate />
</div>
</div>
) : (
""
)}
<div
className={
"w-full shadow flex flex-col justify-center items-start mt-16 border-2 border-solid border-gray-600 py-2 px-4 " +
(!showConfig ? "hidden" : "block")
}
>
<div className="flex justify-between items-center w-full">
<div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2">
Config options
<span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1">
new feature
</span>
</div>
<button
className="text-xxs sm:text-sm border-2 w-auto px-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center"
onClick={handleResetForm}
>
Reset form
</button>
</div>
<div className="w-full flex justify-start items-center my-4">
<input
type="text"
className="outline-none w-1/2 mr-6 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix"
placeholder="Paste JSON code or upload file"
value={restore}
onChange={e => setRestore(e.target.value)}
/>
<div className="overflow-hidden relative w-64 mt-4 mb-4">
<input
className="cursor-pointer absolute block opacity-0 pin-r pin-t before:cursor-pointer"
type="file"
name="vacancyImageFiles"
onChange={handleFileInput}
/>
<button className="text-xxs sm:text-sm border-2 w-40 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1">
Upload json file
</button>
</div>
</div>
<button
className="mr-5 mb-10 text-xxs sm:text-sm border-2 w-32 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1"
onClick={handleRestore}
>
Restore
</button>
<div className="flex flex-col items-start justify-center">
<div className="text-green-700 font-medium">Tips</div>
<div className="text-sm sm:text-lg text-gray-700">
* Enter the downloaded JSON text to restore.
</div>
<div className="text-sm sm:text-lg text-gray-700">
* Press reset to reset the form.
</div>
</div>
</div>
</div>
</Layout>
)
}
export default IndexPage
+494
View File
@@ -0,0 +1,494 @@
import React, { useState, useEffect } from 'react';
import gsap from 'gsap';
import { ArrowLeftIcon, CopyIcon, DownloadIcon, EyeIcon, CheckIcon, MarkdownIcon, FileCodeIcon } from '@primer/octicons-react';
import MarkdownPreview from '../components/markdownPreview';
import Markdown from '../components/markdown';
import Title from '../components/title';
import Subtitle from '../components/subtitle';
import Work from '../components/work';
import Social from '../components/social';
import Addons from '../components/addons';
import Skills from '../components/skills';
import Donate from '../components/donate';
import Support from '../components/support';
import { initialSkillState } from '../constants/skills';
import Loader from '../components/loader';
import SEO from '../components/seo';
import Layout from '../components/layout';
import './index.css';
import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../utils/validation';
import { DEFAULT_PREFIX, DEFAULT_DATA, DEFAULT_LINK, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
useEffect(() => {
localStorage.setItem(
'cache',
JSON.stringify({
prefix,
data,
link,
social,
skills,
support,
}),
);
}, [prefix, data, link, social, skills, support]);
};
const DEFAULT_SKILLS = initialSkillState;
const IndexPage = () => {
const [prefix, setPrefix] = useState(DEFAULT_PREFIX);
const [data, setData] = useState(DEFAULT_DATA);
const [link, setLink] = useState(DEFAULT_LINK);
const [social, setSocial] = useState(DEFAULT_SOCIAL);
const [skills, setSkills] = useState(DEFAULT_SKILLS);
const [support, setSupport] = useState(DEFAULT_SUPPORT);
const [restore, setRestore] = useState('');
const [generatePreview, setGeneratePreview] = useState(false);
const [generateMarkdown, setGenerateMarkdown] = useState(false);
const [displayLoader, setDisplayLoader] = useState(false);
const [showConfig, setShowConfig] = useState(true);
const [copyObj, setcopyObj] = useState({
isCopied: false,
copiedText: 'copy-markdown',
});
const [previewMarkdown, setPreviewMarkdown] = useState({
isPreview: false,
buttonText: 'preview',
});
const handleSkillsChange = (field) => {
const change = { ...skills };
change[field] = !change[field];
setSkills(change);
};
const handlePrefixChange = (field, e) => {
const change = { ...prefix };
change[field] = e.target.value;
setPrefix(change);
};
const handleDataChange = (field, e) => {
const change = { ...data };
change[field] = e.target.value;
setData(change);
};
const handleLinkChange = (field, e) => {
const change = { ...link };
change[field] = e.target.value;
setLink(change);
};
const handleSocialChange = (field, e) => {
const change = { ...social };
change[field] = field === 'discord' ? e.target.value : e.target.value.toLowerCase();
setSocial(change);
};
const handleSupportChange = (field, e) => {
const change = { ...support };
change[field] = e.target.value;
setSupport(change);
};
const handleCheckChange = (field) => {
const change = { ...data };
change[field] = !change[field];
setData(change);
};
const generate = () => {
setShowConfig(false);
const tl = gsap.timeline();
tl.to('.generate', {
scale: 0,
duration: 0.5,
ease: 'Linear.easeNone',
});
tl.set('#form', { display: 'none' });
setDisplayLoader(true);
setTimeout(() => {
setDisplayLoader(false);
setGenerateMarkdown(!generateMarkdown);
gsap.fromTo(
'#markdown-box',
{
scale: 0.2,
},
{
scale: 1,
duration: 0.5,
ease: 'Linear.easeNone',
},
);
gsap.fromTo(
'#support',
{
autoAlpha: 0,
},
{
autoAlpha: 1,
duration: 2,
ease: 'Linear.easeNone',
},
);
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
}, 3000);
};
const trimDataValues = (item, setItem) => {
const dataObj = { ...item };
Object.keys(dataObj).forEach((k) => {
if (typeof dataObj[k] === 'string') {
dataObj[k] = dataObj[k].trim();
}
});
setItem(dataObj);
};
const resetCopyMarkdownButton = () => {
const el = document.getElementById('copy-markdown');
if (el) {
gsap.set('#copy-markdown', {
color: '#0a0a23',
});
}
setcopyObj({
isCopied: false,
copiedText: 'copy-markdown',
});
};
const handleGenerate = () => {
trimDataValues(data, setData);
trimDataValues(social, setSocial);
trimDataValues(link, setLink);
resetCopyMarkdownButton();
if (data.visitorsBadge || data.githubProfileTrophy || data.githubStats || data.topLanguages || data.streakStats) {
if (social.github && isGitHubUsernameValid(social.github)) {
generate();
}
} else if (data.twitterBadge) {
if (social.twitter && isTwitterUsernameValid(social.twitter)) {
generate();
}
} else if (social.github) {
if (isGitHubUsernameValid(social.github)) {
generate();
}
} else {
generate();
}
};
const handleGeneratePreview = () => {
setGenerateMarkdown(!generateMarkdown);
setGeneratePreview(!generatePreview);
if (!generatePreview) {
gsap.set('#copy-button, #download-md-button, #download-json-button', {
visibility: 'hidden',
});
setPreviewMarkdown({
isPreview: true,
buttonText: 'markdown',
});
} else {
gsap.set('#copy-button, #download-md-button, #download-json-button', {
visibility: 'visible',
});
gsap.to('#copy-button', {
border: '2px solid #3b3b4f',
duration: 1,
});
setPreviewMarkdown({
isPreview: false,
buttonText: 'preview',
});
resetCopyMarkdownButton();
}
};
const setCopyMarkdownButton = () => {
const el = document.getElementById('copy-markdown');
if (el) {
gsap.set('#copy-markdown', {
color: '#00471b',
});
}
gsap.fromTo(
'#copy-button',
{
scale: 0.5,
},
{
scale: 1,
ease: 'elastic.in',
border: '2px solid #00471b',
duration: 0.5,
},
);
setcopyObj({
isCopied: true,
copiedText: 'copied',
});
};
const handleCopyToClipboard = () => {
const range = document.createRange();
range.selectNode(document.getElementById('markdown-content'));
window.getSelection().removeAllRanges(); // clear current selection
window.getSelection().addRange(range); // to select text
document.execCommand('copy');
window.getSelection().removeAllRanges();
setCopyMarkdownButton();
};
const handleDownloadMarkdown = () => {
const markdownContent = document.getElementById('markdown-content');
const tempElement = document.createElement('a');
tempElement.setAttribute('href', `data:text/markdown;charset=utf-8,${encodeURIComponent(markdownContent.innerText)}`);
tempElement.setAttribute('download', 'README.md');
tempElement.style.display = 'none';
document.body.appendChild(tempElement);
tempElement.click();
document.body.removeChild(tempElement);
};
const handleDownloadJson = () => {
const tempElement = document.createElement('a');
tempElement.setAttribute('href', `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify({ prefix, data, link, social, skills, support }))}`);
tempElement.setAttribute('download', 'data.json');
tempElement.style.display = 'none';
document.body.appendChild(tempElement);
tempElement.click();
document.body.removeChild(tempElement);
};
const handleBackToEdit = () => {
setGeneratePreview(false);
setGenerateMarkdown(false);
setShowConfig(true);
gsap.set('#form', {
display: '',
});
gsap.to('.generate', {
scale: 1,
});
};
const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) =>
Object.keys(defaultSkills).reduce((previous, currentKey) => {
let currentSelected = false;
if (newSkills[currentKey]) {
currentSelected = true;
}
return {
...previous,
[currentKey]: currentSelected,
};
}, {});
const setInitialValues = () => {
const cache = JSON.parse(localStorage.getItem('cache'));
if (!cache) {
return;
}
setPrefix(cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX);
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA);
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK);
setSocial(cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL);
const cacheSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, cache.skills);
setSkills(cacheSkills || DEFAULT_SKILLS);
setSupport(cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT);
};
useEffect(() => {
gsap.fromTo(
'.generate',
{
boxShadow: '0 0 0 0px rgba(59, 59, 79, 0.4)',
},
{
boxShadow: '0 0 0 10px rgba(59, 59, 79, 0)',
repeat: -1,
duration: 1,
},
);
// set initial values
setInitialValues();
}, []);
// keep cache updated
KeepCacheUpdated({ prefix, data, link, social, skills, support });
const handleResetForm = () => {
setPrefix(DEFAULT_PREFIX);
setData(DEFAULT_DATA);
setLink(DEFAULT_LINK);
setSocial(DEFAULT_SOCIAL);
setSkills(DEFAULT_SKILLS);
setSupport(DEFAULT_SUPPORT);
};
const handleRestore = () => {
try {
const restoreData = JSON.parse(restore);
if (!restoreData) {
return;
}
setPrefix(restoreData.prefix || DEFAULT_PREFIX);
setData(restoreData.data || DEFAULT_DATA);
setLink(restoreData.link || DEFAULT_LINK);
setSocial(restoreData.social || DEFAULT_SOCIAL);
setSupport(restoreData.support || DEFAULT_SUPPORT);
const restoreDataSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, restoreData.skills);
setSkills(restoreDataSkills || DEFAULT_SKILLS);
} catch (error) {
throw new Error(error);
} finally {
setRestore('');
}
};
const handleFileInput = (e) => {
const file = e.target.files[0];
if (file && file.type === 'application/json') {
const reader = new FileReader();
reader.readAsText(file, 'UTF-8');
reader.onload = () => {
setRestore(reader.result);
};
}
};
return (
<Layout>
<div className="m-4 sm:p-4">
<SEO title="GitHub Profile Readme Generator" />
<div id="form">
<Title data={data} prefix={prefix} handleDataChange={handleDataChange} handlePrefixChange={handlePrefixChange} />
<Subtitle data={data} handleDataChange={handleDataChange} />
<Work prefix={prefix} data={data} link={link} handlePrefixChange={handlePrefixChange} handleLinkChange={handleLinkChange} handleDataChange={handleDataChange} />
<Skills skills={skills} handleSkillsChange={handleSkillsChange} />
<Social social={social} handleSocialChange={handleSocialChange} />
<Addons data={data} social={social} handleCheckChange={handleCheckChange} handleDataChange={handleDataChange} />
<Support support={support} handleSupportChange={handleSupportChange} />
<div className="section">
{(data.visitorsBadge || data.githubProfileTrophy || data.githubStats || data.topLanguages || data.streakStats) && !social.github ? <div className="warning">* Please add github username to use these add-ons</div> : ''}
{social.github && !isGitHubUsernameValid(social.github) ? <div className="warning">* GitHub username is invalid, please add a valid username</div> : ''}
{social.medium && !isMediumUsernameValid(social.medium) ? <div className="warning">* Medium username is invalid, please add a valid username (with @)</div> : ''}
{data.mediumDynamicBlogs && !social.medium ? <div className="warning">* Please add medium username to display latest blogs dynamically</div> : ''}
{data.devDynamicBlogs && !social.dev ? <div className="warning">* Please add dev.to username to display latest blogs dynamically</div> : ''}
{data.rssDynamicBlogs && !social.rssurl ? <div className="warning">* Please add your rss feed url to display latest blogs dynamically from your personal blog</div> : ''}
{data.twitterBadge && !social.twitter ? <div className="warning">* Please add twitter username to use these add-ons</div> : ''}
{social.twitter && !isTwitterUsernameValid(social.twitter) ? <div className="warning">* Twitter username is invalid, please add a valid username</div> : ''}
</div>
<div className="flex items-center justify-center w-full">
<div className="text-xs sm:text-xl font-medium border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 sm:py-2 px-2 sm:px-4 generate" tabIndex="0" role="button" onClick={handleGenerate} onKeyDown={(e) => e.keyCode === 13 && handleGenerate()}>
Generate README
</div>
</div>
</div>
{displayLoader ? <Loader /> : ''}
{generateMarkdown || generatePreview ? (
<div className="markdown-section p-4 sm:py-4 sm:px-10">
<div className="w-full flex justify-between items-center">
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" onClick={handleBackToEdit}>
<ArrowLeftIcon size={24} />
<span className="hidden sm:block"> back to edit</span>
</button>
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="copy-button" onClick={handleCopyToClipboard}>
{copyObj.isCopied === true ? <CheckIcon size={24} /> : <CopyIcon size={24} />}
<span className="hidden sm:block" id="copy-markdown">
{copyObj.copiedText}
</span>
</button>
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="download-md-button" onClick={handleDownloadMarkdown}>
<DownloadIcon size={24} />
<span className="hidden sm:block" id="download-markdown">
download markdown
</span>
</button>
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="download-json-button" onClick={handleDownloadJson}>
<FileCodeIcon size={24} />
<span className="hidden sm:block" id="download-json">
download backup
</span>
</button>
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" onClick={handleGeneratePreview}>
{previewMarkdown.isPreview ? <MarkdownIcon size={16} /> : <EyeIcon size={16} />}
<span className="hidden sm:block ml-1" id="preview-markdown">
{previewMarkdown.buttonText}
</span>
</button>
</div>
<div className="w-full flex justify-center items-center">
<div className="w-full text-sm text-gray-900 shadow-xl mt-2 p-4 bg-gray-100 border-2 border-solid border-gray-800" id="markdown-box">
{generatePreview ? <MarkdownPreview prefix={prefix} data={data} link={link} social={social} skills={skills} support={support} /> : ''}
{generateMarkdown ? <Markdown prefix={prefix} data={data} link={link} social={social} skills={skills} support={support} /> : ''}
</div>
</div>
<div className="mt-10" id="support">
<Donate />
</div>
</div>
) : (
''
)}
<div className={`w-full shadow flex flex-col justify-center items-start mt-16 border-2 border-solid border-gray-600 py-2 px-4 ${!showConfig ? 'hidden' : 'block'}`}>
<div className="flex justify-between items-center w-full">
<div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2">
Config options
<span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1">new feature</span>
</div>
<button type="button" className="text-xxs sm:text-sm border-2 w-auto px-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center" onClick={handleResetForm}>
Reset form
</button>
</div>
<div className="w-full flex justify-start items-center my-4">
<input type="text" className="outline-none w-1/2 mr-6 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix" placeholder="Paste JSON code or upload file" value={restore} onChange={(e) => setRestore(e.target.value)} />
<div className="overflow-hidden relative w-64 mt-4 mb-4">
<input className="cursor-pointer absolute block opacity-0 pin-r pin-t before:cursor-pointer" type="file" name="vacancyImageFiles" onChange={handleFileInput} />
<button type="button" className="text-xxs sm:text-sm border-2 w-40 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1">
Upload json file
</button>
</div>
</div>
<button type="button" className="mr-5 mb-10 text-xxs sm:text-sm border-2 w-32 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1" onClick={handleRestore}>
Restore
</button>
<div className="flex flex-col items-start justify-center">
<div className="text-green-700 font-medium">Tips</div>
<div className="text-sm sm:text-lg text-gray-700">* Enter the downloaded JSON text to restore.</div>
<div className="text-sm sm:text-lg text-gray-700">* Press reset to reset the form.</div>
</div>
</div>
</div>
</Layout>
);
};
export default IndexPage;
-48
View File
@@ -1,48 +0,0 @@
// If you don't want to use TypeScript you can delete this file!
import React from "react"
import { PageProps, Link, graphql } from "gatsby"
import SEO from "../components/seo"
type DataProps = {
site: {
buildTime: string
}
}
const UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => (
<div>
<SEO title="Using TypeScript" />
<h1>Gatsby supports TypeScript by default!</h1>
<p>
This means that you can create and write <em>.ts/.tsx</em> files for your
pages, components etc. Please note that the <em>gatsby-*.js</em> files
(like gatsby-node.js) currently don't support TypeScript yet.
</p>
<p>
For type checking you'll want to install <em>typescript</em> via npm and
run <em>tsc --init</em> to create a <em>.tsconfig</em> file.
</p>
<p>
You're currently on the page "{path}" which was built on{" "}
{data.site.buildTime}.
</p>
<p>
To learn more, head over to our{" "}
<a href="https://www.gatsbyjs.org/docs/typescript/">
documentation about TypeScript
</a>
.
</p>
<Link to="/">Go back to the homepage</Link>
</div>
)
export default UsingTypescript
export const query = graphql`
{
site {
buildTime(formatString: "YYYY-MM-DD hh:mm a z")
}
}
`
+10 -16
View File
@@ -1,36 +1,30 @@
import React from "react" import React from 'react';
import { graphql } from "gatsby" import { graphql } from 'gatsby';
// import Header from '../components/header' // import Header from '../components/header'
// import Footer from '../components/footer' // import Footer from '../components/footer'
import { Helmet } from "react-helmet" import { Helmet } from 'react-helmet';
import Layout from "../components/layout" import Layout from '../components/layout';
export default function Template({ export default function Template({
data, // this prop will be injected by the GraphQL query below. data, // this prop will be injected by the GraphQL query below.
}) { }) {
const { markdownRemark } = data // data.markdownRemark holds your post data const { markdownRemark } = data; // data.markdownRemark holds your post data
const { frontmatter, html } = markdownRemark const { frontmatter, html } = markdownRemark;
return ( return (
<Layout> <Layout>
<Helmet> <Helmet>
<meta charSet="utf-8" /> <meta charSet="utf-8" />
<title>{frontmatter.title}</title> <title>{frontmatter.title}</title>
<link <link rel="canonical" href={`https://rahuldkjain.github.io/gh-profile-readme-generator`} />
rel="canonical"
href={`https://rahuldkjain.github.io/gh-profile-readme-generator`}
/>
</Helmet> </Helmet>
<div className="m-4 sm:p-10"> <div className="m-4 sm:p-10">
<div className="blog-post"> <div className="blog-post">
<h1 className="text-4xl font-bold">{frontmatter.title}</h1> <h1 className="text-4xl font-bold">{frontmatter.title}</h1>
<div <div className="markdown" dangerouslySetInnerHTML={{ __html: html }} />
className="markdown"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div> </div>
</div> </div>
</Layout> </Layout>
) );
} }
export const pageQuery = graphql` export const pageQuery = graphql`
@@ -44,4 +38,4 @@ export const pageQuery = graphql`
} }
} }
} }
` `;
+18
View File
@@ -0,0 +1,18 @@
import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../validation';
describe('validation', () => {
it('isGitHubUsernameValid', () => {
expect(isGitHubUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
expect(isGitHubUsernameValid('rahuldkjain')).toBe(true);
});
it('isMediumUsernameValid', () => {
expect(isMediumUsernameValid('rahuldkjain')).toBe(false);
expect(isMediumUsernameValid('@rahuldkjain')).toBe(true);
});
it('isTwitterUsernameValid', () => {
expect(isTwitterUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
expect(isTwitterUsernameValid('rahuldkjain')).toBe(true);
});
});
+25 -24
View File
@@ -1,31 +1,32 @@
const githubStatsStylingQueryString = options => { const githubStatsStylingQueryString = (options) => {
const params = { const params = {
show_icons: true, show_icons: true,
...(options.theme && options.theme !== "none") && { theme: options.theme }, ...(options.theme && options.theme !== 'none' && { theme: options.theme }),
...options.titleColor && { "title_color": options.titleColor }, ...(options.titleColor && { title_color: options.titleColor }),
...options.textColor && { "text_color": options.textColor}, ...(options.textColor && { text_color: options.textColor }),
...options.bgColor && { "bg_color": options.bgColor}, ...(options.bgColor && { bg_color: options.bgColor }),
...options.hideBorder && { "hide_border": options.hideBorder}, ...(options.hideBorder && { hide_border: options.hideBorder }),
...options.cacheSeconds && { "cache_seconds": options.cacheSeconds}, ...(options.cacheSeconds && { cache_seconds: options.cacheSeconds }),
...options.locale && { "locale": options.locale}, ...(options.locale && { locale: options.locale }),
} };
const query_string = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&") const queryString = Object.entries(params)
return query_string .map(([key, value]) => `${key}=${value}`)
} .join('&');
return queryString;
};
const streakStatsStylingQueryString = options => { const streakStatsStylingQueryString = (options) => {
const params = { const params = {
...(options.theme && options.theme !== "none") && { theme: options.theme }, ...(options.theme && options.theme !== 'none' && { theme: options.theme }),
} };
const query_string = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&") const queryString = Object.entries(params)
return query_string .map(([key, value]) => `${key}=${value}`)
} .join('&');
return queryString;
};
export const githubStatsLinkGenerator = ({github, options}) => export const githubStatsLinkGenerator = ({ github, options }) => `https://github-readme-stats.vercel.app/api?username=${github}&${githubStatsStylingQueryString(options)}`;
`https://github-readme-stats.vercel.app/api?username=${github}&${githubStatsStylingQueryString(options)}`
export const topLanguagesLinkGenerator = ({github, options}) => export const topLanguagesLinkGenerator = ({ github, options }) => `https://github-readme-stats.vercel.app/api/top-langs?username=${github}&${githubStatsStylingQueryString(options)}&layout=compact`;
`https://github-readme-stats.vercel.app/api/top-langs?username=${github}&${githubStatsStylingQueryString(options)}&layout=compact`
export const streakStatsLinkGenerator = ({github, options}) => export const streakStatsLinkGenerator = ({ github, options }) => `https://github-readme-streak-stats.herokuapp.com/?user=${github}&${streakStatsStylingQueryString(options)}`;
`https://github-readme-streak-stats.herokuapp.com/?user=${github}&${streakStatsStylingQueryString(options)}`
+13 -13
View File
@@ -1,17 +1,17 @@
const isGitHubUsernameValid = username => { const isGitHubUsernameValid = (username) => {
var pattern = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i const pattern = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i;
return pattern.test(username) return pattern.test(username);
} };
const isMediumUsernameValid = username => { const isMediumUsernameValid = (username) => {
if (username) { if (username) {
return username[0] === "@" return username[0] === '@';
} }
return true return true;
} };
const isTwitterUsernameValid = username => { const isTwitterUsernameValid = (username) => {
var pattern = /^[a-zA-Z0-9_]{1,15}$/ const pattern = /^[a-zA-Z0-9_]{1,15}$/;
return pattern.test(username) return pattern.test(username);
} };
export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid };
+18 -63
View File
@@ -1,70 +1,27 @@
import { isMediumUsernameValid } from "../utils/validation" import { isMediumUsernameValid } from './validation';
const latestBlogs = payload => { export default function latestBlogs(payload) {
let rssFeed = "" let rssFeed = '';
if ( if (payload.dev.show && payload.dev.username && payload.rssurl.show && payload.rssurl.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
payload.dev.show && rssFeed = `https://dev.to/feed/${payload.dev.username}, https://medium.com/feed/${payload.medium.username}, ${payload.rssurl.username}`;
payload.dev.username &&
payload.rssurl.show &&
payload.rssurl.username &&
payload.medium.show &&
payload.medium.username &&
isMediumUsernameValid(payload.medium.username)
) {
rssFeed =
"https://dev.to/feed/" +
payload.dev.username +
", https://medium.com/feed/" +
payload.medium.username +
", " +
payload.rssurl.username
} }
//when any two blog providers are selected // when any two blog providers are selected
else if ( else if (payload.dev.show && payload.dev.username && payload.rssurl.show && payload.rssurl.username) {
payload.dev.show && rssFeed = `https://dev.to/feed/${payload.dev.username}, ${payload.rssurl.username}`;
payload.dev.username && } else if (payload.rssurl.show && payload.rssurl.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
payload.rssurl.show && rssFeed = `https://medium.com/feed/${payload.medium.username}, ${payload.rssurl.username}`;
payload.rssurl.username } else if (payload.dev.show && payload.dev.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
) { rssFeed = `https://dev.to/feed/${payload.dev.username}, https://medium.com/feed/${payload.medium.username}`;
rssFeed =
"https://dev.to/feed/" +
payload.dev.username +
", " +
payload.rssurl.username
} else if (
payload.rssurl.show &&
payload.rssurl.username &&
payload.medium.show &&
payload.medium.username &&
isMediumUsernameValid(payload.medium.username)
) {
rssFeed =
"https://medium.com/feed/" +
payload.medium.username +
", " +
payload.rssurl.username
} else if (
payload.dev.show &&
payload.dev.username &&
payload.medium.show &&
payload.medium.username &&
isMediumUsernameValid(payload.medium.username)
) {
rssFeed =
"https://dev.to/feed/" +
payload.dev.username +
", https://medium.com/feed/" +
payload.medium.username
} }
// when only one blog provider is selected // when only one blog provider is selected
else if (payload.dev.show && payload.dev.username) { else if (payload.dev.show && payload.dev.username) {
rssFeed = "https://dev.to/feed/" + payload.dev.username rssFeed = `https://dev.to/feed/${payload.dev.username}`;
} else if (payload.rssurl.show && payload.rssurl.username) { } else if (payload.rssurl.show && payload.rssurl.username) {
rssFeed = payload.rssurl.username rssFeed = payload.rssurl.username;
} else { } else {
rssFeed = "https://medium.com/feed/" + payload.medium.username rssFeed = `https://medium.com/feed/${payload.medium.username}`;
} }
let data = `name: Latest blog post workflow const data = `name: Latest blog post workflow
on: on:
schedule: schedule:
- cron: '0 * * * *' - cron: '0 * * * *'
@@ -77,9 +34,7 @@ jobs:
- uses: gautamkrishnar/blog-post-workflow@master - uses: gautamkrishnar/blog-post-workflow@master
with: with:
max_post_count: "4" max_post_count: "4"
feed_list: "${rssFeed}"` feed_list: "${rssFeed}"`;
return data return data;
} }
export { latestBlogs }
+16 -16
View File
@@ -3,25 +3,25 @@ module.exports = {
theme: { theme: {
extend: {}, extend: {},
fontSize: { fontSize: {
xxs: ".60rem", xxs: '.60rem',
xs: ".75rem", xs: '.75rem',
sm: ".875rem", sm: '.875rem',
tiny: ".875rem", tiny: '.875rem',
base: "1rem", base: '1rem',
lg: "1.125rem", lg: '1.125rem',
xl: "1.25rem", xl: '1.25rem',
"2xl": "1.5rem", '2xl': '1.5rem',
"3xl": "1.875rem", '3xl': '1.875rem',
"4xl": "2.25rem", '4xl': '2.25rem',
"5xl": "3rem", '5xl': '3rem',
"6xl": "4rem", '6xl': '4rem',
"7xl": "5rem", '7xl': '5rem',
}, },
fontFamily: { fontFamily: {
title: ["Lato", "sans-serif"], title: ['Lato', 'sans-serif'],
body: ["Roboto Mono", "monospace"], body: ['Roboto Mono', 'monospace'],
}, },
}, },
variants: {}, variants: {},
plugins: [], plugins: [],
} };