Compare commits

..

No commits in common. "master" and "yet-another-revamp" have entirely different histories.

110 changed files with 2448 additions and 3409 deletions

View File

@ -1,10 +0,0 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,json,yml}]
charset = utf-8
indent_style = space
indent_size = 2

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
/.yarn/** linguist-vendored
/.yarn/releases/* binary
/.yarn/plugins/**/* binary
/.pnp.* binary linguist-generated

3
.gitignore vendored
View File

@ -12,11 +12,10 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
.vercel

View File

@ -0,0 +1,19 @@
{
"version": 3,
"routes": [
{
"src": "^/_astro/(.*)$",
"headers": {
"cache-control": "public, max-age=31536000, immutable"
},
"continue": true
},
{
"handle": "filesystem"
},
{
"src": "/.*",
"dest": "render"
}
]
}

View File

@ -0,0 +1,5 @@
{
"runtime": "nodejs18.x",
"handler": "dist/entry.mjs",
"launcherType": "Nodejs"
}

View File

@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@ -0,0 +1 @@
import{j as e}from"./jsx-runtime.391947bd.js";import{r as a}from"./index.ed373d49.js";const d=({pictures:s})=>{a.useRef(0);const[r,l]=a.useState(0),i=a.useRef(null),u=()=>{r>0&&l(t=>t-1)},c=()=>{r<s.length-1&&l(t=>t+1)},o=t=>t==="prev"?r<=0:t==="next"&&r>=s.length-1?r>=s.length-1:!1;function g(t,n){switch(n){case r:return"translate-x-0 z-20";case r-1:return"-translate-x-full z-10";case r+1:return"translate-x-full z-10";default:return"hidden"}}return e.jsxs("div",{className:"relative w-full",children:[e.jsx("div",{ref:i,className:"relative h-56 overflow-hidden rounded-xl md:h-64",children:s.map((t,n)=>e.jsx("div",{className:`duration-700 ease-in-out transition-transform ${g(t,n)}`,children:e.jsx("a",{href:t.image||"",target:"_blank",className:"absolute block w-full h-full -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2",children:e.jsx("img",{src:t.image||"",alt:t.title,className:"object-cover h-64 w-full"})})},n))}),e.jsx("div",{className:"absolute z-30 flex space-x-3 -translate-x-1/2 bottom-5 left-1/2",children:s.map((t,n)=>e.jsx("button",{type:"button",className:"w-3 h-3 rounded-full","aria-current":t.title===s[r].title,"aria-label":t.title,onClick:()=>l(n)}))}),e.jsx("button",{type:"button",className:"absolute top-0 left-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none",onClick:u,disabled:o("prev"),children:e.jsxs("span",{className:"inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none",children:[e.jsx("svg",{className:"w-4 h-4 text-white dark:text-gray-800","aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 6 10",children:e.jsx("path",{stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 1 1 5l4 4"})}),e.jsx("span",{className:"sr-only",children:"Previous"})]})}),e.jsx("button",{type:"button",className:"absolute top-0 right-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none",onClick:c,disabled:o("next"),children:e.jsxs("span",{className:"inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none",children:[e.jsx("svg",{className:"w-4 h-4 text-white dark:text-gray-800","aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 6 10",children:e.jsx("path",{stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m1 9 4-4-4-4"})}),e.jsx("span",{className:"sr-only",children:"Next"})]})})]})},h=[{title:"Drone Picture of Hampshire College",image:"/img/DJI_0565.JPG"},{title:"Drone Picture of Hampshire College (winter)",image:"/img/DJI_0605.JPG"},{title:"Bean!!",image:"/img/IMG_0196.JPG"},{title:"Ricky!!",image:"/img/IMG_3942.JPG"}];function m(){return e.jsx("div",{className:"h-64",children:e.jsx(d,{pictures:h})})}export{m as default};

View File

