126 lines
4 KiB
TypeScript
126 lines
4 KiB
TypeScript
import React from 'react'
|
|
import { createFileRoute } from '@tanstack/react-router'
|
|
import { AppContainer, p as MyText } from 'web-components'
|
|
import CouponForm from '../components/CouponForm'
|
|
import { trpc } from '@/lib/trpc-client'
|
|
import { ErrorToast } from '@/services/toaster'
|
|
import dayjs from 'dayjs'
|
|
|
|
// Ported from common-ui/shared-types (CreateCouponPayload) — @packages/shared
|
|
// does not export it, so the shape is copied here to keep behavior identical.
|
|
interface CreateCouponPayload {
|
|
couponCodes: string[],
|
|
discountPercent?: number,
|
|
flatDiscount?: number,
|
|
minOrder?: number,
|
|
maxValue?: number,
|
|
validTill?: string,
|
|
maxLimitForUser?: number,
|
|
isApplyForAll: boolean,
|
|
isUserBased: boolean,
|
|
targetUsers?: number[],
|
|
productIds?: number[],
|
|
skuIds?: number[],
|
|
applicableUsers?: number[],
|
|
applicableProducts?: number[],
|
|
exclusiveApply?: boolean
|
|
}
|
|
|
|
export const Route = createFileRoute('/dashboard/coupons/$id/edit')({
|
|
component: EditCoupon,
|
|
})
|
|
|
|
function EditCoupon() {
|
|
const { id } = Route.useParams()
|
|
const couponId = parseInt(id as string)
|
|
|
|
const { data: coupon, isLoading, refetch } = trpc.admin.coupon.getById.useQuery({ id: couponId })
|
|
const { refetch: refetchCoupons } = trpc.admin.coupon.getAll.useInfiniteQuery(
|
|
{ limit: 20, search: '' },
|
|
{
|
|
enabled: false,
|
|
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
}
|
|
)
|
|
const { refetch: refetchReservedCoupons } = trpc.admin.coupon.getReservedCoupons.useInfiniteQuery(
|
|
{ limit: 20, search: '' },
|
|
{
|
|
enabled: false,
|
|
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
}
|
|
)
|
|
const updateCoupon = trpc.admin.coupon.update.useMutation()
|
|
|
|
const handleUpdateCoupon = (values: CreateCouponPayload & { isReservedCoupon?: boolean }) => {
|
|
// Transform targetUsers array to targetUser for backend compatibility
|
|
const { targetUsers, ...rest } = values
|
|
const updates = {
|
|
...rest,
|
|
targetUser: targetUsers?.[0] || undefined,
|
|
}
|
|
|
|
// For flat discounts, send the discount value as maxValue too
|
|
if (updates.flatDiscount !== undefined) {
|
|
updates.maxValue = updates.flatDiscount
|
|
}
|
|
|
|
updateCoupon.mutate({ id: couponId, updates }, {
|
|
onSuccess: async () => {
|
|
await refetch()
|
|
await refetchCoupons()
|
|
await refetchReservedCoupons()
|
|
window.alert('Success: Coupon updated successfully')
|
|
window.history.back()
|
|
},
|
|
onError: (error: any) => {
|
|
ErrorToast(error.message || 'Failed to update coupon')
|
|
},
|
|
})
|
|
}
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<AppContainer>
|
|
<div className="flex flex-1 flex-col items-center justify-center">
|
|
<MyText>Loading...</MyText>
|
|
</div>
|
|
</AppContainer>
|
|
)
|
|
}
|
|
|
|
if (!coupon) {
|
|
return (
|
|
<AppContainer>
|
|
<div className="flex flex-1 flex-col items-center justify-center">
|
|
<MyText>Coupon not found</MyText>
|
|
</div>
|
|
</AppContainer>
|
|
)
|
|
}
|
|
|
|
// Transform coupon data for form (targetUser to targetUsers array)
|
|
const initialValues: Partial<CreateCouponPayload & { isReservedCoupon?: boolean }> = {
|
|
couponCodes: coupon.couponCode ? [coupon.couponCode] : [''],
|
|
isUserBased: coupon.isUserBased,
|
|
isApplyForAll: coupon.isApplyForAll,
|
|
targetUsers: coupon.targetUser ? [coupon.targetUser.id] : [],
|
|
discountPercent: coupon.discountPercent ? parseFloat(coupon.discountPercent) : undefined,
|
|
flatDiscount: coupon.flatDiscount ? parseFloat(coupon.flatDiscount) : undefined,
|
|
minOrder: coupon.minOrder ? parseFloat(coupon.minOrder) : undefined,
|
|
maxValue: coupon.maxValue ? parseFloat(coupon.maxValue) : undefined,
|
|
validTill: coupon.validTill ? dayjs(coupon.validTill).format('YYYY-MM-DD') : undefined,
|
|
maxLimitForUser: coupon.maxLimitForUser || undefined,
|
|
skuIds: coupon.skuIds,
|
|
isReservedCoupon: false, // Normal coupons
|
|
}
|
|
|
|
return (
|
|
<AppContainer>
|
|
<CouponForm
|
|
initialValues={initialValues}
|
|
onSubmit={handleUpdateCoupon}
|
|
isLoading={updateCoupon.isPending}
|
|
/>
|
|
</AppContainer>
|
|
)
|
|
}
|