diff --git a/README.md b/README.md index 8e286e2..48fcb32 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,4 @@ It requires Node.js 22 or newer. 6. Run `npm test` to execute the unit tests. 7. When you are satisfied with the results run `npm run export` to generate the static site. * The results of the export can be found in the `out` folder. + diff --git a/__tests__/index.test.jsx b/__tests__/index.test.jsx index 1ce08cc..48fd099 100644 --- a/__tests__/index.test.jsx +++ b/__tests__/index.test.jsx @@ -18,13 +18,13 @@ describe('Home page', () => { it('renders all entry types with links', () => { const entries = [ - { url: 'https://github.com/u', title: 'GitHub', fa: 'fab fa-github', type: 'github' }, - { url: 'https://twitter.com/u', title: 'Twitter', fa: 'fab fa-twitter', type: 'twitter' }, - { url: 'https://www.linkedin.com/in/u', title: 'LinkedIn', fa: 'fab fa-linkedin-in', type: 'linkedin' }, - { url: 'mailto:u@example.com', title: 'Email u@example.com', fa: 'fas fa-at', type: 'email', target: '_self' }, - { url: 'https://bitbucket.org/u', title: 'Bitbucket', fa: 'fab fa-bitbucket', type: 'bitbucket' }, - { url: 'https://stackoverflow.com/users/1', title: 'Stack Overflow', fa: 'fab fa-stack-overflow', type: 'stack-overflow' }, - { url: 'https://stackexchange.com/users/1', title: 'Stack Exchange', fa: 'fab fa-stack-exchange', type: 'stack-exchange' } + { url: 'https://github.com/u', title: 'GitHub', type: 'github' }, + { url: 'https://twitter.com/u', title: 'Twitter', type: 'twitter' }, + { url: 'https://www.linkedin.com/in/u', title: 'LinkedIn', type: 'linkedin' }, + { url: 'mailto:u@example.com', title: 'Email u@example.com', type: 'email', target: '_self' }, + { url: 'https://bitbucket.org/u', title: 'Bitbucket', type: 'bitbucket' }, + { url: 'https://stackoverflow.com/users/1', title: 'Stack Overflow', type: 'stack-overflow' }, + { url: 'https://stackexchange.com/users/1', title: 'Stack Exchange', type: 'stack-exchange' } ]; render(); @@ -40,7 +40,7 @@ describe('Home page', () => { }); it('renders div when entry has no URL', () => { - const entry = { url: null, title: 'Twitter', fa: 'fab fa-twitter', type: 'twitter' }; + const entry = { url: null, title: 'Twitter', type: 'twitter' }; const { container } = render(); const element = container.querySelector('.portfolio__element--twitter'); expect(element.tagName).toBe('DIV'); diff --git a/package-lock.json b/package-lock.json index b306353..ad4b159 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,10 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.0", "next": "15.3.3", "react": "18.2.0", "react-dom": "18.2.0" @@ -669,6 +673,64 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.2.tgz", + "integrity": "sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -7565,7 +7627,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8079,7 +8140,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -8091,7 +8151,6 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/psl": { diff --git a/package.json b/package.json index 18c22f0..e2497b5 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,11 @@ "dependencies": { "next": "15.3.3", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.0" }, "devDependencies": { "@testing-library/jest-dom": "6.1.5", diff --git a/pages/index.js b/pages/index.js index 2c27419..4b0740b 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,5 +1,15 @@ import Head from 'next/head' import Script from 'next/script' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { + faGithub, + faTwitter, + faLinkedinIn, + faBitbucket, + faStackOverflow, + faStackExchange, +} from '@fortawesome/free-brands-svg-icons' +import { faAt } from '@fortawesome/free-solid-svg-icons' export async function getStaticProps() { const fs = require('fs') @@ -43,13 +53,13 @@ export async function getStaticProps() { } } const p = data.portfolio || {} - if (p.github) assign(p.github.order, { url: p.github.username ? `https://github.com/${p.github.username}` : null, title: 'GitHub', fa: 'fab fa-github', type: 'github' }) - if (p.twitter) assign(p.twitter.order, { url: p.twitter.handle ? `https://twitter.com/${p.twitter.handle}` : null, title: 'Twitter', fa: 'fab fa-twitter', type: 'twitter' }) - if (p.linkedIn) assign(p.linkedIn.order, { url: p.linkedIn.username ? `https://www.linkedin.com/in/${p.linkedIn.username}` : null, title: 'LinkedIn', fa: 'fab fa-linkedin-in', type: 'linkedin' }) - if (p.email) assign(p.email.order, { url: p.email.address ? `mailto:${p.email.address}` : null, title: `Email ${p.email.address || 'me'}`, fa: 'fas fa-at', type: 'email', target: '_self' }) - if (p.bitbucket) assign(p.bitbucket.order, { url: p.bitbucket.username ? `https://bitbucket.org/${p.bitbucket.username}` : null, title: 'Bitbucket', fa: 'fab fa-bitbucket', type: 'bitbucket' }) - if (p.stackOverflow) assign(p.stackOverflow.order, { url: p.stackOverflow.id ? `https://stackoverflow.com/users/${p.stackOverflow.id}` : null, title: 'Stack Overflow', fa: 'fab fa-stack-overflow', type: 'stack-overflow' }) - if (p.stackExchange) assign(p.stackExchange.order, { url: p.stackExchange.id ? `https://stackexchange.com/users/${p.stackExchange.id}` : null, title: 'Stack Exchange', fa: 'fab fa-stack-exchange', type: 'stack-exchange' }) + if (p.github) assign(p.github.order, { url: p.github.username ? `https://github.com/${p.github.username}` : null, title: 'GitHub', type: 'github' }) + if (p.twitter) assign(p.twitter.order, { url: p.twitter.handle ? `https://twitter.com/${p.twitter.handle}` : null, title: 'Twitter', type: 'twitter' }) + if (p.linkedIn) assign(p.linkedIn.order, { url: p.linkedIn.username ? `https://www.linkedin.com/in/${p.linkedIn.username}` : null, title: 'LinkedIn', type: 'linkedin' }) + if (p.email) assign(p.email.order, { url: p.email.address ? `mailto:${p.email.address}` : null, title: `Email ${p.email.address || 'me'}`, type: 'email', target: '_self' }) + if (p.bitbucket) assign(p.bitbucket.order, { url: p.bitbucket.username ? `https://bitbucket.org/${p.bitbucket.username}` : null, title: 'Bitbucket', type: 'bitbucket' }) + if (p.stackOverflow) assign(p.stackOverflow.order, { url: p.stackOverflow.id ? `https://stackoverflow.com/users/${p.stackOverflow.id}` : null, title: 'Stack Overflow', type: 'stack-overflow' }) + if (p.stackExchange) assign(p.stackExchange.order, { url: p.stackExchange.id ? `https://stackexchange.com/users/${p.stackExchange.id}` : null, title: 'Stack Exchange', type: 'stack-exchange' }) const portfolioEntries = entries.filter(Boolean) @@ -60,6 +70,16 @@ export async function getStaticProps() { } } +const icons = { + github: faGithub, + twitter: faTwitter, + linkedin: faLinkedinIn, + email: faAt, + bitbucket: faBitbucket, + 'stack-overflow': faStackOverflow, + 'stack-exchange': faStackExchange, +} + export default function Home({ data, headerPictureUrl, faviconUrl, faviconType, portfolioEntries, description }) { return ( <> @@ -69,7 +89,6 @@ export default function Home({ data, headerPictureUrl, faviconUrl, faviconType, {faviconUrl && } -