fix: sample app

This commit is contained in:
John Yeo
2025-10-21 11:26:19 +01:00
parent ddf07b0ed0
commit 4687022e7d
10 changed files with 56 additions and 47 deletions

View File

@@ -142,6 +142,7 @@ export const productsAreSame = ({
item1: item,
item2: similarItem!,
features,
logDifferences: false,
});
if (!same) {

View File

@@ -105,9 +105,11 @@ const tiersAreSame = (
export const featureItemsAreSame = ({
item1,
item2,
logDifferences = false,
}: {
item1: FeatureItem;
item2: FeatureItem;
logDifferences?: boolean;
}) => {
const checks = {
feature_id: {
@@ -135,15 +137,22 @@ export const featureItemsAreSame = ({
item1.reset_usage_when_enabled == item2.reset_usage_when_enabled,
message: `Reset usage when enabled different: ${item1.reset_usage_when_enabled} !== ${item2.reset_usage_when_enabled}`,
},
config: {
condition: JSON.stringify(item1.config) === JSON.stringify(item2.config),
message: `Config different: ${JSON.stringify(item1.config)} !== ${JSON.stringify(item2.config)}`,
rollover_config: {
condition: rolloversAreSame({
rollover1: item1.config?.rollover || undefined,
rollover2: item2.config?.rollover || undefined,
}),
message: `Rollover config different: ${JSON.stringify(item1.config?.rollover)} !== ${JSON.stringify(item2.config?.rollover)}`,
},
// config: {
// condition: JSON.stringify(item1.config) === JSON.stringify(item2.config),
// message: `Config different: ${JSON.stringify(item1.config)} !== ${JSON.stringify(item2.config)}`,
// },
};
const same = Object.values(checks).every((d) => d.condition);
if (!same) {
if (!same && logDifferences) {
console.log(
"Feature items different:",
Object.values(checks)
@@ -158,16 +167,18 @@ export const featureItemsAreSame = ({
export const priceItemsAreSame = ({
item1,
item2,
logDifferences = false,
}: {
item1: PriceItem;
item2: PriceItem;
logDifferences?: boolean;
}) => {
const same =
item1.price === item2.price &&
item1.interval == item2.interval &&
(item1.interval_count || 1) == (item2.interval_count || 1);
if (!same) {
if (!same && logDifferences) {
console.log(`Price items different: ${item1.price}`);
}
@@ -210,9 +221,11 @@ const rolloversAreSame = ({
export const featurePriceItemsAreSame = ({
item1,
item2,
logDifferences = false,
}: {
item1: FeaturePriceItem;
item2: FeaturePriceItem;
logDifferences?: boolean;
}) => {
// console.log("Item 1 config:", item1.config);
// console.log("Item 2 config:", item2.config);
@@ -297,7 +310,7 @@ export const featurePriceItemsAreSame = ({
const pricesChanged = Object.values(pricesSame).some((d) => !d.condition);
if (!same) {
if (!same && logDifferences) {
console.log(
"Feature price items different:",
Object.values(entsSame)
@@ -319,10 +332,12 @@ export const itemsAreSame = ({
item1,
item2,
features,
logDifferences = false,
}: {
item1: ProductItem;
item2: ProductItem;
features?: Feature[];
logDifferences?: boolean;
}) => {
// 1. If feature item
let same = false;
@@ -339,6 +354,7 @@ export const itemsAreSame = ({
same = featureItemsAreSame({
item1: item1 as FeatureItem,
item2: item2 as FeatureItem,
logDifferences,
});
pricesChanged = false;
@@ -356,6 +372,7 @@ export const itemsAreSame = ({
featurePriceItemsAreSame({
item1: item1 as FeaturePriceItem,
item2: item2 as FeaturePriceItem,
logDifferences,
});
same = same_;
@@ -377,6 +394,7 @@ export const itemsAreSame = ({
same = priceItemsAreSame({
item1: item1 as PriceItem,
item2: item2 as PriceItem,
logDifferences,
});
if (!same) {
pricesChanged = true;

View File

@@ -190,6 +190,7 @@ export const productsAreSame = ({
item1: item,
item2: similarItem,
features,
logDifferences: false,
});
if (!same) {

View File

@@ -73,7 +73,7 @@ export default function PricingTablePreview({
} else if (productCount === 2) {
return "flex flex-col gap-6 max-w-2xl mx-auto px-4 sm:grid sm:grid-cols-2 sm:flex-none"; // Vertical on mobile, 2 columns on sm+
} else {
return "flex flex-col gap-6 max-w-7xl mx-auto px-4 sm:grid md:grid-cols-2 xl:grid-cols-3 sm:flex-none"; // Vertical on mobile, 2 columns on sm+, 3 on lg+
return "flex flex-col gap-6 max-w-7xl mx-auto px-4 sm:grid lg:grid-cols-2 2xl:grid-cols-3 sm:flex-none"; // Vertical on mobile, 2 columns on sm+, 3 on lg+
}
};

View File

@@ -33,8 +33,10 @@ export const OnboardingStepRenderer = () => {
const setProduct = useProductStore((s) => s.setProduct);
const sheetType = useSheetStore((s) => s.type);
const itemId = useSheetStore((s) => s.itemId);
const [trackResponse, setTrackResponse] = useState<any>(null);
const [checkResponse, setCheckResponse] = useState<any>(null);
const [lastUsedFeatureId, setLastUsedFeatureId] = useState<
string | undefined
>(undefined);

View File

@@ -1,6 +1,6 @@
import { FeatureType } from "@autumn/shared";
import { ArrowRightIcon } from "@phosphor-icons/react";
import { useCustomer } from "autumn-js/react";
import { PaywallDialog, useCustomer } from "autumn-js/react";
import { useState } from "react";
import { Button } from "@/components/v2/buttons/Button";
import { Input } from "@/components/v2/inputs/Input";
@@ -104,11 +104,11 @@ export const AvailableFeatures = ({
const featureId = customer?.features[x].id;
// Check the feature access
const { data: checkResponse, error: checkError } =
await check({
featureId: featureId,
requiredBalance: value,
});
const { data: checkResponse, error: checkError } = check({
featureId: featureId,
requiredBalance: value,
dialog: PaywallDialog,
});
if (!checkError && checkResponse && onCheckSuccess) {
onCheckSuccess(checkResponse);
@@ -118,6 +118,8 @@ export const AvailableFeatures = ({
onFeatureUsed(featureId);
}
if (!checkResponse?.allowed) return;
// Track the usage
const { data, error } = await track({
featureId: featureId,
@@ -135,8 +137,8 @@ export const AvailableFeatures = ({
))
) : (
<span className="text-sm text-muted-foreground">
Your current plan doesn't have any features. Try purchasing a
plan in the preview first.
Your current plan doesn't have any features. Try purchasing a plan
in the preview first.
</span>
)}
</div>

View File

@@ -152,10 +152,7 @@ export const QuickStartCodeGroup = ({
snippets={snippets.track}
trackResponse={trackResponse}
/>
<CodeSnippetSection
title="Create checkout session"
snippets={snippets.checkout}
/>
<CodeSnippetSection title="Checkout" snippets={snippets.checkout} />
<CustomerSection />
</div>
</SheetSection>

View File

@@ -11,10 +11,14 @@ export const getCodeSnippets = (
allowed: {
react: `import { useCustomer } from 'autumn-js/react';
const { allowed } = useCustomer();
const { check } = useCustomer();
const handleCheckFeature = async () => {
if ( !allowed({ featureId: '${actualFeatureId}' }) ) {
const { data } = await check({
featureId: '${actualFeatureId}',
requiredQuantity: 1
});
if (!data?.allowed) {
alert('Feature not allowed');
}
}`,
@@ -24,7 +28,7 @@ const autumn = new Autumn({
apiKey: process.env.AUTUMN_API_KEY
});
const allowed = await autumn.check({
const { data, error } = await autumn.check({
customerId: 'cust_123',
featureId: '${actualFeatureId}'
});`,

View File

@@ -2,7 +2,6 @@ import { UserIcon } from "@phosphor-icons/react";
import { useState } from "react";
import { toast } from "sonner";
import { AdminHover } from "@/components/general/AdminHover";
import { Badge } from "@/components/v2/badges/Badge";
import { IconBadge } from "@/components/v2/badges/IconBadge";
import V2Breadcrumb from "@/components/v2/breadcrumb";
import { Button } from "@/components/v2/buttons/Button";
@@ -18,7 +17,6 @@ import { useSheetStore } from "@/hooks/stores/useSheetStore";
import { useAxiosInstance } from "@/services/useAxiosInstance";
import { getBackendErr } from "@/utils/genUtils";
import { isOneOffProduct } from "@/utils/product/priceUtils";
import { PlanTypeBadge } from "../../components/PlanTypeBadge";
import { useMigrationsQuery } from "../../product/hooks/queries/useMigrationsQuery.tsx.tsx";
import { useProductCountsQuery } from "../../product/hooks/queries/useProductCountsQuery";
import {
@@ -143,12 +141,12 @@ export const EditPlanHeader = () => {
size="sm"
/>
)}
{product.is_default && <Badge variant="muted">Default</Badge>}
{product.is_add_on && <Badge variant="muted">Add-on</Badge>}
{/* {product.is_default && <Badge variant="muted">Default</Badge>}
{product.is_add_on && <Badge variant="muted">Add-on</Badge>} */}
<IconBadge variant="muted" icon={<UserIcon />}>
{counts?.active || 0}
</IconBadge>
<PlanTypeBadge product={product} />
{/* <PlanTypeBadge product={product} /> */}
<PlanToolbar />
</div>

View File

@@ -52,28 +52,14 @@ export const PlanCardToolbar = ({
aria-label="Edit plan"
variant="muted"
disabled={editDisabled}
size="sm"
className={cn(isEditingPlan && "btn-secondary-active !opacity-100 ")}
// size="sm"
className={cn(
// "text-body",
isEditingPlan && "btn-secondary-active !opacity-100 ",
)}
>
Edit Details
Plan Details
</IconButton>
{/* {product?.archived ? (
<Button variant="muted" onClick={() => setDeleteOpen(true)} size="sm">
Archived
</Button>
) : (
<IconButton
icon={<TrashIcon />}
onClick={() => setDeleteOpen(true)}
aria-label="Delete plan"
variant="muted"
iconOrientation="center"
disabled={deleteDisabled}
title={deleteDisabled && deleteTooltip ? deleteTooltip : undefined}
className={cn(deleteDisabled && "opacity-50 cursor-not-allowed")}
/>
)} */}
</div>
</>
);