Add contact form functionality and enhance logo styles

This commit is contained in:
Daniel LaForce 2025-04-09 17:38:13 -06:00
parent 236e64a2cc
commit 04c59f7d7a
6 changed files with 127 additions and 82 deletions

View File

@ -0,0 +1,54 @@
import { Resend } from 'resend';
/**
* Cloudflare Pages Function - /api/send-email
*/
export async function onRequestPost(context) {
const { name, email, subject, message } = await context.request.json();
try {
const response = await fetch("https://api.mailersend.com/v1/email", {
method: "POST",
headers: {
Authorization: "Bearer " + context.env.MAILERSEND_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
from: {
email: "daniel@laforceit.com",
name: "Daniel LaForce"
},
to: [
{
email: "daniel@laforceit.com",
name: "Daniel LaForce"
}
],
subject: `[Argobox] ${subject}`,
html: `
<h2>New Contact Message</h2>
<p><strong>Name:</strong> ${name}</p>
<p><strong>Email:</strong> ${email}</p>
<p><strong>Message:</strong><br>${message.replace(/\n/g, "<br>")}</p>
`,
reply_to: [
{
email,
name
}
]
})
});
if (!response.ok) {
console.error("MailerSend Error:", await response.json());
return new Response(JSON.stringify({ error: "Failed to send email" }), { status: 500 });
}
return new Response(JSON.stringify({ success: true }), { status: 200 });
} catch (err) {
console.error("Unexpected Error:", err);
return new Response(JSON.stringify({ error: "Unexpected server error" }), { status: 500 });
}
}

View File

@ -25,7 +25,6 @@
<!-- CSS -->
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="test-styles.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
@ -41,8 +40,7 @@
<div class="container">
<div class="logo">
<a href="#home">
<span class="logo-text">LaForceIT</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">LaForceIT</span><span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu">
@ -645,7 +643,7 @@
<div class="footer-logo">
<span class="logo-text">LaForceIT</span>
<span class="logo-dot">.com</span>
</div>
</div>
<div class="footer-links">
<a href="#home">Home</a>

View File

@ -294,8 +294,8 @@
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">LaForceIT</span>
<span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu">
@ -805,8 +805,8 @@
<div class="container">
<div class="footer-content">
<div class="footer-logo">
<span class="logo-text">Argobox</span>
<span class="logo-dot">.com</span>
<span class="logo-text-glow">LaForceIT</span>
<span class="logo-dot-glow">.com</span>
</div>
<div class="footer-links">

View File

@ -394,32 +394,49 @@ function updateMetrics() {
setInterval(updateMetricValues, 5000);
}
/**
* Initialize contact form handling
*/
/**
* Initialize contact form handling
*/
function initFormHandling(form) {
form.addEventListener('submit', async function(e) {
form.addEventListener('submit', async function (e) {
e.preventDefault();
const submitButton = form.querySelector('button[type="submit"]');
const originalButtonText = submitButton.innerHTML;
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
submitButton.disabled = true;
const formData = {
name: form.elements['name'].value,
email: form.elements['email'].value,
subject: form.elements['subject'].value,
message: form.elements['message'].value
};
try {
// Simulated form submission - in production replace with actual API call
// const formData = new FormData(form);
// const formValues = Object.fromEntries(formData.entries());
// Simulated API response delay
await new Promise(resolve => setTimeout(resolve, 1500));
// Success message
alert('Thank you for your message! I will get back to you soon.');
form.reset();
const res = await fetch("/api/send-email", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(formData)
});
const data = await res.json();
if (data.success) {
alert("Thank you for your message! I will get back to you soon.");
form.reset();
} else {
alert("Failed to send message. Please try again or contact me directly.");
}
} catch (error) {
console.error('Error:', error);
alert('Failed to send message. Please try again or contact me directly via email.');
console.error("Error:", error);
alert("Something went wrong while sending your message.");
} finally {
submitButton.innerHTML = originalButtonText;
submitButton.disabled = false;

View File

@ -215,7 +215,8 @@ section {
font-size: 1.5rem;
color: transparent;
background: linear-gradient(135deg, #3b82f6, #2563eb);
-webkit-background-clip: text;
-webkit-background-clip: text;
background-clip: text;
background-clip: text;
text-shadow: 0 0 8px rgba(59, 130, 246, 0.5);
}
@ -1505,4 +1506,36 @@ section {
break-inside: avoid;
page-break-inside: avoid;
}
}
}
/* ============================
LaForceIT.com Logo Styling
============================ */
.logo-text-glow {
font-weight: 800;
font-size: 1.6rem;
background: linear-gradient(90deg, var(--accent), var(--accent-darker));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 6px rgba(59, 130, 246, 0.5);
transition: all 0.3s ease-in-out;
}
.logo-dot-glow {
color: white;
font-weight: 600;
font-size: 1.6rem;
margin-left: 2px;
text-shadow: 0 0 3px rgba(255, 255, 255, 0.3);
transition: all 0.3s ease-in-out;
}
.logo-text-glow:hover,
.logo-dot-glow:hover {
text-shadow: 0 0 10px rgba(59, 130, 246, 0.8), 0 0 8px rgba(255, 255, 255, 0.3);
transform: scale(1.02);
}

View File

@ -1,57 +0,0 @@
/* Test CSS file to confirm changes are working */
/* Save this as test-styles.css in your repository root */
/* Logo Styles - Enhanced Version */
.logo {
position: relative;
display: flex;
align-items: center;
}
.logo a {
display: flex;
align-items: center;
text-decoration: none;
position: relative;
}
.logo-text {
font-family: 'Inter', sans-serif;
font-weight: 700;
font-size: 1.5rem;
background: linear-gradient(90deg, #ff0000 0%, #ff6e00 50%, #ffa500 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
position: relative;
text-shadow: 0 0 15px rgba(255, 150, 100, 0.2);
letter-spacing: 0.5px;
}
.logo-dot {
font-family: 'Inter', sans-serif;
font-weight: 700;
font-size: 1.5rem;
color: #ff6e00;
position: relative;
}
/* Logo with tech icon detail - using different brackets to be obviously visible */
.logo a::before {
content: "[ ";
font-family: 'JetBrains Mono', monospace;
color: #ff6e00;
font-weight: bold;
opacity: 0.8;
margin-right: 2px;
}
.logo a::after {
content: " ]";
font-family: 'JetBrains Mono', monospace;
color: #ff6e00;
font-weight: bold;
opacity: 0.8;
margin-left: 2px;
}