Add newsletter signup, update contact→fatkiss@, Turnstile, Listmonk integration

This commit is contained in:
2026-05-11 09:39:18 -10:00
parent 2dbe602e8a
commit 20a6656ebc
10 changed files with 99 additions and 2 deletions
+46
View File
@@ -0,0 +1,46 @@
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('newsletterForm');
if (!form) return;
form.addEventListener('submit', async (e) => {
e.preventDefault();
const btn = document.getElementById('nlSubmitBtn');
const msg = document.getElementById('nlMessage');
btn.disabled = true;
btn.textContent = 'Subscribing…';
try {
const fd = new FormData(form);
if (fd.get('website')) { btn.disabled = false; btn.textContent = 'Subscribe'; return; }
const res = await fetch('https://newsletter.getfatkiss.com/api/subscribers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('fatkiss:fk-api-token-2026-safe')
},
body: JSON.stringify({
email: fd.get('email'),
name: fd.get('name') || '',
status: 'enabled',
lists: [17],
preconfirm_subscriptions: true
})
});
const data = await res.json();
if (res.ok && data.data) {
msg.innerHTML = '<div class="form-message form-message--success">You are in. Welcome to the Kiss.</div>';
form.reset();
if (typeof turnstile !== 'undefined') turnstile.reset();
} else {
msg.innerHTML = '<div class="form-message form-message--error">Something did not go through. Please try again.</div>';
}
} catch (err) {
msg.innerHTML = '<div class="form-message form-message--error">Something did not go through. Please try again.</div>';
}
btn.disabled = false;
btn.textContent = 'Subscribe';
});
});
+1 -1
View File
@@ -1,5 +1,5 @@
public_aliases: public_aliases:
general: hello@getfatkiss.com general: fatkiss@getfatkiss.com
orders: orders@getfatkiss.com orders: orders@getfatkiss.com
press: press@getfatkiss.com press: press@getfatkiss.com
+5
View File
@@ -51,3 +51,8 @@ waitlist:
body: "" body: ""
cta_label: "" cta_label: ""
cta_url: "" cta_url: ""
newsletter:
enabled: true
title: "Stay in the Kiss"
body: "Notes from the studio. New balms. Seasonal rituals. No spam — just Amber when there is something worth saying."
+1
View File
@@ -17,3 +17,4 @@ enable_contact_form: true
noindex_admin: true noindex_admin: true
analytics_provider: "" analytics_provider: ""
analytics_id: "" analytics_id: ""
enable_newsletter: true
+1 -1
View File
@@ -9,7 +9,7 @@ title = "Fat Kiss — Natural Ritual Skincare"
[params] [params]
description = "Fat Kiss — rich, natural balm rituals for skin that lives, works, glows, and keeps going. Everybody Wants One." description = "Fat Kiss — rich, natural balm rituals for skin that lives, works, glows, and keeps going. Everybody Wants One."
author = "Fat Kiss" author = "Fat Kiss"
email = "hello@getfatkiss.com" email = "fatkiss@getfatkiss.com"
slogan = "Everybody Wants One." slogan = "Everybody Wants One."
ogImage = "/uploads/og-fatkiss.jpg" ogImage = "/uploads/og-fatkiss.jpg"
favicon = "/favicon.svg" favicon = "/favicon.svg"
+3
View File
@@ -13,5 +13,8 @@
{{ partial "footer.html" . }} {{ partial "footer.html" . }}
{{ $js := resources.Get "js/main.js" | minify | fingerprint }} {{ $js := resources.Get "js/main.js" | minify | fingerprint }}
<script src="{{ $js.RelPermalink }}" defer></script> <script src="{{ $js.RelPermalink }}" defer></script>
{{ $nl := resources.Get "js/newsletter.js" | minify | fingerprint }}
<script src="{{ $nl.RelPermalink }}" defer></script>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</body> </body>
</html> </html>
+5
View File
@@ -15,4 +15,9 @@
</div> </div>
</section> </section>
</article> </article>
<section class="section">
<div class="container container--narrow">
{{ partial "newsletter-signup.html" . }}
</div>
</section>
{{ end }} {{ end }}
+7
View File
@@ -114,6 +114,13 @@
</section> </section>
{{ end }} {{ end }}
{{ if and $home.newsletter.enabled (ne .Site.Data.site.settings.enable_newsletter false) }}
<section class="section">
<div class="container container--narrow">
{{ partial "newsletter-signup.html" . }}
</div>
</section>
{{ end }}
{{ if $home.waitlist.enabled }} {{ if $home.waitlist.enabled }}
<section class="section"> <section class="section">
<div class="container container--narrow"> <div class="container container--narrow">
+19
View File
@@ -0,0 +1,19 @@
<div class="newsletter-signup" id="newsletter">
<div class="newsletter-signup__inner">
<h3 class="newsletter-signup__title">Stay in the Kiss</h3>
<p class="newsletter-signup__body">Notes from the studio. New balms. Seasonal rituals. Amber sends them when there's something worth saying — not every Tuesday at 10am.</p>
<form class="newsletter-form" id="newsletterForm">
<div class="form-honeypot" aria-hidden="true">
<label for="nl_website">Leave empty</label>
<input type="text" id="nl_website" name="website" tabindex="-1" autocomplete="off">
</div>
<div class="newsletter-form__fields">
<input type="email" name="email" class="form-input" placeholder="Your email address" required autocomplete="email" maxlength="200">
<input type="text" name="name" class="form-input" placeholder="First name (optional)" maxlength="100" autocomplete="given-name">
<button type="submit" class="btn btn--primary" id="nlSubmitBtn">Subscribe</button>
</div>
<div class="cf-turnstile" data-sitekey="0x4AAAAAADNXU5KZ9DfJl2VL" style="margin-top:var(--fk-space-md)"></div>
<div id="nlMessage"></div>
</form>
</div>
</div>
+11
View File
@@ -162,3 +162,14 @@ collections:
- {label: "Rating", name: "rating", widget: "number", min: 1, max: 5, required: false} - {label: "Rating", name: "rating", widget: "number", min: 1, max: 5, required: false}
- {label: "Date", name: "date", widget: "date", required: false} - {label: "Date", name: "date", widget: "date", required: false}
- {label: "Featured", name: "featured", widget: "boolean", default: false} - {label: "Featured", name: "featured", widget: "boolean", default: false}
- name: "newsletter"
label: "Newsletter"
files:
- name: "newsletter_settings"
label: "Newsletter Settings"
file: "data/site/settings.yaml"
fields:
- {label: "Enable Newsletter", name: "enable_newsletter", widget: "boolean", default: true}
- {label: "Listmonk List ID", name: "listmonk_list_id", widget: "number", default: 17, required: false}
- {label: "Listmonk API Token", name: "listmonk_api_token", widget: "string", required: false}