personal website

update resume, social links, packages, turn to static

+153 -311
+3
.gitignore
··· 23 23 # jetbrains setting folder 24 24 .idea/ 25 25 .vercel 26 + 27 + # Local Netlify folder 28 + .netlify
+7 -4
astro.config.mjs
··· 3 3 import icon from "astro-icon"; 4 4 import mdx from "@astrojs/mdx"; 5 5 import svelte from "@astrojs/svelte"; 6 - import tailwind from "@astrojs/tailwind"; 6 + import tailwindcss from "@tailwindcss/vite"; 7 7 8 8 import netlify from "@astrojs/netlify"; 9 9 10 10 // https://astro.build/config 11 11 export default defineConfig({ 12 - integrations: [tailwind(), svelte(), mdx(), icon()], 13 - output: "server", 12 + integrations: [svelte(), mdx(), icon()], 13 + output: "static", 14 14 adapter: netlify(), 15 - }); 15 + vite: { 16 + plugins: [tailwindcss()], 17 + } 18 + });
bun.lockb

This is a binary file and will not be displayed.

+14 -14
package.json
··· 10 10 "astro": "astro" 11 11 }, 12 12 "dependencies": { 13 - "@astrojs/check": "^0.9.4", 14 - "@astrojs/mdx": "^3.1.9", 15 - "@astrojs/netlify": "^5.5.4", 16 - "@astrojs/svelte": "^5.7.3", 17 - "@astrojs/tailwind": "^5.1.2", 18 - "@iconify-json/tabler": "^1.2.7", 19 - "@sveltejs/vite-plugin-svelte": "^4.0.0", 20 - "astro": "^4.16.11", 21 - "astro-icon": "^1.1.2", 22 - "bits-ui": "^0.21.16", 23 - "svelte": "^5.1.16", 24 - "tailwindcss": "^3.4.14", 25 - "typescript": "^5.6.3" 13 + "@astrojs/check": "0.9.6", 14 + "@astrojs/mdx": "4.3.12", 15 + "@astrojs/netlify": "6.6.3", 16 + "@astrojs/svelte": "7.2.2", 17 + "@iconify-json/tabler": "^1.2.23", 18 + "@sveltejs/vite-plugin-svelte": "^6.2.1", 19 + "@tailwindcss/vite": "^4.1.17", 20 + "astro": "5.16.4", 21 + "astro-icon": "^1.1.5", 22 + "bits-ui": "^2.14.4", 23 + "svelte": "^5.45.5", 24 + "tailwindcss": "^4.1.17", 25 + "typescript": "^5.9.3" 26 26 }, 27 27 "devDependencies": { 28 - "@tailwindcss/typography": "^0.5.15" 28 + "@tailwindcss/typography": "^0.5.19" 29 29 } 30 30 }
public/opensauced.png

This is a binary file and will not be displayed.

public/pomerium.png

This is a binary file and will not be displayed.

-1
public/src/env.d.ts
··· 1 - /// <reference path="../.astro/types.d.ts" />
public/zuplo.png

This is a binary file and will not be displayed.

