diff --git a/.vscode/settings.json b/.vscode/settings.json index 1d2895a..e6e1636 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "cSpell.words": [ "Bandcamp", "bradleyshellnut", + "clazz", "iconify", "Mullvad", "nextjs", diff --git a/src/lib/assets/images/cottage.png b/src/lib/assets/images/cottage.png new file mode 100644 index 0000000..4f92d65 Binary files /dev/null and b/src/lib/assets/images/cottage.png differ diff --git a/src/lib/assets/images/rural.png b/src/lib/assets/images/rural.png new file mode 100644 index 0000000..7aabdc7 Binary files /dev/null and b/src/lib/assets/images/rural.png differ diff --git a/src/lib/components/ExternalLink.svelte b/src/lib/components/ExternalLink.svelte index 3632a52..4e2fcd5 100644 --- a/src/lib/components/ExternalLink.svelte +++ b/src/lib/components/ExternalLink.svelte @@ -6,11 +6,12 @@ export let href: string; export let ariaLabel: string; export let showIcon: boolean = false; + export let clazz = ""; export let icon: IconifyIcon = OpenInNew; - + {#if showIcon} diff --git a/src/lib/types/article.ts b/src/lib/types/article.ts index b93b96c..33d5e60 100644 --- a/src/lib/types/article.ts +++ b/src/lib/types/article.ts @@ -29,3 +29,12 @@ export type WallabagTag = { label: string; slug: string; }; + +export type ArticlePageLoad = { + articles: Article[]; + currentPage: number; + totalPages: number; + limit: number; + totalArticles: number; + cacheControl: string; +}; diff --git a/src/lib/types/courses.ts b/src/lib/types/courses.ts new file mode 100644 index 0000000..b4edbb6 --- /dev/null +++ b/src/lib/types/courses.ts @@ -0,0 +1,12 @@ +export type Course = { + name: string, + externalLinks: ExternalLink[], + tags: string[] +} + +export type ExternalLink = { + ariaLabel: string, + href: string, + showIcon: boolean, + text: string +} \ No newline at end of file diff --git a/src/lib/util/fetchBandcampAlbums.ts b/src/lib/util/fetchBandcampAlbums.ts index 9c01bd1..dbeca6b 100644 --- a/src/lib/util/fetchBandcampAlbums.ts +++ b/src/lib/util/fetchBandcampAlbums.ts @@ -55,5 +55,6 @@ export async function fetchBandcampAlbums() { } } catch (error) { console.error(error); + return []; } } diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index 15731c5..f60e295 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -2,6 +2,8 @@ import type { MetaTagsProps } from 'svelte-meta-tags'; import { PUBLIC_SITE_URL } from '$env/static/public'; import type { PageServerLoad } from './$types'; import { fetchBandcampAlbums } from '$lib/util/fetchBandcampAlbums'; +import type { Album } from '$lib/types/album'; +import type { ArticlePageLoad } from '$lib/types/article'; export const load: PageServerLoad = async ({ fetch, setHeaders, url }) => { let baseUrl = 'https://bradleyshellnut.com'; @@ -41,14 +43,11 @@ export const load: PageServerLoad = async ({ fetch, setHeaders, url }) => { url: currentPageUrl }); - const [albums, articles] = await Promise.all([ + const [albums, articles]: [Album[], ArticlePageLoad] = await Promise.all([ await fetchBandcampAlbums(), (await fetch(`/api/articles?page=1&limit=3`)).json() ]); - console.log('Albums', albums); - console.log('Articles', articles); - setHeaders({ 'cache-control': 'max-age=43200' }); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index a0155e5..333088c 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -3,8 +3,7 @@ import Bandcamp from '$lib/components/bandcamp/index.svelte'; import Articles from '$lib/components/Articles.svelte'; import type { Album } from '$lib/types/album'; - import type { Article } from '$lib/types/article'; - import type { ArticlePageLoad } from './articles/[page]/+page.server'; + import type { Article, ArticlePageLoad } from '$lib/types/article'; export let data: PageData; let albums: Album[]; diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte index a09c104..278983f 100644 --- a/src/routes/about/+page.svelte +++ b/src/routes/about/+page.svelte @@ -9,12 +9,16 @@ import Svelte from '@iconify-icons/simple-icons/svelte'; import TypeScript from '@iconify-icons/simple-icons/typescript'; import LazyImage from '$lib/components/LazyImage.svelte'; - import adventure from '$lib/assets/images/adventure.png?as=run:0'; + import rural from '$lib/assets/images/rural.png?as=run:0'; import tortie_derp from '$lib/assets/images/tortie_derp.jpg?as=run'; import orange_derp from '$lib/assets/images/orange_derp.jpg?as=run'; import turnip from '$lib/assets/images/turnip.svg'; - import Tag from '$lib/components/Tag.svelte'; - import ExternalLink from '$lib/components/ExternalLink.svelte'; + import CourseCard from './CourseCard.svelte'; + import courseData from './course.json'; + import type { Course } from '$root/lib/types/courses'; + import TechListItem from './TechListItem.svelte'; + + const courses: Course[] = courseData.courses;
@@ -44,99 +48,70 @@ At home I delve into other frameworks, languages, and platforms such as:

-
- + - -

React

-
- - -

TypeScript

-
- + + - -

Svelte

-
- + - -

NextJS

-
- + - -

Remix

-
- + - -

GraphQL

-
- + - -

Prisma

-
- + - -

Gatsby

-
- + - -

Docker

-
+ clazz="center" + icon={Docker} + />
@@ -146,113 +121,16 @@ those below:

-
-

- - Wes Bos - -

-
- - - - -
-
-
-

- - Scott Tolinski - - - Level Up Tutorials - -

-
- - - - - - -
-
-
-

- - Amy Kapernick - - - Level Up Tutorials - -

-
- -
-
-
-

- - Andrew Mead - -

-
- - - -
-
-
-

- - Steven Grider - -

-
- - - - - - - -
-
+ {#each courses as course} + + {/each}

Other fun things about me…

- Currently traveling around the world! + Living it up in Mountain View

- -

Traveling around

+ +

Mountain View

-

Bringing these two cats, Turnip and Taco, along for the ride.

+

Hanging out with these two cats, Turnip and Taco.

-

Turnip Turnip

+

Turnip Turnip

@@ -310,31 +188,6 @@ gap: 1rem; margin-top: 1rem; font-size: 2rem; - - & a { - display: grid; - justify-items: center; - - font-weight: bold; - margin-right: 0; - text-decoration: none; - padding: 0.3rem; - margin-left: 1rem; - color: var(--lightGrey); - - & p { - font-size: 1.5rem; - padding-top: 0.3rem; - margin: 0; - } - - &:hover { - color: var(--shellYellow); - & p { - color: var(--shellYellow); - } - } - } } .extracurricular { @@ -343,10 +196,6 @@ place-content: center; gap: 1.5rem; - .card { - max-width: 30rem; - } - @media (max-width: 1000px) { grid-template-columns: repeat(2, auto); --cardHeightMin: 20rem; @@ -358,13 +207,6 @@ } } - .tags { - display: flex; - flex-wrap: wrap; - justify-content: left; - align-items: center; - } - .cat-pics { display: grid; grid-template-columns: repeat(2, minmax(200px, 0.3fr)); diff --git a/src/routes/about/CourseCard.svelte b/src/routes/about/CourseCard.svelte new file mode 100644 index 0000000..d64d9e4 --- /dev/null +++ b/src/routes/about/CourseCard.svelte @@ -0,0 +1,40 @@ + + +
+

+ {#each externalLinks as link} + + {link.text} + + {/each} +

+
+ {#each tags as tag} + + {/each} +
+
+ + \ No newline at end of file diff --git a/src/routes/about/TechListItem.svelte b/src/routes/about/TechListItem.svelte new file mode 100644 index 0000000..dbbbb13 --- /dev/null +++ b/src/routes/about/TechListItem.svelte @@ -0,0 +1,47 @@ + + + + +

{itemText}

+
+ + diff --git a/src/routes/about/course.json b/src/routes/about/course.json new file mode 100644 index 0000000..3014bf9 --- /dev/null +++ b/src/routes/about/course.json @@ -0,0 +1,88 @@ +{ + "courses": [ + { + "name": "Wes Bos", + "externalLinks": [ + { + "ariaLabel": "Wes Bos Courses", + "href": "https://wesbos.com/courses", + "showIcon": true, + "text": "Wes Bos" + } + ], + "tags": ["React", "GraphQL", "Gatsby", "JavaScript"] + }, + { + "name": "Scott Tolinski", + "externalLinks": [ + { + "ariaLabel": "Scott Tolinski", + "href": "https://www.scotttolinski.com", + "showIcon": true, + "text": "Scott Tolinski" + }, + { + "ariaLabel": "Levelup Tutorials", + "href": "https://levelup.video", + "showIcon": true, + "text": "Levelup Tutorials" + } + ], + "tags": ["React", "TypeScript", "Svelte Kit", "Remix", "Figma", "Design Systems"] + }, + { + "name": "Josh Comeau", + "externalLinks": [ + { + "ariaLabel": "Josh Comeau", + "href": "https://www.joshwcomeau.com", + "showIcon": true, + "text": "Josh Comeau" + }, + { + "ariaLabel": "The Joy of React", + "href": "https://www.joyofreact.com/", + "showIcon": true, + "text": "The Joy of React" + } + ], + "tags": ["Full Stack React", "NextJS"] + }, + { + "name": "Amy Kapernick", + "externalLinks": [ + { + "ariaLabel": "Amy Kapernick", + "href": "https://www.amyskapers.dev/", + "showIcon": true, + "text": "Amy Kapernick" + } + ], + "tags": ["Accessibility for Everyone"] + }, + { + "name": "Andrew Mead", + "externalLinks": [ + { + "ariaLabel": "Andrew Mead on Udemy", + "href": "https://www.udemy.com/user/andrewmead/", + "showIcon": true, + "text": "Andrew Mead" + } + ], + "tags": ["GraphQL", "Apollo", "Prisma"] + }, + { + "name": "Steven Grider", + "externalLinks": [ + { + "ariaLabel": "Steven Grider on Udemy", + "href": "https://www.udemy.com/user/sgslo/", + "showIcon": true, + "text": "Steven Grider" + } + ], + "tags": ["React", "Redux", "Docker", "GraphQL", "CSS", "HTML", "JavaScript"] + } + ] +} diff --git a/src/routes/api.ts b/src/routes/api.ts index b6aeac2..5d9ecc2 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -10,7 +10,7 @@ import { USE_REDIS_CACHE } from '$env/static/private'; import intersect from 'just-intersect'; -import type { Article, WallabagArticle } from '$lib/types/article'; +import type { Article, ArticlePageLoad, WallabagArticle } from '$lib/types/article'; import { ArticleTag } from '$lib/types/articleTag'; import type { PageQuery } from '$lib/types/pageQuery'; import { URLSearchParams } from 'url'; @@ -77,7 +77,7 @@ export async function fetchArticlesApi( throw new Error(pageResponse.statusText); } - const cacheControl = pageResponse.headers.get('cache-control'); + const cacheControl = pageResponse.headers.get('cache-control') || 'no-cache'; const { _embedded, page, pages, total, limit } = await pageResponse.json(); const articles: Article[] = []; @@ -101,7 +101,7 @@ export async function fetchArticlesApi( } }); - const responseData = { + const responseData: ArticlePageLoad = { articles, currentPage: page, totalPages: pages > +WALLABAG_MAX_PAGES ? +WALLABAG_MAX_PAGES : pages, diff --git a/src/routes/api/articles/+server.ts b/src/routes/api/articles/+server.ts index a0d42a9..ad6de07 100644 --- a/src/routes/api/articles/+server.ts +++ b/src/routes/api/articles/+server.ts @@ -1,9 +1,8 @@ import { json, error } from '@sveltejs/kit'; import { WALLABAG_MAX_PAGES } from '$env/static/private'; -import type { RequestHandler, RequestEvent } from './$types'; import { fetchArticlesApi } from '$root/routes/api'; -export const GET: RequestHandler = async ({ setHeaders, url }: RequestEvent) => { +export async function GET({ setHeaders, url }) { const page = url?.searchParams?.get('page') || '1'; if (+page > +WALLABAG_MAX_PAGES) { error(404, 'Page does not exist'); diff --git a/src/routes/articles/[page]/+page.server.ts b/src/routes/articles/[page]/+page.server.ts index 8245397..ccd8a50 100644 --- a/src/routes/articles/[page]/+page.server.ts +++ b/src/routes/articles/[page]/+page.server.ts @@ -2,18 +2,9 @@ import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; import { WALLABAG_MAX_PAGES } from '$env/static/private'; import { PUBLIC_SITE_URL } from '$env/static/public'; -import type { Article } from '$lib/types/article'; +import type { ArticlePageLoad } from '$lib/types/article'; import type { MetaTagsProps } from 'svelte-meta-tags'; -export type ArticlePageLoad = { - articles: Article[]; - currentPage: number; - totalPages: number; - limit: number; - totalArticles: number; - cacheControl: string; -}; - export const load: PageServerLoad = async ({ fetch, params, setHeaders, url }) => { const { page } = params; if (+page > +WALLABAG_MAX_PAGES) {