Add content pages (contact, events, happy tails, sponsors, donate)
All pages use config-driven org info via data.orgConfig — no hardcoded org names, emails, or external URLs. Stripe donate page gracefully falls back to a contact CTA when STRIPE_SECRET_KEY is not configured. RateLimiter applied to contact form and happy tails submission. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
|
||||
let { data, form } = $props();
|
||||
|
||||
const orgName = $derived(data.orgConfig.orgInfo.name);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Share Your Happy Tail | {orgName}</title>
|
||||
<meta name="description" content="Adopted from {orgName}? Share your happy tail story with us!" />
|
||||
</svelte:head>
|
||||
|
||||
<section class="bg-teal-brand py-16 text-center text-white">
|
||||
<div class="mx-auto max-w-4xl px-4">
|
||||
<h1 class="text-4xl font-bold sm:text-5xl">Share Your Happy Tail</h1>
|
||||
<p class="mt-4 text-lg text-teal-light/90">
|
||||
Adopted from {orgName}? We'd love to hear how your new family member is doing!
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="bg-warm-bg py-16">
|
||||
<div class="mx-auto max-w-2xl px-4">
|
||||
{#if form?.success}
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-soft p-8 text-center">
|
||||
<div class="w-16 h-16 mx-auto mb-4 bg-green-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-gray-brand">Thank You!</h2>
|
||||
<p class="mt-2 text-gray-mid">Your story has been submitted and will be reviewed by our team. Once approved, it'll appear on our Happy Tails page!</p>
|
||||
<a href="/happy-tails" class="mt-6 inline-block text-teal-brand font-semibold hover:text-teal-dark">
|
||||
← Back to Happy Tails
|
||||
</a>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="bg-white rounded-2xl shadow-sm border border-gray-soft p-6 sm:p-8">
|
||||
{#if form?.error}
|
||||
<div class="mb-6 p-4 bg-red-50 border border-red-200 rounded-xl text-sm text-red-700">{form.error}</div>
|
||||
{/if}
|
||||
|
||||
<form method="POST" use:enhance class="space-y-6">
|
||||
<div>
|
||||
<label for="adopterName" class="block text-sm font-medium text-gray-700 mb-1">Your Name <span class="text-red-500">*</span></label>
|
||||
<input
|
||||
type="text"
|
||||
id="adopterName"
|
||||
name="adopterName"
|
||||
required
|
||||
value={form?.adopterName ?? ''}
|
||||
placeholder="Your name or family name"
|
||||
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:ring-2 focus:ring-teal-brand/20 focus:border-teal-brand outline-none text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email <span class="text-gray-400 font-normal">(optional)</span></label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="your@email.com"
|
||||
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:ring-2 focus:ring-teal-brand/20 focus:border-teal-brand outline-none text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="title" class="block text-sm font-medium text-gray-700 mb-1">Story Title <span class="text-red-500">*</span></label>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
required
|
||||
value={form?.title ?? ''}
|
||||
placeholder="Our life with Buddy"
|
||||
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:ring-2 focus:ring-teal-brand/20 focus:border-teal-brand outline-none text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="story" class="block text-sm font-medium text-gray-700 mb-1">Your Story <span class="text-red-500">*</span></label>
|
||||
<textarea
|
||||
id="story"
|
||||
name="story"
|
||||
required
|
||||
rows="8"
|
||||
placeholder="Tell us about your experience adopting and how your pet is doing..."
|
||||
class="w-full px-4 py-2.5 rounded-lg border border-gray-300 focus:ring-2 focus:ring-teal-brand/20 focus:border-teal-brand outline-none text-sm resize-y"
|
||||
>{form?.story ?? ''}</textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full py-3 rounded-lg bg-teal-brand text-white font-semibold hover:bg-teal-dark transition cursor-pointer">
|
||||
Submit Your Story
|
||||
</button>
|
||||
|
||||
<p class="text-xs text-gray-400 text-center">
|
||||
Your story will be reviewed by our team before being published.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user