add themes, better backend

This commit is contained in:
Jay Robson 2024-03-09 19:26:51 +11:00
parent f1a70a2abc
commit 058bcd5c65
10 changed files with 243 additions and 49 deletions

View File

@ -3,7 +3,7 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
std::string Files::load(const char* path) std::string Files::load(const std::string& path)
{ {
std::ifstream file(path); std::ifstream file(path);
std::stringstream ss; std::stringstream ss;

View File

@ -5,6 +5,6 @@
namespace Files namespace Files
{ {
std::string load(const char* path); std::string load(const std::string& path);
} }

View File

@ -6,25 +6,57 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <format> #include <format>
#include <regex>
std::string data_index = Files::load("../static/index.html"); std::string data_index = Files::load("../static/index.html");
std::string data_projects = Files::load("../static/public/html/projects.html"); std::string data_error = Files::load("../static/error.html");
std::string data_contact = Files::load("../static/public/html/contact.html");
std::string data_about = Files::load("../static/public/html/about.html");
std::string data_resume = Files::load("../static/public/html/resume.html");
std::string data_404 = Files::load("../static/public/html/error.html");
httplib::Server svr; httplib::Server svr;
auto page_handler(std::string data_content) std::string theme_light = R"(
<div><link rel="stylesheet" href="/static/css/light.css"></div>
<button hx-post="/theme/dark" hx-target="#theme-target" aria-label="Light mode">&#x1F31E</button>
)";
std::string theme_dark = R"(
<div><link rel="stylesheet" href="/static/css/dark.css"></div>
<button hx-post="/theme/light" hx-target="#theme-target" aria-label="Dark mode">&#x1F319</button>
)";
std::string get_theme(const httplib::Request& req)
{ {
return [data_content](const httplib::Request& req, httplib::Response& res) std::string cookies = req.get_header_value("Cookie");
{ return regex_search(cookies, std::regex("(^|(; *))theme=light")) ? theme_light : theme_dark;
std::string data = std::vformat(data_index, std::make_format_args(data_content));
res.set_content(data, "text/html");
};
} }
struct page_handler
{
std::string path;
page_handler(std::string path) : path(path) {}
void operator()(const httplib::Request& req, httplib::Response& res)
{
std::string data_content = Files::load(path);
std::string page = std::vformat(data_index, std::make_format_args(get_theme(req), data_content));
res.set_content(page, "text/html");
}
};
struct theme_handler
{
std::string theme;
std::string content;
theme_handler(std::string theme, std::string content) : theme(theme), content(content) {}
void operator()(const httplib::Request& req, httplib::Response& res)
{
res.set_header("Set-Cookie", std::format("theme={}; Path=/; SameSite=Strict; HttpOnly; Max-Age=31536000", theme));
res.set_content(content, "text/html");
}
};
void post_contact(const httplib::Request& req, httplib::Response& res) void post_contact(const httplib::Request& req, httplib::Response& res)
{ {
std::cout << "Contact form submitted\n"; std::cout << "Contact form submitted\n";
@ -37,21 +69,22 @@ void post_contact(const httplib::Request& req, httplib::Response& res)
void error_handler(const httplib::Request& req, httplib::Response& res) void error_handler(const httplib::Request& req, httplib::Response& res)
{ {
std::string data = std::vformat(data_index, std::make_format_args(data_404)); std::string page = std::vformat(data_index, std::make_format_args(get_theme(req), data_error));
res.set_content(data, "text/html"); res.set_content(page, "text/html");
} }
int main() int main()
{ {
svr.set_mount_point("/static", "../static/public/"); svr.set_mount_point("/static", "../static/public/");
svr.Get("/", page_handler(data_projects)); svr.Get("/", page_handler("../static/public/html/projects.html"));
svr.Get("/projects", page_handler(data_projects)); svr.Get("/projects", page_handler("../static/public/html/projects.html"));
svr.Get("/contact", page_handler(data_contact)); svr.Get("/contact", page_handler("../static/public/html/contact.html"));
svr.Get("/about", page_handler(data_about)); svr.Get("/about", page_handler("../static/public/html/about.html"));
svr.Get("/resume", page_handler(data_resume));
svr.Post("/contact", post_contact); svr.Post("/contact", post_contact);
svr.Post("/theme/light", theme_handler("light", theme_light));
svr.Post("/theme/dark", theme_handler("dark", theme_dark));
svr.set_error_handler(error_handler); svr.set_error_handler(error_handler);

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<link rel="stylesheet" href="/static/style.css" /> <link rel="stylesheet" href="/static/css/style.css" />
<script src="/static/js/htmx.min.js"></script> <script src="/static/js/htmx.min.js"></script>
</head> </head>
<body> <body>
@ -11,7 +11,7 @@
<li><button hx-get="/static/html/projects.html" hx-target="#main-content" hx-push-url="/">Projects</button></li> <li><button hx-get="/static/html/projects.html" hx-target="#main-content" hx-push-url="/">Projects</button></li>
<li><button hx-get="/static/html/contact.html" hx-target="#main-content" hx-push-url="/contact">Contact</button></li> <li><button hx-get="/static/html/contact.html" hx-target="#main-content" hx-push-url="/contact">Contact</button></li>
<li><button hx-get="/static/html/about.html" hx-target="#main-content" hx-push-url="/about">About</button></li> <li><button hx-get="/static/html/about.html" hx-target="#main-content" hx-push-url="/about">About</button></li>
<li><button hx-get="/static/html/resume.html" hx-target="#main-content" hx-push-url="/resume">Resume</button></li> <li class="right" id="theme-target">{}</li>
</ul> </ul>
<div id="root-body"> <div id="root-body">
<div id="main-content"> <div id="main-content">

View File

@ -0,0 +1,58 @@
h1, h2, h3, h4, h5, h6, p, li, th, td, label {
color: lightgray;
}
a:link, .button-link {
color: #2b7bab;
}
a:visited {
color: #0b8b8b;
}
a:hover, .button-link:hover {
background-color: inherit;
color: #ab4b4b;
}
input:focus, textarea:focus {
outline: none;
}
input, button, textarea {
background-color: #101014;
}
button, input, textarea {
color: lightgray;
}
input[type="text"], input[type="email"], input[type="button"], textarea, button {
border-color: gray;
}
button:hover {
background-color: #30303c;
}
th, td {
border: 1px solid gray;
}
ul.navbar {
background-color: #282830;
}
ul.navbar button:hover {
background-color: #383846;
}
html, body {
background-color: #101018;
}
#root-head {
background-color: #202028;
}

View File

@ -0,0 +1,54 @@
button, input, textarea {
color: black;
}
input[type="text"], input[type="email"], input[type="button"], textarea, button {
border-color: black;
}
button:hover {
background-color: lightgray;
}
h1, h2, h3, h4, h5, h6, p, li, th, td, label {
color: black;
}
a:link, .button-link {
color: blue;
}
a:visited {
color: purple;
}
input, button, textarea {
background-color: white;
}
a:hover, .button-link:hover {
background-color: inherit;
color: red;
}
th, td {
border: 1px solid black;
}
ul.navbar {
background-color: #c8c8d8;
}
ul.navbar button:hover {
background-color: #b8b8c8;
}
html, body {
background-color: #f0f0ff;
}
#root-head {
background-color: #e0e0ee;
}

View File

@ -1,4 +1,13 @@
.button-link {
background: none;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
text-decoration: underline;
}
img { img {
width: calc(min(100%, 800px)); width: calc(min(100%, 800px));
border-radius: 0.25em; border-radius: 0.25em;
@ -9,7 +18,16 @@ button {
font: inherit; font: inherit;
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
color: black; }
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: left;
padding: 0.75em;
} }
.visually-hidden { .visually-hidden {
@ -22,43 +40,40 @@ button {
transform: translateY(-100%); transform: translateY(-100%);
} }
.button-link {
background: none;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
text-decoration: underline;
color: blue;
}
ul.navbar { ul.navbar {
list-style-type: none; list-style-type: none;
background-color: #c0c0c4;
margin: 0; margin: 0;
padding: 0; padding: 0;
display: flex; overflow: hidden;
} }
ul.navbar li { ul.navbar li {
display: inline; display: inline;
float: left;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
ul.navbar button { ul.navbar li button {
background-color: #c0c0c4; transition: 0.25s;
background-color: inherit;
border: none; border: none;
padding: 1em 1.5em; padding: 1em 1.5em;
font: inherit; font: inherit;
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
display: block; display: block;
color: black;
} }
ul.navbar button:hover { ul.navbar li#theme-target {
background-color: #a0a0a4; float: right;
}
ul.navbar li#theme-target button {
font-size: 1.5em;
padding: 0;
height: 54px;
width: 54px;
} }
input[type="text"], input[type="email"], textarea { input[type="text"], input[type="email"], textarea {
@ -71,7 +86,7 @@ input[type="text"], input[type="email"], input[type="button"], textarea, button
border-width: thin; border-width: thin;
border-style: solid; border-style: solid;
border-color: gray; border-color: gray;
padding: 0.25em 0.5em; padding: 0.5em 0.75em;
} }
textarea { textarea {
@ -84,7 +99,6 @@ label {
} }
html, body { html, body {
background-color: #404044;
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -93,7 +107,6 @@ html, body {
#root-head { #root-head {
margin: 0 auto; margin: 0 auto;
padding: 0; padding: 0;
background-color: #e0e0e0;
display: block; display: block;
max-width: calc(max(80%, 800px)); max-width: calc(max(80%, 800px));
min-height: 100%; min-height: 100%;

View File

@ -1,5 +1,46 @@
<title>Jays Portfolio - About</title> <title>Jays Portfolio - About</title>
<h1>About</h1> <h2>About Me</h2>
<h2>Education</h2>
<table>
<tr>
<th width="150px">Time</th>
<th>Location</th>
<th>Course</th>
</tr>
<tr>
<td>2022 - Present</td>
<td>University of Tasmania</td>
<td>Bachelor of Information and Communication Technology</td>
</tr>
<tr>
<td>2020 - 2021</td>
<td>Hobart College</td>
<td>Year 11 and 12</td>
</tr>
</table>
<h2>Experience</h2>
<table>
<tr>
<th width="150px">Time</th>
<th>Location</th>
<th>Role</th>
</tr>
<tr>
<td>2020 - Present</td>
<td>Goulds Natural Medicine - Webstore</td>
<td>Full Stack Developer - Contractor</td>
<tr>
<td>2019</td>
<td>EditorKH - Jumpcutter</td>
<td>Frontend Developer - Internship</td>
</tr>
</table>
<h2>Skills</h2>

View File

@ -1,5 +0,0 @@
<title>Jays Portfolio - Resume</title>
<h1>Resume</h1>