feat: change Jerry's Story page background to white

Update background to white and adjust text and border colors for readability.

Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com>
This commit is contained in:
v0 2025-09-03 08:38:01 +00:00
parent 8d2ccf7330
commit 001f65d5e2
3 changed files with 153 additions and 35 deletions

View File

@ -0,0 +1,41 @@
import { type NextRequest, NextResponse } from "next/server"
export async function POST(request: NextRequest) {
try {
const { name, email, subject, message } = await request.json()
// Validate required fields
if (!name || !email || !subject || !message) {
return NextResponse.json({ error: "All fields are required" }, { status: 400 })
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(email)) {
return NextResponse.json({ error: "Invalid email format" }, { status: 400 })
}
console.log("[v0] Email submission received:", {
name,
email,
subject,
message: message.substring(0, 100) + "...",
})
// For now, we'll log the email details
// In a production environment, you would integrate with an email service like:
// - Resend
// - SendGrid
// - Nodemailer with SMTP
console.log("[v0] Email would be sent to: alertbaytrumpeter@icloud.com")
console.log("[v0] From:", name, "<" + email + ">")
console.log("[v0] Subject:", subject)
console.log("[v0] Message:", message)
// Simulate email sending success
return NextResponse.json({ message: "Email sent successfully" }, { status: 200 })
} catch (error) {
console.error("[v0] Error processing email:", error)
return NextResponse.json({ error: "Failed to send email" }, { status: 500 })
}
}

View File

