99 lines
4.5 KiB
Text
99 lines
4.5 KiB
Text
|
|
---
|
||
|
|
import BaseLayout from "../layouts/BaseLayout.astro";
|
||
|
|
import Breadcrumbs from "../components/Breadcrumbs.astro";
|
||
|
|
import Icon from "../components/Icon.astro";
|
||
|
|
import { SITE } from "../lib/blog-data.js";
|
||
|
|
---
|
||
|
|
|
||
|
|
<BaseLayout
|
||
|
|
title={`Contact - ${SITE.name}`}
|
||
|
|
description={`Get in touch with ${SITE.name}.`}
|
||
|
|
canonical="/contact"
|
||
|
|
>
|
||
|
|
<div class="mx-auto max-w-3xl px-5 py-12">
|
||
|
|
<Breadcrumbs items={[{ label: "Home", to: "/" }, { label: "Contact" }]} />
|
||
|
|
|
||
|
|
<header class="mt-6">
|
||
|
|
<div class="text-xs font-medium uppercase tracking-[0.2em] text-primary">Contact</div>
|
||
|
|
<h1 class="mt-2 font-serif text-5xl font-semibold tracking-tight">Say hello.</h1>
|
||
|
|
<p class="mt-4 max-w-xl text-muted-foreground">
|
||
|
|
A restaurant tip, a correction, or a question about where to eat in Medellín. We read everything and reply to most of it.
|
||
|
|
</p>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<div class="mt-12 grid gap-12 lg:grid-cols-[1fr_240px]">
|
||
|
|
<form data-contact-form class="space-y-5">
|
||
|
|
<div>
|
||
|
|
<label for="name" class="text-xs font-medium uppercase tracking-wider text-muted-foreground">Name</label>
|
||
|
|
<input id="name" required class="mt-2 w-full border-0 border-b border-input bg-transparent py-2 text-base outline-none focus:border-primary" />
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<label for="email" class="text-xs font-medium uppercase tracking-wider text-muted-foreground">Email</label>
|
||
|
|
<input id="email" type="email" required class="mt-2 w-full border-0 border-b border-input bg-transparent py-2 text-base outline-none focus:border-primary" />
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<label for="message" class="text-xs font-medium uppercase tracking-wider text-muted-foreground">Message</label>
|
||
|
|
<textarea id="message" required rows="6" class="mt-2 w-full border-0 border-b border-input bg-transparent py-2 text-base outline-none focus:border-primary"></textarea>
|
||
|
|
</div>
|
||
|
|
<div aria-hidden="true" style="position:absolute;left:-9999px;height:0;overflow:hidden">
|
||
|
|
<label>Website<input id="website" name="website" tabindex="-1" autocomplete="off" /></label>
|
||
|
|
</div>
|
||
|
|
<button type="submit" class="rounded-md bg-foreground px-6 py-2.5 text-sm font-medium text-background hover:opacity-90">
|
||
|
|
Send
|
||
|
|
</button>
|
||
|
|
<p data-contact-sent class="text-sm text-primary" role="status" hidden>Thanks — we'll be in touch.</p>
|
||
|
|
</form>
|
||
|
|
|
||
|
|
<aside class="space-y-6 border-l border-border pl-8 lg:block">
|
||
|
|
<div>
|
||
|
|
<div class="text-xs font-medium uppercase tracking-wider text-muted-foreground">Elsewhere</div>
|
||
|
|
<ul class="mt-3 space-y-3 text-sm">
|
||
|
|
<li><a href="https://x.com/hicarlosarias" class="flex items-center gap-2 hover:text-primary"><Icon name="twitter" class="h-3.5 w-3.5" /> @hicarlosarias</a></li>
|
||
|
|
<li><a href="/rss.xml" class="flex items-center gap-2 hover:text-primary"><Icon name="rss" class="h-3.5 w-3.5" /> RSS feed</a></li>
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<div class="text-xs font-medium uppercase tracking-wider text-muted-foreground">Restaurant tips</div>
|
||
|
|
<p class="mt-2 text-sm text-muted-foreground">Know a new opening or an underrated spot? Send it our way — we factor reader tips into our guides and news roundups.</p>
|
||
|
|
</div>
|
||
|
|
</aside>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</BaseLayout>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
const contactForm = document.querySelector("[data-contact-form]");
|
||
|
|
const sent = document.querySelector("[data-contact-sent]");
|
||
|
|
contactForm?.addEventListener("submit", async (event) => {
|
||
|
|
event.preventDefault();
|
||
|
|
const btn = contactForm.querySelector("button[type=submit]");
|
||
|
|
const payload = {
|
||
|
|
name: document.getElementById("name").value.trim(),
|
||
|
|
email: document.getElementById("email").value.trim(),
|
||
|
|
message: document.getElementById("message").value.trim(),
|
||
|
|
website: document.getElementById("website")?.value || "",
|
||
|
|
};
|
||
|
|
if (btn) {
|
||
|
|
btn.disabled = true;
|
||
|
|
btn.textContent = "Sending…";
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
const r = await fetch("/contact-submit", {
|
||
|
|
method: "POST",
|
||
|
|
headers: { "Content-Type": "application/json" },
|
||
|
|
body: JSON.stringify(payload),
|
||
|
|
});
|
||
|
|
if (!r.ok) throw new Error((await r.json()).error || "Something went wrong. Please try again.");
|
||
|
|
contactForm.reset();
|
||
|
|
if (sent) sent.hidden = false;
|
||
|
|
} catch (err) {
|
||
|
|
alert(err.message);
|
||
|
|
} finally {
|
||
|
|
if (btn) {
|
||
|
|
btn.disabled = false;
|
||
|
|
btn.textContent = "Send";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|