diff --git a/src/app/store/[slug]/components/product-tabs.tsx b/src/app/store/[slug]/components/product-tabs.tsx new file mode 100644 index 00000000..abf287df --- /dev/null +++ b/src/app/store/[slug]/components/product-tabs.tsx @@ -0,0 +1,259 @@ +"use client"; + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Card, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Star, User } from "lucide-react"; +import { cn } from "@/lib/utils"; + +// Mock reviews data for demonstration (can be replaced with actual data from API) +const MOCK_REVIEWS = [ + { + id: "1", + author: "John Doe", + rating: 5, + date: "2024-03-15", + comment: "Excellent product! Highly recommended.", + verified: true, + }, + { + id: "2", + author: "Jane Smith", + rating: 4, + date: "2024-03-10", + comment: "Good quality, fast delivery.", + verified: true, + }, +]; + +interface Review { + id: string; + author: string; + rating: number; + date: string; + comment: string; + verified: boolean; +} + +interface ProductTabsProps { + description?: string | null; + specifications?: Record; + sku?: string; + barcode?: string | null; + weight?: number | null; + dimensions?: { + length?: number | null; + width?: number | null; + height?: number | null; + }; + reviews?: Review[]; + averageRating?: number; + className?: string; +} + +/** + * Product tabs component for displaying Description, Specifications, and Reviews + * Used on product detail pages to organize product information + */ +export function ProductTabs({ + description, + specifications = {}, + sku, + barcode, + weight, + dimensions, + reviews = MOCK_REVIEWS, + averageRating, + className, +}: ProductTabsProps) { + // Calculate average rating from reviews if not provided + const calculatedRating = averageRating ?? ( + reviews.length > 0 + ? reviews.reduce((sum, review) => sum + review.rating, 0) / reviews.length + : 0 + ); + + const hasSpecs = Object.keys(specifications).length > 0 || sku || barcode || weight || + (dimensions?.length && dimensions?.width && dimensions?.height); + + return ( + + + + Description + + {hasSpecs && ( + + Specifications + + )} + + Reviews ({reviews.length}) + + + + {/* Description Tab */} + +
+ {description ? ( +

+ {description} +

+ ) : ( +

+ No description available for this product. +

+ )} +
+
+ + {/* Specifications Tab */} + {hasSpecs && ( + +
+ {sku && ( +
+ SKU + {sku} +
+ )} + {barcode && ( +
+ Barcode + {barcode} +
+ )} + {weight && ( +
+ Weight + {weight} kg +
+ )} + {dimensions?.length && dimensions?.width && dimensions?.height && ( +
+ Dimensions + + {dimensions.length} × {dimensions.width} × {dimensions.height} cm + +
+ )} + {Object.entries(specifications).map(([key, value]) => ( +
+ {key} + {value} +
+ ))} +
+
+ )} + + {/* Reviews Tab */} + +
+ {/* Reviews Summary */} +
+
+
+
+ {[1, 2, 3, 4, 5].map((star) => ( + + ))} +
+ + {calculatedRating > 0 ? calculatedRating.toFixed(1) : "N/A"} + +
+

+ Based on {reviews.length} {reviews.length === 1 ? "review" : "reviews"} +

