Refactor: Update petition form
This commit is contained in:
@ -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"
|
||||
|
||||
@ -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>
|
||||
|
||||
Reference in New Issue
Block a user