diff --git a/.babelrc b/.babelrc index f0e761d..854cb73 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,4 @@ -{ - "presets": ["next/babel"], - "plugins": [["styled-components", { "ssr": true }]] -} \ No newline at end of file +{ + "presets": ["next/babel"], + "plugins": [["styled-components", { "ssr": true }]] +} diff --git a/.eslintrc.json b/.eslintrc.json index 15886dc..73a5509 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,7 @@ { - "extends": "next", - "rules": { - "@next/next/no-img-element": "off", - "@next/next/no-document-import-in-page": "off" - } -} \ No newline at end of file + "extends": "next", + "rules": { + "@next/next/no-img-element": "off", + "@next/next/no-document-import-in-page": "off" + } +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76cca52..33f8195 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,40 +4,54 @@ 1. [Fork][fork-link] the repository [Git o Get](https://github.com/Mridul2820/git-o-get/fork). 2. [Clone][clone-link] your new fork of the repository locally. + ``` git clone https://github.com//git-o-get ``` + 3. Set upstream command + ``` git remote add upstream https://github.com/Mridul2820/git-o-get.git ``` + 4. Navigate to the new project directory: + ``` cd git-o-get ``` + 5. Create Your own [branch][branch-link] + ``` git checkout -b ``` + 6. [Run it Locally](https://github.com/Mridul2820/git-o-get#run-locally-) 7. Add yor changes + ``` git add . ``` + 8. Commit your changes with a meaningful message + ``` git checkout -m "" ``` + 9. Push your local commits to the remote repository + ``` git push origin ``` + 10. Create a[ Pull request](pull-request) 11. **Congratulations!** You've made your **first contribution!** 🙌🏼 -[repo-link]: -[branch-link]: -[clone-link]: -[fork-link]: -[syncing-link]: -[pull-request]: +[repo-link]: https://github.com/Mridul2820/git-o-get/fork +[branch-link]: http://guides.github.com/introduction/flow/ +[clone-link]: https://help.github.com/articles/cloning-a-repository/ +[fork-link]: http://guides.github.com/activities/forking/ +[syncing-link]: https://help.github.com/articles/syncing-a-fork +[pull-request]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request/ diff --git a/README.md b/README.md index ca0c099..941a3cc 100644 --- a/README.md +++ b/README.md @@ -17,16 +17,17 @@ License -

## What it does 🤔 + - Just seach your github username and get your profile data in a different way - This app also generates a shareable card dynamically - The card is downloadable also ## Contents 🧧 + - Profile Details - Language Crad - Shareable Social Card @@ -37,6 +38,7 @@ - Most Stared Repository Graph ## Tech Stack 👾 + - [Next JS](https://nextjs.org/) - [Tailwind](https://tailwindcss.com/) - [Recoil](https://recoiljs.org/) @@ -47,50 +49,65 @@ - [Cloudinary](https://cloudinary.com/) ## Demo 🌍 + This app is Deployed to Vercel
[View Demo](https://git-o-get.mridul.tech/) ## SnapShots 💻 + ### Home Page + ### User Detail Page + ## Prerequisites '✔ + Required to install and run the software: -* [Node JS 14+](https://nodejs.org/) -* [NPM](https://www.npmjs.com/get-npm) -* [Cloudinary](https://cloudinary.com/) + +- [Node JS 14+](https://nodejs.org/) +- [NPM](https://www.npmjs.com/get-npm) +- [Cloudinary](https://cloudinary.com/) ## Run Locally 🤠 + 1. Clone the respository locally + ``` git clone https://github.com/Mridul2820/git-o-get.git ``` + 2. Create a `.env` file in the root directory + ``` GITHUB_TOKEN = SITE_URL = CLOUD_NAME = BASE_IMAGE_URL = ``` -- **```GITHUB_TOKEN```: Get your `Personal Access Token` by signing in to your github account and then go to your setting -> developer setting -> Personal access tokens -> Generate new token** -- **```SITE_URL```: Your base URL for the app** -- **```CLOUD_NAME```: Create a [Cloudinary](https://cloudinary.com/users/register/free) account and Get your ```CLOUD NAME```** -- **```BASE_IMAGE_URL```: Upload [Base Image](https://github.com/Mridul2820/git-o-get/blob/main/public/assets/github-social.jpg) in Your Cloudinary Cloud and Get the public Id** + +- **`GITHUB_TOKEN`: Get your `Personal Access Token` by signing in to your github account and then go to your setting -> developer setting -> Personal access tokens -> Generate new token** +- **`SITE_URL`: Your base URL for the app** +- **`CLOUD_NAME`: Create a [Cloudinary](https://cloudinary.com/users/register/free) account and Get your `CLOUD NAME`** +- **`BASE_IMAGE_URL`: Upload [Base Image](https://github.com/Mridul2820/git-o-get/blob/main/public/assets/github-social.jpg) in Your Cloudinary Cloud and Get the public Id** 3. Install the `node_modules` + ``` npm install ``` + 4. Start the Server + ``` npm run dev ``` ## How to contribute? 💻 + Contributing Guide ## All the best! 🥇 diff --git a/client.js b/client.js index 7e73532..6781833 100644 --- a/client.js +++ b/client.js @@ -1,29 +1,29 @@ -import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client"; -import { setContext } from '@apollo/client/link/context'; - -const { GITHUB_TOKEN } = process.env - -// Create the http link -const httpLink = createHttpLink({ - uri: 'https://api.github.com/graphql', -}); - -// Generate and set the header with the auth details -const authLink = setContext((_, { headers }) => { - // get the authentication token from env variables if it exists - const token = GITHUB_TOKEN - - // return the headers to the context so httpLink can read them - return { - headers: { - ...headers, - authorization: `Bearer ${token}`, - } - } -}); - -// Generate your client with the authLink and httpLink -export const client = new ApolloClient({ - cache: new InMemoryCache(), - link: authLink.concat(httpLink) -}); \ No newline at end of file +import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; +import { setContext } from '@apollo/client/link/context'; + +const { GITHUB_TOKEN } = process.env; + +// Create the http link +const httpLink = createHttpLink({ + uri: 'https://api.github.com/graphql', +}); + +// Generate and set the header with the auth details +const authLink = setContext((_, { headers }) => { + // get the authentication token from env variables if it exists + const token = GITHUB_TOKEN; + + // return the headers to the context so httpLink can read them + return { + headers: { + ...headers, + authorization: `Bearer ${token}`, + }, + }; +}); + +// Generate your client with the authLink and httpLink +export const client = new ApolloClient({ + cache: new InMemoryCache(), + link: authLink.concat(httpLink), +}); diff --git a/components/404/NotFound.js b/components/404/NotFound.js index e089129..05ec0dc 100644 --- a/components/404/NotFound.js +++ b/components/404/NotFound.js @@ -1,23 +1,24 @@ -import Link from 'next/link' -import React from 'react' -import { BiArrowBack } from 'react-icons/bi' +import Link from 'next/link'; +import React from 'react'; +import { BiArrowBack } from 'react-icons/bi'; const NotFound = ({ image, message }) => { - return ( -
- not found -

{message}

- - - Back to home - - -
- ) -} + return ( +
+ not found +

{message}

+ + + + Back to home + + +
+ ); +}; -export default NotFound +export default NotFound; diff --git a/components/footer/Footer.js b/components/footer/Footer.js index 802bbf5..9d94024 100644 --- a/components/footer/Footer.js +++ b/components/footer/Footer.js @@ -1,32 +1,33 @@ -import React from 'react' +import React from 'react'; const Footer = () => { - return ( - - ) -} + return ( + + ); +}; -export default Footer +export default Footer; diff --git a/components/graphs/ContributionGraph.js b/components/graphs/ContributionGraph.js index 67f2475..c405173 100644 --- a/components/graphs/ContributionGraph.js +++ b/components/graphs/ContributionGraph.js @@ -1,71 +1,86 @@ -import React from 'react' -import { LineChart, Line, Tooltip, YAxis, XAxis, ResponsiveContainer, CartesianGrid } from 'recharts'; +import React from 'react'; +import { + LineChart, + Line, + Tooltip, + YAxis, + XAxis, + ResponsiveContainer, + CartesianGrid, +} from 'recharts'; import CustomTooltip from '../reuse/CustomTooltip'; -const ContributionGraph = ({ weeks,username }) => { - let contributions = [] - //slicing last 6 weeks - weeks.slice(weeks.length - 6, weeks.length).map((week) => - week.contributionDays.map((contributionCount) => { - contributions.push({ - contributionCount: contributionCount.contributionCount, - date: contributionCount.date - }); - }) - ); +const ContributionGraph = ({ weeks, username }) => { + let contributions = []; + //slicing last 6 weeks + weeks.slice(weeks.length - 6, weeks.length).map((week) => + week.contributionDays.map((contributionCount) => { + contributions.push({ + contributionCount: contributionCount.contributionCount, + date: contributionCount.date, + }); + }) + ); - //returning data of last 31 days - const presentDay = new Date().getDay(); - contributions = contributions.slice( - 5 + presentDay, - 36 + presentDay - ); + //returning data of last 31 days + const presentDay = new Date().getDay(); + contributions = contributions.slice(5 + presentDay, 36 + presentDay); - const tickDate = value => { - const roundVal = new Date(value).getDate(); + const tickDate = (value) => { + const roundVal = new Date(value).getDate(); - return roundVal - } + return roundVal; + }; - return ( -
-

{username}'s Contribution Graph

-

Contributions

-

- Days {'(' + contributions[0].date + ' - ' + contributions.slice(-1)[0].date + ')'} -

-
- - - - } - /> - - - - - -
-
- ) -} + return ( +
+

+ {username}'s Contribution Graph +

+

+ Contributions +

+

+ Days{' '} + + {'(' + + contributions[0].date + + ' - ' + + contributions.slice(-1)[0].date + + ')'} + +

+
+ + + + + } + /> + + + + + +
+
+ ); +}; -export default ContributionGraph +export default ContributionGraph; diff --git a/components/graphs/LanguagePie.js b/components/graphs/LanguagePie.js index 3c73c5a..103d49b 100644 --- a/components/graphs/LanguagePie.js +++ b/components/graphs/LanguagePie.js @@ -1,147 +1,162 @@ import { motion } from 'framer-motion'; import { sumBy } from 'lodash'; -import React, { useState } from 'react' -import { PieChart, Pie, Sector, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts'; +import React, { useState } from 'react'; +import { + PieChart, + Pie, + Sector, + Cell, + ResponsiveContainer, + Tooltip, + Legend, +} from 'recharts'; const LanguagePie = ({ repositories }) => { - const [activeIndex, setActiveIndex] = useState(0) + const [activeIndex, setActiveIndex] = useState(0); - const onPieEnter = index => { - setActiveIndex(index) - }; + const onPieEnter = (index) => { + setActiveIndex(index); + }; - let langObjFull = [] + let langObjFull = []; - repositories?.map(repo => - repo.languages.edges.map(lang => { - langObjFull.push({ - name: lang.node.name, - color: lang.node.color, - size: lang.size - }) - }) - ); + repositories?.map((repo) => + repo.languages.edges.map((lang) => { + langObjFull.push({ + name: lang.node.name, + color: lang.node.color, + size: lang.size, + }); + }) + ); - const allLangs = Array.from(langObjFull.reduce((acc, {size, ...r}) => { + const allLangs = Array.from( + langObjFull + .reduce((acc, { size, ...r }) => { const key = JSON.stringify(r); - const current = acc.get(key) || {...r, size: 0}; - return acc.set(key, {...current, size: current.size + size}); - }, new Map).values()).sort((a, b) => (a.size < b.size ? 1 : -1)); - - const formatLangs = [] + const current = acc.get(key) || { ...r, size: 0 }; + return acc.set(key, { ...current, size: current.size + size }); + }, new Map()) + .values() + ).sort((a, b) => (a.size < b.size ? 1 : -1)); - if(allLangs.length >= 5){ - const mainLangs = allLangs.slice(0, 4) + const formatLangs = []; - const sum_of_other = sumBy(allLangs.slice(4), 'size') + if (allLangs.length >= 5) { + const mainLangs = allLangs.slice(0, 4); - formatLangs.push(...mainLangs,{ - name: 'Others', - color: '#bbb', - size: sum_of_other - }) - } else { - formatLangs.push(...allLangs) - } + const sum_of_other = sumBy(allLangs.slice(4), 'size'); - const sum_of_all_values = sumBy(formatLangs, 'size') + formatLangs.push(...mainLangs, { + name: 'Others', + color: '#bbb', + size: sum_of_other, + }); + } else { + formatLangs.push(...allLangs); + } - const renderActiveShape = ({ cx, cy, innerRadius, outerRadius, startAngle, endAngle, fill }) => { - return ( - - - - - ); - }; + const sum_of_all_values = sumBy(formatLangs, 'size'); - const CustomTooltip = ({ active, payload }) => { - if (active && payload && payload.length) { - return ( -
- {payload[0].name + ': ' + (payload[0].value * 100/(sum_of_all_values)).toFixed(2) + '%'} -
- ); - } - return null; - }; + const renderActiveShape = ({ + cx, + cy, + innerRadius, + outerRadius, + startAngle, + endAngle, + fill, + }) => { + return ( + + + + + ); + }; - const RenderLegend = () => { - return ( -
-
    - {formatLangs?.map((entry, index) => ( -
  • -
    - - {entry.name} - - - {(entry.size * 100/(sum_of_all_values)).toFixed(2) + '%'} - -
  • - ))} -
-
- ); + const CustomTooltip = ({ active, payload }) => { + if (active && payload && payload.length) { + return ( +
+ {payload[0].name + + ': ' + + ((payload[0].value * 100) / sum_of_all_values).toFixed(2) + + '%'} +
+ ); } + return null; + }; + const RenderLegend = () => { return ( - -

Language Card

- - - - - {formatLangs.map((entry, index) => ( - onPieEnter(index)} - /> - ))} - - } - isAnimationActive={true} - /> - - -
- ) -} +
+
    + {formatLangs?.map((entry, index) => ( +
  • +
    + {entry.name} + + {((entry.size * 100) / sum_of_all_values).toFixed(2) + '%'} + +
  • + ))} +
