intial eslint pre-commit setup

This commit is contained in:
Rahul Jain
2021-10-31 12:51:09 +05:30
parent fb6389f569
commit 004401a8d1
63 changed files with 4355 additions and 3550 deletions
+1
View File
@@ -0,0 +1 @@
node_modules/**
+16
View File
@@ -0,0 +1,16 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["plugin:react/recommended", "airbnb"],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {}
}
+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
+11 -1
View File
@@ -1,4 +1,14 @@
{ {
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"arrowParens": "avoid", "arrowParens": "avoid",
"semi": false "endOfLine": "auto"
} }
+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
+56 -50
View File
@@ -9,22 +9,23 @@
## 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 needed 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`.
* Discuss 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.
+2 -4
View File
@@ -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(),
} };
+1549 -339
View File
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -4,12 +4,27 @@
"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",
"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",
@@ -31,13 +46,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() });
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();
}) });
}) });
+121 -122
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: '',
@@ -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();
}) });
}) });
+355 -366
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 regularly 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}
link={link}
social={social}
skills={skills} />)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("Title Preview", () => { describe('Title Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />) const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no prefix", () => { it('renders correctly with no prefix', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
const tree = shallow(<TitlePreview prefix={prefix.title} title={""} />) const tree = shallow(<TitlePreview prefix={prefix.title} title={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no title", () => { it('renders correctly with no title', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
const tree = shallow(<TitlePreview title={data.title} prefix={""} />) const tree = shallow(<TitlePreview title={data.title} prefix={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no title and prefix", () => { it('renders correctly with no title and prefix', () => {
const tree = shallow(<TitlePreview />) const tree = shallow(<TitlePreview />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("SubTitle Preview", () => { describe('SubTitle Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />) const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no subtitle", () => { it('renders correctly with no subtitle', () => {
const tree = shallow(<SubTitlePreview subtitle={""} />) const tree = shallow(<SubTitlePreview subtitle={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("SectionTitle Preview", () => { describe('SectionTitle Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
const tree = shallow(<SectionTitle visible={true} label={"dummy"} />) const tree = shallow(<SectionTitle visible={true} label={'dummy'} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no label", () => { it('renders correctly with no label', () => {
const tree = shallow(<SectionTitle visible={true} label={""} />) const tree = shallow(<SectionTitle visible={true} label={''} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with visible false", () => { it('renders correctly with visible false', () => {
const tree = shallow(<SectionTitle visible={false} label={"dummy"} />) const tree = shallow(<SectionTitle visible={false} label={'dummy'} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("DisplayWork Preview", () => { describe('DisplayWork 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;
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />) const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no prefix, link and project", () => { it('renders correctly with no prefix, link and project', () => {
const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />) const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no prefix", () => { it('renders correctly with no prefix', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
let link = DEFAULT_LINK; let link = DEFAULT_LINK;
const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />) const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no project", () => { it('renders correctly with no project', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
let link = DEFAULT_LINK; let link = DEFAULT_LINK;
const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />) const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no link", () => { it('renders correctly with no link', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined}/>) const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no prefix and link", () => { it('renders correctly with no prefix and link', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
const tree = shallow(<DisplayWork project={data.currentWork} />) const tree = shallow(<DisplayWork project={data.currentWork} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no project and link", () => { it('renders correctly with no project and link', () => {
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
const tree = shallow(<DisplayWork prefix={prefix} />) const tree = shallow(<DisplayWork prefix={prefix} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no project and prefix", () => { it('renders correctly with no project and prefix', () => {
let link = DEFAULT_LINK; let link = DEFAULT_LINK;
const tree = shallow(<DisplayWork link={link.currentWork} />) const tree = shallow(<DisplayWork link={link.currentWork} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("DisplaySocial Preview", () => { describe('DisplaySocial Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let social = DEFAULT_SOCIAL; let social = DEFAULT_SOCIAL;
const tree = shallow(<DisplaySocial const tree = shallow(
base="https://codepen.io" <DisplaySocial
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" base="https://codepen.io"
username={social.codepen} icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
/> username={social.codepen}
) />
);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no username", () => { it('renders correctly with no username', () => {
const tree = shallow(<DisplaySocial const tree = shallow(
base="https://codepen.io" <DisplaySocial
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" base="https://codepen.io"
username={""} icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
/> username={''}
) />
);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("VisitorsBadge Preview", () => { describe('VisitorsBadge 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(<VisitorsBadgePreview const tree = shallow(
show={data.visitorsBadge} <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", () => { 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(<VisitorsBadgePreview const tree = shallow(
show={true} <VisitorsBadgePreview
github={social.github} show={true}
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();
}) });
}) });
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 const tree = shallow(<GithubProfileTrophyPreview show={data.githubProfileTrophy} github={social.github} />);
show={data.githubProfileTrophy}
github={social.github}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with show true", () => { 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(<GithubProfileTrophyPreview const tree = shallow(<GithubProfileTrophyPreview show={true} github={social.github} />);
show={true}
github={social.github}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("TwitterBadgePreview Preview", () => { describe('TwitterBadgePreview 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(<TwitterBadgePreview const tree = shallow(<TwitterBadgePreview show={data.twitterBadge} twitter={social.twitter} />);
show={data.twitterBadge}
twitter={social.twitter}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with show true", () => { 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={true}
twitter={social.twitter}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("Work Preview", () => { describe('Work Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let data = DEFAULT_DATA; let data = DEFAULT_DATA;
let prefix = DEFAULT_PREFIX; let prefix = DEFAULT_PREFIX;
let link = DEFAULT_LINK; let link = DEFAULT_LINK;
let props = { data: data, prefix: prefix, link: link } let props = { data: data, prefix: prefix, link: link };
const tree = shallow(<WorkPreview work={props} />) const tree = shallow(<WorkPreview work={props} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("Social Preview", () => { describe('Social Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let social = DEFAULT_SOCIAL; let social = DEFAULT_SOCIAL;
const tree = shallow(<SocialPreview social={social} />) const tree = shallow(<SocialPreview social={social} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("Skills Preview", () => { describe('Skills Preview', () => {
it("renders correctly", () => { it('renders correctly', () => {
let skills = DUMMY_SKILLS.skills let skills = DUMMY_SKILLS.skills;
const tree = shallow(<SkillsPreview skills={skills} />) const tree = shallow(<SkillsPreview skills={skills} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with no skills", () => { it('renders correctly with no skills', () => {
let skills = {} let skills = {};
const tree = shallow(<SkillsPreview skills={skills} />) const tree = shallow(<SkillsPreview skills={skills} />);
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("TopLanguages Preview", () => { describe('TopLanguages 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(<TopLanguagesPreview const tree = shallow(
show={data.topLanguages} <TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
github={social.github} );
options={data.topLanguagesOptions}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
it("renders correctly with show true", () => { 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(<TopLanguagesPreview const tree = shallow(<TopLanguagesPreview show={true} github={social.github} options={data.topLanguagesOptions} />);
show={true}
github={social.github}
options={data.topLanguagesOptions}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
}) });
describe("GitHubStats Preview", () => { describe('GitHubStats 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(<GitHubStatsPreview const tree = shallow(
show={data.githubStats} <GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
github={social.github} );
options={data.githubStatsOptions}
/>)
expect(tree).toMatchSnapshot() expect(tree).toMatchSnapshot();
}) });
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(<GitHubStatsPreview const tree = shallow(<GitHubStatsPreview show={true} github={social.github} options={data.githubStatsOptions} />);
show={true}
github={social.github}
options={data.githubStatsOptions}
/>)
expect(tree).toMatchSnapshot() 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();
}) });
}) });
+101 -144
View File
@@ -1,23 +1,13 @@
import React, { useState, useEffect } from "react" import React, { useState, useEffect } from 'react';
import { withPrefix } from "gatsby" import { withPrefix } from 'gatsby';
import { latestBlogs } from "../utils/workflows" import { latestBlogs } from '../utils/workflows';
import links from "../constants/page-links" import links from '../constants/page-links';
import { import { isMediumUsernameValid, isGitHubUsernameValid } from '../utils/validation';
isMediumUsernameValid, import { ToolsIcon, XCircleIcon } from '@primer/octicons-react';
isGitHubUsernameValid,
} from "../utils/validation"
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react"
const AddonsItem = ({ const AddonsItem = ({ inputId, inputChecked, onInputChange, Options, onIconClick, ...props }) => {
inputId, const [open, setOpen] = useState(false);
inputChecked, const Icon = open ? XCircleIcon : ToolsIcon;
onInputChange,
Options,
onIconClick,
...props
}) => {
const [open, setOpen] = useState(false)
const Icon = open ? XCircleIcon : ToolsIcon
return ( return (
<> <>
@@ -38,7 +28,7 @@ const AddonsItem = ({
id={`${inputId}-open-btn`} id={`${inputId}-open-btn`}
onClick={() => setOpen(!open)} onClick={() => setOpen(!open)}
className="flex ml-3 focus:bg-gray-400" className="flex ml-3 focus:bg-gray-400"
style={{ outline: "none" }} style={{ outline: 'none' }}
> >
<Icon className="transform scale-100 md:scale-125" /> <Icon className="transform scale-100 md:scale-125" />
</button> </button>
@@ -46,21 +36,16 @@ const AddonsItem = ({
</div> </div>
{Options && open && Options} {Options && open && Options}
</> </>
) );
} };
const CustomizeOptions = ({ title, CustomizationOptions }) => ( const CustomizeOptions = ({ title, CustomizationOptions }) => (
<div <div className={`border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8`} style={{ maxWidth: '21rem' }}>
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> <header className="text-base sm:text-lg">{title}</header>
<hr className="border-gray-500" /> <hr className="border-gray-500" />
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4"> <div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">{CustomizationOptions}</div>
{CustomizationOptions}
</div>
</div> </div>
) );
const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => { const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
return ( return (
@@ -69,7 +54,7 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
Style:&nbsp; Style:&nbsp;
<select <select
id="badge-style" id="badge-style"
onChange={e => onBadgeUpdate("badgeStyle", e.target.value)} onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)}
value={badgeOptions.badgeStyle} value={badgeOptions.badgeStyle}
> >
<option value="flat">Flat</option> <option value="flat">Flat</option>
@@ -85,9 +70,7 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
id="badge-color" id="badge-color"
defaultValue={`#${badgeOptions.badgeColor}`} defaultValue={`#${badgeOptions.badgeColor}`}
className="w-6" className="w-6"
onChange={e => onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))}
onBadgeUpdate("badgeColor", e.target.value.replace("#", ""))
}
/> />
</label> </label>
@@ -98,7 +81,7 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
id="badge-label-text" id="badge-label-text"
placeholder="Profile views" placeholder="Profile views"
className="w-2/4 bg-gray-300 pl-2" className="w-2/4 bg-gray-300 pl-2"
onChange={e => onBadgeUpdate("badgeLabel", e.target.value.trim())} onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())}
defaultValue={badgeOptions.badgeLabel} defaultValue={badgeOptions.badgeLabel}
/> />
</label> </label>
@@ -117,14 +100,12 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
alt="profile-visitors-count" alt="profile-visitors-count"
/> />
) : ( ) : (
<span className="text-xxs md:text-sm text-red-600"> <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>
Invalid GitHub username
</span>
)} )}
</span> </span>
</> </>
) );
} };
const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => ( const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
<> <>
@@ -132,7 +113,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
Theme:&nbsp; Theme:&nbsp;
<select <select
id={`${prefix}-theme`} id={`${prefix}-theme`}
onChange={({ target: { value } }) => onUpdate("theme", value)} onChange={({ target: { value } }) => onUpdate('theme', value)}
defaultValue={options.theme} defaultValue={options.theme}
> >
<option value="none">none</option> <option value="none">none</option>
@@ -155,7 +136,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
id={`${prefix}-title-color`} id={`${prefix}-title-color`}
defaultValue={`#${options.titleColor}`} defaultValue={`#${options.titleColor}`}
className="w-6" className="w-6"
onChange={e => onUpdate("titleColor", e.target.value.replace("#", ""))} onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))}
/> />
</label> </label>
<label htmlFor={`${prefix}-text-color`}> <label htmlFor={`${prefix}-text-color`}>
@@ -165,7 +146,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
id={`${prefix}-text-color`} id={`${prefix}-text-color`}
defaultValue={`#${options.textColor}`} defaultValue={`#${options.textColor}`}
className="w-6" className="w-6"
onChange={e => onUpdate("textColor", e.target.value.replace("#", ""))} onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))}
/> />
</label> </label>
<label htmlFor={`${prefix}-bg-color`}> <label htmlFor={`${prefix}-bg-color`}>
@@ -175,7 +156,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
id={`${prefix}-bg-color`} id={`${prefix}-bg-color`}
defaultValue={`#${options.bgColor}`} defaultValue={`#${options.bgColor}`}
className="w-6" className="w-6"
onChange={e => onUpdate("bgColor", e.target.value.replace("#", ""))} onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))}
/> />
</label> </label>
<label htmlFor={`${prefix}-hide-border`} className="checkbox-label"> <label htmlFor={`${prefix}-hide-border`} className="checkbox-label">
@@ -185,7 +166,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
type="checkbox" type="checkbox"
className="checkbox-label__input" className="checkbox-label__input"
checked={options.hideBorder} checked={options.hideBorder}
onChange={e => onUpdate("hideBorder", e.target.checked)} onChange={(e) => onUpdate('hideBorder', e.target.checked)}
/> />
<span class="checkbox-label__control" /> <span class="checkbox-label__control" />
</label> </label>
@@ -198,7 +179,7 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
max={86400} max={86400}
placeholder={1800} placeholder={1800}
defaultValue={options.cacheSeconds} defaultValue={options.cacheSeconds}
onChange={e => onUpdate("cacheSeconds", e.target.value)} onChange={(e) => onUpdate('cacheSeconds', e.target.value)}
/> />
</label> </label>
<label htmlFor={`${prefix}-locale`}> <label htmlFor={`${prefix}-locale`}>
@@ -208,12 +189,12 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
type="text" type="text"
placeholder="en" placeholder="en"
defaultValue={options.locale} defaultValue={options.locale}
onChange={e => onUpdate("locale", e.target.value)} onChange={(e) => onUpdate('locale', e.target.value)}
size="2" size="2"
/> />
</label> </label>
</> </>
) );
const CustomizeStreakStats = ({ prefix, options, onUpdate }) => ( const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
<> <>
@@ -221,7 +202,7 @@ const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
Theme:&nbsp; Theme:&nbsp;
<select <select
id={`${prefix}-theme`} id={`${prefix}-theme`}
onChange={({ target: { value } }) => onUpdate("theme", value)} onChange={({ target: { value } }) => onUpdate('theme', value)}
defaultValue={options.theme} defaultValue={options.theme}
> >
<option value="default">default</option> <option value="default">default</option>
@@ -230,53 +211,53 @@ const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
</select> </select>
</label> </label>
</> </>
) );
const Addons = props => { const Addons = (props) => {
const [debounce, setDebounce] = useState(undefined) const [debounce, setDebounce] = useState(undefined);
const [badgeOptions, setBadgeOptions] = useState({ const [badgeOptions, setBadgeOptions] = useState({
badgeStyle: props.data.badgeStyle, badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor, badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel, badgeLabel: props.data.badgeLabel,
}) });
useEffect(() => { useEffect(() => {
setBadgeOptions({ setBadgeOptions({
badgeStyle: props.data.badgeStyle, badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor, badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel, badgeLabel: props.data.badgeLabel,
}) });
}, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel]) }, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel]);
const [githubStatsOptions, setGithubStatsOptions] = useState({ const [githubStatsOptions, setGithubStatsOptions] = useState({
...props.data.githubStatsOptions, ...props.data.githubStatsOptions,
}) });
useEffect(() => { useEffect(() => {
setGithubStatsOptions({ setGithubStatsOptions({
...props.data.githubStatsOptions, ...props.data.githubStatsOptions,
}) });
}, [props.data.githubStatsOptions]) }, [props.data.githubStatsOptions]);
const [topLanguagesOptions, setTopLanguagesOptions] = useState({ const [topLanguagesOptions, setTopLanguagesOptions] = useState({
...props.data.topLanguagesOptions, ...props.data.topLanguagesOptions,
}) });
useEffect(() => { useEffect(() => {
setTopLanguagesOptions({ setTopLanguagesOptions({
...props.data.topLanguagesOptions, ...props.data.topLanguagesOptions,
}) });
}, [props.data.topLanguagesOptions]) }, [props.data.topLanguagesOptions]);
const [streakStatsOptions, setStreakStatsOptions] = useState({ const [streakStatsOptions, setStreakStatsOptions] = useState({
...props.data.streakStatsOptions, ...props.data.streakStatsOptions,
}) });
useEffect(() => { useEffect(() => {
setStreakStatsOptions({ setStreakStatsOptions({
...props.data.streakStatsOptions, ...props.data.streakStatsOptions,
}) });
}, [props.data.streakStatsOptions]) }, [props.data.streakStatsOptions]);
const blogPostPorkflow = () => { const blogPostPorkflow = () => {
let payload = { let payload = {
@@ -292,64 +273,58 @@ const Addons = props => {
show: props.data.rssDynamicBlogs, show: props.data.rssDynamicBlogs,
username: props.social.rssurl, username: props.social.rssurl,
}, },
} };
var actionContent = latestBlogs(payload) var actionContent = latestBlogs(payload);
var tempElement = document.createElement("a") var tempElement = document.createElement('a');
tempElement.setAttribute( tempElement.setAttribute('href', 'data:text/yaml;charset=utf-8,' + encodeURIComponent(actionContent));
"href", tempElement.setAttribute('download', 'blog-post-workflow.yml');
"data:text/yaml;charset=utf-8," + encodeURIComponent(actionContent) tempElement.style.display = 'none';
) document.body.appendChild(tempElement);
tempElement.setAttribute("download", "blog-post-workflow.yml") tempElement.click();
tempElement.style.display = "none" document.body.removeChild(tempElement);
document.body.appendChild(tempElement) };
tempElement.click()
document.body.removeChild(tempElement)
}
const onBadgeUpdate = (option, value) => { const onBadgeUpdate = (option, value) => {
const callback = () => { const callback = () => {
let newVal = let newVal = option === 'badgeLabel' && value === '' ? 'Profile views' : value;
option === "badgeLabel" && value === "" ? "Profile views" : value setBadgeOptions({ ...badgeOptions, [option]: newVal });
setBadgeOptions({ ...badgeOptions, [option]: newVal }) props.handleDataChange(option, { target: { value: newVal } });
props.handleDataChange(option, { target: { value: newVal } }) };
} clearTimeout(debounce);
clearTimeout(debounce) setDebounce(setTimeout(callback, 300));
setDebounce(setTimeout(callback, 300)) };
}
const onStatsUpdate = (option, value) => { const onStatsUpdate = (option, value) => {
const newStatsOptions = { ...githubStatsOptions, [option]: value } const newStatsOptions = { ...githubStatsOptions, [option]: value };
setGithubStatsOptions(newStatsOptions) setGithubStatsOptions(newStatsOptions);
props.handleDataChange("githubStatsOptions", { props.handleDataChange('githubStatsOptions', {
target: { value: newStatsOptions }, target: { value: newStatsOptions },
}) });
} };
const onTopLangUpdate = (option, value) => { const onTopLangUpdate = (option, value) => {
const newLangOptions = { ...topLanguagesOptions, [option]: value } const newLangOptions = { ...topLanguagesOptions, [option]: value };
setTopLanguagesOptions(newLangOptions) setTopLanguagesOptions(newLangOptions);
props.handleDataChange("topLanguagesOptions", { props.handleDataChange('topLanguagesOptions', {
target: { value: newLangOptions }, target: { value: newLangOptions },
}) });
} };
const onStreakStatsUpdate = (option, value) => { const onStreakStatsUpdate = (option, value) => {
const newStreakStatsOptions = { ...streakStatsOptions, [option]: value } const newStreakStatsOptions = { ...streakStatsOptions, [option]: value };
setStreakStatsOptions(newStreakStatsOptions) setStreakStatsOptions(newStreakStatsOptions);
props.handleDataChange("streakStatsOptions", { props.handleDataChange('streakStatsOptions', {
target: { value: newStreakStatsOptions }, target: { value: newStreakStatsOptions },
}) });
} };
return ( return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10"> <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"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Add-ons</div>
Add-ons
</div>
<AddonsItem <AddonsItem
inputId="visitors-count" inputId="visitors-count"
inputChecked={props.data.visitorsBadge} inputChecked={props.data.visitorsBadge}
onInputChange={() => props.handleCheckChange("visitorsBadge")} onInputChange={() => props.handleCheckChange('visitorsBadge')}
Options={ Options={
<CustomizeOptions <CustomizeOptions
title="Customize Badge" title="Customize Badge"
@@ -368,23 +343,19 @@ const Addons = props => {
<AddonsItem <AddonsItem
inputId="github-profile-trophy" inputId="github-profile-trophy"
inputChecked={props.data.githubProfileTrophy} inputChecked={props.data.githubProfileTrophy}
onInputChange={() => props.handleCheckChange("githubProfileTrophy")} onInputChange={() => props.handleCheckChange('githubProfileTrophy')}
> >
display github trophy display github trophy
</AddonsItem> </AddonsItem>
<AddonsItem <AddonsItem
inputId="github-stats" inputId="github-stats"
inputChecked={props.data.githubStats} inputChecked={props.data.githubStats}
onInputChange={() => props.handleCheckChange("githubStats")} onInputChange={() => props.handleCheckChange('githubStats')}
Options={ Options={
<CustomizeOptions <CustomizeOptions
title="Customize Github Stats Card" title="Customize Github Stats Card"
CustomizationOptions={ CustomizationOptions={
<CustomizeGithubStatsBase <CustomizeGithubStatsBase prefix="stats" options={githubStatsOptions} onUpdate={onStatsUpdate} />
prefix="stats"
options={githubStatsOptions}
onUpdate={onStatsUpdate}
/>
} }
/> />
} }
@@ -394,16 +365,12 @@ const Addons = props => {
<AddonsItem <AddonsItem
inputId="top-languages" inputId="top-languages"
inputChecked={props.data.topLanguages} inputChecked={props.data.topLanguages}
onInputChange={() => props.handleCheckChange("topLanguages")} onInputChange={() => props.handleCheckChange('topLanguages')}
Options={ Options={
<CustomizeOptions <CustomizeOptions
title="Customize Top Skills Card" title="Customize Top Skills Card"
CustomizationOptions={ CustomizationOptions={
<CustomizeGithubStatsBase <CustomizeGithubStatsBase prefix="top-lang" options={topLanguagesOptions} onUpdate={onTopLangUpdate} />
prefix="top-lang"
options={topLanguagesOptions}
onUpdate={onTopLangUpdate}
/>
} }
/> />
} }
@@ -413,16 +380,12 @@ const Addons = props => {
<AddonsItem <AddonsItem
inputId="streak-stats" inputId="streak-stats"
inputChecked={props.data.streakStats} inputChecked={props.data.streakStats}
onInputChange={() => props.handleCheckChange("streakStats")} onInputChange={() => props.handleCheckChange('streakStats')}
Options={ Options={
<CustomizeOptions <CustomizeOptions
title="Customize Streak Stats Card" title="Customize Streak Stats Card"
CustomizationOptions={ CustomizationOptions={
<CustomizeStreakStats <CustomizeStreakStats prefix="streak-stats" options={streakStatsOptions} onUpdate={onStreakStatsUpdate} />
prefix="streak-stats"
options={streakStatsOptions}
onUpdate={onStreakStatsUpdate}
/>
} }
/> />
} }
@@ -432,68 +395,62 @@ const Addons = props => {
<AddonsItem <AddonsItem
inputId="twitter-badge" inputId="twitter-badge"
inputChecked={props.data.twitterBadge} inputChecked={props.data.twitterBadge}
onInputChange={() => props.handleCheckChange("twitterBadge")} onInputChange={() => props.handleCheckChange('twitterBadge')}
> >
display twitter badge display twitter badge
</AddonsItem> </AddonsItem>
<AddonsItem <AddonsItem
inputId="dev-dynamic-blogs" inputId="dev-dynamic-blogs"
inputChecked={props.data.devDynamicBlogs} inputChecked={props.data.devDynamicBlogs}
onInputChange={() => props.handleCheckChange("devDynamicBlogs")} onInputChange={() => props.handleCheckChange('devDynamicBlogs')}
> >
display latest dev.to blogs dynamically (GitHub Action) display latest dev.to blogs dynamically (GitHub Action)
</AddonsItem> </AddonsItem>
<AddonsItem <AddonsItem
inputId="medium-dynamic-blogs" inputId="medium-dynamic-blogs"
inputChecked={props.data.mediumDynamicBlogs} inputChecked={props.data.mediumDynamicBlogs}
onInputChange={() => props.handleCheckChange("mediumDynamicBlogs")} onInputChange={() => props.handleCheckChange('mediumDynamicBlogs')}
> >
display latest medium blogs dynamically (GitHub Action) display latest medium blogs dynamically (GitHub Action)
</AddonsItem> </AddonsItem>
<AddonsItem <AddonsItem
inputId="rss-dynamic-blogs" inputId="rss-dynamic-blogs"
inputChecked={props.data.rssDynamicBlogs} inputChecked={props.data.rssDynamicBlogs}
onInputChange={() => props.handleCheckChange("rssDynamicBlogs")} onInputChange={() => props.handleCheckChange('rssDynamicBlogs')}
> >
display latest blogs from your personal blog dynamically (GitHub Action) display latest blogs from your personal blog dynamically (GitHub Action)
</AddonsItem> </AddonsItem>
{(props.data.devDynamicBlogs && props.social.dev) || {(props.data.devDynamicBlogs && props.social.dev) ||
(props.data.rssDynamicBlogs && props.social.rssurl) || (props.data.rssDynamicBlogs && props.social.rssurl) ||
(props.data.mediumDynamicBlogs && (props.data.mediumDynamicBlogs && props.social.medium && isMediumUsernameValid(props.social.medium)) ? (
props.social.medium &&
isMediumUsernameValid(props.social.medium)) ? (
<div className="workflow"> <div className="workflow">
<div> <div>
download download
<span <span
id="blog-post-worklow-span" id="blog-post-worklow-span"
onClick={blogPostPorkflow} onClick={blogPostPorkflow}
onKeyDown={e => e.keyCode === 13 && blogPostPorkflow()} onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()}
role="button" role="button"
tabIndex="0" tabIndex="0"
style={{ cursor: "pointer", color: "#002ead" }} style={{ cursor: 'pointer', color: '#002ead' }}
> >
{" "} {' '}
blog-post-workflow.yml blog-post-workflow.yml
</span>{" "} </span>{' '}
file(learn file(learn
<a <a href={withPrefix(links.addons)} target="blank" style={{ color: '#002ead' }}>
href={withPrefix(links.addons)} {' '}
target="blank"
style={{ color: "#002ead" }}
>
{" "}
how to setup how to setup
</a> </a>
) )
</div> </div>
</div> </div>
) : ( ) : (
"" ''
)} )}
</div> </div>
) );
} };
export default Addons export default Addons;
+18 -16
View File
@@ -1,19 +1,17 @@
import React from "react" import React from 'react';
const Donate = () => { const Donate = () => {
return ( return (
<> <>
<div className="text-center text-4xl my-2">Support&nbsp; <div className="text-center text-4xl my-2">
<span role="img" aria-label="praying hand emoji">🙏</span> Support&nbsp;
<span role="img" aria-label="praying hand emoji">
🙏
</span>
</div> </div>
<div className="flex flex-col sm:flex-row items-start justify-between"> <div className="flex flex-col sm:flex-row items-start justify-between">
<div className="w-full sm:w-2/3"> <div className="w-full sm:w-2/3">
<div className="text-2xl mb-2"> <div className="text-2xl mb-2">Are you using the tool and happy with it to create your GitHub Profile?</div>
Are you using the tool and happy with it to create your GitHub <div className="text-lg">Your kind support keeps open-source tools like this free for others.</div>
Profile?
</div>
<div className="text-lg">
Your kind support keeps open-source tools like this free for others.
</div>
<div className="mt-4"> <div className="mt-4">
<a <a
className="flex items-center justify-start w-20" className="flex items-center justify-start w-20"
@@ -25,12 +23,16 @@ const Donate = () => {
alt="tweet github profile readme generator" alt="tweet github profile readme generator"
/> />
</a> </a>
Let the world know how you feel using this tool. Share with others Let the world know how you feel using this tool. Share with others on twitter.
on twitter.
</div> </div>
</div> </div>
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center"> <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> <span>
Tip
<span role="img" aria-label="Dollar medal">
💰
</span>
</span>
{/* Ko-Fi */} {/* Ko-Fi */}
<a <a
href="https://ko-fi.com/A0A81XXSX" href="https://ko-fi.com/A0A81XXSX"
@@ -81,7 +83,7 @@ const Donate = () => {
</div> </div>
</div> </div>
</> </>
) );
} };
export default Donate export default Donate;
+18 -34
View File
@@ -1,8 +1,8 @@
import React from "react" import React from 'react';
import links from "../constants/page-links" import links from '../constants/page-links';
import logo from "../images/mdg.png" import logo from '../images/mdg.png';
import discord from "../images/Discord-Logo.png" import discord from '../images/Discord-Logo.png';
import { Link } from "gatsby" import { Link } from 'gatsby';
const Footer = () => { const Footer = () => {
return ( return (
<div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2"> <div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2">
@@ -10,18 +10,10 @@ const Footer = () => {
<div className="sm:ml-0 sm:mr-6 order-last sm:order-none flex"> <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"> <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"> <div className="flex sm:flex-col items-start mb-3 sm:mb-0">
<img <img src={logo} className="hidden sm:block h-24" alt="github profile markdown generator logo" />
src={logo}
className="hidden sm:block h-24"
alt="github profile markdown generator logo"
/>
<div className="mr-2 sm:mr-0"> <div className="mr-2 sm:mr-0">
GitHub Profile{" "} GitHub Profile{' '}
<img <img src={logo} className="inline sm:hidden h-12" alt="github profile markdown generator logo" />
src={logo}
className="inline sm:hidden h-12"
alt="github profile markdown generator logo"
/>
<span className="block sm:inline">README Generator</span> <span className="block sm:inline">README Generator</span>
</div> </div>
</div> </div>
@@ -32,17 +24,17 @@ const Footer = () => {
<strong>Pages</strong> <strong>Pages</strong>
</div> </div>
<div className="ml-2 sm:ml-0"> <div className="ml-2 sm:ml-0">
<Link to={links.addons} activeStyle={{ color: "#002ead" }}> <Link to={links.addons} activeStyle={{ color: '#002ead' }}>
Addons Addons
</Link> </Link>
</div> </div>
<div className="ml-2 sm:ml-0"> <div className="ml-2 sm:ml-0">
<Link to={links.support} activeStyle={{ color: "#002ead" }}> <Link to={links.support} activeStyle={{ color: '#002ead' }}>
Support Support
</Link> </Link>
</div> </div>
<div className="ml-2 sm:ml-0"> <div className="ml-2 sm:ml-0">
<Link to={links.about} activeStyle={{ color: "#002ead" }}> <Link to={links.about} activeStyle={{ color: '#002ead' }}>
About About
</Link> </Link>
</div> </div>
@@ -93,28 +85,20 @@ const Footer = () => {
<strong>Join Community</strong> <strong>Join Community</strong>
</div> </div>
<div className="ml-2 sm:ml-0"> <div className="ml-2 sm:ml-0">
<a <a href="https://discord.gg/HHMs7Eg" aria-label="Discord of the community" target="blank">
href="https://discord.gg/HHMs7Eg" <img src={discord} className="h-12" alt="Discord of the community" />
aria-label="Discord of the community"
target="blank"
>
<img
src={discord}
className="h-12"
alt="Discord of the community"
/>
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div className="py-2 mt-2"> <div className="py-2 mt-2">
Developed in India{" "} Developed in India{' '}
<span role="img" aria-label="india"> <span role="img" aria-label="india">
{" "} {' '}
🇮🇳 🇮🇳
</span> </span>
</div> </div>
</div> </div>
) );
} };
export default Footer export default Footer;
+36 -50
View File
@@ -1,67 +1,61 @@
import React, { useEffect, useState } from "react" import React, { useEffect, useState } from 'react';
import { StarIcon, RepoForkedIcon } from "@primer/octicons-react" import { StarIcon, RepoForkedIcon } from '@primer/octicons-react';
import logo from "../images/mdg.png" import logo from '../images/mdg.png';
import links from "../constants/page-links" import links from '../constants/page-links';
import gsap from "gsap" import gsap from 'gsap';
import axios from "axios" import axios from 'axios';
import { Link } from "gatsby" import { Link } from 'gatsby';
import { act } from "react-dom/test-utils" import { act } from 'react-dom/test-utils';
const Header = props => { const Header = (props) => {
const shouldRequestStats = () => { const shouldRequestStats = () => {
const isFirstRequest = stats.starsCount === 0 const isFirstRequest = stats.starsCount === 0;
const isVisible = window.document.visibilityState === "visible" const isVisible = window.document.visibilityState === 'visible';
const hasFocus = window.document.hasFocus() const hasFocus = window.document.hasFocus();
return isFirstRequest || (isVisible && hasFocus) return isFirstRequest || (isVisible && hasFocus);
} };
const fetchData = async () => { const fetchData = async () => {
if (shouldRequestStats()) { if (shouldRequestStats()) {
var response = await axios.get( var response = await axios.get('https://api.github.com/repos/rahuldkjain/github-profile-readme-generator');
"https://api.github.com/repos/rahuldkjain/github-profile-readme-generator"
)
const { stargazers_count, forks_count } = response.data const { stargazers_count, forks_count } = response.data;
act(() => act(() =>
setstats({ setstats({
starsCount: stargazers_count, starsCount: stargazers_count,
forksCount: forks_count, forksCount: forks_count,
}) })
) );
} }
} };
const [stats, setstats] = useState({ const [stats, setstats] = useState({
starsCount: 0, starsCount: 0,
forksCount: 0, forksCount: 0,
}) });
useEffect(() => { useEffect(() => {
fetchData() fetchData();
setInterval(fetchData, 60000) setInterval(fetchData, 60000);
gsap.set(".star, .fork", { gsap.set('.star, .fork', {
transformOrigin: "center", transformOrigin: 'center',
}) });
gsap.to(".star, .fork", { gsap.to('.star, .fork', {
rotateZ: "360", rotateZ: '360',
duration: 2, duration: 2,
ease: "elastic.inOut", ease: 'elastic.inOut',
repeat: -1, repeat: -1,
yoyo: true, yoyo: true,
}) });
}, []) }, []);
return ( return (
<div className="shadow flex items-center justify-center flex-col mb-2 py-2"> <div className="shadow flex items-center justify-center flex-col mb-2 py-2">
<Link to={links.home}> <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"> <h1 className="text-base font-bold font-title sm:text-2xl font-medium text-blue-800 flex justify-center items-center flex-col">
<img <img src={logo} className="w-12 h-12" alt="github profile markdown generator logo" />
src={logo}
className="w-12 h-12"
alt="github profile markdown generator logo"
/>
<div>{props.heading}</div> <div>{props.heading}</div>
</h1> </h1>
</Link> </Link>
@@ -75,9 +69,7 @@ const Header = props => {
<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"> <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" /> <StarIcon size={16} id="star-icon" className="px-1 w-6 star" />
Star this repo Star this repo
<span className="github-count px-1 sm:px-2"> <span className="github-count px-1 sm:px-2">{stats.starsCount}</span>
{stats.starsCount}
</span>
</div> </div>
</a> </a>
<a <a
@@ -86,20 +78,14 @@ const Header = props => {
target="blank" 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"> <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 <RepoForkedIcon size={16} id="fork-icon" className="px-1 w-6 fork" />
size={16}
id="fork-icon"
className="px-1 w-6 fork"
/>
Fork on GitHub Fork on GitHub
<span className="github-count px-1 sm:px-2"> <span className="github-count px-1 sm:px-2">{stats.forksCount}</span>
{stats.forksCount}
</span>
</div> </div>
</a> </a>
</div> </div>
</div> </div>
) );
} };
export default Header export default Header;
+6 -6
View File
@@ -1,6 +1,6 @@
import React from "react" import React from 'react';
import Header from "./header" import Header from './header';
import Footer from "./footer" import Footer from './footer';
const Layout = ({ children }) => { const Layout = ({ children }) => {
return ( return (
@@ -13,6 +13,6 @@ const Layout = ({ children }) => {
<Footer /> <Footer />
</footer> </footer>
</div> </div>
) );
} };
export default Layout export default Layout;
+23 -23
View File
@@ -1,49 +1,49 @@
import React, { useRef, useEffect } from "react" import React, { useRef, useEffect } from 'react';
import gsap from "gsap" import gsap from 'gsap';
const Loader = () => { const Loader = () => {
let arrow = useRef([]) let arrow = useRef([]);
useEffect(() => { useEffect(() => {
var tl = new gsap.timeline({ repeat: -1 }) var tl = new gsap.timeline({ repeat: -1 });
tl.fromTo( tl.fromTo(
arrow.current, arrow.current,
{ {
y: 0, y: 0,
color: "#3b3b4f", color: '#3b3b4f',
}, },
{ {
y: -50, y: -50,
color: "#d0d0d5", color: '#d0d0d5',
stagger: 0.1, stagger: 0.1,
duration: 0.5, duration: 0.5,
ease: "Linear.easeNone", ease: 'Linear.easeNone',
} }
) );
tl.add("cp") tl.add('cp');
tl.fromTo( tl.fromTo(
arrow.current, arrow.current,
{ {
y: -50, y: -50,
color: "#d0d0d5", color: '#d0d0d5',
}, },
{ {
y: 0, y: 0,
color: "#3b3b4f", color: '#3b3b4f',
stagger: 0.1, stagger: 0.1,
duration: 0.5, duration: 0.5,
ease: "Linear.easeNone", ease: 'Linear.easeNone',
}, },
"cp-=0.3" 'cp-=0.3'
) );
}) });
return ( return (
<div className="loader"> <div className="loader">
<span ref={el => (arrow.current[0] = el)}></span> <span ref={(el) => (arrow.current[0] = el)}></span>
<span ref={el => (arrow.current[1] = el)}></span> <span ref={(el) => (arrow.current[1] = el)}></span>
<span ref={el => (arrow.current[2] = el)}></span> <span ref={(el) => (arrow.current[2] = el)}></span>
<span ref={el => (arrow.current[3] = el)}></span> <span ref={(el) => (arrow.current[3] = el)}></span>
<span ref={el => (arrow.current[4] = el)}></span> <span ref={(el) => (arrow.current[4] = el)}></span>
</div> </div>
) );
} };
export default Loader export default Loader;
+116 -177
View File
@@ -1,23 +1,23 @@
import React from "react" import React from 'react';
import { isMediumUsernameValid } from "../utils/validation" import { isMediumUsernameValid } from '../utils/validation';
import { icons, skills, skillWebsites } from "../constants/skills" import { icons, skills, skillWebsites } from '../constants/skills';
import { import {
githubStatsLinkGenerator, githubStatsLinkGenerator,
topLanguagesLinkGenerator, topLanguagesLinkGenerator,
streakStatsLinkGenerator, streakStatsLinkGenerator,
} from "../utils/link-generators" } from '../utils/link-generators';
const Title = props => { const Title = (props) => {
if (props.prefix && props.title) { if (props.prefix && props.title) {
return ( return (
<> <>
{`<h1 align="center">${props.prefix + " " + props.title}</h1>`} {`<h1 align="center">${props.prefix + ' ' + props.title}</h1>`}
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const SubTitle = props => { const SubTitle = (props) => {
if (props.subtitle) { if (props.subtitle) {
return ( return (
<> <>
@@ -25,22 +25,22 @@ const SubTitle = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const SectionTitle = props => { const SectionTitle = (props) => {
if (props.label) { if (props.label) {
return ( return (
<> <>
{`<h3 align="left">${props.label}</h3>`} {`<h3 align="left">${props.label}</h3>`}
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const DisplayWork = props => { const DisplayWork = (props) => {
if (props.prefix && props.project) { if (props.prefix && props.project) {
if (props.link) { if (props.link) {
return ( return (
@@ -49,7 +49,7 @@ const DisplayWork = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} else { } else {
return ( return (
<> <>
@@ -57,7 +57,7 @@ const DisplayWork = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
} }
if (props.prefix && props.link) { if (props.prefix && props.link) {
@@ -67,28 +67,28 @@ const DisplayWork = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const DisplaySocial = props => { const DisplaySocial = (props) => {
if (props.username) { if (props.username) {
return ( return (
<> <>
{`<a href="${props.base}/${props.username}" target="blank"><img align="center" src="${props.icon}" alt="${props.username}" height="30" width="40" /></a>`} {`<a href="${props.base}/${props.username}" target="blank"><img align="center" src="${props.icon}" alt="${props.username}" height="30" width="40" /></a>`}
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const VisitorsBadge = props => { const VisitorsBadge = (props) => {
let link = let link =
"https://komarev.com/ghpvc/?username=" + 'https://komarev.com/ghpvc/?username=' +
props.github + props.github +
`&label=${props.badgeOptions.badgeLabel}` + `&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` + `&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}` `&style=${props.badgeOptions.badgeStyle}`;
if (props.show) { if (props.show) {
return ( return (
<> <>
@@ -96,15 +96,12 @@ const VisitorsBadge = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const TwitterBadge = props => { const TwitterBadge = (props) => {
let link = let link = 'https://img.shields.io/twitter/follow/' + props.twitter + '?logo=twitter&style=for-the-badge';
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) { if (props.show) {
return ( return (
<> <>
@@ -112,13 +109,12 @@ const TwitterBadge = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const GithubProfileTrophy = props => { const GithubProfileTrophy = (props) => {
let link = let link = 'https://github-profile-trophy.vercel.app/?username=' + props.github;
"https://github-profile-trophy.vercel.app/?username=" + props.github
if (props.show) { if (props.show) {
return ( return (
<> <>
@@ -126,10 +122,10 @@ const GithubProfileTrophy = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const GitHubStats = ({ show, github, options }) => { const GitHubStats = ({ show, github, options }) => {
if (show) { if (show) {
return ( return (
@@ -141,11 +137,11 @@ const GitHubStats = ({ show, github, options }) => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const isSocial = social => { const isSocial = (social) => {
return ( return (
social.dev || social.dev ||
social.twitter || social.twitter ||
@@ -169,11 +165,11 @@ const isSocial = social => {
social.geeks_for_geeks || social.geeks_for_geeks ||
social.discord || social.discord ||
social.rssurl social.rssurl
) );
} };
const DisplaySkills = props => { const DisplaySkills = (props) => {
const listChosenSkills = [] const listChosenSkills = [];
skills.forEach(skill => { skills.forEach((skill) => {
if (props.skills[skill]) { if (props.skills[skill]) {
listChosenSkills.push( listChosenSkills.push(
` `
@@ -181,21 +177,21 @@ const DisplaySkills = props => {
<img src="${icons[skill]}" alt="${skill}" width="40" height="40"/> <img src="${icons[skill]}" alt="${skill}" width="40" height="40"/>
</a> </a>
` `
) );
} }
}) });
return listChosenSkills.length > 0 ? ( return listChosenSkills.length > 0 ? (
<> <>
<SectionTitle label="Languages and Tools:" /> <SectionTitle label="Languages and Tools:" />
{`<p align="left">${listChosenSkills.join(" ")}</p>`} {`<p align="left">${listChosenSkills.join(' ')}</p>`}
<br /> <br />
<br /> <br />
</> </>
) : ( ) : (
"" ''
) );
} };
const DisplayDynamicBlogs = props => { const DisplayDynamicBlogs = (props) => {
if (props.show) { if (props.show) {
return ( return (
<> <>
@@ -206,11 +202,11 @@ const DisplayDynamicBlogs = props => {
{`<!-- BLOG-POST-LIST:END -->`} {`<!-- BLOG-POST-LIST:END -->`}
<br /> <br /> <br /> <br />
</> </>
) );
} }
return "" return '';
} };
const DisplayTopLanguages = props => { const DisplayTopLanguages = (props) => {
if (props.show) { if (props.show) {
if (!props.showStats) { if (!props.showStats) {
return ( return (
@@ -222,7 +218,7 @@ const DisplayTopLanguages = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return ( return (
<> <>
@@ -233,11 +229,11 @@ const DisplayTopLanguages = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const DisplayStreakStats = props => { const DisplayStreakStats = (props) => {
if (props.show) { if (props.show) {
return ( return (
<> <>
@@ -248,17 +244,17 @@ const DisplayStreakStats = props => {
<br /> <br />
<br /> <br />
</> </>
) );
} }
return "" return '';
} };
const DisplaySupport = props => { const DisplaySupport = (props) => {
let viewSupport = false let viewSupport = false;
Object.keys(props.support).forEach(key => { Object.keys(props.support).forEach((key) => {
if (props.support[key]) { if (props.support[key]) {
viewSupport = true viewSupport = true;
} }
}) });
return viewSupport ? ( return viewSupport ? (
<div> <div>
<SectionTitle label="Support:" /> <SectionTitle label="Support:" />
@@ -274,12 +270,12 @@ const DisplaySupport = props => {
<br /> <br />
</div> </div>
) : ( ) : (
"" ''
) );
} };
const Markdown = props => { const Markdown = (props) => {
const icon_base_url = const icon_base_url =
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/" 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
return ( return (
<div id="markdown-content" className="break-words"> <div id="markdown-content" className="break-words">
@@ -301,28 +297,14 @@ const Markdown = props => {
/> />
</> </>
<> <>
<GithubProfileTrophy <GithubProfileTrophy show={props.data.githubProfileTrophy} github={props.social.github} />
show={props.data.githubProfileTrophy} <TwitterBadge base="https://twitter.com" show={props.data.twitterBadge} twitter={props.social.twitter} />
github={props.social.github}
/>
<TwitterBadge
base="https://twitter.com"
show={props.data.twitterBadge}
twitter={props.social.twitter}
/>
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.currentWork} project={props.data.currentWork} link={props.link.currentWork} />
prefix={props.prefix.currentWork}
project={props.data.currentWork}
link={props.link.currentWork}
/>
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.currentLearn} project={props.data.currentLearn} />
prefix={props.prefix.currentLearn}
project={props.data.currentLearn}
/>
</> </>
<> <>
<DisplayWork <DisplayWork
@@ -332,17 +314,10 @@ const Markdown = props => {
/> />
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.helpWith} project={props.data.helpWith} link={props.link.helpWith} />
prefix={props.prefix.helpWith}
project={props.data.helpWith}
link={props.link.helpWith}
/>
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.portfolio} link={props.link.portfolio} />
prefix={props.prefix.portfolio}
link={props.link.portfolio}
/>
</> </>
<> <>
<DisplayWork prefix={props.prefix.blog} link={props.link.blog} /> <DisplayWork prefix={props.prefix.blog} link={props.link.blog} />
@@ -351,28 +326,20 @@ const Markdown = props => {
<DisplayWork prefix={props.prefix.ama} project={props.data.ama} /> <DisplayWork prefix={props.prefix.ama} project={props.data.ama} />
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.contact} project={props.data.contact} />
prefix={props.prefix.contact}
project={props.data.contact}
/>
</> </>
<> <>
<DisplayWork prefix={props.prefix.resume} link={props.link.resume} /> <DisplayWork prefix={props.prefix.resume} link={props.link.resume} />
</> </>
<> <>
<DisplayWork <DisplayWork prefix={props.prefix.funFact} project={props.data.funFact} />
prefix={props.prefix.funFact}
project={props.data.funFact}
/>
</> </>
<> <>
<DisplayDynamicBlogs <DisplayDynamicBlogs
show={ show={
(props.data.devDynamicBlogs && props.social.dev) || (props.data.devDynamicBlogs && props.social.dev) ||
(props.data.rssDynamicBlogs && props.social.rssurl) || (props.data.rssDynamicBlogs && props.social.rssurl) ||
(props.data.mediumDynamicBlogs && (props.data.mediumDynamicBlogs && props.social.medium && isMediumUsernameValid(props.social.medium))
props.social.medium &&
isMediumUsernameValid(props.social.medium))
} }
/> />
</> </>
@@ -382,97 +349,77 @@ const Markdown = props => {
{`<p align="left">`} {`<p align="left">`}
</> </>
) : ( ) : (
"" ''
)} )}
<br /> <br />
<> <>
<DisplaySocial <DisplaySocial base="https://codepen.io" icon={icon_base_url + 'codepen.svg'} username={props.social.codepen} />
base="https://codepen.io"
icon={icon_base_url + "codepen.svg"}
username={props.social.codepen}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://dev.to" icon={icon_base_url + 'devto.svg'} username={props.social.dev} />
base="https://dev.to"
icon={icon_base_url + "devto.svg"}
username={props.social.dev}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://twitter.com" base="https://twitter.com"
icon={icon_base_url + "twitter.svg"} icon={icon_base_url + 'twitter.svg'}
username={props.social.twitter} username={props.social.twitter}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://linkedin.com/in" base="https://linkedin.com/in"
icon={icon_base_url + "linked-in-alt.svg"} icon={icon_base_url + 'linked-in-alt.svg'}
username={props.social.linkedin} username={props.social.linkedin}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://stackoverflow.com/users" base="https://stackoverflow.com/users"
icon={icon_base_url + "stack-overflow.svg"} icon={icon_base_url + 'stack-overflow.svg'}
username={props.social.stackoverflow} username={props.social.stackoverflow}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://codesandbox.com" base="https://codesandbox.com"
icon={icon_base_url + "codesandbox.svg"} icon={icon_base_url + 'codesandbox.svg'}
username={props.social.codesandbox} username={props.social.codesandbox}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://kaggle.com" icon={icon_base_url + 'kaggle.svg'} username={props.social.kaggle} />
base="https://kaggle.com"
icon={icon_base_url + "kaggle.svg"}
username={props.social.kaggle}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://fb.com" icon={icon_base_url + 'facebook.svg'} username={props.social.fb} />
base="https://fb.com"
icon={icon_base_url + "facebook.svg"}
username={props.social.fb}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://instagram.com" base="https://instagram.com"
icon={icon_base_url + "instagram.svg"} icon={icon_base_url + 'instagram.svg'}
username={props.social.instagram} username={props.social.instagram}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://dribbble.com" base="https://dribbble.com"
icon={icon_base_url + "dribbble.svg"} icon={icon_base_url + 'dribbble.svg'}
username={props.social.dribbble} username={props.social.dribbble}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.behance.net" base="https://www.behance.net"
icon={icon_base_url + "behance.svg"} icon={icon_base_url + 'behance.svg'}
username={props.social.behance} username={props.social.behance}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://medium.com" icon={icon_base_url + 'medium.svg'} username={props.social.medium} />
base="https://medium.com"
icon={icon_base_url + "medium.svg"}
username={props.social.medium}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.youtube.com/c" base="https://www.youtube.com/c"
icon={icon_base_url + "youtube.svg"} icon={icon_base_url + 'youtube.svg'}
username={props.social.youtube} username={props.social.youtube}
/> />
</> </>
@@ -486,58 +433,50 @@ const Markdown = props => {
<> <>
<DisplaySocial <DisplaySocial
base="https://www.hackerrank.com" base="https://www.hackerrank.com"
icon={icon_base_url + "hackerrank.svg"} icon={icon_base_url + 'hackerrank.svg'}
username={props.social.hackerrank} username={props.social.hackerrank}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://codeforces.com/profile" base="https://codeforces.com/profile"
icon={icon_base_url + "codeforces.svg"} icon={icon_base_url + 'codeforces.svg'}
username={props.social.codeforces} username={props.social.codeforces}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.leetcode.com" base="https://www.leetcode.com"
icon={icon_base_url + "leet-code.svg"} icon={icon_base_url + 'leet-code.svg'}
username={props.social.leetcode} username={props.social.leetcode}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.hackerearth.com" base="https://www.hackerearth.com"
icon={icon_base_url + "hackerearth.svg"} icon={icon_base_url + 'hackerearth.svg'}
username={props.social.hackerearth} username={props.social.hackerearth}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://auth.geeksforgeeks.org/user" base="https://auth.geeksforgeeks.org/user"
icon={icon_base_url + "geeks-for-geeks.svg"} icon={icon_base_url + 'geeks-for-geeks.svg'}
username={props.social.geeks_for_geeks} username={props.social.geeks_for_geeks}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.topcoder.com/members" base="https://www.topcoder.com/members"
icon={icon_base_url + "topcoder.svg"} icon={icon_base_url + 'topcoder.svg'}
username={props.social.topcoder} username={props.social.topcoder}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://discord.gg" icon={icon_base_url + 'discord.svg'} username={props.social.discord} />
base="https://discord.gg"
icon={icon_base_url + "discord.svg"}
username={props.social.discord}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="" icon={icon_base_url + 'rss.svg'} username={props.social.rssurl} />
base=""
icon={icon_base_url + "rss.svg"}
username={props.social.rssurl}
/>
</> </>
{isSocial(props.social) ? ( {isSocial(props.social) ? (
<> <>
@@ -546,7 +485,7 @@ const Markdown = props => {
<br /> <br />
</> </>
) : ( ) : (
"" ''
)} )}
<> <>
<DisplaySkills skills={props.skills} /> <DisplaySkills skills={props.skills} />
@@ -577,6 +516,6 @@ const Markdown = props => {
/> />
</> </>
</div> </div>
) );
} };
export default Markdown export default Markdown;
+129 -219
View File
@@ -1,100 +1,76 @@
import React from "react" import React from 'react';
import { icons, skills, skillWebsites } from "../constants/skills" import { icons, skills, skillWebsites } from '../constants/skills';
import { import {
githubStatsLinkGenerator, githubStatsLinkGenerator,
topLanguagesLinkGenerator, topLanguagesLinkGenerator,
streakStatsLinkGenerator, streakStatsLinkGenerator,
} from "../utils/link-generators" } from '../utils/link-generators';
export const TitlePreview = props => { export const TitlePreview = (props) => {
if (props.prefix && props.title) { if (props.prefix && props.title) {
return ( return <h1 className="text-center text-xl font-bold">{props.prefix + ' ' + props.title}</h1>;
<h1 className="text-center text-xl font-bold">
{props.prefix + " " + props.title}
</h1>
)
} }
return null return null;
} };
export const SubTitlePreview = props => { export const SubTitlePreview = (props) => {
if (props.subtitle) { if (props.subtitle) {
return <h3 className="text-center font-medium">{props.subtitle}</h3> return <h3 className="text-center font-medium">{props.subtitle}</h3>;
} }
return null return null;
} };
export const SectionTitle = props => { export const SectionTitle = (props) => {
if (!props.visible) return null if (!props.visible) return null;
else if (props.label) { else if (props.label) {
return <h3 className="w-full text-lg sm:text-xl">{props.label}</h3> return <h3 className="w-full text-lg sm:text-xl">{props.label}</h3>;
} }
return null return null;
} };
export const DisplayWork = props => { export const DisplayWork = (props) => {
if (props.prefix && props.project) { if (props.prefix && props.project) {
if (props.link) { if (props.link) {
return ( return (
<div className="my-2"> <div className="my-2">
{props.prefix + " "} {props.prefix + ' '}
<a <a href={props.link} className="no-underline text-blue-700" target="blank">
href={props.link}
className="no-underline text-blue-700"
target="blank"
>
{props.project} {props.project}
</a> </a>
</div> </div>
) );
} else { } else {
return ( return (
<div className="my-2"> <div className="my-2">
{props.prefix + " "} {props.prefix + ' '}
<b>{props.project}</b> <b>{props.project}</b>
</div> </div>
) );
} }
} }
if (props.prefix && props.link) { if (props.prefix && props.link) {
return ( return (
<div className="my-2"> <div className="my-2">
{props.prefix + " "} {props.prefix + ' '}
<a <a href={props.link} className="no-underline text-blue-700" target="blank">
href={props.link}
className="no-underline text-blue-700"
target="blank"
>
{props.link} {props.link}
</a> </a>
</div> </div>
) );
} }
return null return null;
} };
export const WorkPreview = props => { export const WorkPreview = (props) => {
const prefix = props.work.prefix const prefix = props.work.prefix;
const data = props.work.data const data = props.work.data;
const link = props.work.link const link = props.work.link;
return ( return (
<> <>
<DisplayWork <DisplayWork prefix={prefix.currentWork} project={data.currentWork} link={link.currentWork} />
prefix={prefix.currentWork}
project={data.currentWork}
link={link.currentWork}
/>
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} /> <DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
<DisplayWork <DisplayWork prefix={prefix.helpWith} project={data.helpWith} link={link.helpWith} />
prefix={prefix.helpWith} <DisplayWork prefix={prefix.collaborateOn} project={data.collaborateOn} link={link.collaborateOn} />
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.ama} project={data.ama} />
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} /> <DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
<DisplayWork prefix={prefix.blog} link={link.blog} /> <DisplayWork prefix={prefix.blog} link={link.blog} />
@@ -102,122 +78,98 @@ export const WorkPreview = props => {
<DisplayWork prefix={prefix.contact} project={data.contact} /> <DisplayWork prefix={prefix.contact} project={data.contact} />
<DisplayWork prefix={prefix.funFact} project={data.funFact} /> <DisplayWork prefix={prefix.funFact} project={data.funFact} />
</> </>
) );
} };
export const DisplaySocial = props => { export const DisplaySocial = (props) => {
if (props.username) { if (props.username) {
return ( return (
<a <a className="no-underline text-blue-700 m-2" href={props.base + '/' + props.username} target="blank">
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" /> <img className="w-6 h-6" src={props.icon} alt="props.username" />
</a> </a>
) );
} }
return null return null;
} };
export const SocialPreview = props => { export const SocialPreview = (props) => {
let viewSocial = false let viewSocial = false;
const icon_base_url = const icon_base_url =
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/" 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
Object.keys(props.social).forEach(key => { Object.keys(props.social).forEach((key) => {
if (props.social[key] && key !== "github") viewSocial = true if (props.social[key] && key !== 'github') viewSocial = true;
}) });
return ( return (
<div className="flex justify-start items-end flex-wrap"> <div className="flex justify-start items-end flex-wrap">
<SectionTitle label="Connect with me:" visible={viewSocial} /> <SectionTitle label="Connect with me:" visible={viewSocial} />
<> <>
<DisplaySocial <DisplaySocial base="https://codepen.io" icon={icon_base_url + 'codepen.svg'} username={props.social.codepen} />
base="https://codepen.io"
icon={icon_base_url + "codepen.svg"}
username={props.social.codepen}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://dev.to" icon={icon_base_url + 'devto.svg'} username={props.social.dev} />
base="https://dev.to"
icon={icon_base_url + "devto.svg"}
username={props.social.dev}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://twitter.com" base="https://twitter.com"
icon={icon_base_url + "twitter.svg"} icon={icon_base_url + 'twitter.svg'}
username={props.social.twitter} username={props.social.twitter}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://linkedin.com/in" base="https://linkedin.com/in"
icon={icon_base_url + "linked-in-alt.svg"} icon={icon_base_url + 'linked-in-alt.svg'}
username={props.social.linkedin} username={props.social.linkedin}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://stackoverflow.com/users" base="https://stackoverflow.com/users"
icon={icon_base_url + "stack-overflow.svg"} icon={icon_base_url + 'stack-overflow.svg'}
username={props.social.stackoverflow} username={props.social.stackoverflow}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://codesandbox.com" base="https://codesandbox.com"
icon={icon_base_url + "codesandbox.svg"} icon={icon_base_url + 'codesandbox.svg'}
username={props.social.codesandbox} username={props.social.codesandbox}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://kaggle.com" icon={icon_base_url + 'kaggle.svg'} username={props.social.kaggle} />
base="https://kaggle.com"
icon={icon_base_url + "kaggle.svg"}
username={props.social.kaggle}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://fb.com" icon={icon_base_url + 'facebook.svg'} username={props.social.fb} />
base="https://fb.com"
icon={icon_base_url + "facebook.svg"}
username={props.social.fb}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://instagram.com" base="https://instagram.com"
icon={icon_base_url + "instagram.svg"} icon={icon_base_url + 'instagram.svg'}
username={props.social.instagram} username={props.social.instagram}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://dribbble.com" base="https://dribbble.com"
icon={icon_base_url + "dribbble.svg"} icon={icon_base_url + 'dribbble.svg'}
username={props.social.dribbble} username={props.social.dribbble}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.behance.net" base="https://www.behance.net"
icon={icon_base_url + "behance.svg"} icon={icon_base_url + 'behance.svg'}
username={props.social.behance} username={props.social.behance}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://medium.com" icon={icon_base_url + 'medium.svg'} username={props.social.medium} />
base="https://medium.com"
icon={icon_base_url + "medium.svg"}
username={props.social.medium}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.youtube.com/c" base="https://www.youtube.com/c"
icon={icon_base_url + "youtube.svg"} icon={icon_base_url + 'youtube.svg'}
username={props.social.youtube} username={props.social.youtube}
/> />
</> </>
@@ -231,118 +183,102 @@ export const SocialPreview = props => {
<> <>
<DisplaySocial <DisplaySocial
base="https://www.hackerrank.com" base="https://www.hackerrank.com"
icon={icon_base_url + "hackerrank.svg"} icon={icon_base_url + 'hackerrank.svg'}
username={props.social.hackerrank} username={props.social.hackerrank}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://codeforces.com/profile" base="https://codeforces.com/profile"
icon={icon_base_url + "codeforces.svg"} icon={icon_base_url + 'codeforces.svg'}
username={props.social.codeforces} username={props.social.codeforces}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.leetcode.com" base="https://www.leetcode.com"
icon={icon_base_url + "leet-code.svg"} icon={icon_base_url + 'leet-code.svg'}
username={props.social.leetcode} username={props.social.leetcode}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.hackerearth.com" base="https://www.hackerearth.com"
icon={icon_base_url + "hackerearth.svg"} icon={icon_base_url + 'hackerearth.svg'}
username={props.social.hackerearth} username={props.social.hackerearth}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://auth.geeksforgeeks.org/user" base="https://auth.geeksforgeeks.org/user"
icon={icon_base_url + "geeks-for-geeks.svg"} icon={icon_base_url + 'geeks-for-geeks.svg'}
username={props.social.geeks_for_geeks} username={props.social.geeks_for_geeks}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial
base="https://www.topcoder.com/members" base="https://www.topcoder.com/members"
icon={icon_base_url + "topcoder.svg"} icon={icon_base_url + 'topcoder.svg'}
username={props.social.topcoder} username={props.social.topcoder}
/> />
</> </>
<> <>
<DisplaySocial <DisplaySocial base="https://discord.gg" icon={icon_base_url + 'discord.svg'} username={props.social.discord} />
base="https://discord.gg"
icon={icon_base_url + "discord.svg"}
username={props.social.discord}
/>
</> </>
<> <>
<DisplaySocial <DisplaySocial base="" icon={icon_base_url + 'rss.svg'} username={props.social.rssurl} />
base=""
icon={icon_base_url + "rss.svg"}
username={props.social.rssurl}
/>
</> </>
</div> </div>
) );
} };
export const VisitorsBadgePreview = props => { export const VisitorsBadgePreview = (props) => {
let link = let link =
"https://komarev.com/ghpvc/?username=" + 'https://komarev.com/ghpvc/?username=' +
props.github + props.github +
`&label=${props.badgeOptions.badgeLabel}` + `&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` + `&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}` `&style=${props.badgeOptions.badgeStyle}`;
if (props.show) { if (props.show) {
return ( return (
<div className="text-left my-2"> <div className="text-left my-2">
{" "} {' '}
<img className="h-4 sm:h-6" src={link} alt={props.github} />{" "} <img className="h-4 sm:h-6" src={link} alt={props.github} />{' '}
</div> </div>
) );
} }
return null return null;
} };
export const TwitterBadgePreview = props => { export const TwitterBadgePreview = (props) => {
let link = let link = 'https://img.shields.io/twitter/follow/' + props.twitter + '?logo=twitter&style=for-the-badge';
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) { if (props.show) {
return ( return (
<div className="text-left my-2"> <div className="text-left my-2">
{" "} {' '}
<a <a href="https://twitter.com/${props.twitter}" target="_blank" rel="noreferrer">
href="https://twitter.com/${props.twitter}"
target="_blank"
rel="noreferrer"
>
<img className="h-4 sm:h-6" src={link} alt={props.twitter} /> <img className="h-4 sm:h-6" src={link} alt={props.twitter} />
</a>{" "} </a>{' '}
</div> </div>
) );
} }
return null return null;
} };
export const GithubProfileTrophyPreview = props => { export const GithubProfileTrophyPreview = (props) => {
let link = let link = 'https://github-profile-trophy.vercel.app/?username=' + props.github;
"https://github-profile-trophy.vercel.app/?username=" + props.github
if (props.show) { if (props.show) {
return ( return (
<div className="text-left my-2"> <div className="text-left my-2">
{" "} {' '}
<a href="https://github.com/ryo-ma/github-profile-trophy"> <a href="https://github.com/ryo-ma/github-profile-trophy">
<img src={link} alt={props.github} /> <img src={link} alt={props.github} />
</a>{" "} </a>{' '}
</div> </div>
) );
} }
return null return null;
} };
export const GitHubStatsPreview = ({ github, options, show }) => { export const GitHubStatsPreview = ({ github, options, show }) => {
if (show) { if (show) {
@@ -350,24 +286,21 @@ export const GitHubStatsPreview = ({ github, options, show }) => {
<div className="text-center mx-4 mb-4"> <div className="text-center mx-4 mb-4">
<img src={githubStatsLinkGenerator({ github, options })} alt={github} /> <img src={githubStatsLinkGenerator({ github, options })} alt={github} />
</div> </div>
) );
} }
return null return null;
} };
export const TopLanguagesPreview = ({ github, options, show }) => { export const TopLanguagesPreview = ({ github, options, show }) => {
if (show) { if (show) {
return ( return (
<div className="text-center mx-4 mb-4"> <div className="text-center mx-4 mb-4">
<img <img src={topLanguagesLinkGenerator({ github, options })} alt={github} />
src={topLanguagesLinkGenerator({ github, options })}
alt={github}
/>
</div> </div>
) );
} }
return <div className="text-center mx-4 mb-4"> &nbsp;</div> return <div className="text-center mx-4 mb-4"> &nbsp;</div>;
} };
export const StreakStatsPreview = ({ github, options, show }) => { export const StreakStatsPreview = ({ github, options, show }) => {
if (show) { if (show) {
@@ -375,57 +308,44 @@ export const StreakStatsPreview = ({ github, options, show }) => {
<div className="text-center mx-4 mb-4"> <div className="text-center mx-4 mb-4">
<img src={streakStatsLinkGenerator({ github, options })} alt={github} /> <img src={streakStatsLinkGenerator({ github, options })} alt={github} />
</div> </div>
) );
} }
return null return null;
} };
export const SkillsPreview = props => { export const SkillsPreview = (props) => {
var listSkills = [] var listSkills = [];
skills.forEach(skill => { skills.forEach((skill) => {
if (props.skills[skill]) { if (props.skills[skill]) {
listSkills.push( listSkills.push(
<a <a href={skillWebsites[skill]} key={skill} target="_blank" rel="noreferrer">
href={skillWebsites[skill]} <img className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10" src={icons[skill]} alt={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> </a>
) );
} }
}) });
return listSkills.length > 0 ? ( return listSkills.length > 0 ? (
<div className="flex flex-wrap justify-start items-center"> <div className="flex flex-wrap justify-start items-center">
<SectionTitle label="Languages and Tools:" visible={true} /> <SectionTitle label="Languages and Tools:" visible={true} />
{listSkills} {listSkills}
</div> </div>
) : ( ) : (
"" ''
) );
} };
export const SupportPreview = props => { export const SupportPreview = (props) => {
let viewSupport = false let viewSupport = false;
Object.keys(props.support).forEach(key => { Object.keys(props.support).forEach((key) => {
if (props.support[key]) { if (props.support[key]) {
viewSupport = true viewSupport = true;
} }
}) });
return props.support.buyMeACoffee || props.support.buyMeAKofi ? ( return props.support.buyMeACoffee || props.support.buyMeAKofi ? (
<div className="flex flex-wrap justify-start items-center"> <div className="flex flex-wrap justify-start items-center">
<SectionTitle label="Support:" visible={viewSupport} /> <SectionTitle label="Support:" visible={viewSupport} />
{props.support.buyMeACoffee && ( {props.support.buyMeACoffee && (
<a <a href={`https://www.buymeacoffee.com/` + props.support.buyMeACoffee} target="_blank" rel="noreferrer">
href={`https://www.buymeacoffee.com/` + props.support.buyMeACoffee}
target="_blank"
rel="noreferrer"
>
<img <img
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png"
alt="Buy Me A Coffee" alt="Buy Me A Coffee"
@@ -434,11 +354,7 @@ export const SupportPreview = props => {
</a> </a>
)} )}
{props.support.buyMeAKofi && ( {props.support.buyMeAKofi && (
<a <a href={`https://ko-fi.com/` + props.support.buyMeAKofi} target="_blank" rel="noreferrer">
href={`https://ko-fi.com/` + props.support.buyMeAKofi}
target="_blank"
rel="noreferrer"
>
<img <img
src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3"
alt="Buy Me A Ko-fi" alt="Buy Me A Ko-fi"
@@ -448,11 +364,11 @@ export const SupportPreview = props => {
)} )}
</div> </div>
) : ( ) : (
"" ''
) );
} };
const MarkdownPreview = props => { const MarkdownPreview = (props) => {
return ( return (
<div id="markdown-preview"> <div id="markdown-preview">
<TitlePreview prefix={props.prefix.title} title={props.data.title} /> <TitlePreview prefix={props.prefix.title} title={props.data.title} />
@@ -466,14 +382,8 @@ const MarkdownPreview = props => {
badgeStyle: props.data.badgeStyle, badgeStyle: props.data.badgeStyle,
}} }}
/> />
<GithubProfileTrophyPreview <GithubProfileTrophyPreview show={props.data.githubProfileTrophy} github={props.social.github} />
show={props.data.githubProfileTrophy} <TwitterBadgePreview show={props.data.twitterBadge} twitter={props.social.twitter} />
github={props.social.github}
/>
<TwitterBadgePreview
show={props.data.twitterBadge}
twitter={props.social.twitter}
/>
<WorkPreview work={props} /> <WorkPreview work={props} />
<SocialPreview social={props.social} /> <SocialPreview social={props.social} />
<SkillsPreview skills={props.skills} /> <SkillsPreview skills={props.skills} />
@@ -496,7 +406,7 @@ const MarkdownPreview = props => {
/> />
</div> </div>
</div> </div>
) );
} };
export default MarkdownPreview export default MarkdownPreview;
+10 -10
View File
@@ -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(
@@ -23,9 +23,9 @@ 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;
+67 -74
View File
@@ -1,106 +1,99 @@
import React, {useState} from "react" import React, { useState } from 'react';
import { icons, categorizedSkills } from "../constants/skills" import { icons, categorizedSkills } from '../constants/skills';
import { SearchIcon, XIcon } from "@primer/octicons-react"; import { SearchIcon, XIcon } from '@primer/octicons-react';
const Skills = (props) => {
const Skills = props => { const [search, setSearch] = useState('');
const [search, setSearch] = useState('')
const [debounce, setDebounce] = useState(undefined); const [debounce, setDebounce] = useState(undefined);
const inputRef = React.createRef() const inputRef = React.createRef();
const createSkill = skill => { const createSkill = (skill) => {
return ( return (
<div className="w-1/3 sm:w-1/4 my-6" key={skill}> <div className="w-1/3 sm:w-1/4 my-6" key={skill}>
<label <label htmlFor={skill} className="checkbox-label flex items-center justify-start">
htmlFor={skill}
className="checkbox-label flex items-center justify-start"
>
<input <input
id={skill} id={skill}
type="checkbox" type="checkbox"
className="checkbox-label__input" className="checkbox-label__input"
checked={props.skills[skill]} checked={props.skills[skill]}
onChange={event => props.handleSkillsChange(skill)} onChange={(event) => props.handleSkillsChange(skill)}
/> />
<span class="checkbox-label__control" /> <span class="checkbox-label__control" />
<img <img className="ml-4 w-8 h-8 sm:w-10 sm:h-10" src={icons[skill]} alt={skill} />
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
src={icons[skill]}
alt={skill}
/>
<span className="tooltiptext">{skill}</span> <span className="tooltiptext">{skill}</span>
</label> </label>
</div> </div>
) );
} };
const onSearchChange = (value) => { const onSearchChange = (value) => {
const callback = () => { const callback = () => {
setSearch(value) setSearch(value);
} };
clearTimeout(debounce) clearTimeout(debounce);
setDebounce(setTimeout(callback, 50)) setDebounce(setTimeout(callback, 50));
} };
return ( return (
<div className="px-2 sm:px-6 mb-10 "> <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"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-4 flex justify-between">
Skills Skills
<div className="relative flex"> <div className="relative flex">
<input <input
type="text" type="text"
onChange={(e) => onSearchChange(e.target.value)} 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" 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" placeholder="Search Skills"
ref = {inputRef} ref={inputRef}
/> />
<span className="absolute" style={{right:"10px"}}> <span className="absolute" style={{ right: '10px' }}>
{(search !== '') {search !== '' ? (
?<button className="focus:outline-none" onClick={() => { <button
setSearch('') className="focus:outline-none"
inputRef.current.value = '' 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"/> <XIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
} </button>
</span> ) : (
<SearchIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
)}
</span>
</div> </div>
</div> </div>
{Object.keys(categorizedSkills) {Object.keys(categorizedSkills)
.filter(key => { .filter((key) => {
let filtered = categorizedSkills[key].skills.filter(skill => { let filtered = categorizedSkills[key].skills.filter((skill) => {
return skill.includes(search.toLowerCase()) return skill.includes(search.toLowerCase());
});
return filtered.length !== 0;
}) })
return filtered.length !== 0 .map((key) => (
}) <div key={key} className="divide-y divide-gray-500">
.map(key => ( <div className="text-sm sm:text-xl text-gray-900 text-left py-1">{categorizedSkills[key].title}</div>
<div key={key} className="divide-y divide-gray-500"> <div className="flex justify-start items-center flex-wrap w-full mb-6 pl-4 sm:pl-10">
<div className="text-sm sm:text-xl text-gray-900 text-left py-1"> {categorizedSkills[key].skills
{categorizedSkills[key].title} .filter((skill) => {
return skill.includes(search.toLowerCase());
})
.map((skill) => createSkill(skill))}
</div> </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>
</div> ))}
))}
<span className="flex justify-center text-gray-900"> <span className="flex justify-center text-gray-900">
{(Object.keys(categorizedSkills) {Object.keys(categorizedSkills).filter((key) => {
.filter(key => { let filtered = categorizedSkills[key].skills.filter((skill) => {
let filtered = categorizedSkills[key].skills.filter(skill => { return skill.includes(search.toLowerCase());
return skill.includes(search.toLowerCase()) });
}) return filtered.length !== 0;
return filtered.length !== 0 }).length === 0
}) ? 'No Results Found'
.length === 0)?"No Results Found":""} : ''}
</span> </span>
</div> </div>
) );
} };
export default Skills export default Skills;
+29 -33
View File
@@ -1,11 +1,9 @@
import React from "react" import React from 'react';
const Social = props => { const Social = (props) => {
return ( return (
<div className="px-2 sm:px-6 mb-4"> <div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Social</div>
Social
</div>
<div className="flex flex-wrap justify-center items-center"> <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"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img <img
@@ -18,7 +16,7 @@ const Social = props => {
placeholder="github username" 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" 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} value={props.social.github}
onChange={event => props.handleSocialChange("github", event)} onChange={(event) => props.handleSocialChange('github', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -32,7 +30,7 @@ const Social = props => {
placeholder="twitter username" 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" 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} value={props.social.twitter}
onChange={event => props.handleSocialChange("twitter", event)} onChange={(event) => props.handleSocialChange('twitter', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -46,7 +44,7 @@ const Social = props => {
placeholder="dev.to username" 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" 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} value={props.social.dev}
onChange={event => props.handleSocialChange("dev", event)} onChange={(event) => props.handleSocialChange('dev', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -60,7 +58,7 @@ const Social = props => {
placeholder="codepen username" 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" 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} value={props.social.codepen}
onChange={event => props.handleSocialChange("codepen", event)} onChange={(event) => props.handleSocialChange('codepen', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -74,7 +72,7 @@ const Social = props => {
placeholder="codesandbox username" 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" 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} value={props.social.codesandbox}
onChange={event => props.handleSocialChange("codesandbox", event)} onChange={(event) => props.handleSocialChange('codesandbox', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -88,7 +86,7 @@ const Social = props => {
placeholder="stackoverflow user ID" 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" 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} value={props.social.stackoverflow}
onChange={event => props.handleSocialChange("stackoverflow", event)} onChange={(event) => props.handleSocialChange('stackoverflow', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -102,7 +100,7 @@ const Social = props => {
placeholder="linkedin username" 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" 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} value={props.social.linkedin}
onChange={event => props.handleSocialChange("linkedin", event)} onChange={(event) => props.handleSocialChange('linkedin', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -116,7 +114,7 @@ const Social = props => {
placeholder="kaggle username" 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" 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} value={props.social.kaggle}
onChange={event => props.handleSocialChange("kaggle", event)} onChange={(event) => props.handleSocialChange('kaggle', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -130,7 +128,7 @@ const Social = props => {
placeholder="facebook username" 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" 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} value={props.social.fb}
onChange={event => props.handleSocialChange("fb", event)} onChange={(event) => props.handleSocialChange('fb', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -144,7 +142,7 @@ const Social = props => {
placeholder="instagram username" 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" 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} value={props.social.instagram}
onChange={event => props.handleSocialChange("instagram", event)} onChange={(event) => props.handleSocialChange('instagram', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -158,7 +156,7 @@ const Social = props => {
placeholder="dribbble username" 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" 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} value={props.social.dribbble}
onChange={event => props.handleSocialChange("dribbble", event)} onChange={(event) => props.handleSocialChange('dribbble', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -172,7 +170,7 @@ const Social = props => {
placeholder="behance username" 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" 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} value={props.social.behance}
onChange={event => props.handleSocialChange("behance", event)} onChange={(event) => props.handleSocialChange('behance', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -186,7 +184,7 @@ const Social = props => {
placeholder="medium username (with @)" 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" 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} value={props.social.medium}
onChange={event => props.handleSocialChange("medium", event)} onChange={(event) => props.handleSocialChange('medium', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -200,7 +198,7 @@ const Social = props => {
placeholder="youtube channel name" 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" 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} value={props.social.youtube}
onChange={event => props.handleSocialChange("youtube", event)} onChange={(event) => props.handleSocialChange('youtube', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -214,7 +212,7 @@ const Social = props => {
placeholder="codechef username" 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" 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} value={props.social.codechef}
onChange={event => props.handleSocialChange("codechef", event)} onChange={(event) => props.handleSocialChange('codechef', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -228,7 +226,7 @@ const Social = props => {
placeholder="hackerrank username" 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" 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} value={props.social.hackerrank}
onChange={event => props.handleSocialChange("hackerrank", event)} onChange={(event) => props.handleSocialChange('hackerrank', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -242,7 +240,7 @@ const Social = props => {
placeholder="codeforces username" 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" 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} value={props.social.codeforces}
onChange={event => props.handleSocialChange("codeforces", event)} onChange={(event) => props.handleSocialChange('codeforces', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -256,7 +254,7 @@ const Social = props => {
placeholder="leetcode username" 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" 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} value={props.social.leetcode}
onChange={event => props.handleSocialChange("leetcode", event)} onChange={(event) => props.handleSocialChange('leetcode', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -270,7 +268,7 @@ const Social = props => {
placeholder="topcoder username" 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" 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} value={props.social.topcoder}
onChange={event => props.handleSocialChange("topcoder", event)} onChange={(event) => props.handleSocialChange('topcoder', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -284,7 +282,7 @@ const Social = props => {
placeholder="hackerearth user (with @)" 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" 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} value={props.social.hackerearth}
onChange={event => props.handleSocialChange("hackerearth", event)} onChange={(event) => props.handleSocialChange('hackerearth', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -298,9 +296,7 @@ const Social = props => {
placeholder="GFG (<username>/profile)" 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" 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} value={props.social.geeks_for_geeks}
onChange={event => onChange={(event) => props.handleSocialChange('geeks_for_geeks', event)}
props.handleSocialChange("geeks_for_geeks", event)
}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -314,7 +310,7 @@ const Social = props => {
placeholder="discord invite (only code)" 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" 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} value={props.social.discord}
onChange={event => props.handleSocialChange("discord", event)} onChange={(event) => props.handleSocialChange('discord', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -328,12 +324,12 @@ const Social = props => {
placeholder="RSS feed URL" 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" 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} value={props.social.rssurl}
onChange={event => props.handleSocialChange("rssurl", event)} onChange={(event) => props.handleSocialChange('rssurl', event)}
/> />
</div> </div>
</div> </div>
</div> </div>
) );
} };
export default Social export default Social;
+7 -9
View File
@@ -1,19 +1,17 @@
import React from "react" import React from 'react';
const Subtitle = props => { const Subtitle = (props) => {
return ( return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10"> <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"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Subtitle</div>
Subtitle
</div>
<input <input
id="subtitle" 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" 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} value={props.data.subtitle}
onChange={event => props.handleDataChange("subtitle", event)} onChange={(event) => props.handleDataChange('subtitle', event)}
/> />
</div> </div>
) );
} };
export default Subtitle export default Subtitle;
+10 -12
View File
@@ -1,11 +1,9 @@
import React from "react" import React from 'react';
const Support = props => { const Support = (props) => {
return ( return (
<div className="px-2 sm:px-6 mb-4"> <div className="px-2 sm:px-6 mb-4">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Support</div>
Support
</div>
<div className="flex flex-wrap justify-start items-center"> <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"> <div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
<img <img
@@ -17,8 +15,8 @@ const Support = props => {
id="buy-me-a-coffee" id="buy-me-a-coffee"
placeholder="buymeacoffee username" 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" 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={props.support.buyMeACoffee || ""} value={props.support.buyMeACoffee || ''}
onChange={event => props.handleSupportChange("buyMeACoffee", event)} onChange={(event) => props.handleSupportChange('buyMeACoffee', event)}
/> />
</div> </div>
<div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0"> <div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
@@ -31,13 +29,13 @@ const Support = props => {
id="buy-me-a-kofi" id="buy-me-a-kofi"
placeholder="Ko-fi username" 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" 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.buyMeAKofi || ""} value={props.support.buyMeAKofi || ''}
onChange={event => props.handleSupportChange("buyMeAKofi", event)} onChange={(event) => props.handleSupportChange('buyMeAKofi', event)}
/> />
</div> </div>
</div> </div>
</div> </div>
) );
} };
export default Support export default Support;
+8 -10
View File
@@ -1,28 +1,26 @@
import React from "react" import React from 'react';
const Title = props => { const Title = (props) => {
return ( return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10"> <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"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Title</div>
Title
</div>
<div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg"> <div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg">
<input <input
id="title-prefix" 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" 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} value={props.prefix.title}
onChange={event => props.handlePrefixChange("title", event)} onChange={(event) => props.handlePrefixChange('title', event)}
/> />
<input <input
id="title-name" id="title-name"
placeholder="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" 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} value={props.data.title}
onChange={event => props.handleDataChange("title", event)} onChange={(event) => props.handleDataChange('title', event)}
/> />
</div> </div>
</div> </div>
) );
} };
export default Title export default Title;
+30 -32
View File
@@ -1,32 +1,30 @@
import React from "react" import React from 'react';
const Work = props => { const Work = (props) => {
return ( return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10"> <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"> <div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Work</div>
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"> <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 <input
id="currentWork-prefix" id="currentWork-prefix"
placeholder="Hi, I'm " 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" 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} value={props.prefix.currentWork}
onChange={event => props.handlePrefixChange("currentWork", event)} onChange={(event) => props.handlePrefixChange('currentWork', event)}
/> />
<input <input
id="currentWork" id="currentWork"
placeholder="project name" 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" 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} value={props.data.currentWork}
onChange={event => props.handleDataChange("currentWork", event)} onChange={(event) => props.handleDataChange('currentWork', event)}
/> />
<input <input
id="currentWork-link" id="currentWork-link"
placeholder="project 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" 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} value={props.link.currentWork}
onChange={event => props.handleLinkChange("currentWork", event)} onChange={(event) => props.handleLinkChange('currentWork', event)}
/> />
</div> </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"> <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">
@@ -34,21 +32,21 @@ const Work = props => {
id="collaborateOn-prefix" 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" 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} value={props.prefix.collaborateOn}
onChange={event => props.handlePrefixChange("collaborateOn", event)} onChange={(event) => props.handlePrefixChange('collaborateOn', event)}
/> />
<input <input
id="collaborateOn" id="collaborateOn"
placeholder="project name" 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" 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} value={props.data.collaborateOn}
onChange={event => props.handleDataChange("collaborateOn", event)} onChange={(event) => props.handleDataChange('collaborateOn', event)}
/> />
<input <input
id="collaborateOn-link" id="collaborateOn-link"
placeholder="project 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" 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} value={props.link.collaborateOn}
onChange={event => props.handleLinkChange("collaborateOn", event)} onChange={(event) => props.handleLinkChange('collaborateOn', event)}
/> />
</div> </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"> <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">
@@ -56,21 +54,21 @@ const Work = props => {
id="helpWith-prefix" 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" 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} value={props.prefix.helpWith}
onChange={event => props.handlePrefixChange("helpWith", event)} onChange={(event) => props.handlePrefixChange('helpWith', event)}
/> />
<input <input
id="helpWith" id="helpWith"
placeholder="project name" 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" 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} value={props.data.helpWith}
onChange={event => props.handleDataChange("helpWith", event)} onChange={(event) => props.handleDataChange('helpWith', event)}
/> />
<input <input
id="helpWith-link" id="helpWith-link"
placeholder="project 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" 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} value={props.link.helpWith}
onChange={event => props.handleLinkChange("helpWith", event)} onChange={(event) => props.handleLinkChange('helpWith', event)}
/> />
</div> </div>
@@ -79,14 +77,14 @@ const Work = props => {
id="currentLearn-prefix" 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" 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} value={props.prefix.currentLearn}
onChange={event => props.handlePrefixChange("currentLearn", event)} onChange={(event) => props.handlePrefixChange('currentLearn', event)}
/> />
<input <input
id="currentLearn" id="currentLearn"
placeholder="Frameworks, courses etc." 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" 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} value={props.data.currentLearn}
onChange={event => props.handleDataChange("currentLearn", event)} onChange={(event) => props.handleDataChange('currentLearn', event)}
/> />
</div> </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"> <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">
@@ -94,14 +92,14 @@ const Work = props => {
id="ama-prefix" 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" 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} value={props.prefix.ama}
onChange={event => props.handlePrefixChange("ama", event)} onChange={(event) => props.handlePrefixChange('ama', event)}
/> />
<input <input
id="ama" id="ama"
placeholder="react, vue and gsap" 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" 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} value={props.data.ama}
onChange={event => props.handleDataChange("ama", event)} onChange={(event) => props.handleDataChange('ama', event)}
/> />
</div> </div>
@@ -110,14 +108,14 @@ const Work = props => {
id="contact-prefix" 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" 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} value={props.prefix.contact}
onChange={event => props.handlePrefixChange("contact", event)} onChange={(event) => props.handlePrefixChange('contact', event)}
/> />
<input <input
id="contact" id="contact"
placeholder="example@gmail.com" 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" 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} value={props.data.contact}
onChange={event => props.handleDataChange("contact", event)} onChange={(event) => props.handleDataChange('contact', event)}
/> />
</div> </div>
@@ -126,14 +124,14 @@ const Work = props => {
id="portfolio-prefix" 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" 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} value={props.prefix.portfolio}
onChange={event => props.handlePrefixChange("portfolio", event)} onChange={(event) => props.handlePrefixChange('portfolio', event)}
/> />
<input <input
id="portfolio" id="portfolio"
placeholder="portfolio link" 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" 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} value={props.link.portfolio}
onChange={event => props.handleLinkChange("portfolio", event)} onChange={(event) => props.handleLinkChange('portfolio', event)}
/> />
</div> </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"> <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">
@@ -141,14 +139,14 @@ const Work = props => {
id="blog-prefix" 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" 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} value={props.prefix.blog}
onChange={event => props.handlePrefixChange("blog", event)} onChange={(event) => props.handlePrefixChange('blog', event)}
/> />
<input <input
id="blog" id="blog"
placeholder="blog link" 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" 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} value={props.link.blog}
onChange={event => props.handleLinkChange("blog", event)} onChange={(event) => props.handleLinkChange('blog', event)}
/> />
</div> </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"> <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">
@@ -156,34 +154,34 @@ const Work = props => {
id="resume-prefix" 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" 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} value={props.prefix.resume}
onChange={event => props.handlePrefixChange("resume", event)} onChange={(event) => props.handlePrefixChange('resume', event)}
/> />
<input <input
id="resume" id="resume"
placeholder="resume link" 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" 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} value={props.link.resume}
onChange={event => props.handleLinkChange("resume", event)} onChange={(event) => props.handleLinkChange('resume', event)}
/> />
</div> </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"> <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 <input
id="funFact-prefix" 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" 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} value={props.prefix.funFact}
onChange={event => props.handlePrefixChange("funFact", event)} onChange={(event) => props.handlePrefixChange('funFact', event)}
/> />
<input <input
id="funFact" id="funFact"
placeholder="I think I am funny" 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" 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} value={props.data.funFact}
onChange={event => props.handleDataChange("funFact", event)} onChange={(event) => props.handleDataChange('funFact', event)}
/> />
</div> </div>
</div> </div>
) );
} };
export default Work export default Work;
+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;
+431 -549
View File
File diff suppressed because it is too large Load Diff
+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,
} };
+3 -3
View File
@@ -1,7 +1,7 @@
--- ---
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">
+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;
+257 -329
View File
@@ -1,20 +1,20 @@
import React, { useState, useEffect } from "react" import React, { useState, useEffect } from 'react';
import gsap from "gsap" import gsap from 'gsap';
import MarkdownPreview from "../components/markdownPreview" import MarkdownPreview from '../components/markdownPreview';
import Markdown from "../components/markdown" import Markdown from '../components/markdown';
import Title from "../components/title" import Title from '../components/title';
import Subtitle from "../components/subtitle" import Subtitle from '../components/subtitle';
import Work from "../components/work" import Work from '../components/work';
import Social from "../components/social" import Social from '../components/social';
import Addons from "../components/addons" import Addons from '../components/addons';
import Skills from "../components/skills" import Skills from '../components/skills';
import Donate from "../components/donate" import Donate from '../components/donate';
import Support from "../components/support" import Support from '../components/support';
import { initialSkillState } from "../constants/skills" import { initialSkillState } from '../constants/skills';
import Loader from "../components/loader" import Loader from '../components/loader';
import SEO from "../components/seo" import SEO from '../components/seo';
import Layout from "../components/layout" import Layout from '../components/layout';
import "./index.css" import './index.css';
import { import {
ArrowLeftIcon, ArrowLeftIcon,
CopyIcon, CopyIcon,
@@ -23,24 +23,14 @@ import {
CheckIcon, CheckIcon,
MarkdownIcon, MarkdownIcon,
FileCodeIcon, FileCodeIcon,
} from "@primer/octicons-react" } from '@primer/octicons-react';
import { import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../utils/validation';
isGitHubUsernameValid, import { DEFAULT_PREFIX, DEFAULT_DATA, DEFAULT_LINK, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
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 }) => { const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
useEffect(() => { useEffect(() => {
localStorage.setItem( localStorage.setItem(
"cache", 'cache',
JSON.stringify({ JSON.stringify({
prefix, prefix,
data, data,
@@ -49,377 +39,355 @@ const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
skills, skills,
support, support,
}) })
) );
}, [prefix, data, link, social, skills, support]) }, [prefix, data, link, social, skills, support]);
} };
const DEFAULT_SKILLS = initialSkillState const DEFAULT_SKILLS = initialSkillState;
const IndexPage = () => { const IndexPage = () => {
const [prefix, setPrefix] = useState(DEFAULT_PREFIX) const [prefix, setPrefix] = useState(DEFAULT_PREFIX);
const [data, setData] = useState(DEFAULT_DATA) const [data, setData] = useState(DEFAULT_DATA);
const [link, setLink] = useState(DEFAULT_LINK) const [link, setLink] = useState(DEFAULT_LINK);
const [social, setSocial] = useState(DEFAULT_SOCIAL) const [social, setSocial] = useState(DEFAULT_SOCIAL);
const [skills, setSkills] = useState(DEFAULT_SKILLS) const [skills, setSkills] = useState(DEFAULT_SKILLS);
const [support, setSupport] = useState(DEFAULT_SUPPORT) const [support, setSupport] = useState(DEFAULT_SUPPORT);
const [restore, setRestore] = useState("") const [restore, setRestore] = useState('');
const [generatePreview, setGeneratePreview] = useState(false) const [generatePreview, setGeneratePreview] = useState(false);
const [generateMarkdown, setGenerateMarkdown] = useState(false) const [generateMarkdown, setGenerateMarkdown] = useState(false);
const [displayLoader, setDisplayLoader] = useState(false) const [displayLoader, setDisplayLoader] = useState(false);
const [showConfig, setShowConfig] = useState(true) const [showConfig, setShowConfig] = useState(true);
const [copyObj, setcopyObj] = useState({ const [copyObj, setcopyObj] = useState({
isCopied: false, isCopied: false,
copiedText: "copy-markdown", copiedText: 'copy-markdown',
}) });
const [previewMarkdown, setPreviewMarkdown] = useState({ const [previewMarkdown, setPreviewMarkdown] = useState({
isPreview: false, isPreview: false,
buttonText: "preview", buttonText: 'preview',
}) });
const handleSkillsChange = field => { const handleSkillsChange = (field) => {
let change = { ...skills } let change = { ...skills };
change[field] = !change[field] change[field] = !change[field];
setSkills(change) setSkills(change);
} };
const handlePrefixChange = (field, e) => { const handlePrefixChange = (field, e) => {
let change = { ...prefix } let change = { ...prefix };
change[field] = e.target.value change[field] = e.target.value;
setPrefix(change) setPrefix(change);
} };
const handleDataChange = (field, e) => { const handleDataChange = (field, e) => {
let change = { ...data } let change = { ...data };
change[field] = e.target.value change[field] = e.target.value;
setData(change) setData(change);
} };
const handleLinkChange = (field, e) => { const handleLinkChange = (field, e) => {
let change = { ...link } let change = { ...link };
change[field] = e.target.value change[field] = e.target.value;
setLink(change) setLink(change);
} };
const handleSocialChange = (field, e) => { const handleSocialChange = (field, e) => {
let change = { ...social } let change = { ...social };
change[field] = change[field] = field === 'discord' ? e.target.value : e.target.value.toLowerCase();
field === "discord" ? e.target.value : e.target.value.toLowerCase() setSocial(change);
setSocial(change) };
}
const handleSupportChange = (field, e) => { const handleSupportChange = (field, e) => {
let change = { ...support } let change = { ...support };
change[field] = e.target.value change[field] = e.target.value;
setSupport(change) setSupport(change);
} };
const handleCheckChange = field => { const handleCheckChange = (field) => {
let change = { ...data } let change = { ...data };
change[field] = !change[field] change[field] = !change[field];
setData(change) setData(change);
} };
const generate = () => { const generate = () => {
setShowConfig(false) setShowConfig(false);
var tl = new gsap.timeline() var tl = new gsap.timeline();
tl.to(".generate", { tl.to('.generate', {
scale: 0, scale: 0,
duration: 0.5, duration: 0.5,
ease: "Linear.easeNone", ease: 'Linear.easeNone',
}) });
tl.set("#form", { display: "none" }) tl.set('#form', { display: 'none' });
setDisplayLoader(true) setDisplayLoader(true);
setTimeout(() => { setTimeout(() => {
setDisplayLoader(false) setDisplayLoader(false);
setGenerateMarkdown(!generateMarkdown) setGenerateMarkdown(!generateMarkdown);
gsap.fromTo( gsap.fromTo(
"#markdown-box", '#markdown-box',
{ {
scale: 0.2, scale: 0.2,
}, },
{ {
scale: 1, scale: 1,
duration: 0.5, duration: 0.5,
ease: "Linear.easeNone", ease: 'Linear.easeNone',
} }
) );
gsap.fromTo( gsap.fromTo(
"#support", '#support',
{ {
autoAlpha: 0, autoAlpha: 0,
}, },
{ {
autoAlpha: 1, autoAlpha: 1,
duration: 2, duration: 2,
ease: "Linear.easeNone", ease: 'Linear.easeNone',
} }
) );
document.body.scrollTop = 0 // For Safari document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0 // For Chrome, Firefox, IE and Opera document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
}, 3000) }, 3000);
} };
const trimDataValues = (item, setItem) => { const trimDataValues = (item, setItem) => {
const dataObj = { ...item } const dataObj = { ...item };
Object.keys(dataObj).forEach(k => Object.keys(dataObj).forEach((k) => (typeof dataObj[k] === 'string' ? (dataObj[k] = dataObj[k].trim()) : null));
typeof dataObj[k] === "string" ? (dataObj[k] = dataObj[k].trim()) : null setItem(dataObj);
) };
setItem(dataObj)
}
const handleGenerate = () => { const handleGenerate = () => {
trimDataValues(data, setData) trimDataValues(data, setData);
trimDataValues(social, setSocial) trimDataValues(social, setSocial);
trimDataValues(link, setLink) trimDataValues(link, setLink);
resetCopyMarkdownButton() resetCopyMarkdownButton();
if ( if (data.visitorsBadge || data.githubProfileTrophy || data.githubStats || data.topLanguages || data.streakStats) {
data.visitorsBadge ||
data.githubProfileTrophy ||
data.githubStats ||
data.topLanguages ||
data.streakStats
) {
if (social.github && isGitHubUsernameValid(social.github)) { if (social.github && isGitHubUsernameValid(social.github)) {
generate() generate();
} }
} else if (data.twitterBadge) { } else if (data.twitterBadge) {
if (social.twitter && isTwitterUsernameValid(social.twitter)) { if (social.twitter && isTwitterUsernameValid(social.twitter)) {
generate() generate();
} }
} else if (social.github) { } else if (social.github) {
if (isGitHubUsernameValid(social.github)) { if (isGitHubUsernameValid(social.github)) {
generate() generate();
} }
} else { } else {
generate() generate();
} }
} };
const handleGeneratePreview = () => { const handleGeneratePreview = () => {
setGenerateMarkdown(!generateMarkdown) setGenerateMarkdown(!generateMarkdown);
setGeneratePreview(!generatePreview) setGeneratePreview(!generatePreview);
if (!generatePreview) { if (!generatePreview) {
gsap.set("#copy-button, #download-md-button, #download-json-button", { gsap.set('#copy-button, #download-md-button, #download-json-button', {
visibility: "hidden", visibility: 'hidden',
}) });
setPreviewMarkdown({ setPreviewMarkdown({
isPreview: true, isPreview: true,
buttonText: "markdown", buttonText: 'markdown',
}) });
} else { } else {
gsap.set("#copy-button, #download-md-button, #download-json-button", { gsap.set('#copy-button, #download-md-button, #download-json-button', {
visibility: "visible", visibility: 'visible',
}) });
gsap.to("#copy-button", { gsap.to('#copy-button', {
border: "2px solid #3b3b4f", border: '2px solid #3b3b4f',
duration: 1, duration: 1,
}) });
setPreviewMarkdown({ setPreviewMarkdown({
isPreview: false, isPreview: false,
buttonText: "preview", buttonText: 'preview',
}) });
resetCopyMarkdownButton() resetCopyMarkdownButton();
} }
} };
const resetCopyMarkdownButton = () => { const resetCopyMarkdownButton = () => {
var el = document.getElementById("copy-markdown") var el = document.getElementById('copy-markdown');
if (el) { if (el) {
gsap.set("#copy-markdown", { gsap.set('#copy-markdown', {
color: "#0a0a23", color: '#0a0a23',
}) });
} }
setcopyObj({ setcopyObj({
isCopied: false, isCopied: false,
copiedText: "copy-markdown", copiedText: 'copy-markdown',
}) });
} };
const setCopyMarkdownButton = () => { const setCopyMarkdownButton = () => {
var el = document.getElementById("copy-markdown") var el = document.getElementById('copy-markdown');
if (el) { if (el) {
gsap.set("#copy-markdown", { gsap.set('#copy-markdown', {
color: "#00471b", color: '#00471b',
}) });
} }
gsap.fromTo( gsap.fromTo(
"#copy-button", '#copy-button',
{ {
scale: 0.5, scale: 0.5,
}, },
{ {
scale: 1, scale: 1,
ease: "elastic.in", ease: 'elastic.in',
border: "2px solid #00471b", border: '2px solid #00471b',
duration: 0.5, duration: 0.5,
} }
) );
setcopyObj({ setcopyObj({
isCopied: true, isCopied: true,
copiedText: "copied", copiedText: 'copied',
}) });
} };
const handleCopyToClipboard = () => { const handleCopyToClipboard = () => {
var range = document.createRange() var range = document.createRange();
range.selectNode(document.getElementById("markdown-content")) range.selectNode(document.getElementById('markdown-content'));
window.getSelection().removeAllRanges() // clear current selection window.getSelection().removeAllRanges(); // clear current selection
window.getSelection().addRange(range) // to select text window.getSelection().addRange(range); // to select text
document.execCommand("copy") document.execCommand('copy');
window.getSelection().removeAllRanges() window.getSelection().removeAllRanges();
setCopyMarkdownButton() setCopyMarkdownButton();
} };
const handleDownloadMarkdown = () => { const handleDownloadMarkdown = () => {
var markdownContent = document.getElementById("markdown-content") var markdownContent = document.getElementById('markdown-content');
var tempElement = document.createElement("a") var tempElement = document.createElement('a');
tempElement.setAttribute( tempElement.setAttribute(
"href", 'href',
"data:text/markdown;charset=utf-8," + 'data:text/markdown;charset=utf-8,' + encodeURIComponent(markdownContent.innerText)
encodeURIComponent(markdownContent.innerText) );
) tempElement.setAttribute('download', 'README.md');
tempElement.setAttribute("download", "README.md") tempElement.style.display = 'none';
tempElement.style.display = "none" document.body.appendChild(tempElement);
document.body.appendChild(tempElement) tempElement.click();
tempElement.click() document.body.removeChild(tempElement);
document.body.removeChild(tempElement) };
}
const handleDownloadJson = () => { const handleDownloadJson = () => {
var tempElement = document.createElement("a") var tempElement = document.createElement('a');
tempElement.setAttribute( tempElement.setAttribute(
"href", 'href',
`data:text/json;charset=utf-8,${encodeURIComponent( `data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify({ prefix, data, link, social, skills, support }) JSON.stringify({ prefix, data, link, social, skills, support })
)}` )}`
) );
tempElement.setAttribute("download", "data.json") tempElement.setAttribute('download', 'data.json');
tempElement.style.display = "none" tempElement.style.display = 'none';
document.body.appendChild(tempElement) document.body.appendChild(tempElement);
tempElement.click() tempElement.click();
document.body.removeChild(tempElement) document.body.removeChild(tempElement);
} };
const handleBackToEdit = () => { const handleBackToEdit = () => {
setGeneratePreview(false) setGeneratePreview(false);
setGenerateMarkdown(false) setGenerateMarkdown(false);
setShowConfig(true) setShowConfig(true);
gsap.set("#form", { gsap.set('#form', {
display: "", display: '',
}) });
gsap.to(".generate", { gsap.to('.generate', {
scale: 1, scale: 1,
}) });
} };
const setInitialValues = () => { const setInitialValues = () => {
const cache = JSON.parse(localStorage.getItem("cache")) const cache = JSON.parse(localStorage.getItem('cache'));
if (!cache) { if (!cache) {
return return;
} }
setPrefix( setPrefix(cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX);
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);
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA) setSocial(cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL);
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK)
setSocial(
cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL
)
const cacheSkills = mergeDefaultWithNewDataSkills( const cacheSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, cache.skills);
DEFAULT_SKILLS, setSkills(cacheSkills || DEFAULT_SKILLS);
cache.skills
)
setSkills(cacheSkills || DEFAULT_SKILLS)
setSupport( setSupport(cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT);
cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT };
)
}
useEffect(() => { useEffect(() => {
gsap.fromTo( gsap.fromTo(
".generate", '.generate',
{ {
boxShadow: "0 0 0 0px rgba(59, 59, 79, 0.4)", boxShadow: '0 0 0 0px rgba(59, 59, 79, 0.4)',
}, },
{ {
boxShadow: "0 0 0 10px rgba(59, 59, 79, 0)", boxShadow: '0 0 0 10px rgba(59, 59, 79, 0)',
repeat: -1, repeat: -1,
duration: 1, duration: 1,
} }
) );
// set initial values // set initial values
setInitialValues() setInitialValues();
}, []) }, []);
// keep cache updated // keep cache updated
KeepCacheUpdated({ prefix, data, link, social, skills, support }) KeepCacheUpdated({ prefix, data, link, social, skills, support });
const handleResetForm = () => { const handleResetForm = () => {
setPrefix(DEFAULT_PREFIX) setPrefix(DEFAULT_PREFIX);
setData(DEFAULT_DATA) setData(DEFAULT_DATA);
setLink(DEFAULT_LINK) setLink(DEFAULT_LINK);
setSocial(DEFAULT_SOCIAL) setSocial(DEFAULT_SOCIAL);
setSkills(DEFAULT_SKILLS) setSkills(DEFAULT_SKILLS);
setSupport(DEFAULT_SUPPORT) setSupport(DEFAULT_SUPPORT);
} };
const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) => { const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) => {
return Object.keys(defaultSkills).reduce((previous, currentKey) => { return Object.keys(defaultSkills).reduce((previous, currentKey) => {
let currentSelected = false let currentSelected = false;
if (newSkills[currentKey]) { if (newSkills[currentKey]) {
currentSelected = true currentSelected = true;
} }
return { return {
...previous, ...previous,
[currentKey]: currentSelected, [currentKey]: currentSelected,
} };
}, {}) }, {});
} };
const handleRestore = () => { const handleRestore = () => {
try { try {
const restoreData = JSON.parse(restore) const restoreData = JSON.parse(restore);
if (!restoreData) { if (!restoreData) {
return return;
} }
setPrefix(restoreData.prefix || DEFAULT_PREFIX) setPrefix(restoreData.prefix || DEFAULT_PREFIX);
setData(restoreData.data || DEFAULT_DATA) setData(restoreData.data || DEFAULT_DATA);
setLink(restoreData.link || DEFAULT_LINK) setLink(restoreData.link || DEFAULT_LINK);
setSocial(restoreData.social || DEFAULT_SOCIAL) setSocial(restoreData.social || DEFAULT_SOCIAL);
setSupport(restoreData.support || DEFAULT_SUPPORT) setSupport(restoreData.support || DEFAULT_SUPPORT);
const restoreDataSkills = mergeDefaultWithNewDataSkills( const restoreDataSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, restoreData.skills);
DEFAULT_SKILLS, setSkills(restoreDataSkills || DEFAULT_SKILLS);
restoreData.skills
)
setSkills(restoreDataSkills || DEFAULT_SKILLS)
} catch (error) { } catch (error) {
} finally { } finally {
setRestore("") setRestore('');
} }
} };
const handleFileInput = e => { const handleFileInput = (e) => {
const file = e.target.files[0] const file = e.target.files[0];
if (file && file.type === "application/json") { if (file && file.type === 'application/json') {
const reader = new FileReader() const reader = new FileReader();
reader.readAsText(file, "UTF-8") reader.readAsText(file, 'UTF-8');
reader.onload = () => { reader.onload = () => {
setRestore(reader.result) setRestore(reader.result);
} };
} }
} };
return ( return (
<Layout> <Layout>
@@ -449,10 +417,7 @@ const IndexPage = () => {
handleCheckChange={handleCheckChange} handleCheckChange={handleCheckChange}
handleDataChange={handleDataChange} handleDataChange={handleDataChange}
/> />
<Support <Support support={support} handleSupportChange={handleSupportChange} />
support={support}
handleSupportChange={handleSupportChange}
/>
<div className="section"> <div className="section">
{(data.visitorsBadge || {(data.visitorsBadge ||
data.githubProfileTrophy || data.githubProfileTrophy ||
@@ -460,62 +425,46 @@ const IndexPage = () => {
data.topLanguages || data.topLanguages ||
data.streakStats) && data.streakStats) &&
!social.github ? ( !social.github ? (
<div className="warning"> <div className="warning">* Please add github username to use these add-ons</div>
* Please add github username to use these add-ons
</div>
) : ( ) : (
"" ''
)} )}
{social.github && !isGitHubUsernameValid(social.github) ? ( {social.github && !isGitHubUsernameValid(social.github) ? (
<div className="warning"> <div className="warning">* GitHub username is invalid, please add a valid username</div>
* GitHub username is invalid, please add a valid username
</div>
) : ( ) : (
"" ''
)} )}
{social.medium && !isMediumUsernameValid(social.medium) ? ( {social.medium && !isMediumUsernameValid(social.medium) ? (
<div className="warning"> <div className="warning">* Medium username is invalid, please add a valid username (with @)</div>
* Medium username is invalid, please add a valid username (with
@)
</div>
) : ( ) : (
"" ''
)} )}
{data.mediumDynamicBlogs && !social.medium ? ( {data.mediumDynamicBlogs && !social.medium ? (
<div className="warning"> <div className="warning">* Please add medium username to display latest blogs dynamically</div>
* Please add medium username to display latest blogs dynamically
</div>
) : ( ) : (
"" ''
)} )}
{data.devDynamicBlogs && !social.dev ? ( {data.devDynamicBlogs && !social.dev ? (
<div className="warning"> <div className="warning">* Please add dev.to username to display latest blogs dynamically</div>
* Please add dev.to username to display latest blogs dynamically
</div>
) : ( ) : (
"" ''
)} )}
{data.rssDynamicBlogs && !social.rssurl ? ( {data.rssDynamicBlogs && !social.rssurl ? (
<div className="warning"> <div className="warning">
* Please add your rss feed url to display latest blogs * Please add your rss feed url to display latest blogs dynamically from your personal blog
dynamically from your personal blog
</div> </div>
) : ( ) : (
"" ''
)} )}
{data.twitterBadge && !social.twitter ? ( {data.twitterBadge && !social.twitter ? (
<div className="warning"> <div className="warning">* Please add twitter username to use these add-ons</div>
* Please add twitter username to use these add-ons
</div>
) : ( ) : (
"" ''
)} )}
{social.twitter && !isTwitterUsernameValid(social.twitter) ? ( {social.twitter && !isTwitterUsernameValid(social.twitter) ? (
<div className="warning"> <div className="warning">* Twitter username is invalid, please add a valid username</div>
* Twitter username is invalid, please add a valid username
</div>
) : ( ) : (
"" ''
)} )}
</div> </div>
<div className="flex items-center justify-center w-full"> <div className="flex items-center justify-center w-full">
@@ -524,14 +473,14 @@ const IndexPage = () => {
tabIndex="0" tabIndex="0"
role="button" role="button"
onClick={handleGenerate} onClick={handleGenerate}
onKeyDown={e => e.keyCode === 13 && handleGenerate()} onKeyDown={(e) => e.keyCode === 13 && handleGenerate()}
> >
Generate README Generate README
</div> </div>
</div> </div>
</div> </div>
{displayLoader ? <Loader /> : ""} {displayLoader ? <Loader /> : ''}
{generateMarkdown || generatePreview ? ( {generateMarkdown || generatePreview ? (
<div className="markdown-section p-4 sm:py-4 sm:px-10"> <div className="markdown-section p-4 sm:py-4 sm:px-10">
@@ -549,11 +498,7 @@ const IndexPage = () => {
id="copy-button" id="copy-button"
onClick={handleCopyToClipboard} onClick={handleCopyToClipboard}
> >
{copyObj.isCopied === true ? ( {copyObj.isCopied === true ? <CheckIcon size={24} /> : <CopyIcon size={24} />}
<CheckIcon size={24} />
) : (
<CopyIcon size={24} />
)}
<span className="hidden sm:block" id="copy-markdown"> <span className="hidden sm:block" id="copy-markdown">
{copyObj.copiedText} {copyObj.copiedText}
</span> </span>
@@ -585,11 +530,7 @@ const IndexPage = () => {
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" 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} onClick={handleGeneratePreview}
> >
{previewMarkdown.isPreview ? ( {previewMarkdown.isPreview ? <MarkdownIcon size={16} /> : <EyeIcon size={16} />}
<MarkdownIcon size={16} />
) : (
<EyeIcon size={16} />
)}
<span className="hidden sm:block ml-1" id="preview-markdown"> <span className="hidden sm:block ml-1" id="preview-markdown">
{previewMarkdown.buttonText} {previewMarkdown.buttonText}
</span> </span>
@@ -611,19 +552,12 @@ const IndexPage = () => {
support={support} support={support}
/> />
) : ( ) : (
"" ''
)} )}
{generateMarkdown ? ( {generateMarkdown ? (
<Markdown <Markdown prefix={prefix} data={data} link={link} social={social} skills={skills} support={support} />
prefix={prefix}
data={data}
link={link}
social={social}
skills={skills}
support={support}
/>
) : ( ) : (
"" ''
)} )}
</div> </div>
</div> </div>
@@ -632,20 +566,18 @@ const IndexPage = () => {
</div> </div>
</div> </div>
) : ( ) : (
"" ''
)} )}
<div <div
className={ className={
"w-full shadow flex flex-col justify-center items-start mt-16 border-2 border-solid border-gray-600 py-2 px-4 " + '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") (!showConfig ? 'hidden' : 'block')
} }
> >
<div className="flex justify-between items-center w-full"> <div className="flex justify-between items-center w-full">
<div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2"> <div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2">
Config options Config options
<span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1"> <span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1">new feature</span>
new feature
</span>
</div> </div>
<button <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" 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"
@@ -660,7 +592,7 @@ const IndexPage = () => {
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" 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" placeholder="Paste JSON code or upload file"
value={restore} value={restore}
onChange={e => setRestore(e.target.value)} onChange={(e) => setRestore(e.target.value)}
/> />
<div className="overflow-hidden relative w-64 mt-4 mb-4"> <div className="overflow-hidden relative w-64 mt-4 mb-4">
@@ -683,17 +615,13 @@ const IndexPage = () => {
</button> </button>
<div className="flex flex-col items-start justify-center"> <div className="flex flex-col items-start justify-center">
<div className="text-green-700 font-medium">Tips</div> <div className="text-green-700 font-medium">Tips</div>
<div className="text-sm sm:text-lg text-gray-700"> <div className="text-sm sm:text-lg text-gray-700">* Enter the downloaded JSON text to restore.</div>
* Enter the downloaded JSON text to restore. <div className="text-sm sm:text-lg text-gray-700">* Press reset to reset the form.</div>
</div>
<div className="text-sm sm:text-lg text-gray-700">
* Press reset to reset the form.
</div>
</div> </div>
</div> </div>
</div> </div>
</Layout> </Layout>
) );
} };
export default IndexPage export default IndexPage;
+16 -21
View File
@@ -1,43 +1,38 @@
// If you don't want to use TypeScript you can delete this file! // If you don't want to use TypeScript you can delete this file!
import React from "react" import React from 'react';
import { PageProps, Link, graphql } from "gatsby" import { PageProps, Link, graphql } from 'gatsby';
import SEO from "../components/seo" import SEO from '../components/seo';
type DataProps = { type DataProps = {
site: { site: {
buildTime: string buildTime: string;
} };
} };
const UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => ( const UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => (
<div> <div>
<SEO title="Using TypeScript" /> <SEO title="Using TypeScript" />
<h1>Gatsby supports TypeScript by default!</h1> <h1>Gatsby supports TypeScript by default!</h1>
<p> <p>
This means that you can create and write <em>.ts/.tsx</em> files for your This means that you can create and write <em>.ts/.tsx</em> files for your pages, components etc. Please note that
pages, components etc. Please note that the <em>gatsby-*.js</em> files the <em>gatsby-*.js</em> files (like gatsby-node.js) currently don't support TypeScript yet.
(like gatsby-node.js) currently don't support TypeScript yet.
</p> </p>
<p> <p>
For type checking you'll want to install <em>typescript</em> via npm and For type checking you'll want to install <em>typescript</em> via npm and run <em>tsc --init</em> to create a{' '}
run <em>tsc --init</em> to create a <em>.tsconfig</em> file. <em>.tsconfig</em> file.
</p> </p>
<p> <p>
You're currently on the page "{path}" which was built on{" "} You're currently on the page "{path}" which was built on {data.site.buildTime}.
{data.site.buildTime}.
</p> </p>
<p> <p>
To learn more, head over to our{" "} To learn more, head over to our{' '}
<a href="https://www.gatsbyjs.org/docs/typescript/"> <a href="https://www.gatsbyjs.org/docs/typescript/">documentation about TypeScript</a>.
documentation about TypeScript
</a>
.
</p> </p>
<Link to="/">Go back to the homepage</Link> <Link to="/">Go back to the homepage</Link>
</div> </div>
) );
export default UsingTypescript export default UsingTypescript;
export const query = graphql` export const query = graphql`
{ {
@@ -45,4 +40,4 @@ export const query = graphql`
buildTime(formatString: "YYYY-MM-DD hh:mm a z") 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`
} }
} }
} }
` `;
+15 -27
View File
@@ -1,30 +1,18 @@
import { import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../validation';
isGitHubUsernameValid,
isMediumUsernameValid,
isTwitterUsernameValid,
} from "../validation"
describe("validation", () => { describe('validation', () => {
it("isGitHubUsernameValid", () => { it('isGitHubUsernameValid', () => {
expect( expect(isGitHubUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
isGitHubUsernameValid( expect(isGitHubUsernameValid('rahuldkjain')).toBe(true);
"Lorem ipsum dolor sit amet, consectetur adipiscing elit" });
)
).toBe(false)
expect(isGitHubUsernameValid("rahuldkjain")).toBe(true)
})
it("isMediumUsernameValid", () => { it('isMediumUsernameValid', () => {
expect(isMediumUsernameValid("rahuldkjain")).toBe(false) expect(isMediumUsernameValid('rahuldkjain')).toBe(false);
expect(isMediumUsernameValid("@rahuldkjain")).toBe(true) expect(isMediumUsernameValid('@rahuldkjain')).toBe(true);
}) });
it("isTwitterUsernameValid", () => { it('isTwitterUsernameValid', () => {
expect( expect(isTwitterUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
isTwitterUsernameValid( expect(isTwitterUsernameValid('rahuldkjain')).toBe(true);
"Lorem ipsum dolor sit amet, consectetur adipiscing elit" });
) });
).toBe(false)
expect(isTwitterUsernameValid("rahuldkjain")).toBe(true)
})
})
+30 -24
View File
@@ -1,31 +1,37 @@
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 query_string = Object.entries(params)
return query_string .map(([key, value]) => `${key}=${value}`)
} .join('&');
return query_string;
};
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 query_string = Object.entries(params)
return query_string .map(([key, value]) => `${key}=${value}`)
} .join('&');
return query_string;
};
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 var 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}$/ var pattern = /^[a-zA-Z0-9_]{1,15}$/;
return pattern.test(username) return pattern.test(username);
} };
export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid };
+18 -35
View File
@@ -1,7 +1,7 @@
import { isMediumUsernameValid } from "../utils/validation" import { isMediumUsernameValid } from '../utils/validation';
const latestBlogs = payload => { const latestBlogs = (payload) => {
let rssFeed = "" let rssFeed = '';
if ( if (
payload.dev.show && payload.dev.show &&
payload.dev.username && payload.dev.username &&
@@ -12,25 +12,16 @@ const latestBlogs = payload => {
isMediumUsernameValid(payload.medium.username) isMediumUsernameValid(payload.medium.username)
) { ) {
rssFeed = rssFeed =
"https://dev.to/feed/" + 'https://dev.to/feed/' +
payload.dev.username + payload.dev.username +
", https://medium.com/feed/" + ', https://medium.com/feed/' +
payload.medium.username + payload.medium.username +
", " + ', ' +
payload.rssurl.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 &&
payload.rssurl.show &&
payload.rssurl.username
) {
rssFeed =
"https://dev.to/feed/" +
payload.dev.username +
", " +
payload.rssurl.username
} else if ( } else if (
payload.rssurl.show && payload.rssurl.show &&
payload.rssurl.username && payload.rssurl.username &&
@@ -38,11 +29,7 @@ const latestBlogs = payload => {
payload.medium.username && payload.medium.username &&
isMediumUsernameValid(payload.medium.username) isMediumUsernameValid(payload.medium.username)
) { ) {
rssFeed = rssFeed = 'https://medium.com/feed/' + payload.medium.username + ', ' + payload.rssurl.username;
"https://medium.com/feed/" +
payload.medium.username +
", " +
payload.rssurl.username
} else if ( } else if (
payload.dev.show && payload.dev.show &&
payload.dev.username && payload.dev.username &&
@@ -50,19 +37,15 @@ const latestBlogs = payload => {
payload.medium.username && payload.medium.username &&
isMediumUsernameValid(payload.medium.username) isMediumUsernameValid(payload.medium.username)
) { ) {
rssFeed = rssFeed = 'https://dev.to/feed/' + payload.dev.username + ', https://medium.com/feed/' + payload.medium.username;
"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 let data = `name: Latest blog post workflow
on: on:
@@ -77,9 +60,9 @@ 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 } 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: [],
} };