Refactor: Update petition form

This commit is contained in:
gpt-engineer-app[bot]
2025-10-24 14:19:23 +00:00
parent 3540e3ed7f
commit 0270c2f2dc
2 changed files with 89 additions and 35 deletions

View File

@ -12,20 +12,33 @@ const petitionSchema = z.object({
comment: z.string().trim().max(1000, "Comment must be less than 1000 characters").optional(),
});
export const PetitionForm = () => {
const anonymousSchema = z.object({
email: z.string().trim().email("Invalid email address").max(255, "Email must be less than 255 characters"),
});
interface PetitionFormProps {
compact?: boolean;
}
export const PetitionForm = ({ compact = false }: PetitionFormProps) => {
const [formData, setFormData] = useState({
name: "",
email: "",
comment: "",
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [isAnonymous, setIsAnonymous] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// Validate input
// Validate input based on mode
try {
if (isAnonymous) {
anonymousSchema.parse({ email: formData.email });
} else {
petitionSchema.parse(formData);
}
} catch (error) {
if (error instanceof z.ZodError) {
toast.error(error.errors[0].message);
@ -39,15 +52,16 @@ export const PetitionForm = () => {
const { error } = await supabase
.from('petition_signatures')
.insert([{
name: formData.name.trim(),
name: isAnonymous ? 'Anonymous' : formData.name.trim(),
email: formData.email.trim(),
comment: formData.comment.trim() || null,
comment: isAnonymous ? null : (formData.comment.trim() || null),
}]);
if (error) throw error;
toast.success("Thank you for signing! Your voice matters.");
setFormData({ name: "", email: "", comment: "" });
setIsAnonymous(false);
} catch (error) {
console.error('Error signing petition:', error);
toast.error("Failed to submit signature. Please try again.");
@ -57,7 +71,31 @@ export const PetitionForm = () => {
};
return (
<form onSubmit={handleSubmit} className="space-y-4 max-w-xl mx-auto">
<form onSubmit={handleSubmit} className={`space-y-4 ${compact ? 'max-w-md' : 'max-w-xl'} mx-auto`}>
{!compact && (
<div className="mb-4 flex items-center gap-2">
<Button
type="button"
variant={isAnonymous ? "outline" : "default"}
size="sm"
onClick={() => setIsAnonymous(false)}
className="flex-1"
>
Full Signature
</Button>
<Button
type="button"
variant={isAnonymous ? "default" : "outline"}
size="sm"
onClick={() => setIsAnonymous(true)}
className="flex-1"
>
Anonymous Sign
</Button>
</div>
)}
{!isAnonymous && (
<div>
<Input
placeholder="Your Name"
@ -67,6 +105,8 @@ export const PetitionForm = () => {
className="bg-background border-border"
/>
</div>
)}
<div>
<Input
type="email"
@ -77,6 +117,8 @@ export const PetitionForm = () => {
className="bg-background border-border"
/>
</div>
{!isAnonymous && !compact && (
<div>
<Textarea
placeholder="Why is Victoria Way Carpark important to you? (Optional)"
@ -85,6 +127,14 @@ export const PetitionForm = () => {
className="bg-background border-border min-h-24"
/>
</div>
)}
{isAnonymous && (
<p className="text-sm text-muted-foreground">
Your signature will be recorded as "Anonymous" with only your email for verification.
</p>
)}
<Button
type="submit"
size="lg"

View File

@ -74,8 +74,8 @@ const Index = () => {
return (
<div className="min-h-screen bg-background">
{/* Hero Section */}
<section className="relative h-[600px] flex items-center justify-center text-center overflow-hidden">
{/* Hero Section with Petition */}
<section className="relative min-h-[700px] flex items-center justify-center text-center overflow-hidden py-16">
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: `url(${carparkHero})` }}
@ -89,13 +89,17 @@ const Index = () => {
<p className="text-xl md:text-2xl text-primary-foreground/90 mb-8">
We support safety-first action, but this area of Woking needs adequate parking and communication from the council
</p>
<Button
size="lg"
onClick={scrollToPetition}
className="bg-gradient-to-r from-accent to-accent/90 hover:from-accent/90 hover:to-accent/80 text-accent-foreground text-lg px-8 py-6 shadow-[var(--shadow-elevated)] font-semibold"
>
Sign the Petition Now
</Button>
<div className="bg-card/95 backdrop-blur-sm rounded-lg p-8 shadow-[var(--shadow-elevated)] mb-6">
<div className="mb-6">
<h2 className="text-3xl font-bold text-primary mb-2">Sign the Petition</h2>
<p className="text-lg text-muted-foreground">
{signatureCount > 0 && <span className="font-semibold text-accent">{signatureCount} people</span>}
{signatureCount > 0 ? ' have' : 'Be the first to'} signed so far
</p>
</div>
<PetitionForm compact />
</div>
</div>
</section>
@ -359,14 +363,14 @@ const Index = () => {
</div>
</section>
{/* Petition Form */}
{/* Additional Petition Section */}
<section id="petition" className="py-16 px-6">
<div className="max-w-4xl mx-auto text-center">
<h2 className="text-4xl font-bold text-primary mb-4">
Add Your Voice
Add Your Story
</h2>
<p className="text-xl text-muted-foreground mb-12">
Sign the petition asking Woking Council to provide regular updates and adequate parking solutions for this area of Woking
Share why this matters to you and add your full testimony to the petition
</p>
<PetitionForm />
</div>