made contact form functional

This commit is contained in:
Jay Robson 2024-04-18 11:24:33 +10:00
parent ba2da4dbfe
commit 6d44c020b3
9 changed files with 83 additions and 26 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "cpp-httplib"]
path = cpp-httplib
url = https://github.com/yhirose/cpp-httplib
[submodule "matrix-commander"]
path = matrix-commander
url = https://github.com/8go/matrix-commander

View File

@ -14,5 +14,5 @@ message("Using cmake flags: ${CMAKE_CXX_FLAGS}")
file(GLOB_RECURSE SOURCES src/*.cpp)
add_executable(Portfolio ${SOURCES})
target_link_libraries(Portfolio PUBLIC stdc++)
target_link_libraries(Portfolio PUBLIC stdc++ jsoncpp)

1
matrix-commander Submodule

@ -0,0 +1 @@
Subproject commit 79a5d0c2db9b3c49de0d0538affbe07f1a266f84

23
src/contact.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "contact.hpp"
#include <format>
#include <unistd.h>
bool Contact::init()
{
return true;
}
bool Contact::send(const std::string &name, const std::string &email, const std::string &message)
{
int id = fork();
if(!id)
{
std::string body = std::format("Message: {0} ({1})\n\n{2}", name, email, message);
execlp("../matrix-commander/venv/bin/python3", "../matrix-commander/venv/bin/python3", "../matrix-commander/matrix_commander/matrix-commander", "-m", body.c_str(), nullptr);
}
return true;
}

13
src/contact.hpp Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace Contact
{
bool init();
bool send(const std::string& name, const std::string& email, const std::string& message);
};

View File

@ -1,6 +1,8 @@
#include "../cpp-httplib/httplib.h"
#include "files.hpp"
#include "contact.hpp"
#include <fstream>
#include <iostream>
@ -8,14 +10,13 @@
#include <format>
#include <regex>
std::string data_index = Files::load("../static/index.html");
std::string data_error = Files::load("../static/error.html");
httplib::Server svr;
const std::string DATA_INDEX = Files::load("../static/index.html");
const std::string DATA_ERROR = Files::load("../static/error.html");
const std::string PATH_LIGHT = "/static/css/light.css";
const std::string PATH_DARK = "/static/css/dark.css";
httplib::Server svr;
std::string get_theme(const httplib::Request& req)
{
std::string cookies = req.get_header_value("Cookie");
@ -31,7 +32,7 @@ struct page_handler
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));
std::string page = std::vformat(DATA_INDEX, std::make_format_args(get_theme(req), data_content));
res.set_content(page, "text/html");
}
};
@ -50,24 +51,38 @@ struct theme_handler
}
};
void post_contact(const httplib::Request& req, httplib::Response& res)
void put_contact(const httplib::Request& req, httplib::Response& res)
{
std::cout << "Contact form submitted\n";
std::cout << "Name: " << req.get_param_value("name") << "\n";
std::cout << "Email: " << req.get_param_value("email") << "\n";
std::cout << "Message: " << req.get_param_value("message") << "\n";
if(!req.has_param("name") || !req.has_param("email") || !req.has_param("message"))
{
res.status = 400;
res.set_content("<p>Bad request</p>", "text/html");
return;
}
if(!Contact::send(req.get_param_value("name"), req.get_param_value("email"), req.get_param_value("message")))
{
res.status = 500;
res.set_content("<p>Internal server error</p>", "text/html");
return;
}
res.set_content("<p>Message sent. Thanks!</p>", "text/html");
}
void error_handler(const httplib::Request& req, httplib::Response& res)
{
std::string page = std::vformat(data_index, std::make_format_args(get_theme(req), data_error));
std::string page = std::vformat(DATA_INDEX, std::make_format_args(get_theme(req), DATA_ERROR));
res.set_content(page, "text/html");
}
int main()
{
if(!Contact::init())
{
return 1;
}
svr.set_mount_point("/static", "../static/public/");
svr.Get("/", page_handler("../static/public/html/projects.html"));
@ -75,7 +90,7 @@ int main()
svr.Get("/contact", page_handler("../static/public/html/contact.html"));
svr.Get("/about", page_handler("../static/public/html/about.html"));
svr.Post("/contact", post_contact);
svr.Put("/contact", put_contact);
svr.set_error_handler(error_handler);

View File

@ -14,7 +14,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/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 class="right"><button id="theme-button"></button></li>
<li class="right"><button id="theme-button" class="button-emoji"></button></li>
</ul>
<div id="root-body">
<div id="main-content">

View File

@ -1,4 +1,8 @@
p, label, th, td, li {
font-size: 16px;
}
.button-link {
background: none;
border: none;
@ -10,7 +14,7 @@
img {
width: calc(min(100%, 800px));
border-radius: 0.25em;
border-radius: 4px;
border-style: none;
}
@ -54,11 +58,11 @@ ul.navbar li {
padding: 0;
}
ul.navbar li button {
ul.navbar li button, ul.navbar li .button-link {
transition: 0.25s;
background-color: inherit;
border: none;
padding: 1em 1.5em;
padding: 16px 24px;
font: inherit;
cursor: pointer;
text-decoration: none;
@ -69,11 +73,9 @@ ul.navbar li.right {
float: right;
}
ul.navbar li.right button {
font-size: 1.5em;
padding: 0;
height: 54px;
width: 54px;
ul.navbar li .button-emoji {
font-size: 30px;
padding: 6px 12px;
}
input[type="text"], input[type="email"], textarea {
@ -82,11 +84,11 @@ input[type="text"], input[type="email"], textarea {
}
input[type="text"], input[type="email"], input[type="button"], textarea, button {
border-radius: 0.25em;
border-radius: 4px;
border-width: thin;
border-style: solid;
border-color: gray;
padding: 0.5em 0.75em;
padding: 8px 12px;
}
textarea {

View File

@ -6,7 +6,7 @@
<div id="contact-response">
<p>
You can contact me via this form or by emailing me at <a href="mailto:jsrobson10@gmail.com">jsrobson10@gmail.com</a>.
<form hx-post="/contact", hx-target="#contact-response">
<form hx-put="/contact", hx-target="#contact-response">
<label for="contact-name">Name</label>
<input type="text" name="name" id="contact-name" required />
<label for="contact-email">Email</label>