mirror of
https://github.com/BradNut/personal-website-sveltekit
synced 2025-09-08 23:20:18 +00:00
Svelte 5 for portfolio page.
This commit is contained in:
parent
e6a2f8fcb6
commit
e8c6b83a1e
6 changed files with 132 additions and 65 deletions
|
|
@ -63,6 +63,7 @@
|
|||
"@resvg/resvg-js": "^2.6.2",
|
||||
"@sveltejs/adapter-vercel": "^5.5.0",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@unpic/svelte": "^0.0.56",
|
||||
"@vercel/og": "^0.6.4",
|
||||
"bits-ui": "^0.21.16",
|
||||
"flexsearch": "^0.7.43",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ importers:
|
|||
'@types/nprogress':
|
||||
specifier: ^0.2.3
|
||||
version: 0.2.3
|
||||
'@unpic/svelte':
|
||||
specifier: ^0.0.56
|
||||
version: 0.0.56(svelte@5.3.1)
|
||||
'@vercel/og':
|
||||
specifier: ^0.6.4
|
||||
version: 0.6.4
|
||||
|
|
@ -1395,6 +1398,14 @@ packages:
|
|||
'@types/unist@2.0.6':
|
||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||
|
||||
'@unpic/core@0.0.52':
|
||||
resolution: {integrity: sha512-XRX0ePG0nH/K9x/coCQwFzSzg66INBNgPZR2FeSis6BHyxw3sBjL4KDzYse6d/Zx0F3APWsWkK2htaGRznjHMw==}
|
||||
|
||||
'@unpic/svelte@0.0.56':
|
||||
resolution: {integrity: sha512-YkZaHLYEQycs4MoBH0YXt29hdSaS6RoUOpSf1IaZ4MnfJOrRcjpAxIsN8uMaLu8g7IyxO9dWHmPmmECpKluA5g==}
|
||||
peerDependencies:
|
||||
svelte: '*'
|
||||
|
||||
'@vercel/nft@0.27.1':
|
||||
resolution: {integrity: sha512-K6upzYHCV1cq2gP83r1o8uNV1vwvAlozvMqp7CEjYWxo0CMI8/4jKcDkVjlypVhrfZ54SXwh9QbH0ZIk/vQCsw==}
|
||||
engines: {node: '>=16'}
|
||||
|
|
@ -2634,6 +2645,9 @@ packages:
|
|||
strip-literal@2.1.0:
|
||||
resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
|
||||
|
||||
style-object-to-css-string@1.1.3:
|
||||
resolution: {integrity: sha512-bISQoUsir/qGfo7vY8rw00ia9nnyE1jvYt3zZ2jhdkcXZ6dAEi74inMzQ6On57vFI+I4Fck6wOv5UI9BEwJDgw==}
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -2789,6 +2803,9 @@ packages:
|
|||
unist-util-visit@3.1.0:
|
||||
resolution: {integrity: sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==}
|
||||
|
||||
unpic@3.20.0:
|
||||
resolution: {integrity: sha512-reWY4Ez9FCjw8J7fGByyyi1Z1fv20xjkFgDa9xI7vqdg89fcLzUYkROKo7yZ5WHRelq6x+pL4ohPRzEdU020aQ==}
|
||||
|
||||
update-browserslist-db@1.1.0:
|
||||
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
||||
hasBin: true
|
||||
|
|
@ -3944,6 +3961,17 @@ snapshots:
|
|||
|
||||
'@types/unist@2.0.6': {}
|
||||
|
||||
'@unpic/core@0.0.52':
|
||||
dependencies:
|
||||
unpic: 3.20.0
|
||||
|
||||
'@unpic/svelte@0.0.56(svelte@5.3.1)':
|
||||
dependencies:
|
||||
'@unpic/core': 0.0.52
|
||||
style-object-to-css-string: 1.1.3
|
||||
svelte: 5.3.1
|
||||
unpic: 3.20.0
|
||||
|
||||
'@vercel/nft@0.27.1':
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 1.0.11
|
||||
|
|
@ -5335,6 +5363,8 @@ snapshots:
|
|||
dependencies:
|
||||
js-tokens: 9.0.0
|
||||
|
||||
style-object-to-css-string@1.1.3: {}
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
svelte-check@4.1.0(picomatch@4.0.2)(svelte@5.3.1)(typescript@5.7.2):
|
||||
|
|
@ -5483,6 +5513,8 @@ snapshots:
|
|||
unist-util-is: 5.2.0
|
||||
unist-util-visit-parents: 4.1.1
|
||||
|
||||
unpic@3.20.0: {}
|
||||
|
||||
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
||||
dependencies:
|
||||
browserslist: 4.23.3
|
||||
|
|
|
|||
|
|
@ -1,21 +1,30 @@
|
|||
<script lang="ts">
|
||||
import LazyImage from './LazyImage.svelte';
|
||||
import type { Picture } from 'vite-imagetools';
|
||||
import type { Snippet } from 'svelte';
|
||||
import { ExternalLinkType } from '../types/externalLinkType';
|
||||
|
||||
export let name: string;
|
||||
export let src: Record<string, any>;
|
||||
export let alt: string;
|
||||
export let style = "";
|
||||
export let loading: "lazy" | "eager" = "lazy";
|
||||
const {
|
||||
links,
|
||||
details,
|
||||
portfolioDetails,
|
||||
externalLinks,
|
||||
name,
|
||||
src,
|
||||
alt,
|
||||
style,
|
||||
fetchpriority = 'auto',
|
||||
loading = 'lazy',
|
||||
}: { links: Snippet<ExternalLinkType[]>, details: Snippet<string>, portfolioDetails: string, externalLinks: ExternalLinkType[], name: string; src: string | Picture; alt: string; style: string; fetchpriority?: 'high' | 'low' | 'auto'; loading?: 'lazy' | 'eager' } = $props();
|
||||
</script>
|
||||
|
||||
<div class="portfolio">
|
||||
<div class="portfolio-picture">
|
||||
<h2>{name}</h2>
|
||||
<LazyImage {style} {src} {alt} {loading} />
|
||||
<slot name="portfolio-links" />
|
||||
<enhanced:img {src} {style} {alt} {fetchpriority} {loading} />
|
||||
{@render links(externalLinks)}
|
||||
</div>
|
||||
<div class="portfolio-details">
|
||||
<slot name="portfolio-details" />
|
||||
{@render details()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
9
src/lib/types/externalLinkType.ts
Normal file
9
src/lib/types/externalLinkType.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import type { IconifyIcon } from "iconify-icon";
|
||||
|
||||
export type ExternalLinkType = {
|
||||
ariaLabel: string;
|
||||
href: string;
|
||||
icon?: IconifyIcon;
|
||||
showIcon: boolean;
|
||||
text: string;
|
||||
};
|
||||
|
|
@ -43,10 +43,10 @@ export const load: PageServerLoad = async ({ fetch, setHeaders, url }) => {
|
|||
url: currentPageUrl
|
||||
});
|
||||
|
||||
const [albums, articles]: [Album[], ArticlePageLoad] = await Promise.all([
|
||||
await fetchBandcampAlbums(),
|
||||
(await fetch('/api/articles?page=1&limit=3')).json()
|
||||
]);
|
||||
// const [albums, articles]: [Album[], ArticlePageLoad] = await Promise.all([
|
||||
// await fetchBandcampAlbums(),
|
||||
// (await fetch('/api/articles?page=1&limit=3')).json()
|
||||
// ]);
|
||||
|
||||
setHeaders({
|
||||
'cache-control': 'max-age=43200'
|
||||
|
|
@ -54,7 +54,7 @@ export const load: PageServerLoad = async ({ fetch, setHeaders, url }) => {
|
|||
return {
|
||||
baseUrl,
|
||||
metaTagsChild: metaTags,
|
||||
albums,
|
||||
articlesData: articles
|
||||
albums: await fetchBandcampAlbums(),
|
||||
articlesData: await (await fetch('/api/articles?page=1&limit=3')).json()
|
||||
};
|
||||
};
|
||||
|
|
@ -1,33 +1,53 @@
|
|||
<script lang="ts">
|
||||
import { createTabs, melt } from '@melt-ui/svelte';
|
||||
import GitHub from '@iconify-icons/simple-icons/github';
|
||||
import Portfolio from '$lib/components/Portfolio.svelte';
|
||||
import personalSite from "$lib/assets/images/portfolio/Bradley_Shellnut_New_Site.png?as=run";
|
||||
import weddingWebsite from "$lib/assets/images/portfolio/Wedding_Website.png?as=run";
|
||||
import oldSite from '$lib/assets/images/portfolio/Old_Website_Bradley_Shellnut.png?as=run';
|
||||
import shellnutArchitectWebsite from "$lib/assets/images/portfolio/Mark_Shellnut_Architect.png?as=run";
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import PersonalWebsiteSvelteKit from "$lib/content/portfolio/personal/personal-website-sveltekit.md";
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import WeddingWebsite from '$lib/content/portfolio/personal/wedding-website.md';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import MarkShellnutArchitect from '$lib/content/portfolio/professional/mark-shellnut-architect.md';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import OldWebsite from '$lib/content/portfolio/personal/old-website.md';
|
||||
import ExternalLink from '$lib/components/ExternalLink.svelte';
|
||||
import ExternalLink from '$lib/components/ExternalLink.svelte';
|
||||
import Portfolio from '$lib/components/Portfolio.svelte';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import OldWebsite from '$lib/content/portfolio/personal/old-website.md';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import PersonalWebsiteSvelteKit from '$lib/content/portfolio/personal/personal-website-sveltekit.md';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import WeddingWebsite from '$lib/content/portfolio/personal/wedding-website.md';
|
||||
// @ts-expect-error: Cannot find module '$lib/content/uses/development.md' or its corresponding type declarations.ts(2307)
|
||||
import MarkShellnutArchitect from '$lib/content/portfolio/professional/mark-shellnut-architect.md';
|
||||
import type { ExternalLinkType } from '$lib/types/externalLinkType';
|
||||
import GitHub from '@iconify-icons/simple-icons/github';
|
||||
import { createTabs, melt } from '@melt-ui/svelte';
|
||||
import personalSite from '../../lib/assets/images/portfolio/Bradley_Shellnut_New_Site.png?enhanced';
|
||||
import shellnutArchitectWebsite from '../../lib/assets/images/portfolio/Mark_Shellnut_Architect.png?enhanced';
|
||||
import oldSite from '../../lib/assets/images/portfolio/Old_Website_Bradley_Shellnut.png?enhanced';
|
||||
import weddingWebsite from '../../lib/assets/images/portfolio/Wedding_Website.png?enhanced';
|
||||
|
||||
const {
|
||||
elements: { root, list, content, trigger }
|
||||
} = createTabs({
|
||||
defaultValue: 'personal'
|
||||
});
|
||||
const {
|
||||
elements: { root, list, content, trigger },
|
||||
} = createTabs({
|
||||
defaultValue: 'personal',
|
||||
});
|
||||
|
||||
const triggers = [
|
||||
{ id: 'personal', title: 'Personal Sites' },
|
||||
{ id: 'professional', title: 'Professional Sites'}
|
||||
];
|
||||
const triggers = [
|
||||
{ id: 'personal', title: 'Personal Sites' },
|
||||
{ id: 'professional', title: 'Professional Sites' },
|
||||
];
|
||||
</script>
|
||||
|
||||
{#snippet links(externalLinks: ExternalLinkType[])}
|
||||
<span>
|
||||
{#each externalLinks as link}
|
||||
<ExternalLink
|
||||
ariaLabel={link.ariaLabel}
|
||||
href={link.href}
|
||||
icon={link.icon}
|
||||
showIcon={link.showIcon}
|
||||
>
|
||||
{link.text}
|
||||
</ExternalLink>
|
||||
{/each}
|
||||
</span>
|
||||
{/snippet}
|
||||
|
||||
{#snippet details(portfolioDetails: string)}
|
||||
{portfolioDetails}
|
||||
{/snippet}
|
||||
|
||||
<h1>Portfolio!</h1>
|
||||
<div use:melt={$root} class="root tab-group">
|
||||
<div use:melt={$list} aria-label="tabs portfolios" class="list tab-list">
|
||||
|
|
@ -42,42 +62,38 @@
|
|||
style="max-height: 550px;"
|
||||
src={personalSite}
|
||||
loading="eager"
|
||||
alt="Picture of Bradley Shellnut's Personal Website">
|
||||
<span slot="portfolio-links">
|
||||
<ExternalLink ariaLabel="View GitHub repository for my personal website" href="https://github.com/BradNut/personal-website-sveltekit" icon={GitHub} showIcon>GitHub repository</ExternalLink>
|
||||
</span>
|
||||
<PersonalWebsiteSvelteKit slot="portfolio-details" />
|
||||
alt="Picture of Bradley Shellnut's Personal Website"
|
||||
{links}
|
||||
{details}
|
||||
portfolioDetails={PersonalWebsiteSvelteKit}
|
||||
externalLinks={[{ ariaLabel: 'View GitHub repository for my personal website', href: 'https://github.com/BradNut/personal-website-sveltekit', icon: GitHub, showIcon: true, text: 'GitHub repository'}]}>
|
||||
</Portfolio>
|
||||
<Portfolio name="Wedding Website"
|
||||
style="max-height: 550px;"
|
||||
src={weddingWebsite}
|
||||
alt="Picture of NextJS Wedding Website">
|
||||
<span slot="portfolio-links">
|
||||
<ExternalLink ariaLabel="View Wedding Website" href="https://weddingsite-six.vercel.app/" showIcon>View Site</ExternalLink>
|
||||
<ExternalLink ariaLabel="View GitHub repository for the wedding site" href="https://github.com/BradNut/weddingsite" icon={GitHub} showIcon>GitHub repository</ExternalLink>
|
||||
</span>
|
||||
<WeddingWebsite slot="portfolio-details" />
|
||||
</Portfolio>
|
||||
<Portfolio name="Old Personal Website"
|
||||
alt="Picture of NextJS Wedding Website"
|
||||
{links}
|
||||
{details}
|
||||
portfolioDetails={WeddingWebsite}
|
||||
externalLinks={[{ ariaLabel: 'View GitHub repository for the wedding site', href: 'https://github.com/BradNut/weddingsite', icon: GitHub, showIcon: true, text: 'GitHub repository'}]}/>
|
||||
<Portfolio name="Old Personal Website"
|
||||
style="max-height: 320px;"
|
||||
src={oldSite}
|
||||
alt="Home Page of the old bradleyshellnut.com website">
|
||||
<span slot="portfolio-links">
|
||||
<ExternalLink ariaLabel="Archive of bradleyshellnut.com" href="https://web.archive.org/web/20201205233507/https://bradleyshellnut.com/about" showIcon>Link to an archive snapshot</ExternalLink>
|
||||
</span>
|
||||
<OldWebsite slot="portfolio-details" />
|
||||
</Portfolio>
|
||||
alt="Home Page of the old bradleyshellnut.com website"
|
||||
{links}
|
||||
{details}
|
||||
portfolioDetails={OldWebsite}
|
||||
externalLinks={[{ ariaLabel: 'Archive of bradleyshellnut.com', href: 'https://web.archive.org/web/20201205233507/https://bradleyshellnut.com/about', icon: GitHub, showIcon: true, text: 'Link to an archive snapshot'}]}/>
|
||||
</div>
|
||||
<div use:melt={$content('professional')} class="content">
|
||||
<Portfolio name="Mark Shellnut Architect"
|
||||
style="max-height: 550px;"
|
||||
src={shellnutArchitectWebsite}
|
||||
alt="Picture of Mark Shellnut Architect's Website">
|
||||
<span slot="portfolio-links">
|
||||
<ExternalLink ariaLabel="View markshellnutarchitect.com" href="https://markshellnutarchitect.com" showIcon>Link to Mark Shellnut's Website</ExternalLink>
|
||||
</span>
|
||||
<MarkShellnutArchitect slot="portfolio-details" />
|
||||
</Portfolio>
|
||||
alt="Picture of Mark Shellnut Architect's Website"
|
||||
{links}
|
||||
{details}
|
||||
portfolioDetails={MarkShellnutArchitect}
|
||||
externalLinks={[{ ariaLabel: 'View Mark Shellnut Architect', href: 'https://markshellnutarchitect.com', showIcon: false, text: 'Link to Mark Shellnut Architect'}]} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue