From c690b749d12f6dd7ad0429c6463101e28033cc8a Mon Sep 17 00:00:00 2001 From: amianthus <49116958+SirTenzin@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:46:26 +0100 Subject: [PATCH 01/45] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20ui=20for=20rollove?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../products/product/hooks/useProductData.tsx | 1 + .../product-item/ProductItemConfig.tsx | 18 +- .../product-item/UpdateProductItem.tsx | 4 +- .../advanced-config/AdvancedItemConfig.tsx | 247 ++++++++++++------ 4 files changed, 180 insertions(+), 90 deletions(-) diff --git a/vite/src/views/products/product/hooks/useProductData.tsx b/vite/src/views/products/product/hooks/useProductData.tsx index eea9ffc28..ff0b4887e 100644 --- a/vite/src/views/products/product/hooks/useProductData.tsx +++ b/vite/src/views/products/product/hooks/useProductData.tsx @@ -27,6 +27,7 @@ export const useProductData = ({ data }: { data: any }) => { ...data.product, items: sortProductItems(data.product.items), }; + initialProductRef.current = structuredClone(sortedProduct); setEntityFeatureIds(initEntityFeatureIds(sortedProduct)); setProduct(sortedProduct); diff --git a/vite/src/views/products/product/product-item/ProductItemConfig.tsx b/vite/src/views/products/product/product-item/ProductItemConfig.tsx index 4c88deeeb..c86894644 100644 --- a/vite/src/views/products/product/product-item/ProductItemConfig.tsx +++ b/vite/src/views/products/product/product-item/ProductItemConfig.tsx @@ -63,13 +63,21 @@ export const ProductItemConfig = () => { reset_usage_when_enabled: resetUsageWhenEnabled, }; - const newConfig = !showProration ? undefined : item.config; + // Only manage proration config if this item should show proration + if (showProration) { + // Preserve existing config and manage proration parts + const existingConfig = item.config || {}; + const newConfig = { + ...existingConfig, + on_increase: existingConfig.on_increase, + on_decrease: existingConfig.on_decrease, + }; - if (newConfig) { - newItem.config = newConfig; - } else { - delete newItem.config; + if (Object.keys(newConfig).length > 0) { + newItem.config = newConfig; + } } + // If showProration is false, don't touch the config at all - preserve whatever is there setItem(newItem); } diff --git a/vite/src/views/products/product/product-item/UpdateProductItem.tsx b/vite/src/views/products/product/product-item/UpdateProductItem.tsx index 5a13461b0..ebbc02854 100644 --- a/vite/src/views/products/product/product-item/UpdateProductItem.tsx +++ b/vite/src/views/products/product/product-item/UpdateProductItem.tsx @@ -27,6 +27,8 @@ export default function UpdateProductItem({ const { product, setProduct, features } = useProductContext(); const [showCreateFeature, setShowCreateFeature] = useState(false); + + const handleUpdateProductItem = () => { console.log("Selected Item: ", selectedItem); const validatedItem = validateProductItem({ @@ -83,4 +85,4 @@ export default function UpdateProductItem({ ); -} +}; diff --git a/vite/src/views/products/product/product-item/product-item-config/advanced-config/AdvancedItemConfig.tsx b/vite/src/views/products/product/product-item/product-item-config/advanced-config/AdvancedItemConfig.tsx index ce0643331..bc8d8c302 100644 --- a/vite/src/views/products/product/product-item/product-item-config/advanced-config/AdvancedItemConfig.tsx +++ b/vite/src/views/products/product/product-item/product-item-config/advanced-config/AdvancedItemConfig.tsx @@ -7,99 +7,178 @@ import { OnDecreaseSelect } from "./proration-config/OnDecreaseSelect"; import { OnIncreaseSelect } from "./proration-config/OnIncreaseSelect"; import { shouldShowProrationConfig } from "@/utils/product/productItemUtils"; import { - getFeature, - getFeatureUsageType, + getFeature, + getFeatureUsageType, } from "@/utils/product/entitlementUtils"; -import { FeatureUsageType } from "@autumn/shared"; +import { FeatureUsageType, ProductItemInterval } from "@autumn/shared"; import { Input } from "@/components/ui/input"; export const AdvancedItemConfig = () => { - const { features } = useProductContext(); - const { item, setItem } = useProductItemContext(); - const [isOpen, setIsOpen] = useState(item.usage_limit != null); + const { features } = useProductContext(); + const { item, setItem } = useProductItemContext(); + console.log("item", item); + const [isOpen, setIsOpen] = useState(item.usage_limit != null); - const showProrationConfig = shouldShowProrationConfig({ item, features }); - const usageType = getFeatureUsageType({ item, features }); + const showProrationConfig = shouldShowProrationConfig({ item, features }); + const usageType = getFeatureUsageType({ item, features }); - return ( -
month(s)
+ > + } + /> +month(s)
+ > + } + /> +month(s)
- > - } - /> -month(s)
+ > + } + /> +month(s)
- > - } - /> -month(s)
+ > + } + /> +month(s)
- > - } - /> -- Attach a product to grant access to features -
-+ Attach a product to grant access to features +
++ {entityBalance} + {rolloverAmount > 0 && ( + + {" + "} + {rolloverAmount} (rolled over) + + )} +
++ {totalBalance} + {rolloverAmount > 0 && ( + + {" + "} + {rolloverAmount} (rolled over) + + )} +
++ {cusEnt.balance} + {rolloverAmount > 0 && ( + + {rolloverAmount} (rolled over) + )} + {cusEnt.replaceables.length > 0 && ( + + {` (${cusEnt.replaceables.length} free)`} + + )} +
+- Attach a product to grant access to features -
-+ Attach a product to grant access to features +
+