File size: 5,709 Bytes
b89a86e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { useState, useEffect } from "react";
import { useLocation } from "wouter";
import { useQuery } from "@tanstack/react-query";
import { productsApi, categoriesApi } from "@/lib/api";
import Header from "@/components/layout/header";
import ProductCard from "@/components/product/product-card";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { ArrowLeft } from "lucide-react";
import { LoadingSpinner } from "@/components/ui/spinner";

export default function SearchResults() {
  const [, setLocation] = useLocation();
  const [searchQuery, setSearchQuery] = useState("");
  const [selectedCategory, setSelectedCategory] = useState<string>("");

  // Get search parameters from URL
  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const query = urlParams.get('q') || '';
    const category = urlParams.get('category') || '';
    setSearchQuery(query);
    setSelectedCategory(category);
  }, []);

  // Update URL when search parameters change
  useEffect(() => {
    const params = new URLSearchParams();
    if (searchQuery) params.set('q', searchQuery);
    if (selectedCategory) params.set('category', selectedCategory);
    
    const newUrl = `/search${params.toString() ? '?' + params.toString() : ''}`;
    window.history.replaceState({}, '', newUrl);
  }, [searchQuery, selectedCategory]);

  const { data: categories = [], isLoading: categoriesLoading } = useQuery({
    queryKey: ['/api/categories'],
    queryFn: () => categoriesApi.getAll(),
  });

  const { data: searchResults = [], isLoading: searchLoading } = useQuery({
    queryKey: ['/api/products', { search: searchQuery, category: selectedCategory }],
    queryFn: () => productsApi.getAll({ 
      ...(searchQuery && { search: searchQuery }),
      ...(selectedCategory && { category: selectedCategory })
    }),
    enabled: !!(searchQuery || selectedCategory),
  });

  const getPageTitle = () => {
    if (searchQuery && selectedCategory) {
      const categoryName = categories.find((c: any) => c.id === selectedCategory)?.name || 'Category';
      return `"${searchQuery}" in ${categoryName}`;
    } else if (searchQuery) {
      return `"${searchQuery}"`;
    } else if (selectedCategory) {
      const categoryName = categories.find((c: any) => c.id === selectedCategory)?.name || 'Category';
      return categoryName;
    }
    return 'Search Results';
  };

  return (
    <div className="min-h-screen page-gradient">
      <Header searchQuery={searchQuery} setSearchQuery={setSearchQuery} />

      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8" data-testid="search-results-page">
        {/* Back Navigation */}
        <Button
          variant="ghost"
          onClick={() => setLocation('/')}
          className="mb-6"
          data-testid="back-to-home"
        >
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back to Home
        </Button>

        {/* Search Header */}
        <div className="mb-8">
          <h1 className="text-3xl font-bold text-gray-900 mb-2" data-testid="search-title">
            Search Results for {getPageTitle()}
          </h1>
          {!searchLoading && (
            <p className="text-gray-600" data-testid="results-count">
              {searchResults.length} {searchResults.length === 1 ? 'product' : 'products'} found
            </p>
          )}
        </div>


        {/* Search Results */}
        <section data-testid="search-results-section">
          {searchLoading ? (
            <div className="flex flex-col items-center">
              <LoadingSpinner text="Searching products..." />
              <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mt-6 w-full">
                {[...Array(8)].map((_, i) => (
                  <div key={i} className="glass-card rounded-2xl p-4">
                    <Skeleton className="aspect-square w-full mb-4 rounded-xl" />
                    <Skeleton className="h-4 w-3/4 mb-2" />
                    <Skeleton className="h-4 w-1/2 mb-2" />
                    <Skeleton className="h-6 w-1/4" />
                  </div>
                ))}
              </div>
            </div>
          ) : searchResults.length > 0 ? (
            <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4 sm:gap-5 md:gap-6" data-testid="search-product-grid">
              {searchResults.map((product: any) => (
                <ProductCard key={product.id} product={product} />
              ))}
            </div>
          ) : (searchQuery || selectedCategory) ? (
            <div className="text-center py-12" data-testid="no-results">
              <h3 className="text-xl font-semibold text-gray-900 mb-2">No products found</h3>
              <p className="text-gray-600 mb-6">
                Try adjusting your search terms or browse all products
              </p>
              <Button 
                onClick={() => {
                  setSearchQuery('');
                  setSelectedCategory('');
                  setLocation('/');
                }}
                data-testid="browse-all-products"
              >
                Browse All Products
              </Button>
            </div>
          ) : (
            <div className="text-center py-12" data-testid="search-prompt">
              <h3 className="text-xl font-semibold text-gray-900 mb-2">Search for products</h3>
              <p className="text-gray-600">
                Use the search bar above or select a category to find products
              </p>
            </div>
          )}
        </section>
      </div>

    </div>
  );
}