feat(addons): finalize event addon catalog and ai styling upgrade flow
This commit is contained in:
@@ -434,6 +434,24 @@ export default function MobileEventControlRoomPage() {
|
||||
const aiStylingAddon = React.useMemo(() => {
|
||||
return catalogAddons.find((addon) => addon.price_id && aiStylingAddonKeys.includes(addon.key)) ?? null;
|
||||
}, [aiStylingAddonKeys, catalogAddons]);
|
||||
const aiStylingAddonCta = React.useMemo(() => {
|
||||
if (!aiStylingAddon) {
|
||||
return t('controlRoom.aiUpsell.cta', 'Unlock AI Magic Edit');
|
||||
}
|
||||
|
||||
if (typeof aiStylingAddon.price !== 'number' || !Number.isFinite(aiStylingAddon.price)) {
|
||||
return t('controlRoom.aiUpsell.cta', 'Unlock AI Magic Edit');
|
||||
}
|
||||
|
||||
const currency = aiStylingAddon.currency || 'EUR';
|
||||
|
||||
try {
|
||||
const formattedPrice = new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(aiStylingAddon.price);
|
||||
return t('controlRoom.aiUpsell.ctaWithPrice', 'Unlock AI Magic Edit ({{price}})', { price: formattedPrice });
|
||||
} catch {
|
||||
return t('controlRoom.aiUpsell.cta', 'Unlock AI Magic Edit');
|
||||
}
|
||||
}, [aiStylingAddon, t]);
|
||||
const aiSettingsDirty = React.useMemo(
|
||||
() => isAiSettingsDirty(aiSettingsDraft, initialAiSettingsDraft),
|
||||
[aiSettingsDraft, initialAiSettingsDraft],
|
||||
@@ -907,12 +925,13 @@ export default function MobileEventControlRoomPage() {
|
||||
const params = new URLSearchParams(location.search);
|
||||
if (params.get('addon_success')) {
|
||||
toast.success(t('mobileBilling.addonApplied', 'Add-on applied. Limits update shortly.'));
|
||||
void refetch();
|
||||
setModerationPage(1);
|
||||
void loadModeration();
|
||||
params.delete('addon_success');
|
||||
navigate({ pathname: location.pathname, search: params.toString() ? `?${params.toString()}` : '' }, { replace: true });
|
||||
}
|
||||
}, [location.search, slug, loadModeration, navigate, t, location.pathname]);
|
||||
}, [location.search, slug, loadModeration, navigate, t, location.pathname, refetch]);
|
||||
|
||||
const updateQueueState = React.useCallback((queue: PhotoModerationAction[]) => {
|
||||
replacePhotoQueue(queue);
|
||||
@@ -1161,7 +1180,7 @@ export default function MobileEventControlRoomPage() {
|
||||
cancel_url: currentUrl,
|
||||
accepted_terms: consents.acceptedTerms,
|
||||
accepted_waiver: consents.acceptedWaiver,
|
||||
} as any);
|
||||
});
|
||||
if (checkout.checkout_url) {
|
||||
window.location.href = checkout.checkout_url;
|
||||
} else {
|
||||
@@ -1832,6 +1851,27 @@ export default function MobileEventControlRoomPage() {
|
||||
/>
|
||||
</XStack>
|
||||
</MobileCard>
|
||||
) : aiStylingAddon ? (
|
||||
<MobileCard gap="$3" borderColor={border} backgroundColor={surface}>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Sparkles size={18} color={primary} />
|
||||
<Text fontSize="$md" fontWeight="800" color={textStrong}>
|
||||
{t('controlRoom.aiUpsell.title', 'Unlock AI Magic Edit')}
|
||||
</Text>
|
||||
</XStack>
|
||||
<Text fontSize="$sm" color={muted}>
|
||||
{t(
|
||||
'controlRoom.aiUpsell.body',
|
||||
'Buy the AI Styling add-on for this event without upgrading your full package.'
|
||||
)}
|
||||
</Text>
|
||||
<CTAButton
|
||||
label={aiStylingAddonCta}
|
||||
onPress={() => startAddonCheckout('ai')}
|
||||
loading={busyScope === 'ai'}
|
||||
disabled={consentBusy}
|
||||
/>
|
||||
</MobileCard>
|
||||
) : null
|
||||
) : null}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user