@wazobiatech/wazui 0.0.5 → 0.0.7

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.
Files changed (75) hide show
  1. package/README.md +3 -3
  2. package/USAGE.md +96 -0
  3. package/package.json +8 -4
  4. package/src/assets/dashboard/book.svg +0 -6
  5. package/src/assets/dashboard/edit.svg +0 -5
  6. package/src/assets/dashboard/emerald.svg +0 -9
  7. package/src/assets/dashboard/eye.svg +0 -4
  8. package/src/assets/dashboard/gold.svg +0 -9
  9. package/src/assets/dashboard/percentage-square.svg +0 -6
  10. package/src/assets/dashboard/sapphire.svg +0 -9
  11. package/src/assets/dashboard/send-2.svg +0 -4
  12. package/src/assets/desktop.svg +0 -7
  13. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.otf +0 -0
  14. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff +0 -0
  15. package/src/assets/fonts/UniversalFeature/FeatureJungle-Light.woff2 +0 -0
  16. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.otf +0 -0
  17. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff +0 -0
  18. package/src/assets/fonts/UniversalFeature/FeatureJungle-Regular.woff2 +0 -0
  19. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.otf +0 -0
  20. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff +0 -0
  21. package/src/assets/fonts/UniversalJungle/UniversalJungle-420.woff2 +0 -0
  22. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.otf +0 -0
  23. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff +0 -0
  24. package/src/assets/fonts/UniversalJungle/UniversalJungle-515.woff2 +0 -0
  25. package/src/assets/instagram.svg +0 -9
  26. package/src/assets/mobile.svg +0 -4
  27. package/src/assets/no-data-image.svg +0 -41
  28. package/src/assets/no-image-icon.svg +0 -84
  29. package/src/assets/pexels.svg +0 -9
  30. package/src/assets/react.svg +0 -1
  31. package/src/assets/sounds/draft.mp3 +0 -0
  32. package/src/assets/sounds/error.mp3 +0 -0
  33. package/src/assets/sounds/publish.mp3 +0 -0
  34. package/src/assets/tablet.svg +0 -4
  35. package/src/assets/unsplash.svg +0 -3
  36. package/src/assets/upload-image.svg +0 -43
  37. package/src/assets/user.svg +0 -4
  38. package/src/components/shadcn/index.ts +0 -31
  39. package/src/config/env.ts +0 -15
  40. package/src/contexts/ThemeContext.tsx +0 -11
  41. package/src/data/users.json +0 -6014
  42. package/src/decorators/ActionModalDecorator.tsx +0 -10
  43. package/src/decorators/ApolloDecorator.tsx +0 -19
  44. package/src/decorators/DolosApolloDecorator.tsx +0 -31
  45. package/src/decorators/JestDecorators.tsx +0 -34
  46. package/src/decorators/ReactQueryDecorator.tsx +0 -13
  47. package/src/decorators/RouterDecorator.tsx +0 -5
  48. package/src/decorators/UnsafePropsDecorator.tsx +0 -0
  49. package/src/env.ts +0 -99
  50. package/src/hooks/use-autogrow.ts +0 -28
  51. package/src/hooks/use-mobile.ts +0 -19
  52. package/src/hooks/useAuthors.ts +0 -78
  53. package/src/hooks/useDebounce.ts +0 -18
  54. package/src/hooks/useMercuryProjectToken.ts +0 -112
  55. package/src/hooks/useProjectToken.ts +0 -21
  56. package/src/hooks/useTheme.ts +0 -12
  57. package/src/index.css +0 -397
  58. package/src/index.ts +0 -62
  59. package/src/mocks/env.ts +0 -12
  60. package/src/providers/QueryProvider/index.tsx +0 -10
  61. package/src/providers/ThemeProvider/index.tsx +0 -52
  62. package/src/types/category.types.ts +0 -13
  63. package/src/types/image.types.ts +0 -44
  64. package/src/types/post.types.ts +0 -121
  65. package/src/types/theme.types.ts +0 -10
  66. package/src/types/users.types.ts +0 -5
  67. package/src/utils/apolloClient.ts +0 -160
  68. package/src/utils/articleMetadata.ts +0 -92
  69. package/src/utils/audio.ts +0 -10
  70. package/src/utils/imageProcessing.ts +0 -399
  71. package/src/utils/images.ts +0 -279
  72. package/src/utils/mercury.ts +0 -0
  73. package/src/utils/utils.ts +0 -638
  74. package/src/utils/videos.ts +0 -29
  75. 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
- };
@@ -1,5 +0,0 @@
1
- import { Decorator } from '@storybook/react';
2
-
3
- export const withRouter: Decorator = Story => {
4
- return <Story />;
5
- };
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
- };
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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;