← back to Dear Bubbe Nextjs
app/api/shopify/products/route.ts
196 lines
import { NextRequest, NextResponse } from 'next/server'
// Mock Shopify products data - replace with actual Shopify API integration
const MOCK_PRODUCTS = [
{
id: 'prod_001',
title: 'Elegant Floral Wallcovering',
handle: 'elegant-floral-wallcovering',
vendor: 'Designer Collection',
sku: 'DC-FLR-001',
imageUrl: 'https://via.placeholder.com/400x400/f093fb/ffffff?text=Floral',
price: '$89.99',
description: 'Beautiful floral pattern perfect for dining rooms and living spaces'
},
{
id: 'prod_002',
title: 'Modern Geometric Design',
handle: 'modern-geometric-design',
vendor: 'Contemporary Line',
sku: 'CL-GEO-002',
imageUrl: 'https://via.placeholder.com/400x400/667eea/ffffff?text=Geometric',
price: '$129.99',
description: 'Bold geometric patterns for modern interior design'
},
{
id: 'prod_003',
title: 'Vintage Damask Pattern',
handle: 'vintage-damask-pattern',
vendor: 'Classic Designs',
sku: 'CD-DMS-003',
imageUrl: 'https://via.placeholder.com/400x400/f5576c/ffffff?text=Damask',
price: '$156.99',
description: 'Traditional damask pattern with a vintage aesthetic'
},
{
id: 'prod_004',
title: 'Tropical Leaf Collection',
handle: 'tropical-leaf-collection',
vendor: 'Nature Series',
sku: 'NS-TRP-004',
imageUrl: 'https://via.placeholder.com/400x400/48bb78/ffffff?text=Tropical',
price: '$94.99',
description: 'Lush tropical leaves bringing nature indoors'
},
{
id: 'prod_005',
title: 'Abstract Art Wallcovering',
handle: 'abstract-art-wallcovering',
vendor: 'Artist Collection',
sku: 'AC-ABS-005',
imageUrl: 'https://via.placeholder.com/400x400/fd79a8/ffffff?text=Abstract',
price: '$198.99',
description: 'Contemporary abstract design for artistic spaces'
}
]
interface ShopifyProductsQuery {
limit?: number
sortKey?: 'CREATED_AT' | 'UPDATED_AT' | 'TITLE' | 'VENDOR'
reverse?: boolean
query?: string
}
// Simulate Shopify GraphQL API response
async function fetchShopifyProducts(queryParams: ShopifyProductsQuery) {
// In a real implementation, this would make an actual GraphQL call to Shopify
const { limit = 20, sortKey = 'CREATED_AT', reverse = true, query } = queryParams
let products = [...MOCK_PRODUCTS]
// Apply search filter
if (query) {
products = products.filter(product =>
product.title.toLowerCase().includes(query.toLowerCase()) ||
product.sku.toLowerCase().includes(query.toLowerCase()) ||
product.vendor.toLowerCase().includes(query.toLowerCase()) ||
product.description.toLowerCase().includes(query.toLowerCase())
)
}
// Apply sorting
products.sort((a, b) => {
let comparison = 0
switch (sortKey) {
case 'TITLE':
comparison = a.title.localeCompare(b.title)
break
case 'VENDOR':
comparison = a.vendor.localeCompare(b.vendor)
break
case 'CREATED_AT':
case 'UPDATED_AT':
default:
// Mock timestamp sorting
comparison = a.id.localeCompare(b.id)
break
}
return reverse ? -comparison : comparison
})
// Apply limit
products = products.slice(0, limit)
return {
data: {
products: {
edges: products.map(product => ({
node: product
}))
}
}
}
}
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
const queryParams: ShopifyProductsQuery = {
limit: searchParams.get('limit') ? parseInt(searchParams.get('limit')!) : 20,
sortKey: (searchParams.get('sortKey') as any) || 'CREATED_AT',
reverse: searchParams.get('reverse') !== 'false',
query: searchParams.get('query') || undefined
}
console.log('[SHOPIFY] Fetching products with params:', queryParams)
const shopifyResponse = await fetchShopifyProducts(queryParams)
if (shopifyResponse.data?.products) {
const products = shopifyResponse.data.products.edges.map((edge: any) => ({
id: edge.node.id,
title: edge.node.title,
handle: edge.node.handle,
vendor: edge.node.vendor,
sku: edge.node.sku,
imageUrl: edge.node.imageUrl,
price: edge.node.price,
description: edge.node.description
}))
console.log(`[SHOPIFY] Retrieved ${products.length} products`)
return NextResponse.json({
products,
count: products.length,
query: queryParams.query || null
})
} else {
return NextResponse.json({
products: [],
count: 0,
error: 'No products found'
})
}
} catch (error) {
console.error('[SHOPIFY] Error fetching products:', error)
return NextResponse.json({
error: 'Failed to fetch products from Shopify',
details: error instanceof Error ? error.message : String(error)
}, { status: 500 })
}
}
export async function POST(request: NextRequest) {
try {
// This could be used to create new products via GraphQL mutation
const body = await request.json()
console.log('[SHOPIFY] Create product request:', body)
// Mock successful creation
const newProduct = {
id: `prod_${Date.now()}`,
title: body.title || 'New Product',
handle: (body.title || 'new-product').toLowerCase().replace(/\s+/g, '-'),
vendor: body.vendor || 'Default Vendor',
sku: body.sku || `SKU-${Date.now()}`,
imageUrl: body.imageUrl || 'https://via.placeholder.com/400x400/cccccc/ffffff?text=New+Product',
price: body.price || '$0.00',
description: body.description || 'Product description'
}
return NextResponse.json({
success: true,
product: newProduct,
message: 'Product created successfully (mock)'
})
} catch (error) {
console.error('[SHOPIFY] Error creating product:', error)
return NextResponse.json({
error: 'Failed to create product',
details: error instanceof Error ? error.message : String(error)
}, { status: 500 })
}
}