diff --git a/resources/js/admin/mobile/PackageShopPage.tsx b/resources/js/admin/mobile/PackageShopPage.tsx
index 68f1e5c..513be5e 100644
--- a/resources/js/admin/mobile/PackageShopPage.tsx
+++ b/resources/js/admin/mobile/PackageShopPage.tsx
@@ -182,8 +182,8 @@ function PackageShopCard({
const { t } = useTranslation('management');
const statusLabel = getPackageStatusLabel({ t, isActive, owned });
- const isSubdued = Boolean(isDowngrade && !isActive);
- const canSelect = canSelectPackage(isDowngrade, isActive);
+ const isSubdued = Boolean((isDowngrade || !isUpgrade) && !isActive);
+ const canSelect = canSelectPackage(isUpgrade, isActive);
return (
@@ -425,12 +425,12 @@ function PackageShopCompareView({
{entries.map((entry) => {
- const canSelect = canSelectPackage(entry.isDowngrade, entry.isActive);
+ const canSelect = canSelectPackage(entry.isUpgrade, entry.isActive);
const label = entry.isActive
? t('shop.manage', 'Manage Plan')
- : entry.isDowngrade
- ? t('shop.selectDisabled', 'Not available')
- : t('shop.select', 'Select');
+ : entry.isUpgrade
+ ? t('shop.select', 'Select')
+ : t('shop.selectDisabled', 'Not available');
return (
@@ -470,8 +470,8 @@ function getPackageStatusLabel({
return null;
}
-function canSelectPackage(isDowngrade?: boolean, isActive?: boolean): boolean {
- return !isDowngrade || Boolean(isActive);
+function canSelectPackage(isUpgrade?: boolean, isActive?: boolean): boolean {
+ return Boolean(isActive || isUpgrade);
}
function CheckoutConfirmation({ pkg, onCancel }: { pkg: Package; onCancel: () => void }) {
diff --git a/resources/js/admin/mobile/__tests__/packageShop.test.ts b/resources/js/admin/mobile/__tests__/packageShop.test.ts
index 27defd0..2f5e7a4 100644
--- a/resources/js/admin/mobile/__tests__/packageShop.test.ts
+++ b/resources/js/admin/mobile/__tests__/packageShop.test.ts
@@ -29,6 +29,11 @@ describe('classifyPackageChange', () => {
const candidate = { ...active, id: 3, max_photos: 50, features: { advanced_analytics: false } } as any;
expect(classifyPackageChange(candidate, active)).toEqual({ isUpgrade: false, isDowngrade: true });
});
+
+ it('treats mixed changes as downgrade', () => {
+ const candidate = { ...active, id: 4, max_photos: 200, gallery_days: 10, features: { advanced_analytics: false } } as any;
+ expect(classifyPackageChange(candidate, active)).toEqual({ isUpgrade: false, isDowngrade: true });
+ });
});
describe('selectRecommendedPackageId', () => {
diff --git a/resources/js/admin/mobile/lib/packageShop.ts b/resources/js/admin/mobile/lib/packageShop.ts
index 84aaabc..b07ec7d 100644
--- a/resources/js/admin/mobile/lib/packageShop.ts
+++ b/resources/js/admin/mobile/lib/packageShop.ts
@@ -86,7 +86,7 @@ export function classifyPackageChange(pkg: Package, active: Package | null): Pac
const hasUpgrade = hasFeatureUpgrade || hasLimitUpgrade;
const hasDowngrade = hasFeatureDowngrade || hasLimitDowngrade;
- if (hasUpgrade) {
+ if (hasUpgrade && !hasDowngrade) {
return { isUpgrade: true, isDowngrade: false };
}