@ -1,5 +1,7 @@
"use client" "use client"
import type React from "react"
import Image from "next/image" import Image from "next/image"
import Link from "next/link" import Link from "next/link"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
@ -10,6 +12,13 @@ import { useState } from "react"
export default function ContactPage() { export default function ContactPage() {
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const [formData, setFormData] = useState({
name: "",
email: "",
subject: "",
message: "",
})
const [isSubmitting, setIsSubmitting] = useState(false)
const handleMonthlySponsorship = async () => { const handleMonthlySponsorship = async () => {
setIsLoading(true) setIsLoading(true)
@ -44,6 +53,42 @@ export default function ContactPage() {
} }
} }
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setIsSubmitting(true)
try {
console.log("[v0] Submitting contact form:", formData)
const response = await fetch("/api/send-email", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.error || "Failed to send message")
}
// Reset form on success
setFormData({ name: "", email: "", subject: "", message: "" })
alert("Message sent successfully! Jerry will get back to you soon.")
} catch (error) {
console.error("Error sending message:", error)
alert("There was an error sending your message. Please try again.")
} finally {
setIsSubmitting(false)
}
}
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { id, value } = e.target
setFormData((prev) => ({ ...prev, [id]: value }))
}
return ( return (
<div className="min-h-screen bg-gray-50"> <div className="min-h-screen bg-gray-50">
{/* Header */} {/* Header */}
@ -90,38 +135,70 @@ export default function ContactPage() {
<CardHeader> <CardHeader>
<CardTitle className="text-2xl text-slate-700">Send Jerry a Message</CardTitle> <CardTitle className="text-2xl text-slate-700">Send Jerry a Message</CardTitle>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent>
<div> <form onSubmit={handleSubmit} className="space-y-4">
<label htmlFor="name" className="block text-sm font-medium text-slate-700 mb-1"> <div>
Name <label htmlFor="name" className="block text-sm font-medium text-slate-700 mb-1">
</label> Name
<Input id="name" placeholder="Your name" /> </label>
</div> <Input
id="name"
placeholder="Your name"
value={formData.name}
onChange={handleInputChange}
required
/>
</div>
<div> <div>
<label htmlFor="email" className="block text-sm font-medium text-slate-700 mb-1"> <label htmlFor="email" className="block text-sm font-medium text-slate-700 mb-1">
Email Email
</label> </label>
<Input id="email" type="email" placeholder="your.email@example.com" /> <Input
</div> id="email"
type="email"
placeholder="your.email@example.com"
value={formData.email}
onChange={handleInputChange}
required
/>
</div>
<div> <div>
<label htmlFor="subject" className="block text-sm font-medium text-slate-700 mb-1"> <label htmlFor="subject" className="block text-sm font-medium text-slate-700 mb-1">
Subject Subject
</label> </label>
<Input id="subject" placeholder="Message subject" /> <Input
</div> id="subject"
placeholder="Message subject"
value={formData.subject}
onChange={handleInputChange}
required
/>
</div>
<div> <div>
<label htmlFor="message" className="block text-sm font-medium text-slate-700 mb-1"> <label htmlFor="message" className="block text-sm font-medium text-slate-700 mb-1">
Message Message
</label> </label>
<Textarea id="message" placeholder="Your message to Jerry..." rows={6} /> <Textarea
</div> id="message"
placeholder="Your message to Jerry..."
rows={6}
value={formData.message}
onChange={handleInputChange}
required
/>
</div>
<Button className="w-full bg-blue-800 hover:bg-blue-600 shadow-lg hover:shadow-xl transition-all duration-300"> <Button
Send Message type="submit"
</Button> disabled={isSubmitting}
className="w-full bg-blue-800 hover:bg-blue-600 shadow-lg hover:shadow-xl transition-all duration-300 disabled:opacity-50"
>
{isSubmitting ? "Sending..." : "Send Message"}
</Button>
</form>
</CardContent> </CardContent>
</Card> </Card>

View File

@ -37,9 +37,9 @@ export default function JerryStoryPage() {
</header> </header>
{/* Jerry's Story Content */} {/* Jerry's Story Content */}
<section className="py-16 px-6 bg-slate-700"> <section className="py-16 px-6 bg-white">
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<h1 className="text-4xl font-serif font-bold text-white mb-8 text-center">Jerry's Story</h1> <h1 className="text-4xl font-serif font-bold text-slate-700 mb-8 text-center">Jerry's Story</h1>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12"> <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-12">
<div className="rounded-lg overflow-hidden shadow-lg"> <div className="rounded-lg overflow-hidden shadow-lg">
@ -66,29 +66,29 @@ export default function JerryStoryPage() {
</div> </div>
<div className="max-w-3xl mx-auto space-y-6"> <div className="max-w-3xl mx-auto space-y-6">
<p className="text-white leading-relaxed"> <p className="text-slate-700 leading-relaxed">
Jerry Higginson has been the Alert Bay Trumpeter for over 27 years, bringing joy and music to cruise ship Jerry Higginson has been the Alert Bay Trumpeter for over 27 years, bringing joy and music to cruise ship
passengers traveling through the beautiful waters of northern Vancouver Island. passengers traveling through the beautiful waters of northern Vancouver Island.
</p> </p>
<p className="text-white leading-relaxed"> <p className="text-slate-700 leading-relaxed">
Since 1996, Jerry has performed over 1000 nautical serenades, creating unforgettable memories for millions Since 1996, Jerry has performed over 1000 nautical serenades, creating unforgettable memories for millions
of passengers from around the world. His dedication to spreading happiness through music has made him a of passengers from around the world. His dedication to spreading happiness through music has made him a
beloved figure in the maritime community. beloved figure in the maritime community.
</p> </p>
<p className="text-white leading-relaxed"> <p className="text-slate-700 leading-relaxed">
From his small boat, Jerry greets each passing cruise ship with enthusiasm and his signature trumpet From his small boat, Jerry greets each passing cruise ship with enthusiasm and his signature trumpet
performances, embodying the spirit of Alert Bay and the warmth of Canadian hospitality. performances, embodying the spirit of Alert Bay and the warmth of Canadian hospitality.
</p> </p>
<p className="text-white leading-relaxed"> <p className="text-slate-700 leading-relaxed">
Jerry's mission is simple: to bring smiles to people's faces and create magical moments at sea. His Jerry's mission is simple: to bring smiles to people's faces and create magical moments at sea. His
passion for music and connection with travelers has made him an integral part of the cruise experience passion for music and connection with travelers has made him an integral part of the cruise experience
through the Johnstone Straits. through the Johnstone Straits.
</p> </p>
<div className="mt-8 pt-6 border-t border-slate-500 text-center"> <div className="mt-8 pt-6 border-t border-gray-200 text-center">
<div className="mb-6"> <div className="mb-6">
<img <img
src="/images/jerry-masks-display.jpeg" src="/images/jerry-masks-display.jpeg"