@wazobiatech/wazui 0.0.4 → 0.0.6
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 +1 -1
- package/USAGE.md +96 -0
- package/package.json +8 -4
- package/src/assets/dashboard/book.svg +0 -6
- package/src/assets/dashboard/edit.svg +0 -5
- package/src/assets/dashboard/emerald.svg +0 -9
- package/src/assets/dashboard/eye.svg +0 -4
- package/src/assets/dashboard/gold.svg +0 -9
- package/src/assets/dashboard/percentage-square.svg +0 -6
- package/src/assets/dashboard/sapphire.svg +0 -9
- package/src/assets/dashboard/send-2.svg +0 -4
- package/src/assets/desktop.svg +0 -7
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.otf +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff2 +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.otf +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff +0 -0
- package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff2 +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.otf +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff2 +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.otf +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff +0 -0
- package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff2 +0 -0
- package/src/assets/instagram.svg +0 -9
- package/src/assets/mobile.svg +0 -4
- package/src/assets/no-data-image.svg +0 -41
- package/src/assets/no-image-icon.svg +0 -84
- package/src/assets/pexels.svg +0 -9
- package/src/assets/react.svg +0 -1
- package/src/assets/sounds/draft.mp3 +0 -0
- package/src/assets/sounds/error.mp3 +0 -0
- package/src/assets/sounds/publish.mp3 +0 -0
- package/src/assets/tablet.svg +0 -4
- package/src/assets/unsplash.svg +0 -3
- package/src/assets/upload-image.svg +0 -43
- package/src/assets/user.svg +0 -4
- package/src/components/shadcn/index.ts +0 -31
- package/src/config/env.ts +0 -15
- package/src/contexts/ThemeContext.tsx +0 -11
- package/src/data/users.json +0 -6014
- package/src/decorators/ActionModalDecorator.tsx +0 -10
- package/src/decorators/ApolloDecorator.tsx +0 -19
- package/src/decorators/DolosApolloDecorator.tsx +0 -31
- package/src/decorators/JestDecorators.tsx +0 -34
- package/src/decorators/ReactQueryDecorator.tsx +0 -13
- package/src/decorators/RouterDecorator.tsx +0 -5
- package/src/decorators/UnsafePropsDecorator.tsx +0 -0
- package/src/env.ts +0 -99
- package/src/hooks/use-autogrow.ts +0 -28
- package/src/hooks/use-mobile.ts +0 -19
- package/src/hooks/useAuthors.ts +0 -78
- package/src/hooks/useDebounce.ts +0 -18
- package/src/hooks/useMercuryProjectToken.ts +0 -112
- package/src/hooks/useProjectToken.ts +0 -21
- package/src/hooks/useTheme.ts +0 -12
- package/src/index.css +0 -397
- package/src/index.ts +0 -62
- package/src/mocks/env.ts +0 -12
- package/src/providers/QueryProvider/index.tsx +0 -10
- package/src/providers/ThemeProvider/index.tsx +0 -52
- package/src/types/category.types.ts +0 -13
- package/src/types/image.types.ts +0 -44
- package/src/types/post.types.ts +0 -121
- package/src/types/theme.types.ts +0 -10
- package/src/types/users.types.ts +0 -5
- package/src/utils/apolloClient.ts +0 -160
- package/src/utils/articleMetadata.ts +0 -92
- package/src/utils/audio.ts +0 -10
- package/src/utils/imageProcessing.ts +0 -399
- package/src/utils/images.ts +0 -279
- package/src/utils/mercury.ts +0 -0
- package/src/utils/utils.ts +0 -638
- package/src/utils/videos.ts +0 -29
- package/src/vite-env.d.ts +0 -1
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { WazuiActionModalProvider } from '@/components/wazui/WazuiActionModal/provider';
|
|
2
|
-
import { Decorator } from '@storybook/react';
|
|
3
|
-
|
|
4
|
-
export const withActionModalProvider: Decorator = Story => {
|
|
5
|
-
return (
|
|
6
|
-
<WazuiActionModalProvider>
|
|
7
|
-
<Story />
|
|
8
|
-
</WazuiActionModalProvider>
|
|
9
|
-
);
|
|
10
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { createApolloClient } from '@/utils/apolloClient';
|
|
2
|
-
import { ApolloProvider } from '@apollo/client/react';
|
|
3
|
-
import { env } from '@/env';
|
|
4
|
-
import { Decorator } from '@storybook/react';
|
|
5
|
-
|
|
6
|
-
export const withApollo: Decorator = (Story, context) => {
|
|
7
|
-
const apolloConfig = context.parameters.apollo;
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
// use muse endpoint as default
|
|
11
|
-
|
|
12
|
-
<ApolloProvider client={createApolloClient(apolloConfig?.uri || env.VITE_MUSE_ENDPOINT)}>
|
|
13
|
-
<Story />
|
|
14
|
-
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js'></script>
|
|
15
|
-
<script src='https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js'></script>
|
|
16
|
-
<script src='https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js'></script>
|
|
17
|
-
</ApolloProvider>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { ApolloClient, InMemoryCache } from '@apollo/client';
|
|
2
|
-
import { ApolloProvider } from '@apollo/client/react';
|
|
3
|
-
import { Decorator } from '@storybook/react';
|
|
4
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
5
|
-
// import createUploadLink from 'apollo-upload-client/createUploadLink.mjs';
|
|
6
|
-
import UploadHttpLink from 'apollo-upload-client/UploadHttpLink.mjs';
|
|
7
|
-
import { createTestQueryClient } from './JestDecorators';
|
|
8
|
-
import { env } from '@/env';
|
|
9
|
-
|
|
10
|
-
export const dolosApolloClient = new ApolloClient({
|
|
11
|
-
cache: new InMemoryCache(),
|
|
12
|
-
link: new UploadHttpLink({ uri: env.VITE_DOLOS_URL }),
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export const withDolosApollo: Decorator = Story => {
|
|
16
|
-
return (
|
|
17
|
-
<ApolloProvider client={dolosApolloClient}>
|
|
18
|
-
<Story />
|
|
19
|
-
</ApolloProvider>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const dolosTestProviders = ({ children }: { children: React.ReactNode }) => {
|
|
24
|
-
const queryClient = createTestQueryClient();
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<QueryClientProvider client={queryClient}>
|
|
28
|
-
<ApolloProvider client={dolosApolloClient}>{children}</ApolloProvider>
|
|
29
|
-
</QueryClientProvider>
|
|
30
|
-
);
|
|
31
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { ApolloClient } from '@apollo/client';
|
|
2
|
-
import { ApolloProvider } from '@apollo/client/react';
|
|
3
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
-
import { createApolloClient } from '@/utils/apolloClient';
|
|
5
|
-
import { WazuiActionModalProvider } from '@/components/wazui/WazuiActionModal/provider';
|
|
6
|
-
|
|
7
|
-
// Create test clients with mocked responses
|
|
8
|
-
export const createTestQueryClient = () =>
|
|
9
|
-
new QueryClient({
|
|
10
|
-
defaultOptions: {
|
|
11
|
-
queries: {
|
|
12
|
-
retry: false,
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Create a wrapper for both providers
|
|
18
|
-
export const AllTestProviders = ({
|
|
19
|
-
children,
|
|
20
|
-
}: {
|
|
21
|
-
children: React.ReactNode;
|
|
22
|
-
apolloClient?: ApolloClient;
|
|
23
|
-
}) => {
|
|
24
|
-
const queryClient = createTestQueryClient();
|
|
25
|
-
const client = createApolloClient('https://muse.hogfort.com/graphql');
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<QueryClientProvider client={queryClient}>
|
|
29
|
-
<WazuiActionModalProvider>
|
|
30
|
-
<ApolloProvider client={client}>{children}</ApolloProvider>
|
|
31
|
-
</WazuiActionModalProvider>
|
|
32
|
-
</QueryClientProvider>
|
|
33
|
-
);
|
|
34
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Decorator } from '@storybook/react';
|
|
2
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
3
|
-
// import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
|
4
|
-
|
|
5
|
-
const queryClient = new QueryClient();
|
|
6
|
-
export const withReactQuery: Decorator = Story => {
|
|
7
|
-
return (
|
|
8
|
-
<QueryClientProvider client={queryClient}>
|
|
9
|
-
{/* <ReactQueryDevtools initialIsOpen /> */}
|
|
10
|
-
<Story />
|
|
11
|
-
</QueryClientProvider>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
File without changes
|
package/src/env.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
const envSchema = z.object({
|
|
4
|
-
VITE_PORTAL_GRAPHQL_ENDPOINT: z.string(),
|
|
5
|
-
VITE_DOLOS_URL: z.string(),
|
|
6
|
-
VITE_DOLOS_TRANSFORMATION_ENDPOINT: z.string(),
|
|
7
|
-
VITE_MUSE_TOKEN: z.string(),
|
|
8
|
-
VITE_MUSE_ENDPOINT: z.string(),
|
|
9
|
-
VITE_RECIPES_ENDPOINT: z.string(),
|
|
10
|
-
VITE_PHOENIX_ENDPOINT: z.string(),
|
|
11
|
-
VITE_MERCURY_TOKEN_ENDPOINT: z.string(),
|
|
12
|
-
VITE_ATHENS_APP_ID: z.string(),
|
|
13
|
-
VITE_ATHENS_APP_SECRET: z.string(),
|
|
14
|
-
VITE_PROJECT_TOKEN: z.string(),
|
|
15
|
-
VITE_REVALIDATION_TWISTEDFOOD_TOKEN: z.string(),
|
|
16
|
-
VITE_REVALIDATION_VT_TOKEN: z.string(),
|
|
17
|
-
VITE_GRAPH_QL_URL: z.string().optional(),
|
|
18
|
-
VITE_MUSE_GRAPHQL_URL: z.string().optional(),
|
|
19
|
-
VITE_RECIPE_GRAPHQL_URL: z.string().optional(),
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const getEnvironmentVariables = () => {
|
|
23
|
-
// In Next.js environment, use process.env; in Vite environment, use import.meta.env
|
|
24
|
-
const isViteEnvironment = typeof import.meta !== 'undefined' && (import.meta as unknown as { env: Record<string, string | undefined> }).env;
|
|
25
|
-
const isNextEnvironment = typeof process !== 'undefined' && process.env;
|
|
26
|
-
|
|
27
|
-
if (process.env.NODE_ENV === 'test') {
|
|
28
|
-
return {
|
|
29
|
-
VITE_PORTAL_GRAPHQL_ENDPOINT: process.env.VITE_DOLOS_URL ?? 'https://fallback.test',
|
|
30
|
-
VITE_DOLOS_URL: process.env.VITE_DOLOS_URL ?? 'https://fallback.test',
|
|
31
|
-
VITE_DOLOS_TRANSFORMATION_ENDPOINT: process.env.VITE_DOLOS_URL ?? 'https://fallback.test',
|
|
32
|
-
VITE_MUSE_TOKEN: process.env.VITE_MUSE_TOKEN ?? 'fallback-token',
|
|
33
|
-
VITE_MUSE_ENDPOINT: process.env.VITE_MUSE_ENDPOINT ?? 'https://fallback.test',
|
|
34
|
-
VITE_RECIPES_ENDPOINT: process.env.VITE_RECIPES_ENDPOINT ?? 'https://fallback.test',
|
|
35
|
-
VITE_PHOENIX_ENDPOINT: process.env.VITE_PHOENIX_ENDPOINT ?? 'https://fallback.test',
|
|
36
|
-
VITE_MERCURY_TOKEN_ENDPOINT:
|
|
37
|
-
process.env.VITE_MERCURY_TOKEN_ENDPOINT ?? 'https://fallback.test',
|
|
38
|
-
VITE_ATHENS_APP_ID: process.env.VITE_ATHENS_APP_ID ?? 'https://fallback.test',
|
|
39
|
-
VITE_ATHENS_APP_SECRET: process.env.VITE_ATHENS_APP_SECRET ?? 'https://fallback.test',
|
|
40
|
-
VITE_PROJECT_TOKEN: process.env.VITE_PROJECT_TOKEN ?? '',
|
|
41
|
-
VITE_REVALIDATION_TWISTEDFOOD_TOKEN: process.env.VITE_REVALIDATION_TWISTEDFOOD_TOKEN ?? 'fallback-token',
|
|
42
|
-
VITE_REVALIDATION_VT_TOKEN: process.env.VITE_REVALIDATION_VT_TOKEN ?? 'fallback-token',
|
|
43
|
-
VITE_GRAPH_QL_URL: process.env.VITE_GRAPH_QL_URL ?? '',
|
|
44
|
-
VITE_MUSE_GRAPHQL_URL: process.env.VITE_MUSE_GRAPHQL_URL ?? '',
|
|
45
|
-
VITE_RECIPE_GRAPHQL_URL: process.env.VITE_RECIPE_GRAPHQL_URL ?? '',
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let envSource: Record<string, string | undefined> = {};
|
|
50
|
-
|
|
51
|
-
if (isViteEnvironment) {
|
|
52
|
-
// Use Vite's import.meta.env
|
|
53
|
-
envSource = (import.meta as unknown as { env: Record<string, string | undefined> }).env;
|
|
54
|
-
} else if (isNextEnvironment) {
|
|
55
|
-
envSource = {
|
|
56
|
-
VITE_PORTAL_GRAPHQL_ENDPOINT: process.env.NEXT_PUBLIC_GRAPHQL_URL,
|
|
57
|
-
VITE_DOLOS_URL: process.env.NEXT_PUBLIC_DOLOS_URL,
|
|
58
|
-
VITE_DOLOS_TRANSFORMATION_ENDPOINT: process.env.NEXT_PUBLIC_DOLOS_TRANSFORMATION_ENDPOINT,
|
|
59
|
-
VITE_MUSE_TOKEN: process.env.NEXT_PUBLIC_MUSE_TOKEN,
|
|
60
|
-
VITE_MUSE_ENDPOINT: process.env.NEXT_PUBLIC_MUSE_GRAPHQL_URL,
|
|
61
|
-
VITE_RECIPES_ENDPOINT: process.env.NEXT_PUBLIC_RECIPE_GRAPHQL_URL,
|
|
62
|
-
VITE_PHOENIX_ENDPOINT: process.env.NEXT_PUBLIC_PHOENIX_ENDPOINT,
|
|
63
|
-
VITE_MERCURY_TOKEN_ENDPOINT: process.env.NEXT_PUBLIC_MERCURY_TOKEN_ENDPOINT,
|
|
64
|
-
VITE_ATHENS_APP_ID: process.env.NEXT_PUBLIC_ATHENS_APP_ID,
|
|
65
|
-
VITE_ATHENS_APP_SECRET: process.env.NEXT_PUBLIC_ATHENS_APP_SECRET,
|
|
66
|
-
VITE_PROJECT_TOKEN: process.env.NEXT_PUBLIC_PROJECT_TOKEN,
|
|
67
|
-
VITE_REVALIDATION_TWISTEDFOOD_TOKEN: process.env.NEXT_PUBLIC_REVALIDATION_TWISTEDFOOD_TOKEN,
|
|
68
|
-
VITE_REVALIDATION_VT_TOKEN: process.env.NEXT_PUBLIC_REVALIDATION_VT_TOKEN,
|
|
69
|
-
VITE_GRAPH_QL_URL: process.env.NEXT_PUBLIC_GRAPH_QL_URL,
|
|
70
|
-
VITE_MUSE_GRAPHQL_URL: process.env.NEXT_PUBLIC_MUSE_GRAPHQL_URL,
|
|
71
|
-
VITE_RECIPE_GRAPHQL_URL: process.env.NEXT_PUBLIC_RECIPE_GRAPHQL_URL,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
VITE_PORTAL_GRAPHQL_ENDPOINT: envSource.VITE_PORTAL_GRAPHQL_ENDPOINT,
|
|
77
|
-
VITE_DOLOS_URL: envSource.VITE_DOLOS_URL,
|
|
78
|
-
VITE_DOLOS_TRANSFORMATION_ENDPOINT: envSource.VITE_DOLOS_TRANSFORMATION_ENDPOINT,
|
|
79
|
-
VITE_MUSE_TOKEN: envSource.VITE_MUSE_TOKEN,
|
|
80
|
-
VITE_MUSE_ENDPOINT: envSource.VITE_MUSE_ENDPOINT,
|
|
81
|
-
VITE_RECIPES_ENDPOINT: envSource.VITE_RECIPES_ENDPOINT,
|
|
82
|
-
VITE_PHOENIX_ENDPOINT: envSource.VITE_PHOENIX_ENDPOINT,
|
|
83
|
-
VITE_MERCURY_TOKEN_ENDPOINT: envSource.VITE_MERCURY_TOKEN_ENDPOINT,
|
|
84
|
-
VITE_ATHENS_APP_ID: envSource.VITE_ATHENS_APP_ID,
|
|
85
|
-
VITE_ATHENS_APP_SECRET: envSource.VITE_ATHENS_APP_SECRET,
|
|
86
|
-
VITE_PROJECT_TOKEN: envSource.VITE_PROJECT_TOKEN,
|
|
87
|
-
VITE_REVALIDATION_TWISTEDFOOD_TOKEN: envSource.VITE_REVALIDATION_TWISTEDFOOD_TOKEN,
|
|
88
|
-
VITE_REVALIDATION_VT_TOKEN: envSource.VITE_REVALIDATION_VT_TOKEN,
|
|
89
|
-
VITE_GRAPH_QL_URL: envSource.VITE_GRAPH_QL_URL,
|
|
90
|
-
VITE_MUSE_GRAPHQL_URL: envSource.VITE_MUSE_GRAPHQL_URL,
|
|
91
|
-
VITE_RECIPE_GRAPHQL_URL: envSource.VITE_RECIPE_GRAPHQL_URL,
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const raw = getEnvironmentVariables();
|
|
96
|
-
// ts-expect-error Node fails to recognize env vars
|
|
97
|
-
export const env = envSchema.parse(raw);
|
|
98
|
-
|
|
99
|
-
export type Env = z.infer<typeof envSchema>;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
export const useAutoGrow = (maxRows = 3) => {
|
|
4
|
-
const ref = useRef<HTMLTextAreaElement>(null);
|
|
5
|
-
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const el = ref.current;
|
|
8
|
-
if (!el) return;
|
|
9
|
-
|
|
10
|
-
const { lineHeight } = getComputedStyle(el);
|
|
11
|
-
const maxHeight = parseFloat(lineHeight) * maxRows;
|
|
12
|
-
|
|
13
|
-
const resize = () => {
|
|
14
|
-
el.style.height = 'auto'; // reset to shrink when deleting
|
|
15
|
-
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
resize(); // initial
|
|
19
|
-
el.addEventListener('input', resize);
|
|
20
|
-
el.addEventListener('focusin', resize);
|
|
21
|
-
return () => {
|
|
22
|
-
el.removeEventListener('input', resize);
|
|
23
|
-
el.removeEventListener('focusin', resize);
|
|
24
|
-
};
|
|
25
|
-
}, [maxRows]);
|
|
26
|
-
|
|
27
|
-
return ref;
|
|
28
|
-
};
|
package/src/hooks/use-mobile.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
const MOBILE_BREAKPOINT = 768;
|
|
4
|
-
|
|
5
|
-
export function useIsMobile() {
|
|
6
|
-
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
|
|
7
|
-
|
|
8
|
-
React.useEffect(() => {
|
|
9
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
10
|
-
const onChange = () => {
|
|
11
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
-
};
|
|
13
|
-
mql.addEventListener('change', onChange);
|
|
14
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
15
|
-
return () => mql.removeEventListener('change', onChange);
|
|
16
|
-
}, []);
|
|
17
|
-
|
|
18
|
-
return !!isMobile;
|
|
19
|
-
}
|
package/src/hooks/useAuthors.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { QueryConfig } from '@/components/wazui/WazUiBlogComponent/types';
|
|
2
|
-
import { useInfiniteQuery } from '@tanstack/react-query';
|
|
3
|
-
import { useDebounce } from './useDebounce';
|
|
4
|
-
import { useCallback, useMemo } from 'react';
|
|
5
|
-
import { createApolloClient } from '@/utils/apolloClient';
|
|
6
|
-
import { GET_ALL_USERS } from '@/components/wazui/WazUiCreateBlogContent/samples/queries';
|
|
7
|
-
|
|
8
|
-
export function useAuthors({
|
|
9
|
-
searchValue,
|
|
10
|
-
apolloUri,
|
|
11
|
-
}: {
|
|
12
|
-
config?: QueryConfig;
|
|
13
|
-
searchValue?: string;
|
|
14
|
-
apolloUri: string;
|
|
15
|
-
}) {
|
|
16
|
-
const config = useMemo(
|
|
17
|
-
() => ({
|
|
18
|
-
query: GET_ALL_USERS,
|
|
19
|
-
variables: { first: 350 },
|
|
20
|
-
dataKey: 'users',
|
|
21
|
-
}),
|
|
22
|
-
[]
|
|
23
|
-
);
|
|
24
|
-
const client = createApolloClient(apolloUri);
|
|
25
|
-
|
|
26
|
-
// Simple optimization: Debounce search to reduce API calls
|
|
27
|
-
const debouncedSearchValue = useDebounce(searchValue || '', 300);
|
|
28
|
-
|
|
29
|
-
// Simple optimization: Memoize query function
|
|
30
|
-
const queryFn = useCallback(
|
|
31
|
-
async ({ pageParam = 1 }) => {
|
|
32
|
-
if (config?.query) {
|
|
33
|
-
const query = config?.query;
|
|
34
|
-
const variables = config?.variables;
|
|
35
|
-
const response = await client.query({
|
|
36
|
-
query,
|
|
37
|
-
variables: {
|
|
38
|
-
...(variables || {}),
|
|
39
|
-
search: debouncedSearchValue,
|
|
40
|
-
page: pageParam,
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
const data = response.data as Record<string, unknown>;
|
|
44
|
-
const dataKey = data[config.dataKey] as {
|
|
45
|
-
paginatorInfo?: { currentPage: number; lastPage: number };
|
|
46
|
-
data: unknown[];
|
|
47
|
-
};
|
|
48
|
-
return {
|
|
49
|
-
paginatorInfo: dataKey.paginatorInfo || {
|
|
50
|
-
currentPage: 1,
|
|
51
|
-
lastPage: 1,
|
|
52
|
-
},
|
|
53
|
-
data: dataKey?.data,
|
|
54
|
-
};
|
|
55
|
-
} else {
|
|
56
|
-
console.error('Invalid Query Configuration');
|
|
57
|
-
throw Error('Invalid Query Configuration');
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
[client, config, debouncedSearchValue]
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
return useInfiniteQuery({
|
|
64
|
-
queryKey: [config?.dataKey, debouncedSearchValue],
|
|
65
|
-
queryFn,
|
|
66
|
-
getNextPageParam: lastPage => {
|
|
67
|
-
if (lastPage?.paginatorInfo?.currentPage < lastPage?.paginatorInfo?.lastPage) {
|
|
68
|
-
return lastPage.paginatorInfo.currentPage + 1;
|
|
69
|
-
}
|
|
70
|
-
return undefined;
|
|
71
|
-
},
|
|
72
|
-
initialPageParam: 1,
|
|
73
|
-
staleTime: 5 * 60 * 1000,
|
|
74
|
-
gcTime: 10 * 60 * 1000,
|
|
75
|
-
refetchOnMount: false,
|
|
76
|
-
refetchOnWindowFocus: false,
|
|
77
|
-
});
|
|
78
|
-
}
|
package/src/hooks/useDebounce.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
export function useDebounce<T>(value: T, delay: number): T {
|
|
5
|
-
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const handler = setTimeout(() => {
|
|
9
|
-
setDebouncedValue(value);
|
|
10
|
-
}, delay);
|
|
11
|
-
|
|
12
|
-
return () => {
|
|
13
|
-
clearTimeout(handler);
|
|
14
|
-
};
|
|
15
|
-
}, [value, delay]);
|
|
16
|
-
|
|
17
|
-
return debouncedValue;
|
|
18
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { env } from '@/env';
|
|
2
|
-
import { useQuery } from '@tanstack/react-query';
|
|
3
|
-
import axios from 'axios';
|
|
4
|
-
|
|
5
|
-
interface MercuryTokenResponse {
|
|
6
|
-
success: boolean;
|
|
7
|
-
token: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface TokenCache {
|
|
11
|
-
token: string;
|
|
12
|
-
expiresAt: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class TokenManager {
|
|
16
|
-
private tokenCache: TokenCache | null = null;
|
|
17
|
-
private refreshPromise: Promise<string> | null = null;
|
|
18
|
-
|
|
19
|
-
constructor(
|
|
20
|
-
private readonly mercuryUrl: string,
|
|
21
|
-
private readonly appId: string,
|
|
22
|
-
private readonly appSecret: string
|
|
23
|
-
) {}
|
|
24
|
-
|
|
25
|
-
async getToken(): Promise<string> {
|
|
26
|
-
if (this.tokenCache && this.isTokenValid()) {
|
|
27
|
-
return this.tokenCache.token;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (this.refreshPromise) {
|
|
31
|
-
return this.refreshPromise;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this.refreshPromise = this.fetchNewToken();
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
const token = await this.refreshPromise;
|
|
38
|
-
return token;
|
|
39
|
-
} finally {
|
|
40
|
-
this.refreshPromise = null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private isTokenValid(): boolean {
|
|
45
|
-
if (!this.tokenCache) return false;
|
|
46
|
-
return Date.now() < this.tokenCache.expiresAt;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private async fetchNewToken(): Promise<string> {
|
|
50
|
-
try {
|
|
51
|
-
const response = await axios.post(this.mercuryUrl, {
|
|
52
|
-
app_id: this.appId,
|
|
53
|
-
app_secret: this.appSecret,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const data: MercuryTokenResponse = response.data;
|
|
57
|
-
|
|
58
|
-
if (!data.token) {
|
|
59
|
-
throw new Error('No token received from Mercury');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
this.tokenCache = {
|
|
63
|
-
token: data.token,
|
|
64
|
-
expiresAt: Date.now() + 60 * 60 * 1000,
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
return data.token;
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.error('Failed to fetch token from Mercury:', error);
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
clearCache(): void {
|
|
75
|
-
this.tokenCache = null;
|
|
76
|
-
this.refreshPromise = null;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let tokenManagerInstance: TokenManager | null = null;
|
|
81
|
-
|
|
82
|
-
function getTokenManager(): TokenManager {
|
|
83
|
-
if (!tokenManagerInstance) {
|
|
84
|
-
tokenManagerInstance = new TokenManager(
|
|
85
|
-
env.VITE_MERCURY_TOKEN_ENDPOINT,
|
|
86
|
-
env.VITE_ATHENS_APP_ID,
|
|
87
|
-
env.VITE_ATHENS_APP_SECRET
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
return tokenManagerInstance;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export const fetchMercuryToken = async (): Promise<MercuryTokenResponse> => {
|
|
94
|
-
const tokenManager = getTokenManager();
|
|
95
|
-
const token = await tokenManager.getToken();
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
success: true,
|
|
99
|
-
token,
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export function useMercuryProjectToken() {
|
|
104
|
-
return useQuery<MercuryTokenResponse>({
|
|
105
|
-
queryKey: ['mercury-project-token'],
|
|
106
|
-
staleTime: Infinity,
|
|
107
|
-
gcTime: Infinity,
|
|
108
|
-
queryFn: fetchMercuryToken,
|
|
109
|
-
refetchOnWindowFocus: false,
|
|
110
|
-
refetchOnMount: false,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useQuery } from '@tanstack/react-query';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Hook for fetching project token with React Query caching
|
|
5
|
-
* This is the only hook that should use React Query for the dashboard
|
|
6
|
-
*/
|
|
7
|
-
export function useProjectToken() {
|
|
8
|
-
return useQuery({
|
|
9
|
-
queryKey: ['project-token'],
|
|
10
|
-
staleTime: 50 * 60000, // Data stays fresh for 50 minutes
|
|
11
|
-
gcTime: 50 * 60000, // Data stays fresh for 50 minutes
|
|
12
|
-
queryFn: async () => {
|
|
13
|
-
// This would be replaced with actual project token fetching logic
|
|
14
|
-
const projectToken = import.meta.env.VITE_PROJECT_TOKEN;
|
|
15
|
-
if (!projectToken) {
|
|
16
|
-
throw new Error('Project token not configured');
|
|
17
|
-
}
|
|
18
|
-
return projectToken;
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
}
|
package/src/hooks/useTheme.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import ThemeContext from '@/contexts/ThemeContext';
|
|
2
|
-
import { useContext } from 'react';
|
|
3
|
-
|
|
4
|
-
const useTheme = () => {
|
|
5
|
-
const context = useContext(ThemeContext);
|
|
6
|
-
|
|
7
|
-
if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider');
|
|
8
|
-
|
|
9
|
-
return context;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default useTheme;
|