Skip to content

Commit 67e0db6

Browse files
committed
feat: enhance product editing functionality with improved form handling and caching
1 parent 5b971db commit 67e0db6

4 files changed

Lines changed: 221 additions & 200 deletions

File tree

src/lib/server/api/commercify.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
type DiscountDTO,
4343
type UserLoginResponse,
4444
type CreateProductRequest,
45+
type UpdateProductRequest,
4546
type CategoryDTO,
4647
type CreateCategoryRequest,
4748
type UpdateCategoryRequest,
@@ -62,6 +63,7 @@ import type {
6263
} from '$lib/types/checkout';
6364
import type { CreateDiscount, Discount } from '$lib/types/discount';
6465
import type { CommercifyUser } from '$lib/types/user';
66+
import { boolean } from 'zod/v4';
6567

6668
export class CommercifyClient {
6769
private baseUrl: string;
@@ -506,6 +508,7 @@ export class CommercifyClient {
506508
if (params.page) searchParams.append('page', params.page.toString());
507509
if (params.page_size) searchParams.append('page_size', params.page_size.toString());
508510
if (params.currency) searchParams.append('currency', params.currency);
511+
searchParams.append('active', 'all');
509512

510513
const endpoint = `/admin/products?${searchParams.toString()}`;
511514

@@ -671,10 +674,34 @@ export class CommercifyClient {
671674
error: 'No product ID provided'
672675
};
673676
}
677+
678+
console.log('Editing product:', { productId, data });
679+
680+
// Transform data to match API expectations
681+
const apiData: UpdateProductRequest = {
682+
name: data.name,
683+
description: data.description,
684+
currency: data.currency,
685+
category_id: data.categoryId ? parseInt(data.categoryId) : undefined,
686+
images: data.images,
687+
active: data.isActive,
688+
variants: data.variants?.map((variant) => ({
689+
sku: variant.sku,
690+
price: variant.price,
691+
stock: variant.stock,
692+
weight: variant.weight,
693+
attributes: variant.attributes
694+
? Object.entries(variant.attributes).map(([name, value]) => ({ name, value }))
695+
: undefined,
696+
images: variant.images,
697+
is_default: variant.isDefault
698+
}))
699+
};
700+
674701
try {
675702
const response = await this.request<ResponseDTO<ProductDTO>>(`/admin/products/${productId}`, {
676703
method: 'PUT',
677-
body: JSON.stringify(data)
704+
body: JSON.stringify(apiData)
678705
});
679706
if (response.success && response.data) {
680707
return {
@@ -1796,8 +1823,6 @@ export class CommercifyClient {
17961823
try {
17971824
const response = await this.request<ListResponseDTO<CategoryDTO>>('/categories');
17981825

1799-
console.log('Categories response:', response);
1800-
18011826
if (!response.success || !response.data) {
18021827
return {
18031828
success: false,

src/lib/types/product.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,6 @@ export interface Currency {
3939
updatedAt: string | null;
4040
}
4141

42-
export interface UpdateProductVariantInput {
43-
sku?: string;
44-
price?: number /* float64 */;
45-
stock?: number /* int */;
46-
attributes?: { [key: string]: string };
47-
images?: string[];
48-
isDefault?: boolean;
49-
}
50-
5142
export interface CreateProductVariantInput {
5243
sku: string;
5344
price: number /* float64 */;
@@ -68,15 +59,6 @@ export interface CreateProductInput {
6859
variants?: CreateProductVariantInput[];
6960
}
7061

71-
export interface UpdateProductInput {
72-
name?: string;
73-
description?: string;
74-
currency?: string;
75-
categoryId?: string;
76-
images?: string[];
77-
isActive?: boolean;
78-
}
79-
8062
export interface Category {
8163
id: string;
8264
name: string;
@@ -97,3 +79,6 @@ export interface UpdateCategoryInput {
9779
description?: string;
9880
parentId?: string | null;
9981
}
82+
83+
export type UpdateProductInput = Partial<CreateProductInput>;
84+
export type UpdateProductVariantInput = Partial<CreateProductVariantInput>;

src/routes/admin/products/[id]/edit/+page.server.ts

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import type { Actions } from '@sveltejs/kit';
22
import { fail, redirect } from '@sveltejs/kit';
33
import { superValidate } from 'sveltekit-superforms';
44
import { zod } from 'sveltekit-superforms/adapters';
5-
import { productSchema, productVariantSchema } from '$lib/schemas/product.schema';
6-
import type { CreateProductVariantInput } from '$lib/types/product.js';
5+
import { productSchema } from '$lib/schemas/product.schema';
76

87
export const load = async ({ params, locals }) => {
98
const productId = params.id;
@@ -110,65 +109,9 @@ export const actions: Actions = {
110109
}
111110

112111
console.log('Product updated successfully:', result.data);
112+
113+
// Invalidate all cached data to ensure fresh product data is loaded
114+
// This will refresh the product list, product details, and any other cached data
113115
redirect(303, '/admin/products');
114-
},
115-
removeVariant: async ({ request, params, locals }) => {
116-
const productId = params.id;
117-
if (!productId) {
118-
return fail(400, { error: 'Product ID is required' });
119-
}
120-
const { commercify } = locals;
121-
const formData = await request.formData();
122-
const variantId = formData.get('variantId') as string;
123-
if (!variantId) {
124-
return fail(400, { error: 'Variant ID is required' });
125-
}
126-
try {
127-
const result = await commercify.deleteProductVariant(productId, variantId);
128-
if (!result.success) {
129-
console.error('Error removing product variant:', result.error);
130-
return fail(400, {
131-
error: result.error || 'Failed to remove product variant'
132-
});
133-
}
134-
console.log('Product variant removed successfully:', result.data);
135-
redirect(303, `/admin/products/${productId}/edit`);
136-
} catch (error) {
137-
console.error('Error removing product variant:', error);
138-
return fail(500, { error: 'Failed to remove product variant' });
139-
}
140-
},
141-
addVariant: async ({ request, params, locals }) => {
142-
const productId = params.id;
143-
if (!productId) {
144-
return fail(400, { error: 'Product ID is required' });
145-
}
146-
const { commercify } = locals;
147-
const form = await superValidate(request, zod(productVariantSchema));
148-
if (!form.valid) {
149-
return fail(400, { form });
150-
}
151-
console.log('Adding product variant with data:', form.data);
152-
153-
const input: CreateProductVariantInput = {
154-
sku: form.data.sku,
155-
price: form.data.price,
156-
stock: form.data.stock || 0,
157-
weight: form.data.weight || 0,
158-
attributes: form.data.attributes || {},
159-
images: form.data.images || [],
160-
isDefault: form.data.isDefault || false
161-
};
162-
163-
const result = await commercify.addProductVariant(productId, input);
164-
if (!result.success) {
165-
console.error('Error adding product variant:', result.error);
166-
return fail(400, {
167-
form,
168-
error: result.error || 'Failed to add product variant'
169-
});
170-
}
171-
console.log('Product variant added successfully:', result.data);
172-
redirect(303, `/admin/products/${productId}/edit`);
173116
}
174117
};

0 commit comments

Comments
 (0)