diff --git a/server/src/internal/customers/internalHandlers/handleGetCustomer.ts b/server/src/internal/customers/internalHandlers/handleGetCustomer.ts
index 078297ebe..c62f44126 100644
--- a/server/src/internal/customers/internalHandlers/handleGetCustomer.ts
+++ b/server/src/internal/customers/internalHandlers/handleGetCustomer.ts
@@ -1,8 +1,14 @@
-import { CusProductStatus, CustomerExpand, Scopes } from "@autumn/shared";
+import {
+ CusProductStatus,
+ CustomerExpand,
+ type FullCusProduct,
+ Scopes,
+} from "@autumn/shared";
import { getTestClockFrozenTimeMs } from "@/external/stripe/testClocks/utils/convertStripeTestClock";
import { createRoute } from "@/honoMiddlewares/routeHandler";
import { CusService } from "@/internal/customers/CusService";
import { getCusAutoTopupPurchaseLimits } from "@/internal/customers/cusUtils/cusResponseUtils/getCusAutoTopupPurchaseLimits";
+import { getCusRewards } from "@/internal/customers/cusUtils/cusResponseUtils/getCusRewards";
/**
* Internal route for get full customer object.
@@ -10,6 +16,9 @@ import { getCusAutoTopupPurchaseLimits } from "@/internal/customers/cusUtils/cus
* Note: schedules are NOT hydrated here. Dashboard consumers that need the
* customer's persisted schedule must fetch it separately via
* `GET /customers/:customer_id/schedule`.
+ *
+ * Supports optional `?expand=rewards` query param to lazily fetch
+ * per-subscription discount data from Stripe.
*/
export const handleGetCustomer = createRoute({
scopes: [Scopes.Customers.Read],
@@ -17,11 +26,17 @@ export const handleGetCustomer = createRoute({
const ctx = c.get("ctx");
const { customer_id } = c.req.param();
+ const expandParam = c.req.query("expand");
+ const extraExpands = expandParam
+ ? (expandParam.split(",").filter(Boolean) as CustomerExpand[])
+ : [];
+ const expand = [CustomerExpand.Invoices, ...extraExpands];
+
const fullCus = await CusService.getFull({
ctx,
idOrInternalId: customer_id,
withEntities: true,
- expand: [CustomerExpand.Invoices],
+ expand,
inStatuses: [
CusProductStatus.Active,
CusProductStatus.PastDue,
@@ -30,23 +45,34 @@ export const handleGetCustomer = createRoute({
],
});
- const [testClockFrozenTimeMs, autoTopupsWithLimits] = await Promise.all([
- getTestClockFrozenTimeMs({
- ctx,
- stripeCustomerId: fullCus.processor?.id,
- }),
- getCusAutoTopupPurchaseLimits({
- ctx,
- internalCustomerId: fullCus.internal_id,
- autoTopupsConfig: fullCus.auto_topups,
- expand: [CustomerExpand.AutoTopupsPurchaseLimit],
- }),
- ]);
+ const [testClockFrozenTimeMs, autoTopupsWithLimits, rewards] =
+ await Promise.all([
+ getTestClockFrozenTimeMs({
+ ctx,
+ stripeCustomerId: fullCus.processor?.id,
+ }),
+ getCusAutoTopupPurchaseLimits({
+ ctx,
+ internalCustomerId: fullCus.internal_id,
+ autoTopupsConfig: fullCus.auto_topups,
+ expand: [CustomerExpand.AutoTopupsPurchaseLimit],
+ }),
+ getCusRewards({
+ org: ctx.org,
+ env: ctx.env,
+ fullCus,
+ subIds: fullCus.customer_products.flatMap(
+ (cp: FullCusProduct) => cp.subscription_ids || [],
+ ),
+ expand,
+ }),
+ ]);
return c.json({
customer: {
...fullCus,
auto_topups: autoTopupsWithLimits ?? fullCus.auto_topups,
+ rewards: rewards ?? undefined,
},
test_clock_frozen_time_ms: testClockFrozenTimeMs,
});
diff --git a/vite/src/components/forms/attach-v2/components/AttachDiscountRow.tsx b/vite/src/components/forms/attach-v2/components/AttachDiscountRow.tsx
index c525dbefa..a56240e95 100644
--- a/vite/src/components/forms/attach-v2/components/AttachDiscountRow.tsx
+++ b/vite/src/components/forms/attach-v2/components/AttachDiscountRow.tsx
@@ -1,110 +1,25 @@
-import { XIcon } from "@phosphor-icons/react";
-import { CheckIcon } from "lucide-react";
-import { IconButton } from "@/components/v2/buttons/IconButton";
-import { SearchableSelect } from "@/components/v2/selects/SearchableSelect";
-import { useRewardsQuery } from "@/hooks/queries/useRewardsQuery";
-import { useStripeCouponsQuery } from "@/hooks/queries/useStripeCouponsQuery";
+import { DiscountRow } from "@/components/forms/shared/discount-row/DiscountRow";
import { useAttachFormContext } from "../context/AttachFormProvider";
-import { buildDiscountOptions } from "../utils/discountOptionUtils";
import { removeDiscount, updateDiscount } from "../utils/discountUtils";
-interface AttachDiscountRowProps {
- index: number;
-}
-
-export function AttachDiscountRow({ index }: AttachDiscountRowProps) {
+export function AttachDiscountRow({ index }: { index: number }) {
const { form, formValues, product } = useAttachFormContext();
- const { rewards, rewardPrograms } = useRewardsQuery();
- const { stripeCoupons } = useStripeCouponsQuery();
-
const discounts = formValues.discounts;
- const discount = discounts[index];
-
- if (!discount) return null;
-
- const allOptions = buildDiscountOptions({
- rewards,
- rewardPrograms,
- stripeCoupons,
- productId: product?.id,
- });
-
- // Get reward IDs already selected in other rows
- const selectedRewardIds = discounts
- .filter((d, i) => i !== index && "reward_id" in d)
- .map((d) => ("reward_id" in d ? d.reward_id : ""))
- .filter(Boolean);
-
- // Filter out already-selected options
- const availableOptions = allOptions.filter(
- (o) => !selectedRewardIds.includes(o.id),
- );
-
- const handleRewardChange = (rewardId: string) => {
- form.setFieldValue(
- "discounts",
- updateDiscount(discounts, index, { reward_id: rewardId }),
- );
- };
-
- const handleRemove = () => {
- form.setFieldValue("discounts", removeDiscount(discounts, index));
- };
-
- const currentRewardId =
- "reward_id" in discount ? (discount.reward_id ?? "") : "";
return (
-
- {/* Reward select */}
-
- o.id}
- getOptionLabel={(o) => o.label}
- placeholder="Select discount..."
- searchable
- searchPlaceholder="Search discounts..."
- emptyText="No discounts found"
- triggerClassName="h-7 px-2 text-xs border-0 shadow-none bg-transparent hover:bg-muted/50"
- renderOption={(option, isSelected) => (
- <>
- {option.label}
- {option.sublabel && (
-
- {option.sublabel}
-
- )}
- {isSelected && }
- >
- )}
- renderValue={(option) => {
- if (!option)
- return Select discount...;
- return (
-
- {option.label}
- {option.sublabel && (
-
- {option.sublabel}
-
- )}
-
- );
- }}
- />
-
-
- {/* Remove button */}
-
}
- className="shrink-0 text-t3 hover:text-red-500"
- />
-
+ {
+ form.setFieldValue(
+ "discounts",
+ updateDiscount(discounts, index, { reward_id: rewardId }),
+ );
+ }}
+ onRemove={() => {
+ form.setFieldValue("discounts", removeDiscount(discounts, index));
+ }}
+ />
);
}
diff --git a/vite/src/components/forms/shared/discount-row/DiscountRow.tsx b/vite/src/components/forms/shared/discount-row/DiscountRow.tsx
new file mode 100644
index 000000000..0f634e5ca
--- /dev/null
+++ b/vite/src/components/forms/shared/discount-row/DiscountRow.tsx
@@ -0,0 +1,102 @@
+import { XIcon } from "@phosphor-icons/react";
+import { CheckIcon } from "lucide-react";
+import {
+ buildDiscountOptions,
+ type DiscountOption,
+} from "@/components/forms/attach-v2/utils/discountOptionUtils";
+import type { FormDiscount } from "@/components/forms/attach-v2/utils/discountUtils";
+import { IconButton } from "@/components/v2/buttons/IconButton";
+import { SearchableSelect } from "@/components/v2/selects/SearchableSelect";
+import { useRewardsQuery } from "@/hooks/queries/useRewardsQuery";
+import { useStripeCouponsQuery } from "@/hooks/queries/useStripeCouponsQuery";
+
+export function DiscountRow({
+ discounts,
+ index,
+ productId,
+ onUpdate,
+ onRemove,
+}: {
+ discounts: FormDiscount[];
+ index: number;
+ productId: string | undefined;
+ onUpdate: ({ rewardId }: { rewardId: string }) => void;
+ onRemove: () => void;
+}) {
+ const { rewards, rewardPrograms } = useRewardsQuery();
+ const { stripeCoupons } = useStripeCouponsQuery();
+
+ const discount = discounts[index];
+ if (!discount) return null;
+
+ const allOptions = buildDiscountOptions({
+ rewards,
+ rewardPrograms,
+ stripeCoupons,
+ productId,
+ });
+
+ const selectedRewardIds = discounts
+ .filter((d, i) => i !== index && "reward_id" in d)
+ .map((d) => ("reward_id" in d ? d.reward_id : ""))
+ .filter(Boolean);
+
+ const availableOptions = allOptions.filter(
+ (o) => !selectedRewardIds.includes(o.id),
+ );
+
+ const currentRewardId =
+ "reward_id" in discount ? (discount.reward_id ?? "") : "";
+
+ return (
+
+
+ onUpdate({ rewardId })}
+ options={availableOptions}
+ getOptionValue={(o: DiscountOption) => o.id}
+ getOptionLabel={(o: DiscountOption) => o.label}
+ placeholder="Select discount..."
+ searchable
+ searchPlaceholder="Search discounts..."
+ emptyText="No discounts found"
+ triggerClassName="h-7 px-2 text-xs border-0 shadow-none bg-transparent hover:bg-muted/50"
+ renderOption={(option: DiscountOption, isSelected: boolean) => (
+ <>
+ {option.label}
+ {option.sublabel && (
+
+ {option.sublabel}
+
+ )}
+ {isSelected && }
+ >
+ )}
+ renderValue={(option: DiscountOption | undefined) => {
+ if (!option)
+ return Select discount...;
+ return (
+
+ {option.label}
+ {option.sublabel && (
+
+ {option.sublabel}
+
+ )}
+
+ );
+ }}
+ />
+
+
+
}
+ className="shrink-0 text-t3 hover:text-red-500"
+ />
+
+ );
+}
diff --git a/vite/src/components/forms/update-subscription-v2/components/PriceDisplay.tsx b/vite/src/components/forms/update-subscription-v2/components/PriceDisplay.tsx
index cb2bc2d08..3d558ba47 100644
--- a/vite/src/components/forms/update-subscription-v2/components/PriceDisplay.tsx
+++ b/vite/src/components/forms/update-subscription-v2/components/PriceDisplay.tsx
@@ -52,7 +52,9 @@ export function PriceDisplay({ product, currency }: PriceDisplayProps) {
return (
- {priceDisplay.formattedPrice}
+
+ {priceDisplay.formattedPrice}
+
{priceDisplay.intervalText}
);
diff --git a/vite/src/components/forms/update-subscription-v2/components/UpdateSubscriptionAdvancedSection.tsx b/vite/src/components/forms/update-subscription-v2/components/UpdateSubscriptionAdvancedSection.tsx
index 9387b46de..e49f3895d 100644
--- a/vite/src/components/forms/update-subscription-v2/components/UpdateSubscriptionAdvancedSection.tsx
+++ b/vite/src/components/forms/update-subscription-v2/components/UpdateSubscriptionAdvancedSection.tsx
@@ -1,59 +1,127 @@
+import { PlusIcon } from "@phosphor-icons/react";
+import { AnimatePresence, motion } from "motion/react";
+import {
+ addDiscount,
+ removeDiscount,
+ updateDiscount,
+} from "@/components/forms/attach-v2/utils/discountUtils";
import {
AdvancedSection,
ConfigRow,
} from "@/components/forms/shared/advanced-section";
+import { DiscountRow } from "@/components/forms/shared/discount-row/DiscountRow";
import { Switch } from "@/components/ui/switch";
+import { IconButton } from "@/components/v2/buttons/IconButton";
import { useUpdateSubscriptionFormContext } from "../context/UpdateSubscriptionFormProvider";
export function UpdateSubscriptionAdvancedSection() {
const { form, formValues, formContext } = useUpdateSubscriptionFormContext();
- const { billingBehavior, resetBillingCycle, noBillingChanges } = formValues;
- const { customerProduct } = formContext;
+ const { billingBehavior, resetBillingCycle, noBillingChanges, discounts } =
+ formValues;
+ const { customerProduct, product } = formContext;
const hasActiveSubscription =
(customerProduct.subscription_ids?.length ?? 0) > 0;
const isProrate = billingBehavior !== "none";
- if (!hasActiveSubscription) return null;
+ const handleAddDiscount = () => {
+ form.setFieldValue("discounts", addDiscount(discounts));
+ };
return (
- form.setFieldValue("billingBehavior", checked ? null : "none")
+ }
+ className="text-t3"
+ >
+ Add
+
+ }
+ >
+ {discounts.length > 0 && (
+
+
+ {discounts.map((discount, index) => (
+
+ {
+ form.setFieldValue(
+ "discounts",
+ updateDiscount(discounts, index, {
+ reward_id: rewardId,
+ }),
+ );
+ }}
+ onRemove={() => {
+ form.setFieldValue(
+ "discounts",
+ removeDiscount(discounts, index),
+ );
+ }}
+ />
+
+ ))}
+
+
+ )}
+
+
+ {hasActiveSubscription && (
+ <>
+
+ form.setFieldValue("billingBehavior", checked ? null : "none")
+ }
+ />
}
/>
- }
- />
-
- form.setFieldValue("noBillingChanges", !!checked)
+
+ form.setFieldValue("noBillingChanges", !!checked)
+ }
+ />
}
/>
- }
- />
-
- form.setFieldValue("resetBillingCycle", !!checked)
+
+ form.setFieldValue("resetBillingCycle", !!checked)
+ }
+ />
}
/>
- }
- />
+ >
+ )}
);
}
diff --git a/vite/src/components/forms/update-subscription-v2/hooks/useHasSubscriptionChanges.ts b/vite/src/components/forms/update-subscription-v2/hooks/useHasSubscriptionChanges.ts
index 999fb4eb6..8a0a75942 100644
--- a/vite/src/components/forms/update-subscription-v2/hooks/useHasSubscriptionChanges.ts
+++ b/vite/src/components/forms/update-subscription-v2/hooks/useHasSubscriptionChanges.ts
@@ -36,6 +36,8 @@ export function useHasSubscriptionChanges({
if (formValues.resetBillingCycle) return true;
if (formValues.noBillingChanges) return true;
+ if (formValues.discounts?.length > 0) return true;
+
const trialChanges = generateTrialChanges({
customerProduct,
removeTrial: formValues.removeTrial,
@@ -83,6 +85,7 @@ export function useHasSubscriptionChanges({
formValues.billingBehavior,
formValues.resetBillingCycle,
formValues.noBillingChanges,
+ formValues.discounts,
initialBillingBehavior,
formValues.removeTrial,
formValues.trialLength,
diff --git a/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionForm.ts b/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionForm.ts
index a5e74ae2c..3e8376125 100644
--- a/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionForm.ts
+++ b/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionForm.ts
@@ -56,6 +56,7 @@ export function useUpdateSubscriptionForm({
refundBehavior: null,
refundAmount: null,
noBillingChanges: false,
+ discounts: [],
...defaultOverrides,
} as UpdateSubscriptionForm,
validators: {
diff --git a/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionRequestBody.ts b/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionRequestBody.ts
index 46c99952b..8fa9b7c31 100644
--- a/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionRequestBody.ts
+++ b/vite/src/components/forms/update-subscription-v2/hooks/useUpdateSubscriptionRequestBody.ts
@@ -120,8 +120,13 @@ export function useUpdateSubscriptionRequestBody({
refundBehavior,
refundAmount,
noBillingChanges,
+ discounts,
} = formValues;
+ const validDiscounts = discounts?.length
+ ? discounts.filter((d) => "reward_id" in d && d.reward_id)
+ : undefined;
+
const base = {
customer_id: customerId ?? "",
product_id: product?.id,
@@ -172,6 +177,7 @@ export function useUpdateSubscriptionRequestBody({
billing_behavior: billingBehavior || undefined,
billing_cycle_anchor: resetBillingCycle ? "now" : undefined,
no_billing_changes: noBillingChanges || undefined,
+ discounts: validDiscounts,
};
}, [
form.store,
diff --git a/vite/src/components/forms/update-subscription-v2/updateSubscriptionFormSchema.ts b/vite/src/components/forms/update-subscription-v2/updateSubscriptionFormSchema.ts
index 4d03d4b05..9c20f729d 100644
--- a/vite/src/components/forms/update-subscription-v2/updateSubscriptionFormSchema.ts
+++ b/vite/src/components/forms/update-subscription-v2/updateSubscriptionFormSchema.ts
@@ -6,6 +6,7 @@ import {
} from "@autumn/shared";
import { z } from "zod/v4";
+import type { FormDiscount } from "@/components/forms/attach-v2/utils/discountUtils";
import { RefundBehaviorSchema } from "@/components/forms/update-subscription-v2/types/refundBehaviourSchema";
export const UpdateSubscriptionFormSchema = z.object({
@@ -27,6 +28,7 @@ export const UpdateSubscriptionFormSchema = z.object({
refundBehavior: RefundBehaviorSchema.nullable(),
refundAmount: z.enum(["prorated", "full"]).nullable(),
noBillingChanges: z.boolean(),
+ discounts: z.custom(),
});
export type UpdateSubscriptionForm = z.infer<
diff --git a/vite/src/hooks/queries/useCusRewardsQuery.tsx b/vite/src/hooks/queries/useCusRewardsQuery.tsx
new file mode 100644
index 000000000..0548dabb5
--- /dev/null
+++ b/vite/src/hooks/queries/useCusRewardsQuery.tsx
@@ -0,0 +1,57 @@
+import type { ApiDiscount } from "@autumn/shared";
+import { useQuery } from "@tanstack/react-query";
+import { useCallback, useMemo } from "react";
+import { useParams } from "react-router";
+import { useQueryKeyFactory } from "@/hooks/common/useQueryKeyFactory";
+import { useAxiosInstance } from "@/services/useAxiosInstance";
+
+export const useCusRewardsQuery = ({
+ enabled = true,
+}: {
+ enabled?: boolean;
+} = {}) => {
+ const { customer_id } = useParams();
+ const axiosInstance = useAxiosInstance();
+ const buildKey = useQueryKeyFactory();
+
+ const fetcher = async () => {
+ if (!customer_id) return { customer: { rewards: { discounts: [] } } };
+
+ const { data } = await axiosInstance.get(
+ `/customers/${customer_id}?expand=rewards`,
+ );
+ return data;
+ };
+
+ const { data, isLoading, error, refetch } = useQuery({
+ queryKey: buildKey(["customer-rewards", customer_id]),
+ queryFn: fetcher,
+ enabled: enabled && !!customer_id,
+ staleTime: 5 * 60 * 1000,
+ });
+
+ const discounts: ApiDiscount[] = useMemo(
+ () => data?.customer?.rewards?.discounts ?? [],
+ [data],
+ );
+
+ const getDiscountsForSubscription = useCallback(
+ ({ subscriptionIds }: { subscriptionIds: string[] }) => {
+ if (subscriptionIds.length === 0) return [];
+ return discounts.filter(
+ (discount) =>
+ discount.subscription_id &&
+ subscriptionIds.includes(discount.subscription_id),
+ );
+ },
+ [discounts],
+ );
+
+ return {
+ discounts,
+ getDiscountsForSubscription,
+ isLoading,
+ error,
+ refetch,
+ };
+};
diff --git a/vite/src/views/customers2/components/sheets/SubscriptionDetailSheet.tsx b/vite/src/views/customers2/components/sheets/SubscriptionDetailSheet.tsx
index 633f7e3da..5dfb539d7 100644
--- a/vite/src/views/customers2/components/sheets/SubscriptionDetailSheet.tsx
+++ b/vite/src/views/customers2/components/sheets/SubscriptionDetailSheet.tsx
@@ -1,3 +1,4 @@
+import type { ApiDiscount } from "@autumn/shared";
import {
CusProductStatus,
type Entity,
@@ -19,6 +20,7 @@ import {
Info,
SubtractIcon,
TagIcon,
+ TicketIcon,
TimerIcon,
XCircle,
} from "@phosphor-icons/react";
@@ -30,6 +32,7 @@ import { MiniCopyButton } from "@/components/v2/buttons/CopyButton";
import { IconButton } from "@/components/v2/buttons/IconButton";
import { InfoRow } from "@/components/v2/InfoRow";
import { SheetHeader, SheetSection } from "@/components/v2/sheets/InlineSheet";
+import { useCusRewardsQuery } from "@/hooks/queries/useCusRewardsQuery";
import { useOrgStripeQuery } from "@/hooks/queries/useOrgStripeQuery";
import { useProductVersionQuery } from "@/hooks/queries/useProductVersionQuery";
import { usePrepaidItems } from "@/hooks/stores/useProductStore";
@@ -44,6 +47,15 @@ import { BasePriceDisplay } from "@/views/products/plan/components/plan-card/Bas
import { PlanFeatureRow } from "@/views/products/plan/components/plan-card/PlanFeatureRow";
import { CustomerProductsStatus } from "../table/customer-products/CustomerProductsStatus";
+function formatDiscountLabel({ discount }: { discount: ApiDiscount }): string {
+ const value =
+ discount.type === "percentage_discount"
+ ? `${discount.discount_value}% off`
+ : `${discount.discount_value / 100} ${discount.currency?.toUpperCase() ?? ""} off`;
+
+ return discount.name ? `${discount.name} (${value})` : value;
+}
+
function SubscriptionDetailItems({
items,
product,
@@ -53,9 +65,7 @@ function SubscriptionDetailItems({
items: ProductItem[];
product: FrontendProduct;
prepaidDisplayQuantities: Record;
- adminIds?: import(
- "@/components/forms/shared/admin/AdminPlanIdsTooltip"
- ).AdminPlanIds;
+ adminIds?: import("@/components/forms/shared/admin/AdminPlanIdsTooltip").AdminPlanIds;
}) {
const sortedItems = useMemo(() => sortPlanItems({ items }), [items]);
const { visibleItems, collapsedBooleanItems } = useMemo(
@@ -114,6 +124,7 @@ export function SubscriptionDetailSheet() {
const setSheet = useSheetStore((s) => s.setSheet);
// Get customer product and productV2 by itemId
const { cusProduct, productV2 } = useSubscriptionById({ itemId });
+ const { getDiscountsForSubscription } = useCusRewardsQuery();
// Prefetch product version data so the update sheet has it cached immediately
useProductVersionQuery({ productId: productV2?.id });
@@ -142,6 +153,10 @@ export function SubscriptionDetailSheet() {
);
const isScheduled = cusProduct.status === CusProductStatus.Scheduled;
+ const subscriptionDiscounts = getDiscountsForSubscription({
+ subscriptionIds: cusProduct.subscription_ids ?? [],
+ });
+
const canCancel = !isExpired;
const canUpdate = !isExpired && !isScheduled;
const prepaidDisplayQuantities = backendToDisplayQuantity({
@@ -310,6 +325,15 @@ export function SubscriptionDetailSheet() {
}
/>
+ {subscriptionDiscounts.map((discount: ApiDiscount) => (
+ }
+ label="Coupon"
+ value={formatDiscountLabel({ discount })}
+ />
+ ))}
+
}
label="Started"
diff --git a/vite/src/views/customers2/customer/CustomerView2.tsx b/vite/src/views/customers2/customer/CustomerView2.tsx
index a457d6d06..17231943a 100644
--- a/vite/src/views/customers2/customer/CustomerView2.tsx
+++ b/vite/src/views/customers2/customer/CustomerView2.tsx
@@ -13,6 +13,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/v2/tooltips/Tooltip";
+import { useCusRewardsQuery } from "@/hooks/queries/useCusRewardsQuery";
import { useSheetStore } from "@/hooks/stores/useSheetStore";
import { useEntity } from "@/hooks/stores/useSubscriptionStore";
import { useIsMobile } from "@/hooks/useIsMobile";
@@ -46,6 +47,7 @@ export default function CustomerView2() {
} = useCusQuery();
useCusReferralQuery();
+ useCusRewardsQuery();
const { entityId, setEntityId } = useEntity();
const sheetType = useSheetStore((s) => s.type);