diff options
| author | Elias Haugsbakk <[email protected]> | 2026-07-01 14:05:14 +0200 |
|---|---|---|
| committer | Elias Haugsbakk <[email protected]> | 2026-07-01 14:05:14 +0200 |
| commit | c4da920843972b6571e978cdc9f9278eb87b7398 (patch) | |
| tree | f972778f7cab4e4b231f5adc7450d590fa6d0fae /clams-server/src | |
| parent | 5ed99f3c87f0337ffac03dd1e45073fbc7f63b68 (diff) | |
add HTML, CSS and basic routing
Diffstat (limited to 'clams-server/src')
| -rw-r--r-- | clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java | 16 | ||||
| -rw-r--r-- | clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java | 21 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/css/blog.css | 58 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/css/common.css | 195 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/css/home.css | 27 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/css/post.css | 63 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/css/projects.css | 60 | ||||
| -rw-r--r-- | clams-server/src/main/resources/public/images/elias_haugsbakk.JPEG | bin | 0 -> 438398 bytes | |||
| -rw-r--r-- | clams-server/src/main/resources/templates/404.html | 41 | ||||
| -rw-r--r-- | clams-server/src/main/resources/templates/blog.html | 48 | ||||
| -rw-r--r-- | clams-server/src/main/resources/templates/home.html | 39 | ||||
| -rw-r--r-- | clams-server/src/main/resources/templates/post.html | 38 | ||||
| -rw-r--r-- | clams-server/src/main/resources/templates/projects.html | 87 |
13 files changed, 692 insertions, 1 deletions
diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java index 62c1677..200d23d 100644 --- a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/Main.java @@ -1,11 +1,25 @@ package no.eliashaugsbakk.clams.server; import io.javalin.Javalin; +import io.javalin.rendering.template.JavalinPebble; +import no.eliashaugsbakk.clams.server.controller.BlogController; public class Main { void main() { + BlogController blogController = new BlogController(); + var app = Javalin.create(config -> { - config.routes.get("/", ctx -> ctx.result("Hello World")); + config.staticFiles.add("/public"); + config.fileRenderer(new JavalinPebble()); + + config.routes.error(404, ctx -> ctx.render("templates/404.html")); + + config.routes.get("/", ctx -> ctx.redirect("/home")); + config.routes.get("/home", ctx -> ctx.render("templates/home.html")); + config.routes.get("/projects", ctx -> ctx.render("templates/projects.html")); + + config.routes.get("/blog/{slug}", blogController::handleGetPost); + config.routes.get("/blog", blogController::handleGetOverview); }).start(7070); } } diff --git a/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java new file mode 100644 index 0000000..d4fc9d3 --- /dev/null +++ b/clams-server/src/main/java/no/eliashaugsbakk/clams/server/controller/BlogController.java @@ -0,0 +1,21 @@ +package no.eliashaugsbakk.clams.server.controller; + +import io.javalin.http.Context; +import java.util.Map; + +public class BlogController { + public void handleGetPost(Context ctx) { + ctx.render("templates/post.html", + Map.of("title", "place holder Title", + "published_date", "place holder Release Date", + "author", "place holder Author", + "content", "place holder Content")); + } + + public void handleGetOverview(Context ctx) { + ctx.render("templates/blog.html", Map.of( + "all_posts_by_year", "place holder for all posts", + "recent_posts", " place holder for recent posts" + )); + } +} diff --git a/clams-server/src/main/resources/public/css/blog.css b/clams-server/src/main/resources/public/css/blog.css new file mode 100644 index 0000000..86eb0ed --- /dev/null +++ b/clams-server/src/main/resources/public/css/blog.css @@ -0,0 +1,58 @@ +/* blog.css - page specific styles */ + +.intro-text { + margin-bottom: 60px; +} + +section { + margin-bottom: 60px; +} + +.search-form { + position: absolute; + top: 20px; + right: 20px; +} + +.search-form input { + font-family: var(--font-serif), serif; + padding: 6px 10px; + border: 1px solid var(--border-color); + border-radius: 4px; + background: transparent; + color: var(--text-color); + width: 180px; + font-size: 0.8rem; +} + +.search-form button { + font-family: var(--font-serif), serif; + padding: 6px 12px; + background: #e8e8e4; + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: 4px; + cursor: pointer; + font-weight: bold; + font-size: 0.8rem; +} + +.search-form button:hover { + background: #ddd; +} + +@media (max-width: 850px) { + .search-form { + position: static; + text-align: center; + margin-bottom: 40px; + } + .search-form input { + width: 250px; + } +} + +/* Specific spacing for blog lists */ +.content-grid li { + margin-bottom: 0.8rem; +} diff --git a/clams-server/src/main/resources/public/css/common.css b/clams-server/src/main/resources/public/css/common.css new file mode 100644 index 0000000..3c8d927 --- /dev/null +++ b/clams-server/src/main/resources/public/css/common.css @@ -0,0 +1,195 @@ +* { box-sizing: border-box; } + +:root { + --bg-color: #efefeb; + --text-color: #373838; + --border-color: #ccc; + --font-serif: "Times New Roman", serif; +} + +html, body { + height: 100%; + margin: 0; + font-size: 18px; + background-color: var(--bg-color); + color: var(--text-color); + font-family: var(--font-serif), serif; + line-height: 1.6; +} + +body { + display: flex; + flex-direction: column; + align-items: center; +} + +.main-container { + max-width: 800px; + width: 90%; + padding: 20px; + flex: 1; + position: relative; +} + +h1 { + text-align: center; + margin-top: 40px; + margin-bottom: 40px; + font-size: 2.5rem; +} + +h2 { + font-size: 1.2rem; + border-bottom: 1px solid var(--border-color); + margin-bottom: 20px; + padding-bottom: 5px; + text-transform: uppercase; + letter-spacing: 1px; +} + +.content-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 60px; + margin-top: 30px; +} + +.left-column { text-align: right; } +.right-column { text-align: left; } + +ul { + list-style-type: none; + padding: 0; + margin: 0; +} + +li { margin-bottom: 1rem; } + +details { + margin-bottom: 1rem; + cursor: pointer; +} + +summary { + font-weight: bold; + list-style: none; /* Removes the default arrow in some browsers */ +} + +summary::-webkit-details-marker { + display: none; /* Removes the default arrow in Safari/Chrome */ +} + +summary:hover { + opacity: 0.7; +} + +.tag { + display: inline-block; + background-color: rgba(0,0,0,0.05); + padding: 2px 8px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: bold; + text-transform: uppercase; + letter-spacing: 1px; + margin-right: 5px; + border: 1px solid var(--border-color); +} + +details ul { + margin-top: 10px; + padding-left: 20px; + border-left: 2px solid var(--border-color); +} + +a { + color: var(--text-color); + text-decoration: underline; + font-weight: bold; + transition: opacity 0.2s; +} + +a:hover { + opacity: 0.7; +} + +footer { + padding: 30px 20px; + border-top: 1px solid var(--border-color); + width: 100%; + font-size: 0.9rem; +} + +footer p { + margin: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.footer-left { + flex: 1; + text-align: right; + padding-right: 15px; +} + +.footer-right { + flex: 1; + text-align: left; + padding-left: 15px; +} + +.footer-separator { + opacity: 0.5; +} + +.intro-text { + text-align: center; + max-width: 600px; + margin: 0 auto 60px auto; +} + +@media (max-width: 600px) { + .content-grid { + grid-template-columns: 1fr; + gap: 40px; + } + .left-column, .right-column { text-align: center; } + + footer p { + flex-direction: column; + gap: 10px; + } + .footer-left, .footer-right { + text-align: center; + padding: 0; + } + .footer-separator { + display: none; + } +} + +/* Subtle Scrollbar Styling */ +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: var(--bg-color); +} + +::-webkit-scrollbar-thumb { + background-color: #d1d1cd; + border-radius: 20px; + border: 3px solid var(--bg-color); +} + +::-webkit-scrollbar-thumb:hover { + background-color: #bbb; +} + +/* Firefox Support */ +* { + scrollbar-width: thin; + scrollbar-color: #d1d1cd var(--bg-color); +} diff --git a/clams-server/src/main/resources/public/css/home.css b/clams-server/src/main/resources/public/css/home.css new file mode 100644 index 0000000..c3679b4 --- /dev/null +++ b/clams-server/src/main/resources/public/css/home.css @@ -0,0 +1,27 @@ +.profile-img { + border: 3px solid var(--text-color); + border-radius: 20px; + width: 200px; + display: block; + margin-left: auto; + margin-bottom: 20px; +} + +.right-column a { + font-size: 1.2rem; +} + +.description { + display: block; + font-size: 0.9rem; + opacity: 0.8; + white-space: normal; + overflow: visible; + word-wrap: break-word; +} + +@media (max-width: 600px) { + .profile-img { + margin: 0 auto 20px auto; + } +} diff --git a/clams-server/src/main/resources/public/css/post.css b/clams-server/src/main/resources/public/css/post.css new file mode 100644 index 0000000..0c8391c --- /dev/null +++ b/clams-server/src/main/resources/public/css/post.css @@ -0,0 +1,63 @@ +/* post.css - specific styles for blog posts */ + +.post-header { + display: flex; + justify-content: space-between; + margin-bottom: 40px; + font-size: 0.9rem; + opacity: 0.7; + border-bottom: 1px solid var(--border-color); + padding-bottom: 10px; +} + +.post-content { + line-height: 1.8; + margin-bottom: 80px; +} + +.post-content p { + margin-bottom: 1.5rem; +} + +.post-image { + margin: 40px 0; + text-align: center; +} + +.post-image img { + max-width: 100%; + height: auto; + border: 1px solid var(--border-color); + border-radius: 8px; +} + +.post-image figcaption { + margin-top: 10px; + font-size: 0.85rem; + opacity: 0.7; +} + +.post-nav { + display: flex; + justify-content: space-between; + margin-top: 60px; + padding-top: 30px; + border-top: 1px dashed var(--border-color); +} + +.prev-post, .next-post { + font-size: 1rem; + text-decoration: none; +} + +.prev-post:hover, .next-post:hover { + text-decoration: underline; +} + +@media (max-width: 600px) { + .post-header { + flex-direction: column; + align-items: center; + gap: 10px; + } +} diff --git a/clams-server/src/main/resources/public/css/projects.css b/clams-server/src/main/resources/public/css/projects.css new file mode 100644 index 0000000..8453a01 --- /dev/null +++ b/clams-server/src/main/resources/public/css/projects.css @@ -0,0 +1,60 @@ +/* projects.css - specific styles for the projects page */ + +.projects-category { + margin-bottom: 80px; +} + +.project-item { + margin-bottom: 100px; +} + +.project-item h3 { + margin-top: 0; + font-size: 1.5rem; +} + +.tech-stack { + margin: 10px 0 20px 0; +} + +.project-links { + margin-top: 20px; + font-size: 0.9rem; +} + +.project-img, .project-placeholder { + width: 100%; + border: 1px solid var(--border-color); + border-radius: 8px; + display: block; +} + +.project-placeholder { + height: 200px; + background-color: #e0e0dc; + display: flex; + align-items: center; + justify-content: center; + color: #888; + font-size: 0.9rem; +} + +/* Simple list for smaller projects */ +.simple-project-list { + margin-top: 30px; +} + +.simple-project-list li { + margin-bottom: 1.5rem; +} + +.tech-stack-inline { + font-size: 0.85rem; + opacity: 0.6; + margin: 0 10px; +} + +.small-link { + font-size: 0.8rem; + margin-left: 5px; +} diff --git a/clams-server/src/main/resources/public/images/elias_haugsbakk.JPEG b/clams-server/src/main/resources/public/images/elias_haugsbakk.JPEG Binary files differnew file mode 100644 index 0000000..1cef0f9 --- /dev/null +++ b/clams-server/src/main/resources/public/images/elias_haugsbakk.JPEG diff --git a/clams-server/src/main/resources/templates/404.html b/clams-server/src/main/resources/templates/404.html new file mode 100644 index 0000000..6bbcecd --- /dev/null +++ b/clams-server/src/main/resources/templates/404.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>404 - Page Not Found</title> + <link rel="stylesheet" href="/css/common.css"> + <style> + .error-container { + text-align: center; + margin-top: 100px; + } + .error-code { + font-size: 5rem; + margin-bottom: 10px; + opacity: 0.3; + } + </style> +</head> +<body> + + <main class="main-container"> + <div class="error-container"> + <div class="error-code">404</div> + <h1>Page Not Found</h1> + <p>The page you are looking for does not exist.</p> + <p style="margin-top: 40px;"> + <a href="/">Return to Home Page</a> + </p> + </div> + </main> + + <footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> + </footer> + +</body> +</html> diff --git a/clams-server/src/main/resources/templates/blog.html b/clams-server/src/main/resources/templates/blog.html new file mode 100644 index 0000000..168cfe1 --- /dev/null +++ b/clams-server/src/main/resources/templates/blog.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Elias Haugsbakk's Blog</title> + <link rel="stylesheet" href="/css/common.css"> + <link rel="stylesheet" href="/css/blog.css"> +</head> +<body> + +<main class="main-container"> + <header> + <h1>Elias Haugsbakk's Blog</h1> + <p class="intro-text">This is the home page for my blog. The list of blog posts is a diverse collection of some of my writings; if you're just browsing, this might be a good place to start.</p> + + <form action="/blog" method="GET" class="search-form"> + <input type="text" name="search" value="{{ search_value }}" placeholder="Search posts..." aria-label="Search blog posts"> + <button type="submit">Search</button> + </form> + </header> + + <div class="content-grid"> + <div class="left-column"> + <section id="all"> + <h2>{{ all_posts_title }}</h2> + <!-- Tells Pebble to trust your pre-grouped HTML links --> + {{ all_posts_by_year | raw }} + </section> + </div> + + <div class="right-column"> + <section id="recent"> + <h2>Recent</h2> + {{ recent_posts | raw }} + </section> + </div> + </div> +</main> + +<footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> +</footer> +</body> +</html> diff --git a/clams-server/src/main/resources/templates/home.html b/clams-server/src/main/resources/templates/home.html new file mode 100644 index 0000000..199ae29 --- /dev/null +++ b/clams-server/src/main/resources/templates/home.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Elias Haugsbakk</title> + <link rel="stylesheet" href="/css/common.css"> + <link rel="stylesheet" href="/css/home.css"> +</head> +<body> + + <main class="main-container"> + <h1>Elias Haugsbakk's Webpage</h1> + + <div class="content-grid"> + <div class="left-column"> + <img src="/images/elias_haugsbakk.JPEG" alt="Image of Elias Haugsbakk" class="profile-img"> + <p>Hello! I am Elias and this is my webpage.</p> + </div> + + <div class="right-column"> + <ul> + <li><a href="/blog">Blog</a> <span class="description">-- personal projects and thoughts</span></li> + <li><a href="https://github.com/eliashaugsbakk">GitHub</a> <span class="description">-- home for my code</span></li> + <li><a href="/projects">Projects</a> <span class="description">-- the projects I have worked on</span></li> + </ul> + </div> + </div> + </main> + + <footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> + </footer> + +</body> +</html> diff --git a/clams-server/src/main/resources/templates/post.html b/clams-server/src/main/resources/templates/post.html new file mode 100644 index 0000000..85f8977 --- /dev/null +++ b/clams-server/src/main/resources/templates/post.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>{{ title }} - Elias Haugsbakk</title> + <link rel="stylesheet" href="/css/common.css"> + <link rel="stylesheet" href="/css/post.css"> +</head> +<body> + +<main class="main-container"> + <header class="post-header"> + <span class="post-date">{{ published_date }}</span> + <span class="post-author">{{ author }}</span> + </header> + + <h1>{{ title }}</h1> + + <article class="post-content"> + {{ content | raw }} + </article> + + <nav class="post-nav"> + {{ previous_post_link | raw }} + {{ next_post_link | raw }} + </nav> +</main> + +<footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> +</footer> + +</body> +</html> diff --git a/clams-server/src/main/resources/templates/projects.html b/clams-server/src/main/resources/templates/projects.html new file mode 100644 index 0000000..8af0538 --- /dev/null +++ b/clams-server/src/main/resources/templates/projects.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Projects - Elias Haugsbakk</title> + <link rel="stylesheet" href="/css/common.css"> + <link rel="stylesheet" href="/css/projects.css"> +</head> +<body> + +<main class="main-container"> + <header> + <h1>Projects</h1> + </header> + + <section class="projects-category"> + <h2>Featured Projects</h2> + + <div class="project-item"> + <div class="content-grid"> + <div class="left-column"> + <h3>Project One Name</h3> + <div class="tech-stack"> + <span class="tag">Java</span> + <span class="tag">SQLite</span> + </div> + <p>Short project description / introduction.</p> + <div class="project-links"> + <a href="#">GitHub</a> | <a href="#">Live Demo</a> + </div> + </div> + <div class="right-column"> + <div class="project-placeholder"> + <span>Image Placeholder</span> + </div> + </div> + </div> + </div> + + <div class="project-item"> + <div class="content-grid"> + <div class="left-column"> + <h3>Project Two Name</h3> + <div class="tech-stack"> + <span class="tag">Rust</span> + </div> + <p>Short project description / introduction.</p> + <div class="project-links"> + <a href="#">GitHub</a> | <a href="#">Read More</a> + </div> + </div> + <div class="right-column"> + <div class="project-placeholder"> + <span>Image Placeholder</span> + </div> + </div> + </div> + </div> + </section> + + <section class="projects-category"> + <h2>Other Projects</h2> + <ul class="simple-project-list"> + <li> + <strong>Other Project One</strong> - A short one-line description. + <span class="tech-stack-inline">(Bash)</span> + <a href="#" class="small-link">GitHub</a> + </li> + <li> + <strong>Other Project Two</strong> - A short one-line description. + <span class="tech-stack-inline">(Python, PostgreSQL)</span> + <a href="#" class="small-link">GitHub</a> + </li> + </ul> + </section> +</main> + +<footer> + <p> + <span class="footer-left"><a href="/">eliashaugsbakk.xyz</a></span> + <span class="footer-separator">|</span> + <span class="footer-right"><a href="mailto:[email protected]">[email protected]</a></span> + </p> +</footer> + +</body> +</html> |
