"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog" import { Alert, AlertDescription } from "@/components/ui/alert" import { Plus, Search, Edit, Trash2, Save, X, AlertCircle, CheckCircle, DollarSign, Package, Image, } from "lucide-react" import type { Product } from "@/lib/products/types" interface ProductFormData { name: string description: string price: string currency: string images: string[] metadata: Record } const initialFormData: ProductFormData = { name: "", description: "", price: "", currency: "usd", images: [], metadata: {}, } const currencyOptions = [ { value: "usd", label: "USD ($)" }, { value: "eur", label: "EUR (€)" }, { value: "gbp", label: "GBP (£)" }, { value: "cad", label: "CAD ($)" }, { value: "aud", label: "AUD ($)" }, ] export function ProductAdmin() { const [products, setProducts] = useState([]) const [loading, setLoading] = useState(true) const [searchTerm, setSearchTerm] = useState("") const [selectedProducts, setSelectedProducts] = useState([]) const [showCreateDialog, setShowCreateDialog] = useState(false) const [editingProduct, setEditingProduct] = useState(null) const [isSaving, setIsSaving] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) const [formData, setFormData] = useState(initialFormData) // Fetch products const fetchProducts = async () => { try { setLoading(true) const response = await fetch("/api/products/admin") if (!response.ok) throw new Error("Failed to fetch products") const data = await response.json() setProducts(data.products) } catch (err) { setError(err instanceof Error ? err.message : "Failed to fetch products") } finally { setLoading(false) } } useEffect(() => { fetchProducts() }, []) // Handle form input changes const handleInputChange = (field: keyof ProductFormData, value: any) => { setFormData((prev) => ({ ...prev, [field]: value, })) } // Handle metadata input changes const handleMetadataChange = (key: string, value: string) => { setFormData((prev) => ({ ...prev, metadata: { ...prev.metadata, [key]: value, }, })) } // Add metadata field const addMetadataField = () => { const emptyKey = Object.keys(formData.metadata).length === 0 ? "category" : `key${Object.keys(formData.metadata).length + 1}` setFormData((prev) => ({ ...prev, metadata: { ...prev.metadata, [emptyKey]: "", }, })) } // Remove metadata field const removeMetadataField = (key: string) => { setFormData((prev) => { const newMetadata = { ...prev.metadata } delete newMetadata[key] return { ...prev, metadata: newMetadata, } }) } // Create product const handleCreateProduct = async () => { try { setIsSaving(true) setError(null) setSuccess(null) // Validate form if (!formData.name || !formData.price) { setError("Name and price are required") return } const price = parseFloat(formData.price) if (isNaN(price) || price <= 0) { setError("Price must be a valid positive number") return } const response = await fetch("/api/products/admin", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: formData.name, description: formData.description, price, currency: formData.currency, images: formData.images.filter(Boolean), metadata: formData.metadata, }), }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.error || "Failed to create product") } const newProduct = await response.json() setProducts((prev) => [newProduct.product, ...prev]) setSuccess(`Product "${newProduct.product.name}" created successfully`) // Reset form setFormData(initialFormData) setShowCreateDialog(false) } catch (err) { setError(err instanceof Error ? err.message : "Failed to create product") } finally { setIsSaving(false) } } // Update product (placeholder - would need implementation) const handleUpdateProduct = async (product: Product) => { try { setIsSaving(true) setError(null) setSuccess(null) // In a real implementation, you would call the update API console.log("Updating product:", product) setSuccess(`Product "${product.name}" updated successfully`) setEditingProduct(null) } catch (err) { setError(err instanceof Error ? err.message : "Failed to update product") } finally { setIsSaving(false) } } // Delete product (placeholder - would need implementation) const handleDeleteProduct = async (productId: string) => { try { if ( !confirm( "Are you sure you want to delete this product? This action cannot be undone." ) ) { return } setLoading(true) setError(null) // In a real implementation, you would call the delete API console.log("Deleting product:", productId) setProducts((prev) => prev.filter((p) => p.id !== productId)) setSuccess("Product deleted successfully") } catch (err) { setError(err instanceof Error ? err.message : "Failed to delete product") } finally { setLoading(false) } } // Bulk actions const handleBulkAction = async (action: "deactivate") => { try { setLoading(true) setError(null) const response = await fetch("/api/products/admin", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ action, productIds: selectedProducts, }), }) if (!response.ok) { throw new Error("Failed to perform bulk action") } await fetchProducts() setSelectedProducts([]) setSuccess( `Successfully ${action}d ${selectedProducts.length} product(s)` ) } catch (err) { setError( err instanceof Error ? err.message : "Failed to perform bulk action" ) } finally { setLoading(false) } } // Filter products based on search const filteredProducts = products.filter( (product) => product.name.toLowerCase().includes(searchTerm.toLowerCase()) || product.description?.toLowerCase().includes(searchTerm.toLowerCase()) ) // Clear alerts useEffect(() => { if (error || success) { const timer = setTimeout(() => { setError(null) setSuccess(null) }, 5000) return () => clearTimeout(timer) } }, [error, success]) return (
{/* Alerts */} {error && ( {error} )} {success && ( {success} )} {/* Header */}

Product Management

Manage your Stripe products and inventory

Create New Product Add a new product to your Stripe inventory.
handleInputChange("name", e.target.value)} placeholder="Enter product name" />
handleInputChange("price", e.target.value)} placeholder="0.00" />