+
+ ); + }; + + return ( + +

Language Card

+ + + + + {formatLangs.map((entry, index) => ( + onPieEnter(index)} + /> + ))} + + } isAnimationActive={true} /> + + +
+ ); +}; -export default LanguagePie +export default LanguagePie; diff --git a/components/graphs/MostForked.js b/components/graphs/MostForked.js index d6d8c5d..2869647 100644 --- a/components/graphs/MostForked.js +++ b/components/graphs/MostForked.js @@ -1,60 +1,72 @@ -import React from 'react' +import React from 'react'; import { truncate } from 'lodash'; -import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, +} from 'recharts'; import CustomTooltip from '../reuse/CustomTooltip'; const MostForked = ({ repos }) => { - const sortByFork = repos.slice(0).sort((a, b) => (a.forkCount > b.forkCount ? -1 : 1)).slice(0, 4) - - const tickFork = value => { - let roundVal = value > 1000 ? (value/1000).toFixed(1) + 'k' : value - - return roundVal - } - - const tickRepo = value => { - let shaortVal = truncate(value, {length: 10}) - - return shaortVal - } - - return ( -
-

Most Forked Repositories

- - - - - - } /> - - - - -
- -

Fork Count

-
-
- ) -} - -export default MostForked + const sortByFork = repos + .slice(0) + .sort((a, b) => (a.forkCount > b.forkCount ? -1 : 1)) + .slice(0, 4); + + const tickFork = (value) => { + let roundVal = value > 1000 ? (value / 1000).toFixed(1) + 'k' : value; + + return roundVal; + }; + + const tickRepo = (value) => { + let shaortVal = truncate(value, { length: 10 }); + + return shaortVal; + }; + + return ( +
+

+ Most Forked Repositories +

+ + + + + + + } + /> + + + + +
+ +

