← back to Sdcc Awards

cypressaward/frontend/app/nonprofit/register/page.tsx

359 lines

'use client'

import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { useRouter } from 'next/navigation'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { toast } from '@/components/ui/use-toast'

const nonprofitSchema = z.object({
  organizationName: z.string().min(2, 'Organization name is required'),
  ein: z.string().regex(/^\d{2}-\d{7}$/, 'EIN must be in format XX-XXXXXXX'),
  website: z.string().url('Please enter a valid URL'),
  phone: z.string().min(10, 'Please enter a valid phone number'),
  email: z.string().email('Please enter a valid email'),
  mission: z.string().min(50, 'Mission statement must be at least 50 characters'),
  sectors: z.array(z.string()).min(1, 'Select at least one sector'),
  programs: z.string().min(30, 'Please describe your programs'),
  geography: z.array(z.string()).min(1, 'Select at least one geographic area'),
  annualBudget: z.string().optional(),
  yearFounded: z.string().regex(/^\d{4}$/, 'Please enter a valid year'),
  contactName: z.string().min(2, 'Contact name is required'),
  contactTitle: z.string().min(2, 'Contact title is required'),
  contactEmail: z.string().email('Please enter a valid email'),
  contactPhone: z.string().min(10, 'Please enter a valid phone number'),
  cyPresExperience: z.string().optional(),
  acceptTerms: z.boolean().refine(val => val === true, 'You must accept the terms'),
})

type NonprofitFormData = z.infer<typeof nonprofitSchema>

const sectors = [
  'Education',
  'Healthcare',
  'Environment',
  'Civil Rights',
  'Consumer Protection',
  'Privacy',
  'Labor Rights',
  'Housing',
  'Financial Justice',
  'Technology',
  'Arts & Culture',
  'Youth Services',
]

const geographicAreas = [
  'National',
  'Northeast',
  'Southeast',
  'Midwest',
  'Southwest',
  'West Coast',
  'International',
]

