@tagadapay/plugin-sdk 2.6.18 → 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 +10 -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 +16 -1
- package/dist/v2/react/index.js +8 -0
- 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
|
@@ -20,5 +20,13 @@ export type { ShippingRate, ShippingRatesResponse } from './core/resources/shipp
|
|
|
20
20
|
export type { ApplyDiscountResponse, Discount, DiscountCodeValidation, RemoveDiscountResponse } from './core/resources/discounts';
|
|
21
21
|
export type { ToggleOrderBumpResponse, VipOffer, VipPreviewResponse } from './core/resources/vipOffers';
|
|
22
22
|
export type { StoreConfig } from './core/resources/storeConfig';
|
|
23
|
-
export type {
|
|
24
|
-
export { ApplePayButton, ExpressPaymentMethodsProvider, formatMoney, getAvailableLanguages, GooglePayButton, queryKeys, TagadaProvider, useApiMutation, useApiQuery, useCheckout, useCheckoutToken, useCountryOptions, useCurrency, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal,
|
|
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, 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, useDiscounts, useExpressPaymentMethods, useGeoLocation, useGoogleAutocomplete, useInvalidateQuery, useISOData, useLanguageImport, useOffers, useOrder, useOrderBump, usePayment, usePluginConfig, usePostPurchases, usePreloadQuery, useProducts, usePromotions, useRegionOptions, useShippingRates, useStoreConfig, useTagadaContext, useThreeds, useThreedsModal,
|
|
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;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
/**
|
|
3
|
+
* useCustomerInfos - Hook to fetch customer information (v2)
|
|
4
|
+
* Fetches customer infos from `/api/v1/customers/{customerId}` with `storeId` param
|
|
5
|
+
*/
|
|
6
|
+
import { useQuery } from '@tanstack/react-query';
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
import { CustomerResource } from '../../core/resources/customer';
|
|
9
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
10
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
11
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
12
|
+
export function useCustomerInfos(options = {}) {
|
|
13
|
+
const { storeId } = usePluginConfig();
|
|
14
|
+
const { isSessionInitialized } = useTagadaContext();
|
|
15
|
+
const { customerId = null, enabled = true } = options;
|
|
16
|
+
// Create customer resource client
|
|
17
|
+
const customerResource = useMemo(() => {
|
|
18
|
+
try {
|
|
19
|
+
return new CustomerResource(getGlobalApiClient());
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error('Failed to initialize customer resource: ' +
|
|
23
|
+
(error instanceof Error ? error.message : 'Unknown error'));
|
|
24
|
+
}
|
|
25
|
+
}, []);
|
|
26
|
+
// Determine if query should be enabled
|
|
27
|
+
const isEnabled = useMemo(() => {
|
|
28
|
+
return Boolean(enabled && customerId && storeId && isSessionInitialized);
|
|
29
|
+
}, [enabled, customerId, storeId, isSessionInitialized]);
|
|
30
|
+
// Create query key
|
|
31
|
+
const queryKey = useMemo(() => ['customer-infos', { customerId, storeId }], [customerId, storeId]);
|
|
32
|
+
// Fetch customer infos using TanStack Query
|
|
33
|
+
const { data = null, isLoading, error, refetch, } = useQuery({
|
|
34
|
+
queryKey,
|
|
35
|
+
enabled: isEnabled,
|
|
36
|
+
queryFn: async () => {
|
|
37
|
+
if (!customerId || !storeId) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return await customerResource.getCustomerInfos(customerId, storeId);
|
|
41
|
+
},
|
|
42
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
43
|
+
refetchOnWindowFocus: false,
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
data,
|
|
47
|
+
isLoading,
|
|
48
|
+
error,
|
|
49
|
+
refetch: async () => {
|
|
50
|
+
await refetch();
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCustomerOrders - Hook to fetch customer orders (v2)
|
|
3
|
+
*/
|
|
4
|
+
import { OrderWithRelations } from '../../core/resources/customer';
|
|
5
|
+
export interface UseCustomerOrdersOptions {
|
|
6
|
+
customerId?: string | null;
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface UseCustomerOrdersResult {
|
|
10
|
+
data: {
|
|
11
|
+
orders: OrderWithRelations[];
|
|
12
|
+
} | null;
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
refetch: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function useCustomerOrders(options?: UseCustomerOrdersOptions): UseCustomerOrdersResult;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCustomerOrders - Hook to fetch customer orders (v2)
|
|
3
|
+
*/
|
|
4
|
+
import { useQuery } from '@tanstack/react-query';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
import { CustomerResource } from '../../core/resources/customer';
|
|
7
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
8
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
9
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
10
|
+
export function useCustomerOrders(options = {}) {
|
|
11
|
+
const { storeId } = usePluginConfig();
|
|
12
|
+
const { isSessionInitialized } = useTagadaContext();
|
|
13
|
+
const { customerId = null, enabled = true } = options;
|
|
14
|
+
// Create customer resource client
|
|
15
|
+
const customerResource = useMemo(() => {
|
|
16
|
+
try {
|
|
17
|
+
return new CustomerResource(getGlobalApiClient());
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw new Error('Failed to initialize customer resource: ' +
|
|
21
|
+
(error instanceof Error ? error.message : 'Unknown error'));
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
// Determine if query should be enabled
|
|
25
|
+
const isEnabled = useMemo(() => {
|
|
26
|
+
return Boolean(enabled && customerId && storeId && isSessionInitialized);
|
|
27
|
+
}, [enabled, customerId, storeId, isSessionInitialized]);
|
|
28
|
+
// Create query key
|
|
29
|
+
const queryKey = useMemo(() => ['customer-orders', { customerId, storeId }], [customerId, storeId]);
|
|
30
|
+
// Fetch customer orders using TanStack Query
|
|
31
|
+
const { data = null, isLoading, error, refetch, } = useQuery({
|
|
32
|
+
queryKey,
|
|
33
|
+
enabled: isEnabled,
|
|
34
|
+
queryFn: async () => {
|
|
35
|
+
if (!customerId || !storeId) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return await customerResource.getCustomerOrders(customerId, storeId);
|
|
39
|
+
},
|
|
40
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
41
|
+
refetchOnWindowFocus: false,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
data,
|
|
45
|
+
isLoading,
|
|
46
|
+
error,
|
|
47
|
+
refetch: async () => {
|
|
48
|
+
await refetch();
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCustomerSubscriptions - Hook to manage customer subscriptions (v2)
|
|
3
|
+
*/
|
|
4
|
+
import { SubscriptionsResponse } from '../../core/resources/customer';
|
|
5
|
+
export interface UseCustomerSubscriptionsOptions {
|
|
6
|
+
customerId?: string | null;
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface UseCustomerSubscriptionsResult {
|
|
10
|
+
data: SubscriptionsResponse | null;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
error: Error | null;
|
|
13
|
+
refetch: () => Promise<void>;
|
|
14
|
+
resumeSubscription: (subscriptionId: string) => Promise<{
|
|
15
|
+
success: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
}>;
|
|
18
|
+
cancelSubscription: (subscriptionId: string) => Promise<{
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
export declare function useCustomerSubscriptions(options?: UseCustomerSubscriptionsOptions): UseCustomerSubscriptionsResult;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCustomerSubscriptions - Hook to manage customer subscriptions (v2)
|
|
3
|
+
*/
|
|
4
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { useCallback, useMemo } from 'react';
|
|
6
|
+
import { CustomerResource } from '../../core/resources/customer';
|
|
7
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
8
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
9
|
+
export function useCustomerSubscriptions(options = {}) {
|
|
10
|
+
const { isSessionInitialized } = useTagadaContext();
|
|
11
|
+
const queryClient = useQueryClient();
|
|
12
|
+
const { customerId = null, enabled = true } = options;
|
|
13
|
+
// Create customer resource client
|
|
14
|
+
const customerResource = useMemo(() => {
|
|
15
|
+
try {
|
|
16
|
+
return new CustomerResource(getGlobalApiClient());
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new Error('Failed to initialize customer resource: ' +
|
|
20
|
+
(error instanceof Error ? error.message : 'Unknown error'));
|
|
21
|
+
}
|
|
22
|
+
}, []);
|
|
23
|
+
// Determine if query should be enabled
|
|
24
|
+
const isEnabled = useMemo(() => {
|
|
25
|
+
return Boolean(enabled && customerId && isSessionInitialized);
|
|
26
|
+
}, [enabled, customerId, isSessionInitialized]);
|
|
27
|
+
// Create query key
|
|
28
|
+
const queryKey = useMemo(() => ['customer-subscriptions', { customerId }], [customerId]);
|
|
29
|
+
// Fetch customer subscriptions using TanStack Query
|
|
30
|
+
const { data = null, isLoading, error, refetch, } = useQuery({
|
|
31
|
+
queryKey,
|
|
32
|
+
enabled: isEnabled,
|
|
33
|
+
queryFn: async () => {
|
|
34
|
+
if (!customerId) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return await customerResource.getCustomerSubscriptions();
|
|
38
|
+
},
|
|
39
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
40
|
+
refetchOnWindowFocus: false,
|
|
41
|
+
});
|
|
42
|
+
// Resume subscription mutation
|
|
43
|
+
const resumeMutation = useMutation({
|
|
44
|
+
mutationFn: async (subscriptionId) => {
|
|
45
|
+
return await customerResource.resumeSubscription(subscriptionId);
|
|
46
|
+
},
|
|
47
|
+
onSuccess: () => {
|
|
48
|
+
// Invalidate and refetch subscriptions
|
|
49
|
+
void queryClient.invalidateQueries({ queryKey });
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
// Cancel subscription mutation
|
|
53
|
+
const cancelMutation = useMutation({
|
|
54
|
+
mutationFn: async (subscriptionId) => {
|
|
55
|
+
return await customerResource.cancelSubscription(subscriptionId);
|
|
56
|
+
},
|
|
57
|
+
onSuccess: () => {
|
|
58
|
+
// Invalidate and refetch subscriptions
|
|
59
|
+
void queryClient.invalidateQueries({ queryKey });
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
// Resume subscription
|
|
63
|
+
const resumeSubscription = useCallback(async (subscriptionId) => {
|
|
64
|
+
try {
|
|
65
|
+
await resumeMutation.mutateAsync(subscriptionId);
|
|
66
|
+
return { success: true };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to resume subscription';
|
|
70
|
+
return { success: false, error: errorMessage };
|
|
71
|
+
}
|
|
72
|
+
}, [resumeMutation]);
|
|
73
|
+
// Cancel subscription
|
|
74
|
+
const cancelSubscription = useCallback(async (subscriptionId) => {
|
|
75
|
+
try {
|
|
76
|
+
await cancelMutation.mutateAsync(subscriptionId);
|
|
77
|
+
return { success: true };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to cancel subscription';
|
|
81
|
+
return { success: false, error: errorMessage };
|
|
82
|
+
}
|
|
83
|
+
}, [cancelMutation]);
|
|
84
|
+
return {
|
|
85
|
+
data,
|
|
86
|
+
isLoading,
|
|
87
|
+
error,
|
|
88
|
+
refetch: async () => {
|
|
89
|
+
await refetch();
|
|
90
|
+
},
|
|
91
|
+
resumeSubscription,
|
|
92
|
+
cancelSubscription,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface UseLoginOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Callback when login is successful
|
|
4
|
+
*/
|
|
5
|
+
onSuccess?: (token: string) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Callback when an error occurs
|
|
8
|
+
*/
|
|
9
|
+
onError?: (error: Error) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface UseLoginResult {
|
|
12
|
+
/**
|
|
13
|
+
* Request verification code for email
|
|
14
|
+
*/
|
|
15
|
+
requestCode: (email: string) => Promise<{
|
|
16
|
+
success: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Verify code and complete login
|
|
21
|
+
*/
|
|
22
|
+
verifyCode: (email: string, code: string) => Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
token?: string;
|
|
25
|
+
sessionId?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Combined loading state (true if either request or verify is loading)
|
|
30
|
+
*/
|
|
31
|
+
isLoading: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Loading state for request code
|
|
34
|
+
*/
|
|
35
|
+
isRequestingCode: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Loading state for verify code
|
|
38
|
+
*/
|
|
39
|
+
isVerifyingCode: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Combined error state
|
|
42
|
+
*/
|
|
43
|
+
error: Error | null;
|
|
44
|
+
/**
|
|
45
|
+
* Error from request code
|
|
46
|
+
*/
|
|
47
|
+
requestCodeError: Error | null;
|
|
48
|
+
/**
|
|
49
|
+
* Error from verify code
|
|
50
|
+
*/
|
|
51
|
+
verifyCodeError: Error | null;
|
|
52
|
+
}
|
|
53
|
+
export declare function useLogin(options?: UseLoginOptions): UseLoginResult;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
/**
|
|
3
|
+
* useLogin - Hook for authentication (v2)
|
|
4
|
+
* Handles email/code authentication flow
|
|
5
|
+
*/
|
|
6
|
+
import { useMutation } from '@tanstack/react-query';
|
|
7
|
+
import { useCallback, useMemo } from 'react';
|
|
8
|
+
import { setClientToken } from '../../../react/utils/tokenStorage';
|
|
9
|
+
import { SessionResource } from '../../core/resources/session';
|
|
10
|
+
import { getGlobalApiClient } from './useApiQuery';
|
|
11
|
+
import { usePluginConfig } from './usePluginConfig';
|
|
12
|
+
export function useLogin(options = {}) {
|
|
13
|
+
const { onSuccess, onError } = options;
|
|
14
|
+
const { storeId } = usePluginConfig();
|
|
15
|
+
// Create session resource client
|
|
16
|
+
const sessionResource = useMemo(() => {
|
|
17
|
+
try {
|
|
18
|
+
return new SessionResource(getGlobalApiClient());
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new Error('Failed to initialize session resource: ' +
|
|
22
|
+
(error instanceof Error ? error.message : 'Unknown error'));
|
|
23
|
+
}
|
|
24
|
+
}, []);
|
|
25
|
+
// Request code mutation
|
|
26
|
+
const requestCodeMutation = useMutation({
|
|
27
|
+
mutationFn: async (email) => {
|
|
28
|
+
if (!storeId) {
|
|
29
|
+
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
30
|
+
}
|
|
31
|
+
return await sessionResource.requestCode(email, storeId);
|
|
32
|
+
},
|
|
33
|
+
onError: (error) => {
|
|
34
|
+
console.error('[SDK] Failed to request code:', error);
|
|
35
|
+
onError?.(error);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
// Verify code mutation
|
|
39
|
+
const verifyCodeMutation = useMutation({
|
|
40
|
+
mutationFn: async ({ email, code }) => {
|
|
41
|
+
if (!storeId) {
|
|
42
|
+
throw new Error('Store ID not found. Make sure the TagadaProvider is properly configured.');
|
|
43
|
+
}
|
|
44
|
+
const result = await sessionResource.verifyCode(email, code, storeId);
|
|
45
|
+
if (result.success && result.token) {
|
|
46
|
+
// Store the token
|
|
47
|
+
setClientToken(result.token);
|
|
48
|
+
// Call success callback
|
|
49
|
+
onSuccess?.(result.token);
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
},
|
|
53
|
+
onError: (error) => {
|
|
54
|
+
console.error('[SDK] Failed to verify code:', error);
|
|
55
|
+
onError?.(error);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Action functions
|
|
59
|
+
const requestCode = useCallback(async (email) => {
|
|
60
|
+
return await requestCodeMutation.mutateAsync(email);
|
|
61
|
+
}, [requestCodeMutation]);
|
|
62
|
+
const verifyCode = useCallback(async (email, code) => {
|
|
63
|
+
return await verifyCodeMutation.mutateAsync({ email, code });
|
|
64
|
+
}, [verifyCodeMutation]);
|
|
65
|
+
return {
|
|
66
|
+
requestCode,
|
|
67
|
+
verifyCode,
|
|
68
|
+
isLoading: requestCodeMutation.isPending || verifyCodeMutation.isPending,
|
|
69
|
+
isRequestingCode: requestCodeMutation.isPending,
|
|
70
|
+
isVerifyingCode: verifyCodeMutation.isPending,
|
|
71
|
+
error: requestCodeMutation.error || verifyCodeMutation.error,
|
|
72
|
+
requestCodeError: requestCodeMutation.error,
|
|
73
|
+
verifyCodeError: verifyCodeMutation.error,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -29,7 +29,7 @@ export const useTranslation = (options = {}) => {
|
|
|
29
29
|
// Check for language query parameter
|
|
30
30
|
if (typeof window !== 'undefined') {
|
|
31
31
|
const urlParams = new URLSearchParams(window.location.search);
|
|
32
|
-
const langFromQuery = urlParams.get('
|
|
32
|
+
const langFromQuery = urlParams.get('locale');
|
|
33
33
|
if (langFromQuery)
|
|
34
34
|
return langFromQuery;
|
|
35
35
|
}
|
package/dist/v2/react/index.d.ts
CHANGED
|
@@ -6,11 +6,18 @@ export { ExpressPaymentMethodsProvider } from './providers/ExpressPaymentMethods
|
|
|
6
6
|
export { TagadaProvider, useTagadaContext } from './providers/TagadaProvider';
|
|
7
7
|
export { ApplePayButton } from './components/ApplePayButton';
|
|
8
8
|
export { GooglePayButton } from './components/GooglePayButton';
|
|
9
|
+
export { useAuth } from './hooks/useAuth';
|
|
9
10
|
export { useCheckoutToken } from './hooks/useCheckoutToken';
|
|
11
|
+
export { useClubOffers } from './hooks/useClubOffers';
|
|
12
|
+
export { useCustomer } from './hooks/useCustomer';
|
|
13
|
+
export { useCustomerInfos } from './hooks/useCustomerInfos';
|
|
14
|
+
export { useCustomerOrders } from './hooks/useCustomerOrders';
|
|
15
|
+
export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
|
|
10
16
|
export { useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
|
|
11
17
|
export { useGeoLocation } from './hooks/useGeoLocation';
|
|
12
18
|
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
13
19
|
export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
|
|
20
|
+
export { useLogin } from './hooks/useLogin';
|
|
14
21
|
export { usePluginConfig } from './hooks/usePluginConfig';
|
|
15
22
|
export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
|
|
16
23
|
export { useCheckoutQuery as useCheckout } from './hooks/useCheckoutQuery';
|
|
@@ -27,18 +34,27 @@ export { useShippingRatesQuery as useShippingRates } from './hooks/useShippingRa
|
|
|
27
34
|
export { useStoreConfigQuery as useStoreConfig } from './hooks/useStoreConfigQuery';
|
|
28
35
|
export { useThreeds } from './hooks/useThreeds';
|
|
29
36
|
export { useThreedsModal } from './hooks/useThreedsModal';
|
|
37
|
+
export { useTranslation } from './hooks/useTranslation';
|
|
30
38
|
export { useVipOffersQuery as useVipOffers } from './hooks/useVipOffersQuery';
|
|
31
39
|
export { useFunnel, useSimpleFunnel } from './hooks/useFunnel';
|
|
32
40
|
export type { UseCheckoutTokenOptions, UseCheckoutTokenResult } from './hooks/useCheckoutToken';
|
|
41
|
+
export type { ClubOffer, ClubOfferItem, ClubOfferLineItem, ClubOfferSummary, UseClubOffersOptions, UseClubOffersResult } from './hooks/useClubOffers';
|
|
42
|
+
export type { UseCustomerResult } from './hooks/useCustomer';
|
|
43
|
+
export type { UseCustomerInfosOptions, UseCustomerInfosResult } from './hooks/useCustomerInfos';
|
|
44
|
+
export type { UseCustomerOrdersOptions, UseCustomerOrdersResult } from './hooks/useCustomerOrders';
|
|
45
|
+
export type { UseCustomerSubscriptionsOptions, UseCustomerSubscriptionsResult } from './hooks/useCustomerSubscriptions';
|
|
33
46
|
export type { ExpressPaymentMethodsContextType, ExpressPaymentMethodsProviderProps } from './hooks/useExpressPaymentMethods';
|
|
47
|
+
export type { UseLoginOptions, UseLoginResult } from './hooks/useLogin';
|
|
34
48
|
export type { ApplePayButtonProps } from './components/ApplePayButton';
|
|
35
49
|
export type { GooglePayButtonProps } from './components/GooglePayButton';
|
|
36
50
|
export type { GeoLocationData, UseGeoLocationOptions, UseGeoLocationReturn } from './hooks/useGeoLocation';
|
|
37
51
|
export type { ExtractedAddress, GooglePlaceDetails, GooglePrediction, UseGoogleAutocompleteOptions, UseGoogleAutocompleteResult } from './hooks/useGoogleAutocomplete';
|
|
38
52
|
export type { ISOCountry, ISORegion, UseISODataResult } from './hooks/useISOData';
|
|
39
53
|
export type { UsePluginConfigOptions, UsePluginConfigResult } from './hooks/usePluginConfig';
|
|
54
|
+
export type { TranslateFunction, UseTranslationOptions, UseTranslationResult } from './hooks/useTranslation';
|
|
40
55
|
export type { UseCheckoutQueryOptions as UseCheckoutOptions, UseCheckoutQueryResult as UseCheckoutResult } from './hooks/useCheckoutQuery';
|
|
41
56
|
export type { UseDiscountsQueryOptions as UseDiscountsOptions, UseDiscountsQueryResult as UseDiscountsResult } from './hooks/useDiscountsQuery';
|
|
57
|
+
export type { FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext, UseFunnelOptions, UseFunnelResult } from './hooks/useFunnel';
|
|
42
58
|
export type { UseOffersQueryOptions as UseOffersOptions, UseOffersQueryResult as UseOffersResult } from './hooks/useOffersQuery';
|
|
43
59
|
export type { UseOrderBumpQueryOptions as UseOrderBumpOptions, UseOrderBumpQueryResult as UseOrderBumpResult } from './hooks/useOrderBumpQuery';
|
|
44
60
|
export type { UseOrderQueryOptions as UseOrderOptions, UseOrderQueryResult as UseOrderResult } from './hooks/useOrderQuery';
|
|
@@ -50,6 +66,5 @@ export type { UseShippingRatesQueryOptions as UseShippingRatesOptions, UseShippi
|
|
|
50
66
|
export type { UseStoreConfigQueryOptions as UseStoreConfigOptions, UseStoreConfigQueryResult as UseStoreConfigResult } from './hooks/useStoreConfigQuery';
|
|
51
67
|
export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession } from './hooks/useThreeds';
|
|
52
68
|
export type { UseVipOffersQueryOptions as UseVipOffersOptions, UseVipOffersQueryResult as UseVipOffersResult } from './hooks/useVipOffersQuery';
|
|
53
|
-
export type { UseFunnelOptions, UseFunnelResult, FunnelEvent, FunnelNavigationAction, FunnelNavigationResult, SimpleFunnelContext } from './hooks/useFunnel';
|
|
54
69
|
export { formatMoney } from '../../react/utils/money';
|
|
55
70
|
export type OrderItem = import('../core/utils/order').OrderLineItem;
|
package/dist/v2/react/index.js
CHANGED
|
@@ -9,11 +9,18 @@ export { TagadaProvider, useTagadaContext } from './providers/TagadaProvider';
|
|
|
9
9
|
export { ApplePayButton } from './components/ApplePayButton';
|
|
10
10
|
export { GooglePayButton } from './components/GooglePayButton';
|
|
11
11
|
// Hooks
|
|
12
|
+
export { useAuth } from './hooks/useAuth';
|
|
12
13
|
export { useCheckoutToken } from './hooks/useCheckoutToken';
|
|
14
|
+
export { useClubOffers } from './hooks/useClubOffers';
|
|
15
|
+
export { useCustomer } from './hooks/useCustomer';
|
|
16
|
+
export { useCustomerInfos } from './hooks/useCustomerInfos';
|
|
17
|
+
export { useCustomerOrders } from './hooks/useCustomerOrders';
|
|
18
|
+
export { useCustomerSubscriptions } from './hooks/useCustomerSubscriptions';
|
|
13
19
|
export { useExpressPaymentMethods } from './hooks/useExpressPaymentMethods';
|
|
14
20
|
export { useGeoLocation } from './hooks/useGeoLocation';
|
|
15
21
|
export { useGoogleAutocomplete } from './hooks/useGoogleAutocomplete';
|
|
16
22
|
export { getAvailableLanguages, useCountryOptions, useISOData, useLanguageImport, useRegionOptions } from './hooks/useISOData';
|
|
23
|
+
export { useLogin } from './hooks/useLogin';
|
|
17
24
|
export { usePluginConfig } from './hooks/usePluginConfig';
|
|
18
25
|
// TanStack Query hooks (recommended)
|
|
19
26
|
export { queryKeys, useApiMutation, useApiQuery, useInvalidateQuery, usePreloadQuery } from './hooks/useApiQuery';
|
|
@@ -31,6 +38,7 @@ export { useShippingRatesQuery as useShippingRates } from './hooks/useShippingRa
|
|
|
31
38
|
export { useStoreConfigQuery as useStoreConfig } from './hooks/useStoreConfigQuery';
|
|
32
39
|
export { useThreeds } from './hooks/useThreeds';
|
|
33
40
|
export { useThreedsModal } from './hooks/useThreedsModal';
|
|
41
|
+
export { useTranslation } from './hooks/useTranslation';
|
|
34
42
|
export { useVipOffersQuery as useVipOffers } from './hooks/useVipOffersQuery';
|
|
35
43
|
// Funnel hooks
|
|
36
44
|
export { useFunnel, useSimpleFunnel } from './hooks/useFunnel';
|
package/package.json
CHANGED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single Discount Hook using TanStack Query
|
|
3
|
-
* Fetches a specific discount for a given store
|
|
4
|
-
*/
|
|
5
|
-
import { UseQueryResult } from '@tanstack/react-query';
|
|
6
|
-
export interface StoreDiscountRuleAmount {
|
|
7
|
-
rate: number;
|
|
8
|
-
amount: number;
|
|
9
|
-
lock: boolean;
|
|
10
|
-
date: string;
|
|
11
|
-
}
|
|
12
|
-
export interface StoreDiscountRule {
|
|
13
|
-
id: string;
|
|
14
|
-
createdAt: string;
|
|
15
|
-
updatedAt: string;
|
|
16
|
-
promotionId: string;
|
|
17
|
-
type: string;
|
|
18
|
-
productId: string | null;
|
|
19
|
-
minimumQuantity: number | null;
|
|
20
|
-
minimumAmount: Record<string, StoreDiscountRuleAmount> | null;
|
|
21
|
-
variantIds: string[] | null;
|
|
22
|
-
}
|
|
23
|
-
export interface StoreDiscountAction {
|
|
24
|
-
id: string;
|
|
25
|
-
createdAt: string;
|
|
26
|
-
updatedAt: string;
|
|
27
|
-
promotionId: string;
|
|
28
|
-
type: string;
|
|
29
|
-
adjustmentAmount: number | null;
|
|
30
|
-
adjustmentPercentage: number | null;
|
|
31
|
-
adjustmentType: string | null;
|
|
32
|
-
freeShipping: boolean | null;
|
|
33
|
-
priceIdToAdd: string | null;
|
|
34
|
-
productIdToAdd: string | null;
|
|
35
|
-
variantIdToAdd: string | null;
|
|
36
|
-
subscriptionFreeTrialDuration: number | null;
|
|
37
|
-
subscriptionFreeTrialDurationType: string | null;
|
|
38
|
-
targetProductId: string | null;
|
|
39
|
-
targetVariantIds: string[] | null;
|
|
40
|
-
maxQuantityDiscounted: number | null;
|
|
41
|
-
appliesOnEachItem: boolean | null;
|
|
42
|
-
}
|
|
43
|
-
export interface StoreDiscount {
|
|
44
|
-
id: string;
|
|
45
|
-
createdAt: string;
|
|
46
|
-
updatedAt: string;
|
|
47
|
-
storeId: string;
|
|
48
|
-
accountId: string;
|
|
49
|
-
name: string;
|
|
50
|
-
code: string;
|
|
51
|
-
automatic: boolean;
|
|
52
|
-
usageLimit: number | null;
|
|
53
|
-
usageCount: number;
|
|
54
|
-
startDate: string;
|
|
55
|
-
endDate: string | null;
|
|
56
|
-
enabled: boolean;
|
|
57
|
-
archived: boolean;
|
|
58
|
-
ruleOperator: string;
|
|
59
|
-
externalId: string | null;
|
|
60
|
-
combinesWithOrderLevelDiscounts: boolean;
|
|
61
|
-
combinesWithLineItemDiscounts: boolean;
|
|
62
|
-
combinesWithShippingDiscounts: boolean;
|
|
63
|
-
forceCombine: boolean;
|
|
64
|
-
isTemporary: boolean;
|
|
65
|
-
rules: StoreDiscountRule[];
|
|
66
|
-
actions: StoreDiscountAction[];
|
|
67
|
-
}
|
|
68
|
-
export interface UseDiscountQueryOptions {
|
|
69
|
-
storeId?: string;
|
|
70
|
-
discountId?: string;
|
|
71
|
-
enabled?: boolean;
|
|
72
|
-
}
|
|
73
|
-
export interface UseDiscountQueryResult<TData = StoreDiscount> {
|
|
74
|
-
discount: TData | undefined;
|
|
75
|
-
isLoading: boolean;
|
|
76
|
-
error: Error | null;
|
|
77
|
-
refetch: UseQueryResult<TData>['refetch'];
|
|
78
|
-
}
|
|
79
|
-
export declare function useDiscountQuery<TData = StoreDiscount>(options: UseDiscountQueryOptions): UseDiscountQueryResult<TData>;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single Discount Hook using TanStack Query
|
|
3
|
-
* Fetches a specific discount for a given store
|
|
4
|
-
*/
|
|
5
|
-
import { useMemo } from 'react';
|
|
6
|
-
import { useApiQuery } from './useApiQuery';
|
|
7
|
-
import { usePluginConfig } from './usePluginConfig';
|
|
8
|
-
export function useDiscountQuery(options) {
|
|
9
|
-
const { storeId: storeIdFromConfig } = usePluginConfig();
|
|
10
|
-
const { storeId = storeIdFromConfig, discountId, enabled = true } = options;
|
|
11
|
-
const key = useMemo(() => ['discount', storeId, discountId], [storeId, discountId]);
|
|
12
|
-
const url = useMemo(() => {
|
|
13
|
-
if (!storeId || !discountId)
|
|
14
|
-
return null;
|
|
15
|
-
return `/api/v1/stores/${storeId}/discounts/${discountId}`;
|
|
16
|
-
}, [storeId, discountId]);
|
|
17
|
-
const query = useApiQuery(key, url, { enabled });
|
|
18
|
-
return {
|
|
19
|
-
discount: query.data,
|
|
20
|
-
isLoading: query.isLoading,
|
|
21
|
-
error: query.error || null,
|
|
22
|
-
refetch: query.refetch,
|
|
23
|
-
};
|
|
24
|
-
}
|