@ -0,0 +1 @@
import{j as e}from"./jsx-runtime.391947bd.js";import{r as n}from"./index.ed373d49.js";import{s as c}from"./index.64e1f044.cbeca326.js";const o="#1DB954",x=n.forwardRef(function({title:a="Spotify",color:t="currentColor",size:l=24,...i},r){return t==="default"&&(t=o),e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:l,height:l,fill:t,viewBox:"0 0 24 24",ref:r,...i,children:[e.jsx("title",{children:a}),e.jsx("path",{d:"M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"})]})});function u(){const[s,a]=n.useState(null);return n.useEffect(()=>{fetch("/api/spotify").then(t=>t.json()).then(t=>a(t))},[]),n.useEffect(()=>{const t=setInterval(()=>{fetch("/api/spotify").then(l=>l.json()).then(l=>a(l))},1e4);return()=>clearInterval(t)},[]),e.jsxs("div",{className:"flex p-4 items-end gap-3 self-stretch border border-[#1DB954] rounded-2xl bg-gradient-to-r from-[#11652F] to-[#417152]",children:[s?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"relative w-10 h-10 flex items-center justify-center",children:[e.jsx("img",{src:s.album.image,className:"rounded-xl w-10 h-10 absolute opacity-50"}),e.jsx("a",{href:s.url,target:"_blank",rel:"noreferrer",className:"z-50 text-white",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",className:"w-6 h-6 z-50",children:e.jsx("path",{fillRule:"evenodd",d:"M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm14.024-.983a1.125 1.125 0 010 1.966l-5.603 3.113A1.125 1.125 0 019 15.113V8.887c0-.857.921-1.4 1.671-.983l5.603 3.113z",clipRule:"evenodd"})})})]}),e.jsxs("div",{className:"flex flex-col justify-center items-start flex-1 self-stretch",children:[e.jsx("span",{className:"text-white/60 font-light text-xs truncate max-w-[250px]",title:s.artist,children:s.artist}),e.jsx("span",{className:"text-white font-normal text-base truncate max-w-[250px]",title:s.song,children:s.song})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"block w-10 h-10 rounded-xl bg-white/10 animate-pulse"}),e.jsxs("div",{className:"flex flex-col justify-center items-start flex-1 self-stretch space-y-1",children:[e.jsx("div",{className:"block h-3 w-28 bg-white/10 animate-pulse rounded-md"}),e.jsx("div",{className:"block h-5 w-36 bg-white/10 animate-pulse rounded-md"})]})]}),e.jsxs("div",{className:`flex flex-col ${s?.nowPlaying?"justify-between":""} h-full items-center`,children:[s?.nowPlaying&&e.jsx(d,{}),e.jsx(x,{className:"w-4 h-4"})]})]})}function d(){return e.jsxs("div",{className:c.nowplaying,title:"Currently Playing",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]})}export{u as default};

View File

@ -0,0 +1 @@
import{j as e}from"./jsx-runtime.391947bd.js";import{r as t}from"./index.ed373d49.js";function n(){const[r,o]=t.useState(null);return t.useEffect(()=>{fetch("/api/waiwo").then(s=>s.json()).then(s=>o(s))},[]),e.jsxs("section",{className:"border border-[#1E1B22] rounded-3xl p-8 gap-y-3 flex flex-col",children:[e.jsx("h1",{className:"font-medium text-2xl",children:"What I'm working on"}),r?.image?e.jsx("a",{href:`https://github.com/${r.repo}`,target:"_blank",rel:"noreferrer",children:e.jsx("img",{className:"flex-1 self-stretch rounded-xl",src:r.image})}):e.jsx("div",{className:"block w-full h-40 rounded-xl bg-gray-200 animate-pulse"})]})}export{n as default};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
._nowplaying_ckbqr_1{position:relative;display:flex;justify-content:space-between;width:13px;height:13px}._nowplaying_ckbqr_1 span{width:3px;height:100%;background-color:#fff;border-radius:3px;transform-origin:bottom;animation:_bounce_ckbqr_1 2.2s ease infinite alternate;content:""}._nowplaying_ckbqr_1 span:nth-of-type(2){animation-delay:-2.2s}._nowplaying_ckbqr_1 span:nth-of-type(3){animation-delay:-3.7s}@keyframes _bounce_ckbqr_1{10%{transform:scaleY(.3)}30%{transform:scaleY(1)}60%{transform:scaleY(.5)}80%{transform:scaleY(.75)}to{transform:scaleY(.6)}}

View File

@ -0,0 +1 @@
const n="_nowplaying_ckbqr_1",o="_bounce_ckbqr_1",c={nowplaying:n,bounce:o};export{c as s};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
import{r as l}from"./index.ed373d49.js";var f={exports:{}},n={};/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var u=l,m=Symbol.for("react.element"),x=Symbol.for("react.fragment"),y=Object.prototype.hasOwnProperty,a=u.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,v={key:!0,ref:!0,__self:!0,__source:!0};function i(t,r,p){var e,o={},s=null,_=null;p!==void 0&&(s=""+p),r.key!==void 0&&(s=""+r.key),r.ref!==void 0&&(_=r.ref);for(e in r)y.call(r,e)&&!v.hasOwnProperty(e)&&(o[e]=r[e]);if(t&&t.defaultProps)for(e in r=t.defaultProps,r)o[e]===void 0&&(o[e]=r[e]);return{$$typeof:m,type:t,key:s,ref:_,props:o,_owner:a.current}}n.Fragment=x;n.jsx=i;n.jsxs=i;f.exports=n;var d=f.exports;export{d as j};

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
{"artist":"The Black Keys","album":{"name":"Brothers","image":"https://lastfm.freetls.fastly.net/i/u/300x300/fe84144e16808e200304351b5e9410de.jpg"},"song":"Ten Cent Pistol","nowPlaying":false,"url":"https://www.last.fm/music/The+Black+Keys/_/Ten+Cent+Pistol"}

View File

@ -0,0 +1 @@
{"image":"https://opengraph.githubassets.com/f42e3ec0e9a857dd79081ec7253727204fc00b662a25a266d41cf3f61a2c9d6b/jackmerrill/hampbot","repo":"jackmerrill/hampbot"}

View File

@ -0,0 +1,182 @@
/**
* @license
*
* Font Family: Sentient
* Designed by: Noopur Choksi
* URL: https://www.fontshare.com/fonts/sentient
* © 2023 Indian Type Foundry
*
* Font Styles:
* Sentient Variable(Variable font)
* Sentient Variable Italic(Variable font)
* Sentient Extralight
* Sentient Extralight Italic
* Sentient Light
* Sentient Light Italic
* Sentient Regular
* Sentient Italic
* Sentient Medium
* Sentient Medium Italic
* Sentient Bold
* Sentient Bold Italic
*
*/
/**
* This is a variable font
* You can controll variable axes as shown below:
* font-variation-settings: 'wght' 700.0 'wght' 400.0;
*
* available axes:
* 'wght' (range from 200.0 to 700.0)
* 'wght' (range from 200.0 to 700.0)
*/
@font-face {
font-family: 'Sentient-Variable';
src: url('../fonts/Sentient-Variable.woff2') format('woff2'),
url('../fonts/Sentient-Variable.woff') format('woff'),
url('../fonts/Sentient-Variable.ttf') format('truetype');
font-weight: 200 700;
font-display: swap;
font-style: normal;
}
/**
* This is a variable font
* You can controll variable axes as shown below:
* font-variation-settings: 'wght' 700.0 'wght' 400.0;
*
* available axes:
* 'wght' (range from 200.0 to 700.0)
* 'wght' (range from 200.0 to 700.0)
*/
@font-face {
font-family: 'Sentient-VariableItalic';
src: url('../fonts/Sentient-VariableItalic.woff2') format('woff2'),
url('../fonts/Sentient-VariableItalic.woff') format('woff'),
url('../fonts/Sentient-VariableItalic.ttf') format('truetype');
font-weight: 200 700;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Sentient-Extralight';
src: url('../fonts/Sentient-Extralight.woff2') format('woff2'),
url('../fonts/Sentient-Extralight.woff') format('woff'),
url('../fonts/Sentient-Extralight.ttf') format('truetype');
font-weight: 200;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Sentient-ExtralightItalic';
src: url('../fonts/Sentient-ExtralightItalic.woff2') format('woff2'),
url('../fonts/Sentient-ExtralightItalic.woff') format('woff'),
url('../fonts/Sentient-ExtralightItalic.ttf') format('truetype');
font-weight: 200;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Sentient-Light';
src: url('../fonts/Sentient-Light.woff2') format('woff2'),
url('../fonts/Sentient-Light.woff') format('woff'),
url('../fonts/Sentient-Light.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Sentient-LightItalic';
src: url('../fonts/Sentient-LightItalic.woff2') format('woff2'),
url('../fonts/Sentient-LightItalic.woff') format('woff'),
url('../fonts/Sentient-LightItalic.ttf') format('truetype');
font-weight: 300;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Sentient-Regular';
src: url('../fonts/Sentient-Regular.woff2') format('woff2'),
url('../fonts/Sentient-Regular.woff') format('woff'),
url('../fonts/Sentient-Regular.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Sentient-Italic';
src: url('../fonts/Sentient-Italic.woff2') format('woff2'),
url('../fonts/Sentient-Italic.woff') format('woff'),
url('../fonts/Sentient-Italic.ttf') format('truetype');
font-weight: 400;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Sentient-Medium';
src: url('../fonts/Sentient-Medium.woff2') format('woff2'),
url('../fonts/Sentient-Medium.woff') format('woff'),
url('../fonts/Sentient-Medium.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Sentient-MediumItalic';
src: url('../fonts/Sentient-MediumItalic.woff2') format('woff2'),
url('../fonts/Sentient-MediumItalic.woff') format('woff'),
url('../fonts/Sentient-MediumItalic.ttf') format('truetype');
font-weight: 500;
font-display: swap;
font-style: italic;
}
@font-face {
font-family: 'Sentient-Bold';
src: url('../fonts/Sentient-Bold.woff2') format('woff2'),
url('../fonts/Sentient-Bold.woff') format('woff'),
url('../fonts/Sentient-Bold.ttf') format('truetype');
font-weight: 700;
font-display: swap;
font-style: normal;
}
@font-face {
font-family: 'Sentient-BoldItalic';
src: url('../fonts/Sentient-BoldItalic.woff2') format('woff2'),
url('../fonts/Sentient-BoldItalic.woff') format('woff'),
url('../fonts/Sentient-BoldItalic.ttf') format('truetype');
font-weight: 700;
font-display: swap;
font-style: italic;
}

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

View File

Before

Width:  |  Height:  |  Size: 541 KiB

After

Width:  |  Height:  |  Size: 541 KiB

View File

Before

Width:  |  Height:  |  Size: 602 KiB

After

Width:  |  Height:  |  Size: 602 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
nodeLinker: node-modules

View File

@ -1,3 +1,47 @@
# jackmerrill.com
# Astro Starter Kit: Minimal
This is my website! Written using Astro (and some React), styled with TailwindCSS, designed with Figma, and deployed with Vercel.
```sh
npm create astro@latest -- --template minimal
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
├── src/
│ └── pages/
│ └── index.astro
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

View File

@ -1,8 +1,4 @@
import {
defineConfig,
passthroughImageService,
squooshImageService,
} from "astro/config";
import { defineConfig } from "astro/config";
import tailwind from "@astrojs/tailwind";
import react from "@astrojs/react";
@ -12,17 +8,5 @@ import vercel from "@astrojs/vercel/serverless";
export default defineConfig({
integrations: [tailwind(), react()],
output: "hybrid",
adapter: vercel({
imageService: true,
webAnalytics: {
enabled: true,
},
speedInsights: {
enabled: true,
},
functionPerRoute: true,
}),
// image: {
// service: passthroughImageService(),
// },
adapter: vercel(),
});

View File

@ -10,27 +10,18 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/react": "3.6.2",
"@astrojs/tailwind": "5.1.0",
"@astrojs/vercel": "7.7.2",
"@astrojs/react": "^3.0.4",
"@astrojs/tailwind": "^5.0.2",
"@astrojs/vercel": "^5.1.0",
"@icons-pack/react-simple-icons": "^9.1.0",
"@react-three/drei": "^9.101.0",
"@react-three/fiber": "^8.15.19",
"@react-three/xr": "^5.7.1",
"@tailwindcss/typography": "^0.5.10",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"astro": "4.14.2",
"astro-seo": "^0.8.0",
"astro": "^3.4.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sharp": "^0.33.5",
"squoosh": "^0.0.0",
"tailwindcss": "^3.0.24",
"three": "^0.162.0"
"tailwindcss": "^3.0.24"
},
"devDependencies": {
"sass": "^1.69.5",
"typescript": "^5.5.4"
"sass": "^1.69.5"
}
}

View File

@ -1,8 +0,0 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px"
width="1080px" height="1080px" viewBox="0 0 1080 1080"
style="enable-background:new 0 0 1080 1080;" xml:space="preserve">
<path fill="currentColor" d="M714.82,280.16l-94.47,163.37l-80.35,7.84l-80.36-7.84l-94.47-163.37L262.55,457.94l129.9,341.89h295.11l129.9-341.89
L714.82,280.16z M523.47,766.75h-108.2L299.05,460.87l66.15-114.58l74.32,128.52l83.94,8.19V766.75z M664.73,766.75h-108.2V483
l83.94-8.19l74.32-128.52l66.15,114.58L664.73,766.75z"/>
</svg>

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

9
public/favicon.svg Normal file
View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

After

Width:  |  Height:  |  Size: 749 B

BIN
public/img/DJI_0565.JPG Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

BIN
public/img/DJI_0605.JPG Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

BIN
public/img/IMG_0196.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

BIN
public/img/IMG_3942.JPG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -1,66 +0,0 @@
import { Interactive, XR, ARButton, Controllers } from "@react-three/xr";
import { Text } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import { useState, Suspense } from "react";
function Box({ color, size, scale, children, ...rest }: any) {
return (
<mesh scale={scale} {...rest}>
<boxBufferGeometry args={size} />
<meshPhongMaterial color={color} />
{children}
</mesh>
);
}
function Button(props: any) {
const [hover, setHover] = useState(false);
const [color, setColor] = useState<any>("blue");
const onSelect = () => {
setColor((Math.random() * 0xffffff) | 0);
};
return (
<Interactive
onHover={() => setHover(true)}
onBlur={() => setHover(false)}
onSelect={onSelect}
>
<Box
color={color}
scale={hover ? [0.6, 0.6, 0.6] : [0.5, 0.5, 0.5]}
size={[0.4, 0.1, 0.1]}
{...props}
>
<Suspense fallback={null}>
<Text
position={[0, 0, 0.06]}
fontSize={0.05}
color="#000"
anchorX="center"
anchorY="middle"
>
Hello react-xr!
</Text>
</Suspense>
</Box>
</Interactive>
);
}
export default function AR() {
return (
<>
<ARButton />
<Canvas>
<XR referenceSpace="local">
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Button position={[0, 0.1, -0.2]} />
<Controllers />
</XR>
</Canvas>
</>
);
}

View File

@ -6,6 +6,7 @@ export type Picture = {
};
const Carousel = ({ pictures }: { pictures: Picture[] }) => {
const maxScrollWidth = useRef(0);
const [currentIndex, setCurrentIndex] = useState(0);
const carousel = useRef(null);
@ -33,6 +34,13 @@ const Carousel = ({ pictures }: { pictures: Picture[] }) => {
return false;
};
// useEffect(() => {
// if (carousel !== null && carousel.current !== null) {
// (carousel.current as any).scrollLeft =
// (carousel.current as any).offsetWidth * currentIndex;
// }
// }, [currentIndex]);
function getClassnames(picture: Picture, index: number): string {
switch (index) {
case currentIndex: // current
@ -46,6 +54,13 @@ const Carousel = ({ pictures }: { pictures: Picture[] }) => {
}
}
// useEffect(() => {
// maxScrollWidth.current = carousel.current
// ? (carousel.current as any).scrollWidth -
// (carousel.current as any).offsetWidth
// : 0;
// }, []);
return (
<div className="relative w-full">
<div
@ -72,6 +87,15 @@ const Carousel = ({ pictures }: { pictures: Picture[] }) => {
className="object-cover h-64 w-full"
/>
</a>
{/* <a
href={resource.image || ""}
target="_blank"
className="h-full w-full aspect-square block absolute top-0 left-0 transition-opacity duration-300 opacity-0 hover:opacity-100 bg-black/30 z-10"
>
<h3 className="text-white py-6 px-3 mx-auto text-xl">
{resource.title}
</h3>
</a> */}
</div>
);
})}
@ -105,9 +129,9 @@ const Carousel = ({ pictures }: { pictures: Picture[] }) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 1 1 5l4 4"
/>
</svg>
@ -131,9 +155,9 @@ const Carousel = ({ pictures }: { pictures: Picture[] }) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m1 9 4-4-4-4"
/>
</svg>

View File

@ -1,40 +0,0 @@
---
import { SEO } from "astro-seo";
import Pride from "./Pride.astro";
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<link rel="stylesheet" href="/css/sentient.css" />
<SEO
title="Jack Merrill"
description="UI/UX designer and front-end developer based in Western Massachussetts."
twitter={{
creator: "@jack__merrill",
}}
/>
</head>
<body
class="font-serif text-white bg-gradient-to-b from-[#060009] to-[#08000B] min-h-[100svh]"
>
<Pride />
<main
class="mx-auto max-w-4xl grid md:grid-cols-2 px-2 gap-x-3 gap-y-4 my-6"
>
<header
class="bg-green-700 rounded-lg px-4 py-3 col-span-2 text-lg font-bold"
>
👋 I'm currently urgently looking for work! If you have any
opportunities or know of any, please reach out to me at{" "}
<a href="mailto:jobs@jackmerrill.com" class="underline">
jobs at jackmerrill dot com
</a>
</header>
<slot />
</main>
</body>
</html>

View File

@ -1,7 +1,26 @@
import { useState } from "react";
import Carousel, { type Picture } from "./Carousel";
export default function PictureShowcase({ pictures }: { pictures: Picture[] }) {
const pictures: Picture[] = [
{
title: "Drone Picture of Hampshire College",
image: "/img/DJI_0565.JPG",
},
{
title: "Drone Picture of Hampshire College (winter)",
image: "/img/DJI_0605.JPG",
},
{
title: "Bean!!",
image: "/img/IMG_0196.JPG",
},
{
title: "Ricky!!",
image: "/img/IMG_3942.JPG",
},
];
export default function PictureShowcase() {
return (
<div className="h-64">
<Carousel pictures={pictures} />

View File

@ -1,73 +0,0 @@
---
---
<style>
.pride {
background: linear-gradient(
90deg,
#fff 0%,
#fff 10%,
#ffafc8 10%,
#ffafc8 20%,
#74d7ee 20%,
#74d7ee 30%,
#613915 30%,
#613915 40%,
#e40303 40%,
#e40303 50%,
#ff8c00 50%,
#ff8c00 60%,
#ffed00 60%,
#ffed00 70%,
#008026 70%,
#008026 80%,
#24408e 80%,
#24408e 90%,
#732982 90%,
#732982 100%
);
}
.box {
position: relative;
transform-style: preserve-3d;
border-radius: 0px;
}
.box::before {
content: "";
position: absolute;
inset: -10px;
background: linear-gradient(
90deg,
#fff 0%,
#fff 10%,
#ffafc8 10%,
#ffafc8 20%,
#74d7ee 20%,
#74d7ee 30%,
#613915 30%,
#613915 40%,
#e40303 40%,
#e40303 50%,
#ff8c00 50%,
#ff8c00 60%,
#ffed00 60%,
#ffed00 70%,
#008026 70%,
#008026 80%,
#24408e 80%,
#24408e 90%,
#732982 90%,
#732982 100%
);
filter: blur(18px);
transform: translate3d(0px, 0px, -1px);
border-radius: inherit;
pointer-events: none;
}
</style>
<div class="box">
<hr class="pride w-full h-4 border-transparent pb-4" />
</div>

View File

@ -38,7 +38,6 @@ export default function SpotifyNowPlaying() {
<img
src={nowPlaying.album.image}
className="rounded-xl w-10 h-10 absolute opacity-50"
alt={nowPlaying.album.name}
/>
<a
@ -46,7 +45,6 @@ export default function SpotifyNowPlaying() {
target="_blank"
rel="noreferrer"
className="z-50 text-white"
title="View on Last.fm"
>
<svg
xmlns="http://www.w3.org/2000/svg"

View File

@ -20,13 +20,8 @@ export default function WAIWO() {
href={`https://github.com/${repo.repo}`}
target="_blank"
rel="noreferrer"
title="View on GitHub"
>
<img
className="flex-1 self-stretch rounded-xl"
src={repo.image}
alt={repo.repo}
/>
<img className="flex-1 self-stretch rounded-xl" src={repo.image} />
</a>
) : (
<div className="block w-full h-40 rounded-xl bg-gray-200 animate-pulse"></div>

View File

@ -1,15 +0,0 @@
import { defineCollection, z } from "astro:content";
const workCollection = defineCollection({
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
image: image().optional(),
link: z.string().optional(),
}),
});
export const collections = {
work: workCollection,
};

View File

@ -1,27 +0,0 @@
---
title: JackNet
description: "My various servers and services I host in my dorm room."
---
I host a variety of servers and services on my server, JackNet. These include:
- [Authentication](https://auth.jackmerrill.com) - A Casdoor server I use for my other services.
- Home Assistant - Connected to my various smart home devices. Likely have the "smartest" dorm on campus.
- Jellyfin - A media server for my media.
- [Gitea](https://git.jackmerrill.com) - A self-hosted Git server.
- Various Minecraft Servers - I host a variety of Minecraft servers for my friends and I to play on.
- Bitwarden - A self-hosted password manager.
- Speedtest Tracker - A speedtest tracker that runs every hour and logs the results. Mainly to detect network issues at my college.
- Lubelog - Car maintenance tracker.
- [Family Guy Discord Bot](https://discord.com/oauth2/authorize?client_id=839624581055774741&permissions=2048&scope=bot%20applications.commands) - A bot that posts random Family Guy quotes in Discord. \[[GitHub](https://github.com/jackmerrill/FamilyGuyQuotesBot)\]
| My Rack (15U): |
| ---------------------------------------------------------------------------------------------------------------------------- |
| Cisco Catalyst 3560G w/ Uplink to Unifi Express |
| Shelf |
| <br>Alienware Steam Machine<br>Dell Optiplex 390 w/ GTX 1650 <br><br> |
| \[Empty\] |
| <br>Dell Poweredge R710 (Intel Xeon E5540, 128GB DDR3 ECC RAM, running Proxmox <br>&nbsp; |
| \[Empty\] |
| \[Empty\] |
| <br>UnRAID server<br>(Supermicro X9DRi-LN4+, 2x Intel Xeon E5-2650, 368GB DDR3 ECC RAM, 29TB total storage w/Parity)<br><br> |

View File

@ -1,8 +0,0 @@
---
title: This Website
description: "The website you're currently on. Built with Astro, Tailwind CSS, and MDX."
image: "thumb.png"
link: /
---
I created this website using Figma and designed it to be a simple, clean, and fast website. It uses a Bento box design, keeping everything in its own area, separated from everything.

Some files were not shown because too many files have changed in this diff Show More