wip: New Application Architecture

Explore a new approach to clean up the implementation of an AppShell and individual pages. Will likely retire htmx for a lightweight custom page router.
This commit is contained in:
2025-10-17 13:53:30 -07:00
parent cc79afaea0
commit 16cf44b42d
21 changed files with 129 additions and 260 deletions

44
src/frontend/AppShell.tsx Normal file
View File

@@ -0,0 +1,44 @@
import { Html } from "@elysiajs/html";
const styles = Bun.file("./src/public/styles.css").text();
const headScript = Bun.file("./src/public/head.js").text();
const onLoadScript = Bun.file("./src/public/onLoad.js").text();
export function AppShell(responseValue: any) {
return (
<html>
<head>
<title>Caleb's Blog</title>
<style>
{styles}
</style>
<script>
{headScript}
</script>
<script defer>
{onLoadScript}
</script>
</head>
<body>
{responseValue}
<aside>
<h3>About Me</h3>
<p>I'm a software engineer</p>
<ul>
<li>Twitter</li>
<li>GitHub</li>
<li>LinkedIn</li>
</ul>
<h3>Categories</h3>
<ul>
<li>Web Development</li>
<li>UI/UX Design</li>
<li>Productivity</li>
<li>Career</li>
</ul>
</aside>
</body>
</html>
)
}

9
src/frontend/blog.tsx Normal file
View File

@@ -0,0 +1,9 @@
import { Html } from "@elysiajs/html";
export function Blog() {
return (
<main>
<h1>Blog</h1>
</main>
)
}

View File

@@ -1,15 +0,0 @@
export function Header() {
return (
<div>
<header hx-boost="true">
<span>Caleb Braaten</span>
<nav>
<a hx-target="main" href="/">Home</a>
<a hx-target="main" href="/blog">Blog</a>
<a hx-target="main" href="/projects">Projects</a>
</nav>
</header>
<hr />
</div>
)
}

View File

@@ -1,60 +0,0 @@
export function GithubIcon(props: any) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
<path d="M9 18c-4.51 2-5-2-7-2" />
</svg>
)
}
export function LinkedinIcon(props: any) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z" />
<rect width="4" height="12" x="2" y="9" />
<circle cx="4" cy="4" r="2" />
</svg>
)
}
export function XIcon(props: any) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 1200 1227"
preserveAspectRatio="none"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="black" />
</svg>
)
}

9
src/frontend/home.tsx Normal file
View File

@@ -0,0 +1,9 @@
import { Html } from "@elysiajs/html";
export function Home() {
return (
<main>
<h1>Home</h1>
</main>
)
}

View File

@@ -1,35 +0,0 @@
import { Header } from "./components/Header";
import { Home } from "./pages/home";
import { Blog } from "./pages/blog";
import { Projects } from "./pages/projects";
export function Index(path: string) {
return (
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script defer src="./htmx.min.js"></script>
<title>Caleb's Blog</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<Header />
<main>
{selectPage(path)}
</main>
</body>
</html>
)
}
export function selectPage(path: string) {
switch (path) {
case '/':
return <Home />
case '/blog':
return <Blog />
case '/projects':
return <Projects />
}
}

View File

@@ -0,0 +1,9 @@
import { Html } from "@elysiajs/html";
export function NotFound() {
return (
<main>
<h1>404 Not Found</h1>
</main>
)
}

View File

@@ -1,50 +0,0 @@
export function Blog(){
return (
<div>
<section>
<article>
<h2>Blog Post Title</h2>
<div>Posted on January 1, 2024</div>
<p>Google Chrome is a web browser developed by Google, released in 2008. Chrome is the world's most popular web browser today!</p>
<a href="/post/3">Read More</a>
</article>
<article>
<h2>Another Blog Post Title</h2>
<div>Posted on December 1, 2023</div>
<p>Mozilla Firefox is an open-source web browser developed by Mozilla. Firefox has been the second most popular web browser since January, 2018.</p>
<a href="/post/2">Read More</a>
</article>
<article>
<h2>The First Blog Post</h2>
<div>Posted on November 1, 2023</div>
<p>Microsoft Edge is a web browser developed by Microsoft, released in 2015. Microsoft Edge replaced Internet Explorer.</p>
<a href="/post/1">Read More</a>
</article>
</section>
<aside>
<div>
<h3>About Me</h3>
<p>I'm a software engineer</p>
<h3>Connect with me</h3>
<ul>
<li>Twitter</li>
<li>GitHub</li>
<li>LinkedIn</li>
</ul>
</div>
<div>
<h3>Categories</h3>
<ul>
<li>Web Development</li>
<li>UI/UX Design</li>
<li>Productivity</li>
<li>Career</li>
</ul>
</div>
</aside>
</div>
)
}

View File

@@ -1,41 +0,0 @@
import { GithubIcon, LinkedinIcon, XIcon } from "../components/icons"
export function Home(){
return (
<div>
<article class="post-spotlight">
<h2>Most Recent Blog Post Title</h2>
<div>Posted on January 1, 2024</div>
<p>Google Chrome is a web browser developed by Google, released in 2008. Chrome is the world's most popular web browser today!</p>
<a href="/post/3">Continue Reading...</a>
</article>
<hr />
<aside>
<div class="about">
<h3>About Me</h3>
<p>I'm a software engineer</p>
<ul>
<li>
<a href=""><XIcon /></a>
</li>
<li>
<a href=""><GithubIcon /></a>
</li>
<li>
<a href=""><LinkedinIcon /></a>
</li>
</ul>
</div>
<div class="content-categories">
<h3>Categories</h3>
<ul>
<li>Web Development</li>
<li>UI/UX Design</li>
<li>Productivity</li>
<li>Career</li>
</ul>
</div>
</aside>
</div>
)
}

View File

@@ -1,18 +0,0 @@
export function Projects(){
return (
<div class="projects">
<div>
<img src="https://via.placeholder.com/150" />
<h2>This Site</h2>
<p>Project 1 description</p>
<a href="/project/1">Git Repo</a>
</div>
<div>
<img src="https://via.placeholder.com/150" />
<h2>Home Server</h2>
<p>Project 1 description</p>
<a href="/project/1">Git Repo</a>
</div>
</div>
)
}

File diff suppressed because one or more lines are too long

View File

@@ -1,97 +0,0 @@
body, a {
margin: 0px;
text-decoration: none;
color: black;
}
header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
background-color: #f2f2f2;
padding: 15px;
height: 50px;
}
header span {
font-size: 30px;
font-weight: bold;
}
nav {
display: flex;
flex-direction: row;
align-items: center;
text-align: center;
gap: 10px;
}
nav a {
text-decoration: none;
color: black;
font-size: 20px;
}
hr {
margin: 0px;
opacity: 75%;
}
.post-spotlight {
display: flex;
flex-direction: column;
align-items: center;
margin: 30px;
padding: 4em;
}
article {
font-family: 'Arial Narrow Bold', sans-serif;
}
article > h2 {
font-size: 3em;
font-weight: bold;
margin: 15px;
}
article > div {
color: gray;
}
article > a {
text-decoration: none;
border: 1px solid black;
padding: 10px;
border-radius: 5px;
background-color: #f2f2f2;
color: black;
text-align: end;
}
aside {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
margin: 15px;
}
aside h3 {
font-size: 2em;
font-weight: bold;
}
aside ul {
list-style-type: none;
padding: 0px;
}
.about ul {
display: flex;
flex-direction: row;
gap: 10px;
}