feat: guest purchase activation UI & landing editor improvements

- Add PendingActivationState component with activate button
- Add double-click ref guard on activation handler
- Add activatePurchase API function
- Update PurchaseStatus type with new fields
- Show gift message and recipient contact in success state
- Add pending activation i18n translations (ru, en, zh, fa)
- Improve AdminLandingEditor with allowed_periods support
This commit is contained in:
Fringg
2026-03-06 19:56:38 +03:00
parent 9bd58cb914
commit b852e1e4cd
7 changed files with 378 additions and 57 deletions

View File

@@ -33,8 +33,22 @@ export interface LandingPaymentMethod {
description: string | null;
icon_url: string | null;
sort_order: number;
min_amount_kopeks: number | null;
max_amount_kopeks: number | null;
currency: string | null;
return_url: string | null;
}
/** Editable fields on a payment method in the landing editor */
export type EditableMethodField =
| 'display_name'
| 'description'
| 'icon_url'
| 'min_amount_kopeks'
| 'max_amount_kopeks'
| 'currency'
| 'return_url';
export interface LandingConfig {
slug: string;
title: string;
@@ -67,13 +81,15 @@ export interface PurchaseResponse {
}
export interface PurchaseStatus {
status: 'pending' | 'paid' | 'delivered' | 'failed' | 'expired';
status: 'pending' | 'paid' | 'delivered' | 'pending_activation' | 'failed' | 'expired';
subscription_url: string | null;
subscription_crypto_link: string | null;
is_gift: boolean;
contact_value: string | null;
recipient_contact_value: string | null;
period_days: number | null;
tariff_name: string | null;
gift_message: string | null;
}
// ============================================================
@@ -203,6 +219,11 @@ export const landingApi = {
const response = await apiClient.get(`/cabinet/landing/purchase/${token}`);
return response.data;
},
activatePurchase: async (token: string): Promise<PurchaseStatus> => {
const response = await apiClient.post(`/cabinet/landing/activate/${token}`);
return response.data;
},
};
// ============================================================