feat: add option to upload json backup file

This commit is contained in:
Tailine Chagas
2020-10-11 16:49:09 -03:00
parent cc962a940a
commit 693ac86846
10 changed files with 212 additions and 149 deletions
+13 -13
View File
@@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
+7 -2
View File
@@ -54,8 +54,8 @@
This tool provides an easy way to create a GitHub profile readme with the latest add-ons such as `visitors count`, `github stats`, etc.
## 🚀 Demo
## 🚀 Demo
<a href="https://rahuldkjain.github.io/gh-profile-readme-generator" target="blank">
<img src="https://img.shields.io/website?url=https%3A%2F%2Frahuldkjain.github.io%2Fgh-profile-readme-generator&logo=github&style=flat-square" />
</a>
@@ -122,11 +122,11 @@ Please contribute using [GitHub Flow](https://guides.github.com/introduction/flo
Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.
## 💻 Built with
- [Gatsby](https://www.gatsbyjs.com/)
- [Tailwind CSS](https://tailwindcss.com/): for styling
- [GSAP](https://greensock.com/gsap/): for small SVG Animations
## 🙇 Special Thanks
- [Anurag Hazra](https://github.com/anuraghazra) for amazing [github-readme-stats](https://github.com/anuraghazra/github-readme-stats)
@@ -156,9 +156,13 @@ Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDU
</p>
## Contributors ✨
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
@@ -173,6 +177,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
<hr>
+1 -1
View File
@@ -1 +1 @@
module.exports = "test-file-stub"
module.exports = "test-file-stub"
+98 -73
View File
@@ -2,10 +2,20 @@ import React, { useState, useEffect } from "react"
import { withPrefix } from "gatsby"
import { latestBlogs } from "../utils/workflows"
import links from "../constants/page-links"
import { isMediumUsernameValid, isGitHubUsernameValid } from "../utils/validation"
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react";
import {
isMediumUsernameValid,
isGitHubUsernameValid,
} from "../utils/validation"
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react"
const AddonsItem = ({inputId, inputChecked, onInputChange, Icon, onIconClick, ...props}) => {
const AddonsItem = ({
inputId,
inputChecked,
onInputChange,
Icon,
onIconClick,
...props
}) => {
return (
<div className="py-2 flex justify-start items-center text-sm sm:text-lg">
<label htmlFor={inputId} className="cursor-pointer flex items-center">
@@ -17,71 +27,85 @@ const AddonsItem = ({inputId, inputChecked, onInputChange, Icon, onIconClick, ..
/>
<span className="pl-4">{props.children}</span>
</label>
{
Icon?
<button onClick={onIconClick} className="flex ml-3 focus:bg-gray-400" style={{outline: "none"}}>
<Icon className="transform scale-100 md:scale-125" />
</button>
:''
}
{Icon ? (
<button
onClick={onIconClick}
className="flex ml-3 focus:bg-gray-400"
style={{ outline: "none" }}
>
<Icon className="transform scale-100 md:scale-125" />
</button>
) : (
""
)}
</div>
)
}
const CustomizeBadge = ({githubName, badgeOptions, onBadgeUpdate}) => {
const CustomizeBadge = ({ githubName, badgeOptions, onBadgeUpdate }) => {
return (
<div className={`border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8`} style={{maxWidth: '21rem'}}>
<div
className={`border-2 border-solid border-gray-900 bg-gray-100 p-2 ml-8`}
style={{ maxWidth: "21rem" }}
>
<header className="text-base sm:text-lg">Customize Badge</header>
<hr className="border-gray-500"/>
<hr className="border-gray-500" />
<div className="text-sm sm:text-lg flex flex-col mt-2 ml-0 md:ml-4">
<label htmlFor="badge-style">Style:&nbsp;
<select
id="badge-style"
onChange={(e) => onBadgeUpdate('badgeStyle', e.target.value)}
value = {badgeOptions.badgeStyle}
<label htmlFor="badge-style">
Style:&nbsp;
<select
id="badge-style"
onChange={e => onBadgeUpdate("badgeStyle", e.target.value)}
value={badgeOptions.badgeStyle}
>
<option value="flat">Flat</option>
<option value="flat-square">Flat Square</option>
<option value="plastic">Plastic</option>
</select>
</select>
</label>
<label htmlFor="badge-color">Color:&nbsp;
<input
type="color"
id="badge-color"
defaultValue={`#${badgeOptions.badgeColor}`}
<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('#', ''))}
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"
<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())}
onChange={e => onBadgeUpdate("badgeLabel", e.target.value.trim())}
defaultValue={badgeOptions.badgeLabel}
/>
</label>
<span className="mt-2 flex items-center">
Preview:&nbsp;
{
isGitHubUsernameValid(githubName)?
<img
src={`https://komarev.com/ghpvc/`
+ `?username=${githubName}`
+ `&label=${encodeURI(badgeOptions.badgeLabel)}`
+ `&color=${badgeOptions.badgeColor}`
+ `&style=${badgeOptions.badgeStyle}`
}
/>
: <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>
}
{isGitHubUsernameValid(githubName) ? (
<img
src={
`https://komarev.com/ghpvc/` +
`?username=${githubName}` +
`&label=${encodeURI(badgeOptions.badgeLabel)}` +
`&color=${badgeOptions.badgeColor}` +
`&style=${badgeOptions.badgeStyle}`
}
/>
) : (
<span className="text-xxs md:text-sm text-red-600">
Invalid GitHub username
</span>
)}
</span>
</div>
</div>
@@ -89,19 +113,19 @@ const CustomizeBadge = ({githubName, badgeOptions, onBadgeUpdate}) => {
}
const Addons = props => {
const [customizeBadgeOpen, setCustomizeOpen] = useState(false);
const [debounce, setDebounce] = useState(undefined);
const [customizeBadgeOpen, setCustomizeOpen] = useState(false)
const [debounce, setDebounce] = useState(undefined)
const [badgeOptions, setBadgeOptions] = useState({
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel
});
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel,
})
useEffect(() => {
setBadgeOptions({
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel,
})
}, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel])
@@ -134,17 +158,18 @@ const Addons = props => {
}
const onCustomizeClick = () => {
setCustomizeOpen(!customizeBadgeOpen);
setCustomizeOpen(!customizeBadgeOpen)
}
const onBadgeUpdate = (option, value) => {
const callback = () => {
let newVal = (option==='badgeLabel' && value==='')?'Profile views':value;
setBadgeOptions({...badgeOptions, [option]: newVal});
props.handleDataChange(option, {target: {value: newVal}})
let newVal =
option === "badgeLabel" && value === "" ? "Profile views" : value
setBadgeOptions({ ...badgeOptions, [option]: newVal })
props.handleDataChange(option, { target: { value: newVal } })
}
clearTimeout(debounce);
setDebounce(setTimeout(callback, 300));
clearTimeout(debounce)
setDebounce(setTimeout(callback, 300))
}
return (
<div className="flex justify-center items-start flex-col w-full px-2 sm:px-6 mb-10">
@@ -155,20 +180,20 @@ const Addons = props => {
inputId="visitors-count"
inputChecked={props.data.visitorsBadge}
onInputChange={() => props.handleCheckChange("visitorsBadge")}
Icon={ customizeBadgeOpen ? XCircleIcon : ToolsIcon }
Icon={customizeBadgeOpen ? XCircleIcon : ToolsIcon}
onIconClick={onCustomizeClick}
>
display visitors count badge
</AddonsItem>
{
customizeBadgeOpen?
<CustomizeBadge
githubName={props.social.github}
badgeOptions={badgeOptions}
onBadgeUpdate={onBadgeUpdate}
/>
: ''
}
{customizeBadgeOpen ? (
<CustomizeBadge
githubName={props.social.github}
badgeOptions={badgeOptions}
onBadgeUpdate={onBadgeUpdate}
/>
) : (
""
)}
<AddonsItem
inputId="github-profile-trophy"
inputChecked={props.data.githubProfileTrophy}
@@ -229,7 +254,7 @@ const Addons = props => {
download
<span
onClick={blogPostPorkflow}
onKeyDown={(e) => e.keyCode === 13 && blogPostPorkflow()}
onKeyDown={e => e.keyCode === 13 && blogPostPorkflow()}
role="button"
tabIndex="0"
style={{ cursor: "pointer", color: "#002ead" }}
+11 -3
View File
@@ -2,8 +2,11 @@ import React from "react"
const Donate = () => {
return (
<>
<div className="text-center text-4xl my-2">Support&nbsp;
<span role="img" aria-label="praying hand emoji">🙏</span>
<div className="text-center text-4xl my-2">
Support&nbsp;
<span role="img" aria-label="praying hand emoji">
🙏
</span>
</div>
<div className="flex flex-col sm:flex-row items-start justify-between">
<div className="w-full sm:w-2/3">
@@ -30,7 +33,12 @@ const Donate = () => {
</div>
</div>
<div className="w-full sm:w-1/3 flex flex-col justify-center items-center">
<span>Tip<span role="img" aria-label="Dollar medal">💰</span></span>
<span>
Tip
<span role="img" aria-label="Dollar medal">
💰
</span>
</span>
{/* Ko-Fi */}
<a
href="https://ko-fi.com/A0A81XXSX"
+11 -7
View File
@@ -80,11 +80,12 @@ const Markdown = props => {
return ""
}
const VisitorsBadge = props => {
let link = "https://komarev.com/ghpvc/?username="
+ props.github
+ `&label=${props.badgeOptions.badgeLabel}`
+ `&color=${props.badgeOptions.badgeColor}`
+ `&style=${props.badgeOptions.badgeStyle}`
let link =
"https://komarev.com/ghpvc/?username=" +
props.github +
`&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}`
if (props.show) {
return (
<>
@@ -97,7 +98,10 @@ const Markdown = props => {
return ""
}
const TwitterBadge = props => {
let link = "https://img.shields.io/twitter/follow/" + props.twitter + "?logo=twitter&style=for-the-badge"
let link =
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) {
return (
<>
@@ -243,7 +247,7 @@ const Markdown = props => {
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle
badgeStyle: props.data.badgeStyle,
}}
/>
</>
+11 -7
View File
@@ -223,11 +223,12 @@ const MarkdownPreview = props => {
)
}
const VisitorsBadgePreview = props => {
let link = "https://komarev.com/ghpvc/?username="
+ props.github
+ `&label=${props.badgeOptions.badgeLabel}`
+ `&color=${props.badgeOptions.badgeColor}`
+ `&style=${props.badgeOptions.badgeStyle}`
let link =
"https://komarev.com/ghpvc/?username=" +
props.github +
`&label=${props.badgeOptions.badgeLabel}` +
`&color=${props.badgeOptions.badgeColor}` +
`&style=${props.badgeOptions.badgeStyle}`
if (props.show) {
return (
<div className="text-left my-2">
@@ -239,7 +240,10 @@ const MarkdownPreview = props => {
return null
}
const TwitterBadgePreview = props => {
let link = "https://img.shields.io/twitter/follow/" + props.twitter + "?logo=twitter&style=for-the-badge"
let link =
"https://img.shields.io/twitter/follow/" +
props.twitter +
"?logo=twitter&style=for-the-badge"
if (props.show) {
return (
<div className="text-left my-2">
@@ -328,7 +332,7 @@ const MarkdownPreview = props => {
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle
badgeStyle: props.data.badgeStyle,
}}
/>
<GithubProfileTrophyPreview
+1 -1
View File
@@ -166,7 +166,7 @@ const Work = props => {
onChange={event => props.handleLinkChange("resume", event)}
/>
</div>
<div className="text-xs sm:text-lg flex flex-col sm:flex-row mb-10 justify-center sm:justify-start items-center sm:items-start w-full px-4 sm:px-0">
<input
id="funFact-prefix"
+21 -28
View File
@@ -120,7 +120,7 @@ const categorizedSkills = {
"bash",
"azure",
"vagrant",
"circleci"
"circleci",
],
},
@@ -140,7 +140,7 @@ const categorizedSkills = {
"codeigniter",
"rails",
"flask",
"quasar"
"quasar",
],
},
@@ -174,21 +174,21 @@ const categorizedSkills = {
static_site_generator: {
title: "Static Site Generators",
skills: [
"gatsby",
"gridsome",
"hugo",
"jekyll",
"nextjs",
"nuxtjs",
"11ty",
"gatsby",
"gridsome",
"hugo",
"jekyll",
"nextjs",
"nuxtjs",
"11ty",
"scully",
"sculpin",
"sapper",
"vuepress"
"vuepress",
],
},
game_engines:{
game_engines: {
title: "Game Engines",
skills: ["unity"],
},
@@ -268,12 +268,10 @@ const icons = {
"https://devicons.github.io/devicon/devicon.git/icons/oracle/oracle-original.svg",
photoshop:
"https://devicons.github.io/devicon/devicon.git/icons/photoshop/photoshop-plain.svg",
xd:
"https://cdn.worldvectorlogo.com/logos/adobe-xd.svg",
xd: "https://cdn.worldvectorlogo.com/logos/adobe-xd.svg",
php:
"https://devicons.github.io/devicon/devicon.git/icons/php/php-original.svg",
perl:
"https://api.iconify.design/logos-perl.svg",
perl: "https://api.iconify.design/logos-perl.svg",
postgresql:
"https://devicons.github.io/devicon/devicon.git/icons/postgresql/postgresql-original-wordmark.svg",
python:
@@ -361,7 +359,7 @@ const icons = {
nextjs: "https://cdn.worldvectorlogo.com/logos/nextjs-3.svg",
reactnative: "https://reactnative.dev/img/header_logo.svg",
mariadb: "https://www.vectorlogo.zone/logos/mariadb/mariadb-icon.svg",
cockroachdb: "https://worldvectorlogo.com/es/download/cockroachdb.svg",
cockroachdb: "https://worldvectorlogo.com/es/download/cockroachdb.svg",
objectivec:
"https://www.vectorlogo.zone/logos/apple_objectivec/apple_objectivec-icon.svg",
clojure:
@@ -389,16 +387,12 @@ const icons = {
"https://devicons.github.io/devicon/devicon.git/icons/ember/ember-original-wordmark.svg",
scikit_learn:
"https://upload.wikimedia.org/wikipedia/commons/0/05/Scikit_learn_logo_small.svg",
quasar:
"https://cdn.quasar.dev/logo/svg/quasar-logo.svg",
quasar: "https://cdn.quasar.dev/logo/svg/quasar-logo.svg",
kibana:
"https://www.vectorlogo.zone/logos/elasticco_kibana/elasticco_kibana-icon.svg",
grafana:
"https://www.vectorlogo.zone/logos/grafana/grafana-icon.svg",
elasticsearch:
"https://www.vectorlogo.zone/logos/elastic/elastic-icon.svg",
circleci:
"https://www.vectorlogo.zone/logos/circleci/circleci-icon.svg",
grafana: "https://www.vectorlogo.zone/logos/grafana/grafana-icon.svg",
elasticsearch: "https://www.vectorlogo.zone/logos/elastic/elastic-icon.svg",
circleci: "https://www.vectorlogo.zone/logos/circleci/circleci-icon.svg",
scully:
"https://raw.githubusercontent.com/scullyio/scully/main/assets/logos/SVG/scullyio-icon.svg",
"11ty":
@@ -406,11 +400,10 @@ const icons = {
sculpin:
"https://gist.githubusercontent.com/vivek32ta/c7f7bf583c1fb1c58d89301ea40f37fd/raw/1782aef8672484698c0dd407f900c4a329ed5bc4/sculpin.svg",
sapper:
"https://raw.githubusercontent.com/bestofjs/bestofjs-webui/master/public/logos/sapper.svg",
"https://raw.githubusercontent.com/bestofjs/bestofjs-webui/master/public/logos/sapper.svg",
vuepress:
"https://raw.githubusercontent.com/AliasIO/wappalyzer/master/src/drivers/webextension/images/icons/VuePress.svg",
unity:
"https://www.vectorlogo.zone/logos/unity3d/unity3d-icon.svg"
unity: "https://www.vectorlogo.zone/logos/unity3d/unity3d-icon.svg",
}
const skillWebsites = {
@@ -542,7 +535,7 @@ const skillWebsites = {
"11ty": "https://www.11ty.dev/",
sapper: "https://sapper.svelte.dev/",
vuepress: "https://vuepress.vuejs.org/",
unity: "https://unity.com/"
unity: "https://unity.com/",
}
const initialSkillState = {}
+38 -14
View File
@@ -42,7 +42,6 @@ const DEFAULT_PREFIX = {
funFact: "⚡ Fun fact",
portfolio: "👨‍💻 All of my projects are available at",
blog: "📝 I regulary write articles on",
}
const DEFAULT_DATA = {
@@ -376,10 +375,14 @@ const IndexPage = () => {
return
}
setPrefix(cache.prefix ? {...DEFAULT_PREFIX, ...cache.prefix} : DEFAULT_PREFIX)
setData(cache.data ? {...DEFAULT_DATA, ...cache.data} : DEFAULT_DATA)
setLink(cache.link ? {...DEFAULT_LINK, ...cache.link} : DEFAULT_LINK)
setSocial(cache.social ? {...DEFAULT_SOCIAL, ...cache.social} : DEFAULT_SOCIAL)
setPrefix(
cache.prefix ? { ...DEFAULT_PREFIX, ...cache.prefix } : DEFAULT_PREFIX
)
setData(cache.data ? { ...DEFAULT_DATA, ...cache.data } : DEFAULT_DATA)
setLink(cache.link ? { ...DEFAULT_LINK, ...cache.link } : DEFAULT_LINK)
setSocial(
cache.social ? { ...DEFAULT_SOCIAL, ...cache.social } : DEFAULT_SOCIAL
)
const cacheSkills = mergeDefaultWithNewDataSkills(
DEFAULT_SKILLS,
@@ -455,6 +458,15 @@ const IndexPage = () => {
}
}
const handleFileInput = e => {
const file = e.target.files[0]
const reader = new FileReader()
reader.readAsText(file, "UTF-8")
reader.onload = () => {
setRestore(reader.result)
}
}
return (
<Layout>
<div className="m-4 sm:p-4">
@@ -532,7 +544,7 @@ const IndexPage = () => {
) : (
""
)}
{(data.twitterBadge && !social.twitter) ? (
{data.twitterBadge && !social.twitter ? (
<div className="warning">
* Please add twitter username to use these add-ons
</div>
@@ -546,7 +558,7 @@ const IndexPage = () => {
tabIndex="0"
role="button"
onClick={handleGenerate}
onKeyDown={(e) => e.keyCode === 13 && handleGenerate()}
onKeyDown={e => e.keyCode === 13 && handleGenerate()}
>
Generate README
</div>
@@ -678,17 +690,29 @@ const IndexPage = () => {
<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="JSON Backup"
placeholder="Paste JSON code or upload file"
value={restore}
onChange={e => setRestore(e.target.value)}
/>
<button
className="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 class="overflow-hidden relative w-64 mt-4 mb-4">
<input
class="cursor-pointer absolute block opacity-0 pin-r pin-t before:cursor-pointer"
type="file"
name="vacancyImageFiles"
onChange={handleFileInput}
/>
<button class="text-xxs sm:text-sm border-2 w-40 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1">
Upload json file
</button>
</div>
</div>
<button
className="mr-5 mb-10 text-xxs sm:text-sm border-2 w-32 border-solid border-gray-900 bg-gray-100 flex items-center justify-center py-1"
onClick={handleRestore}
>
Restore
</button>
<div className="flex flex-col items-start justify-center">
<div className="text-green-700 font-medium">Tips</div>
<div className="text-sm sm:text-lg text-gray-700">