diff --git a/mdsvex.config.js b/mdsvex.config.js new file mode 100644 index 0000000..7ce363f --- /dev/null +++ b/mdsvex.config.js @@ -0,0 +1,14 @@ +import { defineMDSveXConfig as defineConfig } from 'mdsvex'; +import relativeImages from 'mdsvex-relative-images'; + +const config = defineConfig({ + extensions: ['.svelte.md', '.md', '.svx'], + + smartypants: { + dashes: 'oldschool' + }, + remarkPlugins: [relativeImages], + rehypePlugins: [] +}); + +export default config; diff --git a/package.json b/package.json index 6bb03ba..e9ff93b 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,10 @@ "@sveltejs/adapter-auto": "^1.0.3", "@sveltejs/adapter-static": "^2.0.1", "@sveltejs/adapter-vercel": "^1.0.6", - "@sveltejs/kit": "^1.8.5", + "@sveltejs/kit": "^1.8.7", "@types/postcss-preset-env": "^8.0.0", - "@typescript-eslint/eslint-plugin": "^5.53.0", - "@typescript-eslint/parser": "^5.53.0", + "@typescript-eslint/eslint-plugin": "^5.54.0", + "@typescript-eslint/parser": "^5.54.0", "autoprefixer": "^10.4.7", "eslint": "^8.35.0", "eslint-config-prettier": "^8.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08c72d5..b0a8f39 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,10 +12,10 @@ specifiers: '@sveltejs/adapter-auto': ^1.0.3 '@sveltejs/adapter-static': ^2.0.1 '@sveltejs/adapter-vercel': ^1.0.6 - '@sveltejs/kit': ^1.8.5 + '@sveltejs/kit': ^1.8.7 '@types/postcss-preset-env': ^8.0.0 - '@typescript-eslint/eslint-plugin': ^5.53.0 - '@typescript-eslint/parser': ^5.53.0 + '@typescript-eslint/eslint-plugin': ^5.54.0 + '@typescript-eslint/parser': ^5.54.0 autoprefixer: ^10.4.7 eslint: ^8.35.0 eslint-config-prettier: ^8.5.0 @@ -56,13 +56,13 @@ devDependencies: '@leveluptuts/svelte-toy': 2.0.3 '@playwright/test': 1.31.1 '@rgossiaux/svelte-headlessui': 1.0.2_svelte@3.55.1 - '@sveltejs/adapter-auto': 1.0.3_@sveltejs+kit@1.8.5 - '@sveltejs/adapter-static': 2.0.1_@sveltejs+kit@1.8.5 - '@sveltejs/adapter-vercel': 1.0.6_@sveltejs+kit@1.8.5 - '@sveltejs/kit': 1.8.5_svelte@3.55.1+vite@4.1.4 + '@sveltejs/adapter-auto': 1.0.3_@sveltejs+kit@1.8.7 + '@sveltejs/adapter-static': 2.0.1_@sveltejs+kit@1.8.7 + '@sveltejs/adapter-vercel': 1.0.6_@sveltejs+kit@1.8.7 + '@sveltejs/kit': 1.8.7_svelte@3.55.1+vite@4.1.4 '@types/postcss-preset-env': 8.0.0_postcss@8.4.21 - '@typescript-eslint/eslint-plugin': 5.53.0_cjo54hduev4bqhpjw5znwiokqu - '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/eslint-plugin': 5.54.0_6mj2wypvdnknez7kws2nfdgupi + '@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu autoprefixer: 10.4.13_postcss@8.4.21 eslint: 8.35.0 eslint-config-prettier: 8.6.0_eslint@8.35.0 @@ -716,29 +716,29 @@ packages: picomatch: 2.3.1 dev: true - /@sveltejs/adapter-auto/1.0.3_@sveltejs+kit@1.8.5: + /@sveltejs/adapter-auto/1.0.3_@sveltejs+kit@1.8.7: resolution: {integrity: sha512-hc7O12YQqvZ1CD4fo1gMJuPzBZvuoG5kwxb2RRoz4fVoB8B2vuPO2cY751Ln0G6T/HMrAf8kCqw6Pg+wbxcstw==} peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@sveltejs/kit': 1.8.5_svelte@3.55.1+vite@4.1.4 + '@sveltejs/kit': 1.8.7_svelte@3.55.1+vite@4.1.4 import-meta-resolve: 2.2.1 dev: true - /@sveltejs/adapter-static/2.0.1_@sveltejs+kit@1.8.5: + /@sveltejs/adapter-static/2.0.1_@sveltejs+kit@1.8.7: resolution: {integrity: sha512-o5/q3YwD/ErxYCFlK1v3ydvldyNKk1lh3oeyxn4mhz+Pkbx/uuxhzmbOpytTlp5aVqNHDVsb04xadUzOFCDDzw==} peerDependencies: '@sveltejs/kit': ^1.5.0 dependencies: - '@sveltejs/kit': 1.8.5_svelte@3.55.1+vite@4.1.4 + '@sveltejs/kit': 1.8.7_svelte@3.55.1+vite@4.1.4 dev: true - /@sveltejs/adapter-vercel/1.0.6_@sveltejs+kit@1.8.5: + /@sveltejs/adapter-vercel/1.0.6_@sveltejs+kit@1.8.7: resolution: {integrity: sha512-fo6aaEygPd/6B5Jms4Ff7R4jbADnppuLvKOWBNTGe5MGB7ZRUkl+gxHWMQx2av2knyEZkA6V8y5M6R3ML5yN4g==} peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@sveltejs/kit': 1.8.5_svelte@3.55.1+vite@4.1.4 + '@sveltejs/kit': 1.8.7_svelte@3.55.1+vite@4.1.4 '@vercel/nft': 0.22.6 esbuild: 0.16.17 transitivePeerDependencies: @@ -746,8 +746,8 @@ packages: - supports-color dev: true - /@sveltejs/kit/1.8.5_svelte@3.55.1+vite@4.1.4: - resolution: {integrity: sha512-b6kbjVAivoPd3oL9IVBaZBWiuHeI0qBKfszSDXcqsPfiSMyUK7ilHDFVSWNn+2EMPO48+87iuho71yTCOXZE3w==} + /@sveltejs/kit/1.8.7_svelte@3.55.1+vite@4.1.4: + resolution: {integrity: sha512-DQ2JpuL4iFdA4wQw4f0W6yAxWov4xN9JOxbmt0VOHNcWeqIiEzw4GY8g4Ve5gF4f4cwjSlcxvUmS+mEGCLduLA==} engines: {node: ^16.14 || >=18} hasBin: true requiresBuild: true @@ -852,8 +852,8 @@ packages: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} dev: true - /@typescript-eslint/eslint-plugin/5.53.0_cjo54hduev4bqhpjw5znwiokqu: - resolution: {integrity: sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==} + /@typescript-eslint/eslint-plugin/5.54.0_6mj2wypvdnknez7kws2nfdgupi: + resolution: {integrity: sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -863,10 +863,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu - '@typescript-eslint/scope-manager': 5.53.0 - '@typescript-eslint/type-utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu - '@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/parser': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/scope-manager': 5.54.0 + '@typescript-eslint/type-utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu debug: 4.3.4 eslint: 8.35.0 grapheme-splitter: 1.0.4 @@ -880,8 +880,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: - resolution: {integrity: sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==} + /@typescript-eslint/parser/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -890,9 +890,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.53.0 - '@typescript-eslint/types': 5.53.0 - '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.54.0 + '@typescript-eslint/types': 5.54.0 + '@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5 debug: 4.3.4 eslint: 8.35.0 typescript: 4.9.5 @@ -900,16 +900,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.53.0: - resolution: {integrity: sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==} + /@typescript-eslint/scope-manager/5.54.0: + resolution: {integrity: sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.53.0 - '@typescript-eslint/visitor-keys': 5.53.0 + '@typescript-eslint/types': 5.54.0 + '@typescript-eslint/visitor-keys': 5.54.0 dev: true - /@typescript-eslint/type-utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: - resolution: {integrity: sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==} + /@typescript-eslint/type-utils/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -918,8 +918,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.53.0_ycpbpc6yetojsgtrx3mwntkhsu + '@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5 + '@typescript-eslint/utils': 5.54.0_ycpbpc6yetojsgtrx3mwntkhsu debug: 4.3.4 eslint: 8.35.0 tsutils: 3.21.0_typescript@4.9.5 @@ -928,13 +928,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types/5.53.0: - resolution: {integrity: sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==} + /@typescript-eslint/types/5.54.0: + resolution: {integrity: sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.53.0_typescript@4.9.5: - resolution: {integrity: sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==} + /@typescript-eslint/typescript-estree/5.54.0_typescript@4.9.5: + resolution: {integrity: sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -942,8 +942,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.53.0 - '@typescript-eslint/visitor-keys': 5.53.0 + '@typescript-eslint/types': 5.54.0 + '@typescript-eslint/visitor-keys': 5.54.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -954,17 +954,17 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.53.0_ycpbpc6yetojsgtrx3mwntkhsu: - resolution: {integrity: sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==} + /@typescript-eslint/utils/5.54.0_ycpbpc6yetojsgtrx3mwntkhsu: + resolution: {integrity: sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.53.0 - '@typescript-eslint/types': 5.53.0 - '@typescript-eslint/typescript-estree': 5.53.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.54.0 + '@typescript-eslint/types': 5.54.0 + '@typescript-eslint/typescript-estree': 5.54.0_typescript@4.9.5 eslint: 8.35.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.35.0 @@ -974,11 +974,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.53.0: - resolution: {integrity: sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==} + /@typescript-eslint/visitor-keys/5.54.0: + resolution: {integrity: sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.53.0 + '@typescript-eslint/types': 5.54.0 eslint-visitor-keys: 3.3.0 dev: true diff --git a/src/lib/components/ExternalLink.svelte b/src/lib/components/ExternalLink.svelte index 020f254..309afa0 100644 --- a/src/lib/components/ExternalLink.svelte +++ b/src/lib/components/ExternalLink.svelte @@ -1,10 +1,12 @@ @@ -12,15 +14,14 @@ {#if showIcon} - + {/if} \ No newline at end of file diff --git a/src/lib/content/portfolio/personal-website-gatsby.ts b/src/lib/content/portfolio/personal-website-gatsby.ts new file mode 100644 index 0000000..217c61a --- /dev/null +++ b/src/lib/content/portfolio/personal-website-gatsby.ts @@ -0,0 +1,43 @@ +import meta from '$lib/assets/images/Bradley_Shellnut_New_Site.png?metadata'; +import formatMeta from '$lib/assets/images/Bradley_Shellnut_New_Site.png?format=webp;avif;png&metadata'; +import placeholder from '$lib/assets/images/Bradley_Shellnut_New_Site.png?w=100&png&blur=10'; + +type ImageMeta = { + format: string; + src: string; + type: string; + width: string; + height: string; +}; + +type Sources = { + srcset: URL; + type: string; + width: string; + height: string; +}; + +const { height, src, width }: ImageMeta = meta; + +const sources: Sources[] = []; +const imageFormatsMetadata: ImageMeta[] = JSON.parse(formatMeta); +console.log(`Image format metadata: ${JSON.parse(imageFormatsMetadata)}`); +for (const metadata of imageFormatsMetadata) { + sources.push({ + srcset: new URL(metadata.src), + type: `image/${metadata.format}`, + width: metadata.width, + height: metadata.height + }); +} + +const data = { + alt: 'Home Page of bradleyshellnut.com', + width, + height, + src, + sources, + placeholder +}; + +export { data as default }; diff --git a/src/lib/content/portfolio/personal/old-website.md b/src/lib/content/portfolio/personal/old-website.md new file mode 100644 index 0000000..043cc99 --- /dev/null +++ b/src/lib/content/portfolio/personal/old-website.md @@ -0,0 +1,21 @@ +--- +portfolioName: 'Old Personal Website' +portfolioSubHeading: 'My first personal website.' +portfolioImage: 'Old_Website_Bradley_Shellnut.png' +portfolioImageAlt: 'Home Page of the old bradleyshellnut.com website' +--- + + + +### {portfolioSubHeading} + +This was my first real personal website hosted on DigitalOcean. + +Tech stack: + +- React +- Redux +- ReactStrap for CSS grid management +- React Router for routing links in the page diff --git a/src/lib/content/portfolio/personal/personal-website-gatsby.md b/src/lib/content/portfolio/personal/personal-website-gatsby.md new file mode 100644 index 0000000..61dc2c5 --- /dev/null +++ b/src/lib/content/portfolio/personal/personal-website-gatsby.md @@ -0,0 +1,30 @@ +--- +portfolioName: 'Personal Website' +portfolioSubHeading: 'My personal website written using the following technologies.' +portfolioImage: 'Bradley_Shellnut_New_Site.png' +portfolioImageAlt: 'Home Page of bradleyshellnut.com' +--- + + + +### {portfolioSubHeading} + +Tech Stack: + +- React 18 +- Gatsby 5 +- Radix UI +- Styled Components +- GraphQL +- Deployed using Netlify +- Most icons from react-icons +- Bee, Shell, Nut, and Seattle Icons made by "Freepik" from flaticon.com + +Current version was improved after the suggestions on Show 444 of the Syntax Podcast +Previous archived version of my personal website. diff --git a/src/lib/content/portfolio/personal/wedding-website.md b/src/lib/content/portfolio/personal/wedding-website.md new file mode 100644 index 0000000..1108baa --- /dev/null +++ b/src/lib/content/portfolio/personal/wedding-website.md @@ -0,0 +1,23 @@ +--- +portfolioName: 'Wedding Website' +portfolioSubHeading: 'An application that allows viewing of wedding details and provides the ability to RSVP to the wedding.' +portfolioImage: 'Wedding_Website.png' +portfolioImageAlt: 'Wedding Website' +--- + + + +### {portfolioSubHeading} + +The app was initially created for my wedding but what is linked here is a public demo of the application. + +Tech stack: + +- Next.js 13 +- React 18 +- Radix UI +- MongoDB +- Styled Components +- Next Iron Session diff --git a/src/lib/content/portfolio/professional/mark-shellnut-architect.md b/src/lib/content/portfolio/professional/mark-shellnut-architect.md new file mode 100644 index 0000000..73535cd --- /dev/null +++ b/src/lib/content/portfolio/professional/mark-shellnut-architect.md @@ -0,0 +1,21 @@ +--- +portfolioName: 'Mark Shellnut Architect' +portfolioSubHeading: 'Company website for Mark Shellnut Architect.' +portfolioImage: 'Mark_Shellnut_Architect.png' +portfolioImageAlt: "Picture of Mark Shellnut Architect's Website" +--- + + + +### {portfolioSubHeading} + +Tech stack: + +- React 18 +- Gatsby 5 +- Radix UI +- Styled Components +- GraphQL +- Lambda Functions diff --git a/src/routes/portfolio/+page.server.ts b/src/routes/portfolio/+page.server.ts new file mode 100644 index 0000000..230c200 --- /dev/null +++ b/src/routes/portfolio/+page.server.ts @@ -0,0 +1,28 @@ +import { error } from '@sveltejs/kit'; +import { compile } from 'mdsvex'; +import type { PageServerLoad } from '../$types'; +export const prerender = true; + +export const load: PageServerLoad = async () => { + try { + const personalSiteGatsby = await import( + `../../lib/content/portfolio/personal/personal-website-gatsby.md` + ); + + const { default: page, metadata } = personalSiteGatsby; + + // const [personalSiteGatsbyResponse] = await Promise.all([personalSiteGatsby]); + + console.log(`page: ${JSON.stringify(page)}, metadata: ${JSON.stringify(metadata)}`); + + // const compiledResponse = await compile(personalSiteGatsbyResponse); + + // console.log(`compiledResponse is: ${JSON.stringify(compiledResponse)}`); + return { + portfolios: '' + }; + } catch (e) { + console.error(e); + throw error(500, 'Error loading portfolios'); + } +}; diff --git a/src/routes/portfolio/+page.svelte b/src/routes/portfolio/+page.svelte index 9719bc5..f41e393 100644 --- a/src/routes/portfolio/+page.svelte +++ b/src/routes/portfolio/+page.svelte @@ -1,4 +1,5 @@ @@ -23,346 +37,92 @@

