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 --> <!-- CSS -->
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="test-styles.css">
<!-- Font Awesome --> <!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> <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="container">
<div class="logo"> <div class="logo">
<a href="#home"> <a href="#home">
<span class="logo-text">LaForceIT</span> <span class="logo-text-glow">LaForceIT</span><span class="logo-dot-glow">.com</span>
<span class="logo-dot">.com</span>
</a> </a>
</div> </div>
<div class="nav-menu"> <div class="nav-menu">

View File

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

View File

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

View File

@ -216,6 +216,7 @@ section {
color: transparent; color: transparent;
background: linear-gradient(135deg, #3b82f6, #2563eb); background: linear-gradient(135deg, #3b82f6, #2563eb);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text;
background-clip: text; background-clip: text;
text-shadow: 0 0 8px rgba(59, 130, 246, 0.5); text-shadow: 0 0 8px rgba(59, 130, 246, 0.5);
} }
@ -1506,3 +1507,35 @@ section {
page-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;
}