@akin-travel/partner-sdk 1.0.5
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/README.md +1204 -0
- package/dist/account/components/AccountInfoSection.d.ts +46 -0
- package/dist/account/components/AccountInfoSection.d.ts.map +1 -0
- package/dist/account/components/AccountInfoSection.js +52 -0
- package/dist/account/components/AccountInfoSection.js.map +1 -0
- package/dist/account/components/NotificationPreferencesSection.d.ts +40 -0
- package/dist/account/components/NotificationPreferencesSection.d.ts.map +1 -0
- package/dist/account/components/NotificationPreferencesSection.js +116 -0
- package/dist/account/components/NotificationPreferencesSection.js.map +1 -0
- package/dist/account/components/PasskeySection.d.ts +49 -0
- package/dist/account/components/PasskeySection.d.ts.map +1 -0
- package/dist/account/components/PasskeySection.js +298 -0
- package/dist/account/components/PasskeySection.js.map +1 -0
- package/dist/account/hooks/useAccountForm.d.ts +23 -0
- package/dist/account/hooks/useAccountForm.d.ts.map +1 -0
- package/dist/account/hooks/useAccountForm.js +133 -0
- package/dist/account/hooks/useAccountForm.js.map +1 -0
- package/dist/account/index.d.ts +10 -0
- package/dist/account/index.d.ts.map +1 -0
- package/dist/account/index.js +21 -0
- package/dist/account/index.js.map +1 -0
- package/dist/auth/AkinAuthProvider.d.ts +31 -0
- package/dist/auth/AkinAuthProvider.d.ts.map +1 -0
- package/dist/auth/AkinAuthProvider.js +632 -0
- package/dist/auth/AkinAuthProvider.js.map +1 -0
- package/dist/auth/components/LoginForm.d.ts +63 -0
- package/dist/auth/components/LoginForm.d.ts.map +1 -0
- package/dist/auth/components/LoginForm.js +230 -0
- package/dist/auth/components/LoginForm.js.map +1 -0
- package/dist/auth/components/MagicLinkForm.d.ts +41 -0
- package/dist/auth/components/MagicLinkForm.d.ts.map +1 -0
- package/dist/auth/components/MagicLinkForm.js +88 -0
- package/dist/auth/components/MagicLinkForm.js.map +1 -0
- package/dist/auth/components/RequireAuth.d.ts +62 -0
- package/dist/auth/components/RequireAuth.d.ts.map +1 -0
- package/dist/auth/components/RequireAuth.js +63 -0
- package/dist/auth/components/RequireAuth.js.map +1 -0
- package/dist/auth/components/RequireGuest.d.ts +60 -0
- package/dist/auth/components/RequireGuest.d.ts.map +1 -0
- package/dist/auth/components/RequireGuest.js +64 -0
- package/dist/auth/components/RequireGuest.js.map +1 -0
- package/dist/auth/components/SignupForm.d.ts +45 -0
- package/dist/auth/components/SignupForm.d.ts.map +1 -0
- package/dist/auth/components/SignupForm.js +167 -0
- package/dist/auth/components/SignupForm.js.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +21 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +136 -0
- package/dist/client.js.map +1 -0
- package/dist/components/PhoneInput.d.ts +62 -0
- package/dist/components/PhoneInput.d.ts.map +1 -0
- package/dist/components/PhoneInput.js +65 -0
- package/dist/components/PhoneInput.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config.d.ts +111 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +56 -0
- package/dist/config.js.map +1 -0
- package/dist/constants/preferences.d.ts +22 -0
- package/dist/constants/preferences.d.ts.map +1 -0
- package/dist/constants/preferences.js +52 -0
- package/dist/constants/preferences.js.map +1 -0
- package/dist/currency/CurrencyProvider.d.ts +46 -0
- package/dist/currency/CurrencyProvider.d.ts.map +1 -0
- package/dist/currency/CurrencyProvider.js +145 -0
- package/dist/currency/CurrencyProvider.js.map +1 -0
- package/dist/currency/components/CurrencySelector.d.ts +43 -0
- package/dist/currency/components/CurrencySelector.d.ts.map +1 -0
- package/dist/currency/components/CurrencySelector.js +58 -0
- package/dist/currency/components/CurrencySelector.js.map +1 -0
- package/dist/currency/exchangeRates.d.ts +40 -0
- package/dist/currency/exchangeRates.d.ts.map +1 -0
- package/dist/currency/exchangeRates.js +90 -0
- package/dist/currency/exchangeRates.js.map +1 -0
- package/dist/currency/index.d.ts +6 -0
- package/dist/currency/index.d.ts.map +1 -0
- package/dist/currency/index.js +20 -0
- package/dist/currency/index.js.map +1 -0
- package/dist/header/components/CurrencyAccordion.d.ts +45 -0
- package/dist/header/components/CurrencyAccordion.d.ts.map +1 -0
- package/dist/header/components/CurrencyAccordion.js +54 -0
- package/dist/header/components/CurrencyAccordion.js.map +1 -0
- package/dist/header/components/HeaderMenu.d.ts +49 -0
- package/dist/header/components/HeaderMenu.d.ts.map +1 -0
- package/dist/header/components/HeaderMenu.js +95 -0
- package/dist/header/components/HeaderMenu.js.map +1 -0
- package/dist/header/components/LanguageAccordion.d.ts +45 -0
- package/dist/header/components/LanguageAccordion.d.ts.map +1 -0
- package/dist/header/components/LanguageAccordion.js +54 -0
- package/dist/header/components/LanguageAccordion.js.map +1 -0
- package/dist/header/components/UserAvatar.d.ts +26 -0
- package/dist/header/components/UserAvatar.d.ts.map +1 -0
- package/dist/header/components/UserAvatar.js +46 -0
- package/dist/header/components/UserAvatar.js.map +1 -0
- package/dist/header/index.d.ts +10 -0
- package/dist/header/index.d.ts.map +1 -0
- package/dist/header/index.js +13 -0
- package/dist/header/index.js.map +1 -0
- package/dist/i18n/I18nProvider.d.ts +57 -0
- package/dist/i18n/I18nProvider.d.ts.map +1 -0
- package/dist/i18n/I18nProvider.js +205 -0
- package/dist/i18n/I18nProvider.js.map +1 -0
- package/dist/i18n/components/LanguageSelector.d.ts +43 -0
- package/dist/i18n/components/LanguageSelector.d.ts.map +1 -0
- package/dist/i18n/components/LanguageSelector.js +57 -0
- package/dist/i18n/components/LanguageSelector.js.map +1 -0
- package/dist/i18n/index.d.ts +5 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +14 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/translations/en.json +283 -0
- package/dist/i18n/translations/es.json +283 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +191 -0
- package/dist/index.js.map +1 -0
- package/dist/loyalty/AkinLoyaltyProvider.d.ts +18 -0
- package/dist/loyalty/AkinLoyaltyProvider.d.ts.map +1 -0
- package/dist/loyalty/AkinLoyaltyProvider.js +399 -0
- package/dist/loyalty/AkinLoyaltyProvider.js.map +1 -0
- package/dist/loyalty/components/LoyaltyCard.d.ts +48 -0
- package/dist/loyalty/components/LoyaltyCard.d.ts.map +1 -0
- package/dist/loyalty/components/LoyaltyCard.js +140 -0
- package/dist/loyalty/components/LoyaltyCard.js.map +1 -0
- package/dist/loyalty/components/PointsDisplay.d.ts +40 -0
- package/dist/loyalty/components/PointsDisplay.d.ts.map +1 -0
- package/dist/loyalty/components/PointsDisplay.js +32 -0
- package/dist/loyalty/components/PointsDisplay.js.map +1 -0
- package/dist/loyalty/components/PreviousStays.d.ts +59 -0
- package/dist/loyalty/components/PreviousStays.d.ts.map +1 -0
- package/dist/loyalty/components/PreviousStays.js +101 -0
- package/dist/loyalty/components/PreviousStays.js.map +1 -0
- package/dist/loyalty/components/SimpleTierCards.d.ts +51 -0
- package/dist/loyalty/components/SimpleTierCards.d.ts.map +1 -0
- package/dist/loyalty/components/SimpleTierCards.js +96 -0
- package/dist/loyalty/components/SimpleTierCards.js.map +1 -0
- package/dist/loyalty/components/TierCard.d.ts +30 -0
- package/dist/loyalty/components/TierCard.d.ts.map +1 -0
- package/dist/loyalty/components/TierCard.js +41 -0
- package/dist/loyalty/components/TierCard.js.map +1 -0
- package/dist/loyalty/components/TierProgress.d.ts +32 -0
- package/dist/loyalty/components/TierProgress.d.ts.map +1 -0
- package/dist/loyalty/components/TierProgress.js +41 -0
- package/dist/loyalty/components/TierProgress.js.map +1 -0
- package/dist/loyalty/components/TierRequirementsTable.d.ts +54 -0
- package/dist/loyalty/components/TierRequirementsTable.d.ts.map +1 -0
- package/dist/loyalty/components/TierRequirementsTable.js +104 -0
- package/dist/loyalty/components/TierRequirementsTable.js.map +1 -0
- package/dist/loyalty/components/TransactionList.d.ts +44 -0
- package/dist/loyalty/components/TransactionList.d.ts.map +1 -0
- package/dist/loyalty/components/TransactionList.js +112 -0
- package/dist/loyalty/components/TransactionList.js.map +1 -0
- package/dist/loyalty/components/UpcomingStays.d.ts +49 -0
- package/dist/loyalty/components/UpcomingStays.d.ts.map +1 -0
- package/dist/loyalty/components/UpcomingStays.js +60 -0
- package/dist/loyalty/components/UpcomingStays.js.map +1 -0
- package/dist/loyalty/index.d.ts +12 -0
- package/dist/loyalty/index.d.ts.map +1 -0
- package/dist/loyalty/index.js +27 -0
- package/dist/loyalty/index.js.map +1 -0
- package/dist/types/account.d.ts +108 -0
- package/dist/types/account.d.ts.map +1 -0
- package/dist/types/account.js +3 -0
- package/dist/types/account.js.map +1 -0
- package/dist/types/auth.d.ts +205 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +3 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/currency.d.ts +102 -0
- package/dist/types/currency.d.ts.map +1 -0
- package/dist/types/currency.js +3 -0
- package/dist/types/currency.js.map +1 -0
- package/dist/types/header.d.ts +105 -0
- package/dist/types/header.d.ts.map +1 -0
- package/dist/types/header.js +3 -0
- package/dist/types/header.js.map +1 -0
- package/dist/types/i18n.d.ts +90 -0
- package/dist/types/i18n.d.ts.map +1 -0
- package/dist/types/i18n.js +3 -0
- package/dist/types/i18n.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/loyalty.d.ts +312 -0
- package/dist/types/loyalty.d.ts.map +1 -0
- package/dist/types/loyalty.js +3 -0
- package/dist/types/loyalty.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/tierLabels.d.ts +27 -0
- package/dist/utils/tierLabels.d.ts.map +1 -0
- package/dist/utils/tierLabels.js +110 -0
- package/dist/utils/tierLabels.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { AccountInfoRenderProps } from '../../types/account';
|
|
3
|
+
export interface AccountInfoSectionProps {
|
|
4
|
+
/**
|
|
5
|
+
* Render function receiving account form state and actions
|
|
6
|
+
*/
|
|
7
|
+
children: (props: AccountInfoRenderProps) => ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Callback when profile is successfully updated
|
|
10
|
+
*/
|
|
11
|
+
onSuccess?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Callback when profile update fails
|
|
14
|
+
*/
|
|
15
|
+
onError?: (error: Error) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Headless account info section component
|
|
19
|
+
*
|
|
20
|
+
* Provides form state and actions for displaying/editing member profile
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* <AccountInfoSection>
|
|
24
|
+
* {({ member, isEditing, formData, setFormField, handleSubmit, handleCancel }) => (
|
|
25
|
+
* <div>
|
|
26
|
+
* {isEditing ? (
|
|
27
|
+
* <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
|
|
28
|
+
* <input
|
|
29
|
+
* value={formData.firstName}
|
|
30
|
+
* onChange={(e) => setFormField('firstName', e.target.value)}
|
|
31
|
+
* />
|
|
32
|
+
* <button type="submit">Save</button>
|
|
33
|
+
* <button type="button" onClick={handleCancel}>Cancel</button>
|
|
34
|
+
* </form>
|
|
35
|
+
* ) : (
|
|
36
|
+
* <div>
|
|
37
|
+
* <p>{member?.firstName} {member?.lastName}</p>
|
|
38
|
+
* <button onClick={() => setIsEditing(true)}>Edit</button>
|
|
39
|
+
* </div>
|
|
40
|
+
* )}
|
|
41
|
+
* </div>
|
|
42
|
+
* )}
|
|
43
|
+
* </AccountInfoSection>
|
|
44
|
+
*/
|
|
45
|
+
export declare function AccountInfoSection({ children, onSuccess, onError }: AccountInfoSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
//# sourceMappingURL=AccountInfoSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountInfoSection.d.ts","sourceRoot":"","sources":["../../../src/account/components/AccountInfoSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,SAAS,CAAC;IACvD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,uBAAuB,2CAiB3F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AccountInfoSection = AccountInfoSection;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const useAccountForm_1 = require("../hooks/useAccountForm");
|
|
7
|
+
/**
|
|
8
|
+
* Headless account info section component
|
|
9
|
+
*
|
|
10
|
+
* Provides form state and actions for displaying/editing member profile
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* <AccountInfoSection>
|
|
14
|
+
* {({ member, isEditing, formData, setFormField, handleSubmit, handleCancel }) => (
|
|
15
|
+
* <div>
|
|
16
|
+
* {isEditing ? (
|
|
17
|
+
* <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
|
|
18
|
+
* <input
|
|
19
|
+
* value={formData.firstName}
|
|
20
|
+
* onChange={(e) => setFormField('firstName', e.target.value)}
|
|
21
|
+
* />
|
|
22
|
+
* <button type="submit">Save</button>
|
|
23
|
+
* <button type="button" onClick={handleCancel}>Cancel</button>
|
|
24
|
+
* </form>
|
|
25
|
+
* ) : (
|
|
26
|
+
* <div>
|
|
27
|
+
* <p>{member?.firstName} {member?.lastName}</p>
|
|
28
|
+
* <button onClick={() => setIsEditing(true)}>Edit</button>
|
|
29
|
+
* </div>
|
|
30
|
+
* )}
|
|
31
|
+
* </div>
|
|
32
|
+
* )}
|
|
33
|
+
* </AccountInfoSection>
|
|
34
|
+
*/
|
|
35
|
+
function AccountInfoSection({ children, onSuccess, onError }) {
|
|
36
|
+
const props = (0, useAccountForm_1.useAccountForm)();
|
|
37
|
+
// Wrap handleSubmit to call callbacks
|
|
38
|
+
const wrappedProps = {
|
|
39
|
+
...props,
|
|
40
|
+
handleSubmit: async () => {
|
|
41
|
+
try {
|
|
42
|
+
await props.handleSubmit();
|
|
43
|
+
onSuccess?.();
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
onError?.(err instanceof Error ? err : new Error('Unknown error'));
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children(wrappedProps) });
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=AccountInfoSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountInfoSection.js","sourceRoot":"","sources":["../../../src/account/components/AccountInfoSection.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAiDb,gDAiBC;;AA/DD,4DAAyD;AAkBzD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAA2B;IAC1F,MAAM,KAAK,GAAG,IAAA,+BAAc,GAAE,CAAC;IAE/B,sCAAsC;IACtC,MAAM,YAAY,GAA2B;QAC3C,GAAG,KAAK;QACR,YAAY,EAAE,KAAK,IAAI,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;gBAC3B,SAAS,EAAE,EAAE,CAAC;YAChB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;KACF,CAAC;IAEF,OAAO,2DAAG,QAAQ,CAAC,YAAY,CAAC,GAAI,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { NotificationPreferencesRenderProps } from '../../types/account';
|
|
3
|
+
export interface NotificationPreferencesSectionProps {
|
|
4
|
+
/**
|
|
5
|
+
* Render function receiving preferences state and actions
|
|
6
|
+
*/
|
|
7
|
+
children: (props: NotificationPreferencesRenderProps) => ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Callback when preferences are successfully saved
|
|
10
|
+
*/
|
|
11
|
+
onSuccess?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Callback when save fails
|
|
14
|
+
*/
|
|
15
|
+
onError?: (error: Error) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Headless notification preferences section component
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* <NotificationPreferencesSection>
|
|
22
|
+
* {({ preferences, setPreference, handleSave, isLoading }) => (
|
|
23
|
+
* <div>
|
|
24
|
+
* <label>
|
|
25
|
+
* <input
|
|
26
|
+
* type="checkbox"
|
|
27
|
+
* checked={preferences.marketingOptIn}
|
|
28
|
+
* onChange={(e) => setPreference('marketingOptIn', e.target.checked)}
|
|
29
|
+
* />
|
|
30
|
+
* Marketing communications
|
|
31
|
+
* </label>
|
|
32
|
+
* <button onClick={handleSave} disabled={isLoading}>
|
|
33
|
+
* Save
|
|
34
|
+
* </button>
|
|
35
|
+
* </div>
|
|
36
|
+
* )}
|
|
37
|
+
* </NotificationPreferencesSection>
|
|
38
|
+
*/
|
|
39
|
+
export declare function NotificationPreferencesSection({ children, onSuccess, onError, }: NotificationPreferencesSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
//# sourceMappingURL=NotificationPreferencesSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationPreferencesSection.d.ts","sourceRoot":"","sources":["../../../src/account/components/NotificationPreferencesSection.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjF,OAAO,KAAK,EAEV,kCAAkC,EACnC,MAAM,qBAAqB,CAAC;AAY7B,MAAM,WAAW,mCAAmC;IAClD;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,kCAAkC,KAAK,SAAS,CAAC;IACnE;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,QAAQ,EACR,SAAS,EACT,OAAO,GACR,EAAE,mCAAmC,2CAyFrC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.NotificationPreferencesSection = NotificationPreferencesSection;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const client_1 = require("@apollo/client");
|
|
8
|
+
const auth_1 = require("../../auth");
|
|
9
|
+
const client_2 = require("../../client");
|
|
10
|
+
// GraphQL mutation for updating notification preferences
|
|
11
|
+
const UPDATE_NOTIFICATION_PREFERENCES = (0, client_2.gql) `
|
|
12
|
+
mutation UpdateMember($id: ID!, $input: UpdateMemberInput!) {
|
|
13
|
+
updateMember(id: $id, input: $input) {
|
|
14
|
+
id
|
|
15
|
+
marketingOptIn
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
/**
|
|
20
|
+
* Headless notification preferences section component
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* <NotificationPreferencesSection>
|
|
24
|
+
* {({ preferences, setPreference, handleSave, isLoading }) => (
|
|
25
|
+
* <div>
|
|
26
|
+
* <label>
|
|
27
|
+
* <input
|
|
28
|
+
* type="checkbox"
|
|
29
|
+
* checked={preferences.marketingOptIn}
|
|
30
|
+
* onChange={(e) => setPreference('marketingOptIn', e.target.checked)}
|
|
31
|
+
* />
|
|
32
|
+
* Marketing communications
|
|
33
|
+
* </label>
|
|
34
|
+
* <button onClick={handleSave} disabled={isLoading}>
|
|
35
|
+
* Save
|
|
36
|
+
* </button>
|
|
37
|
+
* </div>
|
|
38
|
+
* )}
|
|
39
|
+
* </NotificationPreferencesSection>
|
|
40
|
+
*/
|
|
41
|
+
function NotificationPreferencesSection({ children, onSuccess, onError, }) {
|
|
42
|
+
const { member, refreshMemberData } = (0, auth_1.useAkinAuth)();
|
|
43
|
+
const [updatePreferences] = (0, client_1.useMutation)(UPDATE_NOTIFICATION_PREFERENCES);
|
|
44
|
+
// Initialize with member data or defaults
|
|
45
|
+
const [preferences, setPreferences] = (0, react_1.useState)({
|
|
46
|
+
marketingOptIn: member?.marketingOptIn ?? false,
|
|
47
|
+
});
|
|
48
|
+
// Track initial preferences for dirty checking
|
|
49
|
+
const initialPreferencesRef = (0, react_1.useRef)(preferences);
|
|
50
|
+
const [isLoading, setIsLoading] = (0, react_1.useState)(false);
|
|
51
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
52
|
+
const [success, setSuccess] = (0, react_1.useState)(null);
|
|
53
|
+
// Sync preferences when member data changes
|
|
54
|
+
(0, react_1.useEffect)(() => {
|
|
55
|
+
if (member) {
|
|
56
|
+
const newPrefs = {
|
|
57
|
+
marketingOptIn: member.marketingOptIn ?? false,
|
|
58
|
+
};
|
|
59
|
+
setPreferences(newPrefs);
|
|
60
|
+
initialPreferencesRef.current = newPrefs;
|
|
61
|
+
}
|
|
62
|
+
}, [member]);
|
|
63
|
+
// Check if preferences have changed
|
|
64
|
+
const isDirty = preferences.marketingOptIn !== initialPreferencesRef.current.marketingOptIn;
|
|
65
|
+
// Update a preference
|
|
66
|
+
const setPreference = (0, react_1.useCallback)((key, value) => {
|
|
67
|
+
setPreferences((prev) => ({ ...prev, [key]: value }));
|
|
68
|
+
}, []);
|
|
69
|
+
// Save preferences
|
|
70
|
+
const handleSave = (0, react_1.useCallback)(async () => {
|
|
71
|
+
if (!member?.id) {
|
|
72
|
+
setError('No member data available');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
setIsLoading(true);
|
|
76
|
+
setError(null);
|
|
77
|
+
setSuccess(null);
|
|
78
|
+
try {
|
|
79
|
+
await updatePreferences({
|
|
80
|
+
variables: {
|
|
81
|
+
id: member.id,
|
|
82
|
+
input: {
|
|
83
|
+
marketingOptIn: preferences.marketingOptIn,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
// Refresh member data
|
|
88
|
+
await refreshMemberData();
|
|
89
|
+
// Update initial preferences ref
|
|
90
|
+
initialPreferencesRef.current = { ...preferences };
|
|
91
|
+
setSuccess('Preferences saved');
|
|
92
|
+
onSuccess?.();
|
|
93
|
+
// Clear success after 3 seconds
|
|
94
|
+
setTimeout(() => setSuccess(null), 3000);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to save preferences';
|
|
98
|
+
setError(errorMessage);
|
|
99
|
+
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
setIsLoading(false);
|
|
103
|
+
}
|
|
104
|
+
}, [member?.id, preferences, updatePreferences, refreshMemberData, onSuccess, onError]);
|
|
105
|
+
const props = {
|
|
106
|
+
preferences,
|
|
107
|
+
setPreference,
|
|
108
|
+
handleSave,
|
|
109
|
+
isLoading,
|
|
110
|
+
error,
|
|
111
|
+
success,
|
|
112
|
+
isDirty,
|
|
113
|
+
};
|
|
114
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children(props) });
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=NotificationPreferencesSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationPreferencesSection.js","sourceRoot":"","sources":["../../../src/account/components/NotificationPreferencesSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { PasskeySectionRenderProps } from '../../types/account';
|
|
3
|
+
export declare const PASSKEY_REGISTRATION_OPTIONS: import("@apollo/client").DocumentNode;
|
|
4
|
+
export declare const PASSKEY_REGISTER: import("@apollo/client").DocumentNode;
|
|
5
|
+
export declare const MY_PASSKEYS: import("@apollo/client").DocumentNode;
|
|
6
|
+
export declare const PASSKEY_DELETE: import("@apollo/client").DocumentNode;
|
|
7
|
+
export interface PasskeySectionProps {
|
|
8
|
+
/**
|
|
9
|
+
* Render function receiving passkey state and actions
|
|
10
|
+
*/
|
|
11
|
+
children: (props: PasskeySectionRenderProps) => ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Callback when passkey is successfully registered
|
|
14
|
+
*/
|
|
15
|
+
onRegisterSuccess?: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Callback when passkey is successfully removed
|
|
18
|
+
*/
|
|
19
|
+
onRemoveSuccess?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Callback when an error occurs
|
|
22
|
+
*/
|
|
23
|
+
onError?: (error: Error) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Headless passkey management section component
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* <PasskeySection>
|
|
30
|
+
* {({ passkeys, isSupported, registerPasskey, removePasskey, isLoading }) => (
|
|
31
|
+
* <div>
|
|
32
|
+
* {!isSupported && <p>Passkeys not supported in this browser</p>}
|
|
33
|
+
* <ul>
|
|
34
|
+
* {passkeys.map((pk) => (
|
|
35
|
+
* <li key={pk.id}>
|
|
36
|
+
* {pk.name}
|
|
37
|
+
* <button onClick={() => removePasskey(pk.id)}>Remove</button>
|
|
38
|
+
* </li>
|
|
39
|
+
* ))}
|
|
40
|
+
* </ul>
|
|
41
|
+
* <button onClick={registerPasskey} disabled={isLoading || !isSupported}>
|
|
42
|
+
* Add Passkey
|
|
43
|
+
* </button>
|
|
44
|
+
* </div>
|
|
45
|
+
* )}
|
|
46
|
+
* </PasskeySection>
|
|
47
|
+
*/
|
|
48
|
+
export declare function PasskeySection({ children, onRegisterSuccess, onRemoveSuccess, onError, }: PasskeySectionProps): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
//# sourceMappingURL=PasskeySection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasskeySection.d.ts","sourceRoot":"","sources":["../../../src/account/components/PasskeySection.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIzE,OAAO,KAAK,EAAqB,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAKxF,eAAO,MAAM,4BAA4B,uCAcxC,CAAC;AAEF,eAAO,MAAM,gBAAgB,uCAgB5B,CAAC;AAGF,eAAO,MAAM,WAAW,uCAUvB,CAAC;AAEF,eAAO,MAAM,cAAc,uCAI1B,CAAC;AAgBF,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,SAAS,CAAC;IAC1D;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,OAAO,GACR,EAAE,mBAAmB,2CA+LrB"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.PASSKEY_DELETE = exports.MY_PASSKEYS = exports.PASSKEY_REGISTER = exports.PASSKEY_REGISTRATION_OPTIONS = void 0;
|
|
38
|
+
exports.PasskeySection = PasskeySection;
|
|
39
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
40
|
+
const react_1 = require("react");
|
|
41
|
+
const client_1 = require("@apollo/client");
|
|
42
|
+
const auth_1 = require("../../auth");
|
|
43
|
+
const client_2 = require("../../client");
|
|
44
|
+
// GraphQL operations for passkey management
|
|
45
|
+
// Note: API signatures match apps/api/src/resolvers/Passkey.resolver.ts
|
|
46
|
+
exports.PASSKEY_REGISTRATION_OPTIONS = (0, client_2.gql) `
|
|
47
|
+
mutation PasskeyRegistrationOptions(
|
|
48
|
+
$userId: String!
|
|
49
|
+
$userName: String!
|
|
50
|
+
$userEmail: String!
|
|
51
|
+
$tenantId: String!
|
|
52
|
+
) {
|
|
53
|
+
passkeyRegistrationOptions(
|
|
54
|
+
userId: $userId
|
|
55
|
+
userName: $userName
|
|
56
|
+
userEmail: $userEmail
|
|
57
|
+
tenantId: $tenantId
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
exports.PASSKEY_REGISTER = (0, client_2.gql) `
|
|
62
|
+
mutation PasskeyRegister(
|
|
63
|
+
$userId: String!
|
|
64
|
+
$userType: PasskeyUserType!
|
|
65
|
+
$tenantId: String!
|
|
66
|
+
$registrationResponse: JSONObject!
|
|
67
|
+
$expectedChallenge: String!
|
|
68
|
+
) {
|
|
69
|
+
passkeyRegister(
|
|
70
|
+
userId: $userId
|
|
71
|
+
userType: $userType
|
|
72
|
+
tenantId: $tenantId
|
|
73
|
+
registrationResponse: $registrationResponse
|
|
74
|
+
expectedChallenge: $expectedChallenge
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
// Query to get user's registered passkeys (uses authenticated context)
|
|
79
|
+
exports.MY_PASSKEYS = (0, client_2.gql) `
|
|
80
|
+
query MyPasskeys {
|
|
81
|
+
myPasskeys {
|
|
82
|
+
id
|
|
83
|
+
userAgent
|
|
84
|
+
credentialDeviceType
|
|
85
|
+
createdAt
|
|
86
|
+
lastUsedAt
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
`;
|
|
90
|
+
exports.PASSKEY_DELETE = (0, client_2.gql) `
|
|
91
|
+
mutation DeletePasskey($credentialId: String!) {
|
|
92
|
+
deletePasskey(credentialId: $credentialId)
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
// Helper to dynamically import browser-only WebAuthn functions
|
|
96
|
+
async function importWebAuthnBrowser() {
|
|
97
|
+
if (typeof window === 'undefined') {
|
|
98
|
+
throw new Error('WebAuthn is only available in the browser');
|
|
99
|
+
}
|
|
100
|
+
return await Promise.resolve().then(() => __importStar(require('@simplewebauthn/browser')));
|
|
101
|
+
}
|
|
102
|
+
// Check for WebAuthn support
|
|
103
|
+
function isPasskeySupported() {
|
|
104
|
+
if (typeof window === 'undefined')
|
|
105
|
+
return false;
|
|
106
|
+
return window?.PublicKeyCredential !== undefined && typeof window.PublicKeyCredential === 'function';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Headless passkey management section component
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* <PasskeySection>
|
|
113
|
+
* {({ passkeys, isSupported, registerPasskey, removePasskey, isLoading }) => (
|
|
114
|
+
* <div>
|
|
115
|
+
* {!isSupported && <p>Passkeys not supported in this browser</p>}
|
|
116
|
+
* <ul>
|
|
117
|
+
* {passkeys.map((pk) => (
|
|
118
|
+
* <li key={pk.id}>
|
|
119
|
+
* {pk.name}
|
|
120
|
+
* <button onClick={() => removePasskey(pk.id)}>Remove</button>
|
|
121
|
+
* </li>
|
|
122
|
+
* ))}
|
|
123
|
+
* </ul>
|
|
124
|
+
* <button onClick={registerPasskey} disabled={isLoading || !isSupported}>
|
|
125
|
+
* Add Passkey
|
|
126
|
+
* </button>
|
|
127
|
+
* </div>
|
|
128
|
+
* )}
|
|
129
|
+
* </PasskeySection>
|
|
130
|
+
*/
|
|
131
|
+
function PasskeySection({ children, onRegisterSuccess, onRemoveSuccess, onError, }) {
|
|
132
|
+
const { user, member } = (0, auth_1.useAkinAuth)();
|
|
133
|
+
const { config } = (0, auth_1.useSDK)();
|
|
134
|
+
const [passkeys, setPasskeys] = (0, react_1.useState)([]);
|
|
135
|
+
const [isSupported, setIsSupported] = (0, react_1.useState)(false);
|
|
136
|
+
const [isLoading, setIsLoading] = (0, react_1.useState)(false);
|
|
137
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
138
|
+
const [success, setSuccess] = (0, react_1.useState)(null);
|
|
139
|
+
// Apollo mutations and queries
|
|
140
|
+
const [getRegistrationOptions] = (0, client_1.useMutation)(exports.PASSKEY_REGISTRATION_OPTIONS);
|
|
141
|
+
const [registerPasskeyMutation] = (0, client_1.useMutation)(exports.PASSKEY_REGISTER);
|
|
142
|
+
const [deletePasskeyMutation] = (0, client_1.useMutation)(exports.PASSKEY_DELETE);
|
|
143
|
+
const [fetchMyPasskeys] = (0, client_1.useLazyQuery)(exports.MY_PASSKEYS, {
|
|
144
|
+
fetchPolicy: 'network-only',
|
|
145
|
+
});
|
|
146
|
+
// Helper to map API response to PasskeyCredential
|
|
147
|
+
const mapPasskey = (pk) => ({
|
|
148
|
+
id: pk.id,
|
|
149
|
+
name: derivePasskeyName(pk.userAgent, pk.credentialDeviceType),
|
|
150
|
+
createdAt: new Date(pk.createdAt),
|
|
151
|
+
lastUsedAt: pk.lastUsedAt ? new Date(pk.lastUsedAt) : undefined,
|
|
152
|
+
});
|
|
153
|
+
// Derive a friendly name from userAgent or device type
|
|
154
|
+
function derivePasskeyName(userAgent, deviceType) {
|
|
155
|
+
if (userAgent) {
|
|
156
|
+
// Try to extract browser/OS from user agent
|
|
157
|
+
if (userAgent.includes('Chrome'))
|
|
158
|
+
return 'Chrome';
|
|
159
|
+
if (userAgent.includes('Safari'))
|
|
160
|
+
return 'Safari';
|
|
161
|
+
if (userAgent.includes('Firefox'))
|
|
162
|
+
return 'Firefox';
|
|
163
|
+
if (userAgent.includes('Edge'))
|
|
164
|
+
return 'Edge';
|
|
165
|
+
// Return first word as fallback
|
|
166
|
+
const firstWord = userAgent.split(' ')[0];
|
|
167
|
+
if (firstWord && firstWord.length < 20)
|
|
168
|
+
return firstWord;
|
|
169
|
+
}
|
|
170
|
+
if (deviceType === 'platform')
|
|
171
|
+
return 'Device Passkey';
|
|
172
|
+
if (deviceType === 'cross-platform')
|
|
173
|
+
return 'Security Key';
|
|
174
|
+
return 'Passkey';
|
|
175
|
+
}
|
|
176
|
+
// Check support on mount
|
|
177
|
+
(0, react_1.useEffect)(() => {
|
|
178
|
+
setIsSupported(isPasskeySupported());
|
|
179
|
+
}, []);
|
|
180
|
+
// Fetch existing passkeys when user is authenticated
|
|
181
|
+
(0, react_1.useEffect)(() => {
|
|
182
|
+
if (user?.id) {
|
|
183
|
+
fetchMyPasskeys().then(({ data }) => {
|
|
184
|
+
if (data?.myPasskeys) {
|
|
185
|
+
setPasskeys(data.myPasskeys.map(mapPasskey));
|
|
186
|
+
}
|
|
187
|
+
}).catch(() => {
|
|
188
|
+
// Silently fail - passkeys might not be set up for this user yet
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}, [user?.id, fetchMyPasskeys]);
|
|
192
|
+
// Register a new passkey
|
|
193
|
+
const registerPasskey = (0, react_1.useCallback)(async () => {
|
|
194
|
+
if (!user?.id || !user?.email) {
|
|
195
|
+
setError('Must be signed in to register a passkey');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
setIsLoading(true);
|
|
199
|
+
setError(null);
|
|
200
|
+
setSuccess(null);
|
|
201
|
+
try {
|
|
202
|
+
const userName = member?.firstName && member?.lastName
|
|
203
|
+
? `${member.firstName} ${member.lastName}`
|
|
204
|
+
: user.email;
|
|
205
|
+
// Step 1: Get registration options from server
|
|
206
|
+
const { data: optionsData } = await getRegistrationOptions({
|
|
207
|
+
variables: {
|
|
208
|
+
userId: user.id,
|
|
209
|
+
userName,
|
|
210
|
+
userEmail: user.email,
|
|
211
|
+
tenantId: config.gipTenantId,
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
if (!optionsData?.passkeyRegistrationOptions) {
|
|
215
|
+
throw new Error('Failed to get registration options');
|
|
216
|
+
}
|
|
217
|
+
const options = optionsData.passkeyRegistrationOptions;
|
|
218
|
+
// Step 2: Start WebAuthn registration (browser prompts user)
|
|
219
|
+
const { startRegistration } = await importWebAuthnBrowser();
|
|
220
|
+
const registrationResponse = await startRegistration({ optionsJSON: options });
|
|
221
|
+
// Step 3: Verify registration on server
|
|
222
|
+
const registerResult = await registerPasskeyMutation({
|
|
223
|
+
variables: {
|
|
224
|
+
userId: user.id,
|
|
225
|
+
userType: 'MEMBER',
|
|
226
|
+
tenantId: config.gipTenantId,
|
|
227
|
+
registrationResponse,
|
|
228
|
+
expectedChallenge: options.challenge,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
if (!registerResult.data?.passkeyRegister) {
|
|
232
|
+
throw new Error('Failed to register passkey');
|
|
233
|
+
}
|
|
234
|
+
// Step 4: Refresh passkeys list
|
|
235
|
+
const { data: credsData } = await fetchMyPasskeys();
|
|
236
|
+
if (credsData?.myPasskeys) {
|
|
237
|
+
setPasskeys(credsData.myPasskeys.map(mapPasskey));
|
|
238
|
+
}
|
|
239
|
+
setSuccess('Passkey registered successfully');
|
|
240
|
+
onRegisterSuccess?.();
|
|
241
|
+
// Clear success after 3 seconds
|
|
242
|
+
setTimeout(() => setSuccess(null), 3000);
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
// User cancelled - not an error
|
|
246
|
+
if (err.name === 'NotAllowedError') {
|
|
247
|
+
setIsLoading(false);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to register passkey';
|
|
251
|
+
setError(errorMessage);
|
|
252
|
+
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
setIsLoading(false);
|
|
256
|
+
}
|
|
257
|
+
}, [user?.id, user?.email, member, config.gipTenantId, getRegistrationOptions, registerPasskeyMutation, fetchMyPasskeys, onRegisterSuccess, onError]);
|
|
258
|
+
// Remove a passkey
|
|
259
|
+
const removePasskey = (0, react_1.useCallback)(async (credentialId) => {
|
|
260
|
+
setIsLoading(true);
|
|
261
|
+
setError(null);
|
|
262
|
+
setSuccess(null);
|
|
263
|
+
try {
|
|
264
|
+
const { data } = await deletePasskeyMutation({
|
|
265
|
+
variables: { credentialId },
|
|
266
|
+
});
|
|
267
|
+
// deletePasskey returns a boolean directly
|
|
268
|
+
if (!data?.deletePasskey) {
|
|
269
|
+
throw new Error('Failed to remove passkey');
|
|
270
|
+
}
|
|
271
|
+
// Update local state
|
|
272
|
+
setPasskeys((prev) => prev.filter((pk) => pk.id !== credentialId));
|
|
273
|
+
setSuccess('Passkey removed');
|
|
274
|
+
onRemoveSuccess?.();
|
|
275
|
+
// Clear success after 3 seconds
|
|
276
|
+
setTimeout(() => setSuccess(null), 3000);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to remove passkey';
|
|
280
|
+
setError(errorMessage);
|
|
281
|
+
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
setIsLoading(false);
|
|
285
|
+
}
|
|
286
|
+
}, [deletePasskeyMutation, onRemoveSuccess, onError]);
|
|
287
|
+
const props = {
|
|
288
|
+
passkeys,
|
|
289
|
+
isSupported,
|
|
290
|
+
registerPasskey,
|
|
291
|
+
removePasskey,
|
|
292
|
+
isLoading,
|
|
293
|
+
error,
|
|
294
|
+
success,
|
|
295
|
+
};
|
|
296
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children(props) });
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=PasskeySection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasskeySection.js","sourceRoot":"","sources":["../../../src/account/components/PasskeySection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AccountInfoRenderProps } from '../../types/account';
|
|
2
|
+
declare const UPDATE_MEMBER: import("@apollo/client").DocumentNode;
|
|
3
|
+
/**
|
|
4
|
+
* Hook for managing account profile form state
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const accountForm = useAccountForm();
|
|
8
|
+
*
|
|
9
|
+
* return (
|
|
10
|
+
* <form onSubmit={accountForm.handleSubmit}>
|
|
11
|
+
* <input
|
|
12
|
+
* value={accountForm.formData.firstName}
|
|
13
|
+
* onChange={(e) => accountForm.setFormField('firstName', e.target.value)}
|
|
14
|
+
* />
|
|
15
|
+
* </form>
|
|
16
|
+
* );
|
|
17
|
+
*/
|
|
18
|
+
export declare function useAccountForm(): AccountInfoRenderProps;
|
|
19
|
+
/**
|
|
20
|
+
* Export the UPDATE_MEMBER mutation for partners to use with their own client
|
|
21
|
+
*/
|
|
22
|
+
export { UPDATE_MEMBER };
|
|
23
|
+
//# sourceMappingURL=useAccountForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAccountForm.d.ts","sourceRoot":"","sources":["../../../src/account/hooks/useAccountForm.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAmB,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGnF,QAAA,MAAM,aAAa,uCAUlB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,IAAI,sBAAsB,CA4GvD;AAED;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,CAAC"}
|