Compare commits

..

10 Commits

Author SHA1 Message Date
dependabot[bot] 38012a54be Bump express from 4.17.1 to 4.18.2
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 10:10:15 +00:00
Rahul Jain 888aff31e1 Merge pull request #568 from rahuldkjain/hotfix/skills
fix: #565
2022-06-28 19:05:03 +05:30
Rahul Jain f4b2f5cf88 fix: #565 2022-06-28 19:00:18 +05:30
Rahul Jain c83a129e01 Merge pull request #564 from rahuldkjain/hotfix/icons
fix: linting errors
2022-06-26 20:13:18 +05:30
Rahul Jain 3461a5b865 fix: linting errors 2022-06-26 20:05:52 +05:30
Rahul Jain c919601f7e Merge pull request #501 from techieeliot/issue-452-hasnode
feature: add hashnode to socials input and preview
2021-11-01 10:16:46 +05:30
Eliot Sanford 5e0cd2e639 docs: add content to readme 2021-10-31 23:34:18 -05:00
Eliot Sanford 9b24ae64c9 fix: change placeholder to include the 'with @' 2021-10-31 23:19:54 -05:00
Eliot Sanford 71d1fafbd6 feature: add hashnode to socials input and preview
closes #452
2021-10-31 23:07:15 -05:00
Rahul Jain 8947cb3641 Merge pull request #500 from rahuldkjain/issue-499
fix: html.jsx linting
2021-10-31 17:03:37 +05:30
28 changed files with 37797 additions and 3256 deletions
+2 -1
View File
@@ -14,5 +14,6 @@
"plugins": ["react"],
"rules": {
"react/forbid-prop-types": 0
}
},
"ignorePatterns": ["**/*.test.js"]
}
+1 -1
View File
@@ -2,7 +2,7 @@
"singleQuote": true,
"jsxSingleQuote": false,
"tabWidth": 2,
"printWidth": 480,
"printWidth": 120,
"trailingComma": "all",
"semi": true,
"exclude": ["node_modules", "codepipeline"]
+2
View File
@@ -16,9 +16,11 @@
## 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;
+1
View File
@@ -138,6 +138,7 @@ Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDU
- [Gautam Krishna R](https://github.com/gautamkrishnar) for the awesome [blog post workflow](https://github.com/gautamkrishnar/blog-post-workflow)
- [Jonah Lawrence](https://github.com/DenverCoder1) for the incredible [github-readme-streak-stats](https://github.com/DenverCoder1/github-readme-streak-stats)
- [Julien Monty](https://github.com/konpa) for super useful [devicon](https://github.com/konpa/devicon)
- [Eliot Sanford](https://github.com/techieeliot) for adding hashnode as a blog input
## 🙇 Sponsors
+3 -1
View File
@@ -1,4 +1,6 @@
/* eslint-disable no-undef */
const React = require('react');
const gatsby = jest.requireActual('gatsby');
module.exports = {
@@ -10,7 +12,7 @@ module.exports = {
React.createElement('a', {
...rest,
href: to,
})
}),
),
StaticQuery: jest.fn(),
useStaticQuery: jest.fn(),
+36624 -3032
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -91,7 +91,7 @@ describe('Addons', () => {
social={socialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
expect(toJson(addOnComponent)).toMatchSnapshot();
@@ -113,7 +113,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#visitors-count-open-btn').simulate('click', {});
@@ -147,7 +147,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#visitors-count-open-btn').simulate('click', {});
@@ -176,7 +176,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#visitors-count-open-btn').simulate('click', {});
@@ -205,7 +205,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#visitors-count-open-btn').simulate('click', {});
@@ -233,7 +233,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -267,7 +267,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -318,7 +318,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -369,7 +369,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -421,7 +421,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -472,7 +472,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -524,7 +524,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -576,7 +576,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#github-stats-open-btn').simulate('click', {});
@@ -617,7 +617,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#top-languages-open-btn').simulate('click', {});
@@ -652,7 +652,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#top-languages-open-btn').simulate('click', {});
@@ -686,7 +686,7 @@ describe('Addons', () => {
social={socialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#visitors-count').simulate('change', mockEvent);
@@ -725,7 +725,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
const workflowElement = addOnComponent.find('.workflow');
@@ -748,7 +748,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
const workflowElement = addOnComponent.find('.workflow');
@@ -771,7 +771,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
const workflowElement = addOnComponent.find('.workflow');
@@ -797,7 +797,7 @@ describe('Addons', () => {
social={newSocialInput}
handleCheckChange={mockHandleCheckChange}
handleDataChange={mockHandleDataChange}
/>
/>,
);
addOnComponent.find('#blog-post-worklow-span').simulate('click', {});
-1
View File
@@ -1,7 +1,6 @@
import React from 'react';
import toJson from 'enzyme-to-json';
import { shallow } from 'enzyme';
import Donate from '../donate';
describe('Donate', () => {
+10 -10
View File
@@ -85,7 +85,7 @@ describe('Markdown', () => {
...props.data,
subtitle: '',
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -102,7 +102,7 @@ describe('Markdown', () => {
...props.prefix,
title: '',
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -115,7 +115,7 @@ describe('Markdown', () => {
...props.data,
topLanguages: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -129,7 +129,7 @@ describe('Markdown', () => {
topLanguages: true,
githubStats: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -142,7 +142,7 @@ describe('Markdown', () => {
...props.data,
devDynamicBlogs: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -155,7 +155,7 @@ describe('Markdown', () => {
...props.data,
currentWork: '',
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -168,7 +168,7 @@ describe('Markdown', () => {
...props.data,
visitorsBadge: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -181,7 +181,7 @@ describe('Markdown', () => {
...props.data,
twitterBadge: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -194,7 +194,7 @@ describe('Markdown', () => {
...props.data,
githubProfileTrophy: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -207,7 +207,7 @@ describe('Markdown', () => {
...props.data,
githubProfileTrophy: true,
}}
/>
/>,
);
expect(toJson(component)).toMatchSnapshot();
});
@@ -248,7 +248,7 @@ describe('DisplaySocial Preview', () => {
base="https://codepen.io"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
username={social.codepen}
/>
/>,
);
expect(tree).toMatchSnapshot();
@@ -259,7 +259,7 @@ describe('DisplaySocial Preview', () => {
base="https://codepen.io"
icon="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/codepen.svg"
username={''}
/>
/>,
);
expect(tree).toMatchSnapshot();
@@ -278,7 +278,7 @@ describe('VisitorsBadge Preview', () => {
badgeColor: data.badgeColor,
badgeStyle: data.badgeStyle,
}}
/>
/>,
);
expect(tree).toMatchSnapshot();
@@ -295,7 +295,7 @@ describe('VisitorsBadge Preview', () => {
badgeColor: data.badgeColor,
badgeStyle: data.badgeStyle,
}}
/>
/>,
);
expect(tree).toMatchSnapshot();
@@ -371,7 +371,7 @@ describe('TopLanguages Preview', () => {
let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
const tree = shallow(
<TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />
<TopLanguagesPreview show={data.topLanguages} github={social.github} options={data.topLanguagesOptions} />,
);
expect(tree).toMatchSnapshot();
@@ -389,7 +389,7 @@ describe('GitHubStats Preview', () => {
let data = DEFAULT_DATA;
let social = DEFAULT_SOCIAL;
const tree = shallow(
<GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
<GitHubStatsPreview show={data.githubStats} github={social.github} options={data.githubStatsOptions} />,
);
expect(tree).toMatchSnapshot();
+187 -25
View File
@@ -15,12 +15,24 @@ const AddonsItem = (props) => {
<>
<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} />
<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' }}>
<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>
)}
@@ -53,7 +65,11 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => (
<>
<label htmlFor="badge-style">
Style:&nbsp;
<select id="badge-style" onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)} value={badgeOptions.badgeStyle}>
<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>
@@ -62,17 +78,39 @@ const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => (
<label htmlFor="badge-color">
Color:&nbsp;
<input type="color" id="badge-color" defaultValue={`#${badgeOptions.badgeColor}`} className="w-6" onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))} />
<input
type="color"
id="badge-color"
defaultValue={`#${badgeOptions.badgeColor}`}
className="w-6"
onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor="badge-label-text">
Label Text:&nbsp;
<input type="text" id="badge-label-text" placeholder="Profile views" className="w-2/4 bg-gray-300 pl-2" onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())} defaultValue={badgeOptions.badgeLabel} />
<input
type="text"
id="badge-label-text"
placeholder="Profile views"
className="w-2/4 bg-gray-300 pl-2"
onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())}
defaultValue={badgeOptions.badgeLabel}
/>
</label>
<span className="mt-2 flex items-center">
Preview:&nbsp;
{isGitHubUsernameValid(githubName) ? <img src={`https://komarev.com/ghpvc/?username=${githubName}&label=${encodeURI(badgeOptions.badgeLabel)}&color=${badgeOptions.badgeColor}&style=${badgeOptions.badgeStyle}`} alt="profile-visitors-count" /> : <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>}
{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>
</>
);
@@ -86,7 +124,11 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
<>
<label htmlFor={`${prefix}-theme`}>
Theme:&nbsp;
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.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>
@@ -102,28 +144,67 @@ const CustomizeGithubStatsBase = ({ prefix, options, onUpdate }) => (
</label>
<label htmlFor={`${prefix}-title-color`}>
Title Color:&nbsp;
<input type="color" id={`${prefix}-title-color`} defaultValue={`#${options.titleColor}`} className="w-6" onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))} />
<input
type="color"
id={`${prefix}-title-color`}
defaultValue={`#${options.titleColor}`}
className="w-6"
onChange={(e) => onUpdate('titleColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-text-color`}>
Text Color:&nbsp;
<input type="color" id={`${prefix}-text-color`} defaultValue={`#${options.textColor}`} className="w-6" onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))} />
<input
type="color"
id={`${prefix}-text-color`}
defaultValue={`#${options.textColor}`}
className="w-6"
onChange={(e) => onUpdate('textColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-bg-color`}>
Background Color:&nbsp;
<input type="color" id={`${prefix}-bg-color`} defaultValue={`#${options.bgColor}`} className="w-6" onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))} />
<input
type="color"
id={`${prefix}-bg-color`}
defaultValue={`#${options.bgColor}`}
className="w-6"
onChange={(e) => onUpdate('bgColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor={`${prefix}-hide-border`} className="checkbox-label">
Hide border:&nbsp;
<input id={`${prefix}-hide-border`} type="checkbox" className="checkbox-label__input" checked={options.hideBorder} onChange={(e) => onUpdate('hideBorder', e.target.checked)} />
<input
id={`${prefix}-hide-border`}
type="checkbox"
className="checkbox-label__input"
checked={options.hideBorder}
onChange={(e) => onUpdate('hideBorder', e.target.checked)}
/>
<span className="checkbox-label__control" />
</label>
<label htmlFor={`${prefix}-cache-seconds`}>
Cache Seconds:&nbsp;
<input id={`${prefix}-cache-seconds`} type="number" min={1800} max={86400} placeholder={1800} defaultValue={options.cacheSeconds} onChange={(e) => onUpdate('cacheSeconds', e.target.value)} />
<input
id={`${prefix}-cache-seconds`}
type="number"
min={1800}
max={86400}
placeholder={1800}
defaultValue={options.cacheSeconds}
onChange={(e) => onUpdate('cacheSeconds', e.target.value)}
/>
</label>
<label htmlFor={`${prefix}-locale`}>
Locale:&nbsp;
<input id={`${prefix}-locale`} type="text" placeholder="en" defaultValue={options.locale} onChange={(e) => onUpdate('locale', e.target.value)} size="2" />
<input
id={`${prefix}-locale`}
type="text"
placeholder="en"
defaultValue={options.locale}
onChange={(e) => onUpdate('locale', e.target.value)}
size="2"
/>
</label>
</>
);
@@ -137,7 +218,11 @@ const CustomizeStreakStats = ({ prefix, options, onUpdate }) => (
<>
<label htmlFor={`${prefix}-theme`}>
Theme:&nbsp;
<select id={`${prefix}-theme`} onChange={({ target: { value } }) => onUpdate('theme', value)} defaultValue={options.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>
@@ -260,39 +345,116 @@ const Addons = (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">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} />} />}>
<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')}>
<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} />} />}>
<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} />} />}>
<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} />} />}>
<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')}>
<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')}>
<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')}>
<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')}>
<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)) ? (
{(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' }}>
<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>{' '}
+42 -8
View File
@@ -13,8 +13,15 @@ const Donate = () => (
<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
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>
@@ -27,13 +34,31 @@ const Donate = () => (
</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" />
<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" />
<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"
@@ -42,8 +67,17 @@ const Donate = () => (
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" />
<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>
+22 -5
View File
@@ -12,7 +12,8 @@ const Footer = () => (
<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" />
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>
@@ -43,22 +44,38 @@ const Footer = () => (
<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">
<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">
<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">
<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">
<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>
+11 -2
View File
@@ -61,14 +61,23 @@ const Header = (props) => {
</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">
<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">
<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
+73 -14
View File
@@ -2,7 +2,11 @@ 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 {
githubStatsLinkGenerator,
topLanguagesLinkGenerator,
streakStatsLinkGenerator,
} from '../utils/link-generators';
import { DEFAULT_DATA, DEFAULT_LINK, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
const Title = (props) => {
@@ -451,7 +455,8 @@ DisplaySupport.propTypes = {
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/';
const iconBaseUrl =
'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/';
return (
<div id="markdown-content" className="break-words">
<>
@@ -506,7 +511,13 @@ const Markdown = (props) => {
<DisplayWork prefix={prefix.funFact} project={data.funFact} />
</>
<>
<DisplayDynamicBlogs show={(data.devDynamicBlogs && social.dev) || (data.rssDynamicBlogs && social.rssurl) || (data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium))} />
<DisplayDynamicBlogs
show={
(data.devDynamicBlogs && social.dev) ||
(data.rssDynamicBlogs && social.rssurl) ||
(data.mediumDynamicBlogs && social.medium && isMediumUsernameValid(social.medium))
}
/>
</>
{isSocial(social) ? (
<>
@@ -527,13 +538,25 @@ const Markdown = (props) => {
<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://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://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://codesandbox.com"
icon={`${iconBaseUrl}codesandbox.svg`}
username={social.codesandbox}
/>
</>
<>
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
@@ -550,6 +573,9 @@ const Markdown = (props) => {
<>
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
</>
<>
<DisplaySocial base="https://hashnode.com" icon={`${iconBaseUrl}hashnode.svg`} username={social.hashnode} />
</>
<>
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
</>
@@ -557,25 +583,53 @@ const Markdown = (props) => {
<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.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://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://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.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://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://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://www.topcoder.com/members"
icon={`${iconBaseUrl}topcoder.svg`}
username={social.topcoder}
/>
</>
<>
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
@@ -599,7 +653,12 @@ const Markdown = (props) => {
<DisplaySupport support={support} />
</>
<>
<DisplayTopLanguages show={data.topLanguages} showStats={data.githubStats} github={social.github} options={data.topLanguagesOptions} />
<DisplayTopLanguages
show={data.topLanguages}
showStats={data.githubStats}
github={social.github}
options={data.topLanguagesOptions}
/>
</>
<>
<GitHubStats show={data.githubStats} github={social.github} options={data.githubStatsOptions} />
+70 -14
View File
@@ -1,7 +1,11 @@
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 {
githubStatsLinkGenerator,
topLanguagesLinkGenerator,
streakStatsLinkGenerator,
} from '../utils/link-generators';
import { DEFAULT_DATA, DEFAULT_PREFIX, DEFAULT_SOCIAL, DEFAULT_SUPPORT } from '../constants/defaults';
export const TitlePreview = (props) => {
@@ -135,7 +139,8 @@ DisplaySocial.propTypes = {
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/';
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;
});
@@ -152,13 +157,25 @@ export const SocialPreview = (props) => {
<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://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://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://codesandbox.com"
icon={`${iconBaseUrl}codesandbox.svg`}
username={social.codesandbox}
/>
</>
<>
<DisplaySocial base="https://kaggle.com" icon={`${iconBaseUrl}kaggle.svg`} username={social.kaggle} />
@@ -175,6 +192,9 @@ export const SocialPreview = (props) => {
<>
<DisplaySocial base="https://www.behance.net" icon={`${iconBaseUrl}behance.svg`} username={social.behance} />
</>
<>
<DisplaySocial base="https://hashnode.com" icon={`${iconBaseUrl}hashnode.svg`} username={social.hashnode} />
</>
<>
<DisplaySocial base="https://medium.com" icon={`${iconBaseUrl}medium.svg`} username={social.medium} />
</>
@@ -182,25 +202,53 @@ export const SocialPreview = (props) => {
<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.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://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://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.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://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://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://www.topcoder.com/members"
icon={`${iconBaseUrl}topcoder.svg`}
username={social.topcoder}
/>
</>
<>
<DisplaySocial base="https://discord.gg" icon={`${iconBaseUrl}discord.svg`} username={social.discord} />
@@ -388,12 +436,20 @@ export const SupportPreview = (props) => {
<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" />
<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" />
<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>
+19 -3
View File
@@ -11,7 +11,13 @@ const Skills = (props) => {
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)} />
<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>
@@ -32,7 +38,13 @@ const Skills = (props) => {
<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} />
<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
@@ -60,7 +72,11 @@ const Skills = (props) => {
.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 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">
+290 -46
View File
@@ -8,96 +8,340 @@ const Social = (props) => {
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<img
src="https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/hashnode.svg"
className="w-6 h-6 sm:w-8 sm:h-8 mr-1 sm:mr-4"
alt="hashnode"
/>
<input
id="hashnode"
placeholder="hashnode 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.hashnode}
onChange={(event) => handleSocialChange('hashnode', 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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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/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)} />
<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>
+6 -1
View File
@@ -6,7 +6,12 @@ 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={data.subtitle} onChange={(event) => handleDataChange('subtitle', event)} />
<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>
);
};
+24 -4
View File
@@ -8,12 +8,32 @@ const Support = (props) => {
<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)} />
<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)} />
<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>
+13 -2
View File
@@ -7,8 +7,19 @@ const Title = (props) => {
<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)} />
<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>
);
+152 -23
View File
@@ -7,51 +7,180 @@ const Work = (props) => {
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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)} />
<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>
);
+2 -1
View File
@@ -199,7 +199,7 @@ const icons = {
css3: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/css3/css3-original-wordmark.svg',
csharp: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/csharp/csharp-original.svg',
d3js: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/d3js/d3js-original.svg',
django: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/django/django-original.svg',
django: 'https://cdn.worldvectorlogo.com/logos/django.svg',
docker: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/docker/docker-original-wordmark.svg',
dotnet: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/dot-net/dot-net-original-wordmark.svg',
electron: 'https://raw.githubusercontent.com/devicons/devicon/master/icons/electron/electron-original.svg',
@@ -508,6 +508,7 @@ const skillWebsites = {
const initialSkillState = {};
const skillsArray = Object.keys(categorizedSkills).map((key) => categorizedSkills[key].skills);
// eslint-disable-next-line prefer-spread
const skills = [].concat.apply([], skillsArray).sort();
skills.forEach((skill) => {
+11 -1
View File
@@ -11,7 +11,17 @@ export default function HTML(props) {
<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" />
<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}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24"><title>Hashnode icon</title><path d="M3.84 0h16.32A3.84 3.84 0 0 1 24 3.84v16.32A3.84 3.84 0 0 1 20.16 24H3.84A3.84 3.84 0 0 1 0 20.16V3.84A3.84 3.84 0 0 1 3.84 0zm14.175 21.638l-.004-.001a2.577 2.577 0 0 0 .209-5.139l-4.917-8.682c-.719-1.292-2.108-1.236-2.609.598-.43 1.736-.319 3.372-.444 5.348-.001.013-.01.024-.023.027s-.026-.002-.033-.013l-4.39-8.751c.358-.281.568-.711.569-1.167a1.459 1.459 0 1 0-1.459 1.459c.069 0 .125-.014.18-.014 1.848 4.75 3.904 10.293 4.64 11.571.5 1.222 2.209.833 2.251-.486l.18-6.932c0-.042.055-.042.07-.014l3.526 8.389a2.573 2.573 0 0 0 2.254 3.806z"/></svg>

After

Width:  |  Height:  |  Size: 661 B

+174 -29
View File
@@ -1,6 +1,14 @@
import React, { useState, useEffect } from 'react';
import gsap from 'gsap';
import { ArrowLeftIcon, CopyIcon, DownloadIcon, EyeIcon, CheckIcon, MarkdownIcon, FileCodeIcon } from '@primer/octicons-react';
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';
@@ -251,7 +259,10 @@ const IndexPage = () => {
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(
'href',
`data:text/markdown;charset=utf-8,${encodeURIComponent(markdownContent.innerText)}`,
);
tempElement.setAttribute('download', 'README.md');
tempElement.style.display = 'none';
document.body.appendChild(tempElement);
@@ -261,7 +272,12 @@ const IndexPage = () => {
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(
'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);
@@ -381,25 +397,87 @@ const IndexPage = () => {
<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} />
<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} />
<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} />
<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> : ''}
{(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()}>
<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>
@@ -410,33 +488,56 @@ const IndexPage = () => {
{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}>
<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}>
<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}>
<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}>
<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}>
<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}
@@ -445,9 +546,27 @@ const IndexPage = () => {
</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
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">
@@ -457,27 +576,53 @@ const IndexPage = () => {
) : (
''
)}
<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={`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}>
<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)} />
<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">
<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}>
<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">
+8 -3
View File
@@ -25,8 +25,13 @@ const streakStatsStylingQueryString = (options) => {
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)}`;
+23 -3
View File
@@ -2,15 +2,35 @@ import { isMediumUsernameValid } from './validation';
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)) {
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)) {
} 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)) {
} 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