diff --git a/app/cart-checkout/page.tsx b/app/cart-checkout/page.tsx
new file mode 100644
index 000000000..f0775904e
--- /dev/null
+++ b/app/cart-checkout/page.tsx
@@ -0,0 +1,151 @@
+// app/cart-checkout/page.tsx
+'use client'; // For useState if we were to make checkbox interactive
+
+import { useState } from 'react';
+
+export default function CartCheckoutPage() {
+ const [billingSameAsShipping, setBillingSameAsShipping] = useState(true);
+
+ // Dummy cart items
+ const cartItems = [
+ { id: 'p1', name: 'Awesome T-Shirt (Red, L)', quantity: 1, price: 29.99 },
+ { id: 'p2', name: 'Cool Cap - Black', quantity: 2, price: 15.00 },
+ { id: 'p3', name: 'Generic Gadget XL', quantity: 1, price: 199.50 },
+ ];
+
+ const cartSubtotal = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
+ const shippingEstimate = cartItems.length > 0 ? 5.00 : 0; // No shipping if cart is empty
+ const grandTotal = cartSubtotal + shippingEstimate;
+
+ // Inline styles
+ const pageStyle = { padding: '20px', fontFamily: 'Arial, sans-serif', maxWidth: '1000px', margin: '20px auto' };
+ const sectionStyle = { marginBottom: '40px', paddingBottom: '20px', borderBottom: '1px solid #eee' };
+ const headingStyle = { color: '#333', marginBottom: '20px', borderBottom: '1px solid #ddd', paddingBottom: '10px' };
+ const subHeadingStyle = { color: '#444', marginBottom: '15px' };
+ const inputStyle = { width: 'calc(100% - 22px)', padding: '10px', marginBottom: '10px', border: '1px solid #ccc', borderRadius: '4px', boxSizing: 'border-box' as const };
+ const buttonStyle = { padding: '12px 20px', backgroundColor: '#007bff', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer', fontSize: '1em' };
+ const smallButtonStyle = { padding: '5px 8px', margin: '0 5px', cursor: 'pointer' };
+ const cartItemStyle = { borderBottom: '1px solid #eee', padding: '15px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' };
+ const formGroupStyle = { marginBottom: '15px' };
+ const labelStyle = { display: 'block', marginBottom: '5px', fontWeight: 'bold' as const };
+
+
+ return (
+
+
Shopping Cart & Checkout
+
+ {/* Cart Items Section */}
+
+ Your Cart
+ {cartItems.length > 0 ? (
+ <>
+ {cartItems.map(item => (
+
+
+
{item.name}
+
Price: ${item.price.toFixed(2)}
+
+ Quantity:
+ - {item.quantity} +
+
+
+
+
Total: ${(item.price * item.quantity).toFixed(2)}
+
Remove
+
+
+ ))}
+
+
Subtotal: ${cartSubtotal.toFixed(2)}
+
Shipping Estimate: ${shippingEstimate.toFixed(2)}
+
Grand Total: ${grandTotal.toFixed(2)}
+
+ >
+ ) : (
+ Your cart is currently empty.
+ )}
+
+
+ {/* Checkout Form Section */}
+ {cartItems.length > 0 && ( // Only show checkout if cart is not empty
+
+ )}
+
+ {/* Request a Quote Section */}
+
+ Need a Custom Quote?
+ For bulk orders or special requirements, please request a quote.
+ alert('Redirecting to quote request page... (placeholder)')} // Placeholder action
+ onMouseOver={(e) => (e.currentTarget.style.backgroundColor = '#138496')}
+ onMouseOut={(e) => (e.currentTarget.style.backgroundColor = '#17a2b8')}
+ >
+ Request a Quote
+
+
+
+ );
+}
diff --git a/app/content/[slug]/page.tsx b/app/content/[slug]/page.tsx
new file mode 100644
index 000000000..e28dd457c
--- /dev/null
+++ b/app/content/[slug]/page.tsx
@@ -0,0 +1,54 @@
+// app/content/[slug]/page.tsx
+
+// Simulate fetching content (replace with actual CMS fetching later)
+async function getContent(slug: string) {
+ // In a real app, you'd fetch this from a CMS
+ const allContent: { [key: string]: { title: string; body: string[] } } = {
+ 'about-us': {
+ title: 'About Us',
+ body: [
+ 'This is the about us page.',
+ 'We are a company that does things.'
+ ]
+ },
+ 'contact-us': {
+ title: 'Contact Us',
+ body: [
+ 'You can contact us via email or phone.',
+ 'Email: contact@example.com',
+ 'Phone: 123-456-7890'
+ ]
+ },
+ 'privacy-policy': {
+ title: 'Privacy Policy',
+ body: [
+ 'This is our privacy policy.',
+ 'We respect your privacy and are committed to protecting your personal data.'
+ ]
+ }
+ };
+ return allContent[slug] || null;
+}
+
+export default async function ContentPage({ params }: { params: { slug: string } }) {
+ const content = await getContent(params.slug);
+
+ if (!content) {
+ // Handle case where content is not found, e.g., by returning a 404 or a specific message
+ return Content not found for {params.slug}
;
+ }
+
+ return (
+
+
{content.title}
+ {content.body.map((paragraph, index) => (
+
{paragraph}
+ ))}
+
+ );
+}
+
+// Optional: Generate static paths if you have a known set of content pages
+// export async function generateStaticParams() {
+// return [{ slug: 'about-us' }, { slug: 'contact-us' }, { slug: 'privacy-policy' }];
+// }
diff --git a/app/login/page.tsx b/app/login/page.tsx
new file mode 100644
index 000000000..435f3ea4a
--- /dev/null
+++ b/app/login/page.tsx
@@ -0,0 +1,58 @@
+// app/login/page.tsx
+export default function LoginPage() {
+ return (
+
+ );
+}
diff --git a/app/my-page/page.tsx b/app/my-page/page.tsx
new file mode 100644
index 000000000..e0b071573
--- /dev/null
+++ b/app/my-page/page.tsx
@@ -0,0 +1,139 @@
+// app/my-page/page.tsx
+
+export default function MyPage() {
+ // Dummy data
+ const orders = [
+ { id: '12345', date: '2023-10-26', total: '$150.00', status: 'Shipped' },
+ { id: '67890', date: '2023-11-05', total: '$75.50', status: 'Processing' },
+ { id: '10112', date: '2023-11-15', total: '$220.00', status: 'Delivered' },
+ ];
+ const quotes = [
+ { id: 'Q1001', date: '2023-10-20', total: '$500.00', status: 'Accepted' },
+ { id: 'Q1002', date: '2023-11-01', total: '$1250.75', status: 'Pending' },
+ ];
+ const downloads = [
+ { name: 'Product Manual X123.pdf', url: '#' },
+ { name: 'Software License - MyProduct v2.txt', url: '#' },
+ { name: 'Invoice_INV2023-10-26.pdf', url: '#' },
+ ];
+ const userProfile = {
+ name: 'Jane Doe',
+ email: 'jane.doe@example.com',
+ company: 'Innovate Solutions Ltd.',
+ memberSince: '2022-01-15',
+ };
+
+ const sectionStyle = {
+ marginBottom: '40px',
+ paddingBottom: '20px',
+ borderBottom: '1px solid #eee'
+ };
+
+ const headingStyle = {
+ color: '#333',
+ marginBottom: '15px'
+ };
+
+ const tableCellStyle = {
+ border: '1px solid #ddd',
+ padding: '10px',
+ textAlign: 'left' as const // Explicitly type textAlign
+ };
+
+ const buttonStyle = {
+ padding: '10px 15px',
+ backgroundColor: '#007bff',
+ color: 'white',
+ border: 'none',
+ borderRadius: '4px',
+ cursor: 'pointer',
+ fontSize: '1em'
+ };
+
+
+ return (
+
+
My Account
+
+ {/* Order History Section */}
+
+ Order History
+ {orders.length > 0 ? (
+
+
+
+ Order ID
+ Date
+ Total
+ Status
+
+
+
+ {orders.map(order => (
+
+ #{order.id}
+ {order.date}
+ {order.total}
+ {order.status}
+
+ ))}
+
+
+ ) : (
+ You have no past orders.
+ )}
+
+
+ {/* My Quotes Section */}
+
+ My Quotes
+ {quotes.length > 0 ? (
+
+ {quotes.map(quote => (
+
+ Quote #{quote.id} - Date: {quote.date} - Total: {quote.total} - Status: {quote.status}
+
+ ))}
+
+ ) : (
+ You have no active quotes.
+ )}
+
+
+ {/* My Downloads Section */}
+
+ My Downloads
+ {downloads.length > 0 ? (
+
+ {downloads.map((download, index) => ( // Added index for key as names might not be unique
+
+
+ {download.name}
+
+
+ ))}
+
+ ) : (
+ No downloads available.
+ )}
+
+
+ {/* Profile Information Section */}
+
+ My Profile
+
+
Name: {userProfile.name}
+
Email: {userProfile.email}
+
Company: {userProfile.company}
+
Member Since: {userProfile.memberSince}
+
+ (e.currentTarget.style.backgroundColor = '#0056b3')}
+ onMouseOut={(e) => (e.currentTarget.style.backgroundColor = '#007bff')}
+ >
+ Edit Profile
+
+
+
+ );
+}
diff --git a/app/page.tsx b/app/page.tsx
index 7c4a7d74f..69aba7b80 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -10,11 +10,60 @@ export const metadata = {
}
};
+// Simulate fetching page configuration from a CMS
+const pageConfig = {
+ showFeaturedProducts: true,
+ showPromotions: true
+};
+
+// Placeholder Product Item Component
+function ProductItem({ name, price, imageUrl }: { name: string; price: string; imageUrl: string }) {
+ return (
+
+
+
{name}
+
{price}
+
+ );
+}
+
+// Placeholder Promotion Banner Component
+function PromotionBanner({ title, imageUrl }: { title: string; imageUrl: string }) {
+ return (
+
+
+
{title}
+
+ );
+}
+
export default function HomePage() {
return (
<>
+ {/* Existing components can remain if they are part of the desired layout */}
+
+ {pageConfig.showFeaturedProducts && (
+
+ )}
+
+ {pageConfig.showPromotions && (
+
+ )}
+
>
);
diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx
index 33de3c0ba..1c384a211 100644
--- a/app/product/[handle]/page.tsx
+++ b/app/product/[handle]/page.tsx
@@ -1,149 +1,110 @@
-import type { Metadata } from 'next';
-import { notFound } from 'next/navigation';
+// app/product/[handle]/page.tsx
-import { GridTileImage } from 'components/grid/tile';
-import Footer from 'components/layout/footer';
-import { Gallery } from 'components/product/gallery';
-import { ProductProvider } from 'components/product/product-context';
-import { ProductDescription } from 'components/product/product-description';
-import { HIDDEN_PRODUCT_TAG } from 'lib/constants';
-import { getProduct, getProductRecommendations } from 'lib/shopify';
-import { Image } from 'lib/shopify/types';
-import Link from 'next/link';
-import { Suspense } from 'react';
-
-export async function generateMetadata(props: {
- params: Promise<{ handle: string }>;
-}): Promise {
- const params = await props.params;
- const product = await getProduct(params.handle);
-
- if (!product) return notFound();
-
- const { url, width, height, altText: alt } = product.featuredImage || {};
- const indexable = !product.tags.includes(HIDDEN_PRODUCT_TAG);
-
- return {
- title: product.seo.title || product.title,
- description: product.seo.description || product.description,
- robots: {
- index: indexable,
- follow: indexable,
- googleBot: {
- index: indexable,
- follow: indexable
- }
+// Simulate fetching product data
+async function getProduct(handle: string) {
+ const allProducts: { [key: string]: any } = { // Use 'any' for simplicity in this mock
+ 'sample-product-1': {
+ id: 'prod-1',
+ name: 'Awesome T-Shirt',
+ description: 'This is the best t-shirt ever. Made from 100% organic cotton.',
+ price: { amount: '29.99', currencyCode: 'USD' },
+ images: [
+ { src: '/placeholder-tshirt-blue.jpg', alt: 'Awesome T-Shirt - Blue' },
+ { src: '/placeholder-tshirt-red.jpg', alt: 'Awesome T-Shirt - Red' }
+ ],
+ variants: [
+ { id: 'v1-color', name: 'Color', value: 'Blue' },
+ { id: 'v1-size', name: 'Size', value: 'L' },
+ { id: 'v1-material', name: 'Material', value: 'Cotton' }
+ ]
},
- openGraph: url
- ? {
- images: [
- {
- url,
- width,
- height,
- alt
- }
- ]
- }
- : null
- };
-}
-
-export default async function ProductPage(props: { params: Promise<{ handle: string }> }) {
- const params = await props.params;
- const product = await getProduct(params.handle);
-
- if (!product) return notFound();
-
- const productJsonLd = {
- '@context': 'https://schema.org',
- '@type': 'Product',
- name: product.title,
- description: product.description,
- image: product.featuredImage.url,
- offers: {
- '@type': 'AggregateOffer',
- availability: product.availableForSale
- ? 'https://schema.org/InStock'
- : 'https://schema.org/OutOfStock',
- priceCurrency: product.priceRange.minVariantPrice.currencyCode,
- highPrice: product.priceRange.maxVariantPrice.amount,
- lowPrice: product.priceRange.minVariantPrice.amount
+ 'sample-product-2': {
+ id: 'prod-2',
+ name: 'Cool Gadget Pro',
+ description: 'The latest and greatest gadget with amazing features.',
+ price: { amount: '199.50', currencyCode: 'USD' },
+ images: [
+ { src: '/placeholder-gadget-main.jpg', alt: 'Cool Gadget Pro' },
+ { src: '/placeholder-gadget-angle.jpg', alt: 'Cool Gadget Pro - Angle View' }
+ ],
+ variants: [
+ { id: 'v2-color', name: 'Color', value: 'Black' },
+ { id: 'v2-storage', name: 'Storage', value: '256GB' }
+ ]
+ },
+ 'another-item': {
+ id: 'prod-3',
+ name: 'Simple Mug',
+ description: 'A simple mug for your daily coffee or tea.',
+ price: { amount: '12.00', currencyCode: 'USD' },
+ images: [
+ { src: '/placeholder-mug.jpg', alt: 'Simple Mug' }
+ ],
+ variants: [
+ { id: 'v3-color', name: 'Color', value: 'White' },
+ { id: 'v3-size', name: 'Size', value: 'Standard' }
+ ]
}
};
-
- return (
-
-
-
-
-
-
- }
- >
- ({
- src: image.url,
- altText: image.altText
- }))}
- />
-
-
-
-
-
-
-
-
-
- );
+ // Simulate network delay
+ await new Promise(resolve => setTimeout(resolve, 50));
+ return allProducts[handle] || null;
}
-async function RelatedProducts({ id }: { id: string }) {
- const relatedProducts = await getProductRecommendations(id);
+export default async function ProductPage({ params }: { params: { handle: string } }) {
+ const product = await getProduct(params.handle);
- if (!relatedProducts.length) return null;
+ if (!product) {
+ // In a real app, you might use Next.js's notFound() function here
+ return Product not found for handle: {params.handle}
;
+ }
return (
-
-
Related Products
-
- {relatedProducts.map((product) => (
-
-
-
-
-
- ))}
-
+
+
{product.name}
+
+ {product.images && product.images.length > 0 && (
+
+ )}
+
+
{product.description}
+
+
+ Price: {product.price.amount} {product.price.currencyCode}
+
+
+
Variants:
+ {product.variants && product.variants.length > 0 ? (
+
+ {product.variants.map((variant: any) => ( // Using any for mock simplicity
+
+ {variant.name}: {variant.value}
+
+ ))}
+
+ ) : (
+
No variants available for this product.
+ )}
+
+ {/* Add to cart button can be a simple placeholder */}
+
+ Add to Cart
+
);
}
diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx
index dfb07e3c0..3ffa55aa7 100644
--- a/app/search/[collection]/page.tsx
+++ b/app/search/[collection]/page.tsx
@@ -1,45 +1,108 @@
-import { getCollection, getCollectionProducts } from 'lib/shopify';
-import { Metadata } from 'next';
-import { notFound } from 'next/navigation';
+// app/search/[collection]/page.tsx
-import Grid from 'components/grid';
-import ProductGridItems from 'components/layout/product-grid-items';
-import { defaultSort, sorting } from 'lib/constants';
+// Simulate fetching products for a collection
+async function getProductsByCollection(collectionName: string) {
+ // Simulate network delay
+ await new Promise(resolve => setTimeout(resolve, 50));
-export async function generateMetadata(props: {
- params: Promise<{ collection: string }>;
-}): Promise
{
- const params = await props.params;
- const collection = await getCollection(params.collection);
-
- if (!collection) return notFound();
-
- return {
- title: collection.seo?.title || collection.title,
- description:
- collection.seo?.description || collection.description || `${collection.title} products`
+ const allProducts: { [key: string]: any[] } = {
+ 't-shirts': [
+ { id: 'ts1', name: 'Cool T-Shirt', price: { amount: '19.99', currencyCode: 'USD' }, image: { src: '/placeholder-tshirt1.jpg', alt: 'T-Shirt 1' } },
+ { id: 'ts2', name: 'Graphic Tee', price: { amount: '24.99', currencyCode: 'USD' }, image: { src: '/placeholder-tshirt2.jpg', alt: 'T-Shirt 2' } },
+ { id: 'ts3', name: 'Plain V-Neck', price: { amount: '15.50', currencyCode: 'USD' }, image: { src: '/placeholder-tshirt3.jpg', alt: 'Plain V-Neck' } },
+ ],
+ 'accessories': [
+ { id: 'ac1', name: 'Stylish Cap', price: { amount: '15.00', currencyCode: 'USD' }, image: { src: '/placeholder-cap.jpg', alt: 'Cap' } },
+ { id: 'ac2', name: 'Leather Belt', price: { amount: '35.00', currencyCode: 'USD' }, image: { src: '/placeholder-belt.jpg', alt: 'Leather Belt' } },
+ ],
+ 'footwear': [
+ { id: 'fw1', name: 'Running Shoes', price: { amount: '79.99', currencyCode: 'USD' }, image: { src: '/placeholder-shoes1.jpg', alt: 'Running Shoes' } },
+ { id: 'fw2', name: 'Casual Sneakers', price: { amount: '65.00', currencyCode: 'USD' }, image: { src: '/placeholder-sneakers1.jpg', alt: 'Casual Sneakers' } },
+ { id: 'fw3', name: 'Formal Shoes', price: { amount: '120.00', currencyCode: 'USD' }, image: { src: '/placeholder-shoes2.jpg', alt: 'Formal Shoes' } },
+ ]
+ // Add more dummy collections and products as needed
};
+ return allProducts[collectionName.toLowerCase()] || [];
}
-export default async function CategoryPage(props: {
- params: Promise<{ collection: string }>;
- searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
-}) {
- const searchParams = await props.searchParams;
- const params = await props.params;
- const { sort } = searchParams as { [key: string]: string };
- const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort;
- const products = await getCollectionProducts({ collection: params.collection, sortKey, reverse });
+export default async function CollectionPage({ params }: { params: { collection: string } }) {
+ const products = await getProductsByCollection(params.collection);
+ const collectionName = params.collection.charAt(0).toUpperCase() + params.collection.slice(1);
return (
-
- {products.length === 0 ? (
- {`No products found in this collection`}
- ) : (
-
-
-
- )}
-
+
+
+ Products in: {collectionName}
+
+
+
+ {/* Placeholder Filters */}
+
+
Filters
+
+ Category:
+
+ All {collectionName}
+ Sub-Category 1
+ Sub-Category 2
+ Sub-Category 3
+
+
+
+
Price Range:
+
+ {/* Basic display of range value - not functional */}
+
$0 - $200
+
+
+
+ {/* Main Content Area (Search + Product List) */}
+
+ {/* Placeholder Search Input */}
+
+
+
+
+ {/* Product List */}
+
+ {products.length > 0 ? (
+ products.map((product: any) => ( // Using any for mock simplicity
+
+
+
{product.name}
+
+ {product.price.amount} {product.price.currencyCode}
+
+ {/* Use a generic link for now; specific product pages are handled by [handle] route */}
+
+ View Details
+
+
+ ))
+ ) : (
+
No products found in this collection.
+ )}
+
+
+
+
);
}
diff --git a/app/search/page.tsx b/app/search/page.tsx
index dce5f0556..c9f99a354 100644
--- a/app/search/page.tsx
+++ b/app/search/page.tsx
@@ -1,38 +1,129 @@
-import Grid from 'components/grid';
-import ProductGridItems from 'components/layout/product-grid-items';
-import { defaultSort, sorting } from 'lib/constants';
-import { getProducts } from 'lib/shopify';
+// app/search/page.tsx
+'use client'; // Required for using client-side features like useState
-export const metadata = {
- title: 'Search',
- description: 'Search for products in the store.'
-};
+import { useState, useEffect } from 'react';
+import { useSearchParams } from 'next/navigation'; // To get query from URL
-export default async function SearchPage(props: {
- searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
-}) {
- const searchParams = await props.searchParams;
- const { sort, q: searchValue } = searchParams as { [key: string]: string };
- const { sortKey, reverse } = sorting.find((item) => item.slug === sort) || defaultSort;
+// Simulate fetching search results
+async function getSearchResults(query: string | null) {
+ // Simulate network delay
+ await new Promise(resolve => setTimeout(resolve, 50));
+ if (!query) return [];
+
+ const mockResults: { [key: string]: any[] } = {
+ 'shirt': [
+ { id: 'sr1', name: 'Search Result Shirt 1', price: { amount: '29.99', currencyCode: 'USD' }, image: { src: '/placeholder-shirt1.jpg', alt: 'Shirt 1' } },
+ { id: 'sr2', name: 'Search Result Shirt 2', price: { amount: '35.50', currencyCode: 'USD' }, image: { src: '/placeholder-shirt2.jpg', alt: 'Shirt 2' } },
+ ],
+ 'accessory': [
+ { id: 'sa1', name: 'Search Result Accessory', price: { amount: '12.00', currencyCode: 'USD' }, image: { src: '/placeholder-accessory.jpg', alt: 'Accessory' } },
+ ],
+ 'generic': [ // Added a generic list for queries that don't match specific terms
+ { id: 'g1', name: 'Generic Product A', price: { amount: '10.00', currencyCode: 'USD' }, image: { src: '/placeholder-generic1.jpg', alt: 'Generic A' } },
+ { id: 'g2', name: 'Generic Product B', price: { amount: '15.00', currencyCode: 'USD' }, image: { src: '/placeholder-generic2.jpg', alt: 'Generic B' } },
+ ]
+ };
+ return mockResults[query.toLowerCase()] || mockResults['generic']; // Fallback to generic results
+}
+
+export default function SearchPage() {
+ const searchParams = useSearchParams();
+ const initialQuery = searchParams.get('q');
+ const [query, setQuery] = useState(initialQuery || '');
+ const [results, setResults] = useState([]);
+ const [loading, setLoading] = useState(false);
+
+ const handleSearch = async (currentQuery: string) => {
+ if (!currentQuery.trim()) { // Trim query to avoid searching for empty spaces
+ setResults([]);
+ return;
+ }
+ setLoading(true);
+ const fetchedResults = await getSearchResults(currentQuery);
+ setResults(fetchedResults);
+ setLoading(false);
+ };
+
+ // Perform search when initialQuery (from URL) changes or when component mounts with an initialQuery
+ useEffect(() => {
+ if (initialQuery) {
+ setQuery(initialQuery); // Ensure input field is updated if query comes from URL
+ handleSearch(initialQuery);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ // Disabled exhaustive-deps because handleSearch reference might change but we only care about initialQuery
+ }, [initialQuery]);
- const products = await getProducts({ sortKey, reverse, query: searchValue });
- const resultsText = products.length > 1 ? 'results' : 'result';
return (
- <>
- {searchValue ? (
-
- {products.length === 0
- ? 'There are no products that match '
- : `Showing ${products.length} ${resultsText} for `}
- "{searchValue}"
+
+
Search Products
+
+
+
+ Personalization by Relewise will be implemented here.
+
+
+ {loading &&
Loading...
}
+
+ {!loading && results.length > 0 && (
+
+
Results for "{query}"
+
+ {results.map((product) => (
+
+
+
{product.name}
+
+ {product.price.amount} {product.price.currencyCode}
+
+
+ View Details
+
+
+ ))}
+
+
+ )}
+
+ {!loading && results.length === 0 && query && (
+
+
No specific results found for "{query}".
+
Did you mean: t-shirt, accessory, cap, generic?
{/* Placeholder suggestions */}
+
+ )}
+ {!loading && results.length === 0 && !query && (
+
+ Enter a search term above to find products.
- ) : null}
- {products.length > 0 ? (
-
-
-
- ) : null}
- >
+ )}
+
);
}