diff --git a/README.md b/README.md index a99413416..6d2ae7cfe 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ ✓ [Certification Section](#certifications) ✓ [Education Section](#education) ✓ [Projects Section](#projects) +✓ [Publication Section](#publications) ✓ [Blog Posts Section](#blog-posts) To view a live example, **[click here](https://arifszn.github.io/gitprofile)**. @@ -210,6 +211,7 @@ const CONFIG = { linkedin: 'ariful-alam', twitter: 'arif_szn', mastodon: 'arifszn@mastodon.social', + researchGate: '', facebook: '', instagram: '', youtube: '', // example: 'pewdiepie' @@ -282,6 +284,17 @@ const CONFIG = { to: '2014', }, ], + publications: [ + { + title: 'Publication Title', + conferenceName: 'Conference Name', + journalName: 'Journal Name', + authors: 'John Doe, Jane Smith', + link: 'https://example.com', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + }, + ], // Display articles from your medium or dev account. (Optional) blog: { source: 'dev', // medium | dev @@ -473,7 +486,7 @@ Your avatar and bio will be fetched from GitHub automatically. ### Social Links -You can link your social media services you're using, including LinkedIn, Twitter, Mastodon, Facebook, Instagram, YouTube, Dribbble, Behance, Medium, dev, Stack Overflow, Skype, Telegram, personal website, phone and email. +You can link your social media services you're using, including LinkedIn, Twitter, Mastodon, ResearchGate, Facebook, Instagram, YouTube, Dribbble, Behance, Medium, dev, Stack Overflow, Skype, Telegram, personal website, phone and email. ```ts // gitprofile.config.ts @@ -483,6 +496,7 @@ const CONFIG = { linkedin: 'ariful-alam', twitter: 'arif_szn', mastodon: 'arifszn@mastodon.social', + researchGate: '', facebook: '', instagram: '', youtube: '', @@ -660,6 +674,30 @@ const CONFIG = { }; ``` +### Publications + +Provide your academic publishing in `publications`. + +```ts +// gitprofile.config.ts +const CONFIG = { + // ... + publications: [ + { + title: 'Publication Title', + conferenceName: 'Conference Name', + journalName: 'Journal Name', + authors: 'John Doe, Jane Smith', + link: 'https://example.com', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc ut.', + }, + ], +}; +``` + +Empty array will hide the publications section. + ### 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.ts b/gitprofile.config.ts index bed1e2c17..fad74326f 100644 --- a/gitprofile.config.ts +++ b/gitprofile.config.ts @@ -60,6 +60,7 @@ const CONFIG = { linkedin: 'ariful-alam', twitter: 'arif_szn', mastodon: 'arifszn@mastodon.social', + researchGate: '', facebook: '', instagram: '', youtube: '', // example: 'pewdiepie' @@ -132,11 +133,31 @@ const CONFIG = { to: '2014', }, ], + publications: [ + { + title: 'Publication Title', + conferenceName: '', + journalName: 'Journal Name', + authors: 'John Doe, Jane Smith', + link: 'https://example.com', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + }, + { + title: 'Publication Title', + conferenceName: 'Conference Name', + journalName: '', + authors: 'John Doe, Jane Smith', + link: 'https://example.com', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + }, + ], // Display articles from your medium or dev account. (Optional) blog: { source: 'dev', // medium | dev username: 'arifszn', // to hide blog section, keep it empty - limit: 3, // How many articles to display. Max is 10. + limit: 2, // How many articles to display. Max is 10. }, googleAnalytics: { id: '', // GA3 tracking id/GA4 tag id UA-XXXXXXXXX-X | G-XXXXXXXXXX diff --git a/global.d.ts b/global.d.ts index 33179e1ff..bff0e6df4 100644 --- a/global.d.ts +++ b/global.d.ts @@ -122,6 +122,11 @@ interface Social { */ mastodon?: string; + /** + * ResearchGate username + */ + researchGate?: string; + /** * Facebook */ @@ -217,6 +222,15 @@ interface Education { to: string; } +interface Publication { + title: string; + conferenceName?: string; + journalName?: string; + authors?: string; + link?: string; + description?: string; +} + interface GoogleAnalytics { /** * GA3 tracking id/GA4 tag id UA-XXXXXXXXX-X | G-XXXXXXXXXX @@ -370,6 +384,11 @@ interface Config { */ educations?: Array; + /** + * Publication list + */ + publications?: Array; + /** * Resume */ diff --git a/package-lock.json b/package-lock.json index bd13b909f..92de716f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@arifszn/gitprofile", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@arifszn/gitprofile", - "version": "3.0.0", + "version": "3.1.0", "license": "MIT", "dependencies": { "react": "^18.2.0", diff --git a/package.json b/package.json index 587257c10..118a81d50 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@arifszn/gitprofile", "description": "Create an automatic portfolio based on GitHub profile", - "version": "3.0.0", + "version": "3.1.0", "type": "module", "license": "MIT", "author": "arifszn", @@ -81,6 +81,7 @@ "github-pages", "github-portfolio", "vite-portfolio", + "academic-portfolio", "github-api" ] } diff --git a/src/components/blog-card/index.tsx b/src/components/blog-card/index.tsx index 2efc8e5d8..37d44e68c 100644 --- a/src/components/blog-card/index.tsx +++ b/src/components/blog-card/index.tsx @@ -132,7 +132,7 @@ const BlogCard = ({
-

+

{article.title}

diff --git a/src/components/certification-card/index.tsx b/src/components/certification-card/index.tsx index bda4ed90b..3394de159 100644 --- a/src/components/certification-card/index.tsx +++ b/src/components/certification-card/index.tsx @@ -19,7 +19,7 @@ const ListItem = ({ style={{ left: '-4.5px' }} >

{year}
-
+
{name} @@ -78,22 +78,15 @@ const CertificationCard = ({ renderSkeleton() ) : ( <> - {certifications - .filter( - (certification) => - certification.year || - certification.name || - certification.body, - ) - .map((certification, index) => ( - - ))} + {certifications.map((certification, index) => ( + + ))} )} diff --git a/src/components/details-card/index.tsx b/src/components/details-card/index.tsx index 39c8c1f33..b8c2a9c80 100644 --- a/src/components/details-card/index.tsx +++ b/src/components/details-card/index.tsx @@ -4,7 +4,7 @@ import { AiFillInstagram, AiFillMediumSquare, } from 'react-icons/ai'; -import { SiTwitter } from 'react-icons/si'; +import { SiTwitter, SiResearchgate } from 'react-icons/si'; import { CgDribbble } from 'react-icons/cg'; import { RiPhoneFill, RiMailFill } from 'react-icons/ri'; import { Fragment } from 'react'; @@ -147,6 +147,14 @@ const DetailsCard = ({ profile, loading, social, github }: Props) => { value={github.username} link={`https://github.com/${github.username}`} /> + {social?.researchGate && ( + } + title="ResearchGate:" + value={social.researchGate} + link={`https://www.researchgate.net/profile/${social.researchGate}`} + /> + )} {social?.twitter && ( } @@ -265,7 +273,6 @@ const DetailsCard = ({ profile, loading, social, github }: Props) => { link={`https://t.me/${social.telegram}`} /> )} - {social?.phone && ( } diff --git a/src/components/education-card/index.tsx b/src/components/education-card/index.tsx index f21568fe1..be52948e3 100644 --- a/src/components/education-card/index.tsx +++ b/src/components/education-card/index.tsx @@ -70,19 +70,14 @@ const EducationCard = ({ renderSkeleton() ) : ( <> - {educations - .filter( - (item) => - item.institution || item.degree || item.from || item.to, - ) - .map((item, index) => ( - - ))} + {educations.map((item, index) => ( + + ))} )} diff --git a/src/components/experience-card/index.tsx b/src/components/experience-card/index.tsx index ff7532269..cc58deabd 100644 --- a/src/components/experience-card/index.tsx +++ b/src/components/experience-card/index.tsx @@ -75,27 +75,19 @@ const ExperienceCard = ({ renderSkeleton() ) : ( - {experiences - .filter( - (experience) => - experience.company || - experience.position || - experience.from || - experience.to, - ) - .map((experience, index) => ( - - ))} + {experiences.map((experience, index) => ( + + ))} )} diff --git a/src/components/external-project-card/index.tsx b/src/components/external-project-card/index.tsx index 4139568bc..b5e1c17e8 100644 --- a/src/components/external-project-card/index.tsx +++ b/src/components/external-project-card/index.tsx @@ -93,7 +93,7 @@ const ExternalProjectCard = ({
-

+

{item.title}

{item.imageUrl && ( diff --git a/src/components/gitprofile.tsx b/src/components/gitprofile.tsx index 7d1ca0fa2..da3b10370 100644 --- a/src/components/gitprofile.tsx +++ b/src/components/gitprofile.tsx @@ -29,6 +29,7 @@ import GithubProjectCard from './github-project-card'; import ExternalProjectCard from './external-project-card'; import BlogCard from './blog-card'; import Footer from './footer'; +import PublicationCard from './publication-card'; /** * Renders the GitProfile component. @@ -255,6 +256,12 @@ const GitProfile = ({ config }: { config: Config }) => { googleAnalyticsId={sanitizedConfig.googleAnalytics.id} /> )} + {sanitizedConfig.publications.length !== 0 && ( + + )} {sanitizedConfig.projects.external.projects.length !== 0 && ( { + const renderSkeleton = () => { + const array = []; + for (let index = 0; index < publications.length; index++) { + array.push( +
+
+
+
+
+
+

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

+

+ {skeleton({ + widthCls: 'w-20', + heightCls: 'h-4', + className: 'mb-2 mx-auto', + })} +

+

+ {skeleton({ + widthCls: 'w-20', + heightCls: 'h-4', + className: 'mb-2 mx-auto', + })} +

+

+ {skeleton({ + widthCls: 'w-full', + heightCls: 'h-4', + className: 'mb-2 mx-auto', + })} +

+

+ {skeleton({ + widthCls: 'w-full', + heightCls: 'h-4', + className: 'mb-2 mx-auto', + })} +

+

+ {skeleton({ + widthCls: 'w-full', + heightCls: 'h-4', + className: 'mb-2 mx-auto', + })} +

+
+
+
+
+
+
, + ); + } + + return array; + }; + + const renderPublications = () => { + return publications.map((item, index) => ( + +
+
+
+
+
+

+ {item.title} +

+ {item.conferenceName && ( +

+ {item.conferenceName} +

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

+ {item.journalName} +

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

+ Author: {item.authors} +

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

+ {item.description} +

+ )} +
+
+
+
+
+
+ )); + }; + + return ( + +
+
+
+
+
+
+
+ {loading ? ( + skeleton({ widthCls: 'w-40', heightCls: 'h-8' }) + ) : ( + + Publications + + )} +
+
+
+
+ {loading ? renderSkeleton() : renderPublications()} +
+
+
+
+
+
+
+
+ ); +}; + +export default PublicationCard; diff --git a/src/interfaces/sanitized-config.tsx b/src/interfaces/sanitized-config.tsx index d860b8587..4f207df1a 100644 --- a/src/interfaces/sanitized-config.tsx +++ b/src/interfaces/sanitized-config.tsx @@ -46,6 +46,7 @@ export interface SanitizedSocial { linkedin?: string; twitter?: string; mastodon?: string; + researchGate?: string; facebook?: string; instagram?: string; youtube?: string; @@ -87,6 +88,15 @@ export interface SanitizedEducation { to: string; } +export interface SanitizedPublication { + title: string; + conferenceName?: string; + journalName?: string; + authors?: string; + link?: string; + description?: string; +} + export interface SanitizedGoogleAnalytics { id?: string; } @@ -132,6 +142,7 @@ export interface SanitizedConfig { experiences: Array; educations: Array; certifications: Array; + publications: Array; googleAnalytics: SanitizedGoogleAnalytics; hotjar: SanitizedHotjar; blog: SanitizedBlog; diff --git a/src/utils/index.tsx b/src/utils/index.tsx index a1df9c334..86ad24501 100644 --- a/src/utils/index.tsx +++ b/src/utils/index.tsx @@ -77,14 +77,30 @@ export const getSanitizedConfig = ( email: config?.social?.email, skype: config?.social?.skype, telegram: config?.social?.telegram, + researchGate: config?.social?.researchGate, }, resume: { fileUrl: config?.resume?.fileUrl || '', }, skills: config?.skills || [], - experiences: config?.experiences || [], - certifications: config?.certifications || [], - educations: config?.educations || [], + experiences: + config?.experiences?.filter( + (experience) => + experience.company || + experience.position || + experience.from || + experience.to, + ) || [], + certifications: + config?.certifications?.filter( + (certification) => + certification.year || certification.name || certification.body, + ) || [], + educations: + config?.educations?.filter( + (item) => item.institution || item.degree || item.from || item.to, + ) || [], + publications: config?.publications?.filter((item) => item.title) || [], googleAnalytics: { id: config?.googleAnalytics?.id, },