@tagadapay/plugin-sdk 2.6.17 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/v2/core/resources/customer.d.ts +150 -0
- package/dist/v2/core/resources/customer.js +53 -0
- package/dist/v2/core/resources/index.d.ts +3 -1
- package/dist/v2/core/resources/index.js +3 -1
- package/dist/v2/core/resources/session.d.ts +27 -0
- package/dist/v2/core/resources/session.js +56 -0
- package/dist/v2/index.d.ts +9 -2
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/hooks/useAuth.d.ts +8 -0
- package/dist/v2/react/hooks/useAuth.js +9 -0
- package/dist/v2/react/hooks/useClubOffers.d.ts +101 -0
- package/dist/v2/react/hooks/useClubOffers.js +126 -0
- package/dist/v2/react/hooks/useCustomer.d.ts +11 -0
- package/dist/v2/react/hooks/useCustomer.js +11 -0
- package/dist/v2/react/hooks/useCustomerInfos.d.ts +12 -0
- package/dist/v2/react/hooks/useCustomerInfos.js +53 -0
- package/dist/v2/react/hooks/useCustomerOrders.d.ts +17 -0
- package/dist/v2/react/hooks/useCustomerOrders.js +51 -0
- package/dist/v2/react/hooks/useCustomerSubscriptions.d.ts +23 -0
- package/dist/v2/react/hooks/useCustomerSubscriptions.js +94 -0
- package/dist/v2/react/hooks/useLogin.d.ts +53 -0
- package/dist/v2/react/hooks/useLogin.js +75 -0
- package/dist/v2/react/hooks/useTranslation.js +1 -1
- package/dist/v2/react/index.d.ts +15 -4
- package/dist/v2/react/index.js +8 -2
- package/dist/v2/react/providers/TagadaProvider.d.ts +0 -3
- package/dist/v2/react/providers/TagadaProvider.js +44 -32
- package/package.json +1 -1
- package/dist/v2/react/hooks/useDiscountQuery.d.ts +0 -79
- package/dist/v2/react/hooks/useDiscountQuery.js +0 -24
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer Resource Client
|
|
3
|
+
* Handles customer-related API operations
|
|
4
|
+
*/
|
|
5
|
+
import { ApiClient } from './apiClient';
|
|
6
|
+
export interface CustomerAddress {
|
|
7
|
+
firstName: string | null;
|
|
8
|
+
lastName: string | null;
|
|
9
|
+
address1: string | null;
|
|
10
|
+
address2: string | null;
|
|
11
|
+
city: string | null;
|
|
12
|
+
province: string | null;
|
|
13
|
+
country: string | null;
|
|
14
|
+
zip: string | null;
|
|
15
|
+
phone: string | null;
|
|
16
|
+
email?: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface CustomerOrderSummary {
|
|
19
|
+
id: string;
|
|
20
|
+
totalPrice: number;
|
|
21
|
+
currency: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
status: string;
|
|
24
|
+
}
|
|
25
|
+
export interface CustomerInfos {
|
|
26
|
+
customer: {
|
|
27
|
+
id: string;
|
|
28
|
+
email: string | null;
|
|
29
|
+
firstName: string | null;
|
|
30
|
+
lastName: string | null;
|
|
31
|
+
externalCustomerId: string | null;
|
|
32
|
+
lastOrderId: string | null;
|
|
33
|
+
accountId: string;
|
|
34
|
+
storeId: string;
|
|
35
|
+
billingAddress: CustomerAddress | null;
|
|
36
|
+
shippingAddress: Omit<CustomerAddress, 'email'> | null;
|
|
37
|
+
currency: string | null;
|
|
38
|
+
locale: string | null;
|
|
39
|
+
draft: boolean;
|
|
40
|
+
acceptsMarketing: boolean;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
updatedAt: string;
|
|
43
|
+
metadata: Record<string, any>;
|
|
44
|
+
device: any | null;
|
|
45
|
+
orders: CustomerOrderSummary[];
|
|
46
|
+
subscriptions: any[];
|
|
47
|
+
};
|
|
48
|
+
promotionCodes: any[];
|
|
49
|
+
}
|
|
50
|
+
export interface OrderWithRelations {
|
|
51
|
+
id: string;
|
|
52
|
+
currency: string;
|
|
53
|
+
paidAmount: number;
|
|
54
|
+
status: string;
|
|
55
|
+
createdAt: string;
|
|
56
|
+
metadata?: Record<string, any>;
|
|
57
|
+
items: any[];
|
|
58
|
+
summaries?: any[];
|
|
59
|
+
shippingAddress?: any;
|
|
60
|
+
billingAddress?: any;
|
|
61
|
+
pickupAddress?: any;
|
|
62
|
+
checkoutSession?: {
|
|
63
|
+
returnUrl?: string;
|
|
64
|
+
[key: string]: any;
|
|
65
|
+
};
|
|
66
|
+
relatedOrders?: any[];
|
|
67
|
+
customer?: any;
|
|
68
|
+
store?: any;
|
|
69
|
+
account?: {
|
|
70
|
+
id: string;
|
|
71
|
+
name?: string;
|
|
72
|
+
};
|
|
73
|
+
payments?: any[];
|
|
74
|
+
promotions?: any[];
|
|
75
|
+
subscriptions?: any[];
|
|
76
|
+
adjustments: any[];
|
|
77
|
+
}
|
|
78
|
+
export interface Subscription {
|
|
79
|
+
id: string;
|
|
80
|
+
status: string;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
currency: string;
|
|
83
|
+
cancelAtPeriodEnd: boolean;
|
|
84
|
+
currentPeriodEnd: string | null;
|
|
85
|
+
currentPeriodStart: string | null;
|
|
86
|
+
quantity: number;
|
|
87
|
+
trialEnd: string | null;
|
|
88
|
+
customerId: string;
|
|
89
|
+
customerEmail: string;
|
|
90
|
+
customerName: string;
|
|
91
|
+
priceCurrencyOptions: Record<string, {
|
|
92
|
+
rate: number;
|
|
93
|
+
amount: number;
|
|
94
|
+
lock: boolean;
|
|
95
|
+
date: string;
|
|
96
|
+
}>;
|
|
97
|
+
priceInterval: string;
|
|
98
|
+
priceIntervalCount: number;
|
|
99
|
+
priceRecurring: boolean;
|
|
100
|
+
productId: string;
|
|
101
|
+
priceId: string;
|
|
102
|
+
productTitle: string;
|
|
103
|
+
}
|
|
104
|
+
export interface SubscriptionsResponse {
|
|
105
|
+
items: Subscription[];
|
|
106
|
+
pagination: {
|
|
107
|
+
page: number;
|
|
108
|
+
pageSize: number;
|
|
109
|
+
hasNext: boolean;
|
|
110
|
+
nextPage: number | null;
|
|
111
|
+
previousPage: number | null;
|
|
112
|
+
totalItems: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export declare class CustomerResource {
|
|
116
|
+
private apiClient;
|
|
117
|
+
constructor(apiClient: ApiClient);
|
|
118
|
+
/**
|
|
119
|
+
* Get customer information by ID
|
|
120
|
+
*/
|
|
121
|
+
getCustomerInfos(customerId: string, storeId: string): Promise<CustomerInfos>;
|
|
122
|
+
/**
|
|
123
|
+
* Update customer information
|
|
124
|
+
*/
|
|
125
|
+
updateCustomer(customerId: string, data: {
|
|
126
|
+
email?: string;
|
|
127
|
+
firstName?: string;
|
|
128
|
+
lastName?: string;
|
|
129
|
+
acceptsMarketing?: boolean;
|
|
130
|
+
metadata?: Record<string, any>;
|
|
131
|
+
}): Promise<CustomerInfos>;
|
|
132
|
+
/**
|
|
133
|
+
* Get customer orders
|
|
134
|
+
*/
|
|
135
|
+
getCustomerOrders(customerId: string, storeId: string): Promise<{
|
|
136
|
+
orders: OrderWithRelations[];
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Get customer subscriptions
|
|
140
|
+
*/
|
|
141
|
+
getCustomerSubscriptions(): Promise<SubscriptionsResponse>;
|
|
142
|
+
/**
|
|
143
|
+
* Resume a subscription
|
|
144
|
+
*/
|
|
145
|
+
resumeSubscription(subscriptionId: string): Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Cancel a subscription
|
|
148
|
+
*/
|
|
149
|
+
cancelSubscription(subscriptionId: string): Promise<void>;
|
|
150
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer Resource Client
|
|
3
|
+
* Handles customer-related API operations
|
|
4
|
+
*/
|
|
5
|
+
export class CustomerResource {
|
|
6
|
+
constructor(apiClient) {
|
|
7
|
+
this.apiClient = apiClient;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get customer information by ID
|
|
11
|
+
*/
|
|
12
|
+
async getCustomerInfos(customerId, storeId) {
|
|
13
|
+
return this.apiClient.get(`/api/v1/customers/${customerId}`, {
|
|
14
|
+
params: { storeId },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Update customer information
|
|
19
|
+
*/
|
|
20
|
+
async updateCustomer(customerId, data) {
|
|
21
|
+
return this.apiClient.patch(`/api/v1/customers/${customerId}`, data);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get customer orders
|
|
25
|
+
*/
|
|
26
|
+
async getCustomerOrders(customerId, storeId) {
|
|
27
|
+
return this.apiClient.get(`/api/v1/orders/customer/${customerId}`, {
|
|
28
|
+
params: { storeId },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get customer subscriptions
|
|
33
|
+
*/
|
|
34
|
+
async getCustomerSubscriptions() {
|
|
35
|
+
return this.apiClient.get('/api/v1/subscriptions');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Resume a subscription
|
|
39
|
+
*/
|
|
40
|
+
async resumeSubscription(subscriptionId) {
|
|
41
|
+
return this.apiClient.post('/api/v1/subscriptions/resume', {
|
|
42
|
+
subscriptionId,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Cancel a subscription
|
|
47
|
+
*/
|
|
48
|
+
async cancelSubscription(subscriptionId) {
|
|
49
|
+
return this.apiClient.post('/api/v1/subscriptions/cancel', {
|
|
50
|
+
subscriptionId,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export * from './apiClient';
|
|
6
6
|
export * from './checkout';
|
|
7
|
+
export * from './customer';
|
|
7
8
|
export * from './discounts';
|
|
9
|
+
export * from './funnel';
|
|
8
10
|
export * from './offers';
|
|
9
11
|
export * from './orders';
|
|
10
12
|
export * from './payments';
|
|
11
13
|
export * from './postPurchases';
|
|
12
14
|
export * from './products';
|
|
13
15
|
export * from './promotions';
|
|
16
|
+
export * from './session';
|
|
14
17
|
export * from './shippingRates';
|
|
15
18
|
export * from './storeConfig';
|
|
16
19
|
export * from './threeds';
|
|
17
20
|
export * from './vipOffers';
|
|
18
|
-
export * from './funnel';
|
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export * from './apiClient';
|
|
6
6
|
export * from './checkout';
|
|
7
|
+
export * from './customer';
|
|
7
8
|
export * from './discounts';
|
|
9
|
+
export * from './funnel';
|
|
8
10
|
export * from './offers';
|
|
9
11
|
export * from './orders';
|
|
10
12
|
export * from './payments';
|
|
11
13
|
export * from './postPurchases';
|
|
12
14
|
export * from './products';
|
|
13
15
|
export * from './promotions';
|
|
16
|
+
export * from './session';
|
|
14
17
|
export * from './shippingRates';
|
|
15
18
|
export * from './storeConfig';
|
|
16
19
|
export * from './threeds';
|
|
17
20
|
export * from './vipOffers';
|
|
18
|
-
export * from './funnel';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Resource Client
|
|
3
|
+
* Handles authentication and session management
|
|
4
|
+
*/
|
|
5
|
+
import { ApiClient } from './apiClient';
|
|
6
|
+
export interface RequestCodeResponse {
|
|
7
|
+
success: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface VerifyCodeResponse {
|
|
11
|
+
success: boolean;
|
|
12
|
+
token?: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class SessionResource {
|
|
17
|
+
private apiClient;
|
|
18
|
+
constructor(apiClient: ApiClient);
|
|
19
|
+
/**
|
|
20
|
+
* Request verification code for email
|
|
21
|
+
*/
|
|
22
|
+
requestCode(email: string, storeId: string): Promise<RequestCodeResponse>;
|
|
23
|
+
/**
|
|
24
|
+
* Verify code and login
|
|
25
|
+
*/
|
|
26
|
+
verifyCode(email: string, code: string, storeId: string): Promise<VerifyCodeResponse>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Resource Client
|
|
3
|
+
* Handles authentication and session management
|
|
4
|
+
*/
|
|
5
|
+
export class SessionResource {
|
|
6
|
+
constructor(apiClient) {
|
|
7
|
+
this.apiClient = apiClient;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Request verification code for email
|
|
11
|
+
*/
|
|
12
|
+
async requestCode(email, storeId) {
|
|
13
|
+
try {
|
|
14
|
+
await this.apiClient.post('/api/v1/cms/session/request-code', {
|
|
15
|
+
email,
|
|
16
|
+
storeId,
|
|
17
|
+
});
|
|
18
|
+
return { success: true };
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return {
|
|
22
|
+
success: false,
|
|
23
|
+
error: error instanceof Error ? error.message : 'Failed to send code',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Verify code and login
|
|
29
|
+
*/
|
|
30
|
+
async verifyCode(email, code, storeId) {
|
|
31
|
+
try {
|
|
32
|
+
const response = await this.apiClient.post('/api/v1/cms/session/login', {
|
|
33
|
+
email,
|
|
34
|
+
code,
|
|
35
|
+
storeId,
|
|
36
|
+
});
|
|
37
|
+
if (!response) {
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
error: 'Invalid code',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
success: true,
|
|
45
|
+
token: response.token,
|
|
46
|
+
sessionId: response.sessionId,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: error instanceof Error ? error.message : 'Failed to verify code',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
package/dist/v2/index.d.ts
CHANGED
|
@@ -21,5 +21,12 @@ export type { ApplyDiscountResponse, Discount, DiscountCodeValidation, RemoveDis
|
|
|
21
21
|
export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './core/resources/vipOffers';
|
|
22
22
|
export type { StoreConfig } from './core/resources/storeConfig';
|
|
23
23
|
export type { FunnelContextUpdateRequest, FunnelContextUpdateResponse, FunnelEvent, FunnelInitializeRequest, FunnelInitializeResponse, FunnelNavigateRequest, FunnelNavigateResponse, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from './core/resources/funnel';
|
|
24
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency,
|
|
25
|
-
export type {
|
|
24
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
|
|
25
|
+
export type { TranslateFunction, UseTranslationOptions, UseTranslationResult } from './react/hooks/useTranslation';
|
|
26
|
+
export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './react/hooks/useClubOffers';
|
|
27
|
+
export type { UseLoginOptions, UseLoginResult } from './react/hooks/useLogin';
|
|
28
|
+
export type { CustomerAddress, CustomerInfos, CustomerOrderSummary, OrderWithRelations, Subscription, SubscriptionsResponse } from './core/resources/customer';
|
|
29
|
+
export type { UseCustomerResult } from './react/hooks/useCustomer';
|
|
30
|
+
export type { UseCustomerInfosOptions, UseCustomerInfosResult } from './react/hooks/useCustomerInfos';
|
|
31
|
+
export type { UseCustomerOrdersOptions, UseCustomerOrdersResult } from './react/hooks/useCustomerOrders';
|
|
32
|
+
export type { UseCustomerSubscriptionsOptions, UseCustomerSubscriptionsResult } from './react/hooks/useCustomerSubscriptions';
|
package/dist/v2/index.js
CHANGED
|
@@ -12,4 +12,4 @@ export * from './core/utils/currency';
|
|
|
12
12
|
export * from './core/utils/pluginConfig';
|
|
13
13
|
export * from './core/utils/products';
|
|
14
14
|
// React exports (hooks and components only, types are exported above)
|
|
15
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency,
|
|
15
|
+
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useAuth, useCheckout, useCheckoutToken, useClubOffers, useCountryOptions, useCurrency, useCustomer, useCustomerInfos, useCustomerOrders, useCustomerSubscriptions, useDiscounts, useExpressPaymentMethods, useFunnel, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useLogin, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useSimpleFunnel, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal, useTranslation, useVipOffers } from './react';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export interface ClubOfferItem {
|
|
2
|
+
id: string;
|
|
3
|
+
productId: string;
|
|
4
|
+
variantId: string;
|
|
5
|
+
product: {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
};
|
|
9
|
+
variant: {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
imageUrl: string;
|
|
13
|
+
grams: number;
|
|
14
|
+
};
|
|
15
|
+
unitAmount: number;
|
|
16
|
+
quantity: number;
|
|
17
|
+
amount: number;
|
|
18
|
+
adjustedAmount: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ClubOfferSummary {
|
|
21
|
+
currency: string;
|
|
22
|
+
totalAmount: number;
|
|
23
|
+
totalAdjustedAmount: number;
|
|
24
|
+
items: ClubOfferItem[];
|
|
25
|
+
}
|
|
26
|
+
export interface ClubOfferLineItem {
|
|
27
|
+
id: string;
|
|
28
|
+
quantity: number;
|
|
29
|
+
price: {
|
|
30
|
+
variant: {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
description: string | null;
|
|
34
|
+
imageUrl: string;
|
|
35
|
+
grams: number;
|
|
36
|
+
product: {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export interface ClubOffer {
|
|
45
|
+
id: string;
|
|
46
|
+
titleTrans: {
|
|
47
|
+
en: string;
|
|
48
|
+
};
|
|
49
|
+
summaries: ClubOfferSummary[];
|
|
50
|
+
offerLineItems: ClubOfferLineItem[];
|
|
51
|
+
}
|
|
52
|
+
export interface UseClubOffersOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Whether to fetch club offers automatically on mount
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Return URL for payment
|
|
60
|
+
*/
|
|
61
|
+
returnUrl?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface UseClubOffersResult {
|
|
64
|
+
/**
|
|
65
|
+
* Array of fetched club offers
|
|
66
|
+
*/
|
|
67
|
+
offers: ClubOffer[];
|
|
68
|
+
/**
|
|
69
|
+
* Loading state
|
|
70
|
+
*/
|
|
71
|
+
isLoading: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Error state
|
|
74
|
+
*/
|
|
75
|
+
error: Error | null;
|
|
76
|
+
/**
|
|
77
|
+
* Refetch club offers
|
|
78
|
+
*/
|
|
79
|
+
refetch: () => Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Get club offer by ID from the loaded offers
|
|
82
|
+
*/
|
|
83
|
+
getOffer: (offerId: string) => ClubOffer | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Get total value of all club offers
|
|
86
|
+
*/
|
|
87
|
+
getTotalValue: () => number;
|
|
88
|
+
/**
|
|
89
|
+
* Get total savings across all club offers
|
|
90
|
+
*/
|
|
91
|
+
getTotalSavings: () => number;
|
|
92
|
+
/**
|
|
93
|
+
* Clear error state
|
|
94
|
+
*/
|
|
95
|
+
clearError: () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Pay for a club offer
|
|
98
|
+
*/
|
|
99
|
+
payOffer: (offerId: string, returnUrl?: string) => Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
export declare function useClubOffers(options?: UseClubOffersOptions): UseClubOffersResult;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
/**
|
|
3
|
+
* useClubOffers - Hook for club-specific offers (v2)
|
|
4
|
+
* Extends the offers functionality with club filtering
|
|
5
|
+
*/
|
|
6
|
+
import { useMutation, useQuery } from '@tanstack/react-query';
|
|
7
|
+
import { useCallback, useMemo } from 'react';
|
|
8
|
+
import { OffersResource } from '../../core/resources/offers';
|
|
9
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
10
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
11
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
12
|
+
/**
|
|
13
|
+
* Transform generic Offer to ClubOffer format
|
|
14
|
+
*/
|
|
15
|
+
function transformToClubOffer(offer) {
|
|
16
|
+
return {
|
|
17
|
+
id: offer.id,
|
|
18
|
+
titleTrans: offer.titleTrans,
|
|
19
|
+
summaries: offer.summaries.map((summary) => ({
|
|
20
|
+
currency: summary.currency,
|
|
21
|
+
totalAmount: summary.totalAmount,
|
|
22
|
+
totalAdjustedAmount: summary.totalAdjustedAmount,
|
|
23
|
+
items: summary.items.map((item) => ({
|
|
24
|
+
id: item.id,
|
|
25
|
+
productId: item.id, // Using item ID as productId fallback
|
|
26
|
+
variantId: item.id, // Using item ID as variantId fallback
|
|
27
|
+
product: item.product,
|
|
28
|
+
variant: {
|
|
29
|
+
name: item.variant.name,
|
|
30
|
+
description: '', // Not available in base Offer
|
|
31
|
+
imageUrl: item.variant.imageUrl,
|
|
32
|
+
grams: 0, // Not available in base Offer
|
|
33
|
+
},
|
|
34
|
+
unitAmount: item.unitAmount,
|
|
35
|
+
quantity: item.quantity,
|
|
36
|
+
amount: item.amount,
|
|
37
|
+
adjustedAmount: item.adjustedAmount,
|
|
38
|
+
})),
|
|
39
|
+
})),
|
|
40
|
+
offerLineItems: [], // Not available in base Offer
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function useClubOffers(options = {}) {
|
|
44
|
+
const { enabled = true, returnUrl } = options;
|
|
45
|
+
const { storeId } = usePluginConfig();
|
|
46
|
+
const { isSessionInitialized } = useTagadaContext();
|
|
47
|
+
// Create offers resource client
|
|
48
|
+
const offersResource = useMemo(() => {
|
|
49
|
+
try {
|
|
50
|
+
return new OffersResource(getGlobalApiClient());
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
throw new Error('Failed to initialize offers resource: ' +
|
|
54
|
+
(error instanceof Error ? error.message : 'Unknown error'));
|
|
55
|
+
}
|
|
56
|
+
}, []);
|
|
57
|
+
// Create query key
|
|
58
|
+
const queryKey = useMemo(() => ['club-offers', { storeId }], [storeId]);
|
|
59
|
+
// Fetch club offers using TanStack Query
|
|
60
|
+
const { data: offers = [], isLoading, error, refetch, } = useQuery({
|
|
61
|
+
queryKey,
|
|
62
|
+
enabled: enabled && !!storeId && isSessionInitialized,
|
|
63
|
+
queryFn: async () => {
|
|
64
|
+
if (!storeId) {
|
|
65
|
+
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
66
|
+
}
|
|
67
|
+
// Fetch all offers and filter for club type
|
|
68
|
+
// Note: The API endpoint should support a 'type' parameter
|
|
69
|
+
const response = await getGlobalApiClient().get(`/api/v1/stores/${storeId}/offers`, {
|
|
70
|
+
params: {
|
|
71
|
+
type: 'club',
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
// Transform to club offer format
|
|
75
|
+
return (response.offers || []).map(transformToClubOffer);
|
|
76
|
+
},
|
|
77
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
78
|
+
refetchOnWindowFocus: false,
|
|
79
|
+
});
|
|
80
|
+
// Pay offer mutation
|
|
81
|
+
const payOfferMutation = useMutation({
|
|
82
|
+
mutationFn: async ({ offerId, returnUrl }) => {
|
|
83
|
+
const url = returnUrl || (typeof window !== 'undefined' ? window.location.href : '');
|
|
84
|
+
return await offersResource.payOffer(offerId);
|
|
85
|
+
},
|
|
86
|
+
onError: (error) => {
|
|
87
|
+
console.error('[SDK] Failed to pay offer:', error);
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
// Helper functions
|
|
91
|
+
const getOffer = useCallback((offerId) => {
|
|
92
|
+
return offers.find((offer) => offer.id === offerId);
|
|
93
|
+
}, [offers]);
|
|
94
|
+
const getTotalValue = useCallback(() => {
|
|
95
|
+
return offers.reduce((total, offer) => {
|
|
96
|
+
const firstSummary = offer.summaries[0];
|
|
97
|
+
return total + (firstSummary?.totalAdjustedAmount || 0);
|
|
98
|
+
}, 0);
|
|
99
|
+
}, [offers]);
|
|
100
|
+
const getTotalSavings = useCallback(() => {
|
|
101
|
+
return offers.reduce((total, offer) => {
|
|
102
|
+
const firstSummary = offer.summaries[0];
|
|
103
|
+
return total + (firstSummary?.totalAmount - firstSummary?.totalAdjustedAmount || 0);
|
|
104
|
+
}, 0);
|
|
105
|
+
}, [offers]);
|
|
106
|
+
const clearError = useCallback(() => {
|
|
107
|
+
// TanStack Query doesn't have a direct clearError method
|
|
108
|
+
// Error will be cleared on next successful fetch
|
|
109
|
+
}, []);
|
|
110
|
+
const payOffer = useCallback(async (offerId, returnUrl) => {
|
|
111
|
+
await payOfferMutation.mutateAsync({ offerId, returnUrl });
|
|
112
|
+
}, [payOfferMutation]);
|
|
113
|
+
return {
|
|
114
|
+
offers,
|
|
115
|
+
isLoading,
|
|
116
|
+
error,
|
|
117
|
+
refetch: async () => {
|
|
118
|
+
await refetch();
|
|
119
|
+
},
|
|
120
|
+
getOffer,
|
|
121
|
+
getTotalValue,
|
|
122
|
+
getTotalSavings,
|
|
123
|
+
clearError,
|
|
124
|
+
payOffer,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCustomer - Hook to access current customer data (v2)
|
|
3
|
+
*/
|
|
4
|
+
import { Customer } from '../../../react/types';
|
|
5
|
+
export interface UseCustomerResult {
|
|
6
|
+
customer: Customer | null;
|
|
7
|
+
isAuthenticated: boolean;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
isAnonymous: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function useCustomer(): UseCustomerResult;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
3
|
+
export function useCustomer() {
|
|
4
|
+
const { customer, isLoading } = useTagadaContext();
|
|
5
|
+
return {
|
|
6
|
+
customer,
|
|
7
|
+
isAuthenticated: customer?.isAuthenticated || false,
|
|
8
|
+
isLoading,
|
|
9
|
+
isAnonymous: customer?.role === 'anonymous',
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CustomerInfos } from '../../core/resources/customer';
|
|
2
|
+
export interface UseCustomerInfosOptions {
|
|
3
|
+
customerId?: string | null;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface UseCustomerInfosResult {
|
|
7
|
+
data: CustomerInfos | null;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error: Error | null;
|
|
10
|
+
refetch: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function useCustomerInfos(options?: UseCustomerInfosOptions): UseCustomerInfosResult;
|