@gately/react 1.0.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/README.md +277 -0
- package/dist/context.d.ts +35 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +199 -0
- package/dist/context.mjs +193 -0
- package/dist/hooks/context.d.ts +35 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/hooks/index.d.ts +11 -0
- package/dist/hooks/hooks/index.d.ts.map +1 -0
- package/dist/hooks/hooks/useAuth.d.ts +38 -0
- package/dist/hooks/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/hooks/useProtected.d.ts +29 -0
- package/dist/hooks/hooks/useProtected.d.ts.map +1 -0
- package/dist/hooks/hooks/useUser.d.ts +42 -0
- package/dist/hooks/hooks/useUser.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +11 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +212 -0
- package/dist/hooks/index.mjs +208 -0
- package/dist/hooks/useAuth.d.ts +38 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useProtected.d.ts +29 -0
- package/dist/hooks/useProtected.d.ts.map +1 -0
- package/dist/hooks/useUser.d.ts +42 -0
- package/dist/hooks/useUser.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +397 -0
- package/dist/index.mjs +391 -0
- package/package.json +73 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gately React Context
|
|
3
|
+
* Provides authentication state and methods to React components
|
|
4
|
+
*/
|
|
5
|
+
import React, { ReactNode } from 'react';
|
|
6
|
+
import { GatelyClient } from '@gately/sdk';
|
|
7
|
+
import type { Session, User } from '@gately/sdk';
|
|
8
|
+
export interface GatelyContextValue {
|
|
9
|
+
user: User | null;
|
|
10
|
+
session: Session | null;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
isAuthenticated: boolean;
|
|
13
|
+
error: Error | null;
|
|
14
|
+
login: (email: string, password: string) => Promise<any>;
|
|
15
|
+
signup: (email: string, password: string, metadata?: any) => Promise<any>;
|
|
16
|
+
logout: () => Promise<void>;
|
|
17
|
+
sendMagicLink: (email: string, redirectTo?: string) => Promise<void>;
|
|
18
|
+
resetPassword: (email: string) => Promise<void>;
|
|
19
|
+
fetchSession: () => Promise<Session | null>;
|
|
20
|
+
getUserProfile: () => Promise<any>;
|
|
21
|
+
updateUserProfile: (updates: any) => Promise<any>;
|
|
22
|
+
deleteUserAccount: () => Promise<void>;
|
|
23
|
+
changePassword: (current: string, newPassword: string) => Promise<void>;
|
|
24
|
+
client: GatelyClient | null;
|
|
25
|
+
}
|
|
26
|
+
export declare const GatelyContext: React.Context<GatelyContextValue | undefined>;
|
|
27
|
+
export interface GatelyProviderProps {
|
|
28
|
+
projectId: string;
|
|
29
|
+
apiUrl?: string;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
autoRefresh?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare function GatelyProvider({ projectId, apiUrl, children, autoRefresh }: GatelyProviderProps): React.FunctionComponentElement<React.ProviderProps<GatelyContextValue | undefined>>;
|
|
34
|
+
export default GatelyProvider;
|
|
35
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,EAAiB,SAAS,EAAoC,MAAM,OAAO,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEhD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;IACxB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACxD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACzE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpE,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,YAAY,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAC3C,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,iBAAiB,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACjD,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;CAC5B;AAED,eAAO,MAAM,aAAa,+CAA2D,CAAA;AAErF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,MAAM,EACN,QAAQ,EACR,WAAkB,EACnB,EAAE,mBAAmB,uFA+KrB;AAED,eAAe,cAAc,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gately React Hooks
|
|
3
|
+
* Collection of hooks for common auth and user operations
|
|
4
|
+
*/
|
|
5
|
+
export { useAuth } from './useAuth';
|
|
6
|
+
export type {} from './useAuth';
|
|
7
|
+
export { useUser } from './useUser';
|
|
8
|
+
export type { UseUserReturn } from './useUser';
|
|
9
|
+
export { useProtected } from './useProtected';
|
|
10
|
+
export type { UseProtectedReturn } from './useProtected';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAG,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAuth Hook
|
|
3
|
+
* Main hook for accessing Gately auth context
|
|
4
|
+
*/
|
|
5
|
+
import { GatelyContextValue } from '../context';
|
|
6
|
+
/**
|
|
7
|
+
* Hook to access Gately authentication context
|
|
8
|
+
* Must be used inside a GatelyProvider
|
|
9
|
+
*
|
|
10
|
+
* @returns {GatelyContextValue} Auth context with user, session, and auth methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* function LoginForm() {
|
|
15
|
+
* const { login, isLoading, error } = useAuth()
|
|
16
|
+
*
|
|
17
|
+
* const handleSubmit = async (email, password) => {
|
|
18
|
+
* try {
|
|
19
|
+
* await login(email, password)
|
|
20
|
+
* } catch (err) {
|
|
21
|
+
* console.error(err)
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <>
|
|
27
|
+
* {error && <p>{error.message}</p>}
|
|
28
|
+
* <button disabled={isLoading} onClick={() => handleSubmit('test@example.com', 'pass')}>
|
|
29
|
+
* {isLoading ? 'Logging in...' : 'Log In'}
|
|
30
|
+
* </button>
|
|
31
|
+
* </>
|
|
32
|
+
* )
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function useAuth(): GatelyContextValue;
|
|
37
|
+
export default useAuth;
|
|
38
|
+
//# sourceMappingURL=useAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAiB,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,OAAO,IAAI,kBAAkB,CAQ5C;AAED,eAAe,OAAO,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProtected Hook
|
|
3
|
+
* Hook for protecting components that require authentication
|
|
4
|
+
*/
|
|
5
|
+
export interface UseProtectedReturn {
|
|
6
|
+
isAuthenticated: boolean;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
user: any | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Hook to check if user is authenticated and protect a component
|
|
12
|
+
*
|
|
13
|
+
* @returns {UseProtectedReturn} Authentication status
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* function ProtectedPage() {
|
|
18
|
+
* const { isAuthenticated, isLoading } = useProtected()
|
|
19
|
+
*
|
|
20
|
+
* if (isLoading) return <p>Loading...</p>
|
|
21
|
+
* if (!isAuthenticated) return <p>Please log in to access this page</p>
|
|
22
|
+
*
|
|
23
|
+
* return <div>Protected content</div>
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function useProtected(): UseProtectedReturn;
|
|
28
|
+
export default useProtected;
|
|
29
|
+
//# sourceMappingURL=useProtected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProtected.d.ts","sourceRoot":"","sources":["../../src/hooks/useProtected.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,OAAO,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,GAAG,GAAG,IAAI,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAQjD;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useUser Hook
|
|
3
|
+
* Dedicated hook for accessing user information
|
|
4
|
+
*/
|
|
5
|
+
import type { User } from '@gately/sdk';
|
|
6
|
+
export interface UseUserReturn {
|
|
7
|
+
user: User | null;
|
|
8
|
+
profile: any | null;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
refetch: () => Promise<void>;
|
|
12
|
+
update: (updates: any) => Promise<any>;
|
|
13
|
+
delete: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Hook to access and manage user information
|
|
17
|
+
*
|
|
18
|
+
* @returns {UseUserReturn} User data with loading and error states
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* function UserProfile() {
|
|
23
|
+
* const { user, profile, isLoading, error, update } = useUser()
|
|
24
|
+
*
|
|
25
|
+
* if (isLoading) return <p>Loading...</p>
|
|
26
|
+
* if (error) return <p>Error: {error.message}</p>
|
|
27
|
+
* if (!user) return <p>Not logged in</p>
|
|
28
|
+
*
|
|
29
|
+
* return (
|
|
30
|
+
* <div>
|
|
31
|
+
* <p>Email: {user.email}</p>
|
|
32
|
+
* <button onClick={() => update({ name: 'New Name' })}>
|
|
33
|
+
* Update Profile
|
|
34
|
+
* </button>
|
|
35
|
+
* </div>
|
|
36
|
+
* )
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function useUser(): UseUserReturn;
|
|
41
|
+
export default useUser;
|
|
42
|
+
//# sourceMappingURL=useUser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../src/hooks/useUser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEvC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,OAAO,EAAE,GAAG,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAoGvC;AAED,eAAe,OAAO,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gately React Hooks
|
|
3
|
+
* Collection of hooks for common auth and user operations
|
|
4
|
+
*/
|
|
5
|
+
export { useAuth } from './useAuth';
|
|
6
|
+
export type {} from './useAuth';
|
|
7
|
+
export { useUser } from './useUser';
|
|
8
|
+
export type { UseUserReturn } from './useUser';
|
|
9
|
+
export { useProtected } from './useProtected';
|
|
10
|
+
export type { UseProtectedReturn } from './useProtected';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAG,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
require('@gately/sdk');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Gately React Context
|
|
8
|
+
* Provides authentication state and methods to React components
|
|
9
|
+
*/
|
|
10
|
+
const GatelyContext = React.createContext(undefined);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* useAuth Hook
|
|
14
|
+
* Main hook for accessing Gately auth context
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Hook to access Gately authentication context
|
|
18
|
+
* Must be used inside a GatelyProvider
|
|
19
|
+
*
|
|
20
|
+
* @returns {GatelyContextValue} Auth context with user, session, and auth methods
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* function LoginForm() {
|
|
25
|
+
* const { login, isLoading, error } = useAuth()
|
|
26
|
+
*
|
|
27
|
+
* const handleSubmit = async (email, password) => {
|
|
28
|
+
* try {
|
|
29
|
+
* await login(email, password)
|
|
30
|
+
* } catch (err) {
|
|
31
|
+
* console.error(err)
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* return (
|
|
36
|
+
* <>
|
|
37
|
+
* {error && <p>{error.message}</p>}
|
|
38
|
+
* <button disabled={isLoading} onClick={() => handleSubmit('test@example.com', 'pass')}>
|
|
39
|
+
* {isLoading ? 'Logging in...' : 'Log In'}
|
|
40
|
+
* </button>
|
|
41
|
+
* </>
|
|
42
|
+
* )
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function useAuth() {
|
|
47
|
+
const context = React.useContext(GatelyContext);
|
|
48
|
+
if (context === undefined) {
|
|
49
|
+
throw new Error('useAuth must be used within a GatelyProvider');
|
|
50
|
+
}
|
|
51
|
+
return context;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* useUser Hook
|
|
56
|
+
* Dedicated hook for accessing user information
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Hook to access and manage user information
|
|
60
|
+
*
|
|
61
|
+
* @returns {UseUserReturn} User data with loading and error states
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* function UserProfile() {
|
|
66
|
+
* const { user, profile, isLoading, error, update } = useUser()
|
|
67
|
+
*
|
|
68
|
+
* if (isLoading) return <p>Loading...</p>
|
|
69
|
+
* if (error) return <p>Error: {error.message}</p>
|
|
70
|
+
* if (!user) return <p>Not logged in</p>
|
|
71
|
+
*
|
|
72
|
+
* return (
|
|
73
|
+
* <div>
|
|
74
|
+
* <p>Email: {user.email}</p>
|
|
75
|
+
* <button onClick={() => update({ name: 'New Name' })}>
|
|
76
|
+
* Update Profile
|
|
77
|
+
* </button>
|
|
78
|
+
* </div>
|
|
79
|
+
* )
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
function useUser() {
|
|
84
|
+
const { user, isAuthenticated, getUserProfile, updateUserProfile, deleteUserAccount } = useAuth();
|
|
85
|
+
const [profile, setProfile] = React.useState(null);
|
|
86
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
87
|
+
const [error, setError] = React.useState(null);
|
|
88
|
+
// Fetch user profile on mount or when auth state changes
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
if (!isAuthenticated || !user) {
|
|
91
|
+
setProfile(null);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const fetchProfile = async () => {
|
|
95
|
+
setIsLoading(true);
|
|
96
|
+
setError(null);
|
|
97
|
+
try {
|
|
98
|
+
const profileData = await getUserProfile();
|
|
99
|
+
setProfile(profileData);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
103
|
+
setProfile(null);
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
setIsLoading(false);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
fetchProfile();
|
|
110
|
+
}, [isAuthenticated, user, getUserProfile]);
|
|
111
|
+
const refetch = React.useCallback(async () => {
|
|
112
|
+
if (!isAuthenticated) {
|
|
113
|
+
throw new Error('User must be authenticated to fetch profile');
|
|
114
|
+
}
|
|
115
|
+
setIsLoading(true);
|
|
116
|
+
setError(null);
|
|
117
|
+
try {
|
|
118
|
+
const profileData = await getUserProfile();
|
|
119
|
+
setProfile(profileData);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
123
|
+
setError(error);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
setIsLoading(false);
|
|
128
|
+
}
|
|
129
|
+
}, [isAuthenticated, getUserProfile]);
|
|
130
|
+
const update = React.useCallback(async (updates) => {
|
|
131
|
+
if (!isAuthenticated) {
|
|
132
|
+
throw new Error('User must be authenticated to update profile');
|
|
133
|
+
}
|
|
134
|
+
setIsLoading(true);
|
|
135
|
+
setError(null);
|
|
136
|
+
try {
|
|
137
|
+
const updatedProfile = await updateUserProfile(updates);
|
|
138
|
+
setProfile(updatedProfile);
|
|
139
|
+
return updatedProfile;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
143
|
+
setError(error);
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
setIsLoading(false);
|
|
148
|
+
}
|
|
149
|
+
}, [isAuthenticated, updateUserProfile]);
|
|
150
|
+
const deleteUser = React.useCallback(async () => {
|
|
151
|
+
if (!isAuthenticated) {
|
|
152
|
+
throw new Error('User must be authenticated to delete account');
|
|
153
|
+
}
|
|
154
|
+
setIsLoading(true);
|
|
155
|
+
setError(null);
|
|
156
|
+
try {
|
|
157
|
+
await deleteUserAccount();
|
|
158
|
+
setProfile(null);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
162
|
+
setError(error);
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
setIsLoading(false);
|
|
167
|
+
}
|
|
168
|
+
}, [isAuthenticated, deleteUserAccount]);
|
|
169
|
+
return {
|
|
170
|
+
user,
|
|
171
|
+
profile,
|
|
172
|
+
isLoading,
|
|
173
|
+
error,
|
|
174
|
+
refetch,
|
|
175
|
+
update,
|
|
176
|
+
delete: deleteUser
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* useProtected Hook
|
|
182
|
+
* Hook for protecting components that require authentication
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* Hook to check if user is authenticated and protect a component
|
|
186
|
+
*
|
|
187
|
+
* @returns {UseProtectedReturn} Authentication status
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```tsx
|
|
191
|
+
* function ProtectedPage() {
|
|
192
|
+
* const { isAuthenticated, isLoading } = useProtected()
|
|
193
|
+
*
|
|
194
|
+
* if (isLoading) return <p>Loading...</p>
|
|
195
|
+
* if (!isAuthenticated) return <p>Please log in to access this page</p>
|
|
196
|
+
*
|
|
197
|
+
* return <div>Protected content</div>
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
function useProtected() {
|
|
202
|
+
const { isAuthenticated, isLoading, user } = useAuth();
|
|
203
|
+
return {
|
|
204
|
+
isAuthenticated,
|
|
205
|
+
isLoading,
|
|
206
|
+
user
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
exports.useAuth = useAuth;
|
|
211
|
+
exports.useProtected = useProtected;
|
|
212
|
+
exports.useUser = useUser;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import '@gately/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gately React Context
|
|
6
|
+
* Provides authentication state and methods to React components
|
|
7
|
+
*/
|
|
8
|
+
const GatelyContext = createContext(undefined);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* useAuth Hook
|
|
12
|
+
* Main hook for accessing Gately auth context
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Hook to access Gately authentication context
|
|
16
|
+
* Must be used inside a GatelyProvider
|
|
17
|
+
*
|
|
18
|
+
* @returns {GatelyContextValue} Auth context with user, session, and auth methods
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* function LoginForm() {
|
|
23
|
+
* const { login, isLoading, error } = useAuth()
|
|
24
|
+
*
|
|
25
|
+
* const handleSubmit = async (email, password) => {
|
|
26
|
+
* try {
|
|
27
|
+
* await login(email, password)
|
|
28
|
+
* } catch (err) {
|
|
29
|
+
* console.error(err)
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* return (
|
|
34
|
+
* <>
|
|
35
|
+
* {error && <p>{error.message}</p>}
|
|
36
|
+
* <button disabled={isLoading} onClick={() => handleSubmit('test@example.com', 'pass')}>
|
|
37
|
+
* {isLoading ? 'Logging in...' : 'Log In'}
|
|
38
|
+
* </button>
|
|
39
|
+
* </>
|
|
40
|
+
* )
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
function useAuth() {
|
|
45
|
+
const context = useContext(GatelyContext);
|
|
46
|
+
if (context === undefined) {
|
|
47
|
+
throw new Error('useAuth must be used within a GatelyProvider');
|
|
48
|
+
}
|
|
49
|
+
return context;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* useUser Hook
|
|
54
|
+
* Dedicated hook for accessing user information
|
|
55
|
+
*/
|
|
56
|
+
/**
|
|
57
|
+
* Hook to access and manage user information
|
|
58
|
+
*
|
|
59
|
+
* @returns {UseUserReturn} User data with loading and error states
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* function UserProfile() {
|
|
64
|
+
* const { user, profile, isLoading, error, update } = useUser()
|
|
65
|
+
*
|
|
66
|
+
* if (isLoading) return <p>Loading...</p>
|
|
67
|
+
* if (error) return <p>Error: {error.message}</p>
|
|
68
|
+
* if (!user) return <p>Not logged in</p>
|
|
69
|
+
*
|
|
70
|
+
* return (
|
|
71
|
+
* <div>
|
|
72
|
+
* <p>Email: {user.email}</p>
|
|
73
|
+
* <button onClick={() => update({ name: 'New Name' })}>
|
|
74
|
+
* Update Profile
|
|
75
|
+
* </button>
|
|
76
|
+
* </div>
|
|
77
|
+
* )
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
function useUser() {
|
|
82
|
+
const { user, isAuthenticated, getUserProfile, updateUserProfile, deleteUserAccount } = useAuth();
|
|
83
|
+
const [profile, setProfile] = useState(null);
|
|
84
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
85
|
+
const [error, setError] = useState(null);
|
|
86
|
+
// Fetch user profile on mount or when auth state changes
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (!isAuthenticated || !user) {
|
|
89
|
+
setProfile(null);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const fetchProfile = async () => {
|
|
93
|
+
setIsLoading(true);
|
|
94
|
+
setError(null);
|
|
95
|
+
try {
|
|
96
|
+
const profileData = await getUserProfile();
|
|
97
|
+
setProfile(profileData);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
101
|
+
setProfile(null);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
setIsLoading(false);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
fetchProfile();
|
|
108
|
+
}, [isAuthenticated, user, getUserProfile]);
|
|
109
|
+
const refetch = useCallback(async () => {
|
|
110
|
+
if (!isAuthenticated) {
|
|
111
|
+
throw new Error('User must be authenticated to fetch profile');
|
|
112
|
+
}
|
|
113
|
+
setIsLoading(true);
|
|
114
|
+
setError(null);
|
|
115
|
+
try {
|
|
116
|
+
const profileData = await getUserProfile();
|
|
117
|
+
setProfile(profileData);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
121
|
+
setError(error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setIsLoading(false);
|
|
126
|
+
}
|
|
127
|
+
}, [isAuthenticated, getUserProfile]);
|
|
128
|
+
const update = useCallback(async (updates) => {
|
|
129
|
+
if (!isAuthenticated) {
|
|
130
|
+
throw new Error('User must be authenticated to update profile');
|
|
131
|
+
}
|
|
132
|
+
setIsLoading(true);
|
|
133
|
+
setError(null);
|
|
134
|
+
try {
|
|
135
|
+
const updatedProfile = await updateUserProfile(updates);
|
|
136
|
+
setProfile(updatedProfile);
|
|
137
|
+
return updatedProfile;
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
141
|
+
setError(error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
setIsLoading(false);
|
|
146
|
+
}
|
|
147
|
+
}, [isAuthenticated, updateUserProfile]);
|
|
148
|
+
const deleteUser = useCallback(async () => {
|
|
149
|
+
if (!isAuthenticated) {
|
|
150
|
+
throw new Error('User must be authenticated to delete account');
|
|
151
|
+
}
|
|
152
|
+
setIsLoading(true);
|
|
153
|
+
setError(null);
|
|
154
|
+
try {
|
|
155
|
+
await deleteUserAccount();
|
|
156
|
+
setProfile(null);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
160
|
+
setError(error);
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
setIsLoading(false);
|
|
165
|
+
}
|
|
166
|
+
}, [isAuthenticated, deleteUserAccount]);
|
|
167
|
+
return {
|
|
168
|
+
user,
|
|
169
|
+
profile,
|
|
170
|
+
isLoading,
|
|
171
|
+
error,
|
|
172
|
+
refetch,
|
|
173
|
+
update,
|
|
174
|
+
delete: deleteUser
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* useProtected Hook
|
|
180
|
+
* Hook for protecting components that require authentication
|
|
181
|
+
*/
|
|
182
|
+
/**
|
|
183
|
+
* Hook to check if user is authenticated and protect a component
|
|
184
|
+
*
|
|
185
|
+
* @returns {UseProtectedReturn} Authentication status
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```tsx
|
|
189
|
+
* function ProtectedPage() {
|
|
190
|
+
* const { isAuthenticated, isLoading } = useProtected()
|
|
191
|
+
*
|
|
192
|
+
* if (isLoading) return <p>Loading...</p>
|
|
193
|
+
* if (!isAuthenticated) return <p>Please log in to access this page</p>
|
|
194
|
+
*
|
|
195
|
+
* return <div>Protected content</div>
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
function useProtected() {
|
|
200
|
+
const { isAuthenticated, isLoading, user } = useAuth();
|
|
201
|
+
return {
|
|
202
|
+
isAuthenticated,
|
|
203
|
+
isLoading,
|
|
204
|
+
user
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { useAuth, useProtected, useUser };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAuth Hook
|
|
3
|
+
* Main hook for accessing Gately auth context
|
|
4
|
+
*/
|
|
5
|
+
import { GatelyContextValue } from '../context';
|
|
6
|
+
/**
|
|
7
|
+
* Hook to access Gately authentication context
|
|
8
|
+
* Must be used inside a GatelyProvider
|
|
9
|
+
*
|
|
10
|
+
* @returns {GatelyContextValue} Auth context with user, session, and auth methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* function LoginForm() {
|
|
15
|
+
* const { login, isLoading, error } = useAuth()
|
|
16
|
+
*
|
|
17
|
+
* const handleSubmit = async (email, password) => {
|
|
18
|
+
* try {
|
|
19
|
+
* await login(email, password)
|
|
20
|
+
* } catch (err) {
|
|
21
|
+
* console.error(err)
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <>
|
|
27
|
+
* {error && <p>{error.message}</p>}
|
|
28
|
+
* <button disabled={isLoading} onClick={() => handleSubmit('test@example.com', 'pass')}>
|
|
29
|
+
* {isLoading ? 'Logging in...' : 'Log In'}
|
|
30
|
+
* </button>
|
|
31
|
+
* </>
|
|
32
|
+
* )
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function useAuth(): GatelyContextValue;
|
|
37
|
+
export default useAuth;
|
|
38
|
+
//# sourceMappingURL=useAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAiB,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,OAAO,IAAI,kBAAkB,CAQ5C;AAED,eAAe,OAAO,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProtected Hook
|
|
3
|
+
* Hook for protecting components that require authentication
|
|
4
|
+
*/
|
|
5
|
+
export interface UseProtectedReturn {
|
|
6
|
+
isAuthenticated: boolean;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
user: any | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Hook to check if user is authenticated and protect a component
|
|
12
|
+
*
|
|
13
|
+
* @returns {UseProtectedReturn} Authentication status
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* function ProtectedPage() {
|
|
18
|
+
* const { isAuthenticated, isLoading } = useProtected()
|
|
19
|
+
*
|
|
20
|
+
* if (isLoading) return <p>Loading...</p>
|
|
21
|
+
* if (!isAuthenticated) return <p>Please log in to access this page</p>
|
|
22
|
+
*
|
|
23
|
+
* return <div>Protected content</div>
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function useProtected(): UseProtectedReturn;
|
|
28
|
+
export default useProtected;
|
|
29
|
+
//# sourceMappingURL=useProtected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProtected.d.ts","sourceRoot":"","sources":["../../src/hooks/useProtected.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,OAAO,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,GAAG,GAAG,IAAI,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAQjD;AAED,eAAe,YAAY,CAAA"}
|