Fork Count

+
+
+ ); +}; + +export default MostForked; diff --git a/components/graphs/MostStar.js b/components/graphs/MostStar.js index aa785b6..1dd7956 100644 --- a/components/graphs/MostStar.js +++ b/components/graphs/MostStar.js @@ -1,61 +1,73 @@ -import React from 'react' +import React from 'react'; import { truncate } from 'lodash'; -import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, +} from 'recharts'; import CustomTooltip from '../reuse/CustomTooltip'; const MostStar = ({ repos }) => { - const sortByFork = repos.slice(0).sort((a, b) => (a.stargazerCount > b.stargazerCount ? -1 : 1)).slice(0, 4) - - const tickFork = value => { - let roundVal = value > 1000 ? (value/1000).toFixed(1) + 'k' : value - - return roundVal - } - - const tickRepo = value => { - let shaortVal = truncate(value, {length: 10}) - - return shaortVal - } - - return ( -
-

Most Stared Repositories

- - - - - - } /> - - - - - -
- -

Star Count

-
-
- ) -} - -export default MostStar + const sortByFork = repos + .slice(0) + .sort((a, b) => (a.stargazerCount > b.stargazerCount ? -1 : 1)) + .slice(0, 4); + + const tickFork = (value) => { + let roundVal = value > 1000 ? (value / 1000).toFixed(1) + 'k' : value; + + return roundVal; + }; + + const tickRepo = (value) => { + let shaortVal = truncate(value, { length: 10 }); + + return shaortVal; + }; + + return ( +
+

+ Most Stared Repositories +

+ + + + + + + } + /> + + + + + +
+ +

