/* global React */
const { useState, useEffect, useRef, useMemo } = React;
/* ============================================================
Logo, uses brand PNG with full "People Cake" wordmark
============================================================ */
function Logo({ height = 40, src = "assets/logo.png" }) {
return (
);
}
/* ============================================================
Icons
============================================================ */
const IconArrow = ({ size = 16 }) =>
;
const IconCheck = ({ size = 16 }) =>
;
const IconLinkedIn = ({ size = 16 }) =>
;
const IconEmail = ({ size = 16 }) =>
;
/* Big background gear ornament */
function BgGear({ style = {}, size = 600, opacity = 0.04 }) {
return (
);
}
/* ============================================================
Nav
============================================================ */
function Nav({ route, navigate, onCTA }) {
const [scrolled, setScrolled] = useState(false);
const [drawerOpen, setDrawerOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
onScroll();
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);
// Nav is always dark/black across all pages and scroll states.
const navClass = "nav nav--dark-solid";
const links = [
{ id: "home", label: "Home" },
{ id: "about", label: "About" },
{ id: "consultancy", label: "HR Consultancy" },
{ id: "coaching", label: "Career Coaching" },
{ id: "partners", label: "Partners" }];
const go = (id) => {navigate(id);setDrawerOpen(false);};
return (
);
}
/* ============================================================
Footer
============================================================ */
function Footer({ navigate, onCTA }) {
return (
);
}
/* ============================================================
Testimonial
============================================================ */
function Testimonial({ quote, name, role }) {
return (
“
{quote}
”
{name ?
{name}{role && · {role}}
:
{role}}
);
}
/* ============================================================
Contact modal
============================================================ */
function ContactModal({ open, onClose, accent = "purple" }) {
const [submitted, setSubmitted] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState("");
const [form, setForm] = useState({ name: "", email: "", company: "", interest: "consultancy", message: "" });
useEffect(() => {
if (open) {
setSubmitted(false);
setSubmitting(false);
setError("");
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "";
}
return () => { document.body.style.overflow = ""; };
}, [open]);
const interestLabel = {
consultancy: "HR Consultancy, for my business",
coaching: "Career Coaching, for me",
diagnostic: "Team Diagnostic tool",
partner: "Partnership opportunity"
};
const handleSubmit = async (e) => {
e.preventDefault();
setSubmitting(true);
setError("");
try {
const payload = {
access_key: "185359e5-9b58-4947-b399-87d2906c57b6",
subject: `New People Cake enquiry from ${form.name} (${interestLabel[form.interest] || form.interest})`,
from_name: "People Cake website",
name: form.name,
email: form.email,
company: form.company,
interest: interestLabel[form.interest] || form.interest,
message: form.message,
replyto: form.email,
botcheck: ""
};
const res = await fetch("https://api.web3forms.com/submit", {
method: "POST",
headers: { "Content-Type": "application/json", "Accept": "application/json" },
body: JSON.stringify(payload)
});
const data = await res.json();
if (data.success) {
setSubmitted(true);
} else {
setError(data.message || "Something went wrong. Please email sarah@peoplecake.com directly.");
}
} catch (err) {
setError("Couldn't reach the server. Please email sarah@peoplecake.com directly.");
} finally {
setSubmitting(false);
}
};
return (
e.stopPropagation()}>
{!submitted ?
Let's talk
Start a conversation.
A short message, a quick reply. No lengthy proposals, no sales calls, just a conversation to see if there's a fit.
:
Message received.
Thanks {form.name || "for getting in touch"}, I'll be in touch shortly.
}
);
}
/* ============================================================
Cred bar
============================================================ */
function CredBar({ items }) {
return (
{items.map((item, i) =>
{item}
)}
);
}
/* ============================================================
Export
============================================================ */
Object.assign(window, {
Logo, BgGear,
IconArrow, IconCheck, IconLinkedIn, IconEmail,
Nav, Footer, Testimonial, ContactModal, CredBar
});