+6 -6
src/components/NavigationDialog.svelte
··· 1 1 <script lang="ts"> 2 2 import { Dialog } from "bits-ui"; 3 - import { fade } from "svelte/transition"; 4 3 </script> 5 4 6 5 <Dialog.Root> ··· 8 7 Menu 9 8 </Dialog.Trigger> 10 9 <Dialog.Portal> 11 - <Dialog.Overlay transition={fade} class="fixed inset-0 z-50 bg-black/80" /> 10 + <Dialog.Overlay class="fixed inset-0 z-50 bg-black/80" /> 12 11 <Dialog.Content 13 12 class="bg-neutral-800 fixed left-[50%] top-[50%] z-50 w-full max-w-[94%] translate-x-[-50%] translate-y-[-50%] rounded-card-lg border bg-background p-5 shadow-popover outline-none sm:max-w-[490px] md:w-full" 14 13 > ··· 16 15 17 16 <section class="flex flex-col gap-2 text-white"> 18 17 <h3 class="text-yellow-500">socials</h3> 19 - <a href="https://bsky.app/profile/zeu.dev" target="_blank" class="after:content-['_↗']">bluesky</a> 20 - <a href="https://github.com/zeucapua" target="_blank" class="after:content-['_↗']">github</a> 21 - <a href="https://twitch.tv/zeu_dev" target="_blank" class="after:content-['_↗']">twitch</a> 22 - <a href="https://twitter.com/zeu_dev" target="_blank" class="after:content-['_↗']">twitter</a> 18 + <a href="https://bsky.app/profile/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🦋_']">bluesky</a> 19 + <a href="https://github.com/zeucapua" target="_blank" class="after:content-['_↗'] before:content-['💻_']">github</a> 20 + <a href="https://tangled.sh/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🧶_']">tangled</a> 21 + <a href="https://twitch.tv/zeu_dev" target="_blank" class="after:content-['_↗'] before:content-['👾_']">twitch</a> 22 + <a href="https://stream.place/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🟪_']">streamplace</a> 23 23 </section> 24 24 25 25 <hr class="border-yellow-500 " />
+22 -15
src/components/SiteLayout.astro
··· 1 1 --- 2 2 import NavigationDialog from "./NavigationDialog.svelte"; 3 - import { ViewTransitions } from "astro:transitions"; 4 3 const { title } = Astro.props; 5 4 --- 6 5 ··· 17 16 <meta name="viewport" content="width=device-width" /> 18 17 <meta name="generator" content={Astro.generator} /> 19 18 <title>{ title }</title> 20 - <ViewTransitions /> 21 19 </head> 22 20 <body class="relative font-syne bg-neutral-900 text-yellow-500 grid grid-cols-1 md:grid-cols-5 w-full h-full min-w-screen min-h-screen"> 23 21 <aside class="sticky top-0 max-h-screen flex items-center border-yellow-500 justify-between md:border-r-2 w-full md:w-fit md:justify-start md:items-start h-fit md:h-full md:flex-col gap-4 font-medium p-4"> ··· 34 32 <hr class="border-yellow-500 " /> 35 33 36 34 <section class="flex flex-col gap-2 text-white"> 37 - <h3 class="text-yellow-500">socials</h3> 38 - <a href="https://bsky.app/profile/zeu.dev" target="_blank" class="after:content-['_↗']">bluesky</a> 39 - <a href="https://github.com/zeucapua" target="_blank" class="after:content-['_↗']">github</a> 40 - <a href="https://twitch.tv/zeu_dev" target="_blank" class="after:content-['_↗']">twitch</a> 41 - <a href="https://twitter.com/zeu_dev" target="_blank" class="after:content-['_↗']">twitter</a> 35 + <h3 class="text-yellow-500"> 36 + <a href="/blog" class="after:content-['_->'] before:content-['📑_']">blog</a> 37 + </h3> 42 38 </section> 43 39 44 40 <hr class="border-yellow-500 " /> 45 41 46 42 <section class="flex flex-col gap-2 text-white"> 47 43 <h3 class="text-yellow-500"> 48 - <a href="/blog" class="after:content-['_->']">blog</a> 44 + <a href="/resume" class="after:content-['_->'] before:content-['💼_']">resume</a> 45 + </h3> 46 + <h3 class="text-yellow-500"> 47 + <a href="/open-source" class="after:content-['_->'] before:content-['🧮_']">open source</a> 49 48 </h3> 50 49 </section> 51 50 52 51 <hr class="border-yellow-500 " /> 53 52 54 53 <section class="flex flex-col gap-2 text-white"> 55 - <h3 class="text-yellow-500"> 56 - <a href="/resume" class="after:content-['_->']">resume</a> 57 - </h3> 58 - <h3 class="text-yellow-500"> 59 - <a href="/open-source" class="after:content-['_->']">open source</a> 60 - </h3> 61 - <a href="https://easytodo.zeu.dev" target="_blank" class="after:content-['_↗']">easytodo</a> 54 + <h3 class="text-yellow-500">socials</h3> 55 + <a href="https://bsky.app/profile/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🦋_']">bluesky</a> 56 + <a href="https://github.com/zeucapua" target="_blank" class="after:content-['_↗'] before:content-['💻_']">github</a> 57 + <a href="https://tangled.sh/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🧶_']">tangled</a> 58 + <a href="https://twitch.tv/zeu_dev" target="_blank" class="after:content-['_↗'] before:content-['👾_']">twitch</a> 59 + <a href="https://stream.place/zeu.dev" target="_blank" class="after:content-['_↗'] before:content-['🟪_']">streamplace</a> 62 60 </section> 61 + 63 62 </nav> 64 63 </aside> 65 64 ··· 69 68 </body> 70 69 </html> 71 70 71 + 72 72 <style is:global> 73 + @import "tailwindcss"; 74 + @plugin "@tailwindcss/typography"; 75 + 76 + @theme { 77 + --font-syne: "SyneMono"; 78 + } 79 + 73 80 @font-face { 74 81 font-family: "SyneMono"; 75 82 src: url("/SyneMono-Regular.ttf");
+21
src/content/about/as-seen-on.mdx
··· 1 + --- 2 + updated_at: 12-5-2025 3 + draft: false 4 + --- 5 + 6 + import { Icon } from "astro-icon/components"; 7 + 8 + ## Web Dev Challenge: Build a multiplayer web app using PartyKit 9 + - 24k+ views on YouTube 10 + - 18 stars on the typer99 GitHub repository 11 + - Built a type racing game with powerups and obstacles, implementing PartyKit into a SvelteKit application 12 + - Participated alongside Jason Lengstorf (host), Nick Taylor (prev OpenSauced), and Steve Ruiz (tldraw.com) 13 + 14 + ## Web Dev Challenge: What can you build in 4 hours with Google Gemini? [<Icon name="tabler:brand-youtube" class="inline-block" />](https://www.youtube.com/watch?v=pn5Jju4FNG4&t=340s) 15 + 16 + - 97k+ views on YouTube 17 + - 8 stars on the thankadev GitHub repository 18 + - Built an AI generated thank you note that can be shared on X (formerly Twitter) for each library listed in a given repository's SBOM (software bill of materials) 19 + - Sponsored by Google Gemini AI and is integrated into the project, all of which was built in 4 hours 20 + - Participated alongside Jason Lengstorf (host), Brian Holt (Neon DB), and Sarah aka badcop_ (prev Boot.dev) 21 + - Recorded live in studio by a professional camera and sound crew throughout a 12 hour production day
+45 -28
src/content/about/resume.mdx
··· 5 5 6 6 import { Icon } from "astro-icon/components"; 7 7 8 - A generalist Software Engineer, specialized in solutions and product engineering, 9 - utilizing technologies across the stack and languages like Javascript (Next.js), Python (Django), and GoLang (Cobra). 10 - Based in San Bernardino, California USA with remote and open source experience. 8 + A Software Engineer making products and solutions, particular in frontend development, 11 9 12 10 <hr /> 13 11 14 12 # Experience 13 + ## Software Engineer, Pomerium [<Icon name="tabler:external-link" class="inline-block" />](https://pomerium.com) 14 + _April 2025 - October 2025_ 15 + - Implemented new features and bug fixes on the Layer 7 proxy security dashboards 16 + - Worked on two product offerings for general users and enterprise customers, each with their own monorepo 17 + - Coordinated with backend engineers and management to ensure continuity between UX for more technical users 18 + with the CLI and the frontend web interface 19 + - Technology Stack: React Router, React, Redux, Material UI, PostHog, GoLang 20 + <a href="https://pomerium.com" class="flex gap-2 items-center -my-8 hover:underline" target="_blank"> 21 + <img src="/pomerium.png" alt="Pomerium Logo" class="size-8 rounded" /> 22 + pomerium.com 23 + <Icon name="tabler:external-link" class="inline-block -top-2" /> 24 + </a> 25 + 15 26 ## Software Engineer, OpenSauced [<Icon name="tabler:external-link" class="inline-block" />](https://opensauced.pizza) 16 - _February 2024 - Present_ 27 + _February 2024 - October 2024_ 17 28 - Worked with different technology stacks and products throughout the company 18 29 - Coordinated and collaborated with every department, including marketing, product, and engineering 19 30 - Helped market the brand and features on X (formerly Twitter), resulting in thousands of impressions ··· 21 32 - Reviewed external contributors' issues and pull requests 22 33 23 34 ### The OpenSauced App [<Icon name="tabler:brand-github-filled" class="inline-block" />](https://github.com/open-sauced/app) 24 - - Tech Stack: Next.js, React, TailwindCSS, PostHog, Playwright, Supabase, Storybook, SWR and more 35 + - Technology Stack: Next.js, React, TailwindCSS, PostHog, Playwright, Supabase, Storybook, SWR and more 25 36 - 88 pull requests in the last 6 months, about 20% of all contributions on the application product 26 37 27 38 #### Repo Pages ··· 42 53 - Implemented major features for the CODEOWNERS centered CLI program built on Golang, Cobra CLI framework, and the BubbleTea terminal framework 43 54 - `pizza generate config`: an automatic or interactive terminal command that creates a global available YAML file that keeps track Git attributions 44 55 - `pizza offboard`: removes Git attributions by YAML configuration and CODEOWNERS files 45 - - Tech Stack: GoLang, Cobra CLI, BubbleTea 56 + - Technology Stack: GoLang, Cobra CLI, BubbleTea 46 57 47 58 ### Landing Page & Blog [<Icon name="tabler:brand-github-filled" class="inline-block" />](https://github.com/open-sauced/landing-page) 48 59 - Implemented and managed the Sanity CMS for viewing on the company blog 49 60 - Styled with TailwindCSS and Framer Motion based on Figma designs by the Product Manager 50 61 - Created and updated multiple landing pages for product (the app and Pizza CLI) and various use cases (Teams, Maintainers, Contributors, and Students) 51 - - Tech Stack: Next.js, React, TailwindCSS, PostHog and more 62 + - Technology Stack: Next.js, React, TailwindCSS, PostHog and more 63 + 64 + <a href="https://github.com/open-sauced" class="flex gap-2 items-center -my-8 hover:underline" target="_blank"> 65 + <img src="/opensauced.png" alt="OpenSauced Logo" class="size-8 rounded" /> 66 + github.com/open-sauced 67 + <Icon name="tabler:external-link" class="inline-block -top-2" /> 68 + </a> 69 + 70 + <hr /> 71 + 72 + # Contract Work 73 + 74 + ## Consultant Software Engineer, Zuplo [<Icon name="tabler:external-link" class="inline-block" />](https://zuplo.com) 75 + _November 2025 - December 2025_ 76 + - Implemented a proof of concept for `zudoku schema generate example` CLI command, generates examples for response and request body schemas 77 + without explicit examples given an OpenAPI JSON file 78 + - Technology Stack: Yargs, @clack/prompts, Typescript, Nx 79 + <a href="https://zuplo.com" class="flex gap-2 items-center -my-8 hover:underline" target="_blank"> 80 + <img src="/zuplo.png" alt="Zuplo Logo" class="size-8 rounded" /> 81 + zuplo.com 82 + <Icon name="tabler:external-link" class="inline-block -top-2" /> 83 + </a> 52 84 53 85 ## Full Stack Developer, Buttondown [<Icon name="tabler:external-link" class="inline-block" />](https://buttondown.email) 54 86 _November 2023 - February 2024_ 55 87 - Implemented features and bug fixes to the email platform, supporting thousands of newsletters 56 88 - Managed and updated copy and designs on the platform’s marketing website 57 - - Tech Stack: Django, Vue, Next.js, TailwindCSS and more 89 + - Technology Stack: Django, Vue, Next.js, TailwindCSS and more 58 90 59 91 ## Web Developer, SmartWiz [<Icon name="tabler:external-link" class="inline-block" />](https://smartwiz.io) 60 - _September 2023 - November 2024_ 92 + _September 2023 - November 2023_ 61 93 - Refactored existing Stripe integrations and implemented designs from Figma 62 - - Tech Stack: Remix, React, TailwindCSS, Stripe, and more 94 + - Technology Stack: Remix, React, TailwindCSS, Stripe, and more 95 + 96 + <hr /> 63 97 64 98 ## Volunteer Web Developer, Progressive Victory [<Icon name="tabler:external-link" class="inline-block" />](https://progressivevictory.win) 65 99 _August 2022 - November 2022_ 66 100 - Led the frontend development of the initial organization website, implementing designs in coordination with organizers and backend engineers 67 101 - Implemented Airtable as a CMS to display information about volunteer efforts and political candidates’ campaigns throughout the United States 68 - - Tech Stack: React, Next.js, Airtable, Storybook, Vercel and more 69 - 70 - <hr /> 71 - 72 - # Public Speaking and Community Participation 73 - ## Web Dev Challenge: Build a multiplayer web app using PartyKit 74 - - 24k+ views on YouTube 75 - - 18 stars on the typer99 GitHub repository 76 - - Built a type racing game with powerups and obstacles, implementing PartyKit into a SvelteKit application 77 - - Participated alongside Jason Lengstorf (host), Nick Taylor (prev OpenSauced), and Steve Ruiz (tldraw.com) 78 - 79 - ## Web Dev Challenge: What can you build in 4 hours with Google Gemini? 80 - - 97k+ views on YouTube 81 - - 8 stars on the thankadev GitHub repository 82 - - Built an AI generated thank you note that can be shared on X (formerly Twitter) for each library listed in a given repository's SBOM (software bill of materials) 83 - - Sponsored by Google Gemini AI and is integrated into the project, all of which was built in 4 hours 84 - - Participated alongside Jason Lengstorf (host), Brian Holt (Neon DB), and Sarah aka badcop_ (prev Boot.dev) 85 - - Recorded live in studio by a professional camera and sound crew throughout a 12 hour production day 102 + - Technology Stack: React, Next.js, Airtable, Storybook, Vercel and more
-22
src/content/blog/atproto-oauth.md
··· 1 - --- 2 - title: AT Protocol OAuth Basics Tutorial 3 - description: Implement your own Bluesky client using the `@atproto/oauth-client-node` package 4 - date: "2024-11-24" 5 - draft: true 6 - --- 7 - 8 - # Initial Project Setup 9 - 10 - # Database and Auth Stores 11 - 12 - # Implement AT Protocol Client 13 - 14 - # Encryption Practices feat. Pilcrow 15 - 16 - # Locals Variables and Login Flow 17 - 18 - # Implement ATProto OAuth Callback Endpoint 19 - 20 - # Hooks and Middleware for User and Agent 21 - 22 - # Logout Flow
-92
src/content/blog/indexed-1.mdx
··· 1 - --- 2 - title: "This is HTML: Indexed - Web Development Explained" 3 - description: An overview on what HTML is and how to use them while making websites. Part 1 of the Indexed - Web Development Explained series. 4 - date: 01-06-2024 5 - draft: false 6 - --- 7 - import CodePreview from "../../components/CodePreview.astro"; 8 - 9 - ## Elements, Tags, and the Properties Within 10 - 11 - HTML is the programming language used to layout the content inside a webpage. Writing in HTML involves using 12 - elements, also known as tags (throughout the series, I will be using these interchangeably), and putting them in 13 - order for your design. 14 - 15 - Most tags are used in twos, both with angle brackets with the type inside, with the ending tag's type starting 16 - with a slash. Between the two is where we'd put content, which can also include more elements. Some elements, 17 - like `<img />`, are what's called "self-closing tags", denoted with the slash at the end. 18 - 19 - <CodePreview> 20 - <div slot="preview"> 21 - <h2>An error has occurred??</h2> 22 - <img src="https://media.giphy.com/media/ltx2rcXk8sE4OCHnFB/giphy.gif" /> 23 - </div> 24 - <div slot="code"> 25 - ```html 26 - <div> 27 - <h2>An error has occurred??</h2> 28 - <img src="https://media.giphy.com/media/ltx2rcXk8sE4OCHnFB/giphy.gif" /> 29 - </div> 30 - ``` 31 - </div> 32 - </CodePreview> 33 - 34 - We can 35 - configure tags like these with its properties, or "props" for short. For example, to have this image tag to show a 36 - picture, we'll set its `src` property a link, as well as state an alternate text to make it accessible to those 37 - hard of seeing. 38 - 39 - ## So Common You Should Memorize Them 40 - 41 - Mozilla Developer Network (MDN), a definitive web development resource online, has a list of all HTML tags. All in 42 - all, there are 142 elements, 115 of which are functional today with the rest being deprecated. Now you 43 - aren't expected to learn every single tag, but when you make enough websites there will be elements that 44 - comes up often. 45 - 46 - Here's my list of tags I use everyday: 47 - 48 - - `<div>`, `<section>`, `<main>`: containers to label off parts of the page. I use `<main>` for the page's 49 - content, `<section>` when there's a defined part (like the code preview above), and `<div>` when I need 50 - to group elements, but don't need to label them, usually for layout and styling reasons. 51 - - `<h1>`->`<h6>`, `<p>`: headers and paragraph text elements. These come with default styles, 52 - but since I use TailwindCSS, they all look the same. No matter how they look, they do help me 53 - distinguish between a wall of text and something to highlight. 54 - - `<img>`: images (and gifs)! Make sure to use the `alt` prop to describe the image to those who might 55 - need to use screen users. Accessibility is great! 56 - - `<input>`, `<button>`: interactive elements, connect these with a `<form>` or script function to 57 - allow people to use your websites. 58 - - `<a>`: the link tag. Go to another page (either on the same website or another on the internet) by 59 - adding the link as its `href` prop. 60 - 61 - There are plenty more that I'm missing as I rattle these off at the top of my head. I memorize these since 62 - I use these everyday no matter the kind of website I'm creating, but if there's anything I need that I 63 - don't remember (for example `<video>` or `<track>`), MDN and Google are always there for me. 64 - 65 - 66 - ## Just the beginning 67 - 68 - HTML can only get you so far. Over the years, a lot of functionality has been baked into these elements. 69 - A recent example can be seen with the `<dialog>` tag that makes modals native to the browser, a feature 70 - that's been in use for decades before and practically only available in Javascript packages and frameworks. 71 - 72 - With that in mind, dialogs and buttons can't work without some scripting, so in the next part of the 73 - Indexed series, we'll start to take a look at the basics of Javascript ("JS") and how to use them 74 - with HTML. First up is using vanilla JS, before moving onto JS UI frameworks that are popular today, 75 - like React and Svelte. 76 - 77 - ## Thanks for reading 78 - 79 - Indexed is a series to write down all I've learned about web development. Think of this as my notebook 80 - scribbled with tips and lessons about how I think about websites. We'll see if I can make one of these 81 - blogs every week. 82 - 83 - That’s in the future though! For now, I’d like to thank you for reading this blog. 84 - I very much appreciate it, and if you can do me a favor, take a look at the links down below. 85 - Catch you in the next one! 86 - 87 - ## Shameless Plugs 88 - 89 - - If you'd like to look at any of my code, they are all open sourced on my Github [here](https://github.com/zeucapua). 90 - - Most of my projects are made live on my Twitch stream! Code new projects with me weekly on [twitch.tv/zeu_dev](https://twitch.tv/zeu_dev). 91 - - Any comments or questions can reach me on Twitter. Follow me at [twitter.com/zeu_dev](https://twitter.com/zeu_dev). 92 - - Interested on other stuff? Visit my personal website at [zeu.dev](https://zeu.dev) and my other blogs here on [thoughts.zeu.dev](https://thoughts.zeu.dev).
-100
src/content/blog/rash-stack.md
··· 1 - --- 2 - title: "The RASH Stack: React, Astro, Svelte, HTMX" 3 - description: Strap a horse on a rocket and use Astro Partials to stream UI components via HTMX. 4 - date: "2024-09-10" 5 - draft: true 6 - link: https://github.com/zeucapua/ 7 - --- 8 - 9 - ## The Project 10 - 11 - I'm building a Notion-like note taking system that'll (probably) make me more productive with as 12 - little fluff and features as possible. Each block can be added, edited, and deleted freely, with 13 - the full page data is saved locally. 14 - 15 - For the features to demo the RASH stack, we are making: 16 - - Plain text (Astro + HTMX) 17 - - Checkbox (Svelte) 18 - - Whiteboard (React via tldraw library) 19 - 20 - ## What is HTMX? 21 - 22 - The basic idea behind HTMX is that APIs should return HTML that shows the updated part of the page 23 - after a request. For example, let's make a button that adds our feature, simple plain text input: 24 - 25 - ```html 26 - <h1>Hodgepodge App</h1> 27 - <ul id="blocks"> 28 - 29 - </ul> 30 - 31 - <button 32 - hx-post="/addTextBlock" 33 - hx-target="#blocks" 34 - hx-swap="beforeend" 35 - > 36 - Text 37 - </button> 38 - ``` 39 - 40 - The button has a few new attributes to use HTMX: `hx-post` specifies a `POST` API request 41 - at the endpoint `/addTextBlock`; `hx-target` is to determine what element we want to update; 42 - `hx-swap` tells us how we should handle the HTML after the response, in this case adding the 43 - response before the button. Now the endpoint can return HTML like so... 44 - 45 - ```html 46 - <li><textarea /></li> 47 - ``` 48 - 49 - And on the button press, the initial page will now be: 50 - 51 - ```html 52 - <h1>Hodgepodge App</h1> 53 - <ul id="blocks"> 54 - <li><textarea /></li> 55 - </ul> 56 - 57 - <button 58 - hx-post="/addTextBlock" 59 - hx-target="#blocks" 60 - hx-swap="beforeend" 61 - > 62 - Text 63 - </button> 64 - ``` 65 - 66 - While we will be using more attributes during the rest of the blog, there are plenty more 67 - I can't possibly go over. To find more information on the list of attributes and HTMX in 68 - general, go to [htmx.org](https://htmx.org) or read their book 69 - [Hypermedia Systems](https://hypermedia.systems) which is free online, but you can be cool 70 - like me and get the physical book: 71 - 72 - # TODO: ADD PHOTO OF HYPERMEDIA SYSTEMS 73 - 74 - ## Astro Partials 75 - 76 - Since we are using Astro as our meta framework, we can use its feature **Astro Partials** in 77 - conjunction with HTMX for a smooth developer experience. It allows Astro components inside the 78 - `/src/pages` directory to be easily called via its endpoint and returned as HTML. 79 - 80 - For the example above, the only thing needed is for the Lemon to be in the 81 - `/src/pages/addTextBlock.astro` file with one extra line in the *Component Script* (the code 82 - inside the frontmatter like section ran on the server): 83 - 84 - ```astro 85 - --- 86 - export const partial = true; 87 - --- 88 - <li><textarea /></li> 89 - ``` 90 - 91 - Now we can use this page via HTMX under the `/revealSecret` endpoint, like the example above! 92 - 93 - ## Forms and Values via Astro Partials 94 - 95 - Swapping HTML is all fine and dandy, but if we want to do more, we can leverage existing 96 - hypermedia controls to extend functionality like the `<form>` and `<input>` elements. 97 - 98 - ## Streaming in Client Components as Astro Islands 99 - 100 - ## Using the HTMX Javascript API
+25
src/pages/as-seen-on.astro
··· 1 + --- 2 + import { render } from "astro:content"; 3 + import SiteLayout from "../components/SiteLayout.astro"; 4 + import { getEntry } from "astro:content"; 5 + 6 + const entry = await getEntry("about", "as-seen-on"); 7 + if (!entry) { 8 + throw new Error("Could not find ../content/about/as-seen-on.mdx"); 9 + } 10 + const { Content } = await render(entry); 11 + --- 12 + 13 + <SiteLayout title="zeu.dev"> 14 + <main class="flex flex-col gap-4 px-4 py-8 text-white text-lg"> 15 + <h1 class="text-5xl text-yellow-500 font-bold">As seen on</h1> 16 + <p class="text-yellow-500"> 17 + I've participated in a few community events and video. I stream on [stream.place](https://stream.place/zeu.dev) 18 + and [Twitch](https://twitch.tv/zeu_dev), and post videos sometimes on my [youtube channel](https://www.youtube.com/@zeucapua851). 19 + </p> 20 + 21 + <span class="prose prose-invert prose-yellow lg:prose-xl prose-headings:text-yellow-500"> 22 + <Content /> 23 + </span> 24 + </main> 25 + </SiteLayout>
+1 -1
src/pages/blog/index.astro
··· 11 11 12 12 <SiteLayout title="Blogs | zeu.dev"> 13 13 <main class="flex flex-col gap-8 py-8 max-w-3xl"> 14 - <h1 class="text-5xl text-white font-bold">Blog Posts</h1> 14 + <h1 class="text-5xl text-yellow-500 font-bold">Blog Posts</h1> 15 15 16 16 { // @ts-ignore 17 17 blogs.map((blog: any) => <BlogCard {blog} />)
+1 -14
src/pages/index.astro
··· 23 23 </pre> 24 24 <div class="flex flex-col gap-4"> 25 25 <h1 class="text-5xl font-bold text-yellow-500">hey hi hello!</h1> 26 - <h2 class="text-yellow-500 font-medium text-2xl">welcome to my site!</h2> 27 - 28 - <p> 29 - I have plenty of ideas and projects I want to talk to you guys about 30 - and so I made this site to showcase all I've been doing. 31 - </p> 32 - 33 - <p> 34 - updates and showcases will be hosted here, alongside my own thoughts. 35 - </p> 36 - 37 - 38 - <p class="text-yellow-500">- @zeu_dev</p> 39 26 </div> 40 27 41 28 <section class="flex flex-col lg:flex-row gap-8 my-8"> ··· 46 33 47 34 <a href="/resume" class="border-2 rounded-lg w-fit p-4"> 48 35 <h3 class="text-xl text-yellow-500 font-bold">Resume</h3> 49 - <p>Notable professional works</p> 36 + <p>Career and professional work</p> 50 37 </a> 51 38 </section> 52 39 </main>
+4 -1
src/pages/open-source.astro
··· 1 1 --- 2 2 import SiteLayout from "../components/SiteLayout.astro"; 3 3 import { getEntry } from "astro:content"; 4 + 4 5 const entry = await getEntry("about", "open-source"); 5 - 6 + if (!entry) { 7 + throw new Error("Could not find ../content/about/open-source.mdx"); 8 + } 6 9 const { Content } = await entry.render(); 7 10 --- 8 11
+4 -1
src/pages/resume.astro
··· 1 1 --- 2 2 import SiteLayout from "../components/SiteLayout.astro"; 3 3 import { getEntry } from "astro:content"; 4 + 4 5 const entry = await getEntry("about", "resume"); 5 - 6 + if (!entry) { 7 + throw new Error("Could not find ../content/about/resume.mdx"); 8 + } 6 9 const { Content } = await entry.render(); 7 10 --- 8 11
-12
tailwind.config.mjs
··· 1 - /** @type {import('tailwindcss').Config} */ 2 - export default { 3 - content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], 4 - theme: { 5 - extend: { 6 - fontFamily: { 7 - syne: ["SyneMono"] 8 - } 9 - }, 10 - }, 11 - plugins: [require("@tailwindcss/typography")] 12 - }