@elevasis/ui 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/dist/api/index.d.ts +87 -0
- package/dist/api/index.js +3 -0
- package/dist/auth/context.d.ts +19 -0
- package/dist/auth/context.js +1 -0
- package/dist/auth/index.d.ts +85 -0
- package/dist/auth/index.js +3 -0
- package/dist/chunk-3KMDHCAR.js +52 -0
- package/dist/chunk-5UWFGBFM.js +129 -0
- package/dist/chunk-6BJOYF6E.js +8 -0
- package/dist/chunk-6M6OLGQY.js +36 -0
- package/dist/chunk-7AI5ZYJ4.js +202 -0
- package/dist/chunk-7PLEQFHO.js +18 -0
- package/dist/chunk-GDV44UWF.js +138 -0
- package/dist/chunk-GEFB5YIR.js +338 -0
- package/dist/chunk-HBRMWW6V.js +43 -0
- package/dist/chunk-HUWJXLLF.js +681 -0
- package/dist/chunk-J3FALDQE.js +176 -0
- package/dist/chunk-JKERRYVS.js +109 -0
- package/dist/chunk-KA7LO7U5.js +28 -0
- package/dist/chunk-LHQTTUL2.js +27 -0
- package/dist/chunk-MAAS6CGR.js +1299 -0
- package/dist/chunk-NE36BUGQ.js +146 -0
- package/dist/chunk-NGXCFBCS.js +398 -0
- package/dist/chunk-OEYU5O27.js +235 -0
- package/dist/chunk-OUHGHTE7.js +748 -0
- package/dist/chunk-OXVOHOP3.js +661 -0
- package/dist/chunk-PSLKGOBZ.js +58 -0
- package/dist/chunk-PYL4XW6H.js +107 -0
- package/dist/chunk-Q47SPRY7.js +1 -0
- package/dist/chunk-Q7DJKLEN.js +18 -0
- package/dist/chunk-RJCA5672.js +1664 -0
- package/dist/chunk-S66I2PYB.js +748 -0
- package/dist/chunk-W7ZBF5AA.js +1 -0
- package/dist/chunk-WNWKOCGJ.js +1067 -0
- package/dist/chunk-XCYKC6OZ.js +1 -0
- package/dist/chunk-YULUKCS6.js +56 -0
- package/dist/chunk-YZ6GTZXL.js +48 -0
- package/dist/chunk-ZGHDPDTF.js +379 -0
- package/dist/components/command-queue/index.css +53 -0
- package/dist/components/command-queue/index.d.ts +204 -0
- package/dist/components/command-queue/index.js +10 -0
- package/dist/components/forms/index.d.ts +56 -0
- package/dist/components/forms/index.js +2 -0
- package/dist/components/index.css +443 -0
- package/dist/components/index.d.ts +1354 -0
- package/dist/components/index.js +18 -0
- package/dist/components/monitoring/index.d.ts +66 -0
- package/dist/components/monitoring/index.js +2 -0
- package/dist/components/navigation/index.d.ts +54 -0
- package/dist/components/navigation/index.js +91 -0
- package/dist/components/notifications/index.d.ts +52 -0
- package/dist/components/notifications/index.js +4 -0
- package/dist/components/resource-definition/index.css +388 -0
- package/dist/components/resource-definition/index.d.ts +301 -0
- package/dist/components/resource-definition/index.js +3 -0
- package/dist/display/index.css +53 -0
- package/dist/display/index.d.ts +606 -0
- package/dist/display/index.js +6 -0
- package/dist/execution/index.css +388 -0
- package/dist/execution/index.d.ts +1090 -0
- package/dist/execution/index.js +4 -0
- package/dist/graph/index.css +388 -0
- package/dist/graph/index.d.ts +429 -0
- package/dist/graph/index.js +1 -0
- package/dist/hooks/index.d.ts +1927 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/published.d.ts +1653 -0
- package/dist/hooks/published.js +4 -0
- package/dist/index.css +505 -0
- package/dist/index.d.ts +7284 -0
- package/dist/index.js +31 -0
- package/dist/initialization/index.d.ts +2325 -0
- package/dist/initialization/index.js +4 -0
- package/dist/organization/index.d.ts +225 -0
- package/dist/organization/index.js +4 -0
- package/dist/profile/index.d.ts +2265 -0
- package/dist/profile/index.js +3 -0
- package/dist/provider/index.css +61 -0
- package/dist/provider/index.d.ts +291 -0
- package/dist/provider/index.js +7 -0
- package/dist/provider/published.d.ts +198 -0
- package/dist/provider/published.js +6 -0
- package/dist/router/context.d.ts +19 -0
- package/dist/router/context.js +1 -0
- package/dist/router/index.d.ts +31 -0
- package/dist/router/index.js +2 -0
- package/dist/sse/index.d.ts +83 -0
- package/dist/sse/index.js +185 -0
- package/dist/supabase/index.d.ts +4289 -0
- package/dist/supabase/index.js +47 -0
- package/dist/typeform/index.d.ts +458 -0
- package/dist/typeform/index.js +1976 -0
- package/dist/typeform/schemas.d.ts +67 -0
- package/dist/typeform/schemas.js +1 -0
- package/dist/utils/index.d.ts +177 -0
- package/dist/utils/index.js +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* API module types
|
|
5
|
+
*/
|
|
6
|
+
interface ApiClientContextValue {
|
|
7
|
+
getAccessToken: () => Promise<string | undefined>;
|
|
8
|
+
organizationId: string | null;
|
|
9
|
+
isOrganizationReady: boolean;
|
|
10
|
+
onError?: (endpoint: string, error: Error, details?: ApiErrorDetails) => void;
|
|
11
|
+
}
|
|
12
|
+
interface ApiErrorDetails {
|
|
13
|
+
method: string;
|
|
14
|
+
statusCode: number;
|
|
15
|
+
requestId?: string;
|
|
16
|
+
}
|
|
17
|
+
interface ApiClientProviderProps {
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
getAccessToken: () => Promise<string | undefined>;
|
|
20
|
+
organizationId: string | null;
|
|
21
|
+
isOrganizationReady: boolean;
|
|
22
|
+
onError?: (endpoint: string, error: Error, details?: ApiErrorDetails) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Hook to access the API client context
|
|
27
|
+
* Must be used within an ApiClientProvider
|
|
28
|
+
*/
|
|
29
|
+
declare function useApiClientContext(): ApiClientContextValue;
|
|
30
|
+
/**
|
|
31
|
+
* Provider component that configures the API client context
|
|
32
|
+
*
|
|
33
|
+
* Configure this at your app root with auth and organization dependencies.
|
|
34
|
+
* All components using useApiClient will automatically get the configured values.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* function App() {
|
|
39
|
+
* const { getAccessToken } = useAuth()
|
|
40
|
+
* const { currentWorkOSOrganizationId, currentMembership } = useOrganizations()
|
|
41
|
+
*
|
|
42
|
+
* return (
|
|
43
|
+
* <ApiClientProvider
|
|
44
|
+
* getAccessToken={getAccessToken}
|
|
45
|
+
* organizationId={currentWorkOSOrganizationId}
|
|
46
|
+
* isOrganizationReady={!!currentMembership}
|
|
47
|
+
* onError={(endpoint, error, details) => logError(endpoint, error, details)}
|
|
48
|
+
* >
|
|
49
|
+
* <YourApp />
|
|
50
|
+
* </ApiClientProvider>
|
|
51
|
+
* )
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
declare function ApiClientProvider({ children, getAccessToken, organizationId, isOrganizationReady, onError }: ApiClientProviderProps): react_jsx_runtime.JSX.Element;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Return type of useOrganizations hook (subset needed by useApiClient)
|
|
59
|
+
*/
|
|
60
|
+
interface UseOrganizationsReturn {
|
|
61
|
+
isInitializing: boolean;
|
|
62
|
+
isOrgRefreshing: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Factory function to create a useApiClient hook for your app.
|
|
66
|
+
*
|
|
67
|
+
* This pattern allows the shared package to provide the hook logic
|
|
68
|
+
* while each app provides its own useOrganizations hook and API URL.
|
|
69
|
+
*
|
|
70
|
+
* Usage in app:
|
|
71
|
+
* ```typescript
|
|
72
|
+
* import { createUseApiClient } from '@repo/ui/api'
|
|
73
|
+
* import { useOrganizations } from './organization/hooks/useOrganizations'
|
|
74
|
+
*
|
|
75
|
+
* const API_URL = import.meta.env.VITE_API_SERVER || 'http://localhost:5170'
|
|
76
|
+
* export const useApiClient = createUseApiClient(useOrganizations, API_URL)
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare function createUseApiClient(useOrganizations: () => UseOrganizationsReturn, apiUrl: string): () => {
|
|
80
|
+
apiRequest: <T>(endpoint: string, options?: RequestInit) => Promise<T>;
|
|
81
|
+
deferredApiRequest: <T>(endpoint: string, options?: RequestInit) => Promise<T>;
|
|
82
|
+
isOrganizationReady: boolean;
|
|
83
|
+
isInitializing: boolean;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export { ApiClientProvider, createUseApiClient, useApiClientContext };
|
|
87
|
+
export type { ApiClientContextValue, ApiClientProviderProps, ApiErrorDetails };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface AuthAdapter {
|
|
5
|
+
user: {
|
|
6
|
+
id: string;
|
|
7
|
+
} | null;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
getAccessToken: () => Promise<string>;
|
|
10
|
+
organizationId?: string | null;
|
|
11
|
+
}
|
|
12
|
+
declare function useAuthContext(): AuthAdapter;
|
|
13
|
+
declare function AuthProvider({ value, children }: {
|
|
14
|
+
value: AuthAdapter;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}): react.FunctionComponentElement<react.ProviderProps<AuthAdapter | null>>;
|
|
17
|
+
|
|
18
|
+
export { AuthProvider, useAuthContext };
|
|
19
|
+
export type { AuthAdapter };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AuthProvider, useAuthContext } from '../chunk-7PLEQFHO.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
interface AuthAdapter {
|
|
6
|
+
user: {
|
|
7
|
+
id: string;
|
|
8
|
+
} | null;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
getAccessToken: () => Promise<string>;
|
|
11
|
+
organizationId?: string | null;
|
|
12
|
+
}
|
|
13
|
+
declare function useAuthContext(): AuthAdapter;
|
|
14
|
+
declare function AuthProvider({ value, children }: {
|
|
15
|
+
value: AuthAdapter;
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}): react.FunctionComponentElement<react.ProviderProps<AuthAdapter | null>>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Bridge component that reads WorkOS AuthKit state and provides it
|
|
21
|
+
* via the generic AuthContext. Place inside AuthKitProvider.
|
|
22
|
+
*
|
|
23
|
+
* Narrows WorkOS User to { id: string } -- @repo/ui hooks only need the ID.
|
|
24
|
+
* Uses useMemo to stabilize the user object and prevent unnecessary
|
|
25
|
+
* useEffect re-runs in downstream hooks.
|
|
26
|
+
*/
|
|
27
|
+
declare function WorkOSAuthBridge({ children }: {
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
}): react_jsx_runtime.JSX.Element;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Bridge component that reads OAuth state and provides it
|
|
33
|
+
* via the generic AuthContext. Place inside OAuthProvider.
|
|
34
|
+
*
|
|
35
|
+
* Mirrors WorkOSAuthBridge structure -- maps OAuthContextValue to AuthAdapter.
|
|
36
|
+
*/
|
|
37
|
+
declare function OAuthAuthBridge({ children }: {
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
}): react_jsx_runtime.JSX.Element;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns a stable reference to getAccessToken that won't change between renders
|
|
43
|
+
*
|
|
44
|
+
* This prevents SSE connections from reconnecting unnecessarily when the
|
|
45
|
+
* WorkOS useAuth hook returns a new getAccessToken function reference
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* const getAccessToken = useStableAccessToken()
|
|
50
|
+
*
|
|
51
|
+
* useEffect(() => {
|
|
52
|
+
* fetchEventSourceWithTokenRefresh({
|
|
53
|
+
* getToken: getAccessToken,
|
|
54
|
+
* // ...
|
|
55
|
+
* })
|
|
56
|
+
* }, [getAccessToken]) // Won't re-run on every render
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
declare function useStableAccessToken(): () => Promise<string>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Checks WorkOS session validity when window/tab regains focus
|
|
63
|
+
*
|
|
64
|
+
* When window or tab becomes visible after inactivity, validates session
|
|
65
|
+
* by attempting to get access token. If session expired (WorkOS inactivity
|
|
66
|
+
* timeout exceeded), signs out user and redirects to login.
|
|
67
|
+
*
|
|
68
|
+
* How it works:
|
|
69
|
+
* 1. Window/tab regains focus after inactivity
|
|
70
|
+
* 2. Cancel all pending queries to prevent 401 error cascade
|
|
71
|
+
* 3. Attempt to get access token from WorkOS
|
|
72
|
+
* 4. If successful: Resume queries with fresh token
|
|
73
|
+
* 5. If failed (session expired): Sign out and redirect to login
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // In __root.tsx
|
|
77
|
+
* export function RootLayoutComponent() {
|
|
78
|
+
* useSessionCheck()
|
|
79
|
+
* return <YourApp />
|
|
80
|
+
* }
|
|
81
|
+
*/
|
|
82
|
+
declare function useSessionCheck(): void;
|
|
83
|
+
|
|
84
|
+
export { AuthProvider, OAuthAuthBridge, WorkOSAuthBridge, useAuthContext, useSessionCheck as useRefocusSessionCheck, useSessionCheck, useStableAccessToken };
|
|
85
|
+
export type { AuthAdapter };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Text, Box, Code, Title } from '@mantine/core';
|
|
2
|
+
import Markdown from 'react-markdown';
|
|
3
|
+
import { Prism } from 'react-syntax-highlighter';
|
|
4
|
+
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
|
|
5
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/components/display/StyledMarkdown.tsx
|
|
8
|
+
var customCodeTheme = Object.fromEntries(
|
|
9
|
+
Object.entries(oneDark).map(([key, value]) => [
|
|
10
|
+
key,
|
|
11
|
+
typeof value === "object" && value !== null ? { ...value, background: "none", backgroundColor: "none" } : value
|
|
12
|
+
])
|
|
13
|
+
);
|
|
14
|
+
var defaultComponents = {
|
|
15
|
+
h1: ({ children }) => /* @__PURE__ */ jsx(Title, { order: 3, c: "var(--color-primary)", mb: "xs", mt: "md", children }),
|
|
16
|
+
h2: ({ children }) => /* @__PURE__ */ jsx(Title, { order: 4, c: "var(--color-primary)", mb: "xs", mt: "sm", children }),
|
|
17
|
+
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { style: { margin: "0.5rem 0", paddingLeft: "1.5rem" }, children }),
|
|
18
|
+
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { style: { margin: "0.5rem 0", paddingLeft: "1.5rem" }, children }),
|
|
19
|
+
li: ({ children }) => /* @__PURE__ */ jsx("li", { style: { marginBottom: "0.25rem", fontSize: "var(--mantine-font-size-sm)" }, children }),
|
|
20
|
+
code: ({ className, children, ...props }) => {
|
|
21
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
22
|
+
const codeString = String(children).replace(/\n$/, "");
|
|
23
|
+
if (match) {
|
|
24
|
+
return /* @__PURE__ */ jsx(
|
|
25
|
+
Prism,
|
|
26
|
+
{
|
|
27
|
+
style: customCodeTheme,
|
|
28
|
+
language: match[1],
|
|
29
|
+
PreTag: "div",
|
|
30
|
+
customStyle: {
|
|
31
|
+
margin: "0.5rem 0",
|
|
32
|
+
borderRadius: "var(--mantine-radius-default)",
|
|
33
|
+
fontSize: "0.8rem"
|
|
34
|
+
},
|
|
35
|
+
children: codeString
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsx(Code, { ...props, children });
|
|
40
|
+
},
|
|
41
|
+
pre: ({ children }) => /* @__PURE__ */ jsx(Fragment, { children }),
|
|
42
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsx(Box, { pl: "sm", my: "xs", style: { borderLeft: "2px solid var(--color-border)" }, children }),
|
|
43
|
+
p: ({ children }) => /* @__PURE__ */ jsx(Text, { size: "sm", m: 0, children }),
|
|
44
|
+
strong: ({ children }) => /* @__PURE__ */ jsx(Text, { component: "span", fw: 700, children }),
|
|
45
|
+
em: ({ children }) => /* @__PURE__ */ jsx(Text, { component: "span", fs: "italic", children })
|
|
46
|
+
};
|
|
47
|
+
function StyledMarkdown({ children, components, className, style }) {
|
|
48
|
+
const mergedComponents = components ? { ...defaultComponents, ...components } : defaultComponents;
|
|
49
|
+
return /* @__PURE__ */ jsx("div", { className, style, children: /* @__PURE__ */ jsx(Markdown, { components: mergedComponents, children }) });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { StyledMarkdown };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useElevasisServices } from './chunk-KA7LO7U5.js';
|
|
2
|
+
import { useAuthContext } from './chunk-7PLEQFHO.js';
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
|
|
5
|
+
// src/profile/services/UserProfileService.ts
|
|
6
|
+
var UserProfileService = class {
|
|
7
|
+
constructor(apiRequest) {
|
|
8
|
+
this.apiRequest = apiRequest;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Sync WorkOS user data to Supabase users table
|
|
12
|
+
* This creates or updates the user profile with latest WorkOS data
|
|
13
|
+
*/
|
|
14
|
+
async syncUserProfile() {
|
|
15
|
+
try {
|
|
16
|
+
const profile = await this.apiRequest("/users/me/sync", {
|
|
17
|
+
method: "POST"
|
|
18
|
+
});
|
|
19
|
+
return profile;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error("User profile sync error:", error);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get user profile from API
|
|
27
|
+
* Server identifies user from JWT (no user ID needed)
|
|
28
|
+
*/
|
|
29
|
+
async getUserProfile() {
|
|
30
|
+
try {
|
|
31
|
+
const profile = await this.apiRequest("/users/me");
|
|
32
|
+
return profile;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("Get user profile error:", error);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Update last visited organization for the user
|
|
40
|
+
* @param organizationId - The Supabase organization ID
|
|
41
|
+
*/
|
|
42
|
+
async updateLastVisitedOrg(organizationId) {
|
|
43
|
+
try {
|
|
44
|
+
await this.apiRequest("/users/me", {
|
|
45
|
+
method: "PATCH",
|
|
46
|
+
body: JSON.stringify({ lastVisitedOrg: organizationId })
|
|
47
|
+
});
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error("Update last visited org error:", error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Update user profile data
|
|
54
|
+
*/
|
|
55
|
+
async updateUserProfile(updates) {
|
|
56
|
+
try {
|
|
57
|
+
const profile = await this.apiRequest("/users/me", {
|
|
58
|
+
method: "PATCH",
|
|
59
|
+
body: JSON.stringify(updates)
|
|
60
|
+
});
|
|
61
|
+
return profile;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error("Update user profile error:", error);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// src/profile/hooks/useUserProfile.ts
|
|
70
|
+
var useUserProfile = (options) => {
|
|
71
|
+
const { user, isLoading: authLoading } = useAuthContext();
|
|
72
|
+
const { apiRequest } = useElevasisServices();
|
|
73
|
+
const [profile, setProfile] = useState(null);
|
|
74
|
+
const [loading, setLoading] = useState(true);
|
|
75
|
+
const [error, setError] = useState(null);
|
|
76
|
+
const syncAndFetchProfile = async () => {
|
|
77
|
+
if (!user || authLoading) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
setLoading(true);
|
|
82
|
+
setError(null);
|
|
83
|
+
const profileService = new UserProfileService(apiRequest);
|
|
84
|
+
const syncedProfile = await profileService.syncUserProfile();
|
|
85
|
+
if (syncedProfile) {
|
|
86
|
+
setProfile(syncedProfile);
|
|
87
|
+
} else {
|
|
88
|
+
console.warn("Failed to sync user profile");
|
|
89
|
+
}
|
|
90
|
+
} catch (err) {
|
|
91
|
+
const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
|
|
92
|
+
if (options?.onError) {
|
|
93
|
+
options.onError(
|
|
94
|
+
{
|
|
95
|
+
phase: "profile-sync",
|
|
96
|
+
userId: user?.id
|
|
97
|
+
},
|
|
98
|
+
error2
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
setError(error2);
|
|
102
|
+
console.error("User profile sync failed:", error2);
|
|
103
|
+
} finally {
|
|
104
|
+
setLoading(false);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!authLoading) {
|
|
109
|
+
if (user) {
|
|
110
|
+
syncAndFetchProfile();
|
|
111
|
+
} else {
|
|
112
|
+
setProfile(null);
|
|
113
|
+
setLoading(false);
|
|
114
|
+
setError(null);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}, [user, authLoading]);
|
|
118
|
+
const refetch = async () => {
|
|
119
|
+
await syncAndFetchProfile();
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
profile,
|
|
123
|
+
loading: loading || authLoading,
|
|
124
|
+
error,
|
|
125
|
+
refetch
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export { UserProfileService, useUserProfile };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/components/typeform/schemas.ts
|
|
4
|
+
var answerValueSchema = z.discriminatedUnion("type", [
|
|
5
|
+
z.object({ type: z.literal("preset"), value: z.string() }),
|
|
6
|
+
z.object({ type: z.literal("custom"), value: z.string() })
|
|
7
|
+
]);
|
|
8
|
+
var multiAnswerValueSchema = z.array(answerValueSchema);
|
|
9
|
+
function radioWithOtherSchema(presetValues) {
|
|
10
|
+
return z.discriminatedUnion("type", [
|
|
11
|
+
z.object({
|
|
12
|
+
type: z.literal("preset"),
|
|
13
|
+
value: z.enum(presetValues)
|
|
14
|
+
}),
|
|
15
|
+
z.object({
|
|
16
|
+
type: z.literal("custom"),
|
|
17
|
+
value: z.string().min(1, "Please specify a value")
|
|
18
|
+
})
|
|
19
|
+
]);
|
|
20
|
+
}
|
|
21
|
+
function checkboxWithOtherSchema(presetValues) {
|
|
22
|
+
return z.array(
|
|
23
|
+
z.discriminatedUnion("type", [
|
|
24
|
+
z.object({
|
|
25
|
+
type: z.literal("preset"),
|
|
26
|
+
value: z.enum(presetValues)
|
|
27
|
+
}),
|
|
28
|
+
z.object({
|
|
29
|
+
type: z.literal("custom"),
|
|
30
|
+
value: z.string().min(1, "Please specify a value")
|
|
31
|
+
})
|
|
32
|
+
])
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { answerValueSchema, checkboxWithOtherSchema, multiAnswerValueSchema, radioWithOtherSchema };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { notifications } from '@mantine/notifications';
|
|
2
|
+
import { IconUser, IconExternalLink, IconPlug, IconBolt, IconGitBranch, IconBrain } from '@tabler/icons-react';
|
|
3
|
+
|
|
4
|
+
// src/utils/notify.tsx
|
|
5
|
+
|
|
6
|
+
// src/utils/error-utils.ts
|
|
7
|
+
var APIClientError = class extends Error {
|
|
8
|
+
statusCode;
|
|
9
|
+
code;
|
|
10
|
+
requestId;
|
|
11
|
+
fields;
|
|
12
|
+
retryAfter;
|
|
13
|
+
constructor(message, code, statusCode, requestId, fields, retryAfter) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "APIClientError";
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.statusCode = statusCode;
|
|
18
|
+
this.requestId = requestId;
|
|
19
|
+
this.fields = fields;
|
|
20
|
+
this.retryAfter = retryAfter;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function isAPIClientError(error) {
|
|
24
|
+
return error instanceof APIClientError;
|
|
25
|
+
}
|
|
26
|
+
function getErrorInfo(error) {
|
|
27
|
+
if (isAPIClientError(error)) {
|
|
28
|
+
return {
|
|
29
|
+
message: error.message,
|
|
30
|
+
code: error.code,
|
|
31
|
+
requestId: error.requestId,
|
|
32
|
+
statusCode: error.statusCode,
|
|
33
|
+
fields: error.fields,
|
|
34
|
+
retryAfter: error.retryAfter
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (error instanceof Error) {
|
|
38
|
+
return {
|
|
39
|
+
message: error.message
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
message: String(error)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function getErrorTitle(code) {
|
|
47
|
+
if (!code) return "Error";
|
|
48
|
+
switch (code) {
|
|
49
|
+
case "VALIDATION_ERROR":
|
|
50
|
+
return "Validation Error";
|
|
51
|
+
case "AUTHENTICATION_FAILED":
|
|
52
|
+
return "Authentication Required";
|
|
53
|
+
case "FORBIDDEN":
|
|
54
|
+
return "Access Denied";
|
|
55
|
+
case "NOT_FOUND":
|
|
56
|
+
return "Not Found";
|
|
57
|
+
case "CONFLICT":
|
|
58
|
+
return "Conflict";
|
|
59
|
+
case "RATE_LIMIT_EXCEEDED":
|
|
60
|
+
return "Rate Limit Exceeded";
|
|
61
|
+
case "INTERNAL_SERVER_ERROR":
|
|
62
|
+
return "Server Error";
|
|
63
|
+
case "SERVICE_UNAVAILABLE":
|
|
64
|
+
return "Service Temporarily Unavailable";
|
|
65
|
+
default:
|
|
66
|
+
return "Error";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function formatErrorMessage(message, requestId, fields, retryAfter) {
|
|
70
|
+
let formatted = message;
|
|
71
|
+
if (fields && Object.keys(fields).length > 0) {
|
|
72
|
+
const fieldErrors = [];
|
|
73
|
+
for (const [field, errors] of Object.entries(fields)) {
|
|
74
|
+
const fieldName = field === "root" || field === "_root" ? "Request" : field;
|
|
75
|
+
errors.forEach((error) => {
|
|
76
|
+
fieldErrors.push(`\u2022 ${fieldName}: ${error}`);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (fieldErrors.length > 0) {
|
|
80
|
+
formatted = fieldErrors.join("\n");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (retryAfter) {
|
|
84
|
+
formatted += `
|
|
85
|
+
|
|
86
|
+
Please wait ${retryAfter} seconds before retrying.`;
|
|
87
|
+
}
|
|
88
|
+
if (requestId) {
|
|
89
|
+
formatted += `
|
|
90
|
+
|
|
91
|
+
Request ID: ${requestId}`;
|
|
92
|
+
}
|
|
93
|
+
return formatted;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/utils/notify.tsx
|
|
97
|
+
var showInfoNotification = (message) => {
|
|
98
|
+
notifications.show({
|
|
99
|
+
title: "Info",
|
|
100
|
+
message,
|
|
101
|
+
autoClose: 5e3,
|
|
102
|
+
color: "blue",
|
|
103
|
+
position: "top-right"
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
var showSuccessNotification = (message) => {
|
|
107
|
+
notifications.show({
|
|
108
|
+
title: "Action Successful",
|
|
109
|
+
message,
|
|
110
|
+
autoClose: 5e3,
|
|
111
|
+
color: "green",
|
|
112
|
+
position: "top-right"
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
var showErrorNotification = (error) => {
|
|
116
|
+
if (error instanceof Error) {
|
|
117
|
+
error = error.message;
|
|
118
|
+
}
|
|
119
|
+
notifications.show({
|
|
120
|
+
title: "Action Failed",
|
|
121
|
+
message: error,
|
|
122
|
+
autoClose: 5e3,
|
|
123
|
+
color: "red",
|
|
124
|
+
position: "top-right"
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
var showWarningNotification = (message) => {
|
|
128
|
+
notifications.show({
|
|
129
|
+
title: "Warning",
|
|
130
|
+
message,
|
|
131
|
+
autoClose: 5e3,
|
|
132
|
+
color: "orange",
|
|
133
|
+
position: "top-right"
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
var showApiErrorNotification = (error) => {
|
|
137
|
+
const { message, code, requestId, fields, retryAfter } = getErrorInfo(error);
|
|
138
|
+
notifications.show({
|
|
139
|
+
title: getErrorTitle(code),
|
|
140
|
+
message: formatErrorMessage(message, requestId, fields, retryAfter),
|
|
141
|
+
autoClose: retryAfter ? retryAfter * 1e3 : 5e3,
|
|
142
|
+
color: "red",
|
|
143
|
+
position: "top-right"
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// src/utils/formatDate.ts
|
|
148
|
+
var formatDate = (dateString) => {
|
|
149
|
+
const date = new Date(dateString);
|
|
150
|
+
return date.toLocaleDateString("en-US", {
|
|
151
|
+
year: "numeric",
|
|
152
|
+
month: "long",
|
|
153
|
+
day: "numeric",
|
|
154
|
+
hour: "2-digit",
|
|
155
|
+
minute: "2-digit"
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// src/utils/validateEmail.ts
|
|
160
|
+
var validateEmail = (email) => {
|
|
161
|
+
return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+$/.test(email);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// ../core/src/platform/registry/resource-metadata.ts
|
|
165
|
+
var resourceTypeIconNames = {
|
|
166
|
+
agent: "IconBrain",
|
|
167
|
+
workflow: "IconGitBranch",
|
|
168
|
+
trigger: "IconBolt",
|
|
169
|
+
integration: "IconPlug",
|
|
170
|
+
external: "IconExternalLink",
|
|
171
|
+
human: "IconUser"
|
|
172
|
+
};
|
|
173
|
+
var resourceTypeColors = {
|
|
174
|
+
agent: "violet",
|
|
175
|
+
workflow: "blue",
|
|
176
|
+
trigger: "orange",
|
|
177
|
+
integration: "teal",
|
|
178
|
+
external: "gray",
|
|
179
|
+
human: "yellow"
|
|
180
|
+
};
|
|
181
|
+
function getResourceIconName(type) {
|
|
182
|
+
return resourceTypeIconNames[type];
|
|
183
|
+
}
|
|
184
|
+
function getResourceColor(type) {
|
|
185
|
+
return resourceTypeColors[type];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/utils/resource-icons.tsx
|
|
189
|
+
var iconNameToComponent = {
|
|
190
|
+
IconBrain,
|
|
191
|
+
IconGitBranch,
|
|
192
|
+
IconBolt,
|
|
193
|
+
IconPlug,
|
|
194
|
+
IconExternalLink,
|
|
195
|
+
IconUser
|
|
196
|
+
};
|
|
197
|
+
function getResourceIcon(type) {
|
|
198
|
+
const iconName = getResourceIconName(type);
|
|
199
|
+
return iconNameToComponent[iconName];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export { APIClientError, formatDate, formatErrorMessage, getErrorInfo, getErrorTitle, getResourceColor, getResourceIcon, isAPIClientError, showApiErrorNotification, showErrorNotification, showInfoNotification, showSuccessNotification, showWarningNotification, validateEmail };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createContext, useContext, createElement } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/auth/context.ts
|
|
4
|
+
var AuthContext = createContext(null);
|
|
5
|
+
function useAuthContext() {
|
|
6
|
+
const ctx = useContext(AuthContext);
|
|
7
|
+
if (!ctx) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"useAuthContext must be used within an AuthProvider. Wrap your app with <ElevasisProvider> or a custom AuthProvider."
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
function AuthProvider({ value, children }) {
|
|
15
|
+
return createElement(AuthContext.Provider, { value }, children);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { AuthProvider, useAuthContext };
|