Files
hydro-site-final/layouts/testimonials/single.html
Dr. Jones d9961a76ad Initial commit: site code, layouts, content (images added separately)
Fixes duplicate placeholder cover image on the 3 newest blog posts,
broken aspect-ratio classes on the albums listing page, and a
non-responsive fixed sidebar on the chat page.
2026-07-08 06:18:17 +00:00

160 lines
7.5 KiB
HTML

{{ define "main" }}
<div class="bg-gray-900 min-h-screen py-16 px-4 sm:px-6 lg:px-8" x-data="testimonialsPage()" x-init="initTestimonials()">
<div class="max-w-4xl mx-auto">
<div class="text-center mb-12">
<h1 class="text-4xl font-extrabold text-gray-100 tracking-tight sm:text-5xl mb-4">Member Testimonials</h1>
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
Real stories from growers who have transformed their gardens using the sterile hydroponic method.
</p>
</div>
<!-- Paywall Message -->
<div class="paywall-message bg-gray-800 rounded-lg p-8 border border-gray-700 text-center mb-8" style="display: none;">
<h2 class="text-2xl font-bold text-gray-100 mb-4">Members Only Content</h2>
<p class="text-gray-300 mb-6">
Testimonials are available exclusively to members. Sign up to read success stories and share your own experience.
</p>
<a href="/membership/" class="inline-flex items-center px-6 py-3 bg-primary hover:bg-emerald-700 text-white font-semibold rounded-lg transition-colors">
Become a Member
</a>
</div>
<!-- Testimonials Content -->
<div class="paywall-content">
<!-- Submit Testimonial Form (Members Only) -->
<div class="membership-only bg-gray-800 rounded-lg p-8 mb-8 border border-gray-700" style="display: none;">
<h2 class="text-2xl font-bold text-gray-100 mb-6">Share Your Story</h2>
<form @submit.prevent="submitTestimonial()" class="space-y-6">
<div>
<label for="author-name" class="block text-sm font-medium text-gray-300 mb-2">Your Name</label>
<input type="text" id="author-name" x-model="authorName" required
class="w-full px-4 py-3 bg-gray-900 border border-gray-700 rounded-lg text-gray-100 focus:ring-2 focus:ring-primary focus:border-transparent">
</div>
<div>
<label for="testimonial-content" class="block text-sm font-medium text-gray-300 mb-2">Your Testimonial</label>
<textarea id="testimonial-content" x-model="testimonialContent" required rows="6"
class="w-full px-4 py-3 bg-gray-900 border border-gray-700 rounded-lg text-gray-100 focus:ring-2 focus:ring-primary focus:border-transparent"></textarea>
</div>
<div x-show="submitError" class="bg-red-900/50 border border-red-700 rounded-lg p-4 text-red-200">
<p x-text="submitError"></p>
</div>
<div x-show="submitSuccess" class="bg-green-900/50 border border-green-700 rounded-lg p-4 text-green-200">
<p x-text="submitSuccess"></p>
</div>
<button type="submit"
:disabled="submitLoading"
class="px-6 py-3 bg-primary hover:bg-emerald-700 text-white font-semibold rounded-lg transition-colors disabled:opacity-50">
<span x-show="!submitLoading">Submit Testimonial</span>
<span x-show="submitLoading">Submitting...</span>
</button>
</form>
</div>
<!-- Testimonials List -->
<div class="space-y-6">
<div x-show="loading" class="text-center text-gray-400 py-12">
Loading testimonials...
</div>
<div x-show="error" class="bg-red-900/50 border border-red-700 rounded-lg p-4 text-red-200">
<p x-text="error"></p>
</div>
<template x-for="testimonial in testimonials" :key="testimonial.id">
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
<div class="flex items-start justify-between mb-4">
<div>
<h3 class="text-lg font-semibold text-gray-100" x-text="testimonial.author_name"></h3>
<p class="text-sm text-gray-400" x-text="new Date(testimonial.created_at).toLocaleDateString()"></p>
</div>
</div>
<p class="text-gray-300 leading-relaxed" x-text="testimonial.content"></p>
</div>
</template>
<div x-show="!loading && !error && testimonials.length === 0" class="text-center text-gray-400 py-12">
<p>No testimonials yet. Be the first to share your success story!</p>
</div>
</div>
</div>
</div>
</div>
<script>
function testimonialsPage() {
return {
testimonials: [],
loading: true,
error: '',
authorName: '',
testimonialContent: '',
submitError: '',
submitSuccess: '',
submitLoading: false,
initTestimonials() {
// Check auth and show/hide paywall
const authState = window.MembershipAPI.getAuthState();
const paywallMessage = document.querySelector('.paywall-message');
const paywallContent = document.querySelector('.paywall-content');
const membershipOnly = document.querySelectorAll('.membership-only');
if (!authState.authenticated) {
if (paywallMessage) paywallMessage.style.display = 'block';
if (paywallContent) paywallContent.style.display = 'none';
membershipOnly.forEach(el => el.style.display = 'none');
this.loading = false;
} else {
if (paywallMessage) paywallMessage.style.display = 'none';
if (paywallContent) paywallContent.style.display = 'block';
membershipOnly.forEach(el => el.style.display = 'block');
this.loadTestimonials();
}
},
async loadTestimonials() {
this.loading = true;
this.error = '';
const authState = window.MembershipAPI.getAuthState();
if (!authState.authenticated) {
this.loading = false;
return;
}
const result = await window.MembershipAPI.loadTestimonials();
this.loading = false;
if (result.success) {
this.testimonials = result.testimonials || [];
} else {
this.error = result.error || 'Failed to load testimonials';
}
},
async submitTestimonial() {
if (!this.authorName || !this.testimonialContent) {
this.submitError = 'Please fill in all fields';
return;
}
this.submitError = '';
this.submitSuccess = '';
this.submitLoading = true;
const result = await window.MembershipAPI.submitTestimonial(this.testimonialContent, this.authorName);
this.submitLoading = false;
if (result.success) {
this.submitSuccess = result.message || 'Testimonial submitted successfully!';
this.authorName = '';
this.testimonialContent = '';
// Reload testimonials after a delay
setTimeout(() => this.loadTestimonials(), 2000);
} else {
this.submitError = result.error || 'Failed to submit testimonial';
}
}
}
}
</script>
{{ end }}