+
+ +
+ + {/* Reviews List */} +
+ {reviews.length > 0 ? ( + reviews.map((review) => ( + + +
+ {/* Reviewer Info */} +
+
+
+ +
+
+

+ {review.author} + {review.verified && ( + + Verified Purchase + + )} +

+

+ {new Date(review.date).toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + })} +

+
+
+
+ {[1, 2, 3, 4, 5].map((star) => ( + + ))} +
+
+ + {/* Review Comment */} +

+ {review.comment} +

+
+
+
+ )) + ) : ( +
+

No reviews yet. Be the first to review this product!

+
+ )} +
+ + {/* Load More */} +
+ +
+
+
+
+ ); +} diff --git a/src/app/store/[slug]/products/[productSlug]/page.tsx b/src/app/store/[slug]/products/[productSlug]/page.tsx index 897d2c9b..08a1ab0d 100644 --- a/src/app/store/[slug]/products/[productSlug]/page.tsx +++ b/src/app/store/[slug]/products/[productSlug]/page.tsx @@ -9,8 +9,8 @@ import { StockBadge } from "../../components/stock-badge"; import { VariantSelector } from "../../components/variant-selector"; import { AddToCartButton } from "../../components/add-to-cart-button"; import { ProductGrid } from "../../components/product-grid"; +import { ProductTabs } from "../../components/product-tabs"; import { Badge } from "@/components/ui/badge"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Package, TruckIcon, RefreshCw, ShieldCheck } from "lucide-react"; interface StoreProductPageProps { @@ -297,65 +297,17 @@ export default async function StoreProductPage({ params }: StoreProductPageProps {/* Product Details Tabs */}
- - - - Description - - - Specifications - - - - -
- {product.description ? ( -

- {product.description} -

- ) : ( -

- No description available for this product. -

- )} -
-
- - -
-
- SKU - {product.sku} -
- {product.barcode && ( -
- Barcode - {product.barcode} -
- )} - {product.weight && ( -
- Weight - {product.weight} kg -
- )} - {(product.length && product.width && product.height) && ( -
- Dimensions - - {product.length} × {product.width} × {product.height} cm - -
- )} -
-
-
+
{/* Related Products */} diff --git a/src/lib/storefront/get-default-config.ts b/src/lib/storefront/get-default-config.ts new file mode 100644 index 00000000..4bb90912 --- /dev/null +++ b/src/lib/storefront/get-default-config.ts @@ -0,0 +1,93 @@ +import type { StorefrontConfig } from "@/types/storefront-config"; + +/** + * Generate default storefront configuration for a store + * Uses store name and description to create sensible defaults + * + * @param storeName - The name of the store + * @param storeDescription - Optional description of the store + * @returns Complete StorefrontConfig with default values + */ +export function getDefaultStorefrontConfig( + storeName: string, + storeDescription?: string | null +): StorefrontConfig { + return { + // Hero section + hero: { + title: `Welcome to ${storeName}`, + subtitle: storeDescription || `Discover amazing products at ${storeName}`, + ctaText: "Shop Now", + ctaLink: "/products", + enabled: true, + }, + + // Categories section + categories: { + title: "Shop by Category", + subtitle: "Explore our wide range of products", + showCount: 6, + displayStyle: "grid", + enabled: true, + }, + + // Featured products section + featuredProducts: { + title: "Featured Products", + subtitle: "Check out our hand-picked selection", + maxProducts: 8, + displayStyle: "grid", + enabled: true, + }, + + // Newsletter section + newsletter: { + title: "Stay Updated", + subtitle: "Subscribe to our newsletter for exclusive offers and updates", + placeholder: "Enter your email", + buttonText: "Subscribe", + enabled: true, + }, + + // Trust badges + trustBadges: { + enabled: true, + badges: [ + { + icon: "truck", + title: "Free Shipping", + description: "On orders over $50", + }, + { + icon: "shield-check", + title: "Secure Payment", + description: "100% secure checkout", + }, + { + icon: "refresh-cw", + title: "Easy Returns", + description: "30-day return policy", + }, + { + icon: "headset", + title: "24/7 Support", + description: "Dedicated customer service", + }, + ], + }, + + // Theme settings (can be customized per tenant) + theme: { + primaryColor: undefined, + accentColor: undefined, + fontFamily: undefined, + }, + + // SEO settings + seo: { + title: storeName, + description: storeDescription || `Shop at ${storeName} for quality products`, + keywords: [], + }, + }; +} diff --git a/src/types/storefront-config.ts b/src/types/storefront-config.ts new file mode 100644 index 00000000..0285bbdb --- /dev/null +++ b/src/types/storefront-config.ts @@ -0,0 +1,88 @@ +/** + * Storefront Configuration Types + * Defines types for tenant-configurable storefront homepage and theme settings + */ + +/** + * Hero section configuration for storefront homepage + */ +export interface HeroConfig { + title: string; + subtitle: string; + ctaText: string; + ctaLink: string; + backgroundImage?: string; + enabled: boolean; +} + +/** + * Categories section configuration + */ +export interface CategoriesConfig { + title: string; + subtitle?: string; + showCount?: number; + displayStyle: "grid" | "carousel"; + enabled: boolean; +} + +/** + * Featured products section configuration + */ +export interface FeaturedProductsConfig { + title: string; + subtitle?: string; + maxProducts: number; + displayStyle: "grid" | "carousel"; + enabled: boolean; +} + +/** + * Newsletter subscription section configuration + */ +export interface NewsletterConfig { + title: string; + subtitle?: string; + placeholder: string; + buttonText: string; + enabled: boolean; +} + +/** + * Trust badges configuration (e.g., "Free Shipping", "30-Day Returns") + */ +export interface TrustBadgesConfig { + enabled: boolean; + badges: Array<{ + icon: string; + title: string; + description: string; + }>; +} + +/** + * Complete storefront configuration interface + * Used for tenant-specific homepage layout and theme customization + */ +export interface StorefrontConfig { + // Homepage sections + hero: HeroConfig; + categories: CategoriesConfig; + featuredProducts: FeaturedProductsConfig; + newsletter: NewsletterConfig; + trustBadges: TrustBadgesConfig; + + // Theme settings + theme: { + primaryColor?: string; + accentColor?: string; + fontFamily?: string; + }; + + // SEO settings + seo: { + title?: string; + description?: string; + keywords?: string[]; + }; +}