Portfolio!

-
- - - selected ? "tab-selected portfolio-tab" : "tab-unselected portfolio-tab"}> -

Personal Sites

-
- selected ? "tab-selected portfolio-tab" : "tab-unselected portfolio-tab"}> -

Professional Sites

-
-
- - -
-
-
-

Personal Website

- - {#each personalSiteFormats as { src, format }} - - {/each} - -
-
-

- My personal website written using the following - technologies. -

-

Tech Stack:

- -

- Current version was improved after the suggestions on{' '} - - Show 444 - {' '} - of the{' '} - - Syntax Podcast - - . -

-

- Previous archived version of my{' '} - - personal website - - . -

-
-
-
-
-

Wedding Website

-
- - {#each weddingWebsite as { src, format }} - - {/each} - -
-

- - View Site - {' '} - - - -

-

- - Github Repo - {' '} - - - -

-
-
-

- An application that allows viewing of wedding details and - provides the ability to RSVP to the wedding. -

-

- The app was initially created for my wedding but what is - linked here is a public demo of the application. -

-

Tech stack:

-
    -
  • Next.js 13
  • -
  • React 18
  • -
  • - - Radix UI - -
  • -
  • MongoDB
  • -
  • Styled Components
  • -
  • Next Iron Session
  • -
-
-
-
-
-

Old Personal Website

-
- - {#each oldSite as { src, format }} - - {/each} - -
-

- - Link to an archive snapshot - -

-
-
-

- This was my first real personal website hosted on - DigitalOcean. It was built using the following: -

-
    -
  • React
  • -
  • Redux for any state management
  • -
  • ReactStrap for CSS grid management
  • -
  • React Router for routing links in the page
  • -
-
-
-
-
- -
-
-

Mark Shellnut Architect

-
- - {#each shellnutArchitectWebsite as { src, format }} - - {/each} - -
-

- - View Site - {' '} - - - -

-
-
-

Company website for Mark Shellnut Architect.

-

Tech stack:

-
    -
  • React 18
  • -
  • Gatsby 5
  • -
  • - - Radix UI - -
  • -
  • Styled Components
  • -
  • GraphQL
  • -
  • Lambda Functions
  • -
-
-
-
-
-
-
+ + + selected ? "tab-selected portfolio-tab" : "tab-unselected portfolio-tab"}> +

Personal Sites

+
+ selected ? "tab-selected portfolio-tab" : "tab-unselected portfolio-tab"}> +

Professional Sites

+
+
+ + + + + + + +

+ View Site +

+

+ GitHub repository +

+
+ +
+ + +

+ Link to an archive snapshot +

+
+ +
+
+ + + + + + + +
+