← back to Goodquestion

src/components/search/SearchForm.tsx

348 lines

'use client'

import { useState } from 'react'
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Search, MapPin, Briefcase, Navigation } from 'lucide-react'

interface SearchFormProps {
  onSearch: (data: SearchFormData) => void
  isLoading?: boolean
}

export interface SearchFormData {
  location: string
  businessType: string
  radiusMiles: number
  capitalOnHand?: number
  searchMode?: 'single' | 'opportunities'
}

const topTrendingIdeas = [
  { business: 'AI-powered SaaS startup', location: 'San Francisco, CA', description: 'Build the next unicorn with GPT wrappers' },
  { business: 'Craft Coffee Roastery', location: 'Austin, TX', description: 'Single-origin artisan beans for hipsters' },
  { business: 'Ghost Kitchen (Cloud Kitchen)', location: 'Miami, FL', description: 'Virtual restaurants, real profits' },
  { business: 'Electric Vehicle Charging Station', location: 'Los Angeles, CA', description: 'Capitalize on the EV revolution' },
  { business: 'Premium Pet Care & Grooming', location: 'Seattle, WA', description: 'Pamper those fur babies' },
]

export function SearchForm({ onSearch, isLoading = false }: SearchFormProps) {
  const [location, setLocation] = useState('')
  const [businessType, setBusinessType] = useState('')
  const [radiusMiles, setRadiusMiles] = useState(10)
  const [capitalOnHand, setCapitalOnHand] = useState('')
  const [showSuggestions, setShowSuggestions] = useState(false)

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()

    // If both fields are empty, show suggestions
    if (!location.trim() && !businessType.trim()) {
      setShowSuggestions(true)
      return
    }

    // If location is provided but no business type, find opportunities
    if (location.trim() && !businessType.trim()) {
      onSearch({
        location: location.trim(),
        businessType: '',
        radiusMiles,
        capitalOnHand: capitalOnHand ? parseInt(capitalOnHand) : undefined,
        searchMode: 'opportunities',
      })
      return
    }

    // Use defaults if location is empty
    const finalLocation = location.trim() || 'San Francisco, CA'
    const finalBusinessType = businessType.trim()

    onSearch({
      location: finalLocation,
      businessType: finalBusinessType,
      radiusMiles,
      capitalOnHand: capitalOnHand ? parseInt(capitalOnHand) : undefined,
      searchMode: 'single',
    })
  }

  const handleFindOpportunities = () => {
    if (!location.trim()) {
      alert('Please enter a location to search for opportunities')
      return
    }

    if (!capitalOnHand || parseInt(capitalOnHand) <= 0) {
      alert('Please enter your available capital amount')
      return
    }

    onSearch({
      location: location.trim(),
      businessType: '',
      radiusMiles,
      capitalOnHand: parseInt(capitalOnHand),
      searchMode: 'opportunities',
    })
  }

  const handleSurprise = (idea: typeof topTrendingIdeas[0]) => {
    setLocation(idea.location)
    setBusinessType(idea.business)
    setShowSuggestions(false)
    onSearch({
      location: idea.location,
      businessType: idea.business,
      radiusMiles,
    })
  }

  const exampleBusinessTypes = [
    'Coffee Shop',
    'Restaurant',
    'Retail Store',
    'Gym/Fitness',
    'Bakery',
    'Salon',
    'Tech Startup',
    'Consulting',
  ]

  return (
    <Card className="w-full">
      <CardHeader>
        <CardTitle className="flex items-center gap-2 text-2xl">
          <Search className="h-6 w-6" />
          Search Business Ideas in Your Area
        </CardTitle>
        <CardDescription>
          Enter your location and business idea to get an AI-powered SWOT analysis
        </CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit} className="space-y-6">
          {/* Location Input */}
          <div className="space-y-2">
            <label
              htmlFor="location"
              className="flex items-center gap-2 text-sm font-medium"
            >
              <MapPin className="h-4 w-4" />
              Location (City, State)
            </label>
            <input
              id="location"
              type="text"
              value={location}
              onChange={(e) => setLocation(e.target.value)}
              placeholder="e.g., Portland, OR (leave blank for San Francisco, CA)"
              className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all"
            />
            <p className="text-xs text-muted-foreground">
              Leave blank to analyze the best trending location
            </p>
          </div>

          {/* Business Type Input */}
          <div className="space-y-2">
            <label
              htmlFor="businessType"
              className="flex items-center gap-2 text-sm font-medium"
            >
              <Briefcase className="h-4 w-4" />
              Business Idea or Occupation
            </label>
            <input
              id="businessType"
              type="text"
              value={businessType}
              onChange={(e) => setBusinessType(e.target.value)}
              placeholder="e.g., Specialty Coffee Roastery (leave blank for AI SaaS)"
              className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all"
            />
            <div className="flex flex-wrap gap-2 mt-2">
              {exampleBusinessTypes.map((type) => (
                <Badge
                  key={type}
                  variant="outline"
                  className="cursor-pointer hover:bg-blue-50 transition-colors"
                  onClick={() => setBusinessType(type)}
                >
                  {type}
                </Badge>
              ))}
            </div>
            <p className="text-xs text-muted-foreground">
              Click a suggestion, type your own, or leave blank for best AI idea
            </p>
          </div>

          {/* Radius Input */}
          <div className="space-y-2">
            <label
              htmlFor="radius"
              className="flex items-center gap-2 text-sm font-medium"
            >
              <Navigation className="h-4 w-4" />
              Search Radius: {radiusMiles} miles
            </label>
            <div className="flex items-center gap-4">
              <input
                id="radius"
                type="range"
                min="1"
                max="50"
                step="1"
                value={radiusMiles}
                onChange={(e) => setRadiusMiles(parseInt(e.target.value))}
                className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
              />
              <div className="text-sm font-medium bg-blue-50 px-3 py-1 rounded-lg min-w-[60px] text-center">
                {radiusMiles} mi
              </div>
            </div>
            <div className="flex justify-between text-xs text-muted-foreground">
              <span>1 mile</span>
              <span>50 miles</span>
            </div>
            <p className="text-xs text-muted-foreground">
              Search for competitors and opportunities within this radius
            </p>
          </div>

          {/* Capital on Hand Input */}
          <div className="space-y-2">
            <label
              htmlFor="capital"
              className="flex items-center gap-2 text-sm font-medium"
            >
              <Briefcase className="h-4 w-4" />
              Capital on Hand (Optional)
            </label>
            <div className="relative">
              <span className="absolute left-4 top-3 text-gray-500">$</span>
              <input
                id="capital"
                type="number"
                value={capitalOnHand}
                onChange={(e) => setCapitalOnHand(e.target.value)}
                placeholder="25000"
                min="0"
                step="1000"
                className="w-full pl-8 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all"
              />
            </div>
            <p className="text-xs text-muted-foreground">
              Enter your available capital to find opportunities that match your budget
            </p>
          </div>

          {/* Submit Buttons */}
          <div className="space-y-3">
            {/* Regular Analysis Button */}
            <button
              type="submit"
              disabled={isLoading}
              className="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white font-semibold py-4 px-6 rounded-lg transition-all duration-200 flex items-center justify-center gap-2 shadow-lg hover:shadow-xl"
            >
              {isLoading ? (
                <>
                  <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
                  Analyzing...
                </>
              ) : (
                <>
                  <Search className="h-5 w-5" />
                  {!location.trim() && !businessType.trim() ? 'Show Top 5 Trending Ideas' : 'Analyze Business Opportunity'}
                </>
              )}
            </button>

            {/* Find Opportunities Button */}
            <button
              type="button"
              onClick={handleFindOpportunities}
              disabled={isLoading}
              className="w-full bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-700 hover:to-emerald-700 disabled:bg-gray-400 text-white font-semibold py-4 px-6 rounded-lg transition-all duration-200 flex items-center justify-center gap-2 shadow-lg hover:shadow-xl"
            >
              <MapPin className="h-5 w-5" />
              Find Top 10 Opportunities in My Area
            </button>
          </div>

          {/* Top 5 Suggestions Modal */}
          {showSuggestions && (
            <div className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4">
              <div className="bg-white rounded-xl shadow-2xl max-w-3xl w-full max-h-[90vh] overflow-y-auto">
                <div className="p-6 border-b sticky top-0 bg-white">
                  <h2 className="text-2xl font-bold text-gray-900">🔥 Top 5 Trending Business Ideas</h2>
                  <p className="text-sm text-gray-600 mt-1">Click any idea to analyze it, or close to enter your own</p>
                </div>

                <div className="p-6 space-y-4">
                  {topTrendingIdeas.map((idea, index) => (
                    <button
                      key={index}
                      onClick={() => handleSurprise(idea)}
                      className="w-full text-left p-5 border-2 border-gray-200 rounded-lg hover:border-blue-500 hover:bg-blue-50 transition-all duration-200 group"
                    >
                      <div className="flex items-start justify-between">
                        <div className="flex-1">
                          <div className="flex items-center gap-3 mb-2">
                            <span className="text-2xl font-bold text-blue-600 group-hover:scale-110 transition-transform">
                              #{index + 1}
                            </span>
                            <h3 className="text-lg font-bold text-gray-900">{idea.business}</h3>
                          </div>
                          <p className="text-sm text-gray-600 mb-2">{idea.description}</p>
                          <div className="flex items-center gap-2 text-sm text-gray-500">
                            <MapPin className="h-4 w-4" />
                            {idea.location}
                          </div>
                        </div>
                        <div className="ml-4 text-blue-600 group-hover:translate-x-1 transition-transform">
                          →
                        </div>
                      </div>
                    </button>
                  ))}
                </div>

                <div className="p-6 border-t bg-gray-50 flex gap-3">
                  <button
                    onClick={() => setShowSuggestions(false)}
                    className="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-3 px-6 rounded-lg transition-all duration-200"
                  >
                    Close
                  </button>
                  <button
                    onClick={() => {
                      const randomIdea = topTrendingIdeas[Math.floor(Math.random() * topTrendingIdeas.length)]
                      handleSurprise(randomIdea)
                    }}
                    className="flex-1 bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold py-3 px-6 rounded-lg transition-all duration-200 shadow-lg hover:shadow-xl"
                  >
                    🎲 Surprise Me!
                  </button>
                </div>
              </div>
            </div>
          )}

          {/* Help Text */}
          <div className="bg-blue-50 border border-blue-200 rounded-lg p-4 text-sm">
            <p className="font-medium text-blue-900 mb-1">How it works:</p>
            <ol className="list-decimal list-inside space-y-1 text-blue-800">
              <li>Enter your target location and business idea</li>
              <li>AI analyzes local competitors, demographics, and market data</li>
              <li>Get a comprehensive SWOT analysis with visualizations</li>
              <li>Review action plan and income projections</li>
            </ol>
          </div>
        </form>
      </CardContent>
    </Card>
  )
}