Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7898e38f8e | |||
| b23cab5944 | |||
| 8899046e5e | |||
| a0e34df02d | |||
| 9ba8ccff66 | |||
| 004401a8d1 | |||
| fb6389f569 | |||
| d33d139590 | |||
| 1bffabd8bb | |||
| 6ff29bcf87 | |||
| 8c84e917c9 | |||
| f04dc760e2 | |||
| 938a8a9d43 | |||
| 2109192d72 | |||
| 793513dc21 | |||
| bf62cec45f | |||
| 646c0804b9 | |||
| b406f4d181 | |||
| ededb4b8a5 | |||
| 63347fc8b5 | |||
| 1c7bcb7d6b | |||
| edbaa47c40 | |||
| e084c9e775 | |||
| 91bdf52f58 | |||
| 0823cd43ce | |||
| 7a93ebeae1 | |||
| 46d3751b91 | |||
| 6a7a6575b7 | |||
| 61b8362a55 | |||
| 68bfa23dff | |||
| f0a9d02f26 | |||
| 20b47a9c3d | |||
| 9432f7d88d | |||
| 15c63a347a | |||
| fc1ecf5ab6 | |||
| 0194c38eb6 | |||
| be0234927d | |||
| 0253d1b5bb | |||
| c7fc859f0c | |||
| f21bbf2af7 | |||
| bbf6cf6018 | |||
| ccdd09db3f | |||
| 9eb2ab1260 | |||
| 36076a1fe9 | |||
| f8b2c5d9d4 |
@@ -0,0 +1 @@
|
||||
node_modules/**
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": ["plugin:react/recommended", "airbnb", "prettier"],
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["react"],
|
||||
"rules": {
|
||||
"react/forbid-prop-types": 0
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ""
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ""
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
@@ -39,7 +39,6 @@ If applicable, add screenshots to help explain your problem.
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
|
||||
Join the **Discord Server** for further discussions.
|
||||
|
||||
<a href="https://discord.gg/HHMs7Eg">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
name: Feature/Enhancement request
|
||||
about: Suggest an idea for this project
|
||||
title: ""
|
||||
title: ''
|
||||
labels: enhancement, hacktoberfest
|
||||
assignees: ""
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
@@ -40,4 +40,3 @@ as any relevant images for UI changes._
|
||||
## Added to documentation?
|
||||
|
||||
- [ ] readme
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install lint-staged
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false
|
||||
"singleQuote": true,
|
||||
"jsxSingleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"printWidth": 480,
|
||||
"trailingComma": "all",
|
||||
"semi": true,
|
||||
"exclude": ["node_modules", "codepipeline"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "stable"
|
||||
- "14"
|
||||
cache:
|
||||
directories:
|
||||
- "node_modules"
|
||||
|
||||
@@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
|
||||
@@ -9,22 +9,23 @@
|
||||
|
||||
## Reusable 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.
|
||||
* Use ES6 arrow functions for defining 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.
|
||||
- Use ES6 arrow functions for defining components.
|
||||
|
||||
## Spacing
|
||||
|
||||
1. **JS:**
|
||||
* Use a space after `if`, `for`, `while`, `switch`.
|
||||
* Do not use a space after the opening `(` and before the closing `)`.
|
||||
* Use a space before and after destructuring objects.
|
||||
```js
|
||||
//good
|
||||
const { apple, mangoes } = fruits;
|
||||
|
||||
//bad
|
||||
const {apple, mangoes} = fruits;
|
||||
- Use a space after `if`, `for`, `while`, `switch`.
|
||||
- Do not use a space after the opening `(` and before the closing `)`.
|
||||
- Use a space before and after destructuring objects.
|
||||
```js
|
||||
//good
|
||||
const { apple, mangoes } = fruits;
|
||||
|
||||
//bad
|
||||
const { apple, mangoes } = fruits;
|
||||
```
|
||||
|
||||
|
||||
//Same for destructuring props:
|
||||
@@ -36,56 +37,61 @@
|
||||
```
|
||||
|
||||
2. **JSX:**
|
||||
* Use a space before the forward slash (`/`) of a self-closing tag
|
||||
```js
|
||||
//good
|
||||
<Foo />
|
||||
|
||||
//bad
|
||||
<Foo/>
|
||||
```
|
||||
* Do **not** use spaces for JSX curly braces
|
||||
```js
|
||||
//good
|
||||
<Foo bar={baz} />
|
||||
- Use a space before the forward slash (`/`) of a self-closing tag
|
||||
|
||||
//bad
|
||||
<Foo bar={ baz } />
|
||||
```
|
||||
```js
|
||||
//good
|
||||
<Foo />
|
||||
|
||||
//bad
|
||||
<Foo/>
|
||||
```
|
||||
|
||||
- Do **not** use spaces for JSX curly braces
|
||||
|
||||
```js
|
||||
//good
|
||||
<Foo bar={baz} />
|
||||
|
||||
//bad
|
||||
<Foo bar={ baz } />
|
||||
```
|
||||
|
||||
## **Props:**
|
||||
|
||||
* 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.
|
||||
```js
|
||||
//good
|
||||
<Foo
|
||||
prop1={value1}
|
||||
prop2={value2}
|
||||
prop3={value3}
|
||||
/>
|
||||
- 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.
|
||||
|
||||
//bad
|
||||
<Foo prop1={value1} prop2={value2} prop3={value3} />
|
||||
```
|
||||
```js
|
||||
//good
|
||||
<Foo
|
||||
prop1={value1}
|
||||
prop2={value2}
|
||||
prop3={value3}
|
||||
/>
|
||||
|
||||
//bad
|
||||
<Foo prop1={value1} prop2={value2} prop3={value3} />
|
||||
```
|
||||
|
||||
## **Best practices:**
|
||||
|
||||
* **Always** add semicolons after a line.
|
||||
* Use ES6 arrow functions.
|
||||
* Keep the indentation in your code correct.
|
||||
* 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.
|
||||
* **Always** add alt prop to `img` tags.
|
||||
* 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.
|
||||
- **Always** add semicolons after a line.
|
||||
- Use ES6 arrow functions.
|
||||
- Keep the indentation in your code correct.
|
||||
- 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.
|
||||
- **Always** add alt prop to `img` tags.
|
||||
- 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.
|
||||
|
||||
### 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.
|
||||
* 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.
|
||||
- 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`.
|
||||
- Discuss with contributors on discord if you're planning to add/remove a package.
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
## 🚀 Demo
|
||||
|
||||
## 🚀 Demo
|
||||
<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" />
|
||||
</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.
|
||||
|
||||
## 💻 Built with
|
||||
|
||||
- [Gatsby](https://www.gatsbyjs.com/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/): for styling
|
||||
- [GSAP](https://greensock.com/gsap/): for small SVG Animations
|
||||
|
||||
|
||||
## 🙇 Special Thanks
|
||||
|
||||
- [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.
|
||||
- [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
|
||||
|
||||
<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" />
|
||||
</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<p align="center">
|
||||
Developed with ❤️ in India 🇮🇳
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = "test-file-stub"
|
||||
module.exports = 'test-file-stub';
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
const React = require("react")
|
||||
const gatsby = jest.requireActual("gatsby")
|
||||
const React = require('react');
|
||||
const gatsby = jest.requireActual('gatsby');
|
||||
|
||||
module.exports = {
|
||||
...gatsby,
|
||||
graphql: jest.fn(),
|
||||
Link: jest.fn().mockImplementation(
|
||||
// these props are invalid for an `a` tag
|
||||
({
|
||||
activeClassName,
|
||||
activeStyle,
|
||||
getProps,
|
||||
innerRef,
|
||||
partiallyActive,
|
||||
ref,
|
||||
replace,
|
||||
to,
|
||||
...rest
|
||||
}) =>
|
||||
React.createElement("a", {
|
||||
({ activeClassName, activeStyle, getProps, innerRef, partiallyActive, ref, replace, to, ...rest }) =>
|
||||
React.createElement('a', {
|
||||
...rest,
|
||||
href: to,
|
||||
})
|
||||
),
|
||||
StaticQuery: jest.fn(),
|
||||
useStaticQuery: jest.fn(),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
import "./src/styles/tailwind.css"
|
||||
require("prismjs/themes/prism-okaidia.css")
|
||||
import './src/styles/tailwind.css';
|
||||
require('prismjs/themes/prism-okaidia.css');
|
||||
|
||||
@@ -44,7 +44,7 @@ module.exports = {
|
||||
{
|
||||
resolve: `gatsby-plugin-google-analytics`,
|
||||
options: {
|
||||
trackingId: "UA-168596085-3",
|
||||
trackingId: 'UA-168596085-3',
|
||||
// this option places the tracking script into the head of the DOM
|
||||
head: true,
|
||||
// other options
|
||||
@@ -53,7 +53,7 @@ module.exports = {
|
||||
{
|
||||
resolve: `gatsby-plugin-postcss`,
|
||||
options: {
|
||||
postCssPlugins: [require("tailwindcss")],
|
||||
postCssPlugins: [require('tailwindcss')],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -69,4 +69,4 @@ module.exports = {
|
||||
// this (optional) plugin enables Progressive Web App + Offline functionality
|
||||
// To learn more, visit: https://gatsby.dev/offline
|
||||
// `gatsby-plugin-offline`,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
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(`
|
||||
{
|
||||
allMarkdownRemark(
|
||||
sort: { order: DESC, fields: [frontmatter___date] }
|
||||
limit: 1000
|
||||
) {
|
||||
allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }, limit: 1000) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
@@ -18,12 +15,12 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
`);
|
||||
|
||||
// Handle errors
|
||||
if (result.errors) {
|
||||
reporter.panicOnBuild(`Error while running GraphQL query.`)
|
||||
return
|
||||
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
||||
return;
|
||||
}
|
||||
|
||||
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
|
||||
@@ -34,6 +31,6 @@ exports.createPages = async ({ actions, graphql, reporter }) => {
|
||||
// additional data can be passed via context
|
||||
slug: node.frontmatter.slug,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const babelOptions = {
|
||||
presets: ["babel-preset-gatsby"],
|
||||
}
|
||||
presets: ['babel-preset-gatsby'],
|
||||
};
|
||||
|
||||
module.exports = require("babel-jest").createTransformer(babelOptions)
|
||||
module.exports = require('babel-jest').createTransformer(babelOptions);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
module.exports = {
|
||||
transform: {
|
||||
"^.+\\.jsx?$": `<rootDir>/jest-preprocess.js`,
|
||||
'^.+\\.jsx?$': `<rootDir>/jest-preprocess.js`,
|
||||
},
|
||||
moduleNameMapper: {
|
||||
".+\\.(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`,
|
||||
'.+\\.(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`,
|
||||
},
|
||||
testPathIgnorePatterns: [`node_modules`, `\\.cache`, `<rootDir>.*/public`],
|
||||
transformIgnorePatterns: [`node_modules/(?!(gatsby)/)`],
|
||||
globals: {
|
||||
__PATH_PREFIX__: ``,
|
||||
__BASE_PATH__: ``,
|
||||
__BASE_PATH__: ``,
|
||||
},
|
||||
setupFiles: [`<rootDir>/loadershim.js`],
|
||||
setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
|
||||
snapshotSerializers: ["enzyme-to-json/serializer"],
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||
snapshotSerializers: ['enzyme-to-json/serializer'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 0,
|
||||
@@ -23,4 +23,4 @@ module.exports = {
|
||||
statements: 68,
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
global.___loader = {
|
||||
enqueue: jest.fn(),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,12 +4,28 @@
|
||||
"description": "A simple react app to generate beautiful github profile readme in md(markdown)",
|
||||
"version": "1.2.0",
|
||||
"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": {
|
||||
"@primer/octicons-react": "^10.0.0",
|
||||
"axios": "^0.24.0",
|
||||
"enzyme": "^3.11.0",
|
||||
"enzyme-adapter-react-16": "^1.15.5",
|
||||
"enzyme-to-json": "^3.6.1",
|
||||
"eslint": "^7.17.0",
|
||||
"gatsby": "^2.23.12",
|
||||
"gatsby-image": "^2.4.9",
|
||||
"gatsby-plugin-google-analytics": "^2.3.11",
|
||||
@@ -31,13 +47,23 @@
|
||||
"devDependencies": {
|
||||
"babel-jest": "26.3.0",
|
||||
"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-purgecss": "^5.0.0",
|
||||
"gatsby-plugin-twitter": "^2.3.10",
|
||||
"gatsby-remark-embedder": "^3.0.0",
|
||||
"gh-pages": "^3.1.0",
|
||||
"husky": "^7.0.4",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "26.4.2",
|
||||
"lint-staged": "^11.2.6",
|
||||
"prettier": "2.0.5",
|
||||
"tailwindcss": "^1.7.6"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { configure } from "enzyme"
|
||||
import Adapter from "enzyme-adapter-react-16"
|
||||
import { configure } from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
configure({ adapter: new Adapter() })
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
@@ -99,6 +99,24 @@ exports[`Addons renders correctly 1`] = `
|
||||
>
|
||||
display top skills
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
CustomizationOptions={
|
||||
<CustomizeStreakStats
|
||||
onUpdate={[Function]}
|
||||
options={Object {}}
|
||||
prefix="streak-stats"
|
||||
/>
|
||||
}
|
||||
title="Customize Streak Stats Card"
|
||||
/>
|
||||
}
|
||||
inputId="streak-stats"
|
||||
onInputChange={[Function]}
|
||||
>
|
||||
display github streak stats
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputChecked={false}
|
||||
inputId="twitter-badge"
|
||||
@@ -339,15 +357,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="visitors-count"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="visitors-count"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -363,6 +385,7 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<XCircleIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -493,6 +516,7 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
>
|
||||
Preview:
|
||||
<img
|
||||
alt="profile-visitors-count"
|
||||
src="https://komarev.com/ghpvc/?username=undefined&label=Profile%20views&color=0e75b6&style=flat"
|
||||
/>
|
||||
</span>
|
||||
@@ -510,15 +534,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-profile-trophy"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-profile-trophy"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -558,15 +586,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-stats"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -582,6 +614,7 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -644,15 +677,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="top-languages"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="top-languages"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -668,6 +705,86 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
size={16}
|
||||
verticalAlign="text-bottom"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="transform scale-100 md:scale-125"
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
|
||||
}
|
||||
}
|
||||
fill="currentColor"
|
||||
height={16}
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"display": "inline-block",
|
||||
"userSelect": "none",
|
||||
"verticalAlign": "text-bottom",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 16 16"
|
||||
width={16}
|
||||
/>
|
||||
</ToolsIcon>
|
||||
</button>
|
||||
</div>
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
CustomizationOptions={
|
||||
<CustomizeStreakStats
|
||||
onUpdate={[Function]}
|
||||
options={Object {}}
|
||||
prefix="streak-stats"
|
||||
/>
|
||||
}
|
||||
title="Customize Streak Stats Card"
|
||||
/>
|
||||
}
|
||||
inputId="streak-stats"
|
||||
onInputChange={[Function]}
|
||||
>
|
||||
<div
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="streak-stats"
|
||||
>
|
||||
<input
|
||||
className="checkbox-label__input"
|
||||
id="streak-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
display github streak stats
|
||||
</span>
|
||||
</label>
|
||||
<button
|
||||
className="flex ml-3 focus:bg-gray-400"
|
||||
id="streak-stats-open-btn"
|
||||
onClick={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -708,15 +825,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="twitter-badge"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="twitter-badge"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -734,15 +855,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="dev-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="dev-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -760,15 +885,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="medium-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked="some-medium-blogs-value"
|
||||
className="checkbox-label__input"
|
||||
id="medium-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -786,15 +915,19 @@ exports[`Addons should render Customize Badges 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="rss-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="rss-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -931,15 +1064,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="visitors-count"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="visitors-count"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -955,6 +1092,7 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -995,15 +1133,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-profile-trophy"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-profile-trophy"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1043,15 +1185,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-stats"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1067,6 +1213,7 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<XCircleIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -1254,15 +1401,20 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
className="checkbox-label"
|
||||
htmlFor="stats-hide-border"
|
||||
>
|
||||
Hide border:
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="stats-hide-border"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
htmlFor="stats-cache-seconds"
|
||||
@@ -1327,15 +1479,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="top-languages"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="top-languages"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1351,6 +1507,86 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
size={16}
|
||||
verticalAlign="text-bottom"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="transform scale-100 md:scale-125"
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
|
||||
}
|
||||
}
|
||||
fill="currentColor"
|
||||
height={16}
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"display": "inline-block",
|
||||
"userSelect": "none",
|
||||
"verticalAlign": "text-bottom",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 16 16"
|
||||
width={16}
|
||||
/>
|
||||
</ToolsIcon>
|
||||
</button>
|
||||
</div>
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
CustomizationOptions={
|
||||
<CustomizeStreakStats
|
||||
onUpdate={[Function]}
|
||||
options={Object {}}
|
||||
prefix="streak-stats"
|
||||
/>
|
||||
}
|
||||
title="Customize Streak Stats Card"
|
||||
/>
|
||||
}
|
||||
inputId="streak-stats"
|
||||
onInputChange={[Function]}
|
||||
>
|
||||
<div
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="streak-stats"
|
||||
>
|
||||
<input
|
||||
className="checkbox-label__input"
|
||||
id="streak-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
display github streak stats
|
||||
</span>
|
||||
</label>
|
||||
<button
|
||||
className="flex ml-3 focus:bg-gray-400"
|
||||
id="streak-stats-open-btn"
|
||||
onClick={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -1391,15 +1627,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="twitter-badge"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="twitter-badge"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1417,15 +1657,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="dev-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="dev-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1443,15 +1687,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="medium-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked="some-medium-blogs-value"
|
||||
className="checkbox-label__input"
|
||||
id="medium-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1469,15 +1717,19 @@ exports[`Addons should render Customize Github stats card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="rss-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="rss-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1614,15 +1866,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="visitors-count"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="visitors-count"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1638,6 +1894,7 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -1678,15 +1935,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-profile-trophy"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-profile-trophy"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1726,15 +1987,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="github-stats"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="github-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1750,6 +2015,7 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -1812,15 +2078,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="top-languages"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="top-languages"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -1836,6 +2106,7 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<XCircleIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
@@ -2023,15 +2294,20 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
className="checkbox-label"
|
||||
htmlFor="top-lang-hide-border"
|
||||
>
|
||||
Hide border:
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="top-lang-hide-border"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
htmlFor="top-lang-cache-seconds"
|
||||
@@ -2065,6 +2341,85 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
</div>
|
||||
</CustomizeOptions>
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
CustomizationOptions={
|
||||
<CustomizeStreakStats
|
||||
onUpdate={[Function]}
|
||||
options={Object {}}
|
||||
prefix="streak-stats"
|
||||
/>
|
||||
}
|
||||
title="Customize Streak Stats Card"
|
||||
/>
|
||||
}
|
||||
inputId="streak-stats"
|
||||
onInputChange={[Function]}
|
||||
>
|
||||
<div
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="streak-stats"
|
||||
>
|
||||
<input
|
||||
className="checkbox-label__input"
|
||||
id="streak-stats"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
display github streak stats
|
||||
</span>
|
||||
</label>
|
||||
<button
|
||||
className="flex ml-3 focus:bg-gray-400"
|
||||
id="streak-stats-open-btn"
|
||||
onClick={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"outline": "none",
|
||||
}
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
<ToolsIcon
|
||||
className="transform scale-100 md:scale-125"
|
||||
size={16}
|
||||
verticalAlign="text-bottom"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="transform scale-100 md:scale-125"
|
||||
dangerouslySetInnerHTML={
|
||||
Object {
|
||||
"__html": "<path fill-rule=\\"evenodd\\" d=\\"M5.433 2.304A4.494 4.494 0 003.5 6c0 1.598.832 3.002 2.09 3.802.518.328.929.923.902 1.64v.008l-.164 3.337a.75.75 0 11-1.498-.073l.163-3.33c.002-.085-.05-.216-.207-.316A5.996 5.996 0 012 6a5.994 5.994 0 012.567-4.92 1.482 1.482 0 011.673-.04c.462.296.76.827.76 1.423v2.82c0 .082.041.16.11.206l.75.51a.25.25 0 00.28 0l.75-.51A.25.25 0 009 5.282V2.463c0-.596.298-1.127.76-1.423a1.482 1.482 0 011.673.04A5.994 5.994 0 0114 6a5.996 5.996 0 01-2.786 5.068c-.157.1-.209.23-.207.315l.163 3.33a.75.75 0 11-1.498.074l-.164-3.345c-.027-.717.384-1.312.902-1.64A4.496 4.496 0 0012.5 6a4.494 4.494 0 00-1.933-3.696c-.024.017-.067.067-.067.16v2.818a1.75 1.75 0 01-.767 1.448l-.75.51a1.75 1.75 0 01-1.966 0l-.75-.51A1.75 1.75 0 015.5 5.282V2.463c0-.092-.043-.142-.067-.159zm.01-.005z\\"></path>",
|
||||
}
|
||||
}
|
||||
fill="currentColor"
|
||||
height={16}
|
||||
role="img"
|
||||
style={
|
||||
Object {
|
||||
"display": "inline-block",
|
||||
"userSelect": "none",
|
||||
"verticalAlign": "text-bottom",
|
||||
}
|
||||
}
|
||||
viewBox="0 0 16 16"
|
||||
width={16}
|
||||
/>
|
||||
</ToolsIcon>
|
||||
</button>
|
||||
</div>
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputChecked={false}
|
||||
inputId="twitter-badge"
|
||||
@@ -2074,15 +2429,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="twitter-badge"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="twitter-badge"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -2100,15 +2459,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="dev-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="dev-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -2126,15 +2489,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="medium-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked="some-medium-blogs-value"
|
||||
className="checkbox-label__input"
|
||||
id="medium-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
@@ -2152,15 +2519,19 @@ exports[`Addons should render Customize Top Skills Card 1`] = `
|
||||
className="py-2 flex justify-start items-center text-sm sm:text-lg"
|
||||
>
|
||||
<label
|
||||
className="cursor-pointer flex items-center"
|
||||
className="checkbox-label flex items-center"
|
||||
htmlFor="rss-dynamic-blogs"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="checkbox-label__input"
|
||||
id="rss-dynamic-blogs"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<span
|
||||
className="pl-4"
|
||||
>
|
||||
|
||||
@@ -71,17 +71,16 @@ exports[`Donate renders correctly 1`] = `
|
||||
Buy me a ko-fi
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center justify-evenly bg-blue-500 text-white py-2 px-4 my-2"
|
||||
className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid"
|
||||
href="https://www.paypal.me/rahuldkjain/10"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
alt="Donate rahuldkjain via paypal"
|
||||
className="w-6 h-6 mr-2"
|
||||
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg"
|
||||
className="w-32 h-4"
|
||||
src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg"
|
||||
/>
|
||||
Paypal
|
||||
</a>
|
||||
<a
|
||||
className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2"
|
||||
|
||||
@@ -24,8 +24,7 @@ exports[`Footer component renders correctly 1`] = `
|
||||
<div
|
||||
className="mr-2 sm:mr-0"
|
||||
>
|
||||
GitHub Profile
|
||||
|
||||
GitHub Profile
|
||||
<img
|
||||
alt="github profile markdown generator logo"
|
||||
className="inline sm:hidden h-12"
|
||||
@@ -157,7 +156,7 @@ exports[`Footer component renders correctly 1`] = `
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 sm:ml-0"
|
||||
className="ml-2 sm:ml-0"
|
||||
>
|
||||
<a
|
||||
aria-label="Discord of the community"
|
||||
|
||||
@@ -7,7 +7,7 @@ exports[`DisplaySocial Preview renders correctly 1`] = `
|
||||
target="blank"
|
||||
>
|
||||
<img
|
||||
alt="props.username"
|
||||
alt="username"
|
||||
className="w-6 h-6"
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
/>
|
||||
@@ -20,7 +20,7 @@ exports[`DisplayWork Preview renders correctly 1`] = `
|
||||
<div
|
||||
className="my-2"
|
||||
>
|
||||
[object Object]
|
||||
[object Object]
|
||||
<a
|
||||
className="no-underline text-blue-700"
|
||||
href="https://dummy.com"
|
||||
@@ -35,7 +35,7 @@ exports[`DisplayWork Preview renders correctly with no link 1`] = `
|
||||
<div
|
||||
className="my-2"
|
||||
>
|
||||
[object Object]
|
||||
[object Object]
|
||||
<b>
|
||||
readme-generator
|
||||
</b>
|
||||
@@ -52,7 +52,7 @@ exports[`DisplayWork Preview renders correctly with no project 1`] = `
|
||||
<div
|
||||
className="my-2"
|
||||
>
|
||||
[object Object]
|
||||
[object Object]
|
||||
<a
|
||||
className="no-underline text-blue-700"
|
||||
href="https://dummy.com"
|
||||
@@ -86,7 +86,7 @@ exports[`GithubProfileTrophy Preview renders correctly with show true 1`] = `
|
||||
<div
|
||||
className="text-left my-2"
|
||||
>
|
||||
|
||||
|
||||
<a
|
||||
href="https://github.com/ryo-ma/github-profile-trophy"
|
||||
>
|
||||
@@ -95,7 +95,7 @@ exports[`GithubProfileTrophy Preview renders correctly with show true 1`] = `
|
||||
src="https://github-profile-trophy.vercel.app/?username="
|
||||
/>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -219,6 +219,9 @@ exports[`Markdown Preview renders correctly 1`] = `
|
||||
"twitter": "",
|
||||
"youtube": "",
|
||||
},
|
||||
"support": Object {
|
||||
"buyMeACoffee": "",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
@@ -254,6 +257,13 @@ exports[`Markdown Preview renders correctly 1`] = `
|
||||
<SkillsPreview
|
||||
skills={Object {}}
|
||||
/>
|
||||
<SupportPreview
|
||||
support={
|
||||
Object {
|
||||
"buyMeACoffee": "",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className="block sm:flex sm:justify-center sm:items-start"
|
||||
>
|
||||
@@ -287,6 +297,11 @@ exports[`Markdown Preview renders correctly 1`] = `
|
||||
}
|
||||
show={false}
|
||||
/>
|
||||
<StreakStatsPreview
|
||||
github=""
|
||||
options={Object {}}
|
||||
show={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -313,13 +328,13 @@ exports[`Skills Preview renders correctly 1`] = `
|
||||
/>
|
||||
<a
|
||||
href="https://unity.com/"
|
||||
key="unity"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
alt="unity"
|
||||
className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10"
|
||||
key="unity"
|
||||
src="https://www.vectorlogo.zone/logos/unity3d/unity3d-icon.svg"
|
||||
/>
|
||||
</a>
|
||||
@@ -338,112 +353,112 @@ exports[`Social Preview renders correctly 1`] = `
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codepen.svg"
|
||||
username="dummy"
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://dev.to"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/devto.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://twitter.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/twitter.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/twitter.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://linkedin.com/in"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/linked-in-alt.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://stackoverflow.com/users"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/stack-overflow.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://codesandbox.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codesandbox.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://kaggle.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/kaggle.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://fb.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/facebook.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://instagram.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/instagram.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://dribbble.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dribbble.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/dribbble.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.behance.net"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/behance.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/behance.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://medium.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/medium.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/medium.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.youtube.com/c"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/youtube.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/youtube.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.codechef.com/users"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codechef.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://codeforces.com/profile"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerrank.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/hackerrank.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerrank.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://auth.geeksforgeeks.org/user"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/geeksforgeeks.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerearth.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/hackerearth.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.topcoder.com/members"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
|
||||
base="https://codeforces.com/profile"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/codeforces.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.leetcode.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/leetcode.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/leet-code.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerearth.com"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerearth.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://auth.geeksforgeeks.org/user"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/geeks-for-geeks.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://www.topcoder.com/members"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/topcoder.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base="https://discord.gg"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/discord.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/discord.svg"
|
||||
username=""
|
||||
/>
|
||||
<DisplaySocial
|
||||
base=""
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/rss.svg"
|
||||
icon="https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/rss.svg"
|
||||
username=""
|
||||
/>
|
||||
</div>
|
||||
@@ -498,10 +513,11 @@ exports[`TwitterBadgePreview Preview renders correctly with show true 1`] = `
|
||||
<div
|
||||
className="text-left my-2"
|
||||
>
|
||||
|
||||
|
||||
<a
|
||||
href="https://twitter.com/\${props.twitter}"
|
||||
target="blank"
|
||||
href="https://twitter.com/"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
@@ -509,7 +525,7 @@ exports[`TwitterBadgePreview Preview renders correctly with show true 1`] = `
|
||||
src="https://img.shields.io/twitter/follow/?logo=twitter&style=for-the-badge"
|
||||
/>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -519,13 +535,13 @@ exports[`VisitorsBadge Preview renders correctly with show true 1`] = `
|
||||
<div
|
||||
className="text-left my-2"
|
||||
>
|
||||
|
||||
|
||||
<img
|
||||
alt=""
|
||||
className="h-4 sm:h-6"
|
||||
src="https://komarev.com/ghpvc/?username=&label=Profile%20views&color=0e75b6&style=flat"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -537,6 +553,7 @@ exports[`Work Preview renders correctly 1`] = `
|
||||
project="readme-generator"
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="🌱 I’m currently learning"
|
||||
project=""
|
||||
/>
|
||||
@@ -551,26 +568,32 @@ exports[`Work Preview renders correctly 1`] = `
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="💬 Ask me about"
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="👨💻 All of my projects are available at"
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="📝 I regularly write articles on"
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="📄 Know about my experiences"
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="📫 How to reach me"
|
||||
project=""
|
||||
/>
|
||||
<DisplayWork
|
||||
link=""
|
||||
prefix="⚡ Fun fact"
|
||||
project=""
|
||||
/>
|
||||
|
||||
@@ -50,15 +50,19 @@ exports[`Skills renders correctly 1`] = `
|
||||
key="javascript"
|
||||
>
|
||||
<label
|
||||
className="skillCheckboxLabel cursor-pointer flex items-center justify-start"
|
||||
className="checkbox-label flex items-center justify-start"
|
||||
htmlFor="javascript"
|
||||
>
|
||||
<input
|
||||
checked={true}
|
||||
className="checkbox-label__input"
|
||||
id="javascript"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<img
|
||||
alt="javascript"
|
||||
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
|
||||
@@ -90,14 +94,18 @@ exports[`Skills renders correctly 1`] = `
|
||||
key="react"
|
||||
>
|
||||
<label
|
||||
className="skillCheckboxLabel cursor-pointer flex items-center justify-start"
|
||||
className="checkbox-label flex items-center justify-start"
|
||||
htmlFor="react"
|
||||
>
|
||||
<input
|
||||
className="checkbox-label__input"
|
||||
id="react"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<img
|
||||
alt="react"
|
||||
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
|
||||
@@ -115,14 +123,18 @@ exports[`Skills renders correctly 1`] = `
|
||||
key="svelte"
|
||||
>
|
||||
<label
|
||||
className="skillCheckboxLabel cursor-pointer flex items-center justify-start"
|
||||
className="checkbox-label flex items-center justify-start"
|
||||
htmlFor="svelte"
|
||||
>
|
||||
<input
|
||||
className="checkbox-label__input"
|
||||
id="svelte"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="checkbox-label__control"
|
||||
/>
|
||||
<img
|
||||
alt="svelte"
|
||||
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from "react"
|
||||
import toJson from "enzyme-to-json"
|
||||
import { shallow } from "enzyme"
|
||||
import React from 'react';
|
||||
import toJson from 'enzyme-to-json';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import Donate from "../donate"
|
||||
import Donate from '../donate';
|
||||
|
||||
describe("Donate", () => {
|
||||
it("renders correctly", () => {
|
||||
const component = shallow(<Donate />)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe('Donate', () => {
|
||||
it('renders correctly', () => {
|
||||
const component = shallow(<Donate />);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Footer from "../footer"
|
||||
import Footer from '../footer';
|
||||
|
||||
describe("Footer component", () => {
|
||||
const component = shallow(<Footer />)
|
||||
describe('Footer component', () => {
|
||||
const component = shallow(<Footer />);
|
||||
|
||||
it("renders correctly", () => {
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
it('renders correctly', () => {
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Header from "../header"
|
||||
import Header from '../header';
|
||||
|
||||
describe("Header", () => {
|
||||
const component = shallow(<Header heading="heading" />)
|
||||
describe('Header', () => {
|
||||
const component = shallow(<Header heading="heading" />);
|
||||
|
||||
it("renders correctly", () => {
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
it('renders correctly', () => {
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Loader from "../loader"
|
||||
import Loader from '../loader';
|
||||
|
||||
describe("Loader", () => {
|
||||
const component = shallow(<Loader />)
|
||||
describe('Loader', () => {
|
||||
const component = shallow(<Loader />);
|
||||
|
||||
it("renders correctly", () => {
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
it('renders correctly', () => {
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Markdown from "../markdown"
|
||||
import Markdown from '../markdown';
|
||||
|
||||
describe("Markdown", () => {
|
||||
describe('Markdown', () => {
|
||||
const props = {
|
||||
data: {
|
||||
ama: '',
|
||||
@@ -77,139 +77,138 @@ describe("Markdown", () => {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
it("renders without subtitle", () => {
|
||||
it('renders without subtitle', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
subtitle: '',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
subtitle: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders without prefix.title and data.title", () => {
|
||||
it('renders without prefix.title and data.title', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
title: '',
|
||||
}}
|
||||
prefix={{
|
||||
...props.prefix,
|
||||
title: '',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
title: '',
|
||||
}}
|
||||
prefix={{
|
||||
...props.prefix,
|
||||
title: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders topLanguages is true", () => {
|
||||
it('renders topLanguages is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
topLanguages: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
topLanguages: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
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(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
topLanguages: true,
|
||||
githubStats: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
topLanguages: true,
|
||||
githubStats: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders devDynamicBlogs is true", () => {
|
||||
it('renders devDynamicBlogs is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
devDynamicBlogs: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
devDynamicBlogs: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders without link.currentWork", () => {
|
||||
it('renders without link.currentWork', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
link={{
|
||||
...props.data,
|
||||
currentWork: '',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
link={{
|
||||
...props.data,
|
||||
currentWork: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders visitorsBadge is true", () => {
|
||||
it('renders visitorsBadge is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
visitorsBadge: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
visitorsBadge: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders twitterBadge is true", () => {
|
||||
it('renders twitterBadge is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
twitterBadge: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
twitterBadge: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders githubProfileTrophy is true", () => {
|
||||
it('renders githubProfileTrophy is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
githubProfileTrophy: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
githubProfileTrophy: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders githubProfileTrophy is true", () => {
|
||||
it('renders githubProfileTrophy is true', () => {
|
||||
const component = shallow(
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
githubProfileTrophy: true,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
<Markdown
|
||||
{...props}
|
||||
data={{
|
||||
...props.data,
|
||||
githubProfileTrophy: true,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,415 +1,404 @@
|
||||
import React from "react";
|
||||
import React from 'react';
|
||||
import { shallow, configure } from 'enzyme';
|
||||
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() });
|
||||
|
||||
const DEFAULT_PREFIX = {
|
||||
title: "Hi 👋, I'm",
|
||||
currentWork: "🔭 I’m currently working on",
|
||||
currentLearn: "🌱 I’m currently learning",
|
||||
collaborateOn: "👯 I’m looking to collaborate on",
|
||||
helpWith: "🤝 I’m looking for help with",
|
||||
ama: "💬 Ask me about",
|
||||
contact: "📫 How to reach me",
|
||||
resume: "📄 Know about my experiences",
|
||||
funFact: "⚡ Fun fact",
|
||||
portfolio: "👨💻 All of my projects are available at",
|
||||
blog: "📝 I regularly write articles on",
|
||||
}
|
||||
title: "Hi 👋, I'm",
|
||||
currentWork: '🔭 I’m currently working on',
|
||||
currentLearn: '🌱 I’m currently learning',
|
||||
collaborateOn: '👯 I’m looking to collaborate on',
|
||||
helpWith: '🤝 I’m looking for help with',
|
||||
ama: '💬 Ask me about',
|
||||
contact: '📫 How to reach me',
|
||||
resume: '📄 Know about my experiences',
|
||||
funFact: '⚡ Fun fact',
|
||||
portfolio: '👨💻 All of my projects are available at',
|
||||
blog: '📝 I regularly write articles on',
|
||||
};
|
||||
|
||||
const DEFAULT_DATA = {
|
||||
title: "dummy",
|
||||
subtitle: "A passionate frontend developer from India",
|
||||
currentWork: "readme-generator",
|
||||
currentLearn: "",
|
||||
collaborateOn: "",
|
||||
helpWith: "",
|
||||
ama: "",
|
||||
contact: "",
|
||||
funFact: "",
|
||||
twitterBadge: false,
|
||||
visitorsBadge: false,
|
||||
badgeStyle: "flat",
|
||||
badgeColor: "0e75b6",
|
||||
badgeLabel: "Profile views",
|
||||
githubProfileTrophy: false,
|
||||
githubStats: false,
|
||||
githubStatsOptions: {
|
||||
theme: "",
|
||||
titleColor: "",
|
||||
textColor: "",
|
||||
bgColor: "",
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: "en",
|
||||
},
|
||||
topLanguages: false,
|
||||
topLanguagesOptions: {
|
||||
theme: "",
|
||||
titleColor: "",
|
||||
textColor: "",
|
||||
bgColor: "",
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: "en",
|
||||
},
|
||||
devDynamicBlogs: false,
|
||||
mediumDynamicBlogs: false,
|
||||
rssDynamicBlogs: false,
|
||||
}
|
||||
title: 'dummy',
|
||||
subtitle: 'A passionate frontend developer from India',
|
||||
currentWork: 'readme-generator',
|
||||
currentLearn: '',
|
||||
collaborateOn: '',
|
||||
helpWith: '',
|
||||
ama: '',
|
||||
contact: '',
|
||||
funFact: '',
|
||||
twitterBadge: false,
|
||||
visitorsBadge: false,
|
||||
badgeStyle: 'flat',
|
||||
badgeColor: '0e75b6',
|
||||
badgeLabel: 'Profile views',
|
||||
githubProfileTrophy: false,
|
||||
githubStats: false,
|
||||
githubStatsOptions: {
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: 'en',
|
||||
},
|
||||
topLanguages: false,
|
||||
topLanguagesOptions: {
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: 'en',
|
||||
},
|
||||
devDynamicBlogs: false,
|
||||
mediumDynamicBlogs: false,
|
||||
rssDynamicBlogs: false,
|
||||
};
|
||||
|
||||
const DEFAULT_LINK = {
|
||||
currentWork: "https://dummy.com",
|
||||
collaborateOn: "",
|
||||
helpWith: "",
|
||||
portfolio: "",
|
||||
blog: "",
|
||||
resume: "",
|
||||
}
|
||||
currentWork: 'https://dummy.com',
|
||||
collaborateOn: '',
|
||||
helpWith: '',
|
||||
portfolio: '',
|
||||
blog: '',
|
||||
resume: '',
|
||||
};
|
||||
|
||||
const DEFAULT_SOCIAL = {
|
||||
github: "",
|
||||
dev: "",
|
||||
linkedin: "",
|
||||
codepen: "dummy",
|
||||
stackoverflow: "",
|
||||
kaggle: "",
|
||||
codesandbox: "",
|
||||
fb: "",
|
||||
instagram: "",
|
||||
twitter: "",
|
||||
dribbble: "",
|
||||
behance: "",
|
||||
medium: "",
|
||||
youtube: "",
|
||||
codechef: "",
|
||||
hackerrank: "",
|
||||
codeforces: "",
|
||||
leetcode: "",
|
||||
topcoder: "",
|
||||
hackerearth: "",
|
||||
geeks_for_geeks: "",
|
||||
discord: "",
|
||||
rssurl: "",
|
||||
}
|
||||
github: '',
|
||||
dev: '',
|
||||
linkedin: '',
|
||||
codepen: 'dummy',
|
||||
stackoverflow: '',
|
||||
kaggle: '',
|
||||
codesandbox: '',
|
||||
fb: '',
|
||||
instagram: '',
|
||||
twitter: '',
|
||||
dribbble: '',
|
||||
behance: '',
|
||||
medium: '',
|
||||
youtube: '',
|
||||
codechef: '',
|
||||
hackerrank: '',
|
||||
codeforces: '',
|
||||
leetcode: '',
|
||||
topcoder: '',
|
||||
hackerearth: '',
|
||||
geeks_for_geeks: '',
|
||||
discord: '',
|
||||
rssurl: '',
|
||||
};
|
||||
|
||||
const DUMMY_SKILLS = {
|
||||
skills: {
|
||||
unity: true,
|
||||
android: false,
|
||||
angularjs: false,
|
||||
apachecordova: false,
|
||||
}
|
||||
}
|
||||
skills: {
|
||||
unity: true,
|
||||
android: false,
|
||||
angularjs: false,
|
||||
apachecordova: false,
|
||||
},
|
||||
};
|
||||
|
||||
describe("Markdown Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
let skills = {}
|
||||
const tree = shallow(<MarkdownPreview
|
||||
prefix={prefix}
|
||||
data={data}
|
||||
link={link}
|
||||
social={social}
|
||||
skills={skills} />)
|
||||
describe('Markdown Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
let skills = {};
|
||||
const tree = shallow(<MarkdownPreview prefix={prefix} data={data} link={link} social={social} skills={skills} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("Title Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('Title Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<TitlePreview prefix={prefix.title} title={data.title} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no prefix", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
const tree = shallow(<TitlePreview prefix={prefix.title} title={""} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no prefix', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
const tree = shallow(<TitlePreview prefix={prefix.title} title={''} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no title", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<TitlePreview title={data.title} prefix={""} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no title', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<TitlePreview title={data.title} prefix={''} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no title and prefix", () => {
|
||||
const tree = shallow(<TitlePreview />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no title and prefix', () => {
|
||||
const tree = shallow(<TitlePreview />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("SubTitle Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('SubTitle Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<SubTitlePreview subtitle={data.subtitle} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no subtitle", () => {
|
||||
const tree = shallow(<SubTitlePreview subtitle={""} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no subtitle', () => {
|
||||
const tree = shallow(<SubTitlePreview subtitle={''} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("SectionTitle Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
const tree = shallow(<SectionTitle visible={true} label={"dummy"} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('SectionTitle Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
const tree = shallow(<SectionTitle visible={true} label={'dummy'} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no label", () => {
|
||||
const tree = shallow(<SectionTitle visible={true} label={""} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no label', () => {
|
||||
const tree = shallow(<SectionTitle visible={true} label={''} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with visible false", () => {
|
||||
const tree = shallow(<SectionTitle visible={false} label={"dummy"} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with visible false', () => {
|
||||
const tree = shallow(<SectionTitle visible={false} label={'dummy'} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("DisplayWork Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('DisplayWork Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={link.currentWork} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no prefix, link and project", () => {
|
||||
const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no prefix, link and project', () => {
|
||||
const tree = shallow(<DisplayWork prefix={undefined} project={undefined} link={undefined} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no prefix", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no prefix', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={undefined} project={data.currentWork} link={link.currentWork} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no project", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no project', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={undefined} link={link.currentWork} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no link", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined}/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no link', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} project={data.currentWork} link={undefined} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no prefix and link", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<DisplayWork project={data.currentWork} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no prefix and link', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
const tree = shallow(<DisplayWork project={data.currentWork} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no project and link", () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no project and link', () => {
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
const tree = shallow(<DisplayWork prefix={prefix} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no project and prefix", () => {
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork link={link.currentWork} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no project and prefix', () => {
|
||||
let link = DEFAULT_LINK;
|
||||
const tree = shallow(<DisplayWork link={link.currentWork} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("DisplaySocial Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
username={social.codepen}
|
||||
/>
|
||||
)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('DisplaySocial Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(
|
||||
<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
username={social.codepen}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no username", () => {
|
||||
const tree = shallow(<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
username={""}
|
||||
/>
|
||||
)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no username', () => {
|
||||
const tree = shallow(
|
||||
<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
username={''}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("VisitorsBadge Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<VisitorsBadgePreview
|
||||
show={data.visitorsBadge}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('VisitorsBadge Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(
|
||||
<VisitorsBadgePreview
|
||||
show={data.visitorsBadge}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with show true", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<VisitorsBadgePreview
|
||||
show={true}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with show true', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(
|
||||
<VisitorsBadgePreview
|
||||
show={true}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("GithubProfileTrophy Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GithubProfileTrophyPreview
|
||||
show={data.githubProfileTrophy}
|
||||
github={social.github}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('GithubProfileTrophy Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GithubProfileTrophyPreview show={data.githubProfileTrophy} github={social.github} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with show true", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GithubProfileTrophyPreview
|
||||
show={true}
|
||||
github={social.github}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with show true', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GithubProfileTrophyPreview show={true} github={social.github} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("TwitterBadgePreview Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TwitterBadgePreview
|
||||
show={data.twitterBadge}
|
||||
twitter={social.twitter}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('TwitterBadgePreview Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TwitterBadgePreview show={data.twitterBadge} twitter={social.twitter} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with show true", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TwitterBadgePreview
|
||||
show={true}
|
||||
twitter={social.twitter}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with show true', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TwitterBadgePreview show={true} twitter={social.twitter} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("Work Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let link = DEFAULT_LINK;
|
||||
let props = { data: data, prefix: prefix, link: link }
|
||||
const tree = shallow(<WorkPreview work={props} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('Work Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let prefix = DEFAULT_PREFIX;
|
||||
let link = DEFAULT_LINK;
|
||||
let props = { data: data, prefix: prefix, link: link };
|
||||
const tree = shallow(<WorkPreview work={props} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("Social Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<SocialPreview social={social} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('Social Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<SocialPreview social={social} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("Skills Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let skills = DUMMY_SKILLS.skills
|
||||
const tree = shallow(<SkillsPreview skills={skills} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('Skills Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let skills = DUMMY_SKILLS.skills;
|
||||
const tree = shallow(<SkillsPreview skills={skills} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with no skills", () => {
|
||||
let skills = {}
|
||||
const tree = shallow(<SkillsPreview skills={skills} />)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with no skills', () => {
|
||||
let skills = {};
|
||||
const tree = shallow(<SkillsPreview skills={skills} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("TopLanguages Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TopLanguagesPreview
|
||||
show={data.topLanguages}
|
||||
github={social.github}
|
||||
options={data.topLanguagesOptions}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('TopLanguages Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(
|
||||
<TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly with show true", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TopLanguagesPreview
|
||||
show={true}
|
||||
github={social.github}
|
||||
options={data.topLanguagesOptions}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly with show true', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<TopLanguagesPreview show={true} github={social.github} options={data.topLanguagesOptions} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
describe("GitHubStats Preview", () => {
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GitHubStatsPreview
|
||||
show={data.githubStats}
|
||||
github={social.github}
|
||||
options={data.githubStatsOptions}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('GitHubStats Preview', () => {
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(
|
||||
<GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
it("renders correctly", () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GitHubStatsPreview
|
||||
show={true}
|
||||
github={social.github}
|
||||
options={data.githubStatsOptions}
|
||||
/>)
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
it('renders correctly', () => {
|
||||
let data = DEFAULT_DATA;
|
||||
let social = DEFAULT_SOCIAL;
|
||||
const tree = shallow(<GitHubStatsPreview show={true} github={social.github} options={data.githubStatsOptions} />);
|
||||
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,42 +1,40 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Skills from "../skills"
|
||||
import Skills from '../skills';
|
||||
|
||||
jest.mock("../../constants/skills", () => ({
|
||||
jest.mock('../../constants/skills', () => ({
|
||||
__esModule: true,
|
||||
categorizedSkills: {
|
||||
language: {
|
||||
title: "Programming Languages",
|
||||
skills: ["javascript"],
|
||||
title: 'Programming Languages',
|
||||
skills: ['javascript'],
|
||||
},
|
||||
frontend_dev: {
|
||||
title: "Frontend Development",
|
||||
skills: ["react", "svelte"],
|
||||
title: 'Frontend Development',
|
||||
skills: ['react', 'svelte'],
|
||||
},
|
||||
},
|
||||
icons: {
|
||||
javascript: "javascript.svg",
|
||||
react: "react.svg",
|
||||
svelte: "svelte.svg",
|
||||
javascript: 'javascript.svg',
|
||||
react: 'react.svg',
|
||||
svelte: 'svelte.svg',
|
||||
},
|
||||
}))
|
||||
}));
|
||||
|
||||
describe("Skills", () => {
|
||||
it("renders correctly", () => {
|
||||
const component = shallow(<Skills skills={{ javascript: true }} />)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
describe('Skills', () => {
|
||||
it('renders correctly', () => {
|
||||
const component = shallow(<Skills skills={{ javascript: true }} />);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("calls handleSkillsChange prop when a skill is clicked", () => {
|
||||
const mockFn = jest.fn()
|
||||
const component = shallow(
|
||||
<Skills skills={{ javascript: true }} handleSkillsChange={mockFn} />
|
||||
)
|
||||
it('calls handleSkillsChange prop when a skill is clicked', () => {
|
||||
const mockFn = jest.fn();
|
||||
const component = shallow(<Skills skills={{ javascript: true }} handleSkillsChange={mockFn} />);
|
||||
|
||||
component.find("#javascript").simulate("change")
|
||||
component.find('#javascript').simulate('change');
|
||||
|
||||
expect(mockFn).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Social from "../social"
|
||||
import Social from '../social';
|
||||
|
||||
describe("Social", () => {
|
||||
const mockEvent = { target: { value: "This is a mock event" } }
|
||||
describe('Social', () => {
|
||||
const mockEvent = { target: { value: 'This is a mock event' } };
|
||||
const props = {
|
||||
social: {
|
||||
github: "github ",
|
||||
twitter: "twitter",
|
||||
dev: "dev",
|
||||
codepen: "codepen",
|
||||
codesandbox: "codesandbodx",
|
||||
stackoverflow: "stackoverflow",
|
||||
linkedin: "linkedin",
|
||||
kaggle: "kaggle",
|
||||
fb: "fb",
|
||||
instagram: "instagram",
|
||||
dribble: "dribble",
|
||||
behance: "behance",
|
||||
medium: "medium",
|
||||
youtube: "youtube",
|
||||
codechef: "codechef",
|
||||
hackerrack: "hackerranck",
|
||||
codeforces: "codeforces",
|
||||
leetcode: "leetcode",
|
||||
topcoder: "topcoder",
|
||||
hackerearth: "@hackerearth",
|
||||
geeks_for_geeks: "geeks_for_geeks",
|
||||
discord: "discord",
|
||||
rssurl: "rssurl",
|
||||
github: 'github ',
|
||||
twitter: 'twitter',
|
||||
dev: 'dev',
|
||||
codepen: 'codepen',
|
||||
codesandbox: 'codesandbodx',
|
||||
stackoverflow: 'stackoverflow',
|
||||
linkedin: 'linkedin',
|
||||
kaggle: 'kaggle',
|
||||
fb: 'fb',
|
||||
instagram: 'instagram',
|
||||
dribble: 'dribble',
|
||||
behance: 'behance',
|
||||
medium: 'medium',
|
||||
youtube: 'youtube',
|
||||
codechef: 'codechef',
|
||||
hackerrack: 'hackerranck',
|
||||
codeforces: 'codeforces',
|
||||
leetcode: 'leetcode',
|
||||
topcoder: 'topcoder',
|
||||
hackerearth: '@hackerearth',
|
||||
geeks_for_geeks: 'geeks_for_geeks',
|
||||
discord: 'discord',
|
||||
rssurl: 'rssurl',
|
||||
},
|
||||
handleSocialChange: jest.fn().mockReturnValue({}),
|
||||
}
|
||||
it("renders correctly", () => {
|
||||
const component = shallow(<Social {...props} />)
|
||||
for (let i = 0; i < component.find("input").length; i++) {
|
||||
component.find("input").at(i).simulate("change", mockEvent)
|
||||
};
|
||||
it('renders correctly', () => {
|
||||
const component = shallow(<Social {...props} />);
|
||||
for (let i = 0; i < component.find('input').length; i++) {
|
||||
component.find('input').at(i).simulate('change', mockEvent);
|
||||
}
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Subtitle from "../subtitle"
|
||||
import Subtitle from '../subtitle';
|
||||
|
||||
describe("Subtitle", () => {
|
||||
const mockEvent = { target: { value: "This is a mock event" } }
|
||||
describe('Subtitle', () => {
|
||||
const mockEvent = { target: { value: 'This is a mock event' } };
|
||||
const props = {
|
||||
data: {
|
||||
subtitle: "A frontend developer",
|
||||
subtitle: 'A frontend developer',
|
||||
},
|
||||
handleDataChange: jest.fn().mockReturnValue({}),
|
||||
}
|
||||
};
|
||||
|
||||
const component = shallow(<Subtitle {...props} />)
|
||||
const component = shallow(<Subtitle {...props} />);
|
||||
|
||||
it("renders correctly", () => {
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
it('renders correctly', () => {
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("calls onChange", () => {
|
||||
component.find("input").at(0).simulate("change", mockEvent)
|
||||
expect(props.handleDataChange).toBeCalledWith("subtitle", mockEvent)
|
||||
})
|
||||
})
|
||||
it('calls onChange', () => {
|
||||
component.find('input').at(0).simulate('change', mockEvent);
|
||||
expect(props.handleDataChange).toBeCalledWith('subtitle', mockEvent);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Title from "../title"
|
||||
import Title from '../title';
|
||||
|
||||
describe("Title", () => {
|
||||
const mockEvent = { target: { value: "This is a mock event" } }
|
||||
describe('Title', () => {
|
||||
const mockEvent = { target: { value: 'This is a mock event' } };
|
||||
const props = {
|
||||
prefix: {
|
||||
title: "test_title",
|
||||
currentWork: "test_currentwork",
|
||||
title: 'test_title',
|
||||
currentWork: 'test_currentwork',
|
||||
},
|
||||
data: { title: "test_data" },
|
||||
link: { currentWork: "test_currentwork" },
|
||||
data: { title: 'test_data' },
|
||||
link: { currentWork: 'test_currentwork' },
|
||||
handlePrefixChange: jest.fn().mockReturnValue({}),
|
||||
handleLinkChange: jest.fn().mockReturnValue({}),
|
||||
handleDataChange: jest.fn().mockReturnValue({}),
|
||||
}
|
||||
};
|
||||
|
||||
it("renders title component correctly", () => {
|
||||
const component = shallow(<Title {...props} />)
|
||||
component.find("input").at(0).simulate("change", mockEvent)
|
||||
component.find("input").at(1).simulate("change", mockEvent)
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
it('renders title component correctly', () => {
|
||||
const component = shallow(<Title {...props} />);
|
||||
component.find('input').at(0).simulate('change', mockEvent);
|
||||
component.find('input').at(1).simulate('change', mockEvent);
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import React from "react"
|
||||
import { shallow } from "enzyme"
|
||||
import toJson from "enzyme-to-json"
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import toJson from 'enzyme-to-json';
|
||||
|
||||
import Work from "../work"
|
||||
import Work from '../work';
|
||||
|
||||
describe("Work", () => {
|
||||
const mockEvent = { target: { value: "This is a mock event" } }
|
||||
describe('Work', () => {
|
||||
const mockEvent = { target: { value: 'This is a mock event' } };
|
||||
const props = {
|
||||
prefix: {
|
||||
title: "test_title",
|
||||
currentWork: "test_currentwork",
|
||||
title: 'test_title',
|
||||
currentWork: 'test_currentwork',
|
||||
},
|
||||
data: { title: "test_data" },
|
||||
link: { currentWork: "test_currentwork" },
|
||||
data: { title: 'test_data' },
|
||||
link: { currentWork: 'test_currentwork' },
|
||||
handlePrefixChange: jest.fn().mockReturnValue({}),
|
||||
handleLinkChange: jest.fn().mockReturnValue({}),
|
||||
handleDataChange: jest.fn().mockReturnValue({}),
|
||||
}
|
||||
};
|
||||
|
||||
it("renders work component correctly", () => {
|
||||
const component = shallow(<Work {...props} />)
|
||||
for (let i = 0; i < component.find("input").length; i++) {
|
||||
component.find("input").at(i).simulate("change", mockEvent)
|
||||
it('renders work component correctly', () => {
|
||||
const component = shallow(<Work {...props} />);
|
||||
for (let i = 0; i < component.find('input').length; i++) {
|
||||
component.find('input').at(i).simulate('change', mockEvent);
|
||||
}
|
||||
expect(toJson(component)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
expect(toJson(component)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,451 +0,0 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import { withPrefix } from "gatsby"
|
||||
import { latestBlogs } from "../utils/workflows"
|
||||
import links from "../constants/page-links"
|
||||
import { isMediumUsernameValid, isGitHubUsernameValid } from "../utils/validation"
|
||||
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react";
|
||||
|
||||
const AddonsItem = ({ inputId, inputChecked, onInputChange, Options, onIconClick, ...props }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const Icon = open ? XCircleIcon : ToolsIcon;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="py-2 flex justify-start items-center text-sm sm:text-lg">
|
||||
<label htmlFor={inputId} className="cursor-pointer flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={inputId}
|
||||
checked={inputChecked}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
<span className="pl-4">{props.children}</span>
|
||||
</label>
|
||||
{Options && (
|
||||
<button
|
||||
id={`${inputId}-open-btn`}
|
||||
onClick={() => setOpen(!open)}
|
||||
className="flex ml-3 focus:bg-gray-400"
|
||||
style={{ outline: "none" }}
|
||||
>
|
||||
<Icon className="transform scale-100 md:scale-125" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{Options && open && Options}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const CustomizeOptions = ({ title, CustomizationOptions }) => (
|
||||
<div
|
||||
className={`border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8`}
|
||||
style={{ maxWidth: "21rem" }}
|
||||
>
|
||||
<header className="text-base sm:text-lg">{title}</header>
|
||||
<hr className="border-gray-500" />
|
||||
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">
|
||||
{CustomizationOptions}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
const CustomizeBadge = ({githubName, badgeOptions, onBadgeUpdate}) => {
|
||||
return (
|
||||
<>
|
||||
<label htmlFor="badge-style">Style:
|
||||
<select
|
||||
id="badge-style"
|
||||
onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)}
|
||||
value = {badgeOptions.badgeStyle}
|
||||
>
|
||||
<option value="flat">Flat</option>
|
||||
<option value="flat-square">Flat Square</option>
|
||||
<option value="plastic">Plastic</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label htmlFor="badge-color">Color:
|
||||
<input
|
||||
type="color"
|
||||
id="badge-color"
|
||||
defaultValue={`#${badgeOptions.badgeColor}`}
|
||||
className="w-6"
|
||||
onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label htmlFor="badge-label-text">Label Text:
|
||||
<input
|
||||
type="text"
|
||||
id="badge-label-text"
|
||||
placeholder="Profile views"
|
||||
className="w-2/4 bg-gray-300 pl-2"
|
||||
onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())}
|
||||
defaultValue={badgeOptions.badgeLabel}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<span className="mt-2 flex items-center">
|
||||
Preview:
|
||||
{
|
||||
isGitHubUsernameValid(githubName)?
|
||||
<img
|
||||
src={`https://komarev.com/ghpvc/`
|
||||
+ `?username=${githubName}`
|
||||
+ `&label=${encodeURI(badgeOptions.badgeLabel)}`
|
||||
+ `&color=${badgeOptions.badgeColor}`
|
||||
+ `&style=${badgeOptions.badgeStyle}`
|
||||
}
|
||||
/>
|
||||
: <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>
|
||||
}
|
||||
|
||||
</span>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) =>
|
||||
<>
|
||||
<label htmlFor={`${prefix}-theme`}>Theme:
|
||||
<select
|
||||
id={`${prefix}-theme`}
|
||||
onChange={({target: { value }}) => onUpdate("theme", value)}
|
||||
defaultValue={options.theme}
|
||||
>
|
||||
<option value="none">none</option>
|
||||
<option value="dark">Dark</option>
|
||||
<option value="radical">Radical</option>
|
||||
<option value="merko">Merko</option>
|
||||
<option value="gruvbox">Gruvbox</option>
|
||||
<option value="tokyonight">Tokyonight</option>
|
||||
<option value="onedark">Onedark</option>
|
||||
<option value="cobalt">Cobalt</option>
|
||||
<option value="synthwave">Synthwave</option>
|
||||
<option value="highcontrast">Highcontrast</option>
|
||||
<option value="dracula">Dracula</option>
|
||||
</select>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-title-color`}>Title Color:
|
||||
<input
|
||||
type="color"
|
||||
id={`${prefix}-title-color`}
|
||||
defaultValue={`#${options.titleColor}`}
|
||||
className="w-6"
|
||||
onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))}
|
||||
/>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-text-color`}>Text Color:
|
||||
<input
|
||||
type="color"
|
||||
id={`${prefix}-text-color`}
|
||||
defaultValue={`#${options.textColor}`}
|
||||
className="w-6"
|
||||
onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))}
|
||||
/>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-bg-color`}>Background Color:
|
||||
<input
|
||||
type="color"
|
||||
id={`${prefix}-bg-color`}
|
||||
defaultValue={`#${options.bgColor}`}
|
||||
className="w-6"
|
||||
onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))}
|
||||
/>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-hide-border`}>Hide border:
|
||||
<input
|
||||
id={`${prefix}-hide-border`}
|
||||
type="checkbox"
|
||||
checked={options.hideBorder}
|
||||
onChange={(e) => onUpdate('hideBorder', e.target.checked)}
|
||||
/>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-cache-seconds`}>Cache Seconds:
|
||||
<input
|
||||
id={`${prefix}-cache-seconds`}
|
||||
type="number"
|
||||
min={1800}
|
||||
max={86400}
|
||||
placeholder={1800}
|
||||
defaultValue={options.cacheSeconds}
|
||||
onChange={(e) => onUpdate('cacheSeconds', e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-locale`}>Locale:
|
||||
<input
|
||||
id={`${prefix}-locale`}
|
||||
type="text"
|
||||
placeholder="en"
|
||||
defaultValue={options.locale}
|
||||
onChange={(e) => onUpdate('locale', e.target.value)}
|
||||
size="2"
|
||||
/>
|
||||
</label>
|
||||
</>
|
||||
|
||||
const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
|
||||
<>
|
||||
<label htmlFor={`${prefix}-theme`}>
|
||||
Theme:
|
||||
<select
|
||||
id={`${prefix}-theme`}
|
||||
onChange={({ target: { value } }) => onUpdate("theme", value)}
|
||||
defaultValue={options.theme}
|
||||
>
|
||||
<option value="default">default</option>
|
||||
<option value="dark">dark</option>
|
||||
<option value="highcontrast">highcontrast</option>
|
||||
</select>
|
||||
</label>
|
||||
</>
|
||||
)
|
||||
|
||||
const Addons = props => {
|
||||
const [debounce, setDebounce] = useState(undefined);
|
||||
const [badgeOptions, setBadgeOptions] = useState({
|
||||
badgeStyle: props.data.badgeStyle,
|
||||
badgeColor: props.data.badgeColor,
|
||||
badgeLabel: props.data.badgeLabel
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setBadgeOptions({
|
||||
badgeStyle: props.data.badgeStyle,
|
||||
badgeColor: props.data.badgeColor,
|
||||
badgeLabel: props.data.badgeLabel
|
||||
})
|
||||
}, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel])
|
||||
|
||||
const [githubStatsOptions, setGithubStatsOptions] = useState({
|
||||
...props.data.githubStatsOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setGithubStatsOptions({
|
||||
...props.data.githubStatsOptions
|
||||
})
|
||||
}, [props.data.githubStatsOptions])
|
||||
|
||||
const [topLanguagesOptions, setTopLanguagesOptions] = useState({
|
||||
...props.data.topLanguagesOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setTopLanguagesOptions({
|
||||
...props.data.topLanguagesOptions
|
||||
})
|
||||
}, [props.data.topLanguagesOptions])
|
||||
|
||||
const [streakStatsOptions, setStreakStatsOptions] = useState({
|
||||
...props.data.streakStatsOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setStreakStatsOptions({
|
||||
...props.data.streakStatsOptions
|
||||
})
|
||||
}, [props.data.streakStatsOptions])
|
||||
|
||||
const blogPostPorkflow = () => {
|
||||
let payload = {
|
||||
dev: {
|
||||
show: props.data.devDynamicBlogs,
|
||||
username: props.social.dev,
|
||||
},
|
||||
medium: {
|
||||
show: props.data.mediumDynamicBlogs,
|
||||
username: props.social.medium,
|
||||
},
|
||||
rssurl: {
|
||||
show: props.data.rssDynamicBlogs,
|
||||
username: props.social.rssurl,
|
||||
},
|
||||
}
|
||||
var actionContent = latestBlogs(payload)
|
||||
var tempElement = document.createElement("a")
|
||||
tempElement.setAttribute(
|
||||
"href",
|
||||
"data:text/yaml;charset=utf-8," + encodeURIComponent(actionContent)
|
||||
)
|
||||
tempElement.setAttribute("download", "blog-post-workflow.yml")
|
||||
tempElement.style.display = "none"
|
||||
document.body.appendChild(tempElement)
|
||||
tempElement.click()
|
||||
document.body.removeChild(tempElement)
|
||||
}
|
||||
|
||||
const onBadgeUpdate = (option, value) => {
|
||||
const callback = () => {
|
||||
let newVal = (option==='badgeLabel' && value==='')?'Profile views':value;
|
||||
setBadgeOptions({...badgeOptions, [option]: newVal});
|
||||
props.handleDataChange(option, {target: {value: newVal}})
|
||||
}
|
||||
clearTimeout(debounce);
|
||||
setDebounce(setTimeout(callback, 300));
|
||||
}
|
||||
|
||||
const onStatsUpdate = (option, value) => {
|
||||
const newStatsOptions = {...githubStatsOptions, [option]: value}
|
||||
setGithubStatsOptions(newStatsOptions)
|
||||
props.handleDataChange("githubStatsOptions", {target: {value: newStatsOptions}})
|
||||
}
|
||||
|
||||
const onTopLangUpdate = (option, value) => {
|
||||
const newLangOptions = {...topLanguagesOptions, [option]: value}
|
||||
setTopLanguagesOptions(newLangOptions)
|
||||
props.handleDataChange("topLanguagesOptions", {target: {value: newLangOptions}})
|
||||
}
|
||||
|
||||
const onStreakStatsUpdate = (option, value) => {
|
||||
const newStreakStatsOptions = {...streakStatsOptions, [option]: value}
|
||||
setStreakStatsOptions(newStreakStatsOptions)
|
||||
props.handleDataChange("streakStatsOptions", {target: {value: newStreakStatsOptions}})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Add-ons
|
||||
</div>
|
||||
<AddonsItem
|
||||
inputId="visitors-count"
|
||||
inputChecked={props.data.visitorsBadge}
|
||||
onInputChange={() => props.handleCheckChange("visitorsBadge")}
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
title="Customize Badge"
|
||||
CustomizationOptions={
|
||||
<CustomizeBadge
|
||||
githubName={props.social.github}
|
||||
badgeOptions={badgeOptions}
|
||||
onBadgeUpdate={onBadgeUpdate}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
display visitors count badge
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="github-profile-trophy"
|
||||
inputChecked={props.data.githubProfileTrophy}
|
||||
onInputChange={() => props.handleCheckChange("githubProfileTrophy")}
|
||||
>
|
||||
display github trophy
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="github-stats"
|
||||
inputChecked={props.data.githubStats}
|
||||
onInputChange={() => props.handleCheckChange("githubStats")}
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
title="Customize Github Stats Card"
|
||||
CustomizationOptions={
|
||||
<CustomizeGithubStatsBase prefix="stats" options={githubStatsOptions} onUpdate={onStatsUpdate}/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
display github profile stats card
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="top-languages"
|
||||
inputChecked={props.data.topLanguages}
|
||||
onInputChange={() => props.handleCheckChange("topLanguages")}
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
title="Customize Top Skills Card"
|
||||
CustomizationOptions={
|
||||
<CustomizeGithubStatsBase prefix="top-lang" options={topLanguagesOptions} onUpdate={onTopLangUpdate}/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
display top skills
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="streak-stats"
|
||||
inputChecked={props.data.streakStats}
|
||||
onInputChange={() => props.handleCheckChange("streakStats")}
|
||||
Options={
|
||||
<CustomizeOptions
|
||||
title="Customize Streak Stats Card"
|
||||
CustomizationOptions={
|
||||
<CustomizeStreakStats prefix="streak-stats" options={streakStatsOptions} onUpdate={onStreakStatsUpdate}/>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
display github streak stats
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="twitter-badge"
|
||||
inputChecked={props.data.twitterBadge}
|
||||
onInputChange={() => props.handleCheckChange("twitterBadge")}
|
||||
>
|
||||
display twitter badge
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="dev-dynamic-blogs"
|
||||
inputChecked={props.data.devDynamicBlogs}
|
||||
onInputChange={() => props.handleCheckChange("devDynamicBlogs")}
|
||||
>
|
||||
display latest dev.to blogs dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="medium-dynamic-blogs"
|
||||
inputChecked={props.data.mediumDynamicBlogs}
|
||||
onInputChange={() => props.handleCheckChange("mediumDynamicBlogs")}
|
||||
>
|
||||
display latest medium blogs dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
<AddonsItem
|
||||
inputId="rss-dynamic-blogs"
|
||||
inputChecked={props.data.rssDynamicBlogs}
|
||||
onInputChange={() => props.handleCheckChange("rssDynamicBlogs")}
|
||||
>
|
||||
display latest blogs from your personal blog dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
|
||||
{(props.data.devDynamicBlogs && props.social.dev) ||
|
||||
(props.data.rssDynamicBlogs && props.social.rssurl) ||
|
||||
(props.data.mediumDynamicBlogs &&
|
||||
props.social.medium &&
|
||||
isMediumUsernameValid(props.social.medium)) ? (
|
||||
<div className="workflow">
|
||||
<div>
|
||||
download
|
||||
<span
|
||||
id="blog-post-worklow-span"
|
||||
onClick={blogPostPorkflow}
|
||||
onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
style={{ cursor: "pointer", color: "#002ead" }}
|
||||
>
|
||||
{" "}
|
||||
blog-post-workflow.yml
|
||||
</span>{" "}
|
||||
file(learn
|
||||
<a
|
||||
href={withPrefix(links.addons)}
|
||||
target="blank"
|
||||
style={{ color: "#002ead" }}
|
||||
>
|
||||
{" "}
|
||||
how to setup
|
||||
</a>
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Addons
|
||||
@@ -0,0 +1,320 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withPrefix } from 'gatsby';
|
||||
import { ToolsIcon, XCircleIcon } from '@primer/octicons-react';
|
||||
import latestBlogs from '../utils/workflows';
|
||||
import links from '../constants/page-links';
|
||||
import { isMediumUsernameValid, isGitHubUsernameValid } from '../utils/validation';
|
||||
|
||||
const AddonsItem = (props) => {
|
||||
const { inputId, inputChecked, onInputChange, Options, children } = props;
|
||||
const [open, setOpen] = useState(false);
|
||||
const Icon = open ? XCircleIcon : ToolsIcon;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="py-2 flex justify-start items-center text-sm sm:text-lg">
|
||||
<label htmlFor={inputId} className="checkbox-label flex items-center">
|
||||
<input id={inputId} type="checkbox" className="checkbox-label__input" checked={inputChecked} onChange={onInputChange} />
|
||||
<span className="checkbox-label__control" />
|
||||
<span className="pl-4">{children}</span>
|
||||
</label>
|
||||
{Options && (
|
||||
<button type="button" id={`${inputId}-open-btn`} onClick={() => setOpen(!open)} className="flex ml-3 focus:bg-gray-400" style={{ outline: 'none' }}>
|
||||
<Icon className="transform scale-100 md:scale-125" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{Options && open && Options}
|
||||
</>
|
||||
);
|
||||
};
|
||||
AddonsItem.propTypes = {
|
||||
inputId: PropTypes.string.isRequired,
|
||||
inputChecked: PropTypes.bool.isRequired,
|
||||
onInputChange: PropTypes.func.isRequired,
|
||||
Options: PropTypes.element.isRequired,
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const CustomizeOptions = ({ title, CustomizationOptions }) => (
|
||||
<div className="border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8" style={{ maxWidth: '21rem' }}>
|
||||
<header className="text-base sm:text-lg">{title}</header>
|
||||
<hr className="border-gray-500" />
|
||||
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">{CustomizationOptions}</div>
|
||||
</div>
|
||||
);
|
||||
CustomizeOptions.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
CustomizationOptions: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => (
|
||||
<>
|
||||
<label htmlFor="badge-style">
|
||||
Style:
|
||||
<select id="badge-style" onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)} value={badgeOptions.badgeStyle}>
|
||||
<option value="flat">Flat</option>
|
||||
<option value="flat-square">Flat Square</option>
|
||||
<option value="plastic">Plastic</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label htmlFor="badge-color">
|
||||
Color:
|
||||
<input type="color" id="badge-color" defaultValue={`#${badgeOptions.badgeColor}`} className="w-6" onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))} />
|
||||
</label>
|
||||
|
||||
<label htmlFor="badge-label-text">
|
||||
Label Text:
|
||||
<input type="text" id="badge-label-text" placeholder="Profile views" className="w-2/4 bg-gray-300 pl-2" onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())} defaultValue={badgeOptions.badgeLabel} />
|
||||
</label>
|
||||
|
||||
<span className="mt-2 flex items-center">
|
||||
Preview:
|
||||
{isGitHubUsernameValid(githubName) ? <img src={`https://komarev.com/ghpvc/?username=${githubName}&label=${encodeURI(badgeOptions.badgeLabel)}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`} alt="profile-visitors-count" /> : <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>}
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
CustomizeBadge.propTypes = {
|
||||
githubName: PropTypes.string.isRequired,
|
||||
badgeOptions: PropTypes.object.isRequired,
|
||||
onBadgeUpdate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
|
||||
<>
|
||||
<label htmlFor={`${prefix}-theme`}>
|
||||
Theme:
|
||||
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.theme}>
|
||||
<option value="none">none</option>
|
||||
<option value="dark">Dark</option>
|
||||
<option value="radical">Radical</option>
|
||||
<option value="merko">Merko</option>
|
||||
<option value="gruvbox">Gruvbox</option>
|
||||
<option value="tokyonight">Tokyonight</option>
|
||||
<option value="onedark">Onedark</option>
|
||||
<option value="cobalt">Cobalt</option>
|
||||
<option value="synthwave">Synthwave</option>
|
||||
<option value="highcontrast">Highcontrast</option>
|
||||
<option value="dracula">Dracula</option>
|
||||
</select>
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-title-color`}>
|
||||
Title Color:
|
||||
<input type="color" id={`${prefix}-title-color`} defaultValue={`#${options.titleColor}`} className="w-6" onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))} />
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-text-color`}>
|
||||
Text Color:
|
||||
<input type="color" id={`${prefix}-text-color`} defaultValue={`#${options.textColor}`} className="w-6" onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))} />
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-bg-color`}>
|
||||
Background Color:
|
||||
<input type="color" id={`${prefix}-bg-color`} defaultValue={`#${options.bgColor}`} className="w-6" onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))} />
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-hide-border`} className="checkbox-label">
|
||||
Hide border:
|
||||
<input id={`${prefix}-hide-border`} type="checkbox" className="checkbox-label__input" checked={options.hideBorder} onChange={(e) => onUpdate('hideBorder', e.target.checked)} />
|
||||
<span className="checkbox-label__control" />
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-cache-seconds`}>
|
||||
Cache Seconds:
|
||||
<input id={`${prefix}-cache-seconds`} type="number" min={1800} max={86400} placeholder={1800} defaultValue={options.cacheSeconds} onChange={(e) => onUpdate('cacheSeconds', e.target.value)} />
|
||||
</label>
|
||||
<label htmlFor={`${prefix}-locale`}>
|
||||
Locale:
|
||||
<input id={`${prefix}-locale`} type="text" placeholder="en" defaultValue={options.locale} onChange={(e) => onUpdate('locale', e.target.value)} size="2" />
|
||||
</label>
|
||||
</>
|
||||
);
|
||||
CustomizeGithubStatsBase.propTypes = {
|
||||
prefix: PropTypes.string.isRequired,
|
||||
options: PropTypes.object.isRequired,
|
||||
onUpdate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
|
||||
<>
|
||||
<label htmlFor={`${prefix}-theme`}>
|
||||
Theme:
|
||||
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.theme}>
|
||||
<option value="default">default</option>
|
||||
<option value="dark">dark</option>
|
||||
<option value="highcontrast">highcontrast</option>
|
||||
</select>
|
||||
</label>
|
||||
</>
|
||||
);
|
||||
CustomizeStreakStats.propTypes = {
|
||||
prefix: PropTypes.string.isRequired,
|
||||
options: PropTypes.object.isRequired,
|
||||
onUpdate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const Addons = (props) => {
|
||||
const { data, social, handleDataChange, handleCheckChange } = props;
|
||||
const [debounce, setDebounce] = useState(undefined);
|
||||
const [badgeOptions, setBadgeOptions] = useState({
|
||||
badgeStyle: data.badgeStyle,
|
||||
badgeColor: data.badgeColor,
|
||||
badgeLabel: data.badgeLabel,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setBadgeOptions({
|
||||
badgeStyle: data.badgeStyle,
|
||||
badgeColor: data.badgeColor,
|
||||
badgeLabel: data.badgeLabel,
|
||||
});
|
||||
}, [data.badgeStyle, data.badgeColor, data.badgeLabel]);
|
||||
|
||||
const [githubStatsOptions, setGithubStatsOptions] = useState({
|
||||
...data.githubStatsOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setGithubStatsOptions({
|
||||
...data.githubStatsOptions,
|
||||
});
|
||||
}, [data.githubStatsOptions]);
|
||||
|
||||
const [topLanguagesOptions, setTopLanguagesOptions] = useState({
|
||||
...data.topLanguagesOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setTopLanguagesOptions({
|
||||
...data.topLanguagesOptions,
|
||||
});
|
||||
}, [data.topLanguagesOptions]);
|
||||
|
||||
const [streakStatsOptions, setStreakStatsOptions] = useState({
|
||||
...data.streakStatsOptions,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setStreakStatsOptions({
|
||||
...data.streakStatsOptions,
|
||||
});
|
||||
}, [data.streakStatsOptions]);
|
||||
|
||||
const blogPostPorkflow = () => {
|
||||
const payload = {
|
||||
dev: {
|
||||
show: data.devDynamicBlogs,
|
||||
username: social.dev,
|
||||
},
|
||||
medium: {
|
||||
show: data.mediumDynamicBlogs,
|
||||
username: social.medium,
|
||||
},
|
||||
rssurl: {
|
||||
show: data.rssDynamicBlogs,
|
||||
username: social.rssurl,
|
||||
},
|
||||
};
|
||||
const actionContent = latestBlogs(payload);
|
||||
const tempElement = document.createElement('a');
|
||||
tempElement.setAttribute('href', `data:text/yaml;charset=utf-8,${encodeURIComponent(actionContent)}`);
|
||||
tempElement.setAttribute('download', 'blog-post-workflow.yml');
|
||||
tempElement.style.display = 'none';
|
||||
document.body.appendChild(tempElement);
|
||||
tempElement.click();
|
||||
document.body.removeChild(tempElement);
|
||||
};
|
||||
|
||||
const onBadgeUpdate = (option, value) => {
|
||||
const callback = () => {
|
||||
const newVal = option === 'badgeLabel' && value === '' ? 'Profile views' : value;
|
||||
setBadgeOptions({ ...badgeOptions, [option]: newVal });
|
||||
handleDataChange(option, { target: { value: newVal } });
|
||||
};
|
||||
clearTimeout(debounce);
|
||||
setDebounce(setTimeout(callback, 300));
|
||||
};
|
||||
|
||||
const onStatsUpdate = (option, value) => {
|
||||
const newStatsOptions = { ...githubStatsOptions, [option]: value };
|
||||
setGithubStatsOptions(newStatsOptions);
|
||||
handleDataChange('githubStatsOptions', {
|
||||
target: { value: newStatsOptions },
|
||||
});
|
||||
};
|
||||
|
||||
const onTopLangUpdate = (option, value) => {
|
||||
const newLangOptions = { ...topLanguagesOptions, [option]: value };
|
||||
setTopLanguagesOptions(newLangOptions);
|
||||
handleDataChange('topLanguagesOptions', {
|
||||
target: { value: newLangOptions },
|
||||
});
|
||||
};
|
||||
|
||||
const onStreakStatsUpdate = (option, value) => {
|
||||
const newStreakStatsOptions = { ...streakStatsOptions, [option]: value };
|
||||
setStreakStatsOptions(newStreakStatsOptions);
|
||||
handleDataChange('streakStatsOptions', {
|
||||
target: { value: newStreakStatsOptions },
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Add-ons</div>
|
||||
<AddonsItem inputId="visitors-count" inputChecked={data.visitorsBadge} onInputChange={() => handleCheckChange('visitorsBadge')} Options={<CustomizeOptions title="Customize Badge" CustomizationOptions={<CustomizeBadge githubName={social.github} badgeOptions={badgeOptions} onBadgeUpdate={onBadgeUpdate} />} />}>
|
||||
display visitors count badge
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="github-profile-trophy" inputChecked={data.githubProfileTrophy} onInputChange={() => handleCheckChange('githubProfileTrophy')}>
|
||||
display github trophy
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="github-stats" inputChecked={data.githubStats} onInputChange={() => handleCheckChange('githubStats')} Options={<CustomizeOptions title="Customize Github Stats Card" CustomizationOptions={<CustomizeGithubStatsBase prefix="stats" options={githubStatsOptions} onUpdate={onStatsUpdate} />} />}>
|
||||
display github profile stats card
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="top-languages" inputChecked={data.topLanguages} onInputChange={() => handleCheckChange('topLanguages')} Options={<CustomizeOptions title="Customize Top Skills Card" CustomizationOptions={<CustomizeGithubStatsBase prefix="top-lang" options={topLanguagesOptions} onUpdate={onTopLangUpdate} />} />}>
|
||||
display top skills
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="streak-stats" inputChecked={data.streakStats} onInputChange={() => handleCheckChange('streakStats')} Options={<CustomizeOptions title="Customize Streak Stats Card" CustomizationOptions={<CustomizeStreakStats prefix="streak-stats" options={streakStatsOptions} onUpdate={onStreakStatsUpdate} />} />}>
|
||||
display github streak stats
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="twitter-badge" inputChecked={data.twitterBadge} onInputChange={() => handleCheckChange('twitterBadge')}>
|
||||
display twitter badge
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="dev-dynamic-blogs" inputChecked={data.devDynamicBlogs} onInputChange={() => handleCheckChange('devDynamicBlogs')}>
|
||||
display latest dev.to blogs dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="medium-dynamic-blogs" inputChecked={data.mediumDynamicBlogs} onInputChange={() => handleCheckChange('mediumDynamicBlogs')}>
|
||||
display latest medium blogs dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
<AddonsItem inputId="rss-dynamic-blogs" inputChecked={data.rssDynamicBlogs} onInputChange={() => handleCheckChange('rssDynamicBlogs')}>
|
||||
display latest blogs from your personal blog dynamically (GitHub Action)
|
||||
</AddonsItem>
|
||||
|
||||
{(data.devDynamicBlogs && social.dev) || (data.rssDynamicBlogs && social.rssurl) || (data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium)) ? (
|
||||
<div className="workflow">
|
||||
<div>
|
||||
download
|
||||
<span id="blog-post-worklow-span" onClick={blogPostPorkflow} onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()} role="button" tabIndex="0" style={{ cursor: 'pointer', color: '#002ead' }}>
|
||||
{' '}
|
||||
blog-post-workflow.yml
|
||||
</span>{' '}
|
||||
file(learn
|
||||
<a href={withPrefix(links.addons)} target="blank" style={{ color: '#002ead' }}>
|
||||
{' '}
|
||||
how to setup
|
||||
</a>
|
||||
)
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Addons;
|
||||
Addons.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
social: PropTypes.object.isRequired,
|
||||
handleDataChange: PropTypes.func.isRequired,
|
||||
handleCheckChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
import React from "react"
|
||||
const Donate = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="text-center text-4xl my-2">Support
|
||||
<span role="img" aria-label="praying hand emoji">🙏</span>
|
||||
</div>
|
||||
<div className="flex flex-col sm:flex-row items-start justify-between">
|
||||
<div className="w-full sm:w-2/3">
|
||||
<div className="text-2xl mb-2">
|
||||
Are you using the tool and happy with it to create your GitHub
|
||||
Profile?
|
||||
</div>
|
||||
<div className="text-lg">
|
||||
Your kind support keeps open-source tools like this free for others.
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<a
|
||||
className="flex items-center justify-start w-20"
|
||||
href="https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator"
|
||||
>
|
||||
<img
|
||||
className="w-20"
|
||||
src="https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator"
|
||||
alt="tweet github profile readme generator"
|
||||
/>
|
||||
</a>
|
||||
Let the world know how you feel using this tool. Share with others
|
||||
on twitter.
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center">
|
||||
<span>Tip<span role="img" aria-label="Dollar medal">💰</span></span>
|
||||
{/* Ko-Fi */}
|
||||
<a
|
||||
href="https://ko-fi.com/A0A81XXSX"
|
||||
className="flex items-center justify-evenly bg-red-500 text-white py-2 px-4 my-2"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
className="w-6 h-6 mr-2"
|
||||
src="https://www.vectorlogo.zone/logos/ko-fi/ko-fi-icon.svg"
|
||||
alt="Buy ko-fi for rahuldkjain"
|
||||
/>
|
||||
Buy me a ko-fi
|
||||
</a>
|
||||
{/* Paypal */}
|
||||
<a
|
||||
href="https://www.paypal.me/rahuldkjain/10"
|
||||
className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
className="w-32 h-4"
|
||||
src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg"
|
||||
alt="Donate rahuldkjain via paypal"
|
||||
/>
|
||||
{/* <img
|
||||
className="w-6 h-6 mr-2"
|
||||
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg"
|
||||
alt="Donate rahuldkjain via paypal"
|
||||
/>
|
||||
Paypal */}
|
||||
</a>
|
||||
{/* BuyMeACoffee */}
|
||||
<a
|
||||
href="https://www.buymeacoffee.com/rahuldkjain"
|
||||
className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
className="w-6 h-6 mr-2"
|
||||
src="https://www.vectorlogo.zone/logos/buymeacoffee/buymeacoffee-icon.svg"
|
||||
alt="Buy rahuldkjain A Coffee"
|
||||
/>
|
||||
Buy me a coffee
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Donate
|
||||
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
|
||||
const Donate = () => (
|
||||
<>
|
||||
<div className="text-center text-4xl my-2">
|
||||
Support
|
||||
<span role="img" aria-label="praying hand emoji">
|
||||
🙏
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col sm:flex-row items-start justify-between">
|
||||
<div className="w-full sm:w-2/3">
|
||||
<div className="text-2xl mb-2">Are you using the tool and happy with it to create your GitHub Profile?</div>
|
||||
<div className="text-lg">Your kind support keeps open-source tools like this free for others.</div>
|
||||
<div className="mt-4">
|
||||
<a className="flex items-center justify-start w-20" href="https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator">
|
||||
<img className="w-20" src="https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Frahuldkjain.github.io%2Fgithub-profile-readme-generator" alt="tweet github profile readme generator" />
|
||||
</a>
|
||||
Let the world know how you feel using this tool. Share with others on twitter.
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center">
|
||||
<span>
|
||||
Tip
|
||||
<span role="img" aria-label="Dollar medal">
|
||||
💰
|
||||
</span>
|
||||
</span>
|
||||
{/* Ko-Fi */}
|
||||
<a href="https://ko-fi.com/A0A81XXSX" className="flex items-center justify-evenly bg-red-500 text-white py-2 px-4 my-2" target="_blank" rel="noreferrer">
|
||||
<img className="w-6 h-6 mr-2" src="https://www.vectorlogo.zone/logos/ko-fi/ko-fi-icon.svg" alt="Buy ko-fi for rahuldkjain" />
|
||||
Buy me a ko-fi
|
||||
</a>
|
||||
{/* Paypal */}
|
||||
<a href="https://www.paypal.me/rahuldkjain/10" className="flex items-center justify-evenly bg-white-500 text-white py-2 px-4 my-2 border border-solid" target="_blank" rel="noreferrer">
|
||||
<img className="w-32 h-4" src="https://cdn.worldvectorlogo.com/logos/paypal-2.svg" alt="Donate rahuldkjain via paypal" />
|
||||
{/* <img
|
||||
className="w-6 h-6 mr-2"
|
||||
src="https://www.vectorlogo.zone/logos/paypal/paypal-ar21.svg"
|
||||
alt="Donate rahuldkjain via paypal"
|
||||
/>
|
||||
Paypal */}
|
||||
</a>
|
||||
{/* BuyMeACoffee */}
|
||||
<a href="https://www.buymeacoffee.com/rahuldkjain" className="flex items-center justify-evenly bg-orange-500 text-white py-2 px-4 my-2" target="_blank" rel="noreferrer">
|
||||
<img className="w-6 h-6 mr-2" src="https://www.vectorlogo.zone/logos/buymeacoffee/buymeacoffee-icon.svg" alt="Buy rahuldkjain A Coffee" />
|
||||
Buy me a coffee
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
export default Donate;
|
||||
@@ -1,120 +0,0 @@
|
||||
import React from "react"
|
||||
import links from "../constants/page-links"
|
||||
import logo from "../images/mdg.png"
|
||||
import discord from "../images/Discord-Logo.png"
|
||||
import { Link } from "gatsby"
|
||||
const Footer = () => {
|
||||
return (
|
||||
<div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2">
|
||||
<div className="w-full flex flex-col sm:flex-row justify-evenly py-2">
|
||||
<div className="sm:ml-0 sm:mr-6 order-last sm:order-none flex">
|
||||
<h1 className="text-base font-bold font-title text-xl sm:text-2xl mt-3 sm:mt-0">
|
||||
<div className="flex sm:flex-col items-start mb-3 sm:mb-0">
|
||||
<img
|
||||
src={logo}
|
||||
className="hidden sm:block h-24"
|
||||
alt="github profile markdown generator logo"
|
||||
/>
|
||||
<div className="mr-2 sm:mr-0">
|
||||
GitHub Profile{" "}
|
||||
<img
|
||||
src={logo}
|
||||
className="inline sm:hidden h-12"
|
||||
alt="github profile markdown generator logo"
|
||||
/>
|
||||
<span className="block sm:inline">README Generator</span>
|
||||
</div>
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<div className="text-xl sm:text-base font-light sm:font-normal">
|
||||
<div className="font-title font-bold mb-4 sm:mb-2">
|
||||
<strong>Pages</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.addons} activeStyle={{ color: "#002ead" }}>
|
||||
Addons
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.support} activeStyle={{ color: "#002ead" }}>
|
||||
Support
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.about} activeStyle={{ color: "#002ead" }}>
|
||||
About
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xl sm:text-base font-light sm:font-normal">
|
||||
<div className="font-title font-bold my-4 sm:my-0 sm:mb-2">
|
||||
<strong>More</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator"
|
||||
aria-label="Github rahuldkjain/github-profile-readme-generator"
|
||||
target="blank"
|
||||
>
|
||||
Github
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator/releases"
|
||||
aria-label="Releases on Github rahuldkjain/github-profile-readme-generator"
|
||||
target="blank"
|
||||
>
|
||||
Releases
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator/issues"
|
||||
aria-label="Issues in rahuldkjain/github-profile-readme-generator"
|
||||
target="blank"
|
||||
>
|
||||
Issues
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator/pulls"
|
||||
aria-label="Pull Requests in rahuldkjain/github-profile-readme-generator"
|
||||
target="blank"
|
||||
>
|
||||
Pull Requests
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-title font-bold text-xl sm:text-base my-4 sm:my-0 sm:mb-2">
|
||||
<strong>Join Community</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a
|
||||
href="https://discord.gg/HHMs7Eg"
|
||||
aria-label="Discord of the community"
|
||||
target="blank"
|
||||
>
|
||||
<img
|
||||
src={discord}
|
||||
className="h-12"
|
||||
alt="Discord of the community"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-2 mt-2">
|
||||
Developed in India{" "}
|
||||
<span role="img" aria-label="india">
|
||||
{" "}
|
||||
🇮🇳
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Footer
|
||||
@@ -0,0 +1,86 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'gatsby';
|
||||
import links from '../constants/page-links';
|
||||
import logo from '../images/mdg.png';
|
||||
import discord from '../images/Discord-Logo.png';
|
||||
|
||||
const Footer = () => (
|
||||
<div className="bg-gray-100 p-4 flex flex-col justify-center items-center shadow-inner mt-2">
|
||||
<div className="w-full flex flex-col sm:flex-row justify-evenly py-2">
|
||||
<div className="sm:ml-0 sm:mr-6 order-last sm:order-none flex">
|
||||
<h1 className="text-base font-bold font-title text-xl sm:text-2xl mt-3 sm:mt-0">
|
||||
<div className="flex sm:flex-col items-start mb-3 sm:mb-0">
|
||||
<img src={logo} className="hidden sm:block h-24" alt="github profile markdown generator logo" />
|
||||
<div className="mr-2 sm:mr-0">
|
||||
GitHub Profile <img src={logo} className="inline sm:hidden h-12" alt="github profile markdown generator logo" />
|
||||
<span className="block sm:inline">README Generator</span>
|
||||
</div>
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<div className="text-xl sm:text-base font-light sm:font-normal">
|
||||
<div className="font-title font-bold mb-4 sm:mb-2">
|
||||
<strong>Pages</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.addons} activeStyle={{ color: '#002ead' }}>
|
||||
Addons
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.support} activeStyle={{ color: '#002ead' }}>
|
||||
Support
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<Link to={links.about} activeStyle={{ color: '#002ead' }}>
|
||||
About
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xl sm:text-base font-light sm:font-normal">
|
||||
<div className="font-title font-bold my-4 sm:my-0 sm:mb-2">
|
||||
<strong>More</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator" aria-label="Github rahuldkjain/github-profile-readme-generator" target="blank">
|
||||
Github
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/releases" aria-label="Releases on Github rahuldkjain/github-profile-readme-generator" target="blank">
|
||||
Releases
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/issues" aria-label="Issues in rahuldkjain/github-profile-readme-generator" target="blank">
|
||||
Issues
|
||||
</a>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/pulls" aria-label="Pull Requests in rahuldkjain/github-profile-readme-generator" target="blank">
|
||||
Pull Requests
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-title font-bold text-xl sm:text-base my-4 sm:my-0 sm:mb-2">
|
||||
<strong>Join Community</strong>
|
||||
</div>
|
||||
<div className="ml-2 sm:ml-0">
|
||||
<a href="https://discord.gg/HHMs7Eg" aria-label="Discord of the community" target="blank">
|
||||
<img src={discord} className="h-12" alt="Discord of the community" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-2 mt-2">
|
||||
Developed in India{' '}
|
||||
<span role="img" aria-label="india">
|
||||
{' '}
|
||||
🇮🇳
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
export default Footer;
|
||||
@@ -1,105 +0,0 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { StarIcon, RepoForkedIcon } from "@primer/octicons-react"
|
||||
import logo from "../images/mdg.png"
|
||||
import links from "../constants/page-links"
|
||||
import gsap from "gsap"
|
||||
import axios from "axios"
|
||||
import { Link } from "gatsby"
|
||||
import { act } from "react-dom/test-utils"
|
||||
|
||||
const Header = props => {
|
||||
const shouldRequestStats = () => {
|
||||
const isFirstRequest = stats.starsCount === 0
|
||||
const isVisible = window.document.visibilityState === 'visible'
|
||||
const hasFocus = window.document.hasFocus()
|
||||
return isFirstRequest || isVisible && hasFocus
|
||||
}
|
||||
|
||||
const fetchData = async () => {
|
||||
if (shouldRequestStats()) {
|
||||
var response = await axios.get(
|
||||
"https://api.github.com/repos/rahuldkjain/github-profile-readme-generator"
|
||||
)
|
||||
|
||||
const { stargazers_count, forks_count } = response.data
|
||||
|
||||
act(() =>
|
||||
setstats({
|
||||
starsCount: stargazers_count,
|
||||
forksCount: forks_count,
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const [stats, setstats] = useState({
|
||||
starsCount: 0,
|
||||
forksCount: 0,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
fetchData()
|
||||
setInterval(fetchData, 60000)
|
||||
|
||||
gsap.set(".star, .fork", {
|
||||
transformOrigin: "center",
|
||||
})
|
||||
gsap.to(".star, .fork", {
|
||||
rotateZ: "360",
|
||||
duration: 2,
|
||||
ease: "elastic.inOut",
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="shadow flex items-center justify-center flex-col mb-2 py-2">
|
||||
<Link to={links.home}>
|
||||
<h1 className="text-base font-bold font-title sm:text-2xl font-medium text-blue-800 flex justify-center items-center flex-col">
|
||||
<img
|
||||
src={logo}
|
||||
className="w-12 h-12"
|
||||
alt="github profile markdown generator logo"
|
||||
/>
|
||||
<div>{props.heading}</div>
|
||||
</h1>
|
||||
</Link>
|
||||
<div className="flex justify-center items-center">
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator"
|
||||
aria-label="Star rahuldkjain/github-profile-readme-generator on GitHub"
|
||||
target="blank"
|
||||
className="mr-2"
|
||||
>
|
||||
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
|
||||
<StarIcon size={16} id="star-icon" className="px-1 w-6 star" />
|
||||
Star this repo
|
||||
<span className="github-count px-1 sm:px-2">
|
||||
{stats.starsCount}
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/rahuldkjain/github-profile-readme-generator/fork"
|
||||
aria-label="Fork rahuldkjain/github-profile-readme-generator on GitHub"
|
||||
target="blank"
|
||||
>
|
||||
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
|
||||
<RepoForkedIcon
|
||||
size={16}
|
||||
id="fork-icon"
|
||||
className="px-1 w-6 fork"
|
||||
/>
|
||||
Fork on GitHub
|
||||
<span className="github-count px-1 sm:px-2">
|
||||
{stats.forksCount}
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
@@ -0,0 +1,86 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { StarIcon, RepoForkedIcon } from '@primer/octicons-react';
|
||||
import gsap from 'gsap';
|
||||
import axios from 'axios';
|
||||
import { Link } from 'gatsby';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import links from '../constants/page-links';
|
||||
import logo from '../images/mdg.png';
|
||||
|
||||
const Header = (props) => {
|
||||
const { heading } = props;
|
||||
const [stats, setstats] = useState({
|
||||
starsCount: 0,
|
||||
forksCount: 0,
|
||||
});
|
||||
|
||||
const shouldRequestStats = () => {
|
||||
const isFirstRequest = stats.starsCount === 0;
|
||||
const isVisible = window.document.visibilityState === 'visible';
|
||||
const hasFocus = window.document.hasFocus();
|
||||
return isFirstRequest || (isVisible && hasFocus);
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
if (shouldRequestStats()) {
|
||||
const response = await axios.get('https://api.github.com/repos/rahuldkjain/github-profile-readme-generator');
|
||||
|
||||
const { stargazers_count: stargazersCount, forks_count: forksCount } = response.data;
|
||||
|
||||
act(() =>
|
||||
setstats({
|
||||
starsCount: stargazersCount,
|
||||
forksCount,
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
setInterval(fetchData, 60000);
|
||||
|
||||
gsap.set('.star, .fork', {
|
||||
transformOrigin: 'center',
|
||||
});
|
||||
gsap.to('.star, .fork', {
|
||||
rotateZ: '360',
|
||||
duration: 2,
|
||||
ease: 'elastic.inOut',
|
||||
repeat: -1,
|
||||
yoyo: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="shadow flex items-center justify-center flex-col mb-2 py-2">
|
||||
<Link to={links.home}>
|
||||
<h1 className="text-base font-bold font-title sm:text-2xl font-medium text-blue-800 flex justify-center items-center flex-col">
|
||||
<img src={logo} className="w-12 h-12" alt="github profile markdown generator logo" />
|
||||
<div>{heading}</div>
|
||||
</h1>
|
||||
</Link>
|
||||
<div className="flex justify-center items-center">
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator" aria-label="Star rahuldkjain/github-profile-readme-generator on GitHub" target="blank" className="mr-2">
|
||||
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
|
||||
<StarIcon size={16} id="star-icon" className="px-1 w-6 star" />
|
||||
Star this repo
|
||||
<span className="github-count px-1 sm:px-2">{stats.starsCount}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/fork" aria-label="Fork rahuldkjain/github-profile-readme-generator on GitHub" target="blank">
|
||||
<div className="text-xxs sm:text-sm border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 px-2">
|
||||
<RepoForkedIcon size={16} id="fork-icon" className="px-1 w-6 fork" />
|
||||
Fork on GitHub
|
||||
<span className="github-count px-1 sm:px-2">{stats.forksCount}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
Header.propTypes = {
|
||||
heading: PropTypes.string.isRequired,
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
import React from "react"
|
||||
import Header from "./header"
|
||||
import Footer from "./footer"
|
||||
|
||||
const Layout = ({ children }) => {
|
||||
return (
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<header>
|
||||
<Header heading="GitHub Profile README Generator" />
|
||||
</header>
|
||||
<main className="flex-grow">{children}</main>
|
||||
<footer>
|
||||
<Footer />
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Layout
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Header from './header';
|
||||
import Footer from './footer';
|
||||
|
||||
const Layout = ({ children }) => (
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<header>
|
||||
<Header heading="GitHub Profile README Generator" />
|
||||
</header>
|
||||
<main className="flex-grow">{children}</main>
|
||||
<footer>
|
||||
<Footer />
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
export default Layout;
|
||||
|
||||
Layout.defaultProps = {
|
||||
children: '',
|
||||
};
|
||||
|
||||
Layout.propTypes = {
|
||||
children: PropTypes.element,
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
import React, { useRef, useEffect } from "react"
|
||||
import gsap from "gsap"
|
||||
const Loader = () => {
|
||||
let arrow = useRef([])
|
||||
useEffect(() => {
|
||||
var tl = new gsap.timeline({ repeat: -1 })
|
||||
tl.fromTo(
|
||||
arrow.current,
|
||||
{
|
||||
y: 0,
|
||||
color: "#3b3b4f",
|
||||
},
|
||||
{
|
||||
y: -50,
|
||||
color: "#d0d0d5",
|
||||
stagger: 0.1,
|
||||
duration: 0.5,
|
||||
ease: "Linear.easeNone",
|
||||
}
|
||||
)
|
||||
tl.add("cp")
|
||||
tl.fromTo(
|
||||
arrow.current,
|
||||
{
|
||||
y: -50,
|
||||
color: "#d0d0d5",
|
||||
},
|
||||
{
|
||||
y: 0,
|
||||
color: "#3b3b4f",
|
||||
stagger: 0.1,
|
||||
duration: 0.5,
|
||||
ease: "Linear.easeNone",
|
||||
},
|
||||
"cp-=0.3"
|
||||
)
|
||||
})
|
||||
return (
|
||||
<div className="loader">
|
||||
<span ref={el => (arrow.current[0] = el)}>↓</span>
|
||||
<span ref={el => (arrow.current[1] = el)}>↓</span>
|
||||
<span ref={el => (arrow.current[2] = el)}>↓</span>
|
||||
<span ref={el => (arrow.current[3] = el)}>↓</span>
|
||||
<span ref={el => (arrow.current[4] = el)}>↓</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loader
|
||||
@@ -0,0 +1,80 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import gsap from 'gsap';
|
||||
|
||||
const Loader = () => {
|
||||
const arrow = useRef([]);
|
||||
useEffect(() => {
|
||||
const tl = gsap.timeline({ repeat: -1 });
|
||||
tl.fromTo(
|
||||
arrow.current,
|
||||
{
|
||||
y: 0,
|
||||
color: '#3b3b4f',
|
||||
},
|
||||
{
|
||||
y: -50,
|
||||
color: '#d0d0d5',
|
||||
stagger: 0.1,
|
||||
duration: 0.5,
|
||||
ease: 'Linear.easeNone',
|
||||
},
|
||||
);
|
||||
tl.add('cp');
|
||||
tl.fromTo(
|
||||
arrow.current,
|
||||
{
|
||||
y: -50,
|
||||
color: '#d0d0d5',
|
||||
},
|
||||
{
|
||||
y: 0,
|
||||
color: '#3b3b4f',
|
||||
stagger: 0.1,
|
||||
duration: 0.5,
|
||||
ease: 'Linear.easeNone',
|
||||
},
|
||||
'cp-=0.3',
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="loader">
|
||||
<span
|
||||
ref={(el) => {
|
||||
arrow.current[0] = el;
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</span>
|
||||
<span
|
||||
ref={(el) => {
|
||||
arrow.current[1] = el;
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</span>
|
||||
<span
|
||||
ref={(el) => {
|
||||
arrow.current[2] = el;
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</span>
|
||||
<span
|
||||
ref={(el) => {
|
||||
arrow.current[3] = el;
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</span>
|
||||
<span
|
||||
ref={(el) => {
|
||||
arrow.current[4] = el;
|
||||
}}
|
||||
>
|
||||
↓
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Loader;
|
||||
@@ -1,579 +0,0 @@
|
||||
import React from "react"
|
||||
import { isMediumUsernameValid } from "../utils/validation"
|
||||
import { icons, skills, skillWebsites } from "../constants/skills"
|
||||
import {
|
||||
githubStatsLinkGenerator,
|
||||
topLanguagesLinkGenerator,
|
||||
streakStatsLinkGenerator,
|
||||
} from "../utils/link-generators"
|
||||
const Title = props => {
|
||||
if (props.prefix && props.title) {
|
||||
return (
|
||||
<>
|
||||
{`<h1 align="center">${props.prefix + " " + props.title}</h1>`}
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const SubTitle = props => {
|
||||
if (props.subtitle) {
|
||||
return (
|
||||
<>
|
||||
{`<h3 align="center">${props.subtitle}</h3>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const SectionTitle = props => {
|
||||
if (props.label) {
|
||||
return (
|
||||
<>
|
||||
{`<h3 align="left">${props.label}</h3>`}
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const DisplayWork = props => {
|
||||
if (props.prefix && props.project) {
|
||||
if (props.link) {
|
||||
return (
|
||||
<>
|
||||
{`- ${props.prefix} [${props.project}](${props.link})`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{`- ${props.prefix} **${props.project}**`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
if (props.prefix && props.link) {
|
||||
return (
|
||||
<>
|
||||
{`- ${props.prefix} [${props.link}](${props.link})`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const DisplaySocial = props => {
|
||||
if (props.username) {
|
||||
return (
|
||||
<>
|
||||
{`<a href="${props.base}/${props.username}" target="blank"><img align="center" src="${props.icon}" alt="${props.username}" height="30" width="40" /></a>`}
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const VisitorsBadge = props => {
|
||||
let link =
|
||||
"https://komarev.com/ghpvc/?username=" +
|
||||
props.github +
|
||||
`&label=${props.badgeOptions.badgeLabel}` +
|
||||
`&color=${props.badgeOptions.badgeColor}` +
|
||||
`&style=${props.badgeOptions.badgeStyle}`
|
||||
if (props.show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <img src="${link}" alt="${props.github}" /> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const TwitterBadge = props => {
|
||||
let link =
|
||||
"https://img.shields.io/twitter/follow/" +
|
||||
props.twitter +
|
||||
"?logo=twitter&style=for-the-badge"
|
||||
if (props.show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <a href="${props.base}/${props.twitter}" target="blank"><img src="${link}" alt="${props.twitter}" /></a> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const GithubProfileTrophy = props => {
|
||||
let link =
|
||||
"https://github-profile-trophy.vercel.app/?username=" + props.github
|
||||
if (props.show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <a href="https://github.com/ryo-ma/github-profile-trophy"><img src="${link}" alt="${props.github}" /></a> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const GitHubStats = ({ show, github, options }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p> <img align="center" src="${githubStatsLinkGenerator({
|
||||
github: github,
|
||||
options,
|
||||
})}" alt="${github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const isSocial = social => {
|
||||
return (
|
||||
social.dev ||
|
||||
social.twitter ||
|
||||
social.codepen ||
|
||||
social.codesandbox ||
|
||||
social.stackoverflow ||
|
||||
social.linkedin ||
|
||||
social.kaggle ||
|
||||
social.instagram ||
|
||||
social.fb ||
|
||||
social.dribbble ||
|
||||
social.behance ||
|
||||
social.medium ||
|
||||
social.youtube ||
|
||||
social.codechef ||
|
||||
social.hackerrank ||
|
||||
social.codeforces ||
|
||||
social.leetcode ||
|
||||
social.topcoder ||
|
||||
social.hackerearth ||
|
||||
social.geeks_for_geeks ||
|
||||
social.discord ||
|
||||
social.rssurl
|
||||
)
|
||||
}
|
||||
const DisplaySkills = props => {
|
||||
const listChosenSkills = []
|
||||
skills.forEach(skill => {
|
||||
if (props.skills[skill]) {
|
||||
listChosenSkills.push(
|
||||
`
|
||||
<a href="${skillWebsites[skill]}" target="_blank">
|
||||
<img src="${icons[skill]}" alt="${skill}" width="40" height="40"/>
|
||||
</a>
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
return listChosenSkills.length > 0 ? (
|
||||
<>
|
||||
<SectionTitle label="Languages and Tools:" />
|
||||
{`<p align="left">${listChosenSkills.join(" ")}</p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
}
|
||||
const DisplayDynamicBlogs = props => {
|
||||
if (props.show) {
|
||||
return (
|
||||
<>
|
||||
{`### Blogs posts`}
|
||||
<br />
|
||||
{`<!-- BLOG-POST-LIST:START -->`}
|
||||
<br />
|
||||
{`<!-- BLOG-POST-LIST:END -->`}
|
||||
<br /> <br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const DisplayTopLanguages = props => {
|
||||
if (props.show) {
|
||||
if (!props.showStats) {
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="center" src="${topLanguagesLinkGenerator({
|
||||
github: props.github,
|
||||
options: props.options,
|
||||
})}" alt="${props.github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="left" src="${topLanguagesLinkGenerator({
|
||||
github: props.github,
|
||||
options: props.options,
|
||||
})}" alt="${props.github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const DisplayStreakStats = props => {
|
||||
if (props.show) {
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="center" src="${streakStatsLinkGenerator({
|
||||
github: props.github,
|
||||
options: props.options,
|
||||
})}" alt="${props.github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
const DisplaySupport = props => {
|
||||
let viewSupport = false
|
||||
Object.keys(props.support).forEach(key => {
|
||||
if (props.support[key]) {
|
||||
viewSupport = true
|
||||
}
|
||||
})
|
||||
return viewSupport ? (
|
||||
<div>
|
||||
<SectionTitle label="Support:" />
|
||||
{`<p>`}
|
||||
{props.support.buyMeACoffee &&
|
||||
`<a href="https://www.buymeacoffee.com/${props.support.buyMeACoffee}">
|
||||
<img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="${props.support.buyMeACoffee}" /></a>`}
|
||||
{`</p><br><br>`}
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
}
|
||||
const Markdown = props => {
|
||||
const icon_base_url =
|
||||
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/";
|
||||
|
||||
return (
|
||||
<div id="markdown-content" className="break-words">
|
||||
<>
|
||||
<Title prefix={props.prefix.title} title={props.data.title} />
|
||||
</>
|
||||
<>
|
||||
<SubTitle subtitle={props.data.subtitle} />
|
||||
</>
|
||||
<>
|
||||
<VisitorsBadge
|
||||
show={props.data.visitorsBadge}
|
||||
github={props.social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(props.data.badgeLabel),
|
||||
badgeColor: props.data.badgeColor,
|
||||
badgeStyle: props.data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<GithubProfileTrophy
|
||||
show={props.data.githubProfileTrophy}
|
||||
github={props.social.github}
|
||||
/>
|
||||
<TwitterBadge
|
||||
base="https://twitter.com"
|
||||
show={props.data.twitterBadge}
|
||||
twitter={props.social.twitter}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.currentWork}
|
||||
project={props.data.currentWork}
|
||||
link={props.link.currentWork}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.currentLearn}
|
||||
project={props.data.currentLearn}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.collaborateOn}
|
||||
project={props.data.collaborateOn}
|
||||
link={props.link.collaborateOn}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.helpWith}
|
||||
project={props.data.helpWith}
|
||||
link={props.link.helpWith}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.portfolio}
|
||||
link={props.link.portfolio}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={props.prefix.blog} link={props.link.blog} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={props.prefix.ama} project={props.data.ama} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.contact}
|
||||
project={props.data.contact}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={props.prefix.resume} link={props.link.resume} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={props.prefix.funFact}
|
||||
project={props.data.funFact}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayDynamicBlogs
|
||||
show={
|
||||
(props.data.devDynamicBlogs && props.social.dev) ||
|
||||
(props.data.rssDynamicBlogs && props.social.rssurl) ||
|
||||
(props.data.mediumDynamicBlogs &&
|
||||
props.social.medium &&
|
||||
isMediumUsernameValid(props.social.medium))
|
||||
}
|
||||
/>
|
||||
</>
|
||||
{isSocial(props.social) ? (
|
||||
<>
|
||||
<SectionTitle label="Connect with me:" />
|
||||
{`<p align="left">`}
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<br />
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon={icon_base_url + "codepen.svg"}
|
||||
username={props.social.codepen}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://dev.to"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
|
||||
username={props.social.dev}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://twitter.com"
|
||||
icon={icon_base_url + "twitter.svg"}
|
||||
username={props.social.twitter}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://linkedin.com/in"
|
||||
icon={icon_base_url + "linked-in-alt.svg"}
|
||||
username={props.social.linkedin}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://stackoverflow.com/users"
|
||||
icon={icon_base_url + "stack-overflow.svg"}
|
||||
username={props.social.stackoverflow}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codesandbox.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
|
||||
username={props.social.codesandbox}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://kaggle.com"
|
||||
icon={icon_base_url + "kaggle.svg"}
|
||||
username={props.social.kaggle}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://fb.com"
|
||||
icon={icon_base_url + "facebook.svg"}
|
||||
username={props.social.fb}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://instagram.com"
|
||||
icon={icon_base_url + "instagram.svg"}
|
||||
username={props.social.instagram}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://dribbble.com"
|
||||
icon={icon_base_url + "dribbble.svg"}
|
||||
username={props.social.dribbble}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.behance.net"
|
||||
icon={icon_base_url + "behance.svg"}
|
||||
username={props.social.behance}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://medium.com"
|
||||
icon={icon_base_url + "medium.svg"}
|
||||
username={props.social.medium}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.youtube.com/c"
|
||||
icon={icon_base_url + "youtube.svg"}
|
||||
username={props.social.youtube}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.codechef.com/users"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
|
||||
username={props.social.codechef}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerrank.com"
|
||||
icon={icon_base_url + "hackerrank.svg"}
|
||||
username={props.social.hackerrank}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codeforces.com/profile"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
|
||||
username={props.social.codeforces}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.leetcode.com"
|
||||
icon={icon_base_url+"leet-code.svg"}
|
||||
username={props.social.leetcode}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerearth.com"
|
||||
icon={icon_base_url+"hackerearth.svg"}
|
||||
username={props.social.hackerearth}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://auth.geeksforgeeks.org/user"
|
||||
icon={icon_base_url + "geeks-for-geeks.svg"}
|
||||
username={props.social.geeks_for_geeks}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.topcoder.com/members"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
|
||||
username={props.social.topcoder}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://discord.gg"
|
||||
icon={icon_base_url + "discord.svg"}
|
||||
username={props.social.discord}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base=""
|
||||
icon={icon_base_url + "rss.svg"}
|
||||
username={props.social.rssurl}
|
||||
/>
|
||||
</>
|
||||
{isSocial(props.social) ? (
|
||||
<>
|
||||
{`</p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<>
|
||||
<DisplaySkills skills={props.skills} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySupport support={props.support} />
|
||||
</>
|
||||
<>
|
||||
<DisplayTopLanguages
|
||||
show={props.data.topLanguages}
|
||||
showStats={props.data.githubStats}
|
||||
github={props.social.github}
|
||||
options={props.data.topLanguagesOptions}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<GitHubStats
|
||||
show={props.data.githubStats}
|
||||
github={props.social.github}
|
||||
options={props.data.githubStatsOptions}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplayStreakStats
|
||||
show={props.data.streakStats}
|
||||
github={props.social.github}
|
||||
options={props.data.streakStatsOptions}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Markdown
|
||||
@@ -0,0 +1,685 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isMediumUsernameValid } from '../utils/validation';
|
||||
import { icons, skills as SKILLS, skillWebsites } from '../constants/skills';
|
||||
import { githubStatsLinkGenerator, topLanguagesLinkGenerator, streakStatsLinkGenerator } from '../utils/link-generators';
|
||||
import { DEFAULT_DATA, DEFAULT_LINK, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
|
||||
|
||||
const Title = (props) => {
|
||||
const { prefix, title } = props;
|
||||
if (prefix && title) {
|
||||
return (
|
||||
<>
|
||||
{`<h1 align="center">${`${prefix} ${title}`}</h1>`}
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
Title.propTypes = {
|
||||
prefix: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const SubTitle = (props) => {
|
||||
const { subtitle } = props;
|
||||
if (subtitle) {
|
||||
return (
|
||||
<>
|
||||
{`<h3 align="center">${subtitle}</h3>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
SubTitle.propTypes = {
|
||||
subtitle: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const SectionTitle = (props) => {
|
||||
const { label } = props;
|
||||
if (label) {
|
||||
return (
|
||||
<>
|
||||
{`<h3 align="left">${label}</h3>`}
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
SectionTitle.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const DisplayWork = (props) => {
|
||||
const { prefix, project, link } = props;
|
||||
if (prefix && project) {
|
||||
if (link) {
|
||||
return (
|
||||
<>
|
||||
{`- ${prefix} [${project}](${link})`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{`- ${prefix} **${project}**`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (prefix && link) {
|
||||
return (
|
||||
<>
|
||||
{`- ${prefix} [${link}](${link})`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
DisplayWork.defaultProps = {
|
||||
prefix: '',
|
||||
project: '',
|
||||
link: '',
|
||||
};
|
||||
|
||||
DisplayWork.propTypes = {
|
||||
prefix: PropTypes.string,
|
||||
project: PropTypes.string,
|
||||
link: PropTypes.string,
|
||||
};
|
||||
|
||||
const DisplaySocial = (props) => {
|
||||
const { username, base, icon } = props;
|
||||
if (username) {
|
||||
return (
|
||||
<>
|
||||
{`<a href="${base}/${username}" target="blank"><img align="center" src="${icon}" alt="${username}" height="30" width="40" /></a>`}
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
DisplaySocial.propTypes = {
|
||||
username: PropTypes.string.isRequired,
|
||||
base: PropTypes.string.isRequired,
|
||||
icon: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
const VisitorsBadge = (props) => {
|
||||
const { github, badgeOptions, show } = props;
|
||||
const link = `https://komarev.com/ghpvc/?username=${github}&label=${badgeOptions.badgeLabel}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <img src="${link}" alt="${github}" /> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
VisitorsBadge.defaultProps = {
|
||||
badgeOptions: {
|
||||
badgeLabel: '',
|
||||
badgeColor: '',
|
||||
badgeStyle: '',
|
||||
},
|
||||
};
|
||||
|
||||
VisitorsBadge.propTypes = {
|
||||
github: PropTypes.string.isRequired,
|
||||
badgeOptions: {
|
||||
badgeLabel: PropTypes.string.isRequired,
|
||||
badgeColor: PropTypes.string.isRequired,
|
||||
badgeStyle: PropTypes.string.isRequired,
|
||||
},
|
||||
show: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const TwitterBadge = (props) => {
|
||||
const { twitter, show, base } = props;
|
||||
const link = `https://img.shields.io/twitter/follow/${twitter}?logo=twitter&style=for-the-badge`;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <a href="${base}/${twitter}" target="blank"><img src="${link}" alt="${twitter}" /></a> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
TwitterBadge.propTypes = {
|
||||
twitter: PropTypes.string.isRequired,
|
||||
base: PropTypes.string.isRequired,
|
||||
show: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const GithubProfileTrophy = (props) => {
|
||||
const { show, github } = props;
|
||||
const link = `https://github-profile-trophy.vercel.app/?username=${github}`;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p align="left"> <a href="https://github.com/ryo-ma/github-profile-trophy"><img src="${link}" alt="${github}" /></a> </p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
GithubProfileTrophy.propTypes = {
|
||||
github: PropTypes.string.isRequired,
|
||||
show: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const GitHubStats = (props) => {
|
||||
const { show, github, options } = props;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p> <img align="center" src="${githubStatsLinkGenerator({
|
||||
github,
|
||||
options,
|
||||
})}" alt="${github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
GitHubStats.defaultProps = {
|
||||
options: {
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: '',
|
||||
cacheSeconds: 0,
|
||||
locale: '',
|
||||
},
|
||||
};
|
||||
|
||||
GitHubStats.propTypes = {
|
||||
github: PropTypes.string.isRequired,
|
||||
options: {
|
||||
theme: PropTypes.string,
|
||||
titleColor: PropTypes.string,
|
||||
textColor: PropTypes.string,
|
||||
bgColor: PropTypes.string,
|
||||
hideBorder: PropTypes.string,
|
||||
cacheSeconds: PropTypes.number,
|
||||
locale: PropTypes.string,
|
||||
},
|
||||
show: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const isSocial = (social) => {
|
||||
let status = false;
|
||||
const SOCIAL_KEYS = Object.keys(DEFAULT_SOCIAL);
|
||||
Object.keys(social).forEach((key) => {
|
||||
if (SOCIAL_KEYS.includes(key)) {
|
||||
status = true;
|
||||
}
|
||||
});
|
||||
return status;
|
||||
};
|
||||
|
||||
const DisplaySkills = (props) => {
|
||||
const { skills } = props;
|
||||
const listChosenSkills = [];
|
||||
SKILLS.forEach((skill) => {
|
||||
if (skills[skill]) {
|
||||
listChosenSkills.push(
|
||||
`
|
||||
<a href="${skillWebsites[skill]}" target="_blank" rel="noreferrer">
|
||||
<img src="${icons[skill]}" alt="${skill}" width="40" height="40"/>
|
||||
</a>
|
||||
`,
|
||||
);
|
||||
}
|
||||
});
|
||||
return listChosenSkills.length > 0 ? (
|
||||
<>
|
||||
<SectionTitle label="Languages and Tools:" />
|
||||
{`<p align="left">${listChosenSkills.join(' ')}</p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
DisplaySkills.defaultProps = {
|
||||
skills: [],
|
||||
};
|
||||
|
||||
DisplaySkills.propTypes = {
|
||||
skills: [],
|
||||
};
|
||||
|
||||
const DisplayDynamicBlogs = (props) => {
|
||||
const { show } = props;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
### Blogs posts
|
||||
<br />
|
||||
{'<!-- BLOG-POST-LIST:START -->'}
|
||||
<br />
|
||||
{'<!-- BLOG-POST-LIST:END -->'}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
DisplayDynamicBlogs.defaultProps = {
|
||||
show: false,
|
||||
};
|
||||
|
||||
DisplayDynamicBlogs.propTypes = {
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
const DisplayTopLanguages = (props) => {
|
||||
const { show, showStats, github, options } = props;
|
||||
if (show) {
|
||||
if (!showStats) {
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="center" src="${topLanguagesLinkGenerator({
|
||||
github,
|
||||
options,
|
||||
})}" alt="${github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="left" src="${topLanguagesLinkGenerator({
|
||||
github,
|
||||
options,
|
||||
})}" alt="${github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
DisplayTopLanguages.defaultProps = {
|
||||
options: {
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: '',
|
||||
cacheSeconds: '',
|
||||
locale: '',
|
||||
},
|
||||
};
|
||||
|
||||
DisplayTopLanguages.propTypes = {
|
||||
github: PropTypes.string.isRequired,
|
||||
options: {
|
||||
theme: PropTypes.string,
|
||||
titleColor: PropTypes.string,
|
||||
textColor: PropTypes.string,
|
||||
bgColor: PropTypes.string,
|
||||
hideBorder: PropTypes.string,
|
||||
cacheSeconds: PropTypes.number,
|
||||
locale: PropTypes.string,
|
||||
},
|
||||
show: PropTypes.bool.isRequired,
|
||||
showStats: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const DisplayStreakStats = (props) => {
|
||||
const { show, github, options } = props;
|
||||
if (show) {
|
||||
return (
|
||||
<>
|
||||
{`<p><img align="center" src="${streakStatsLinkGenerator({
|
||||
github,
|
||||
options,
|
||||
})}" alt="${github}" /></p>`}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
DisplayStreakStats.defaultProps = {
|
||||
options: {
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: '',
|
||||
cacheSeconds: '',
|
||||
locale: '',
|
||||
},
|
||||
};
|
||||
|
||||
DisplayStreakStats.propTypes = {
|
||||
github: PropTypes.string.isRequired,
|
||||
options: {
|
||||
theme: PropTypes.string,
|
||||
titleColor: PropTypes.string,
|
||||
textColor: PropTypes.string,
|
||||
bgColor: PropTypes.string,
|
||||
hideBorder: PropTypes.string,
|
||||
cacheSeconds: PropTypes.number,
|
||||
locale: PropTypes.string,
|
||||
},
|
||||
show: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const DisplaySupport = (props) => {
|
||||
const { support } = props;
|
||||
let viewSupport = false;
|
||||
Object.keys(support).forEach((key) => {
|
||||
if (support[key]) {
|
||||
viewSupport = true;
|
||||
}
|
||||
});
|
||||
return viewSupport ? (
|
||||
<div>
|
||||
<SectionTitle label="Support:" />
|
||||
{'<p>'}
|
||||
{support.buyMeACoffee &&
|
||||
`<a href="https://www.buymeacoffee.com/${support.buyMeACoffee}">
|
||||
<img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="${support.buyMeACoffee}" /></a>`}
|
||||
{support.buyMeAKofi &&
|
||||
`<a href="https://ko-fi.com/${support.buyMeAKofi}">
|
||||
<img align="left" src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" height="50" width="210" alt="${support.buyMeAKofi}" /></a>`}
|
||||
{'</p><br><br>'}
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
|
||||
DisplaySupport.defaultProps = {
|
||||
support: {
|
||||
buyMeACoffee: '',
|
||||
buyMeAKofi: '',
|
||||
},
|
||||
};
|
||||
|
||||
DisplaySupport.propTypes = {
|
||||
support: {
|
||||
buyMeACoffee: PropTypes.string,
|
||||
buyMeAKofi: PropTypes.string,
|
||||
},
|
||||
};
|
||||
|
||||
const Markdown = (props) => {
|
||||
const { prefix, data, link, social, skills, support } = props;
|
||||
const iconBaseUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
|
||||
return (
|
||||
<div id="markdown-content" className="break-words">
|
||||
<>
|
||||
<Title prefix={prefix.title} title={data.title} />
|
||||
</>
|
||||
<>
|
||||
<SubTitle subtitle={data.subtitle} />
|
||||
</>
|
||||
<>
|
||||
<VisitorsBadge
|
||||
show={data.visitorsBadge}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<GithubProfileTrophy show={data.githubProfileTrophy} github={social.github} />
|
||||
<TwitterBadge base="https://twitter.com" show={data.twitterBadge} twitter={social.twitter} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.currentWork} project={data.currentWork} link={link.currentWork} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.collaborateOn} project={data.collaborateOn} link={link.collaborateOn} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.helpWith} project={data.helpWith} link={link.helpWith} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.blog} link={link.blog} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.ama} project={data.ama} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.contact} project={data.contact} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.resume} link={link.resume} />
|
||||
</>
|
||||
<>
|
||||
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
|
||||
</>
|
||||
<>
|
||||
<DisplayDynamicBlogs show={(data.devDynamicBlogs && social.dev) || (data.rssDynamicBlogs && social.rssurl) || (data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium))} />
|
||||
</>
|
||||
{isSocial(social) ? (
|
||||
<>
|
||||
<SectionTitle label="Connect with me:" />
|
||||
{'<p align="left">'}
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<br />
|
||||
<>
|
||||
<DisplaySocial base="https://codepen.io" icon={`${iconBaseUrl}codepen.svg`} username={social.codepen} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://dev.to" icon={`${iconBaseUrl}devto.svg`} username={social.dev} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://twitter.com" icon={`${iconBaseUrl}twitter.svg`} username={social.twitter} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://linkedin.com/in" icon={`${iconBaseUrl}linked-in-alt.svg`} username={social.linkedin} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://stackoverflow.com/users" icon={`${iconBaseUrl}stack-overflow.svg`} username={social.stackoverflow} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://codesandbox.com" icon={`${iconBaseUrl}codesandbox.svg`} username={social.codesandbox} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://fb.com" icon={`${iconBaseUrl}facebook.svg`} username={social.fb} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://instagram.com" icon={`${iconBaseUrl}instagram.svg`} username={social.instagram} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://dribbble.com" icon={`${iconBaseUrl}dribbble.svg`} username={social.dribbble} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.youtube.com/c" icon={`${iconBaseUrl}youtube.svg`} username={social.youtube} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.codechef.com/users" icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" username={social.codechef} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.hackerrank.com" icon={`${iconBaseUrl}hackerrank.svg`} username={social.hackerrank} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://codeforces.com/profile" icon={`${iconBaseUrl}codeforces.svg`} username={social.codeforces} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.leetcode.com" icon={`${iconBaseUrl}leet-code.svg`} username={social.leetcode} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.hackerearth.com" icon={`${iconBaseUrl}hackerearth.svg`} username={social.hackerearth} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://auth.geeksforgeeks.org/user" icon={`${iconBaseUrl}geeks-for-geeks.svg`} username={social.geeks_for_geeks} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.topcoder.com/members" icon={`${iconBaseUrl}topcoder.svg`} username={social.topcoder} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="" icon={`${iconBaseUrl}rss.svg`} username={social.rssurl} />
|
||||
</>
|
||||
{isSocial(social) ? (
|
||||
<>
|
||||
{'</p>'}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<>
|
||||
<DisplaySkills skills={skills} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySupport support={support} />
|
||||
</>
|
||||
<>
|
||||
<DisplayTopLanguages show={data.topLanguages} showStats={data.githubStats} github={social.github} options={data.topLanguagesOptions} />
|
||||
</>
|
||||
<>
|
||||
<GitHubStats show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
|
||||
</>
|
||||
<>
|
||||
<DisplayStreakStats show={data.streakStats} github={social.github} options={data.streakStatsOptions} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default Markdown;
|
||||
|
||||
Markdown.defaultProps = {
|
||||
prefix: DEFAULT_PREFIX,
|
||||
data: DEFAULT_DATA,
|
||||
link: DEFAULT_LINK,
|
||||
social: DEFAULT_SOCIAL,
|
||||
support: DEFAULT_SUPPORT,
|
||||
skills: [],
|
||||
};
|
||||
Markdown.propTypes = {
|
||||
prefix: {
|
||||
title: PropTypes.string,
|
||||
currentWork: PropTypes.string,
|
||||
currentLearn: PropTypes.string,
|
||||
collaborateOn: PropTypes.string,
|
||||
helpWith: PropTypes.string,
|
||||
ama: PropTypes.string,
|
||||
contact: PropTypes.string,
|
||||
resume: PropTypes.string,
|
||||
funFact: PropTypes.string,
|
||||
portfolio: PropTypes.string,
|
||||
blog: PropTypes.string,
|
||||
},
|
||||
data: {
|
||||
title: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
currentWork: PropTypes.string,
|
||||
currentLearn: PropTypes.string,
|
||||
collaborateOn: PropTypes.string,
|
||||
helpWith: PropTypes.string,
|
||||
ama: PropTypes.string,
|
||||
contact: PropTypes.string,
|
||||
funFact: PropTypes.string,
|
||||
twitterBadge: false,
|
||||
visitorsBadge: false,
|
||||
badgeStyle: PropTypes.string,
|
||||
badgeColor: PropTypes.string,
|
||||
badgeLabel: PropTypes.string,
|
||||
githubProfileTrophy: false,
|
||||
githubStats: false,
|
||||
githubStatsOptions: {
|
||||
theme: PropTypes.string,
|
||||
titleColor: PropTypes.string,
|
||||
textColor: PropTypes.string,
|
||||
bgColor: PropTypes.string,
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: PropTypes.string,
|
||||
},
|
||||
topLanguages: false,
|
||||
topLanguagesOptions: {
|
||||
theme: PropTypes.string,
|
||||
titleColor: PropTypes.string,
|
||||
textColor: PropTypes.string,
|
||||
bgColor: PropTypes.string,
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: PropTypes.string,
|
||||
},
|
||||
streakStats: false,
|
||||
streakStatsOptions: {
|
||||
theme: PropTypes.string,
|
||||
},
|
||||
devDynamicBlogs: false,
|
||||
mediumDynamicBlogs: false,
|
||||
rssDynamicBlogs: false,
|
||||
},
|
||||
link: {},
|
||||
social: {},
|
||||
skills: {},
|
||||
support: {},
|
||||
};
|
||||
@@ -1,484 +0,0 @@
|
||||
import React from "react"
|
||||
import { icons, skills, skillWebsites } from "../constants/skills"
|
||||
import {
|
||||
githubStatsLinkGenerator,
|
||||
topLanguagesLinkGenerator,
|
||||
streakStatsLinkGenerator,
|
||||
} from "../utils/link-generators"
|
||||
|
||||
export const TitlePreview = props => {
|
||||
if (props.prefix && props.title) {
|
||||
return (
|
||||
<h1 className="text-center text-xl font-bold">
|
||||
{props.prefix + " " + props.title}
|
||||
</h1>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const SubTitlePreview = props => {
|
||||
if (props.subtitle) {
|
||||
return <h3 className="text-center font-medium">{props.subtitle}</h3>
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const SectionTitle = props => {
|
||||
if (!props.visible) return null
|
||||
else if (props.label) {
|
||||
return <h3 className="w-full text-lg sm:text-xl">{props.label}</h3>
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const DisplayWork = props => {
|
||||
if (props.prefix && props.project) {
|
||||
if (props.link) {
|
||||
return (
|
||||
<div className="my-2">
|
||||
{props.prefix + " "}
|
||||
<a
|
||||
href={props.link}
|
||||
className="no-underline text-blue-700"
|
||||
target="blank"
|
||||
>
|
||||
{props.project}
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<div className="my-2">
|
||||
{props.prefix + " "}
|
||||
<b>{props.project}</b>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
if (props.prefix && props.link) {
|
||||
return (
|
||||
<div className="my-2">
|
||||
{props.prefix + " "}
|
||||
<a
|
||||
href={props.link}
|
||||
className="no-underline text-blue-700"
|
||||
target="blank"
|
||||
>
|
||||
{props.link}
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const WorkPreview = props => {
|
||||
const prefix = props.work.prefix
|
||||
const data = props.work.data
|
||||
const link = props.work.link
|
||||
return (
|
||||
<>
|
||||
<DisplayWork
|
||||
prefix={prefix.currentWork}
|
||||
project={data.currentWork}
|
||||
link={link.currentWork}
|
||||
/>
|
||||
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
|
||||
<DisplayWork
|
||||
prefix={prefix.helpWith}
|
||||
project={data.helpWith}
|
||||
link={link.helpWith}
|
||||
/>
|
||||
<DisplayWork
|
||||
prefix={prefix.collaborateOn}
|
||||
project={data.collaborateOn}
|
||||
link={link.collaborateOn}
|
||||
/>
|
||||
<DisplayWork prefix={prefix.ama} project={data.ama} />
|
||||
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
|
||||
<DisplayWork prefix={prefix.blog} link={link.blog} />
|
||||
<DisplayWork prefix={prefix.resume} link={link.resume} />
|
||||
<DisplayWork prefix={prefix.contact} project={data.contact} />
|
||||
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const DisplaySocial = props => {
|
||||
if (props.username) {
|
||||
return (
|
||||
<a
|
||||
className="no-underline text-blue-700 m-2"
|
||||
href={props.base + "/" + props.username}
|
||||
target="blank"
|
||||
>
|
||||
<img className="w-6 h-6" src={props.icon} alt="props.username" />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const SocialPreview = props => {
|
||||
let viewSocial = false
|
||||
const icon_base_url =
|
||||
"https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/";
|
||||
Object.keys(props.social).forEach(key => {
|
||||
if (props.social[key] && key != "github") viewSocial = true
|
||||
})
|
||||
return (
|
||||
<div className="flex justify-start items-end flex-wrap">
|
||||
<SectionTitle label="Connect with me:" visible={viewSocial} />
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codepen.io"
|
||||
icon={icon_base_url + "codepen.svg"}
|
||||
username={props.social.codepen}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://dev.to"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
|
||||
username={props.social.dev}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://twitter.com"
|
||||
icon={icon_base_url + "twitter.svg"}
|
||||
username={props.social.twitter}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://linkedin.com/in"
|
||||
icon={icon_base_url + "linked-in-alt.svg"}
|
||||
username={props.social.linkedin}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://stackoverflow.com/users"
|
||||
icon={icon_base_url + "stack-overflow.svg"}
|
||||
username={props.social.stackoverflow}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codesandbox.com"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
|
||||
username={props.social.codesandbox}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://kaggle.com"
|
||||
icon={icon_base_url + "kaggle.svg"}
|
||||
username={props.social.kaggle}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://fb.com"
|
||||
icon={icon_base_url + "facebook.svg"}
|
||||
username={props.social.fb}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://instagram.com"
|
||||
icon={icon_base_url + "instagram.svg"}
|
||||
username={props.social.instagram}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://dribbble.com"
|
||||
icon={icon_base_url + "dribbble.svg"}
|
||||
username={props.social.dribbble}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.behance.net"
|
||||
icon={icon_base_url + "behance.svg"}
|
||||
username={props.social.behance}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://medium.com"
|
||||
icon={icon_base_url + "medium.svg"}
|
||||
username={props.social.medium}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.youtube.com/c"
|
||||
icon={icon_base_url + "youtube.svg"}
|
||||
username={props.social.youtube}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.codechef.com/users"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
|
||||
username={props.social.codechef}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerrank.com"
|
||||
icon={icon_base_url + "hackerrank.svg"}
|
||||
username={props.social.hackerrank}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://codeforces.com/profile"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codeforces.svg"
|
||||
username={props.social.codeforces}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.leetcode.com"
|
||||
icon={icon_base_url+"leet-code.svg"}
|
||||
username={props.social.leetcode}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.hackerearth.com"
|
||||
icon={icon_base_url+"hackerearth.svg"}
|
||||
username={props.social.hackerearth}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://auth.geeksforgeeks.org/user"
|
||||
icon={icon_base_url + "geeks-for-geeks.svg"}
|
||||
username={props.social.geeks_for_geeks}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://www.topcoder.com/members"
|
||||
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/topcoder.svg"
|
||||
username={props.social.topcoder}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base="https://discord.gg"
|
||||
icon={icon_base_url + "discord.svg"}
|
||||
username={props.social.discord}
|
||||
/>
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial
|
||||
base=""
|
||||
icon={icon_base_url + "rss.svg"}
|
||||
username={props.social.rssurl}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const VisitorsBadgePreview = props => {
|
||||
let link =
|
||||
"https://komarev.com/ghpvc/?username=" +
|
||||
props.github +
|
||||
`&label=${props.badgeOptions.badgeLabel}` +
|
||||
`&color=${props.badgeOptions.badgeColor}` +
|
||||
`&style=${props.badgeOptions.badgeStyle}`
|
||||
if (props.show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{" "}
|
||||
<img className="h-4 sm:h-6" src={link} alt={props.github} />{" "}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const TwitterBadgePreview = props => {
|
||||
let link =
|
||||
"https://img.shields.io/twitter/follow/" +
|
||||
props.twitter +
|
||||
"?logo=twitter&style=for-the-badge"
|
||||
if (props.show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{" "}
|
||||
<a href="https://twitter.com/${props.twitter}" target="blank">
|
||||
<img className="h-4 sm:h-6" src={link} alt={props.twitter} />
|
||||
</a>{" "}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const GithubProfileTrophyPreview = props => {
|
||||
let link =
|
||||
"https://github-profile-trophy.vercel.app/?username=" + props.github
|
||||
if (props.show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{" "}
|
||||
<a href="https://github.com/ryo-ma/github-profile-trophy">
|
||||
<img src={link} alt={props.github} />
|
||||
</a>{" "}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const GitHubStatsPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img src={githubStatsLinkGenerator({ github, options })} alt={github} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const TopLanguagesPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img
|
||||
src={topLanguagesLinkGenerator({ github, options })}
|
||||
alt={github}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return <div className="text-center mx-4 mb-4"> </div>
|
||||
}
|
||||
|
||||
export const StreakStatsPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img src={streakStatsLinkGenerator({ github, options })} alt={github} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const SkillsPreview = props => {
|
||||
var listSkills = []
|
||||
skills.forEach(skill => {
|
||||
if (props.skills[skill]) {
|
||||
listSkills.push(
|
||||
<a
|
||||
href={skillWebsites[skill]}
|
||||
key={skill}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10"
|
||||
src={icons[skill]}
|
||||
alt={skill}
|
||||
/>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
})
|
||||
return listSkills.length > 0 ? (
|
||||
<div className="flex flex-wrap justify-start items-center">
|
||||
<SectionTitle label="Languages and Tools:" visible={true} />
|
||||
{listSkills}
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)
|
||||
}
|
||||
|
||||
export const SupportPreview = props => {
|
||||
let viewSupport = false
|
||||
Object.keys(props.support).forEach(key => {
|
||||
if (props.support[key]) {
|
||||
viewSupport = true
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<SectionTitle label="Support:" visible={viewSupport} />
|
||||
{props.support.buyMeACoffee && (
|
||||
<div style={{ width: "210px" }}>
|
||||
<a
|
||||
href={`https://www.buymeacoffee.com/` + props.support.buyMeACoffee}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png"
|
||||
alt="Buy Me A Coffee"
|
||||
className="w-36 h-8 sm:w-52 sm:h-12"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const MarkdownPreview = props => {
|
||||
return (
|
||||
<div id="markdown-preview">
|
||||
<TitlePreview prefix={props.prefix.title} title={props.data.title} />
|
||||
<SubTitlePreview subtitle={props.data.subtitle} />
|
||||
<VisitorsBadgePreview
|
||||
show={props.data.visitorsBadge}
|
||||
github={props.social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(props.data.badgeLabel),
|
||||
badgeColor: props.data.badgeColor,
|
||||
badgeStyle: props.data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
<GithubProfileTrophyPreview
|
||||
show={props.data.githubProfileTrophy}
|
||||
github={props.social.github}
|
||||
/>
|
||||
<TwitterBadgePreview
|
||||
show={props.data.twitterBadge}
|
||||
twitter={props.social.twitter}
|
||||
/>
|
||||
<WorkPreview work={props} />
|
||||
<SocialPreview social={props.social} />
|
||||
<SkillsPreview skills={props.skills} />
|
||||
<SupportPreview support={props.support} />
|
||||
<div className="block sm:flex sm:justify-center sm:items-start">
|
||||
<TopLanguagesPreview
|
||||
show={props.data.topLanguages}
|
||||
github={props.social.github}
|
||||
options={props.data.topLanguagesOptions}
|
||||
/>
|
||||
<GitHubStatsPreview
|
||||
show={props.data.githubStats}
|
||||
github={props.social.github}
|
||||
options={props.data.githubStatsOptions}
|
||||
/>
|
||||
<StreakStatsPreview
|
||||
show={props.data.streakStats}
|
||||
github={props.social.github}
|
||||
options={props.data.streakStatsOptions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MarkdownPreview
|
||||
@@ -0,0 +1,454 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { icons, skills as SKILLS, skillWebsites } from '../constants/skills';
|
||||
import { githubStatsLinkGenerator, topLanguagesLinkGenerator, streakStatsLinkGenerator } from '../utils/link-generators';
|
||||
import { DEFAULT_DATA, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
|
||||
|
||||
export const TitlePreview = (props) => {
|
||||
const { prefix, title } = props;
|
||||
if (prefix && title) {
|
||||
return <h1 className="text-center text-xl font-bold">{`${prefix} ${title}`}</h1>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
TitlePreview.propTypes = {
|
||||
prefix: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export const SubTitlePreview = (props) => {
|
||||
const { subtitle } = props;
|
||||
if (subtitle) {
|
||||
return <h3 className="text-center font-medium">{subtitle}</h3>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
SubTitlePreview.propTypes = {
|
||||
subtitle: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export const SectionTitle = (props) => {
|
||||
const { visible, label } = props;
|
||||
if (!visible) return null;
|
||||
if (label) {
|
||||
return <h3 className="w-full text-lg sm:text-xl">{label}</h3>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
SectionTitle.defaultProps = {
|
||||
visible: false,
|
||||
};
|
||||
SectionTitle.propTypes = {
|
||||
visible: PropTypes.bool,
|
||||
label: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export const DisplayWork = (props) => {
|
||||
const { prefix, project, link } = props;
|
||||
if (prefix && project) {
|
||||
if (link) {
|
||||
return (
|
||||
<div className="my-2">
|
||||
{`${prefix} `}
|
||||
<a href={link} className="no-underline text-blue-700" target="blank">
|
||||
{project}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="my-2">
|
||||
{`${prefix} `}
|
||||
<b>{project}</b>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (prefix && link) {
|
||||
return (
|
||||
<div className="my-2">
|
||||
{`${prefix} `}
|
||||
<a href={link} className="no-underline text-blue-700" target="blank">
|
||||
{link}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
DisplayWork.defaultProps = {
|
||||
prefix: '',
|
||||
project: '',
|
||||
link: '',
|
||||
};
|
||||
|
||||
DisplayWork.propTypes = {
|
||||
prefix: PropTypes.string,
|
||||
project: PropTypes.string,
|
||||
link: PropTypes.string,
|
||||
};
|
||||
|
||||
export const WorkPreview = (props) => {
|
||||
const { work } = props;
|
||||
const { prefix, data, link } = work;
|
||||
return (
|
||||
<>
|
||||
<DisplayWork prefix={prefix.currentWork} project={data.currentWork} link={link.currentWork} />
|
||||
<DisplayWork prefix={prefix.currentLearn} project={data.currentLearn} />
|
||||
<DisplayWork prefix={prefix.helpWith} project={data.helpWith} link={link.helpWith} />
|
||||
<DisplayWork prefix={prefix.collaborateOn} project={data.collaborateOn} link={link.collaborateOn} />
|
||||
<DisplayWork prefix={prefix.ama} project={data.ama} />
|
||||
<DisplayWork prefix={prefix.portfolio} link={link.portfolio} />
|
||||
<DisplayWork prefix={prefix.blog} link={link.blog} />
|
||||
<DisplayWork prefix={prefix.resume} link={link.resume} />
|
||||
<DisplayWork prefix={prefix.contact} project={data.contact} />
|
||||
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
WorkPreview.propTypes = {
|
||||
work: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export const DisplaySocial = (props) => {
|
||||
const { username, base, icon } = props;
|
||||
if (username) {
|
||||
return (
|
||||
<a className="no-underline text-blue-700 m-2" href={`${base}/${username}`} target="blank">
|
||||
<img className="w-6 h-6" src={icon} alt="username" />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
DisplaySocial.defaultProps = {
|
||||
username: '',
|
||||
base: '',
|
||||
icon: '',
|
||||
};
|
||||
DisplaySocial.propTypes = {
|
||||
username: PropTypes.string,
|
||||
base: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
};
|
||||
|
||||
export const SocialPreview = (props) => {
|
||||
const { social } = props;
|
||||
let viewSocial = false;
|
||||
const iconBaseUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
|
||||
Object.keys(social).forEach((key) => {
|
||||
if (social[key] && key !== 'github') viewSocial = true;
|
||||
});
|
||||
return (
|
||||
<div className="flex justify-start items-end flex-wrap">
|
||||
<SectionTitle label="Connect with me:" visible={viewSocial} />
|
||||
<>
|
||||
<DisplaySocial base="https://codepen.io" icon={`${iconBaseUrl}codepen.svg`} username={social.codepen} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://dev.to" icon={`${iconBaseUrl}devto.svg`} username={social.dev} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://twitter.com" icon={`${iconBaseUrl}twitter.svg`} username={social.twitter} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://linkedin.com/in" icon={`${iconBaseUrl}linked-in-alt.svg`} username={social.linkedin} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://stackoverflow.com/users" icon={`${iconBaseUrl}stack-overflow.svg`} username={social.stackoverflow} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://codesandbox.com" icon={`${iconBaseUrl}codesandbox.svg`} username={social.codesandbox} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://fb.com" icon={`${iconBaseUrl}facebook.svg`} username={social.fb} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://instagram.com" icon={`${iconBaseUrl}instagram.svg`} username={social.instagram} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://dribbble.com" icon={`${iconBaseUrl}dribbble.svg`} username={social.dribbble} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.youtube.com/c" icon={`${iconBaseUrl}youtube.svg`} username={social.youtube} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.codechef.com/users" icon="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" username={social.codechef} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.hackerrank.com" icon={`${iconBaseUrl}hackerrank.svg`} username={social.hackerrank} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://codeforces.com/profile" icon={`${iconBaseUrl}codeforces.svg`} username={social.codeforces} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.leetcode.com" icon={`${iconBaseUrl}leet-code.svg`} username={social.leetcode} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.hackerearth.com" icon={`${iconBaseUrl}hackerearth.svg`} username={social.hackerearth} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://auth.geeksforgeeks.org/user" icon={`${iconBaseUrl}geeks-for-geeks.svg`} username={social.geeks_for_geeks} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://www.topcoder.com/members" icon={`${iconBaseUrl}topcoder.svg`} username={social.topcoder} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
|
||||
</>
|
||||
<>
|
||||
<DisplaySocial base="" icon={`${iconBaseUrl}rss.svg`} username={social.rssurl} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
SocialPreview.propTypes = {
|
||||
social: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export const VisitorsBadgePreview = (props) => {
|
||||
const { github, show, badgeOptions } = props;
|
||||
const link = `https://komarev.com/ghpvc/?username=${github}&label=${badgeOptions.badgeLabel}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`;
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{' '}
|
||||
<img className="h-4 sm:h-6" src={link} alt={github} />{' '}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
VisitorsBadgePreview.defaultProps = {
|
||||
github: '',
|
||||
show: false,
|
||||
badgeOptions: {},
|
||||
};
|
||||
VisitorsBadgePreview.propTypes = {
|
||||
github: PropTypes.string,
|
||||
show: PropTypes.bool,
|
||||
badgeOptions: PropTypes.object,
|
||||
};
|
||||
|
||||
export const TwitterBadgePreview = (props) => {
|
||||
const { twitter, show } = props;
|
||||
const link = `https://img.shields.io/twitter/follow/${twitter}?logo=twitter&style=for-the-badge`;
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{' '}
|
||||
<a href={`https://twitter.com/${twitter}`} target="_blank" rel="noreferrer">
|
||||
<img className="h-4 sm:h-6" src={link} alt={twitter} />
|
||||
</a>{' '}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
TwitterBadgePreview.defaultProps = {
|
||||
twitter: '',
|
||||
show: false,
|
||||
};
|
||||
TwitterBadgePreview.propTypes = {
|
||||
twitter: PropTypes.string,
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
export const GithubProfileTrophyPreview = (props) => {
|
||||
const { github, show } = props;
|
||||
const link = `https://github-profile-trophy.vercel.app/?username=${github}`;
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-left my-2">
|
||||
{' '}
|
||||
<a href="https://github.com/ryo-ma/github-profile-trophy">
|
||||
<img src={link} alt={github} />
|
||||
</a>{' '}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
GithubProfileTrophyPreview.defaultProps = {
|
||||
github: '',
|
||||
show: false,
|
||||
};
|
||||
GithubProfileTrophyPreview.propTypes = {
|
||||
github: PropTypes.string,
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
export const GitHubStatsPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img src={githubStatsLinkGenerator({ github, options })} alt={github} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
GitHubStatsPreview.defaultProps = {
|
||||
github: '',
|
||||
options: {},
|
||||
show: false,
|
||||
};
|
||||
GitHubStatsPreview.propTypes = {
|
||||
github: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
export const TopLanguagesPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img src={topLanguagesLinkGenerator({ github, options })} alt={github} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <div className="text-center mx-4 mb-4"> </div>;
|
||||
};
|
||||
TopLanguagesPreview.defaultProps = {
|
||||
github: '',
|
||||
options: {},
|
||||
show: false,
|
||||
};
|
||||
TopLanguagesPreview.propTypes = {
|
||||
github: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
export const StreakStatsPreview = ({ github, options, show }) => {
|
||||
if (show) {
|
||||
return (
|
||||
<div className="text-center mx-4 mb-4">
|
||||
<img src={streakStatsLinkGenerator({ github, options })} alt={github} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
StreakStatsPreview.defaultProps = {
|
||||
github: '',
|
||||
options: {},
|
||||
show: false,
|
||||
};
|
||||
StreakStatsPreview.propTypes = {
|
||||
github: PropTypes.string,
|
||||
options: PropTypes.object,
|
||||
show: PropTypes.bool,
|
||||
};
|
||||
|
||||
export const SkillsPreview = (props) => {
|
||||
const { skills } = props;
|
||||
const listSkills = [];
|
||||
SKILLS.forEach((skill) => {
|
||||
if (skills[skill]) {
|
||||
listSkills.push(
|
||||
<a href={skillWebsites[skill]} key={skill} target="_blank" rel="noreferrer">
|
||||
<img className="mb-4 mr-4 h-6 w-6 sm:h-10 sm:w-10" src={icons[skill]} alt={skill} />
|
||||
</a>,
|
||||
);
|
||||
}
|
||||
});
|
||||
return listSkills.length > 0 ? (
|
||||
<div className="flex flex-wrap justify-start items-center">
|
||||
<SectionTitle label="Languages and Tools:" visible />
|
||||
{listSkills}
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
SkillsPreview.propTypes = {
|
||||
skills: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
export const SupportPreview = (props) => {
|
||||
const { support } = props;
|
||||
let viewSupport = false;
|
||||
Object.keys(support).forEach((key) => {
|
||||
if (support[key]) {
|
||||
viewSupport = true;
|
||||
}
|
||||
});
|
||||
return support.buyMeACoffee || support.buyMeAKofi ? (
|
||||
<div className="flex flex-wrap justify-start items-center">
|
||||
<SectionTitle label="Support:" visible={viewSupport} />
|
||||
{support.buyMeACoffee && (
|
||||
<a href={`https://www.buymeacoffee.com/${support.buyMeACoffee}`} target="_blank" rel="noreferrer">
|
||||
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" className="mb-4 mr-4 w-36 h-8 sm:w-52 sm:h-12" />
|
||||
</a>
|
||||
)}
|
||||
{support.buyMeAKofi && (
|
||||
<a href={`https://ko-fi.com/${support.buyMeAKofi}`} target="_blank" rel="noreferrer">
|
||||
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" alt="Buy Me A Ko-fi" className="mb-4 mr-4 w-36 h-8 sm:w-52 sm:h-12" />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
};
|
||||
SupportPreview.propTypes = {
|
||||
support: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const MarkdownPreview = (props) => {
|
||||
const { prefix, data, social, skills, support } = props;
|
||||
return (
|
||||
<div id="markdown-preview">
|
||||
<TitlePreview prefix={prefix.title} title={data.title} />
|
||||
<SubTitlePreview subtitle={data.subtitle} />
|
||||
<VisitorsBadgePreview
|
||||
show={data.visitorsBadge}
|
||||
github={social.github}
|
||||
badgeOptions={{
|
||||
badgeLabel: encodeURI(data.badgeLabel),
|
||||
badgeColor: data.badgeColor,
|
||||
badgeStyle: data.badgeStyle,
|
||||
}}
|
||||
/>
|
||||
<GithubProfileTrophyPreview show={data.githubProfileTrophy} github={social.github} />
|
||||
<TwitterBadgePreview show={data.twitterBadge} twitter={social.twitter} />
|
||||
<WorkPreview work={props} />
|
||||
<SocialPreview social={social} />
|
||||
<SkillsPreview skills={skills} />
|
||||
<SupportPreview support={support} />
|
||||
<div className="block sm:flex sm:justify-center sm:items-start">
|
||||
<TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
|
||||
<GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
|
||||
<StreakStatsPreview show={data.streakStats} github={social.github} options={data.streakStatsOptions} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarkdownPreview;
|
||||
|
||||
MarkdownPreview.defaultProps = {
|
||||
prefix: DEFAULT_PREFIX,
|
||||
data: DEFAULT_DATA,
|
||||
social: DEFAULT_SOCIAL,
|
||||
support: DEFAULT_SUPPORT,
|
||||
skills: [],
|
||||
};
|
||||
|
||||
MarkdownPreview.propTypes = {
|
||||
prefix: PropTypes.object,
|
||||
data: PropTypes.object,
|
||||
social: PropTypes.object,
|
||||
skills: PropTypes.object,
|
||||
support: PropTypes.object,
|
||||
};
|
||||
@@ -5,10 +5,10 @@
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { Helmet } from "react-helmet"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { useStaticQuery, graphql } from 'gatsby';
|
||||
|
||||
function SEO({ description, lang, meta, title }) {
|
||||
const { site } = useStaticQuery(
|
||||
@@ -22,10 +22,10 @@ function SEO({ description, lang, meta, title }) {
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
`,
|
||||
);
|
||||
|
||||
const metaDescription = description || site.siteMetadata.description
|
||||
const metaDescription = description || site.siteMetadata.description;
|
||||
|
||||
return (
|
||||
<Helmet
|
||||
@@ -69,20 +69,20 @@ function SEO({ description, lang, meta, title }) {
|
||||
},
|
||||
].concat(meta)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
SEO.defaultProps = {
|
||||
lang: `en`,
|
||||
meta: [],
|
||||
description: ``,
|
||||
}
|
||||
};
|
||||
|
||||
SEO.propTypes = {
|
||||
description: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
meta: PropTypes.arrayOf(PropTypes.object),
|
||||
title: PropTypes.string.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
export default SEO
|
||||
export default SEO;
|
||||
@@ -1,104 +0,0 @@
|
||||
import React, {useState} from "react"
|
||||
import { icons, categorizedSkills } from "../constants/skills"
|
||||
import { SearchIcon, XIcon } from "@primer/octicons-react";
|
||||
|
||||
|
||||
const Skills = props => {
|
||||
const [search, setSearch] = useState('')
|
||||
const [debounce, setDebounce] = useState(undefined);
|
||||
const inputRef = React.createRef()
|
||||
const createSkill = skill => {
|
||||
return (
|
||||
<div className="w-1/3 sm:w-1/4 my-6" key={skill}>
|
||||
<label
|
||||
htmlFor={skill}
|
||||
className="skillCheckboxLabel cursor-pointer flex items-center justify-start"
|
||||
>
|
||||
<input
|
||||
id={skill}
|
||||
type="checkbox"
|
||||
checked={props.skills[skill]}
|
||||
onChange={event => props.handleSkillsChange(skill)}
|
||||
/>
|
||||
<img
|
||||
className="ml-4 w-8 h-8 sm:w-10 sm:h-10"
|
||||
src={icons[skill]}
|
||||
alt={skill}
|
||||
/>
|
||||
<span className="tooltiptext">{skill}</span>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const onSearchChange = (value) => {
|
||||
const callback = () => {
|
||||
setSearch(value)
|
||||
}
|
||||
clearTimeout(debounce)
|
||||
setDebounce(setTimeout(callback, 50))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-10 ">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-4 flex justify-between">
|
||||
Skills
|
||||
<div className="relative flex">
|
||||
<input
|
||||
type="text"
|
||||
onChange={(e) => onSearchChange(e.target.value)}
|
||||
className="leading:none text-xs my-0 py-1 px-2 pr-8 sm:text-xl border-2 border-gray-900 focus:border-blue-700 placeholder-gray-700"
|
||||
placeholder="Search Skills"
|
||||
ref = {inputRef}
|
||||
/>
|
||||
<span className="absolute" style={{right:"10px"}}>
|
||||
{(search !== '')
|
||||
?<button className="focus:outline-none" onClick={() => {
|
||||
setSearch('')
|
||||
inputRef.current.value = ''
|
||||
}
|
||||
}>
|
||||
<XIcon size={16} className="mb-1 transform scale-100 md:scale-125"/>
|
||||
</button>
|
||||
:<SearchIcon size={16} className="mb-1 transform scale-100 md:scale-125"/>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{Object.keys(categorizedSkills)
|
||||
.filter(key => {
|
||||
let filtered = categorizedSkills[key].skills.filter(skill => {
|
||||
return skill.includes(search.toLowerCase())
|
||||
})
|
||||
return filtered.length !== 0
|
||||
})
|
||||
.map(key => (
|
||||
<div key={key} className="divide-y divide-gray-500">
|
||||
<div className="text-sm sm:text-xl text-gray-900 text-left py-1">
|
||||
{categorizedSkills[key].title}
|
||||
</div>
|
||||
<div className="flex justify-start items-center flex-wrap w-full mb-6 pl-4 sm:pl-10">
|
||||
{categorizedSkills[key].skills
|
||||
.filter(skill => {
|
||||
return skill.includes(search.toLowerCase())
|
||||
})
|
||||
.map(skill => createSkill(skill))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<span className="flex justify-center text-gray-900">
|
||||
{(Object.keys(categorizedSkills)
|
||||
.filter(key => {
|
||||
let filtered = categorizedSkills[key].skills.filter(skill => {
|
||||
return skill.includes(search.toLowerCase())
|
||||
})
|
||||
return filtered.length !== 0
|
||||
})
|
||||
.length === 0)?"No Results Found":""}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Skills
|
||||
@@ -0,0 +1,83 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { SearchIcon, XIcon } from '@primer/octicons-react';
|
||||
import { icons, categorizedSkills } from '../constants/skills';
|
||||
|
||||
const Skills = (props) => {
|
||||
const { skills, handleSkillsChange } = props;
|
||||
const [search, setSearch] = useState('');
|
||||
const [debounce, setDebounce] = useState(undefined);
|
||||
const inputRef = React.createRef();
|
||||
const createSkill = (skill) => (
|
||||
<div className="w-1/3 sm:w-1/4 my-6" key={skill}>
|
||||
<label htmlFor={skill} className="checkbox-label flex items-center justify-start">
|
||||
<input id={skill} type="checkbox" className="checkbox-label__input" checked={skills[skill]} onChange={() => handleSkillsChange(skill)} />
|
||||
<span className="checkbox-label__control" />
|
||||
<img className="ml-4 w-8 h-8 sm:w-10 sm:h-10" src={icons[skill]} alt={skill} />
|
||||
<span className="tooltiptext">{skill}</span>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
||||
const onSearchChange = (value) => {
|
||||
const callback = () => {
|
||||
setSearch(value);
|
||||
};
|
||||
clearTimeout(debounce);
|
||||
setDebounce(setTimeout(callback, 50));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-10 ">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-4 flex justify-between">
|
||||
Skills
|
||||
<div className="relative flex">
|
||||
<input type="text" onChange={(e) => onSearchChange(e.target.value)} className="leading:none text-xs my-0 py-1 px-2 pr-8 sm:text-xl border-2 border-gray-900 focus:border-blue-700 placeholder-gray-700" placeholder="Search Skills" ref={inputRef} />
|
||||
<span className="absolute" style={{ right: '10px' }}>
|
||||
{search !== '' ? (
|
||||
<button
|
||||
type="button"
|
||||
className="focus:outline-none"
|
||||
onClick={() => {
|
||||
setSearch('');
|
||||
inputRef.current.value = '';
|
||||
}}
|
||||
>
|
||||
<XIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
|
||||
</button>
|
||||
) : (
|
||||
<SearchIcon size={16} className="mb-1 transform scale-100 md:scale-125" />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{Object.keys(categorizedSkills)
|
||||
.filter((key) => {
|
||||
const filtered = categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase()));
|
||||
return filtered.length !== 0;
|
||||
})
|
||||
.map((key) => (
|
||||
<div key={key} className="divide-y divide-gray-500">
|
||||
<div className="text-sm sm:text-xl text-gray-900 text-left py-1">{categorizedSkills[key].title}</div>
|
||||
<div className="flex justify-start items-center flex-wrap w-full mb-6 pl-4 sm:pl-10">{categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase())).map((skill) => createSkill(skill))}</div>
|
||||
</div>
|
||||
))}
|
||||
<span className="flex justify-center text-gray-900">
|
||||
{Object.keys(categorizedSkills).filter((key) => {
|
||||
const filtered = categorizedSkills[key].skills.filter((skill) => skill.includes(search.toLowerCase()));
|
||||
return filtered.length !== 0;
|
||||
}).length === 0
|
||||
? 'No Results Found'
|
||||
: ''}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Skills;
|
||||
|
||||
Skills.propTypes = {
|
||||
skills: PropTypes.array.isRequired,
|
||||
handleSkillsChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,339 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const Social = props => {
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-4">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Social
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-center items-center">
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="github"
|
||||
/>
|
||||
<input
|
||||
id="github"
|
||||
placeholder="github username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 focus:border-blue-700"
|
||||
value={props.social.github}
|
||||
onChange={event => props.handleSocialChange("github", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/twitter.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="twitter"
|
||||
/>
|
||||
<input
|
||||
id="twitter"
|
||||
placeholder="twitter username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.twitter}
|
||||
onChange={event => props.handleSocialChange("twitter", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="dev.to"
|
||||
/>
|
||||
<input
|
||||
id="dev"
|
||||
placeholder="dev.to username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.dev}
|
||||
onChange={event => props.handleSocialChange("dev", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="codepen"
|
||||
/>
|
||||
<input
|
||||
id="codepen"
|
||||
placeholder="codepen username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.codepen}
|
||||
onChange={event => props.handleSocialChange("codepen", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="codesandbox"
|
||||
/>
|
||||
<input
|
||||
id="codesandbox"
|
||||
placeholder="codesandbox username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.codesandbox}
|
||||
onChange={event => props.handleSocialChange("codesandbox", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="stackoverflow"
|
||||
/>
|
||||
<input
|
||||
id="stackoverflow"
|
||||
placeholder="stackoverflow user ID"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.stackoverflow}
|
||||
onChange={event => props.handleSocialChange("stackoverflow", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="linkedin"
|
||||
/>
|
||||
<input
|
||||
id="linkedin"
|
||||
placeholder="linkedin username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.linkedin}
|
||||
onChange={event => props.handleSocialChange("linkedin", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="kaggle"
|
||||
/>
|
||||
<input
|
||||
id="kaggle"
|
||||
placeholder="kaggle username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.kaggle}
|
||||
onChange={event => props.handleSocialChange("kaggle", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="facebook"
|
||||
/>
|
||||
<input
|
||||
id="fb"
|
||||
placeholder="facebook username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.fb}
|
||||
onChange={event => props.handleSocialChange("fb", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="instagram"
|
||||
/>
|
||||
<input
|
||||
id="instagram"
|
||||
placeholder="instagram username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.instagram}
|
||||
onChange={event => props.handleSocialChange("instagram", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/dribbble.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="dribbble"
|
||||
/>
|
||||
<input
|
||||
id="dribbble"
|
||||
placeholder="dribbble username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.dribbble}
|
||||
onChange={event => props.handleSocialChange("dribbble", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/behance.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="behance"
|
||||
/>
|
||||
<input
|
||||
id="behance"
|
||||
placeholder="behance username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.behance}
|
||||
onChange={event => props.handleSocialChange("behance", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/medium.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="medium"
|
||||
/>
|
||||
<input
|
||||
id="medium"
|
||||
placeholder="medium username (with @)"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.medium}
|
||||
onChange={event => props.handleSocialChange("medium", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/youtube.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="youtube"
|
||||
/>
|
||||
<input
|
||||
id="youtube"
|
||||
placeholder="youtube channel name"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.youtube}
|
||||
onChange={event => props.handleSocialChange("youtube", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="codechef"
|
||||
/>
|
||||
<input
|
||||
id="codechef"
|
||||
placeholder="codechef username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.codechef}
|
||||
onChange={event => props.handleSocialChange("codechef", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerrank.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="hackerrank"
|
||||
/>
|
||||
<input
|
||||
id="hackerrank"
|
||||
placeholder="hackerrank username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.hackerrank}
|
||||
onChange={event => props.handleSocialChange("hackerrank", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codeforces.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="codeforces"
|
||||
/>
|
||||
<input
|
||||
id="codeforces"
|
||||
placeholder="codeforces username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.codeforces}
|
||||
onChange={event => props.handleSocialChange("codeforces", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/leetcode.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="leetcode"
|
||||
/>
|
||||
<input
|
||||
id="leetcode"
|
||||
placeholder="leetcode username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.leetcode}
|
||||
onChange={event => props.handleSocialChange("leetcode", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/topcoder.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="topcoder"
|
||||
/>
|
||||
<input
|
||||
id="topcoder"
|
||||
placeholder="topcoder username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.topcoder}
|
||||
onChange={event => props.handleSocialChange("topcoder", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerearth.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="hackerearth"
|
||||
/>
|
||||
<input
|
||||
id="hackerearth"
|
||||
placeholder="hackerearth user (with @)"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.hackerearth}
|
||||
onChange={event => props.handleSocialChange("hackerearth", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/geeksforgeeks.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="geeksforgeeks"
|
||||
/>
|
||||
<input
|
||||
id="geeksforgeeks"
|
||||
placeholder="GFG (<username>/profile)"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.geeks_for_geeks}
|
||||
onChange={event =>
|
||||
props.handleSocialChange("geeks_for_geeks", event)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/discord.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="discord"
|
||||
/>
|
||||
<input
|
||||
id="discord"
|
||||
placeholder="discord invite (only code)"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.discord}
|
||||
onChange={event => props.handleSocialChange("discord", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/rss.svg"
|
||||
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
|
||||
alt="rssfeed"
|
||||
/>
|
||||
<input
|
||||
id="rssurl"
|
||||
placeholder="RSS feed URL"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.social.rssurl}
|
||||
onChange={event => props.handleSocialChange("rssurl", event)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Social
|
||||
@@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Social = (props) => {
|
||||
const { social, handleSocialChange } = props;
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-4">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Social</div>
|
||||
<div className="flex flex-wrap justify-center items-center">
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="github" />
|
||||
<input id="github" placeholder="github username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 focus:border-blue-700" value={social.github} onChange={(event) => handleSocialChange('github', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/twitter.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="twitter" />
|
||||
<input id="twitter" placeholder="twitter username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.twitter} onChange={(event) => handleSocialChange('twitter', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/dev-dot-to.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="dev.to" />
|
||||
<input id="dev" placeholder="dev.to username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.dev} onChange={(event) => handleSocialChange('dev', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codepen" />
|
||||
<input id="codepen" placeholder="codepen username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codepen} onChange={(event) => handleSocialChange('codepen', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codesandbox.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codesandbox" />
|
||||
<input id="codesandbox" placeholder="codesandbox username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codesandbox} onChange={(event) => handleSocialChange('codesandbox', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/stackoverflow.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="stackoverflow" />
|
||||
<input id="stackoverflow" placeholder="stackoverflow user ID" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.stackoverflow} onChange={(event) => handleSocialChange('stackoverflow', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="linkedin" />
|
||||
<input id="linkedin" placeholder="linkedin username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.linkedin} onChange={(event) => handleSocialChange('linkedin', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/kaggle.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="kaggle" />
|
||||
<input id="kaggle" placeholder="kaggle username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.kaggle} onChange={(event) => handleSocialChange('kaggle', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="facebook" />
|
||||
<input id="fb" placeholder="facebook username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.fb} onChange={(event) => handleSocialChange('fb', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="instagram" />
|
||||
<input id="instagram" placeholder="instagram username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.instagram} onChange={(event) => handleSocialChange('instagram', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/dribbble.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="dribbble" />
|
||||
<input id="dribbble" placeholder="dribbble username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.dribbble} onChange={(event) => handleSocialChange('dribbble', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/behance.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="behance" />
|
||||
<input id="behance" placeholder="behance username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.behance} onChange={(event) => handleSocialChange('behance', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/medium.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="medium" />
|
||||
<input id="medium" placeholder="medium username (with @)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.medium} onChange={(event) => handleSocialChange('medium', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/youtube.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="youtube" />
|
||||
<input id="youtube" placeholder="youtube channel name" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.youtube} onChange={(event) => handleSocialChange('youtube', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codechef.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codechef" />
|
||||
<input id="codechef" placeholder="codechef username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codechef} onChange={(event) => handleSocialChange('codechef', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerrank.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="hackerrank" />
|
||||
<input id="hackerrank" placeholder="hackerrank username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.hackerrank} onChange={(event) => handleSocialChange('hackerrank', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/codeforces.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="codeforces" />
|
||||
<input id="codeforces" placeholder="codeforces username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.codeforces} onChange={(event) => handleSocialChange('codeforces', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/leetcode.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="leetcode" />
|
||||
<input id="leetcode" placeholder="leetcode username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.leetcode} onChange={(event) => handleSocialChange('leetcode', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/topcoder.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="topcoder" />
|
||||
<input id="topcoder" placeholder="topcoder username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.topcoder} onChange={(event) => handleSocialChange('topcoder', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/hackerearth.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="hackerearth" />
|
||||
<input id="hackerearth" placeholder="hackerearth user (with @)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.hackerearth} onChange={(event) => handleSocialChange('hackerearth', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/geeksforgeeks.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="geeksforgeeks" />
|
||||
<input id="geeksforgeeks" placeholder="GFG (<username>/profile)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.geeks_for_geeks} onChange={(event) => handleSocialChange('geeks_for_geeks', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/discord.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="discord" />
|
||||
<input id="discord" placeholder="discord invite (only code)" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.discord} onChange={(event) => handleSocialChange('discord', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-center items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.jsdelivr.net/npm/simple-icons@3.1.0/icons/rss.svg" className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4" alt="rssfeed" />
|
||||
<input id="rssurl" placeholder="RSS feed URL" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={social.rssurl} onChange={(event) => handleSocialChange('rssurl', event)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Social;
|
||||
Social.propTypes = {
|
||||
social: PropTypes.object.isRequired,
|
||||
handleSocialChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const Subtitle = props => {
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Subtitle
|
||||
</div>
|
||||
<input
|
||||
id="subtitle"
|
||||
className="outline-none w-full text-xs sm:text-lg sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.subtitle}
|
||||
onChange={event => props.handleDataChange("subtitle", event)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Subtitle
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Subtitle = (props) => {
|
||||
const { data, handleDataChange } = props;
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Subtitle</div>
|
||||
<input id="subtitle" className="outline-none w-full text-xs sm:text-lg sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.subtitle} onChange={(event) => handleDataChange('subtitle', event)} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Subtitle;
|
||||
Subtitle.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
handleDataChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const Support = props => {
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-4">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Support
|
||||
</div>
|
||||
<div className="flex flex-wrap justify-start items-center">
|
||||
<div className="w-2/5 flex justify-between items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img
|
||||
src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png"
|
||||
className="w-36 h-8 sm:w-52 sm:h-12"
|
||||
alt="buymeacoffee"
|
||||
/>
|
||||
<input
|
||||
id="buy-me-a-coffee"
|
||||
placeholder="buymeacoffee username"
|
||||
className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 ml-2 sm:ml-0 focus:border-blue-700"
|
||||
value={props.support.buyMeACoffee || ""}
|
||||
onChange={event => props.handleSupportChange("buyMeACoffee", event)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Support
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Support = (props) => {
|
||||
const { support, handleSupportChange } = props;
|
||||
return (
|
||||
<div className="px-2 sm:px-6 mb-4">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Support</div>
|
||||
<div className="flex flex-wrap justify-start items-center">
|
||||
<div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" className="w-36 h-8 sm:w-52 sm:h-12 mr-1 sm:mr-4" alt="buymeacoffee" />
|
||||
<input id="buy-me-a-coffee" placeholder="buymeacoffee username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 focus:border-blue-700" value={support.buyMeACoffee || ''} onChange={(event) => handleSupportChange('buyMeACoffee', event)} />
|
||||
</div>
|
||||
<div className="w-1/2 flex justify-start items-center text-xxs sm:text-lg py-4 pr-2 sm:pr-0">
|
||||
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" className="w-36 h-8 sm:w-52 sm:h-12 mr-1 sm:mr-4" alt="buymeakofi" />
|
||||
<input id="buy-me-a-kofi" placeholder="Ko-fi username" className="outline-none placeholder-gray-700 w-32 sm:w-1/2 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-1 sm:px-2 ml-2 sm:ml-0 focus:border-blue-700" value={support.buyMeAKofi || ''} onChange={(event) => handleSupportChange('buyMeAKofi', event)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Support;
|
||||
Support.propTypes = {
|
||||
support: PropTypes.object.isRequired,
|
||||
handleSupportChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const Title = props => {
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Title
|
||||
</div>
|
||||
<div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg">
|
||||
<input
|
||||
id="title-prefix"
|
||||
className="outline-none w-24 sm:w-40 mr-10 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix"
|
||||
value={props.prefix.title}
|
||||
onChange={event => props.handlePrefixChange("title", event)}
|
||||
/>
|
||||
<input
|
||||
id="title-name"
|
||||
placeholder="name"
|
||||
className="outline-none placeholder-gray-700 w-1/2 sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.title}
|
||||
onChange={event => props.handleDataChange("title", event)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Title
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Title = (props) => {
|
||||
const { data, prefix, handlePrefixChange, handleDataChange } = props;
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Title</div>
|
||||
<div className="flex justify-start items-center w-full text-regular text-xs sm:text-lg">
|
||||
<input id="title-prefix" className="outline-none w-24 sm:w-40 mr-10 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix" value={prefix.title} onChange={(event) => handlePrefixChange('title', event)} />
|
||||
<input id="title-name" placeholder="name" className="outline-none placeholder-gray-700 w-1/2 sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.title} onChange={(event) => handleDataChange('title', event)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Title;
|
||||
Title.propTypes = {
|
||||
prefix: PropTypes.object.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
handlePrefixChange: PropTypes.func.isRequired,
|
||||
handleDataChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,189 +0,0 @@
|
||||
import React from "react"
|
||||
|
||||
const Work = props => {
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Work
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="currentWork-prefix"
|
||||
placeholder="Hi, I'm "
|
||||
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.currentWork}
|
||||
onChange={event => props.handlePrefixChange("currentWork", event)}
|
||||
/>
|
||||
<input
|
||||
id="currentWork"
|
||||
placeholder="project name"
|
||||
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.currentWork}
|
||||
onChange={event => props.handleDataChange("currentWork", event)}
|
||||
/>
|
||||
<input
|
||||
id="currentWork-link"
|
||||
placeholder="project link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.currentWork}
|
||||
onChange={event => props.handleLinkChange("currentWork", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="collaborateOn-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.collaborateOn}
|
||||
onChange={event => props.handlePrefixChange("collaborateOn", event)}
|
||||
/>
|
||||
<input
|
||||
id="collaborateOn"
|
||||
placeholder="project name"
|
||||
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.collaborateOn}
|
||||
onChange={event => props.handleDataChange("collaborateOn", event)}
|
||||
/>
|
||||
<input
|
||||
id="collaborateOn-link"
|
||||
placeholder="project link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.collaborateOn}
|
||||
onChange={event => props.handleLinkChange("collaborateOn", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="helpWith-prefix"
|
||||
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.helpWith}
|
||||
onChange={event => props.handlePrefixChange("helpWith", event)}
|
||||
/>
|
||||
<input
|
||||
id="helpWith"
|
||||
placeholder="project name"
|
||||
className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.helpWith}
|
||||
onChange={event => props.handleDataChange("helpWith", event)}
|
||||
/>
|
||||
<input
|
||||
id="helpWith-link"
|
||||
placeholder="project link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.helpWith}
|
||||
onChange={event => props.handleLinkChange("helpWith", event)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="currentLearn-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.currentLearn}
|
||||
onChange={event => props.handlePrefixChange("currentLearn", event)}
|
||||
/>
|
||||
<input
|
||||
id="currentLearn"
|
||||
placeholder="Frameworks, courses etc."
|
||||
className="outline-none placeholder-gray-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.currentLearn}
|
||||
onChange={event => props.handleDataChange("currentLearn", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="ama-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.ama}
|
||||
onChange={event => props.handlePrefixChange("ama", event)}
|
||||
/>
|
||||
<input
|
||||
id="ama"
|
||||
placeholder="react, vue and gsap"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.ama}
|
||||
onChange={event => props.handleDataChange("ama", event)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="contact-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.contact}
|
||||
onChange={event => props.handlePrefixChange("contact", event)}
|
||||
/>
|
||||
<input
|
||||
id="contact"
|
||||
placeholder="example@gmail.com"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.contact}
|
||||
onChange={event => props.handleDataChange("contact", event)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="portfolio-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.portfolio}
|
||||
onChange={event => props.handlePrefixChange("portfolio", event)}
|
||||
/>
|
||||
<input
|
||||
id="portfolio"
|
||||
placeholder="portfolio link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.portfolio}
|
||||
onChange={event => props.handleLinkChange("portfolio", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="blog-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.blog}
|
||||
onChange={event => props.handlePrefixChange("blog", event)}
|
||||
/>
|
||||
<input
|
||||
id="blog"
|
||||
placeholder="blog link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.blog}
|
||||
onChange={event => props.handleLinkChange("blog", event)}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="resume-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.resume}
|
||||
onChange={event => props.handlePrefixChange("resume", event)}
|
||||
/>
|
||||
<input
|
||||
id="resume"
|
||||
placeholder="resume link"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.link.resume}
|
||||
onChange={event => props.handleLinkChange("resume", event)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input
|
||||
id="funFact-prefix"
|
||||
className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.prefix.funFact}
|
||||
onChange={event => props.handlePrefixChange("funFact", event)}
|
||||
/>
|
||||
<input
|
||||
id="funFact"
|
||||
placeholder="I think I am funny"
|
||||
className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700"
|
||||
value={props.data.funFact}
|
||||
onChange={event => props.handleDataChange("funFact", event)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Work
|
||||
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Work = (props) => {
|
||||
const { prefix, handlePrefixChange, data, handleDataChange, link, handleLinkChange } = props;
|
||||
return (
|
||||
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
|
||||
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">Work</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="currentWork-prefix" placeholder="Hi, I'm " className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.currentWork} onChange={(event) => handlePrefixChange('currentWork', event)} />
|
||||
<input id="currentWork" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.currentWork} onChange={(event) => handleDataChange('currentWork', event)} />
|
||||
<input id="currentWork-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.currentWork} onChange={(event) => handleLinkChange('currentWork', event)} />
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="collaborateOn-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.collaborateOn} onChange={(event) => handlePrefixChange('collaborateOn', event)} />
|
||||
<input id="collaborateOn" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.collaborateOn} onChange={(event) => handleDataChange('collaborateOn', event)} />
|
||||
<input id="collaborateOn-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.collaborateOn} onChange={(event) => handleLinkChange('collaborateOn', event)} />
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="helpWith-prefix" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.helpWith} onChange={(event) => handlePrefixChange('helpWith', event)} />
|
||||
<input id="helpWith" placeholder="project name" className="outline-none placeholder-gray-700 mr-8 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.helpWith} onChange={(event) => handleDataChange('helpWith', event)} />
|
||||
<input id="helpWith-link" placeholder="project link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/4 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.helpWith} onChange={(event) => handleLinkChange('helpWith', event)} />
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="currentLearn-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.currentLearn} onChange={(event) => handlePrefixChange('currentLearn', event)} />
|
||||
<input id="currentLearn" placeholder="Frameworks, courses etc." className="outline-none placeholder-gray-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.currentLearn} onChange={(event) => handleDataChange('currentLearn', event)} />
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="ama-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.ama} onChange={(event) => handlePrefixChange('ama', event)} />
|
||||
<input id="ama" placeholder="react, vue and gsap" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.ama} onChange={(event) => handleDataChange('ama', event)} />
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="contact-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.contact} onChange={(event) => handlePrefixChange('contact', event)} />
|
||||
<input id="contact" placeholder="example@gmail.com" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.contact} onChange={(event) => handleDataChange('contact', event)} />
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="portfolio-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.portfolio} onChange={(event) => handlePrefixChange('portfolio', event)} />
|
||||
<input id="portfolio" placeholder="portfolio link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.portfolio} onChange={(event) => handleLinkChange('portfolio', event)} />
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="blog-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.blog} onChange={(event) => handlePrefixChange('blog', event)} />
|
||||
<input id="blog" placeholder="blog link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.blog} onChange={(event) => handleLinkChange('blog', event)} />
|
||||
</div>
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="resume-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.resume} onChange={(event) => handlePrefixChange('resume', event)} />
|
||||
<input id="resume" placeholder="resume link" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 text-blue-700 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={link.resume} onChange={(event) => handleLinkChange('resume', event)} />
|
||||
</div>
|
||||
|
||||
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
|
||||
<input id="funFact-prefix" className="outline-none mr-8 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={prefix.funFact} onChange={(event) => handlePrefixChange('funFact', event)} />
|
||||
<input id="funFact" placeholder="I think I am funny" className="outline-none placeholder-gray-700 mr-8 sm:mr-0 w-full sm:w-1/3 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700" value={data.funFact} onChange={(event) => handleDataChange('funFact', event)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Work;
|
||||
Work.propTypes = {
|
||||
prefix: PropTypes.object.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
link: PropTypes.object.isRequired,
|
||||
handlePrefixChange: PropTypes.func.isRequired,
|
||||
handleDataChange: PropTypes.func.isRequired,
|
||||
handleLinkChange: PropTypes.func.isRequired,
|
||||
};
|
||||
@@ -1,97 +1,97 @@
|
||||
export const DEFAULT_PREFIX = {
|
||||
title: "Hi 👋, I'm",
|
||||
currentWork: "🔭 I’m currently working on",
|
||||
currentLearn: "🌱 I’m currently learning",
|
||||
collaborateOn: "👯 I’m looking to collaborate on",
|
||||
helpWith: "🤝 I’m looking for help with",
|
||||
ama: "💬 Ask me about",
|
||||
contact: "📫 How to reach me",
|
||||
resume: "📄 Know about my experiences",
|
||||
funFact: "⚡ Fun fact",
|
||||
portfolio: "👨💻 All of my projects are available at",
|
||||
blog: "📝 I regularly write articles on",
|
||||
}
|
||||
currentWork: '🔭 I’m currently working on',
|
||||
currentLearn: '🌱 I’m currently learning',
|
||||
collaborateOn: '👯 I’m looking to collaborate on',
|
||||
helpWith: '🤝 I’m looking for help with',
|
||||
ama: '💬 Ask me about',
|
||||
contact: '📫 How to reach me',
|
||||
resume: '📄 Know about my experiences',
|
||||
funFact: '⚡ Fun fact',
|
||||
portfolio: '👨💻 All of my projects are available at',
|
||||
blog: '📝 I regularly write articles on',
|
||||
};
|
||||
|
||||
export const DEFAULT_DATA = {
|
||||
title: "",
|
||||
subtitle: "A passionate frontend developer from India",
|
||||
currentWork: "",
|
||||
currentLearn: "",
|
||||
collaborateOn: "",
|
||||
helpWith: "",
|
||||
ama: "",
|
||||
contact: "",
|
||||
funFact: "",
|
||||
title: '',
|
||||
subtitle: 'A passionate frontend developer from India',
|
||||
currentWork: '',
|
||||
currentLearn: '',
|
||||
collaborateOn: '',
|
||||
helpWith: '',
|
||||
ama: '',
|
||||
contact: '',
|
||||
funFact: '',
|
||||
twitterBadge: false,
|
||||
visitorsBadge: false,
|
||||
badgeStyle: "flat",
|
||||
badgeColor: "0e75b6",
|
||||
badgeLabel: "Profile views",
|
||||
badgeStyle: 'flat',
|
||||
badgeColor: '0e75b6',
|
||||
badgeLabel: 'Profile views',
|
||||
githubProfileTrophy: false,
|
||||
githubStats: false,
|
||||
githubStatsOptions: {
|
||||
theme: "",
|
||||
titleColor: "",
|
||||
textColor: "",
|
||||
bgColor: "",
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: "en",
|
||||
locale: 'en',
|
||||
},
|
||||
topLanguages: false,
|
||||
topLanguagesOptions: {
|
||||
theme: "",
|
||||
titleColor: "",
|
||||
textColor: "",
|
||||
bgColor: "",
|
||||
theme: '',
|
||||
titleColor: '',
|
||||
textColor: '',
|
||||
bgColor: '',
|
||||
hideBorder: false,
|
||||
cacheSeconds: null,
|
||||
locale: "en",
|
||||
locale: 'en',
|
||||
},
|
||||
streakStats: false,
|
||||
streakStatsOptions: {
|
||||
theme: "",
|
||||
theme: '',
|
||||
},
|
||||
devDynamicBlogs: false,
|
||||
mediumDynamicBlogs: false,
|
||||
rssDynamicBlogs: false,
|
||||
}
|
||||
};
|
||||
|
||||
export const DEFAULT_LINK = {
|
||||
currentWork: "",
|
||||
collaborateOn: "",
|
||||
helpWith: "",
|
||||
portfolio: "",
|
||||
blog: "",
|
||||
resume: "",
|
||||
}
|
||||
currentWork: '',
|
||||
collaborateOn: '',
|
||||
helpWith: '',
|
||||
portfolio: '',
|
||||
blog: '',
|
||||
resume: '',
|
||||
};
|
||||
|
||||
export const DEFAULT_SOCIAL = {
|
||||
github: "",
|
||||
dev: "",
|
||||
linkedin: "",
|
||||
codepen: "",
|
||||
stackoverflow: "",
|
||||
kaggle: "",
|
||||
codesandbox: "",
|
||||
fb: "",
|
||||
instagram: "",
|
||||
twitter: "",
|
||||
dribbble: "",
|
||||
behance: "",
|
||||
medium: "",
|
||||
youtube: "",
|
||||
codechef: "",
|
||||
hackerrank: "",
|
||||
codeforces: "",
|
||||
leetcode: "",
|
||||
topcoder: "",
|
||||
hackerearth: "",
|
||||
geeks_for_geeks: "",
|
||||
discord: "",
|
||||
rssurl: "",
|
||||
}
|
||||
github: '',
|
||||
dev: '',
|
||||
linkedin: '',
|
||||
codepen: '',
|
||||
stackoverflow: '',
|
||||
kaggle: '',
|
||||
codesandbox: '',
|
||||
fb: '',
|
||||
instagram: '',
|
||||
twitter: '',
|
||||
dribbble: '',
|
||||
behance: '',
|
||||
medium: '',
|
||||
youtube: '',
|
||||
codechef: '',
|
||||
hackerrank: '',
|
||||
codeforces: '',
|
||||
leetcode: '',
|
||||
topcoder: '',
|
||||
hackerearth: '',
|
||||
geeks_for_geeks: '',
|
||||
discord: '',
|
||||
rssurl: '',
|
||||
};
|
||||
|
||||
export const DEFAULT_SUPPORT = {
|
||||
buyMeACoffee: ""
|
||||
}
|
||||
buyMeACoffee: '',
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const links = {
|
||||
home: "/",
|
||||
about: "/about",
|
||||
addons: "/addons",
|
||||
support: "/support",
|
||||
}
|
||||
export default links
|
||||
home: '/',
|
||||
about: '/about',
|
||||
addons: '/addons',
|
||||
support: '/support',
|
||||
};
|
||||
export default links;
|
||||
|
||||
|
Before Width: | Height: | Size: 395 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 968 KiB |
@@ -1,47 +0,0 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default function HTML(props) {
|
||||
return (
|
||||
<html {...props.htmlAttributes}>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
{props.headComponents}
|
||||
<script
|
||||
data-name="BMC-Widget"
|
||||
src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js"
|
||||
data-id="rahuldkjain"
|
||||
data-description="Support me on Buy me a coffee!"
|
||||
data-message="Loved the tool🚀. Buy me a coffee to support the work!"
|
||||
data-color="#FF813F"
|
||||
data-position=""
|
||||
data-x_margin="18"
|
||||
data-y_margin="18"
|
||||
></script>
|
||||
</head>
|
||||
<body {...props.bodyAttributes}>
|
||||
{props.preBodyComponents}
|
||||
<div
|
||||
key={`body`}
|
||||
id="___gatsby"
|
||||
dangerouslySetInnerHTML={{ __html: props.body }}
|
||||
/>
|
||||
{props.postBodyComponents}
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
HTML.propTypes = {
|
||||
htmlAttributes: PropTypes.object,
|
||||
headComponents: PropTypes.array,
|
||||
bodyAttributes: PropTypes.object,
|
||||
preBodyComponents: PropTypes.array,
|
||||
body: PropTypes.string,
|
||||
postBodyComponents: PropTypes.array,
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable react/jsx-props-no-spreading */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default function HTML(props) {
|
||||
const { htmlAttributes, headComponents, bodyAttributes, preBodyComponents, postBodyComponents, body } = props;
|
||||
return (
|
||||
<html {...htmlAttributes} lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
{headComponents}
|
||||
<script data-name="BMC-Widget" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="rahuldkjain" data-description="Support me on Buy me a coffee!" data-message="Loved the tool🚀. Buy me a coffee to support the work!" data-color="#FF813F" data-position="" data-x_margin="18" data-y_margin="18" />
|
||||
</head>
|
||||
<body {...bodyAttributes}>
|
||||
{preBodyComponents}
|
||||
<div key="body" id="___gatsby" dangerouslySetInnerHTML={{ __html: body }} />
|
||||
{postBodyComponents}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
HTML.propTypes = {
|
||||
htmlAttributes: PropTypes.object.isRequired,
|
||||
headComponents: PropTypes.array.isRequired,
|
||||
bodyAttributes: PropTypes.object.isRequired,
|
||||
preBodyComponents: PropTypes.array.isRequired,
|
||||
body: PropTypes.string.isRequired,
|
||||
postBodyComponents: PropTypes.array.isRequired,
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 12" style="enable-background:new 0 0 24 12;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FF4A00;}
|
||||
</style>
|
||||
<path d="M.837 2.756h6.488v4.062H.837z" fill="#09f"/><path d="M.837 6.818H4.9v2.427H.837z" fill="#f1422a"/><path d="M4.9 6.818h2.427v2.427H4.9z" fill="#333"/><path d="M8.168 3.96h1.298v4.08H8.168zm7.418 0H13.36v1.298h.927V8.04h1.298V5.258h.927V3.96zm3.524 0h-2.226v1.298h.927V8.04H19.1V5.258h.927V3.96zm3.524 0h-2.226v1.298h.927V8.04h1.298V5.258h.927V3.96zM13 5.258V3.96h-2.967v4.08h1.298V6.927h1.113V5.63H11.32v-.37z" fill="#09f"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 839 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#DF234F" d="M75.4.3c-.9 0-1.8.2-2.6.5 1.7 1.1 2.6 2.6 3.1 4.3 0 .2.1.4.1.6 0 .2.1.4.1.6.1 2.9-.8 3.3-1.4 5-1 2.2-.7 4.6.5 6.5.1.2.2.5.4.7-1.3-8.4 5.7-9.6 7-12.2.1-2.3-1.8-3.8-3.3-4.9C77.8.5 76.6.3 75.4.3zm10.5 1.8c-.1.8 0 .6-.1 1 0 .3 0 .6-.1.9-.1.3-.1.5-.2.8-.1.3-.2.5-.3.8-.1.2-.2.4-.3.7-.1.1-.2.3-.3.4-.1.1-.1.2-.2.3-.2.2-.3.5-.5.7l-.6.6c-.2.2-.4.4-.6.5-.7.5-1.5.9-2.2 1.4-.2.2-.5.3-.7.5-.2.2-.4.3-.6.5l-.6.6c-.2.2-.4.4-.5.7-.2.2-.3.5-.5.7-.1.3-.2.5-.4.8-.1.3-.2.5-.3.8-.1.3-.2.6-.2.8 0 .1 0 .3-.1.4 0 .1 0 .3-.1.4v1.4c0 .3 0 .5.1.8 0 .3.1.5.2.8.1.3.2.5.3.8.1.2.2.3.2.5l-7.6-2.9c-1.3-.4-2.5-.7-3.8-1-.7-.2-1.4-.3-2.1-.5-2-.4-4-.7-6-.9h-.2c-2-.2-3.9-.3-5.9-.3-1.5 0-2.9.1-4.3.2-2 .1-4 .4-6 .7l-1.5.3c-1 .2-2 .4-3 .7-.5.1-1 .3-1.5.4-.5.2-1 .4-1.4.6-.4.2-.7.3-1.1.5-.1 0-.1 0-.2.1-.3.2-.6.3-.9.5-.1 0-.2.1-.2.1-.4.2-.7.4-1 .5-.2.1-.5.2-.7.3-.1.1-.2.1-.3.2-.3.2-.6.3-.9.5-.3.2-.6.3-.8.5-.2.2-.5.3-.7.5 0 0-.1 0-.1.1-.2.1-.4.3-.6.5l-.1.1c-.2.1-.3.3-.5.4-.1 0-.1.1-.2.1-.2.1-.3.3-.5.4 0 .1-.1.1-.1.1l-.6.6-.1.1-.6.6s0 .1-.1.1l-.5.5c-.1.1-.2.1-.2.2l-.6.6c0 .1-.1.1-.1.2l-.8.8-.1.1c-.5.6-1.1 1.1-1.7 1.6-.6.5-1.2 1-1.9 1.5s-1.3.9-2 1.3-1.4.7-2.1 1c-.7.3-1.4.6-2.1.8-1.4.3-2.8.9-4 1 0-.5-.3-.4-.6-.4-.3.1-.6.1-.8.2-.3.1-.5.2-.8.3-.3.1-.5.2-.8.4-.2.2-.5.3-.7.5-.2.2-.5.4-.7.6-.2.2-.5.4-.7.6-.2.2-.4.4-.6.7-.2.3-.4.5-.5.8-.2.2-.3.5-.5.8-.1.3-.3.6-.4.9l-.3.9c-.1.3-.1.5-.2.8v.1c-.1.3-.1.7-.1.9.1-.1.1.1.1.3v.4c0 .2.1.4.1.6.1.2.1.4.2.6.1.2.2.4.4.6.1.2.3.4.4.6.2.2.4.4.6.5.2.2.4.4.6.5.8.7 1 .9 2 1.5.2.1.3.2.5.3h.1v.2c0 .3.1.5.2.8.1.3.2.6.3.8l.3.6c0 .1.1.1.1.2.1.3.3.5.4.7.2.2.3.5.5.7l.6.6.6.6H8c.2.2.4.3.6.5.2.2.5.3.7.4.2.1.5.3.8.4.2.1.4.2.7.2 0 0 .1 0 .1.1.1 0 .3.1.4.1-.1 1.8-.1 3.5.1 4.1.3.7 1.8-1.4 3.2-3.7-.2 2.3-.3 5 0 5.8.4.8 2.3-1.8 4.1-4.6 23.4-5.4 44.8 10.8 47.1 33.7-.4-3.6-4.8-5.6-6.9-5.1-1 2.4-2.7 5.6-5.4 7.5.2-2.2.1-4.4-.3-6.6-.7 3-2.1 5.9-4.1 8.3-3.1.2-6.3-1.3-7.9-3.6-.1-.1-.2-.3-.3-.4-.1-.2-.2-.5-.3-.7-.1-.2-.2-.5-.2-.7v-.7-.5c0-.2.1-.5.2-.7.1-.2.1-.5.2-.7.1-.2.2-.5.4-.7.6-1.6.6-2.9-.5-3.6l-.6-.3c-.1 0-.3-.1-.4-.1-.1 0-.2-.1-.3-.1-.2-.1-.5-.1-.7-.2-.2-.1-.5-.1-.7-.1-.2 0-.5-.1-.7-.1h-.5c-.3 0-.5 0-.7.1-.2 0-.5.1-.7.1-.2.1-.5.1-.7.2-.2.1-.4.2-.7.3l-.6.3c-7.7 5-3.1 16.8 2.1 20.2-2 .4-4 .8-4.6 1.2l-.1.1c1.4.9 2.9 1.6 4.5 2.2 2.1.7 4.4 1.3 5.4 1.6 2.7.6 5.5.8 8.3.6 14.6-1 26.6-12.2 28.8-26.8.1.3.1.6.2.9.1.6.2 1.2.3 1.9.1.3.1.6.1.9v.1c0 .3.1.6.1.9 0 .4.1.7.1 1.1V91.6c0 .3-.1.5-.1.8v.3c0 .3-.1.6-.1 1-.1.3-.1.6-.2.9v.1c-.1.3-.1.6-.2.9v.1c-.1.3-.1.6-.2.9v.1l-.3.9v.1c-.1.3-.2.7-.3 1-.1.3-.2.6-.4 1-.1.3-.2.7-.4 1-.1.3-.3.6-.4 1-.1.3-.3.6-.4.9 0 .1-.1.2-.1.2s0 .1-.1.1c-2.1 4.3-5.3 8.1-9.3 11.1-.3.2-.5.4-.8.6-.1.1-.2.1-.2.2-.2.2-.5.3-.7.5l.1.2c.5-.1.9-.1 1.4-.2.9-.1 1.7-.3 2.6-.5.2 0 .5-.1.7-.2.2 0 .3-.1.5-.1s.5-.1.7-.1c.2-.1.4-.1.6-.2 3.3-.8 6.5-1.9 9.6-3.2-5.3 7.2-12.3 13-20.5 16.8 3.8-.3 7.6-.9 11.3-2 13.3-3.9 24.5-12.9 31.2-25-1.4 7.6-4.4 14.9-8.9 21.3 3.2-2.1 6.1-4.6 8.8-7.3 7.4-7.7 12.3-17.6 13.9-28.1 1.1 5.2 1.5 10.6 1 15.9 23.9-33.3 2-67.8-7.2-76.9 0-.1-.1-.1-.1-.2v0c0 .4 0 .8-.1 1.2-.1.8-.2 1.5-.3 2.2-.2.7-.4 1.5-.6 2.2-.2.7-.5 1.4-.8 2.1-.3.7-.6 1.4-1 2-.4.6-.8 1.3-1.2 1.9-.4.6-.9 1.2-1.4 1.8-.5.6-1 1.1-1.6 1.7-.3.3-.6.6-1 .8-.3.2-.5.4-.8.7-.6.5-1.2.9-1.9 1.3-.6.4-1.3.8-2 1.1l-2.1.9c-.7.3-1.4.5-2.1.7-.7.2-1.5.4-2.2.5-.8.1-1.5.2-2.2.3-.5 0-1.1.1-1.6.1-.8 0-1.5-.1-2.2-.1-.8-.1-1.5-.2-2.2-.3-.8-.1-1.5-.3-2.2-.6.7-.1 1.5-.1 2.2-.3.8-.1 1.5-.3 2.2-.5.7-.2 1.5-.4 2.1-.7l2.1-.9c.7-.3 1.3-.7 2-1.1.6-.4 1.3-.9 1.9-1.3.6-.5 1.2-1 1.7-1.5.6-.5 1.1-1.1 1.6-1.6.5-.6 1-1.2 1.4-1.8.1-.1.1-.2.2-.3.3-.5.7-1.1 1-1.6.4-.7.7-1.3 1-2 .3-.7.6-1.4.8-2.1l.6-2.1c.1-.8.3-1.5.3-2.2.1-.8.1-1.5.1-2.2 0-.5 0-1.1-.1-1.6-.1-.8-.2-1.5-.3-2.2-.1-.8-.3-1.5-.5-2.2-.2-.7-.5-1.4-.7-2.1-.3-.7-.6-1.4-.9-2-.4-.7-.7-1.3-1.1-2-.4-.6-.9-1.2-1.3-1.8-.5-.6-1-1.1-1.5-1.7-.3-.3-.6-.6-.9-.8-1.5-1.2-3-2.2-4.6-3.2-.2-.1-.4-.2-.7-.3-1.3-1.1-2.3-1.4-3.3-1.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 235 234" xmlns="http://www.w3.org/2000/svg" class="rainbow-logo" preserveAspectRatio="xMinYMin meet"><g fill="none" fill-rule="evenodd"><path fill="#88AEDC" d="m234.04 175.67-75.69 58.28h47.18L234.04 212z"/><path d="m234.04 140.06-121.93 93.89h.02l121.91-93.87zM133.25.95.04 103.51v.02L133.27.95z"/><path fill="#F58F8E" fill-rule="nonzero" d="M.04.95v30.16L39.21.95z"/><path fill="#FEE18A" fill-rule="nonzero" d="M39.21.95.04 31.11v35.9L85.84.95z"/><path fill="#F3F095" fill-rule="nonzero" d="M85.84.95.04 67.01v36.5L133.25.95z"/><path fill="#55C1AE" fill-rule="nonzero" d="M133.27.95.04 103.53v35.59L179.49.95z"/><path fill="#F7B3CE" fill-rule="nonzero" d="M234.04.95h-7.37L.04 175.45v35.93l234-180.18z"/><path fill="#88AEDC" fill-rule="nonzero" d="M179.49.95.04 139.12v36.33L226.67.95z"/><path fill="#F58F8E" fill-rule="nonzero" d="M234.04 31.2.04 211.38v22.57h18.03l215.97-166.3z"/><path fill="#FEE18A" fill-rule="nonzero" d="M234.04 67.65 18.07 233.95H64.7l169.34-130.39z"/><path fill="#F3F095" fill-rule="nonzero" d="M234.04 103.56 64.7 233.95h47.41l121.93-93.89z"/><path fill="#55C1AE" fill-rule="nonzero" d="m234.04 140.08-121.91 93.87h46.22l75.69-58.28z"/><path fill="#F7B3CE" fill-rule="nonzero" d="m234.04 212-28.51 21.95h28.51z"/><g fill="#FFF"><path d="M65.2372 77.75c4.5139.95 7.774 2.8 11.1343 6.3 3.0595 3.2 4.9653 6.85 5.7678 10.95.652 3.45.652 40.55 0 44.05-1.7052 9.1-9.4792 16.2-19.109 17.45-2.0062.25-8.7269.5-14.8458.5H37V77h12.4384c8.8272 0 13.3412.2 15.7988.75ZM51.5449 117v25.6l5.166-.2c4.4637-.15 5.4167-.35 7.4228-1.5 3.9121-2.3 3.9623-2.45 3.9623-24.2 0-21.2 0-21.2-3.6613-23.6-1.8056-1.2-2.558-1.35-7.473-1.55l-5.4168-.15V117ZM130.7895 84.25v7.25h-25.579v18h15.548V124h-15.548l.1003 9.1.1505 9.15 12.6892.15 12.639.1V157h-14.7957c-16.4508 0-19.0087-.3-21.6167-2.6-3.6613-3.2-3.4607-1.15-3.6112-36.3-.1003-21.9.0502-32.25.4013-33.65.7021-2.6 3.6613-5.8 6.2693-6.7 1.5548-.55 5.467-.7 17.7047-.75h15.6483v7.25ZM162.4372 105.1c3.7114 14.25 6.821 25.6 6.9213 25.25.1505-.35 3.3102-12.4 7.0718-26.85l6.8712-26.25 7.8242-.15c5.9183-.1 7.8743.05 7.8743.5s-17.3536 66.2-18.3567 69.5c-.7021 2.3-4.4637 7-6.5702 8.25-2.6582 1.5-6.5703 1.75-8.9777.5-2.1567-1.1-5.0155-4.4-6.47-7.5-.9028-1.9-15.6483-56-19.0588-70l-.3511-1.35h7.8241c7.6737 0 7.8743 0 8.2756 1.1.2006.65 3.4105 12.8 7.122 27Z"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
@@ -1,7 +1,7 @@
|
||||
---
|
||||
slug: "/about"
|
||||
date: "2019-05-04"
|
||||
title: "👨💻 About"
|
||||
slug: '/about'
|
||||
date: '2019-05-04'
|
||||
title: '👨💻 About'
|
||||
---
|
||||
|
||||
<a href="https://github.com/rahuldkjain/github-profile-readme-generator/blob/master/LICENSE" target="blank">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
slug: "/addons"
|
||||
date: "2019-05-04"
|
||||
title: "🚀 Addons"
|
||||
slug: '/addons'
|
||||
date: '2019-05-04'
|
||||
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.
|
||||
@@ -80,7 +80,7 @@ name: Latest blog post workflow
|
||||
on:
|
||||
schedule:
|
||||
# Runs every hour
|
||||
- cron: "0 * * * *"
|
||||
- cron: '0 * * * *'
|
||||
jobs:
|
||||
update-readme-with-blog:
|
||||
name: Update this repo's README with latest blog posts
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gautamkrishnar/blog-post-workflow@master
|
||||
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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
slug: "/support"
|
||||
date: "2019-05-04"
|
||||
title: "💵 Support OSS"
|
||||
slug: '/support'
|
||||
date: '2019-05-04'
|
||||
title: '💵 Support OSS'
|
||||
---
|
||||
|
||||
> Think of giving not as a duty but as a privilege --John D. Rockefeller Hr.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react"
|
||||
import SEO from "../components/seo"
|
||||
import React from 'react';
|
||||
import SEO from '../components/seo';
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<div>
|
||||
@@ -7,6 +7,6 @@ const NotFoundPage = () => (
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
export default NotFoundPage
|
||||
export default NotFoundPage;
|
||||
@@ -1,5 +1,6 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=Lato&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400&display=swap");
|
||||
|
||||
:root {
|
||||
--grey-05: #f5f6f7;
|
||||
--grey-10: #dfdfe2;
|
||||
@@ -25,12 +26,46 @@ body {
|
||||
color: var(--grey-90);
|
||||
}
|
||||
|
||||
[type="checkbox"] {
|
||||
-webkit-box-shadow: 0 1px 1px var(--grey-90) !important;
|
||||
-moz-box-shadow: 0 1px 1px var(--grey-90) !important;
|
||||
box-shadow: 0 1px 1px var(--grey-90) !important;
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
cursor: pointer;
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
.checkbox-label:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
.checkbox-label__input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
.checkbox-label__control {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
background-color: #f7fafc;
|
||||
border: 2px solid var(--grey-90);
|
||||
transform: scale(0.75);
|
||||
}
|
||||
.checkbox-label__input:checked + .checkbox-label__control:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: "";
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--dark-purple);
|
||||
}
|
||||
.checkbox-label__input:hover + .checkbox-label__control,
|
||||
.checkbox-label__input:focus + .checkbox-label__control {
|
||||
box-shadow: 0 0 0 10px rgba(10, 10, 35, .1);
|
||||
}
|
||||
|
||||
.section {
|
||||
@@ -79,11 +114,6 @@ a {
|
||||
padding: 2% 5%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.skillCheckboxLabel:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.tooltiptext::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
@@ -95,6 +125,7 @@ a {
|
||||
border-style: solid;
|
||||
border-color: transparent var(--grey-90) transparent transparent;
|
||||
}
|
||||
|
||||
.workflow {
|
||||
margin-left: 2%;
|
||||
padding: 1%;
|
||||
@@ -120,9 +151,11 @@ a {
|
||||
.tooltiptext {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.warning {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.workflow {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@@ -1,695 +0,0 @@
|
||||
import React, { useState, useEffect } from "react"
|
||||
import gsap from "gsap"
|
||||
import MarkdownPreview from "../components/markdownPreview"
|
||||
import Markdown from "../components/markdown"
|
||||
import Title from "../components/title"
|
||||
import Subtitle from "../components/subtitle"
|
||||
import Work from "../components/work"
|
||||
import Social from "../components/social"
|
||||
import Addons from "../components/addons"
|
||||
import Skills from "../components/skills"
|
||||
import Donate from "../components/donate"
|
||||
import Support from "../components/support"
|
||||
import { initialSkillState } from "../constants/skills"
|
||||
import Loader from "../components/loader"
|
||||
import SEO from "../components/seo"
|
||||
import Layout from "../components/layout"
|
||||
import "./index.css"
|
||||
import {
|
||||
ArrowLeftIcon,
|
||||
CopyIcon,
|
||||
DownloadIcon,
|
||||
EyeIcon,
|
||||
CheckIcon,
|
||||
MarkdownIcon,
|
||||
FileCodeIcon,
|
||||
} from "@primer/octicons-react"
|
||||
import {
|
||||
isGitHubUsernameValid,
|
||||
isMediumUsernameValid,
|
||||
isTwitterUsernameValid,
|
||||
} from "../utils/validation"
|
||||
import {
|
||||
DEFAULT_PREFIX,
|
||||
DEFAULT_DATA,
|
||||
DEFAULT_LINK,
|
||||
DEFAULT_SOCIAL,
|
||||
DEFAULT_SUPPORT,
|
||||
} from "../constants/defaults"
|
||||
|
||||
const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
|
||||
useEffect(() => {
|
||||
localStorage.setItem(
|
||||
"cache",
|
||||
JSON.stringify({
|
||||
prefix,
|
||||
data,
|
||||
link,
|
||||
social,
|
||||
skills,
|
||||
support,
|
||||
})
|
||||
)
|
||||
}, [prefix, data, link, social, skills, support])
|
||||
}
|
||||
|
||||
const DEFAULT_SKILLS = initialSkillState
|
||||
|
||||
const IndexPage = () => {
|
||||
const [prefix, setPrefix] = useState(DEFAULT_PREFIX)
|
||||
const [data, setData] = useState(DEFAULT_DATA)
|
||||
const [link, setLink] = useState(DEFAULT_LINK)
|
||||
const [social, setSocial] = useState(DEFAULT_SOCIAL)
|
||||
const [skills, setSkills] = useState(DEFAULT_SKILLS)
|
||||
const [support, setSupport] = useState(DEFAULT_SUPPORT)
|
||||
|
||||
const [restore, setRestore] = useState("")
|
||||
const [generatePreview, setGeneratePreview] = useState(false)
|
||||
const [generateMarkdown, setGenerateMarkdown] = useState(false)
|
||||
const [displayLoader, setDisplayLoader] = useState(false)
|
||||
const [showConfig, setShowConfig] = useState(true)
|
||||
const [copyObj, setcopyObj] = useState({
|
||||
isCopied: false,
|
||||
copiedText: "copy-markdown",
|
||||
})
|
||||
const [previewMarkdown, setPreviewMarkdown] = useState({
|
||||
isPreview: false,
|
||||
buttonText: "preview",
|
||||
})
|
||||
|
||||
const handleSkillsChange = field => {
|
||||
let change = { ...skills }
|
||||
change[field] = !change[field]
|
||||
setSkills(change)
|
||||
}
|
||||
|
||||
const handlePrefixChange = (field, e) => {
|
||||
let change = { ...prefix }
|
||||
change[field] = e.target.value
|
||||
setPrefix(change)
|
||||
}
|
||||
|
||||
const handleDataChange = (field, e) => {
|
||||
let change = { ...data }
|
||||
change[field] = e.target.value
|
||||
setData(change)
|
||||
}
|
||||
|
||||
const handleLinkChange = (field, e) => {
|
||||
let change = { ...link }
|
||||
change[field] = e.target.value
|
||||
setLink(change)
|
||||
}
|
||||
|
||||
const handleSocialChange = (field, e) => {
|
||||
let change = { ...social }
|
||||
change[field] =
|
||||
field === "discord" ? e.target.value : e.target.value.toLowerCase()
|
||||
setSocial(change)
|
||||
}
|
||||
|
||||
const handleSupportChange = (field, e) => {
|
||||
let change = { ...support }
|
||||
change[field] = e.target.value
|
||||
setSupport(change)
|
||||
}
|
||||
|
||||
const handleCheckChange = field => {
|
||||
let change = { ...data }
|
||||
change[field] = !change[field]
|
||||
setData(change)
|
||||
}
|
||||
|
||||
const generate = () => {
|
||||
setShowConfig(false)
|
||||
var tl = new gsap.timeline()
|
||||
tl.to(".generate", {
|
||||
scale: 0,
|
||||
duration: 0.5,
|
||||
ease: "Linear.easeNone",
|
||||
})
|
||||
tl.set("#form", { display: "none" })
|
||||
setDisplayLoader(true)
|
||||
setTimeout(() => {
|
||||
setDisplayLoader(false)
|
||||
setGenerateMarkdown(!generateMarkdown)
|
||||
gsap.fromTo(
|
||||
"#markdown-box",
|
||||
{
|
||||
scale: 0.2,
|
||||
},
|
||||
{
|
||||
scale: 1,
|
||||
duration: 0.5,
|
||||
ease: "Linear.easeNone",
|
||||
}
|
||||
)
|
||||
gsap.fromTo(
|
||||
"#support",
|
||||
{
|
||||
autoAlpha: 0,
|
||||
},
|
||||
{
|
||||
autoAlpha: 1,
|
||||
duration: 2,
|
||||
ease: "Linear.easeNone",
|
||||
}
|
||||
)
|
||||
document.body.scrollTop = 0 // For Safari
|
||||
document.documentElement.scrollTop = 0 // For Chrome, Firefox, IE and Opera
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
const trimDataValues = (item, setItem) => {
|
||||
const dataObj = { ...item }
|
||||
Object.keys(dataObj).forEach(k =>
|
||||
typeof dataObj[k] === "string" ? (dataObj[k] = dataObj[k].trim()) : null
|
||||
)
|
||||
setItem(dataObj)
|
||||
}
|
||||
|
||||
const handleGenerate = () => {
|
||||
trimDataValues(data, setData)
|
||||
trimDataValues(social, setSocial)
|
||||
trimDataValues(link, setLink)
|
||||
resetCopyMarkdownButton()
|
||||
if (
|
||||
data.visitorsBadge ||
|
||||
data.githubProfileTrophy ||
|
||||
data.githubStats ||
|
||||
data.topLanguages ||
|
||||
data.streakStats
|
||||
) {
|
||||
if (social.github && isGitHubUsernameValid(social.github)) {
|
||||
generate()
|
||||
}
|
||||
} else if (data.twitterBadge) {
|
||||
if (social.twitter && isTwitterUsernameValid(social.twitter)) {
|
||||
generate()
|
||||
}
|
||||
} else if (social.github) {
|
||||
if (isGitHubUsernameValid(social.github)) {
|
||||
generate()
|
||||
}
|
||||
} else {
|
||||
generate()
|
||||
}
|
||||
}
|
||||
|
||||
const handleGeneratePreview = () => {
|
||||
setGenerateMarkdown(!generateMarkdown)
|
||||
setGeneratePreview(!generatePreview)
|
||||
if (!generatePreview) {
|
||||
gsap.set("#copy-button, #download-md-button, #download-json-button", {
|
||||
visibility: "hidden",
|
||||
})
|
||||
setPreviewMarkdown({
|
||||
isPreview: true,
|
||||
buttonText: "markdown",
|
||||
})
|
||||
} else {
|
||||
gsap.set("#copy-button, #download-md-button, #download-json-button", {
|
||||
visibility: "visible",
|
||||
})
|
||||
gsap.to("#copy-button", {
|
||||
border: "2px solid #3b3b4f",
|
||||
duration: 1,
|
||||
})
|
||||
setPreviewMarkdown({
|
||||
isPreview: false,
|
||||
buttonText: "preview",
|
||||
})
|
||||
resetCopyMarkdownButton()
|
||||
}
|
||||
}
|
||||
|
||||
const resetCopyMarkdownButton = () => {
|
||||
var el = document.getElementById("copy-markdown")
|
||||
if (el) {
|
||||
gsap.set("#copy-markdown", {
|
||||
color: "#0a0a23",
|
||||
})
|
||||
}
|
||||
setcopyObj({
|
||||
isCopied: false,
|
||||
copiedText: "copy-markdown",
|
||||
})
|
||||
}
|
||||
|
||||
const setCopyMarkdownButton = () => {
|
||||
var el = document.getElementById("copy-markdown")
|
||||
if (el) {
|
||||
gsap.set("#copy-markdown", {
|
||||
color: "#00471b",
|
||||
})
|
||||
}
|
||||
gsap.fromTo(
|
||||
"#copy-button",
|
||||
{
|
||||
scale: 0.5,
|
||||
},
|
||||
{
|
||||
scale: 1,
|
||||
ease: "elastic.in",
|
||||
border: "2px solid #00471b",
|
||||
duration: 0.5,
|
||||
}
|
||||
)
|
||||
setcopyObj({
|
||||
isCopied: true,
|
||||
copiedText: "copied",
|
||||
})
|
||||
}
|
||||
|
||||
const handleCopyToClipboard = () => {
|
||||
var range = document.createRange()
|
||||
range.selectNode(document.getElementById("markdown-content"))
|
||||
window.getSelection().removeAllRanges() // clear current selection
|
||||
window.getSelection().addRange(range) // to select text
|
||||
document.execCommand("copy")
|
||||
window.getSelection().removeAllRanges()
|
||||
|
||||
setCopyMarkdownButton()
|
||||
}
|
||||
|
||||
const handleDownloadMarkdown = () => {
|
||||
var markdownContent = document.getElementById("markdown-content")
|
||||
var tempElement = document.createElement("a")
|
||||
tempElement.setAttribute(
|
||||
"href",
|
||||
"data:text/markdown;charset=utf-8," +
|
||||
encodeURIComponent(markdownContent.innerText)
|
||||
)
|
||||
tempElement.setAttribute("download", "README.md")
|
||||
tempElement.style.display = "none"
|
||||
document.body.appendChild(tempElement)
|
||||
tempElement.click()
|
||||
document.body.removeChild(tempElement)
|
||||
}
|
||||
|
||||
const handleDownloadJson = () => {
|
||||
var tempElement = document.createElement("a")
|
||||
tempElement.setAttribute(
|
||||
"href",
|
||||
`data:text/json;charset=utf-8,${encodeURIComponent(
|
||||
JSON.stringify({ prefix, data, link, social, skills })
|
||||
)}`
|
||||
)
|
||||
tempElement.setAttribute("download", "data.json")
|
||||
tempElement.style.display = "none"
|
||||
document.body.appendChild(tempElement)
|
||||
tempElement.click()
|
||||
document.body.removeChild(tempElement)
|
||||
}
|
||||
|
||||
const handleBackToEdit = () => {
|
||||
setGeneratePreview(false)
|
||||
setGenerateMarkdown(false)
|
||||
setShowConfig(true)
|
||||
gsap.set("#form", {
|
||||
display: "",
|
||||
})
|
||||
gsap.to(".generate", {
|
||||
scale: 1,
|
||||
})
|
||||
}
|
||||
|
||||
const setInitialValues = () => {
|
||||
const cache = JSON.parse(localStorage.getItem("cache"))
|
||||
|
||||
if (!cache) {
|
||||
return
|
||||
}
|
||||
|
||||
setPrefix(
|
||||
cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX
|
||||
)
|
||||
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA)
|
||||
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK)
|
||||
setSocial(
|
||||
cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL
|
||||
)
|
||||
|
||||
const cacheSkills = mergeDefaultWithNewDataSkills(
|
||||
DEFAULT_SKILLS,
|
||||
cache.skills
|
||||
)
|
||||
setSkills(cacheSkills || DEFAULT_SKILLS)
|
||||
|
||||
setSupport(
|
||||
cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
gsap.fromTo(
|
||||
".generate",
|
||||
{
|
||||
boxShadow: "0 0 0 0px rgba(59, 59, 79, 0.4)",
|
||||
},
|
||||
{
|
||||
boxShadow: "0 0 0 10px rgba(59, 59, 79, 0)",
|
||||
repeat: -1,
|
||||
duration: 1,
|
||||
}
|
||||
)
|
||||
|
||||
// set initial values
|
||||
setInitialValues()
|
||||
}, [])
|
||||
|
||||
// keep cache updated
|
||||
KeepCacheUpdated({ prefix, data, link, social, skills, support })
|
||||
|
||||
const handleResetForm = () => {
|
||||
setPrefix(DEFAULT_PREFIX)
|
||||
setData(DEFAULT_DATA)
|
||||
setLink(DEFAULT_LINK)
|
||||
setSocial(DEFAULT_SOCIAL)
|
||||
setSkills(DEFAULT_SKILLS)
|
||||
}
|
||||
|
||||
const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) => {
|
||||
return Object.keys(defaultSkills).reduce((previous, currentKey) => {
|
||||
let currentSelected = false
|
||||
|
||||
if (newSkills[currentKey]) {
|
||||
currentSelected = true
|
||||
}
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[currentKey]: currentSelected,
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
|
||||
const handleRestore = () => {
|
||||
try {
|
||||
const restoreData = JSON.parse(restore)
|
||||
|
||||
if (!restoreData) {
|
||||
return
|
||||
}
|
||||
|
||||
setPrefix(restoreData.prefix || DEFAULT_PREFIX)
|
||||
setData(restoreData.data || DEFAULT_DATA)
|
||||
setLink(restoreData.link || DEFAULT_LINK)
|
||||
setSocial(restoreData.social || DEFAULT_SOCIAL)
|
||||
|
||||
const restoreDataSkills = mergeDefaultWithNewDataSkills(
|
||||
DEFAULT_SKILLS,
|
||||
restoreData.skills
|
||||
)
|
||||
setSkills(restoreDataSkills || DEFAULT_SKILLS)
|
||||
} catch (error) {
|
||||
} finally {
|
||||
setRestore("")
|
||||
}
|
||||
}
|
||||
|
||||
const handleFileInput = e => {
|
||||
const file = e.target.files[0]
|
||||
const reader = new FileReader()
|
||||
reader.readAsText(file, "UTF-8")
|
||||
reader.onload = () => {
|
||||
setRestore(reader.result)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="m-4 sm:p-4">
|
||||
<SEO title="GitHub Profile Readme Generator" />
|
||||
<div id="form">
|
||||
<Title
|
||||
data={data}
|
||||
prefix={prefix}
|
||||
handleDataChange={handleDataChange}
|
||||
handlePrefixChange={handlePrefixChange}
|
||||
/>
|
||||
<Subtitle data={data} handleDataChange={handleDataChange} />
|
||||
<Work
|
||||
prefix={prefix}
|
||||
data={data}
|
||||
link={link}
|
||||
handlePrefixChange={handlePrefixChange}
|
||||
handleLinkChange={handleLinkChange}
|
||||
handleDataChange={handleDataChange}
|
||||
/>
|
||||
<Skills skills={skills} handleSkillsChange={handleSkillsChange} />
|
||||
<Social social={social} handleSocialChange={handleSocialChange} />
|
||||
<Addons
|
||||
data={data}
|
||||
social={social}
|
||||
handleCheckChange={handleCheckChange}
|
||||
handleDataChange={handleDataChange}
|
||||
/>
|
||||
<Support
|
||||
support={support}
|
||||
handleSupportChange={handleSupportChange}
|
||||
/>
|
||||
<div className="section">
|
||||
{(data.visitorsBadge ||
|
||||
data.githubProfileTrophy ||
|
||||
data.githubStats ||
|
||||
data.topLanguages ||
|
||||
data.streakStats) &&
|
||||
!social.github ? (
|
||||
<div className="warning">
|
||||
* Please add github username to use these add-ons
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{social.github && !isGitHubUsernameValid(social.github) ? (
|
||||
<div className="warning">
|
||||
* GitHub username is invalid, please add a valid username
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{social.medium && !isMediumUsernameValid(social.medium) ? (
|
||||
<div className="warning">
|
||||
* Medium username is invalid, please add a valid username (with
|
||||
@)
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data.mediumDynamicBlogs && !social.medium ? (
|
||||
<div className="warning">
|
||||
* Please add medium username to display latest blogs dynamically
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data.devDynamicBlogs && !social.dev ? (
|
||||
<div className="warning">
|
||||
* Please add dev.to username to display latest blogs dynamically
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data.rssDynamicBlogs && !social.rssurl ? (
|
||||
<div className="warning">
|
||||
* Please add your rss feed url to display latest blogs
|
||||
dynamically from your personal blog
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data.twitterBadge && !social.twitter ? (
|
||||
<div className="warning">
|
||||
* Please add twitter username to use these add-ons
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{social.twitter && !isTwitterUsernameValid(social.twitter) ? (
|
||||
<div className="warning">
|
||||
* Twitter username is invalid, please add a valid username
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-center w-full">
|
||||
<div
|
||||
className="text-xs sm:text-xl font-medium border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 sm:py-2 px-2 sm:px-4 generate"
|
||||
tabIndex="0"
|
||||
role="button"
|
||||
onClick={handleGenerate}
|
||||
onKeyDown={e => e.keyCode === 13 && handleGenerate()}
|
||||
>
|
||||
Generate README
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{displayLoader ? <Loader /> : ""}
|
||||
|
||||
{generateMarkdown || generatePreview ? (
|
||||
<div className="markdown-section p-4 sm:py-4 sm:px-10">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<button
|
||||
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
|
||||
onClick={handleBackToEdit}
|
||||
>
|
||||
<ArrowLeftIcon size={24} />
|
||||
<span className="hidden sm:block"> back to edit</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
|
||||
id="copy-button"
|
||||
onClick={handleCopyToClipboard}
|
||||
>
|
||||
{copyObj.isCopied === true ? (
|
||||
<CheckIcon size={24} />
|
||||
) : (
|
||||
<CopyIcon size={24} />
|
||||
)}
|
||||
<span className="hidden sm:block" id="copy-markdown">
|
||||
{copyObj.copiedText}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
|
||||
id="download-md-button"
|
||||
onClick={handleDownloadMarkdown}
|
||||
>
|
||||
<DownloadIcon size={24} />
|
||||
<span className="hidden sm:block" id="download-markdown">
|
||||
download markdown
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
|
||||
id="download-json-button"
|
||||
onClick={handleDownloadJson}
|
||||
>
|
||||
<FileCodeIcon size={24} />
|
||||
<span className="hidden sm:block" id="download-json">
|
||||
download backup
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1"
|
||||
onClick={handleGeneratePreview}
|
||||
>
|
||||
{previewMarkdown.isPreview ? (
|
||||
<MarkdownIcon size={16} />
|
||||
) : (
|
||||
<EyeIcon size={16} />
|
||||
)}
|
||||
<span className="hidden sm:block ml-1" id="preview-markdown">
|
||||
{previewMarkdown.buttonText}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex justify-center items-center">
|
||||
<div
|
||||
className="w-full text-sm text-gray-900 shadow-xl mt-2 p-4 bg-gray-100 border-2 border-solid border-gray-800"
|
||||
id="markdown-box"
|
||||
>
|
||||
{generatePreview ? (
|
||||
<MarkdownPreview
|
||||
prefix={prefix}
|
||||
data={data}
|
||||
link={link}
|
||||
social={social}
|
||||
skills={skills}
|
||||
support={support}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{generateMarkdown ? (
|
||||
<Markdown
|
||||
prefix={prefix}
|
||||
data={data}
|
||||
link={link}
|
||||
social={social}
|
||||
skills={skills}
|
||||
support={support}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10" id="support">
|
||||
<Donate />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
"w-full shadow flex flex-col justify-center items-start mt-16 border-2 border-solid border-gray-600 py-2 px-4 " +
|
||||
(!showConfig ? "hidden" : "block")
|
||||
}
|
||||
>
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Config options
|
||||
<span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1">
|
||||
new feature
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
className="text-xxs sm:text-sm border-2 w-auto px-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Reset form
|
||||
</button>
|
||||
</div>
|
||||
<div className="w-full flex justify-start items-center my-4">
|
||||
<input
|
||||
type="text"
|
||||
className="outline-none w-1/2 mr-6 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix"
|
||||
placeholder="Paste JSON code or upload file"
|
||||
value={restore}
|
||||
onChange={e => setRestore(e.target.value)}
|
||||
/>
|
||||
|
||||
<div className="overflow-hidden relative w-64 mt-4 mb-4">
|
||||
<input
|
||||
className="cursor-pointer absolute block opacity-0 pin-r pin-t before:cursor-pointer"
|
||||
type="file"
|
||||
name="vacancyImageFiles"
|
||||
onChange={handleFileInput}
|
||||
/>
|
||||
<button className="text-xxs sm:text-sm border-2 w-40 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1">
|
||||
Upload json file
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="mr-5 mb-10 text-xxs sm:text-sm border-2 w-32 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1"
|
||||
onClick={handleRestore}
|
||||
>
|
||||
Restore
|
||||
</button>
|
||||
<div className="flex flex-col items-start justify-center">
|
||||
<div className="text-green-700 font-medium">Tips</div>
|
||||
<div className="text-sm sm:text-lg text-gray-700">
|
||||
* Enter the downloaded JSON text to restore.
|
||||
</div>
|
||||
<div className="text-sm sm:text-lg text-gray-700">
|
||||
* Press reset to reset the form.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default IndexPage
|
||||
@@ -0,0 +1,494 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import gsap from 'gsap';
|
||||
import { ArrowLeftIcon, CopyIcon, DownloadIcon, EyeIcon, CheckIcon, MarkdownIcon, FileCodeIcon } from '@primer/octicons-react';
|
||||
import MarkdownPreview from '../components/markdownPreview';
|
||||
import Markdown from '../components/markdown';
|
||||
import Title from '../components/title';
|
||||
import Subtitle from '../components/subtitle';
|
||||
import Work from '../components/work';
|
||||
import Social from '../components/social';
|
||||
import Addons from '../components/addons';
|
||||
import Skills from '../components/skills';
|
||||
import Donate from '../components/donate';
|
||||
import Support from '../components/support';
|
||||
import { initialSkillState } from '../constants/skills';
|
||||
import Loader from '../components/loader';
|
||||
import SEO from '../components/seo';
|
||||
import Layout from '../components/layout';
|
||||
import './index.css';
|
||||
import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../utils/validation';
|
||||
import { DEFAULT_PREFIX, DEFAULT_DATA, DEFAULT_LINK, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
|
||||
|
||||
const KeepCacheUpdated = ({ prefix, data, link, social, skills, support }) => {
|
||||
useEffect(() => {
|
||||
localStorage.setItem(
|
||||
'cache',
|
||||
JSON.stringify({
|
||||
prefix,
|
||||
data,
|
||||
link,
|
||||
social,
|
||||
skills,
|
||||
support,
|
||||
}),
|
||||
);
|
||||
}, [prefix, data, link, social, skills, support]);
|
||||
};
|
||||
|
||||
const DEFAULT_SKILLS = initialSkillState;
|
||||
|
||||
const IndexPage = () => {
|
||||
const [prefix, setPrefix] = useState(DEFAULT_PREFIX);
|
||||
const [data, setData] = useState(DEFAULT_DATA);
|
||||
const [link, setLink] = useState(DEFAULT_LINK);
|
||||
const [social, setSocial] = useState(DEFAULT_SOCIAL);
|
||||
const [skills, setSkills] = useState(DEFAULT_SKILLS);
|
||||
const [support, setSupport] = useState(DEFAULT_SUPPORT);
|
||||
|
||||
const [restore, setRestore] = useState('');
|
||||
const [generatePreview, setGeneratePreview] = useState(false);
|
||||
const [generateMarkdown, setGenerateMarkdown] = useState(false);
|
||||
const [displayLoader, setDisplayLoader] = useState(false);
|
||||
const [showConfig, setShowConfig] = useState(true);
|
||||
const [copyObj, setcopyObj] = useState({
|
||||
isCopied: false,
|
||||
copiedText: 'copy-markdown',
|
||||
});
|
||||
const [previewMarkdown, setPreviewMarkdown] = useState({
|
||||
isPreview: false,
|
||||
buttonText: 'preview',
|
||||
});
|
||||
|
||||
const handleSkillsChange = (field) => {
|
||||
const change = { ...skills };
|
||||
change[field] = !change[field];
|
||||
setSkills(change);
|
||||
};
|
||||
|
||||
const handlePrefixChange = (field, e) => {
|
||||
const change = { ...prefix };
|
||||
change[field] = e.target.value;
|
||||
setPrefix(change);
|
||||
};
|
||||
|
||||
const handleDataChange = (field, e) => {
|
||||
const change = { ...data };
|
||||
change[field] = e.target.value;
|
||||
setData(change);
|
||||
};
|
||||
|
||||
const handleLinkChange = (field, e) => {
|
||||
const change = { ...link };
|
||||
change[field] = e.target.value;
|
||||
setLink(change);
|
||||
};
|
||||
|
||||
const handleSocialChange = (field, e) => {
|
||||
const change = { ...social };
|
||||
change[field] = field === 'discord' ? e.target.value : e.target.value.toLowerCase();
|
||||
setSocial(change);
|
||||
};
|
||||
|
||||
const handleSupportChange = (field, e) => {
|
||||
const change = { ...support };
|
||||
change[field] = e.target.value;
|
||||
setSupport(change);
|
||||
};
|
||||
|
||||
const handleCheckChange = (field) => {
|
||||
const change = { ...data };
|
||||
change[field] = !change[field];
|
||||
setData(change);
|
||||
};
|
||||
|
||||
const generate = () => {
|
||||
setShowConfig(false);
|
||||
const tl = gsap.timeline();
|
||||
tl.to('.generate', {
|
||||
scale: 0,
|
||||
duration: 0.5,
|
||||
ease: 'Linear.easeNone',
|
||||
});
|
||||
tl.set('#form', { display: 'none' });
|
||||
setDisplayLoader(true);
|
||||
setTimeout(() => {
|
||||
setDisplayLoader(false);
|
||||
setGenerateMarkdown(!generateMarkdown);
|
||||
gsap.fromTo(
|
||||
'#markdown-box',
|
||||
{
|
||||
scale: 0.2,
|
||||
},
|
||||
{
|
||||
scale: 1,
|
||||
duration: 0.5,
|
||||
ease: 'Linear.easeNone',
|
||||
},
|
||||
);
|
||||
gsap.fromTo(
|
||||
'#support',
|
||||
{
|
||||
autoAlpha: 0,
|
||||
},
|
||||
{
|
||||
autoAlpha: 1,
|
||||
duration: 2,
|
||||
ease: 'Linear.easeNone',
|
||||
},
|
||||
);
|
||||
document.body.scrollTop = 0; // For Safari
|
||||
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
const trimDataValues = (item, setItem) => {
|
||||
const dataObj = { ...item };
|
||||
Object.keys(dataObj).forEach((k) => {
|
||||
if (typeof dataObj[k] === 'string') {
|
||||
dataObj[k] = dataObj[k].trim();
|
||||
}
|
||||
});
|
||||
setItem(dataObj);
|
||||
};
|
||||
|
||||
const resetCopyMarkdownButton = () => {
|
||||
const el = document.getElementById('copy-markdown');
|
||||
if (el) {
|
||||
gsap.set('#copy-markdown', {
|
||||
color: '#0a0a23',
|
||||
});
|
||||
}
|
||||
setcopyObj({
|
||||
isCopied: false,
|
||||
copiedText: 'copy-markdown',
|
||||
});
|
||||
};
|
||||
const handleGenerate = () => {
|
||||
trimDataValues(data, setData);
|
||||
trimDataValues(social, setSocial);
|
||||
trimDataValues(link, setLink);
|
||||
resetCopyMarkdownButton();
|
||||
if (data.visitorsBadge || data.githubProfileTrophy || data.githubStats || data.topLanguages || data.streakStats) {
|
||||
if (social.github && isGitHubUsernameValid(social.github)) {
|
||||
generate();
|
||||
}
|
||||
} else if (data.twitterBadge) {
|
||||
if (social.twitter && isTwitterUsernameValid(social.twitter)) {
|
||||
generate();
|
||||
}
|
||||
} else if (social.github) {
|
||||
if (isGitHubUsernameValid(social.github)) {
|
||||
generate();
|
||||
}
|
||||
} else {
|
||||
generate();
|
||||
}
|
||||
};
|
||||
|
||||
const handleGeneratePreview = () => {
|
||||
setGenerateMarkdown(!generateMarkdown);
|
||||
setGeneratePreview(!generatePreview);
|
||||
if (!generatePreview) {
|
||||
gsap.set('#copy-button, #download-md-button, #download-json-button', {
|
||||
visibility: 'hidden',
|
||||
});
|
||||
setPreviewMarkdown({
|
||||
isPreview: true,
|
||||
buttonText: 'markdown',
|
||||
});
|
||||
} else {
|
||||
gsap.set('#copy-button, #download-md-button, #download-json-button', {
|
||||
visibility: 'visible',
|
||||
});
|
||||
gsap.to('#copy-button', {
|
||||
border: '2px solid #3b3b4f',
|
||||
duration: 1,
|
||||
});
|
||||
setPreviewMarkdown({
|
||||
isPreview: false,
|
||||
buttonText: 'preview',
|
||||
});
|
||||
resetCopyMarkdownButton();
|
||||
}
|
||||
};
|
||||
|
||||
const setCopyMarkdownButton = () => {
|
||||
const el = document.getElementById('copy-markdown');
|
||||
if (el) {
|
||||
gsap.set('#copy-markdown', {
|
||||
color: '#00471b',
|
||||
});
|
||||
}
|
||||
gsap.fromTo(
|
||||
'#copy-button',
|
||||
{
|
||||
scale: 0.5,
|
||||
},
|
||||
{
|
||||
scale: 1,
|
||||
ease: 'elastic.in',
|
||||
border: '2px solid #00471b',
|
||||
duration: 0.5,
|
||||
},
|
||||
);
|
||||
setcopyObj({
|
||||
isCopied: true,
|
||||
copiedText: 'copied',
|
||||
});
|
||||
};
|
||||
|
||||
const handleCopyToClipboard = () => {
|
||||
const range = document.createRange();
|
||||
range.selectNode(document.getElementById('markdown-content'));
|
||||
window.getSelection().removeAllRanges(); // clear current selection
|
||||
window.getSelection().addRange(range); // to select text
|
||||
document.execCommand('copy');
|
||||
window.getSelection().removeAllRanges();
|
||||
|
||||
setCopyMarkdownButton();
|
||||
};
|
||||
|
||||
const handleDownloadMarkdown = () => {
|
||||
const markdownContent = document.getElementById('markdown-content');
|
||||
const tempElement = document.createElement('a');
|
||||
tempElement.setAttribute('href', `data:text/markdown;charset=utf-8,${encodeURIComponent(markdownContent.innerText)}`);
|
||||
tempElement.setAttribute('download', 'README.md');
|
||||
tempElement.style.display = 'none';
|
||||
document.body.appendChild(tempElement);
|
||||
tempElement.click();
|
||||
document.body.removeChild(tempElement);
|
||||
};
|
||||
|
||||
const handleDownloadJson = () => {
|
||||
const tempElement = document.createElement('a');
|
||||
tempElement.setAttribute('href', `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify({ prefix, data, link, social, skills, support }))}`);
|
||||
tempElement.setAttribute('download', 'data.json');
|
||||
tempElement.style.display = 'none';
|
||||
document.body.appendChild(tempElement);
|
||||
tempElement.click();
|
||||
document.body.removeChild(tempElement);
|
||||
};
|
||||
|
||||
const handleBackToEdit = () => {
|
||||
setGeneratePreview(false);
|
||||
setGenerateMarkdown(false);
|
||||
setShowConfig(true);
|
||||
gsap.set('#form', {
|
||||
display: '',
|
||||
});
|
||||
gsap.to('.generate', {
|
||||
scale: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const mergeDefaultWithNewDataSkills = (defaultSkills, newSkills) =>
|
||||
Object.keys(defaultSkills).reduce((previous, currentKey) => {
|
||||
let currentSelected = false;
|
||||
|
||||
if (newSkills[currentKey]) {
|
||||
currentSelected = true;
|
||||
}
|
||||
|
||||
return {
|
||||
...previous,
|
||||
[currentKey]: currentSelected,
|
||||
};
|
||||
}, {});
|
||||
|
||||
const setInitialValues = () => {
|
||||
const cache = JSON.parse(localStorage.getItem('cache'));
|
||||
|
||||
if (!cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPrefix(cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX);
|
||||
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA);
|
||||
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK);
|
||||
setSocial(cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL);
|
||||
|
||||
const cacheSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, cache.skills);
|
||||
setSkills(cacheSkills || DEFAULT_SKILLS);
|
||||
|
||||
setSupport(cache.support ? { ...DEFAULT_SUPPORT, ...cache.support } : DEFAULT_SUPPORT);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
gsap.fromTo(
|
||||
'.generate',
|
||||
{
|
||||
boxShadow: '0 0 0 0px rgba(59, 59, 79, 0.4)',
|
||||
},
|
||||
{
|
||||
boxShadow: '0 0 0 10px rgba(59, 59, 79, 0)',
|
||||
repeat: -1,
|
||||
duration: 1,
|
||||
},
|
||||
);
|
||||
|
||||
// set initial values
|
||||
setInitialValues();
|
||||
}, []);
|
||||
|
||||
// keep cache updated
|
||||
KeepCacheUpdated({ prefix, data, link, social, skills, support });
|
||||
|
||||
const handleResetForm = () => {
|
||||
setPrefix(DEFAULT_PREFIX);
|
||||
setData(DEFAULT_DATA);
|
||||
setLink(DEFAULT_LINK);
|
||||
setSocial(DEFAULT_SOCIAL);
|
||||
setSkills(DEFAULT_SKILLS);
|
||||
setSupport(DEFAULT_SUPPORT);
|
||||
};
|
||||
|
||||
const handleRestore = () => {
|
||||
try {
|
||||
const restoreData = JSON.parse(restore);
|
||||
|
||||
if (!restoreData) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPrefix(restoreData.prefix || DEFAULT_PREFIX);
|
||||
setData(restoreData.data || DEFAULT_DATA);
|
||||
setLink(restoreData.link || DEFAULT_LINK);
|
||||
setSocial(restoreData.social || DEFAULT_SOCIAL);
|
||||
setSupport(restoreData.support || DEFAULT_SUPPORT);
|
||||
|
||||
const restoreDataSkills = mergeDefaultWithNewDataSkills(DEFAULT_SKILLS, restoreData.skills);
|
||||
setSkills(restoreDataSkills || DEFAULT_SKILLS);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
} finally {
|
||||
setRestore('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileInput = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file && file.type === 'application/json') {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(file, 'UTF-8');
|
||||
reader.onload = () => {
|
||||
setRestore(reader.result);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="m-4 sm:p-4">
|
||||
<SEO title="GitHub Profile Readme Generator" />
|
||||
<div id="form">
|
||||
<Title data={data} prefix={prefix} handleDataChange={handleDataChange} handlePrefixChange={handlePrefixChange} />
|
||||
<Subtitle data={data} handleDataChange={handleDataChange} />
|
||||
<Work prefix={prefix} data={data} link={link} handlePrefixChange={handlePrefixChange} handleLinkChange={handleLinkChange} handleDataChange={handleDataChange} />
|
||||
<Skills skills={skills} handleSkillsChange={handleSkillsChange} />
|
||||
<Social social={social} handleSocialChange={handleSocialChange} />
|
||||
<Addons data={data} social={social} handleCheckChange={handleCheckChange} handleDataChange={handleDataChange} />
|
||||
<Support support={support} handleSupportChange={handleSupportChange} />
|
||||
<div className="section">
|
||||
{(data.visitorsBadge || data.githubProfileTrophy || data.githubStats || data.topLanguages || data.streakStats) && !social.github ? <div className="warning">* Please add github username to use these add-ons</div> : ''}
|
||||
{social.github && !isGitHubUsernameValid(social.github) ? <div className="warning">* GitHub username is invalid, please add a valid username</div> : ''}
|
||||
{social.medium && !isMediumUsernameValid(social.medium) ? <div className="warning">* Medium username is invalid, please add a valid username (with @)</div> : ''}
|
||||
{data.mediumDynamicBlogs && !social.medium ? <div className="warning">* Please add medium username to display latest blogs dynamically</div> : ''}
|
||||
{data.devDynamicBlogs && !social.dev ? <div className="warning">* Please add dev.to username to display latest blogs dynamically</div> : ''}
|
||||
{data.rssDynamicBlogs && !social.rssurl ? <div className="warning">* Please add your rss feed url to display latest blogs dynamically from your personal blog</div> : ''}
|
||||
{data.twitterBadge && !social.twitter ? <div className="warning">* Please add twitter username to use these add-ons</div> : ''}
|
||||
{social.twitter && !isTwitterUsernameValid(social.twitter) ? <div className="warning">* Twitter username is invalid, please add a valid username</div> : ''}
|
||||
</div>
|
||||
<div className="flex items-center justify-center w-full">
|
||||
<div className="text-xs sm:text-xl font-medium border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1 sm:py-2 px-2 sm:px-4 generate" tabIndex="0" role="button" onClick={handleGenerate} onKeyDown={(e) => e.keyCode === 13 && handleGenerate()}>
|
||||
Generate README
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{displayLoader ? <Loader /> : ''}
|
||||
|
||||
{generateMarkdown || generatePreview ? (
|
||||
<div className="markdown-section p-4 sm:py-4 sm:px-10">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" onClick={handleBackToEdit}>
|
||||
<ArrowLeftIcon size={24} />
|
||||
<span className="hidden sm:block"> back to edit</span>
|
||||
</button>
|
||||
|
||||
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="copy-button" onClick={handleCopyToClipboard}>
|
||||
{copyObj.isCopied === true ? <CheckIcon size={24} /> : <CopyIcon size={24} />}
|
||||
<span className="hidden sm:block" id="copy-markdown">
|
||||
{copyObj.copiedText}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="download-md-button" onClick={handleDownloadMarkdown}>
|
||||
<DownloadIcon size={24} />
|
||||
<span className="hidden sm:block" id="download-markdown">
|
||||
download markdown
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" id="download-json-button" onClick={handleDownloadJson}>
|
||||
<FileCodeIcon size={24} />
|
||||
<span className="hidden sm:block" id="download-json">
|
||||
download backup
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<button type="button" className="text-base w-1/6 border-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center p-1" onClick={handleGeneratePreview}>
|
||||
{previewMarkdown.isPreview ? <MarkdownIcon size={16} /> : <EyeIcon size={16} />}
|
||||
<span className="hidden sm:block ml-1" id="preview-markdown">
|
||||
{previewMarkdown.buttonText}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex justify-center items-center">
|
||||
<div className="w-full text-sm text-gray-900 shadow-xl mt-2 p-4 bg-gray-100 border-2 border-solid border-gray-800" id="markdown-box">
|
||||
{generatePreview ? <MarkdownPreview prefix={prefix} data={data} link={link} social={social} skills={skills} support={support} /> : ''}
|
||||
{generateMarkdown ? <Markdown prefix={prefix} data={data} link={link} social={social} skills={skills} support={support} /> : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-10" id="support">
|
||||
<Donate />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<div className={`w-full shadow flex flex-col justify-center items-start mt-16 border-2 border-solid border-gray-600 py-2 px-4 ${!showConfig ? 'hidden' : 'block'}`}>
|
||||
<div className="flex justify-between items-center w-full">
|
||||
<div className="text-lg sm:text-2xl font-bold font-title mt-2 mb-2">
|
||||
Config options
|
||||
<span className="bg-green-800 text-white text-xs sm:text-sm p-1 ml-1">new feature</span>
|
||||
</div>
|
||||
<button type="button" className="text-xxs sm:text-sm border-2 w-auto px-2 border-solid border-gray-900 bg-gray-100 flex items-center justify-center" onClick={handleResetForm}>
|
||||
Reset form
|
||||
</button>
|
||||
</div>
|
||||
<div className="w-full flex justify-start items-center my-4">
|
||||
<input type="text" className="outline-none w-1/2 mr-6 border-t-0 border-l-0 border-r-0 border solid border-gray-900 py-1 px-2 focus:border-blue-700 prefix" placeholder="Paste JSON code or upload file" value={restore} onChange={(e) => setRestore(e.target.value)} />
|
||||
|
||||
<div className="overflow-hidden relative w-64 mt-4 mb-4">
|
||||
<input className="cursor-pointer absolute block opacity-0 pin-r pin-t before:cursor-pointer" type="file" name="vacancyImageFiles" onChange={handleFileInput} />
|
||||
<button type="button" className="text-xxs sm:text-sm border-2 w-40 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1">
|
||||
Upload json file
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" className="mr-5 mb-10 text-xxs sm:text-sm border-2 w-32 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1" onClick={handleRestore}>
|
||||
Restore
|
||||
</button>
|
||||
<div className="flex flex-col items-start justify-center">
|
||||
<div className="text-green-700 font-medium">Tips</div>
|
||||
<div className="text-sm sm:text-lg text-gray-700">* Enter the downloaded JSON text to restore.</div>
|
||||
<div className="text-sm sm:text-lg text-gray-700">* Press reset to reset the form.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexPage;
|
||||
@@ -1,48 +0,0 @@
|
||||
// If you don't want to use TypeScript you can delete this file!
|
||||
import React from "react"
|
||||
import { PageProps, Link, graphql } from "gatsby"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
type DataProps = {
|
||||
site: {
|
||||
buildTime: string
|
||||
}
|
||||
}
|
||||
|
||||
const UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => (
|
||||
<div>
|
||||
<SEO title="Using TypeScript" />
|
||||
<h1>Gatsby supports TypeScript by default!</h1>
|
||||
<p>
|
||||
This means that you can create and write <em>.ts/.tsx</em> files for your
|
||||
pages, components etc. Please note that the <em>gatsby-*.js</em> files
|
||||
(like gatsby-node.js) currently don't support TypeScript yet.
|
||||
</p>
|
||||
<p>
|
||||
For type checking you'll want to install <em>typescript</em> via npm and
|
||||
run <em>tsc --init</em> to create a <em>.tsconfig</em> file.
|
||||
</p>
|
||||
<p>
|
||||
You're currently on the page "{path}" which was built on{" "}
|
||||
{data.site.buildTime}.
|
||||
</p>
|
||||
<p>
|
||||
To learn more, head over to our{" "}
|
||||
<a href="https://www.gatsbyjs.org/docs/typescript/">
|
||||
documentation about TypeScript
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<Link to="/">Go back to the homepage</Link>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default UsingTypescript
|
||||
|
||||
export const query = graphql`
|
||||
{
|
||||
site {
|
||||
buildTime(formatString: "YYYY-MM-DD hh:mm a z")
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -1,36 +1,30 @@
|
||||
import React from "react"
|
||||
import { graphql } from "gatsby"
|
||||
import React from 'react';
|
||||
import { graphql } from 'gatsby';
|
||||
// import Header from '../components/header'
|
||||
// import Footer from '../components/footer'
|
||||
import { Helmet } from "react-helmet"
|
||||
import Layout from "../components/layout"
|
||||
import { Helmet } from 'react-helmet';
|
||||
import Layout from '../components/layout';
|
||||
|
||||
export default function Template({
|
||||
data, // this prop will be injected by the GraphQL query below.
|
||||
}) {
|
||||
const { markdownRemark } = data // data.markdownRemark holds your post data
|
||||
const { frontmatter, html } = markdownRemark
|
||||
const { markdownRemark } = data; // data.markdownRemark holds your post data
|
||||
const { frontmatter, html } = markdownRemark;
|
||||
return (
|
||||
<Layout>
|
||||
<Helmet>
|
||||
<meta charSet="utf-8" />
|
||||
<title>{frontmatter.title}</title>
|
||||
<link
|
||||
rel="canonical"
|
||||
href={`https://rahuldkjain.github.io/gh-profile-readme-generator`}
|
||||
/>
|
||||
<link rel="canonical" href={`https://rahuldkjain.github.io/gh-profile-readme-generator`} />
|
||||
</Helmet>
|
||||
<div className="m-4 sm:p-10">
|
||||
<div className="blog-post">
|
||||
<h1 className="text-4xl font-bold">{frontmatter.title}</h1>
|
||||
<div
|
||||
className="markdown"
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
/>
|
||||
<div className="markdown" dangerouslySetInnerHTML={{ __html: html }} />
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export const pageQuery = graphql`
|
||||
@@ -44,4 +38,4 @@ export const pageQuery = graphql`
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid } from '../validation';
|
||||
|
||||
describe('validation', () => {
|
||||
it('isGitHubUsernameValid', () => {
|
||||
expect(isGitHubUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
|
||||
expect(isGitHubUsernameValid('rahuldkjain')).toBe(true);
|
||||
});
|
||||
|
||||
it('isMediumUsernameValid', () => {
|
||||
expect(isMediumUsernameValid('rahuldkjain')).toBe(false);
|
||||
expect(isMediumUsernameValid('@rahuldkjain')).toBe(true);
|
||||
});
|
||||
|
||||
it('isTwitterUsernameValid', () => {
|
||||
expect(isTwitterUsernameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit')).toBe(false);
|
||||
expect(isTwitterUsernameValid('rahuldkjain')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,31 +1,32 @@
|
||||
const githubStatsStylingQueryString = options => {
|
||||
const githubStatsStylingQueryString = (options) => {
|
||||
const params = {
|
||||
show_icons: true,
|
||||
...(options.theme && options.theme !== "none") && { theme: options.theme },
|
||||
...options.titleColor && { "title_color": options.titleColor },
|
||||
...options.textColor && { "text_color": options.textColor},
|
||||
...options.bgColor && { "bg_color": options.bgColor},
|
||||
...options.hideBorder && { "hide_border": options.hideBorder},
|
||||
...options.cacheSeconds && { "cache_seconds": options.cacheSeconds},
|
||||
...options.locale && { "locale": options.locale},
|
||||
}
|
||||
const query_string = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&")
|
||||
return query_string
|
||||
}
|
||||
...(options.theme && options.theme !== 'none' && { theme: options.theme }),
|
||||
...(options.titleColor && { title_color: options.titleColor }),
|
||||
...(options.textColor && { text_color: options.textColor }),
|
||||
...(options.bgColor && { bg_color: options.bgColor }),
|
||||
...(options.hideBorder && { hide_border: options.hideBorder }),
|
||||
...(options.cacheSeconds && { cache_seconds: options.cacheSeconds }),
|
||||
...(options.locale && { locale: options.locale }),
|
||||
};
|
||||
const queryString = Object.entries(params)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('&');
|
||||
return queryString;
|
||||
};
|
||||
|
||||
const streakStatsStylingQueryString = options => {
|
||||
const streakStatsStylingQueryString = (options) => {
|
||||
const params = {
|
||||
...(options.theme && options.theme !== "none") && { theme: options.theme },
|
||||
}
|
||||
const query_string = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&")
|
||||
return query_string
|
||||
}
|
||||
...(options.theme && options.theme !== 'none' && { theme: options.theme }),
|
||||
};
|
||||
const queryString = Object.entries(params)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('&');
|
||||
return queryString;
|
||||
};
|
||||
|
||||
export const githubStatsLinkGenerator = ({github, options}) =>
|
||||
`https://github-readme-stats.vercel.app/api?username=${github}&${githubStatsStylingQueryString(options)}`
|
||||
export const githubStatsLinkGenerator = ({ github, options }) => `https://github-readme-stats.vercel.app/api?username=${github}&${githubStatsStylingQueryString(options)}`;
|
||||
|
||||
export const topLanguagesLinkGenerator = ({github, options}) =>
|
||||
`https://github-readme-stats.vercel.app/api/top-langs?username=${github}&${githubStatsStylingQueryString(options)}&layout=compact`
|
||||
export const topLanguagesLinkGenerator = ({ github, options }) => `https://github-readme-stats.vercel.app/api/top-langs?username=${github}&${githubStatsStylingQueryString(options)}&layout=compact`;
|
||||
|
||||
export const streakStatsLinkGenerator = ({github, options}) =>
|
||||
`https://github-readme-streak-stats.herokuapp.com/?user=${github}&${streakStatsStylingQueryString(options)}`
|
||||
export const streakStatsLinkGenerator = ({ github, options }) => `https://github-readme-streak-stats.herokuapp.com/?user=${github}&${streakStatsStylingQueryString(options)}`;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
const isGitHubUsernameValid = username => {
|
||||
var pattern = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i
|
||||
return pattern.test(username)
|
||||
}
|
||||
const isMediumUsernameValid = username => {
|
||||
const isGitHubUsernameValid = (username) => {
|
||||
const pattern = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i;
|
||||
return pattern.test(username);
|
||||
};
|
||||
const isMediumUsernameValid = (username) => {
|
||||
if (username) {
|
||||
return username[0] === "@"
|
||||
return username[0] === '@';
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const isTwitterUsernameValid = username => {
|
||||
var pattern = /^[a-zA-Z0-9_]{1,15}$/
|
||||
return pattern.test(username)
|
||||
}
|
||||
const isTwitterUsernameValid = (username) => {
|
||||
const pattern = /^[a-zA-Z0-9_]{1,15}$/;
|
||||
return pattern.test(username);
|
||||
};
|
||||
|
||||
export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid }
|
||||
export { isGitHubUsernameValid, isMediumUsernameValid, isTwitterUsernameValid };
|
||||
|
||||
@@ -1,70 +1,27 @@
|
||||
import { isMediumUsernameValid } from "../utils/validation"
|
||||
import { isMediumUsernameValid } from './validation';
|
||||
|
||||
const latestBlogs = payload => {
|
||||
let rssFeed = ""
|
||||
if (
|
||||
payload.dev.show &&
|
||||
payload.dev.username &&
|
||||
payload.rssurl.show &&
|
||||
payload.rssurl.username &&
|
||||
payload.medium.show &&
|
||||
payload.medium.username &&
|
||||
isMediumUsernameValid(payload.medium.username)
|
||||
) {
|
||||
rssFeed =
|
||||
"https://dev.to/feed/" +
|
||||
payload.dev.username +
|
||||
", https://medium.com/feed/" +
|
||||
payload.medium.username +
|
||||
", " +
|
||||
payload.rssurl.username
|
||||
export default function latestBlogs(payload) {
|
||||
let rssFeed = '';
|
||||
if (payload.dev.show && payload.dev.username && payload.rssurl.show && payload.rssurl.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
|
||||
rssFeed = `https://dev.to/feed/${payload.dev.username}, https://medium.com/feed/${payload.medium.username}, ${payload.rssurl.username}`;
|
||||
}
|
||||
//when any two blog providers are selected
|
||||
else if (
|
||||
payload.dev.show &&
|
||||
payload.dev.username &&
|
||||
payload.rssurl.show &&
|
||||
payload.rssurl.username
|
||||
) {
|
||||
rssFeed =
|
||||
"https://dev.to/feed/" +
|
||||
payload.dev.username +
|
||||
", " +
|
||||
payload.rssurl.username
|
||||
} else if (
|
||||
payload.rssurl.show &&
|
||||
payload.rssurl.username &&
|
||||
payload.medium.show &&
|
||||
payload.medium.username &&
|
||||
isMediumUsernameValid(payload.medium.username)
|
||||
) {
|
||||
rssFeed =
|
||||
"https://medium.com/feed/" +
|
||||
payload.medium.username +
|
||||
", " +
|
||||
payload.rssurl.username
|
||||
} else if (
|
||||
payload.dev.show &&
|
||||
payload.dev.username &&
|
||||
payload.medium.show &&
|
||||
payload.medium.username &&
|
||||
isMediumUsernameValid(payload.medium.username)
|
||||
) {
|
||||
rssFeed =
|
||||
"https://dev.to/feed/" +
|
||||
payload.dev.username +
|
||||
", https://medium.com/feed/" +
|
||||
payload.medium.username
|
||||
// when any two blog providers are selected
|
||||
else if (payload.dev.show && payload.dev.username && payload.rssurl.show && payload.rssurl.username) {
|
||||
rssFeed = `https://dev.to/feed/${payload.dev.username}, ${payload.rssurl.username}`;
|
||||
} else if (payload.rssurl.show && payload.rssurl.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
|
||||
rssFeed = `https://medium.com/feed/${payload.medium.username}, ${payload.rssurl.username}`;
|
||||
} else if (payload.dev.show && payload.dev.username && payload.medium.show && payload.medium.username && isMediumUsernameValid(payload.medium.username)) {
|
||||
rssFeed = `https://dev.to/feed/${payload.dev.username}, https://medium.com/feed/${payload.medium.username}`;
|
||||
}
|
||||
// when only one blog provider is selected
|
||||
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) {
|
||||
rssFeed = payload.rssurl.username
|
||||
rssFeed = payload.rssurl.username;
|
||||
} else {
|
||||
rssFeed = "https://medium.com/feed/" + payload.medium.username
|
||||
rssFeed = `https://medium.com/feed/${payload.medium.username}`;
|
||||
}
|
||||
let data = `name: Latest blog post workflow
|
||||
const data = `name: Latest blog post workflow
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
@@ -77,9 +34,7 @@ jobs:
|
||||
- uses: gautamkrishnar/blog-post-workflow@master
|
||||
with:
|
||||
max_post_count: "4"
|
||||
feed_list: "${rssFeed}"`
|
||||
feed_list: "${rssFeed}"`;
|
||||
|
||||
return data
|
||||
return data;
|
||||
}
|
||||
|
||||
export { latestBlogs }
|
||||
|
||||
@@ -3,25 +3,25 @@ module.exports = {
|
||||
theme: {
|
||||
extend: {},
|
||||
fontSize: {
|
||||
xxs: ".60rem",
|
||||
xs: ".75rem",
|
||||
sm: ".875rem",
|
||||
tiny: ".875rem",
|
||||
base: "1rem",
|
||||
lg: "1.125rem",
|
||||
xl: "1.25rem",
|
||||
"2xl": "1.5rem",
|
||||
"3xl": "1.875rem",
|
||||
"4xl": "2.25rem",
|
||||
"5xl": "3rem",
|
||||
"6xl": "4rem",
|
||||
"7xl": "5rem",
|
||||
xxs: '.60rem',
|
||||
xs: '.75rem',
|
||||
sm: '.875rem',
|
||||
tiny: '.875rem',
|
||||
base: '1rem',
|
||||
lg: '1.125rem',
|
||||
xl: '1.25rem',
|
||||
'2xl': '1.5rem',
|
||||
'3xl': '1.875rem',
|
||||
'4xl': '2.25rem',
|
||||
'5xl': '3rem',
|
||||
'6xl': '4rem',
|
||||
'7xl': '5rem',
|
||||
},
|
||||
fontFamily: {
|
||||
title: ["Lato", "sans-serif"],
|
||||
body: ["Roboto Mono", "monospace"],
|
||||
title: ['Lato', 'sans-serif'],
|
||||
body: ['Roboto Mono', 'monospace'],
|
||||
},
|
||||
},
|
||||
variants: {},
|
||||
plugins: [],
|
||||
}
|
||||
};
|
||||
|
||||