Merge pull request #209 from YashKandalkar/profile-badge-customization

[add]: Profile badge customization
This commit is contained in:
Rahul Jain
2020-10-04 09:51:23 +05:30
committed by GitHub
4 changed files with 140 additions and 9 deletions
+112 -3
View File
@@ -1,10 +1,11 @@
import React from "react"
import React, { useState, useEffect } from "react"
import { withPrefix } from "gatsby"
import { latestBlogs } from "../utils/workflows"
import links from "../constants/page-links"
import { isMediumUsernameValid } from "../utils/validation"
import { isMediumUsernameValid, isGitHubUsernameValid } from "../utils/validation"
import { ToolsIcon, XCircleIcon } from "@primer/octicons-react";
const AddonsItem = ({ inputId, inputChecked, onInputChange, ...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">
@@ -16,11 +17,94 @@ const AddonsItem = ({ inputId, inputChecked, onInputChange, ...props }) => {
/>
<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>
:''
}
</div>
)
}
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'}}>
<header className="text-base sm:text-lg">Customize Badge</header>
<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}
>
<option value="flat">Flat</option>
<option value="flat-square">Flat Square</option>
<option value="plastic">Plastic</option>
</select>
</label>
<label htmlFor="badge-color">Color:&nbsp;
<input
type="color"
id="badge-color"
defaultValue={`#${badgeOptions.badgeColor}`}
className="w-6"
onChange={(e) => onBadgeUpdate('badgeColor', e.target.value.replace('#', ''))}
/>
</label>
<label htmlFor="badge-label-text">Label Text:&nbsp;
<input
type="text"
id="badge-label-text"
placeholder="Profile views"
className="w-2/4 bg-gray-300 pl-2"
onChange={(e) => onBadgeUpdate('badgeLabel', e.target.value.trim())}
defaultValue={badgeOptions.badgeLabel}
/>
</label>
<span className="mt-2 flex items-center">
Preview:&nbsp;
{
isGitHubUsernameValid(githubName)?
<img
src={`https://komarev.com/ghpvc/`
+ `?username=${githubName}`
+ `&label=${encodeURI(badgeOptions.badgeLabel)}`
+ `&color=${badgeOptions.badgeColor}`
+ `&style=${badgeOptions.badgeStyle}`
}
/>
: <span className="text-xxs md:text-sm text-red-600">Invalid GitHub username</span>
}
</span>
</div>
</div>
)
}
const Addons = props => {
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
});
useEffect(() => {
setBadgeOptions({
badgeStyle: props.data.badgeStyle,
badgeColor: props.data.badgeColor,
badgeLabel: props.data.badgeLabel
})
}, [props.data.badgeStyle, props.data.badgeColor, props.data.badgeLabel])
const blogPostPorkflow = () => {
let payload = {
dev: {
@@ -48,6 +132,20 @@ const Addons = props => {
tempElement.click()
document.body.removeChild(tempElement)
}
const onCustomizeClick = () => {
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}})
}
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">
<div className="text-xl sm:text-2xl font-bold font-title mt-2 mb-2">
@@ -57,9 +155,20 @@ const Addons = props => {
inputId="visitors-count"
inputChecked={props.data.visitorsBadge}
onInputChange={() => props.handleCheckChange("visitorsBadge")}
Icon={ customizeBadgeOpen ? XCircleIcon : ToolsIcon }
onIconClick={onCustomizeClick}
>
display visitors count badge
</AddonsItem>
{
customizeBadgeOpen?
<CustomizeBadge
githubName={props.social.github}
badgeOptions={badgeOptions}
onBadgeUpdate={onBadgeUpdate}
/>
: ''
}
<AddonsItem
inputId="github-profile-trophy"
inputChecked={props.data.githubProfileTrophy}
+10 -1
View File
@@ -80,7 +80,11 @@ const Markdown = props => {
return ""
}
const VisitorsBadge = props => {
let link = "https://komarev.com/ghpvc/?username=" + props.github
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 (
<>
@@ -223,6 +227,11 @@ const Markdown = props => {
<VisitorsBadge
show={props.data.visitorsBadge}
github={props.social.github}
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle
}}
/>
</>
<>
+10 -1
View File
@@ -222,7 +222,11 @@ const MarkdownPreview = props => {
)
}
const VisitorsBadgePreview = props => {
let link = "https://komarev.com/ghpvc/?username=" + props.github
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">
@@ -308,6 +312,11 @@ const MarkdownPreview = props => {
<VisitorsBadgePreview
show={props.data.visitorsBadge}
github={props.social.github}
badgeOptions={{
badgeLabel: encodeURI(props.data.badgeLabel),
badgeColor: props.data.badgeColor,
badgeStyle: props.data.badgeStyle
}}
/>
<GithubProfileTrophyPreview
show={props.data.githubProfileTrophy}
+8 -4
View File
@@ -54,6 +54,9 @@ const DEFAULT_DATA = {
contact: "",
funFact: "",
visitorsBadge: false,
badgeStyle: "flat",
badgeColor: "0e75b6",
badgeLabel: "Profile views",
githubProfileTrophy: false,
githubStats: false,
topLanguages: false,
@@ -365,10 +368,10 @@ const IndexPage = () => {
return
}
setPrefix(cache.prefix || DEFAULT_PREFIX)
setData(cache.data || DEFAULT_DATA)
setLink(cache.link || DEFAULT_LINK)
setSocial(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,
@@ -470,6 +473,7 @@ const IndexPage = () => {
data={data}
social={social}
handleCheckChange={handleCheckChange}
handleDataChange={handleDataChange}
/>
<div className="section">
{(data.visitorsBadge ||