feat(signup): community guidelines agreement and policies routes

Introduces /community-guidelines and /policies/{privacy,terms,[slug]} pages,
swaps the signup/invite checkbox from agreedToTerms to agreedToGuidelines,
adds Member.agreement.acceptedAt, and stamps the field when a Helcim
customer is created.
This commit is contained in:
Jennie Robinson Faber 2026-04-18 17:06:10 +01:00
parent e0d11e47f4
commit c5e901ed24
13 changed files with 1292 additions and 54 deletions

View file

@ -65,7 +65,7 @@
<ul>
<li>Full access to the knowledge commons, Slack, and peer support</li>
<li>Free access to all Ghost Guild events</li>
<li>One member, one vote</li>
<li>Equal access for every member, regardless of contribution</li>
<li>Your circle reflects where you are, not rank</li>
<li>Pay what you can ($0&ndash;$50+/month, separate from circle)</li>
<li>Higher contributions create solidarity spots for others</li>
@ -251,6 +251,20 @@
}"
/>
</div>
<div class="form-group full-width">
<label class="checkbox-label">
<input
v-model="form.agreedToGuidelines"
type="checkbox"
>
<span>
I agree to the Ghost Guild
<NuxtLink to="/community-guidelines" target="_blank"
>Community Guidelines</NuxtLink
>.
</span>
</label>
</div>
<div class="form-group">
<button
class="form-submit"
@ -264,9 +278,7 @@
</div>
</div>
<p class="form-note">
By joining you agree to our
<NuxtLink to="/guidelines">community guidelines</NuxtLink>. You
can change your circle or contribution at any time from your
You can change your circle or contribution at any time from your
dashboard. Payment is handled securely through
<a href="https://www.helcim.com" target="_blank" rel="noopener"
>Helcim</a
@ -397,6 +409,7 @@ const form = reactive({
name: "",
circle: "community",
contributionTier: "15",
agreedToGuidelines: false,
billingAddress: {
street: "",
city: "",
@ -442,7 +455,13 @@ const {
// Form validation
const isFormValid = computed(() => {
return form.name && form.email && form.circle && form.contributionTier;
return (
form.name &&
form.email &&
form.circle &&
form.contributionTier &&
form.agreedToGuidelines
);
});
// Check if payment is required
@ -471,6 +490,7 @@ const handleSubmit = async () => {
email: form.email,
circle: form.circle,
contributionTier: form.contributionTier,
agreedToGuidelines: form.agreedToGuidelines,
billingAddress: form.billingAddress,
},
});
@ -961,6 +981,25 @@ onUnmounted(() => {
color: var(--candle-dim);
}
/* ---- CHECKBOX ---- */
.checkbox-label {
display: flex;
align-items: flex-start;
gap: 8px;
cursor: pointer;
font-size: 12px;
color: var(--text-dim);
line-height: 1.5;
}
.checkbox-label input {
margin-top: 3px;
flex-shrink: 0;
}
.checkbox-label a,
.checkbox-label :deep(a) {
color: var(--candle);
}
/* ---- ERROR & SUCCESS BOXES ---- */
.error-box {
border: 1px dashed var(--ember);