diff --git a/README.md b/README.md index 2426de2..cca5d7a 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,23 @@ const config = { to: '2014', }, ], + // To hide the `Other Projects` section, keep it empty. + externalProjects: [ + { + title: 'Project Name', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + imageUrl: 'https://via.placeholder.com/250x250', + link: 'https://example.com', + }, + { + title: 'Project Name', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + imageUrl: 'https://via.placeholder.com/250x250', + link: 'https://example.com', + }, + ], // Display blog posts from your medium or dev account. (Optional) blog: { source: 'dev', // medium | dev @@ -541,7 +558,9 @@ Empty array will hide the certifications section. ### Projects -Your public repo from GitHub will be displayed here automatically. You can limit how many projects do you want to be displayed. Also, you can hide forked or specific repo. +#### Github Projects + +Your public repo from GitHub will be displayed in the `Github Projects` section automatically. You can limit how many projects do you want to be displayed. Also, you can hide forked or specific repo. ```js // gitprofile.config.js @@ -559,6 +578,25 @@ module.exports = { }; ``` +#### External Projects + +In this section you can showcase your external/personal projects. + +```js +// gitprofile.config.js +module.exports = { + // ... + externalProjects: [ + { + title: 'Project Name', + description: 'Description', + link: 'https://example.com', + imageUrl: 'https://via.placeholder.com/250x250', + }, + ], +}; +``` + ### Blog Posts If you have [medium](https://medium.com) or [dev](https://dev.to) account, you can show your recent blog posts in here just by providing your medium/dev username. You can limit how many posts to display (Max is `10`). diff --git a/gitprofile.config.js b/gitprofile.config.js index 4e1afc7..3547f09 100644 --- a/gitprofile.config.js +++ b/gitprofile.config.js @@ -82,6 +82,25 @@ const config = { to: '2014', }, ], + + // To hide the `Other Projects` section, keep it empty. + externalProjects: [ + { + title: 'Project Name', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + imageUrl: 'https://via.placeholder.com/250x250', + link: 'https://example.com', + }, + { + title: 'Project Name', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + imageUrl: 'https://via.placeholder.com/250x250', + link: 'https://example.com', + }, + ], + // Display blog posts from your medium or dev account. (Optional) blog: { source: 'dev', // medium | dev diff --git a/package-lock.json b/package-lock.json index c3c0113..3b4bf76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@arifszn/gitprofile", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@arifszn/gitprofile", - "version": "2.1.0", + "version": "2.2.0", "license": "MIT", "dependencies": { "react": "^18.2.0", diff --git a/package.json b/package.json index 3a52c21..706fad3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@arifszn/gitprofile", "description": "Create an automatic portfolio based on GitHub profile", - "version": "2.1.0", + "version": "2.2.0", "license": "MIT", "author": "arifszn", "repository": { diff --git a/src/components/GitProfile.jsx b/src/components/GitProfile.jsx index 95d9843..93b7630 100644 --- a/src/components/GitProfile.jsx +++ b/src/components/GitProfile.jsx @@ -25,6 +25,7 @@ import { HelmetProvider } from 'react-helmet-async'; import PropTypes from 'prop-types'; import '../assets/index.css'; import { formatDistance } from 'date-fns'; +import ExternalProject from './external-project'; const bgColor = 'bg-base-300'; @@ -202,6 +203,11 @@ const GitProfile = ({ config }) => { github={sanitizedConfig.github} googleAnalytics={sanitizedConfig.googleAnalytics} /> + { + if ( + externalProjects && + Array.isArray(externalProjects) && + externalProjects.length + ) { + return true; + } else { + return false; + } +}; + +const ExternalProject = ({ externalProjects, loading, googleAnalytics }) => { + const renderSkeleton = () => { + let array = []; + for (let index = 0; index < externalProjects.length; index++) { + array.push( +
+
+
+
+
+
+

+ {skeleton({ + width: 'w-32', + height: 'h-8', + className: 'mb-2 mx-auto', + })} +

+
+
+ {skeleton({ + width: 'w-full', + height: 'h-full', + shape: '', + })} +
+
+
+ {skeleton({ + width: 'w-full', + height: 'h-4', + className: 'mx-auto', + })} +
+
+ {skeleton({ + width: 'w-full', + height: 'h-4', + className: 'mx-auto', + })} +
+
+
+
+
+
+
+ ); + } + + return array; + }; + + const renderExternalProjects = () => { + return externalProjects.map((item, index) => ( + { + e.preventDefault(); + + try { + if (googleAnalytics?.id) { + ga.event({ + action: 'Click External Project', + params: { + post: item.title, + }, + }); + } + } catch (error) { + console.error(error); + } + + window?.open(item.link, '_blank'); + }} + > +
+
+
+
+
+

+ {item.title} +

+ {item.imageUrl && ( +
+
+ +
+
+ )} +

+ {item.description} +

+
+
+
+
+
+
+ )); + }; + + return ( + + {displaySection(externalProjects) && ( +
+
+
+
+
+
+
+ {loading ? ( + skeleton({ width: 'w-40', height: 'h-8' }) + ) : ( + + My Projects + + )} +
+
+
+
+ {loading ? renderSkeleton() : renderExternalProjects()} +
+
+
+
+
+
+
+ )} +
+ ); +}; + +ExternalProject.propTypes = { + externalProjects: PropTypes.array, + loading: PropTypes.bool.isRequired, + googleAnalytics: PropTypes.object, +}; + +export default ExternalProject; diff --git a/src/components/project/index.jsx b/src/components/project/index.jsx index 06d204e..ebec843 100644 --- a/src/components/project/index.jsx +++ b/src/components/project/index.jsx @@ -141,10 +141,10 @@ const Project = ({ repo, loading, github, googleAnalytics }) => {
{loading ? ( - skeleton({ width: 'w-28', height: 'h-8' }) + skeleton({ width: 'w-40', height: 'h-8' }) ) : ( - My Projects + GitHub Projects )}
diff --git a/src/helpers/utils.jsx b/src/helpers/utils.jsx index e4fa356..7a3c22d 100644 --- a/src/helpers/utils.jsx +++ b/src/helpers/utils.jsx @@ -162,6 +162,7 @@ export const sanitizeConfig = (config) => { fileUrl: config?.resume?.fileUrl || '', }, skills: config?.skills || [], + externalProjects: config?.externalProjects || [], experiences: config?.experiences || [], certifications: config?.certifications || [], education: config?.education || [], diff --git a/types/index.d.ts b/types/index.d.ts index 6278739..e8b4482 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -221,6 +221,13 @@ export interface Certifications { link?: string; } +export interface ExternalProjects { + title: string; + description: string; + imageUrl?: string; + link: string; +} + export interface Education { institution?: string; degree?: string; @@ -258,6 +265,11 @@ export interface Config { */ experiences?: Array; + /** + * External Projects + */ + externalProjects?: Array; + /** * Certifications list */