diff --git a/src/modules/market/components/CreateProductDialog.vue b/src/modules/market/components/CreateProductDialog.vue index 20707d2..d03cff1 100644 --- a/src/modules/market/components/CreateProductDialog.vue +++ b/src/modules/market/components/CreateProductDialog.vue @@ -2,7 +2,7 @@ - Add New Product to {{ stall?.name }} + {{ product ? 'Edit' : 'Add New' }} Product{{ stall?.name ? ` ${product ? 'in' : 'to'} ${stall.name}` : '' }}
@@ -183,8 +183,7 @@ type="submit" :disabled="isCreating || !isFormValid" > - Creating... - Create Product + {{ submitButtonText }}
@@ -212,7 +211,7 @@ import { FormMessage, } from '@/components/ui/form' import { Package } from 'lucide-vue-next' -import type { NostrmarketAPI, Stall, CreateProductRequest } from '../services/nostrmarketAPI' +import type { NostrmarketAPI, Stall, Product, CreateProductRequest } from '../services/nostrmarketAPI' import { auth } from '@/composables/useAuthService' import { useToast } from '@/core/composables/useToast' import { injectService, SERVICE_TOKENS } from '@/core/di-container' @@ -221,12 +220,14 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' interface Props { isOpen: boolean stall?: Stall | null + product?: Product | null // For editing existing products } const props = defineProps() const emit = defineEmits<{ close: [] created: [product: any] + updated: [product: any] }>() // Services @@ -237,6 +238,13 @@ const toast = useToast() const isCreating = ref(false) const createError = ref(null) +// Computed properties +const isEditMode = computed(() => !!props.product?.id) +const submitButtonText = computed(() => isCreating.value ? + (isEditMode.value ? 'Updating...' : 'Creating...') : + (isEditMode.value ? 'Update Product' : 'Create Product') +) + // Product form schema const productFormSchema = toTypedSchema(z.object({ name: z.string().min(1, "Product name is required").max(100, "Product name must be less than 100 characters"), @@ -274,10 +282,82 @@ const isFormValid = computed(() => meta.value.valid) // Product form submit handler const onSubmit = form.handleSubmit(async (values) => { - await createProduct(values) + await createOrUpdateProduct(values) }) // Methods +const createOrUpdateProduct = async (formData: any) => { + if (isEditMode.value) { + await updateProduct(formData) + } else { + await createProduct(formData) + } +} + +const updateProduct = async (formData: any) => { + const currentUser = auth.currentUser?.value + if (!currentUser?.wallets?.length || !props.product?.id) { + toast.error('No active store or product ID available') + return + } + + const { + name, + description, + price, + quantity, + categories, + images, + active, + use_autoreply, + autoreply_message + } = formData + + isCreating.value = true + createError.value = null + + try { + const productData: Product = { + id: props.product.id, + stall_id: props.product.stall_id, + name, + categories: categories || [], + images: images || [], + price: Number(price), + quantity: Number(quantity), + active, + pending: false, + config: { + description: description || '', + currency: props.stall?.currency || props.product.config.currency, + use_autoreply, + autoreply_message: use_autoreply ? autoreply_message || '' : '', + shipping: props.product.config.shipping || [] + } + } + + const updatedProduct = await nostrmarketAPI.updateProduct( + currentUser.wallets[0].adminkey, + props.product.id, + productData + ) + + // Reset form and close dialog + resetForm() + emit('updated', updatedProduct) + emit('close') + + toast.success(`Product "${name}" updated successfully!`) + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Failed to update product' + console.error('Error updating product:', error) + createError.value = errorMessage + toast.error(`Failed to update product: ${errorMessage}`) + } finally { + isCreating.value = false + } +} + const createProduct = async (formData: any) => { const currentUser = auth.currentUser?.value if (!currentUser?.wallets?.length || !props.stall) { @@ -342,20 +422,31 @@ const createProduct = async (formData: any) => { // Initialize data when dialog opens watch(() => props.isOpen, async (isOpen) => { if (isOpen) { - // Reset form to initial state - resetForm({ - values: { - name: '', - description: '', - price: 0, - quantity: 1, - categories: [], - images: [], - active: true, - use_autoreply: false, - autoreply_message: '' - } - }) + // If editing, pre-populate with existing product data + const initialValues = props.product ? { + name: props.product.name || '', + description: props.product.config?.description || '', + price: props.product.price || 0, + quantity: props.product.quantity || 1, + categories: props.product.categories || [], + images: props.product.images || [], + active: props.product.active ?? true, + use_autoreply: props.product.config?.use_autoreply || false, + autoreply_message: props.product.config?.autoreply_message || '' + } : { + name: '', + description: '', + price: 0, + quantity: 1, + categories: [], + images: [], + active: true, + use_autoreply: false, + autoreply_message: '' + } + + // Reset form with appropriate initial values + resetForm({ values: initialValues }) // Wait for reactivity await nextTick() diff --git a/src/modules/market/components/MerchantStore.vue b/src/modules/market/components/MerchantStore.vue index 92c8fb8..b4c9b6c 100644 --- a/src/modules/market/components/MerchantStore.vue +++ b/src/modules/market/components/MerchantStore.vue @@ -293,7 +293,11 @@
-
@@ -316,8 +320,10 @@ @@ -370,6 +376,7 @@ const isLoadingProducts = ref(false) // Dialog state const showCreateStoreDialog = ref(false) const showCreateProductDialog = ref(false) +const editingProduct = ref(null) // Computed properties const userHasMerchantProfile = computed(() => { @@ -556,6 +563,21 @@ const onProductCreated = async (_product: Product) => { toast.success('Product created successfully!') } +const onProductUpdated = async (_product: Product) => { + await loadStallProducts() + toast.success('Product updated successfully!') +} + +const editProduct = (product: Product) => { + editingProduct.value = product + showCreateProductDialog.value = true +} + +const closeProductDialog = () => { + showCreateProductDialog.value = false + editingProduct.value = null +} + // Lifecycle onMounted(async () => { console.log('Merchant Store component loaded')