Star Count

+
+
+ ); +}; + +export default MostStar; diff --git a/components/loader/PuffLoader.js b/components/loader/PuffLoader.js index 121b77f..e0c502d 100644 --- a/components/loader/PuffLoader.js +++ b/components/loader/PuffLoader.js @@ -1,20 +1,20 @@ -import React from 'react' -import styled, { keyframes } from 'styled-components' +import React from 'react'; +import styled, { keyframes } from 'styled-components'; const PuffLoader = () => { - return ( - - - - - ) -} + return ( + + + + + ); +}; const Loader = styled.span` - position: relative; - width: 120px; - height: 120px; -` + position: relative; + width: 120px; + height: 120px; +`; const ScaleAnim = keyframes` 0% { @@ -23,7 +23,7 @@ const ScaleAnim = keyframes` 100% { transform: scale(1); } -` +`; const OpaAnim = keyframes` 0% { @@ -32,36 +32,40 @@ const OpaAnim = keyframes` 100% { opacity: 0; } -` +`; const Circle1 = styled.span` - position: absolute; - height: 120px; - width: 120px; - opacity: 1; - top: 0px; - left: 0px; - border-width: thick; - border-style: solid; - border-color: #9a65fd; - border-image: initial; - border-radius: 50%; - animation: 2s cubic-bezier(0.165, 0.84, 0.44, 1) -1s infinite normal none running ${ScaleAnim}, cubic-bezier(0.3, 0.61, 0.355, 1) normal none running ${OpaAnim}; -` + position: absolute; + height: 120px; + width: 120px; + opacity: 1; + top: 0px; + left: 0px; + border-width: thick; + border-style: solid; + border-color: #9a65fd; + border-image: initial; + border-radius: 50%; + animation: 2s cubic-bezier(0.165, 0.84, 0.44, 1) -1s infinite normal none running + ${ScaleAnim}, + cubic-bezier(0.3, 0.61, 0.355, 1) normal none running ${OpaAnim}; +`; const Circle2 = styled.span` - position: absolute; - height: 120px; - width: 120px; - opacity: 1; - top: 0px; - left: 0px; - border-width: thick; - border-style: solid; - border-color: #9a65fd; - border-image: initial; - border-radius: 50%; - animation: 2s cubic-bezier(0.165, 0.84, 0.44, 1) 0s infinite normal none running ${ScaleAnim}, cubic-bezier(0.3, 0.61, 0.355, 1) normal none running ${OpaAnim}; -` + position: absolute; + height: 120px; + width: 120px; + opacity: 1; + top: 0px; + left: 0px; + border-width: thick; + border-style: solid; + border-color: #9a65fd; + border-image: initial; + border-radius: 50%; + animation: 2s cubic-bezier(0.165, 0.84, 0.44, 1) 0s infinite normal none + running ${ScaleAnim}, + cubic-bezier(0.3, 0.61, 0.355, 1) normal none running ${OpaAnim}; +`; -export default PuffLoader +export default PuffLoader; diff --git a/components/nav/Navbar.js b/components/nav/Navbar.js index eb9c87f..57f0bf4 100644 --- a/components/nav/Navbar.js +++ b/components/nav/Navbar.js @@ -1,36 +1,35 @@ -import React from 'react' -import Image from 'next/image' -import Link from 'next/link' -import Search from '../reuse/Search' -import { BsGithub } from 'react-icons/bs' - -const Navbar = () => { - - return ( - - ) -} - -export default Navbar +import React from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; +import Search from '../reuse/Search'; +import { BsGithub } from 'react-icons/bs'; + +const Navbar = () => { + return ( + + ); +}; + +export default Navbar; diff --git a/components/profile/ProfileCalendar.js b/components/profile/ProfileCalendar.js index c1250f2..2782f3a 100644 --- a/components/profile/ProfileCalendar.js +++ b/components/profile/ProfileCalendar.js @@ -1,33 +1,34 @@ import { motion } from 'framer-motion'; -import React from 'react' +import React from 'react'; import GitHubCalendar from 'react-github-calendar'; import ReactTooltip from 'react-tooltip'; import styled from 'styled-components'; const ProfileCalendar = ({ username }) => { - return ( - -

- {'@' + username} on GitHub -

- - - -
- ) -} + return ( + +

+ {'@' + username} on + GitHub +

+ + + +
+ ); +}; const CalenderWrap = styled(motion.div)` - .react-activity-calendar__legend-colors { - @media only screen and (max-width: 600px){ - display: none; - } + .react-activity-calendar__legend-colors { + @media only screen and (max-width: 600px) { + display: none; } -` + } +`; -export default ProfileCalendar +export default ProfileCalendar; diff --git a/components/profile/ProfileFollowers.js b/components/profile/ProfileFollowers.js index 6613187..6b3e177 100644 --- a/components/profile/ProfileFollowers.js +++ b/components/profile/ProfileFollowers.js @@ -1,41 +1,42 @@ import Image from 'next/image'; import Link from 'next/link'; -import React from 'react' +import React from 'react'; const ProfileFollowers = ({ username, followers }) => { - return ( -
-

- {'@'}{username} Follwers {'(Total: '}{followers.totalCount}{')'} -

-
- {followers?.nodes.map(follow => ( - - - {follow.login} -
-

- {'@'}{follow.login} -

-

- {follow.name} -

-
-
- - ))} -
-
- ) -} + return ( +
+

+ {'@'} + {username} Follwers {'(Total: '} + {followers.totalCount} + {')'} +

+
+ {followers?.nodes.map((follow) => ( + + + {follow.login} +
+

+ {'@'} + {follow.login} +

+

+ {follow.name} +

+
+
+ + ))} +
+
+ ); +}; -export default ProfileFollowers +export default ProfileFollowers; diff --git a/components/profile/ProfileInfo.js b/components/profile/ProfileInfo.js index bcec3a8..53223bd 100644 --- a/components/profile/ProfileInfo.js +++ b/components/profile/ProfileInfo.js @@ -1,107 +1,104 @@ -import React from 'react' -import Image from 'next/image' +import React from 'react'; +import Image from 'next/image'; import { motion } from 'framer-motion'; -import { BiBuildings } from 'react-icons/bi' -import { IoLocationOutline } from 'react-icons/io5' -import { AiOutlineTwitter } from 'react-icons/ai' -import { BsLink45Deg } from 'react-icons/bs' -import { HiOutlineMail } from 'react-icons/hi' +import { BiBuildings } from 'react-icons/bi'; +import { IoLocationOutline } from 'react-icons/io5'; +import { AiOutlineTwitter } from 'react-icons/ai'; +import { BsLink45Deg } from 'react-icons/bs'; +import { HiOutlineMail } from 'react-icons/hi'; const ProfileInfo = ({ user }) => { - - const setURL = url => { - if (url.protocol === 'https:') { - return url - } else if (url.protocol === 'http:') { - return url - } else { - return 'https://' + url - } + const setURL = (url) => { + if (url.protocol === 'https:') { + return url; + } else if (url.protocol === 'http:') { + return url; + } else { + return 'https://' + url; } - - return ( - -
- {user.login} -
-

- - {'@'}{user.login} - -

-

{user.name}

-
-
-

{user.bio}

-
- {user.company && -
- - {user.company} -
- } - {user.location && -
- - {user.location} -
- } - {user.email && - - } - {user.twitterUsername && - - } - {user.websiteUrl && - - } -
-
- ) -} + }; + + return ( + +
+ {user.login} +
+

+ + {'@'} + {user.login} + +

+

{user.name}

+
+
+

{user.bio}

+
+ {user.company && ( +
+ + {user.company} +
+ )} + {user.location && ( +
+ + {user.location} +
+ )} + {user.email && ( + + )} + {user.twitterUsername && ( + + )} + {user.websiteUrl && ( + + )} +
+
+ ); +}; -export default ProfileInfo +export default ProfileInfo; diff --git a/components/profile/ProfileNums.js b/components/profile/ProfileNums.js index edfdba6..32d137d 100644 --- a/components/profile/ProfileNums.js +++ b/components/profile/ProfileNums.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; import { GoRepo, GoGist } from 'react-icons/go'; import { FiUsers, FiUserPlus } from 'react-icons/fi'; import { AiOutlinePullRequest } from 'react-icons/ai'; @@ -6,111 +6,118 @@ import { VscIssues } from 'react-icons/vsc'; import styled from 'styled-components'; import { motion } from 'framer-motion'; -const ProfileNums = ({ followers, following, total_repos, total_gists, pullRequests, issues }) => { - const items = [ - { - id: 1, - icon: , - label: 'Followers', - title: 'Total Followers', - value: followers, - color: 'green', - }, - { - id: 2, - icon: , - label: 'Following', - title: 'Total Following', - value: following, - color: 'purple', - }, - { - id: 3, - icon: , - label: 'PRs', - title: 'Total Pull Requests', - value: pullRequests, - color: 'blue', - }, - { - id: 4, - icon: , - label: 'Issues', - title: 'Total Issues', - value: issues, - color: 'red', - }, - { - id: 5, - icon: , - label: 'Repos', - title: 'Total Repos', - value: total_repos, - color: 'pink', - }, - { - id: 6, - icon: , - label: 'Gists', - title: 'Total Gists', - value: total_gists, - color: 'yellow', - }, - ]; +const ProfileNums = ({ + followers, + following, + total_repos, + total_gists, + pullRequests, + issues, +}) => { + const items = [ + { + id: 1, + icon: , + label: 'Followers', + title: 'Total Followers', + value: followers, + color: 'green', + }, + { + id: 2, + icon: , + label: 'Following', + title: 'Total Following', + value: following, + color: 'purple', + }, + { + id: 3, + icon: , + label: 'PRs', + title: 'Total Pull Requests', + value: pullRequests, + color: 'blue', + }, + { + id: 4, + icon: , + label: 'Issues', + title: 'Total Issues', + value: issues, + color: 'red', + }, + { + id: 5, + icon: , + label: 'Repos', + title: 'Total Repos', + value: total_repos, + color: 'pink', + }, + { + id: 6, + icon: , + label: 'Gists', + title: 'Total Gists', + value: total_gists, + color: 'yellow', + }, + ]; - return ( - -

User Stats

-
- {items.map((item) => ( -
- {item.icon} -

{item.value}

-

{item.label}

-
- ))} -
-
- ) -} + return ( + +

User Stats

+
+ {items.map((item) => ( +
+ {item.icon} +

{item.value}

+

{item.label}

+
+ ))} +
+
+ ); +}; const Icon = styled.span` - padding: 12px; - border-radius: 999px; + padding: 12px; + border-radius: 999px; - &.pink { - background: #ffe0f0; - color: #da4a91; - } - &.green { - background: #e0fcff; - color: #2caeba; - } - &.purple { - background: #fae6ff; - color: #d355fa; - } - &.red { - background: #ffe6e6; - color: #fa5555; - } - &.blue { - background: #e6e6ff; - color: #5d55fa; - } - &.yellow { - background: #fffbea; - color: #f0b429; - } -` + &.pink { + background: #ffe0f0; + color: #da4a91; + } + &.green { + background: #e0fcff; + color: #2caeba; + } + &.purple { + background: #fae6ff; + color: #d355fa; + } + &.red { + background: #ffe6e6; + color: #fa5555; + } + &.blue { + background: #e6e6ff; + color: #5d55fa; + } + &.yellow { + background: #fffbea; + color: #f0b429; + } +`; -export default ProfileNums +export default ProfileNums; diff --git a/components/reuse/CustomTooltip.js b/components/reuse/CustomTooltip.js index dd99523..8edf2a9 100644 --- a/components/reuse/CustomTooltip.js +++ b/components/reuse/CustomTooltip.js @@ -1,23 +1,28 @@ import React from 'react'; -const CustomTooltip = ({ active, payload, customLabel1, customLabel2, label }) => { +const CustomTooltip = ({ + active, + payload, + customLabel1, + customLabel2, + label, +}) => { + if (active && payload && payload.length) { + return ( +
+

+ {customLabel1} : + {label} +

- if (active && payload && payload.length) { - return ( -
-

- {customLabel1} : - {label} -

- -

- {customLabel2} : - {payload[0].value} -

-
- ); - } - return null; +

+ {customLabel2} : + {payload[0].value} +

+
+ ); + } + return null; }; export default CustomTooltip; diff --git a/components/reuse/Search.js b/components/reuse/Search.js index 8725af3..3fdba5f 100644 --- a/components/reuse/Search.js +++ b/components/reuse/Search.js @@ -1,36 +1,39 @@ -import React from 'react' -import { FaSearch } from 'react-icons/fa' -import { useRouter } from 'next/router' +import React from 'react'; +import { FaSearch } from 'react-icons/fa'; +import { useRouter } from 'next/router'; const Search = ({ height }) => { - const router = useRouter() + const router = useRouter(); - const handleOnSubmit = (event) => { - event.preventDefault(); - - const fields = Array.from(event.currentTarget.elements); - const username = fields.find(field => field.name === 'username')?.value; - - router.push(`/user/${username}`); - } + const handleOnSubmit = (event) => { + event.preventDefault(); - return ( -
- - -
- ) -} + const fields = Array.from(event.currentTarget.elements); + const username = fields.find((field) => field.name === 'username')?.value; -export default Search + router.push(`/user/${username}`); + }; + + return ( +
+ + +
+ ); +}; + +export default Search; diff --git a/components/social/SocialCard.js b/components/social/SocialCard.js index 3bfc482..b9a7441 100644 --- a/components/social/SocialCard.js +++ b/components/social/SocialCard.js @@ -1,77 +1,76 @@ -import React from 'react' -import axios from 'axios' -import fileDownload from "js-file-download"; -import { BsFillCloudDownloadFill } from 'react-icons/bs' -import styled from 'styled-components' -import SocialShare from './SocialShare' +import React from 'react'; +import axios from 'axios'; +import fileDownload from 'js-file-download'; +import { BsFillCloudDownloadFill } from 'react-icons/bs'; +import styled from 'styled-components'; +import SocialShare from './SocialShare'; import PuffLoader from '../loader/PuffLoader'; import { motion } from 'framer-motion'; const SocialCard = ({ ogImageUrl, username, loading }) => { - const handleDownload = (url, filename) => { - axios - .get(url, { - responseType: "blob" - }) - .then((res) => { - fileDownload(res.data, filename); - }); - }; + const handleDownload = (url, filename) => { + axios + .get(url, { + responseType: 'blob', + }) + .then((res) => { + fileDownload(res.data, filename); + }); + }; - return ( - - {loading ? -
- -
- : - <> -
-

Social Card

- - Social card - - - -
- - } -
- ) -} + return ( + + {loading ? ( +
+ +
+ ) : ( + <> +
+

Social Card

+ + Social card + + + +
+ + )} +
+ ); +}; const CradImage = styled.div` - .download { - opacity: 0; - visibility: hidden; - transition: all .5s; - - &:hover { - opacity: 1 !important; - } - } + .download { + opacity: 0; + visibility: hidden; + transition: all 0.5s; &:hover { - .download { - opacity: .9; - visibility: visible; - } + opacity: 1 !important; } + } -` + &:hover { + .download { + opacity: 0.9; + visibility: visible; + } + } +`; -export default SocialCard +export default SocialCard; diff --git a/components/social/SocialShare.js b/components/social/SocialShare.js index 4407b01..4d7cc45 100644 --- a/components/social/SocialShare.js +++ b/components/social/SocialShare.js @@ -1,120 +1,122 @@ -import styled from 'styled-components' -import { FaTwitter, FaLinkedin } from 'react-icons/fa' -import { BiLinkAlt } from 'react-icons/bi' +import styled from 'styled-components'; +import { FaTwitter, FaLinkedin } from 'react-icons/fa'; +import { BiLinkAlt } from 'react-icons/bi'; import { useState } from 'react'; const SocialShare = ({ username }) => { - const { SITE_URL } = process.env - const shareText = `Check out @${username}'s GitHub profile!` - const [copySuccess, setCopySuccess] = useState('Copy to Clipboard'); - - // copy function - const copyToClipBoard = copyMe => { - //Chrome - if (navigator.clipboard != undefined) { - navigator.clipboard.writeText(copyMe).then(() => { - setCopySuccess("Copied!") - console.log('Copying to clipboard was successful!'); - }, (err) => { - console.error('Could not copy text: ', err); - }); + const { SITE_URL } = process.env; + const shareText = `Check out @${username}'s GitHub profile!`; + const [copySuccess, setCopySuccess] = useState('Copy to Clipboard'); + + // copy function + const copyToClipBoard = (copyMe) => { + //Chrome + if (navigator.clipboard != undefined) { + navigator.clipboard.writeText(copyMe).then( + () => { + setCopySuccess('Copied!'); + console.log('Copying to clipboard was successful!'); + }, + (err) => { + console.error('Could not copy text: ', err); } + ); + } - // Internet Explorer - else if(window.clipboardData) { - window.clipboardData.setData("Text", copyMe); - } - }; - - const ShareClass = 'flex justify-center items-center text-white shadow-bs5 hover:shadow-bs2 transition-all duration-200 p-2 rounded-full' - - return ( -
-

Share Card

- - - - - - - - - - - copyToClipBoard(`${SITE_URL}/user/${username}`)} - onMouseEnter={() => setCopySuccess('Copy to Clipboard')} - className={`copy ${ShareClass}`} - > - - - {copySuccess} - - - -
- ) -} + // Internet Explorer + else if (window.clipboardData) { + window.clipboardData.setData('Text', copyMe); + } + }; + + const ShareClass = + 'flex justify-center items-center text-white shadow-bs5 hover:shadow-bs2 transition-all duration-200 p-2 rounded-full'; + + return ( +
+

Share Card

+ + + + + + + + + + + copyToClipBoard(`${SITE_URL}/user/${username}`)} + onMouseEnter={() => setCopySuccess('Copy to Clipboard')} + className={`copy ${ShareClass}`} + > + + + {copySuccess} + + + +
+ ); +}; export const SocialWrap = styled.div` - .facebook { - background-color: #1877F2; - } + .facebook { + background-color: #1877f2; + } - .twitter { - background-color: #1DA1F2; - } + .twitter { + background-color: #1da1f2; + } - .linkedin { - background-color: #0A66C2; - } + .linkedin { + background-color: #0a66c2; + } - .whatsapp { - background-color: #25D366; - } -` + .whatsapp { + background-color: #25d366; + } +`; const CopyMessage = styled.div` - top: -10px; - opacity: 0; - visibility: hidden; - padding: 3px 8px; - transition: all .5s; - - @media screen and (max-width: 760px) { - right: 0; - } -` + top: -10px; + opacity: 0; + visibility: hidden; + padding: 3px 8px; + transition: all 0.5s; -const CopyLink = styled.a` - position: relative; + @media screen and (max-width: 760px) { + right: 0; + } +`; - &:hover { - ${CopyMessage} { - top: -36px; - opacity: 1; - visibility: visible; - } - } +const CopyLink = styled.a` + position: relative; - &.copy { - background-color: #34465D; + &:hover { + ${CopyMessage} { + top: -36px; + opacity: 1; + visibility: visible; } -` - + } + &.copy { + background-color: #34465d; + } +`; -export default SocialShare \ No newline at end of file +export default SocialShare; diff --git a/graphql/Query.js b/graphql/Query.js index 3c8aae3..0a0fd8a 100644 --- a/graphql/Query.js +++ b/graphql/Query.js @@ -1,69 +1,79 @@ -import { gql } from "@apollo/client"; - -export const GET_USER = gql ` - query searchUser($username: String!) { - user(login: $username) { - avatarUrl - name - url - login - bio - websiteUrl - location - company - twitterUsername - email - following { - totalCount - } - pullRequests{ - totalCount - } - issues { - totalCount - } - followers(last: 100) { - totalCount - nodes { - avatarUrl - name - id - login - url - } - } - repositories(orderBy: {field: UPDATED_AT, direction: DESC}, ownerAffiliations: OWNER, isFork: false, privacy: PUBLIC, first: 100){ - totalCount - nodes { - name - url - stargazerCount - forkCount - languages(first: 20) { - edges{ - size - node { - name - color - } - } - } - } - } - gists(orderBy: {field: UPDATED_AT, direction: DESC}, privacy: PUBLIC, first: 100){ - totalCount - } - contributionsCollection { - contributionCalendar { - totalContributions - weeks { - contributionDays { - date - contributionCount - } - } - } - } - } - } -`; \ No newline at end of file +import { gql } from '@apollo/client'; + +export const GET_USER = gql` + query searchUser($username: String!) { + user(login: $username) { + avatarUrl + name + url + login + bio + websiteUrl + location + company + twitterUsername + email + following { + totalCount + } + pullRequests { + totalCount + } + issues { + totalCount + } + followers(last: 100) { + totalCount + nodes { + avatarUrl + name + id + login + url + } + } + repositories( + orderBy: { field: UPDATED_AT, direction: DESC } + ownerAffiliations: OWNER + isFork: false + privacy: PUBLIC + first: 100 + ) { + totalCount + nodes { + name + url + stargazerCount + forkCount + languages(first: 20) { + edges { + size + node { + name + color + } + } + } + } + } + gists( + orderBy: { field: UPDATED_AT, direction: DESC } + privacy: PUBLIC + first: 100 + ) { + totalCount + } + contributionsCollection { + contributionCalendar { + totalContributions + weeks { + contributionDays { + date + contributionCount + } + } + } + } + } + } +`; diff --git a/lib/gtag.js b/lib/gtag.js index 5ad3602..5f9a329 100644 --- a/lib/gtag.js +++ b/lib/gtag.js @@ -1,17 +1,17 @@ -export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID +export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID; // https://developers.google.com/analytics/devguides/collection/gtagjs/pages export const pageview = (url) => { - window.gtag('config', GA_TRACKING_ID, { - page_path: url, - }) -} + window.gtag('config', GA_TRACKING_ID, { + page_path: url, + }); +}; // https://developers.google.com/analytics/devguides/collection/gtagjs/events export const event = ({ action, category, label, value }) => { - window.gtag('event', action, { - event_category: category, - event_label: label, - value: value, - }) -} + window.gtag('event', action, { + event_category: category, + event_label: label, + value: value, + }); +}; diff --git a/next-seo.config.js b/next-seo.config.js index 1119b30..7cf451e 100644 --- a/next-seo.config.js +++ b/next-seo.config.js @@ -1,23 +1,25 @@ -export default { - title: "Git O Get - Github Profile Stats and Graphs in One Place", - description: "Git O Get - Github Profile Stats, Language Graph, Social Card, Contribution Graph, Repository Stats, Graphs and more", - twitter: { - cardType: 'summary_large_image', - }, - openGraph: { - title: "Git O Get - Github Profile Stats and Graphs in One Place", - description: "Git O Get - Github Profile Stats, Language Graph, Social Card, Contribution Graph, Repository Stats, Graphs and more", - type: 'website', - locale: 'en_IN', - url: 'https://git-o-get.mridul.tech', - site_name: 'git-to-get', - images: [ - { - url: "https://res.cloudinary.com/dbxcernxw/image/upload/v1642425441/git-o-get/ogimage_mmpaia.jpg", - width: 2024, - height: 1012, - alt: "Get Your git", - } - ], - } -}; \ No newline at end of file +export default { + title: 'Git O Get - Github Profile Stats and Graphs in One Place', + description: + 'Git O Get - Github Profile Stats, Language Graph, Social Card, Contribution Graph, Repository Stats, Graphs and more', + twitter: { + cardType: 'summary_large_image', + }, + openGraph: { + title: 'Git O Get - Github Profile Stats and Graphs in One Place', + description: + 'Git O Get - Github Profile Stats, Language Graph, Social Card, Contribution Graph, Repository Stats, Graphs and more', + type: 'website', + locale: 'en_IN', + url: 'https://git-o-get.mridul.tech', + site_name: 'git-to-get', + images: [ + { + url: 'https://res.cloudinary.com/dbxcernxw/image/upload/v1642425441/git-o-get/ogimage_mmpaia.jpg', + width: 2024, + height: 1012, + alt: 'Get Your git', + }, + ], + }, +}; diff --git a/next-sitemap.js b/next-sitemap.js index 753f8c5..1424f7a 100644 --- a/next-sitemap.js +++ b/next-sitemap.js @@ -1,19 +1,16 @@ -const { SITE_URL } = process.env +const { SITE_URL } = process.env; -const siteUrl = SITE_URL +const siteUrl = SITE_URL; module.exports = { - siteUrl, - generateRobotsTxt: true, - robotsTxtOptions: { - policies: [ - { userAgent: "*", disallow: "/500" }, - { userAgent: "*", allow: "/" }, - ], - additionalSitemaps: [ - `${siteUrl}/sitemap.xml`, - ], - }, - exclude: ["/500"], + siteUrl, + generateRobotsTxt: true, + robotsTxtOptions: { + policies: [ + { userAgent: '*', disallow: '/500' }, + { userAgent: '*', allow: '/' }, + ], + additionalSitemaps: [`${siteUrl}/sitemap.xml`], + }, + exclude: ['/500'], }; - \ No newline at end of file diff --git a/next.config.js b/next.config.js index 059fe3b..a2a6bde 100644 --- a/next.config.js +++ b/next.config.js @@ -1,30 +1,24 @@ -const path = require('path') -require('dotenv').config() +const path = require('path'); +require('dotenv').config(); module.exports = { - env: { - GITHUB_TOKEN: process.env.GITHUB_TOKEN, - SITE_URL: process.env.SITE_URL, - CLOUD_NAME: process.env.CLOUD_NAME, - BASE_IMAGE_URL: process.env.BASE_IMAGE_URL, - NEXT_PUBLIC_GA_ID: process.env.NEXT_PUBLIC_GA_ID, - }, - publicRuntimeConfig: {}, - images: { - formats: [ - 'image/avif', - 'image/webp' - ], - domains: [ - 'localhost', - 'avatars.githubusercontent.com' - ] - }, + env: { + GITHUB_TOKEN: process.env.GITHUB_TOKEN, + SITE_URL: process.env.SITE_URL, + CLOUD_NAME: process.env.CLOUD_NAME, + BASE_IMAGE_URL: process.env.BASE_IMAGE_URL, + NEXT_PUBLIC_GA_ID: process.env.NEXT_PUBLIC_GA_ID, + }, + publicRuntimeConfig: {}, + images: { + formats: ['image/avif', 'image/webp'], + domains: ['localhost', 'avatars.githubusercontent.com'], + }, - webpack: (config) => { - config.resolve.alias['components'] = path.join(__dirname, 'components') - config.resolve.alias['public'] = path.join(__dirname, 'public') + webpack: (config) => { + config.resolve.alias['components'] = path.join(__dirname, 'components'); + config.resolve.alias['public'] = path.join(__dirname, 'public'); - return config - }, -} + return config; + }, +}; diff --git a/pages/404.js b/pages/404.js index c88a05c..35d9b9c 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,13 +1,10 @@ -import React from 'react' -import NotFound from '../components/404/NotFound' +import React from 'react'; +import NotFound from '../components/404/NotFound'; const Custom404 = () => { - return ( - - ) -} + return ( + + ); +}; -export default Custom404 +export default Custom404; diff --git a/pages/500.js b/pages/500.js index 8a3b2cd..e4e6048 100644 --- a/pages/500.js +++ b/pages/500.js @@ -1,13 +1,8 @@ -import React from 'react' -import NotFound from '../components/404/NotFound' +import React from 'react'; +import NotFound from '../components/404/NotFound'; const Custom500 = () => { - return ( - - ) -} + return ; +}; -export default Custom500 +export default Custom500; diff --git a/pages/_app.js b/pages/_app.js index 7e6041c..57f9b7d 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,26 +1,26 @@ -import { RecoilRoot } from 'recoil' -import '../styles/globals.css' +import { RecoilRoot } from 'recoil'; +import '../styles/globals.css'; // SEO -import { DefaultSeo } from 'next-seo' -import SEO from '../next-seo.config' +import { DefaultSeo } from 'next-seo'; +import SEO from '../next-seo.config'; // apollo -import { ApolloProvider } from '@apollo/client' -import { client } from '../client' +import { ApolloProvider } from '@apollo/client'; +import { client } from '../client'; -import Footer from '../components/footer/Footer' +import Footer from '../components/footer/Footer'; function MyApp({ Component, pageProps }) { - return ( - - - - -