diff --git a/admin-spa/src/lib/api.ts b/admin-spa/src/lib/api.ts index 67fcac0..9f5dace 100644 --- a/admin-spa/src/lib/api.ts +++ b/admin-spa/src/lib/api.ts @@ -97,6 +97,8 @@ export const OrdersApi = { export const ProductsApi = { search: (search: string, limit = 10) => api.get('/products/search', { search, limit }), + list: (params?: { page?: number; per_page?: number }) => api.get('/products', { params }), + categories: () => api.get('/products/categories'), }; export const CustomersApi = { diff --git a/admin-spa/src/routes/Coupons/CouponForm.tsx b/admin-spa/src/routes/Coupons/CouponForm.tsx index ba7ada6..1217bb6 100644 --- a/admin-spa/src/routes/Coupons/CouponForm.tsx +++ b/admin-spa/src/routes/Coupons/CouponForm.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { useQuery } from '@tanstack/react-query'; import { __ } from '@/lib/i18n'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; @@ -7,6 +8,8 @@ import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Checkbox } from '@/components/ui/checkbox'; import { Button } from '@/components/ui/button'; +import { MultiSelect } from '@/components/ui/multi-select'; +import { ProductsApi } from '@/lib/api'; import type { Coupon, CouponFormData } from '@/lib/api/coupons'; interface CouponFormProps { @@ -31,6 +34,10 @@ export default function CouponForm({ description: initial?.description || '', date_expires: initial?.date_expires || null, individual_use: initial?.individual_use || false, + product_ids: initial?.product_ids || [], + excluded_product_ids: initial?.excluded_product_ids || [], + product_categories: initial?.product_categories || [], + excluded_product_categories: initial?.excluded_product_categories || [], usage_limit: initial?.usage_limit || null, usage_limit_per_user: initial?.usage_limit_per_user || null, free_shipping: initial?.free_shipping || false, @@ -39,6 +46,20 @@ export default function CouponForm({ maximum_amount: initial?.maximum_amount || null, }); + // Fetch products and categories + const { data: productsData } = useQuery({ + queryKey: ['products-list'], + queryFn: () => ProductsApi.list({ per_page: 100 }), + }); + + const { data: categoriesData } = useQuery({ + queryKey: ['product-categories'], + queryFn: () => ProductsApi.categories(), + }); + + const products = (productsData as any)?.rows || []; + const categories = categoriesData || []; + const [submitting, setSubmitting] = useState(false); const handleSubmit = async (e: React.FormEvent) => { @@ -190,6 +211,78 @@ export default function CouponForm({
+ {/* Products */} ++ {__('Products that the coupon will be applied to, or leave blank for all products')} +
++ {__('Products that the coupon will not be applied to')} +
++ {__('Product categories that the coupon will be applied to, or leave blank for all categories')} +
++ {__('Product categories that the coupon will not be applied to')} +
+