export default function NonprofitRegisterPage() {
  const router = useRouter()
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [selectedSectors, setSelectedSectors] = useState<string[]>([])
  const [selectedGeography, setSelectedGeography] = useState<string[]>([])

  const {
    register,
    handleSubmit,
    formState: { errors },
    setValue,
  } = useForm<NonprofitFormData>({
    resolver: zodResolver(nonprofitSchema),
  })

  const onSubmit = async (data: NonprofitFormData) => {
    setIsSubmitting(true)
    try {
      const response = await fetch('/api/nonprofits/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      })

      if (response.ok) {
        toast({
          title: 'Registration Successful',
          description: 'Your nonprofit has been registered. Check your email for verification.',
        })
        router.push('/nonprofit/dashboard')
      } else {
        throw new Error('Registration failed')
      }
    } catch (error) {
      toast({
        title: 'Registration Failed',
        description: 'Please try again later.',
        variant: 'destructive',
      })
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <div className="container max-w-4xl mx-auto py-8">
      <Card>
        <CardHeader>
          <CardTitle>Nonprofit Registration</CardTitle>
          <CardDescription>
            Register your nonprofit to receive notifications about cy pres opportunities 
            and connect with law firms seeking eligible organizations.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            <div className="grid md:grid-cols-2 gap-4">
              <div>
                <Label htmlFor="organizationName">Organization Name *</Label>
                <Input
                  id="organizationName"
                  {...register('organizationName')}
                  placeholder="Your Nonprofit Name"
                />
                {errors.organizationName && (
                  <p className="text-red-500 text-sm mt-1">{errors.organizationName.message}</p>
                )}
              </div>

              <div>
                <Label htmlFor="ein">EIN (Tax ID) *</Label>
                <Input
                  id="ein"
                  {...register('ein')}
                  placeholder="XX-XXXXXXX"
                />
                {errors.ein && (
                  <p className="text-red-500 text-sm mt-1">{errors.ein.message}</p>
                )}
              </div>

              <div>
                <Label htmlFor="website">Website *</Label>
                <Input
                  id="website"
                  {...register('website')}
                  placeholder="https://www.yournonprofit.org"
                />
                {errors.website && (
                  <p className="text-red-500 text-sm mt-1">{errors.website.message}</p>
                )}
              </div>

              <div>
                <Label htmlFor="phone">Phone *</Label>
                <Input
                  id="phone"
                  {...register('phone')}
                  placeholder="(555) 123-4567"
                />
                {errors.phone && (
                  <p className="text-red-500 text-sm mt-1">{errors.phone.message}</p>
                )}
              </div>

              <div>
                <Label htmlFor="email">Organization Email *</Label>
                <Input
                  id="email"
                  type="email"
                  {...register('email')}
                  placeholder="info@yournonprofit.org"
                />
                {errors.email && (
                  <p className="text-red-500 text-sm mt-1">{errors.email.message}</p>
                )}
              </div>

              <div>
                <Label htmlFor="yearFounded">Year Founded *</Label>
                <Input
                  id="yearFounded"
                  {...register('yearFounded')}
                  placeholder="2000"
                />
                {errors.yearFounded && (
                  <p className="text-red-500 text-sm mt-1">{errors.yearFounded.message}</p>
                )}
              </div>
            </div>

            <div>
              <Label htmlFor="mission">Mission Statement *</Label>
              <Textarea
                id="mission"
                {...register('mission')}
                rows={4}
                placeholder="Describe your organization's mission and goals..."
              />
              {errors.mission && (
                <p className="text-red-500 text-sm mt-1">{errors.mission.message}</p>
              )}
            </div>

            <div>
              <Label>Sectors (Select all that apply) *</Label>
              <div className="grid grid-cols-3 gap-3 mt-2">
                {sectors.map((sector) => (
                  <div key={sector} className="flex items-center space-x-2">
                    <Checkbox
                      id={sector}
                      onCheckedChange={(checked) => {
                        const updated = checked
                          ? [...selectedSectors, sector]
                          : selectedSectors.filter(s => s !== sector)
                        setSelectedSectors(updated)
                        setValue('sectors', updated)
                      }}
                    />
                    <Label htmlFor={sector} className="text-sm font-normal cursor-pointer">
                      {sector}
                    </Label>
                  </div>
                ))}
              </div>
              {errors.sectors && (
                <p className="text-red-500 text-sm mt-1">{errors.sectors.message}</p>
              )}
            </div>

            <div>
              <Label htmlFor="programs">Programs & Services *</Label>
              <Textarea
                id="programs"
                {...register('programs')}
                rows={3}
                placeholder="Describe your main programs and services..."
              />
              {errors.programs && (
                <p className="text-red-500 text-sm mt-1">{errors.programs.message}</p>
              )}
            </div>

            <div>
              <Label>Geographic Coverage *</Label>
              <div className="grid grid-cols-3 gap-3 mt-2">
                {geographicAreas.map((area) => (
                  <div key={area} className="flex items-center space-x-2">
                    <Checkbox
                      id={area}
                      onCheckedChange={(checked) => {
                        const updated = checked
                          ? [...selectedGeography, area]
                          : selectedGeography.filter(g => g !== area)
                        setSelectedGeography(updated)
                        setValue('geography', updated)
                      }}
                    />
                    <Label htmlFor={area} className="text-sm font-normal cursor-pointer">
                      {area}
                    </Label>
                  </div>
                ))}
              </div>
              {errors.geography && (
                <p className="text-red-500 text-sm mt-1">{errors.geography.message}</p>
              )}
            </div>

            <div className="border-t pt-6">
              <h3 className="text-lg font-semibold mb-4">Primary Contact Information</h3>
              <div className="grid md:grid-cols-2 gap-4">
                <div>
                  <Label htmlFor="contactName">Contact Name *</Label>
                  <Input
                    id="contactName"
                    {...register('contactName')}
                    placeholder="John Doe"
                  />
                  {errors.contactName && (
                    <p className="text-red-500 text-sm mt-1">{errors.contactName.message}</p>
                  )}
                </div>

                <div>
                  <Label htmlFor="contactTitle">Title *</Label>
                  <Input
                    id="contactTitle"
                    {...register('contactTitle')}
                    placeholder="Executive Director"
                  />
                  {errors.contactTitle && (
                    <p className="text-red-500 text-sm mt-1">{errors.contactTitle.message}</p>
                  )}
                </div>

                <div>
                  <Label htmlFor="contactEmail">Contact Email *</Label>
                  <Input
                    id="contactEmail"
                    type="email"
                    {...register('contactEmail')}
                    placeholder="john@yournonprofit.org"
                  />
                  {errors.contactEmail && (
                    <p className="text-red-500 text-sm mt-1">{errors.contactEmail.message}</p>
                  )}
                </div>

                <div>
                  <Label htmlFor="contactPhone">Contact Phone *</Label>
                  <Input
                    id="contactPhone"
                    {...register('contactPhone')}
                    placeholder="(555) 123-4567"
                  />
                  {errors.contactPhone && (
                    <p className="text-red-500 text-sm mt-1">{errors.contactPhone.message}</p>
                  )}
                </div>
              </div>
            </div>

            <div>
              <Label htmlFor="cyPresExperience">Previous Cy Pres Experience (Optional)</Label>
              <Textarea
                id="cyPresExperience"
                {...register('cyPresExperience')}
                rows={3}
                placeholder="Describe any previous cy pres awards received..."
              />
            </div>

            <div className="flex items-center space-x-2">
              <Checkbox
                id="acceptTerms"
                onCheckedChange={(checked) => setValue('acceptTerms', checked as boolean)}
              />
              <Label htmlFor="acceptTerms" className="text-sm font-normal">
                I accept the terms of service and privacy policy, and certify that all information 
                provided is accurate. I understand this is not legal advice.
              </Label>
            </div>
            {errors.acceptTerms && (
              <p className="text-red-500 text-sm">{errors.acceptTerms.message}</p>
            )}

            <Button type="submit" className="w-full" disabled={isSubmitting}>
              {isSubmitting ? 'Registering...' : 'Register Organization'}
            </Button>
          </form>
        </CardContent>
      </Card>
    </div>
  )
}