File size: 7,439 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import { useState } from "react";
import { useParams, useLocation } from "wouter";
import { useQuery } from "@tanstack/react-query";
import { storesApi } from "@/lib/api";
import Header from "@/components/layout/header";
import SellerProductGrid from "@/components/product/seller-product-grid";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { LoadingSpinner } from "@/components/ui/spinner";
import { ArrowLeft, Star, MapPin, User } from "lucide-react";

export default function StoreDetail() {
  const { id } = useParams();
  const [, setLocation] = useLocation();
  const [searchQuery, setSearchQuery] = useState("");

  const { data: storeData, isLoading, error } = useQuery({
    queryKey: ['/api/stores', id],
    queryFn: () => storesApi.getById(id!),
    enabled: !!id,
  });

  if (isLoading) {
    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">
          <LoadingSpinner text="Loading store details..." />
          <div className="mt-8">
            <Skeleton className="h-32 w-full mb-8 rounded-2xl" />
            <div className="flex items-center space-x-4 mb-8">
              <Skeleton className="w-16 h-16 rounded-full" />
              <div className="flex-1">
                <Skeleton className="h-6 w-48 mb-2" />
                <Skeleton className="h-4 w-32" />
              </div>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
              {[...Array(8)].map((_, i) => (
                <Skeleton key={i} className="aspect-square w-full rounded-2xl" />
              ))}
            </div>
          </div>
        </div>
      </div>
    );
  }

  if (error || !storeData) {
    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">
          <div className="text-center">
            <h1 className="text-2xl font-bold text-foreground mb-4">Store Not Found</h1>
            <Button onClick={() => setLocation('/')}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Back to Home
            </Button>
          </div>
        </div>
      </div>
    );
  }

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

      <div className="max-w-7xl mx-auto px-3 sm:px-4 lg:px-6 py-6" data-testid="store-detail">
        <Button
          variant="ghost"
          onClick={() => setLocation('/')}
          className="mb-6"
          data-testid="back-button"
        >
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back to Stores
        </Button>

        {/* Store Banner */}
        <div className="relative h-48 bg-gradient-to-r from-primary via-secondary to-primary rounded-2xl mb-8 overflow-hidden shadow-xl">
          {storeData.bannerImage ? (
            <img
              src={storeData.bannerImage}
              alt={`${storeData.name} banner`}
              className="w-full h-full object-cover"
              data-testid="store-banner"
            />
          ) : (
            <div className="absolute inset-0 bg-gradient-to-r from-primary via-secondary to-primary" />
          )}
          <div className="absolute inset-0 bg-black/20" />
          <div className="absolute bottom-4 left-4 text-white">
            <h1 className="text-3xl font-bold" data-testid="store-name">
              {storeData.name}
            </h1>
          </div>
        </div>

        {/* Store Info */}
        <Card className="mb-8 glass-card border-0">
          <CardContent className="p-6">
            <div className="flex items-start space-x-6">
              {/* Store Face Image */}
              <div className="w-20 h-20 rounded-full overflow-hidden bg-gray-100 flex-shrink-0">
                {storeData.faceImage ? (
                  <img
                    src={storeData.faceImage}
                    alt={`${storeData.name} profile`}
                    className="w-full h-full object-cover"
                    data-testid="store-face-image"
                  />
                ) : (
                  <div className="w-full h-full bg-gray-200 flex items-center justify-center">
                    <span className="text-gray-400 text-xs">No Image</span>
                  </div>
                )}
              </div>

              <div className="flex-1">
                <div className="flex items-center space-x-4 mb-4">
                  <h2 className="text-xl font-bold text-foreground" data-testid="store-title">
                    {storeData.name}
                  </h2>
                  <div className="flex items-center">
                    <div className="flex text-yellow-400 text-sm">
                      {[...Array(5)].map((_, i) => (
                        <Star key={i} className="h-4 w-4 fill-current" />
                      ))}
                    </div>
                    <span className="text-sm text-muted-foreground ml-2" data-testid="store-rating">
                      (4.9/5)
                    </span>
                  </div>
                </div>

                {/* Seller Info */}
                <div className="flex items-center space-x-2 mb-4">
                  <User className="h-4 w-4 text-primary" />
                  <span className="text-sm font-medium text-foreground">Seller:</span>
                  <span className="text-sm text-muted-foreground" data-testid="seller-name">
                    {storeData.seller?.username || 'Store Owner'}
                  </span>
                </div>

                {storeData.description && (
                  <div className="mb-4">
                    <h3 className="font-semibold text-foreground mb-2">About This Store</h3>
                    <p className="text-muted-foreground leading-relaxed" data-testid="store-description">
                      {storeData.description}
                    </p>
                  </div>
                )}

                <div className="flex items-center text-sm text-muted-foreground">
                  <MapPin className="h-4 w-4 mr-1" />
                  <span>Verified Seller • Bharat</span>
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        {/* Store Products */}
        <div>
          <div className="flex items-center justify-between mb-6">
            <h2 className="text-2xl font-bold text-foreground" data-testid="products-title">
              Products from {storeData.name}
            </h2>
            <span className="text-muted-foreground" data-testid="products-count">
              {storeData.products?.length || 0} products
            </span>
          </div>

          {storeData.products && storeData.products.length > 0 ? (
            <SellerProductGrid products={storeData.products} />
          ) : (
            <div className="text-center py-12" data-testid="no-products">
              <p className="text-muted-foreground">This store doesn't have any products yet.</p>
            </div>
          )}
        </div>
      </div>

    </div>
  );
}