@sudobility/building_blocks 0.0.202 → 0.0.203
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/{SafeSubscriptionContext-CNuEKeqJ.js → SafeSubscriptionContext-D4q_l1Kw.js} +8 -2
- package/dist/SafeSubscriptionContext-D4q_l1Kw.js.map +1 -0
- package/dist/{SubscriptionProviderWrapper-CBJ_psbw.js → SubscriptionProviderWrapper-B-B08xjD.js} +2 -2
- package/dist/{SubscriptionProviderWrapper-CBJ_psbw.js.map → SubscriptionProviderWrapper-B-B08xjD.js.map} +1 -1
- package/dist/components/pages/login-page.d.ts +3 -1
- package/dist/firebase.js +2 -2
- package/dist/index.js +144 -126
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/SafeSubscriptionContext-CNuEKeqJ.js.map +0 -1
|
@@ -9,8 +9,14 @@ import { getFirebaseService, getNetworkService } from "@sudobility/di/web";
|
|
|
9
9
|
import { InfoBanner } from "@sudobility/di_web";
|
|
10
10
|
import { ThemeProvider, FontSize, Theme } from "@sudobility/components";
|
|
11
11
|
import { useToast, ToastContainer, ToastProvider } from "@sudobility/components/ui/toast";
|
|
12
|
+
import { colors } from "@sudobility/design";
|
|
12
13
|
function DefaultLoadingFallback() {
|
|
13
|
-
return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-theme-bg-primary", children: /* @__PURE__ */ jsx(
|
|
14
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-theme-bg-primary", children: /* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: `animate-spin rounded-full h-8 w-8 border-b-2 border-current ${colors.component.alert.info.icon}`
|
|
18
|
+
}
|
|
19
|
+
) });
|
|
14
20
|
}
|
|
15
21
|
function DefaultPageTracker() {
|
|
16
22
|
const location = useLocation();
|
|
@@ -166,4 +172,4 @@ export {
|
|
|
166
172
|
STUB_SUBSCRIPTION_VALUE as b,
|
|
167
173
|
useSafeSubscription as u
|
|
168
174
|
};
|
|
169
|
-
//# sourceMappingURL=SafeSubscriptionContext-
|
|
175
|
+
//# sourceMappingURL=SafeSubscriptionContext-D4q_l1Kw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SafeSubscriptionContext-D4q_l1Kw.js","sources":["../src/components/app/SudobilityApp.tsx","../src/components/subscription/SafeSubscriptionContext.tsx"],"sourcesContent":["/**\n * SudobilityApp - Base app wrapper for all Sudobility apps\n *\n * Provides common infrastructure with sensible defaults:\n * - HelmetProvider for SEO\n * - I18nextProvider for localization\n * - ThemeProvider for theming (built-in default)\n * - NetworkProvider for online/offline status (built-in default)\n * - QueryClientProvider for TanStack Query (built-in default)\n * - ToastProvider for notifications (built-in default)\n * - BrowserRouter for routing\n * - InfoBanner for system notifications (built-in default)\n *\n * All providers have sensible defaults - only pass props to override.\n */\nimport {\n Suspense,\n ComponentType,\n ReactNode,\n useMemo,\n useRef,\n useEffect,\n} from 'react';\nimport { BrowserRouter } from 'react-router-dom';\nimport {\n QueryClient,\n QueryClientProvider,\n type QueryClient as QueryClientType,\n} from '@tanstack/react-query';\nimport { HelmetProvider } from 'react-helmet-async';\nimport { I18nextProvider } from 'react-i18next';\nimport type { i18n } from 'i18next';\nimport { useLocation } from 'react-router-dom';\nimport { NetworkProvider } from '@sudobility/devops-components';\nimport { getNetworkService, getFirebaseService } from '@sudobility/di/web';\nimport { InfoBanner } from '@sudobility/di_web';\nimport {\n ThemeProvider as SharedThemeProvider,\n Theme,\n FontSize,\n} from '@sudobility/components';\nimport {\n ToastProvider as SharedToastProvider,\n ToastContainer as SharedToastContainer,\n useToast,\n} from '@sudobility/components/ui/toast';\nimport { colors } from '@sudobility/design';\n\n/**\n * QueryClient type that's compatible across different package versions.\n * Uses structural typing to avoid cross-package type conflicts when using bun link.\n */\ntype QueryClientLike = {\n getDefaultOptions: () => unknown;\n getQueryCache: () => unknown;\n getMutationCache: () => unknown;\n};\n\n/**\n * i18n type that's compatible across different package versions.\n * Uses structural typing to avoid cross-package type conflicts when using bun link.\n */\ntype I18nLike = {\n language: string;\n languages: readonly string[];\n\n t: (...args: any[]) => any;\n};\n\nexport interface SudobilityAppProps {\n /** App routes and content */\n children: ReactNode;\n\n /**\n * i18next instance for localization.\n * Each app must pass its own configured i18n instance.\n */\n i18n: I18nLike;\n\n /**\n * TanStack Query client instance (optional).\n * Defaults to a QueryClient with sensible settings.\n */\n queryClient?: QueryClientLike;\n\n /**\n * Custom ThemeProvider component (optional).\n * Defaults to SharedThemeProvider from @sudobility/components.\n */\n ThemeProvider?: ComponentType<{ children: ReactNode }>;\n\n /**\n * Custom ToastProvider component (optional).\n * Defaults to ToastProvider from @sudobility/components.\n */\n ToastProvider?: ComponentType<{ children: ReactNode }>;\n\n /**\n * Toast container component rendered after routes (optional).\n * Defaults to a built-in container that renders toasts from context at bottom-right.\n */\n ToastContainer?: ComponentType;\n\n /**\n * Whether to show the InfoBanner for notifications/errors.\n * Defaults to true. Set to false to disable.\n */\n showInfoBanner?: boolean;\n\n /** Custom loading fallback for Suspense (optional) */\n LoadingFallback?: ComponentType;\n\n /**\n * Custom NetworkProvider component (optional).\n * By default, uses the built-in NetworkProvider with getNetworkService().\n * Set to false to disable network status tracking entirely.\n */\n NetworkProvider?: ComponentType<{ children: ReactNode }> | false;\n\n /**\n * Page tracker component for analytics (optional).\n * By default, uses Firebase Analytics to track page_view events.\n * Pass a custom component to override, or false to disable.\n */\n PageTracker?: ComponentType | false;\n\n /**\n * Additional providers to wrap around the router content.\n * These are rendered inside ToastProvider but outside BrowserRouter.\n * Use this for app-specific providers like ApiProvider, SettingsProvider, etc.\n */\n AppProviders?: ComponentType<{ children: ReactNode }>;\n\n /**\n * Storage key prefix for theme persistence (optional).\n * Defaults to \"sudobility\". Used for localStorage keys (e.g., \"sudobility-theme\").\n * Since localStorage is origin-scoped, apps on different domains don't need\n * different prefixes. Only override if running multiple app instances on the\n * same origin or if you want app-specific debugging visibility.\n */\n storageKeyPrefix?: string;\n\n /**\n * Custom router wrapper component (optional).\n * Defaults to BrowserRouter. Pass a fragment wrapper `({ children }) => <>{children}</>`\n * to skip the router entirely (useful when nesting inside an existing router).\n */\n RouterWrapper?: ComponentType<{ children: ReactNode }>;\n}\n\n/**\n * Default loading fallback component\n */\nfunction DefaultLoadingFallback() {\n return (\n <div className='min-h-screen flex items-center justify-center bg-theme-bg-primary'>\n <div\n className={`animate-spin rounded-full h-8 w-8 border-b-2 border-current ${colors.component.alert.info.icon}`}\n />\n </div>\n );\n}\n\n/**\n * Default page tracker using Firebase Analytics.\n * Tracks page_view events on route changes.\n */\nfunction DefaultPageTracker(): null {\n const location = useLocation();\n const previousPathRef = useRef<string | null>(null);\n\n useEffect(() => {\n const currentPath = location.pathname;\n\n // Skip if same path\n if (previousPathRef.current === currentPath) {\n return;\n }\n\n previousPathRef.current = currentPath;\n\n // Track page view via Firebase Analytics\n try {\n const firebaseService = getFirebaseService();\n if (firebaseService?.analytics?.isSupported()) {\n firebaseService.analytics.logEvent('page_view', {\n page_path: currentPath,\n page_location: window.location.href,\n });\n }\n } catch {\n // Firebase not configured - silently skip tracking\n }\n }, [location.pathname]);\n\n return null;\n}\n\n/**\n * Default network provider that uses getNetworkService()\n */\nfunction DefaultNetworkProvider({ children }: { children: ReactNode }) {\n const networkService = useMemo(() => getNetworkService(), []);\n return (\n <NetworkProvider networkService={networkService}>\n {children}\n </NetworkProvider>\n );\n}\n\n/**\n * Create default QueryClient with sensible settings\n */\nfunction createDefaultQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n // Smart retry: don't retry on 4xx client errors, retry up to 3 times otherwise\n retry: (failureCount, error: unknown) => {\n const statusCode = (error as { statusCode?: number })?.statusCode;\n if (statusCode && statusCode >= 400 && statusCode < 500) {\n return false;\n }\n return failureCount < 3;\n },\n // Exponential backoff: 1s, 2s, 4s... up to 30s\n retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),\n refetchOnWindowFocus: true,\n },\n mutations: {\n retry: false,\n },\n },\n });\n}\n\n// Singleton default QueryClient\nlet defaultQueryClient: QueryClient | null = null;\nfunction getDefaultQueryClient(): QueryClient {\n if (!defaultQueryClient) {\n defaultQueryClient = createDefaultQueryClient();\n }\n return defaultQueryClient;\n}\n\n/**\n * Default theme provider using SharedThemeProvider from @sudobility/components\n */\nfunction createDefaultThemeProvider(storageKeyPrefix: string) {\n return function DefaultThemeProvider({ children }: { children: ReactNode }) {\n return (\n <SharedThemeProvider\n themeStorageKey={`${storageKeyPrefix}-theme`}\n fontSizeStorageKey={`${storageKeyPrefix}-font-size`}\n defaultTheme={Theme.LIGHT}\n defaultFontSize={FontSize.MEDIUM}\n >\n {children}\n </SharedThemeProvider>\n );\n };\n}\n\n/**\n * Default toast provider using SharedToastProvider from @sudobility/components\n */\nfunction DefaultToastProvider({ children }: { children: ReactNode }) {\n return <SharedToastProvider>{children}</SharedToastProvider>;\n}\n\n/**\n * Default toast container that renders toasts from context.\n * Wraps SharedToastContainer with useToast consumer.\n */\nfunction DefaultToastContainer() {\n const { toasts, removeToast } = useToast();\n\n if (toasts.length === 0) return null;\n\n return (\n <SharedToastContainer\n toasts={toasts}\n onDismiss={removeToast}\n position='bottom-right'\n />\n );\n}\n\n/**\n * SudobilityApp - Base app wrapper for all Sudobility apps\n *\n * @example\n * ```tsx\n * // Minimal usage - only i18n is required\n * import { SudobilityApp } from '@sudobility/building_blocks';\n * import i18n from './i18n';\n *\n * function App() {\n * return (\n * <SudobilityApp i18n={i18n}>\n * <Routes>\n * <Route path=\"/\" element={<HomePage />} />\n * </Routes>\n * </SudobilityApp>\n * );\n * }\n *\n * // With custom providers\n * function App() {\n * return (\n * <SudobilityApp\n * i18n={i18n}\n * ThemeProvider={MyCustomThemeProvider}\n * AppProviders={ApiProvider}\n * storageKeyPrefix=\"myapp\"\n * >\n * <Routes>\n * <Route path=\"/\" element={<HomePage />} />\n * </Routes>\n * </SudobilityApp>\n * );\n * }\n * ```\n */\nexport function SudobilityApp({\n children,\n i18n: i18nInstance,\n queryClient,\n ThemeProvider: ThemeProviderProp,\n ToastProvider: ToastProviderProp,\n ToastContainer,\n showInfoBanner = true,\n LoadingFallback = DefaultLoadingFallback,\n NetworkProvider: NetworkProviderProp,\n PageTracker: PageTrackerProp,\n AppProviders,\n storageKeyPrefix = 'sudobility',\n RouterWrapper,\n}: SudobilityAppProps) {\n // Determine which providers to use (custom or default)\n const NetworkProviderComponent =\n NetworkProviderProp === false\n ? null\n : (NetworkProviderProp ?? DefaultNetworkProvider);\n\n const PageTrackerComponent =\n PageTrackerProp === false ? null : (PageTrackerProp ?? DefaultPageTracker);\n\n const ThemeProviderComponent =\n ThemeProviderProp ?? createDefaultThemeProvider(storageKeyPrefix);\n\n const ToastProviderComponent = ToastProviderProp ?? DefaultToastProvider;\n\n const ToastContainerComponent = ToastContainer ?? DefaultToastContainer;\n\n const queryClientInstance = queryClient ?? getDefaultQueryClient();\n\n // Use custom RouterWrapper or default BrowserRouter\n const RouterWrapperComponent = RouterWrapper ?? BrowserRouter;\n\n // Build the router content\n let routerContent: ReactNode = (\n <>\n {PageTrackerComponent && <PageTrackerComponent />}\n <Suspense fallback={<LoadingFallback />}>{children}</Suspense>\n <ToastContainerComponent />\n {showInfoBanner && <InfoBanner />}\n </>\n );\n\n // Wrap with Router\n routerContent = (\n <RouterWrapperComponent>{routerContent}</RouterWrapperComponent>\n );\n\n // Wrap with AppProviders if provided\n if (AppProviders) {\n routerContent = <AppProviders>{routerContent}</AppProviders>;\n }\n\n // Wrap with ToastProvider\n routerContent = (\n <ToastProviderComponent>{routerContent}</ToastProviderComponent>\n );\n\n // Wrap with QueryClientProvider\n routerContent = (\n <QueryClientProvider client={queryClientInstance as QueryClientType}>\n {routerContent}\n </QueryClientProvider>\n );\n\n // Wrap with NetworkProvider (uses default if not explicitly disabled)\n if (NetworkProviderComponent) {\n routerContent = (\n <NetworkProviderComponent>{routerContent}</NetworkProviderComponent>\n );\n }\n\n // Wrap with ThemeProvider\n routerContent = (\n <ThemeProviderComponent>{routerContent}</ThemeProviderComponent>\n );\n\n // Wrap with I18nextProvider\n routerContent = (\n <I18nextProvider i18n={i18nInstance as i18n}>\n {routerContent}\n </I18nextProvider>\n );\n\n // Wrap with HelmetProvider\n return <HelmetProvider>{routerContent}</HelmetProvider>;\n}\n\nexport default SudobilityApp;\n","/**\n * Safe Subscription Context\n *\n * Provides a context that can be safely used even when subscription\n * provider isn't loaded yet. Returns stub values for unauthenticated users.\n */\n\nimport { createContext, useContext } from 'react';\nimport type { SubscriptionContextValue } from '@sudobility/subscription-components';\n\n/**\n * Stub subscription value for unauthenticated users or when\n * subscription provider hasn't loaded yet.\n */\nexport const STUB_SUBSCRIPTION_VALUE: SubscriptionContextValue = {\n products: [],\n currentSubscription: null,\n isLoading: false,\n error: null,\n initialize: () => Promise.resolve(),\n purchase: () => Promise.resolve(false),\n restore: () => Promise.resolve(false),\n refresh: () => Promise.resolve(),\n clearError: () => {},\n};\n\n/**\n * Context that provides subscription state with safe defaults.\n */\nexport const SafeSubscriptionContext = createContext<SubscriptionContextValue>(\n STUB_SUBSCRIPTION_VALUE\n);\n\n/**\n * Hook to safely access subscription context.\n * Returns stub values if provider isn't available.\n */\nexport function useSafeSubscription(): SubscriptionContextValue {\n return useContext(SafeSubscriptionContext);\n}\n"],"names":["SharedThemeProvider","SharedToastProvider","SharedToastContainer","ToastContainer"],"mappings":"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"}
|
package/dist/{SubscriptionProviderWrapper-CBJ_psbw.js → SubscriptionProviderWrapper-B-B08xjD.js}
RENAMED
|
@@ -5,7 +5,7 @@ import { useAuthStatus } from "@sudobility/auth-components";
|
|
|
5
5
|
import { getInfoService } from "@sudobility/di/info";
|
|
6
6
|
import { InfoType } from "@sudobility/types";
|
|
7
7
|
import { setRevenueCatUser, refreshSubscription, clearRevenueCatUser } from "@sudobility/subscription_lib";
|
|
8
|
-
import { a as SafeSubscriptionContext } from "./SafeSubscriptionContext-
|
|
8
|
+
import { a as SafeSubscriptionContext } from "./SafeSubscriptionContext-D4q_l1Kw.js";
|
|
9
9
|
const handleSubscriptionError = (error) => {
|
|
10
10
|
try {
|
|
11
11
|
getInfoService().show(
|
|
@@ -60,4 +60,4 @@ export {
|
|
|
60
60
|
SubscriptionProviderWrapper,
|
|
61
61
|
SubscriptionProviderWrapper as default
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=SubscriptionProviderWrapper-
|
|
63
|
+
//# sourceMappingURL=SubscriptionProviderWrapper-B-B08xjD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubscriptionProviderWrapper-
|
|
1
|
+
{"version":3,"file":"SubscriptionProviderWrapper-B-B08xjD.js","sources":["../src/components/subscription/SubscriptionProviderWrapper.tsx"],"sourcesContent":["/**\n * Subscription Provider Wrapper\n *\n * Integrates subscription-components with auth and sets up RevenueCat user.\n */\n\nimport { type ReactNode, useEffect, useRef } from 'react';\nimport {\n SubscriptionProvider,\n useSubscriptionContext,\n} from '@sudobility/subscription-components';\nimport { useAuthStatus } from '@sudobility/auth-components';\nimport { getInfoService } from '@sudobility/di/info';\nimport { InfoType } from '@sudobility/types';\nimport {\n setRevenueCatUser,\n clearRevenueCatUser,\n refreshSubscription,\n} from '@sudobility/subscription_lib';\nimport { SafeSubscriptionContext } from './SafeSubscriptionContext';\n\ninterface SubscriptionProviderWrapperProps {\n children: ReactNode;\n entityId?: string;\n apiKey: string;\n}\n\nconst handleSubscriptionError = (error: Error) => {\n try {\n getInfoService().show(\n 'Subscription Error',\n error.message,\n InfoType.ERROR,\n 5000\n );\n } catch {\n // InfoService not available - log to console\n console.error('[Subscription]', error.message);\n }\n};\n\n/**\n * Bridge that provides context and configures RevenueCat user.\n */\nfunction SubscriptionBridge({\n children,\n entityId,\n}: {\n children: ReactNode;\n entityId?: string;\n}) {\n const { user } = useAuthStatus();\n const context = useSubscriptionContext();\n const entityIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n const shouldSetUser = user && !user.isAnonymous && entityId;\n\n if (shouldSetUser && entityId !== entityIdRef.current) {\n entityIdRef.current = entityId;\n // Set user for both subscription-components and subscription_lib\n context.initialize(entityId, user.email || undefined);\n setRevenueCatUser(entityId, user.email || undefined).then(() => {\n // Refresh subscription_lib data after user is set\n refreshSubscription();\n });\n } else if (!shouldSetUser && entityIdRef.current) {\n entityIdRef.current = null;\n clearRevenueCatUser();\n }\n }, [user, entityId, context]);\n\n return (\n <SafeSubscriptionContext.Provider value={context}>\n {children}\n </SafeSubscriptionContext.Provider>\n );\n}\n\nexport function SubscriptionProviderWrapper({\n children,\n entityId,\n apiKey,\n}: SubscriptionProviderWrapperProps) {\n const { user } = useAuthStatus();\n\n return (\n <SubscriptionProvider\n apiKey={apiKey}\n userEmail={user?.email || undefined}\n onError={handleSubscriptionError}\n >\n <SubscriptionBridge entityId={entityId}>{children}</SubscriptionBridge>\n </SubscriptionProvider>\n );\n}\n\nexport default SubscriptionProviderWrapper;\n"],"names":[],"mappings":";;;;;;;;AA2BA,MAAM,0BAA0B,CAAC,UAAiB;AAChD,MAAI;AACF,mBAAA,EAAiB;AAAA,MACf;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IAAA;AAAA,EAEJ,QAAQ;AAEN,YAAQ,MAAM,kBAAkB,MAAM,OAAO;AAAA,EAC/C;AACF;AAKA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AACF,GAGG;AACD,QAAM,EAAE,KAAA,IAAS,cAAA;AACjB,QAAM,UAAU,uBAAA;AAChB,QAAM,cAAc,OAAsB,IAAI;AAE9C,YAAU,MAAM;AACd,UAAM,gBAAgB,QAAQ,CAAC,KAAK,eAAe;AAEnD,QAAI,iBAAiB,aAAa,YAAY,SAAS;AACrD,kBAAY,UAAU;AAEtB,cAAQ,WAAW,UAAU,KAAK,SAAS,MAAS;AACpD,wBAAkB,UAAU,KAAK,SAAS,MAAS,EAAE,KAAK,MAAM;AAE9D,4BAAA;AAAA,MACF,CAAC;AAAA,IACH,WAAW,CAAC,iBAAiB,YAAY,SAAS;AAChD,kBAAY,UAAU;AACtB,0BAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,OAAO,CAAC;AAE5B,6BACG,wBAAwB,UAAxB,EAAiC,OAAO,SACtC,UACH;AAEJ;AAEO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAAqC;AACnC,QAAM,EAAE,KAAA,IAAS,cAAA;AAEjB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,YAAW,6BAAM,UAAS;AAAA,MAC1B,SAAS;AAAA,MAET,UAAA,oBAAC,oBAAA,EAAmB,UAAqB,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAGxD;"}
|
|
@@ -52,6 +52,8 @@ export interface LoginPageProps {
|
|
|
52
52
|
showGoogleSignIn?: boolean;
|
|
53
53
|
/** Whether to show sign-up option (default: true) */
|
|
54
54
|
showSignUp?: boolean;
|
|
55
|
+
/** Custom text overrides for localization. Falls back to English defaults for any omitted keys. */
|
|
56
|
+
text?: Partial<LoginPageText>;
|
|
55
57
|
/** Custom className for the container */
|
|
56
58
|
className?: string;
|
|
57
59
|
/**
|
|
@@ -111,4 +113,4 @@ export interface LoginPageText {
|
|
|
111
113
|
* }
|
|
112
114
|
* ```
|
|
113
115
|
*/
|
|
114
|
-
export declare function LoginPage({ appName, logo, onEmailSignIn, onEmailSignUp, onGoogleSignIn, onSuccess, onAuthError, showGoogleSignIn, showSignUp, className, colorVariant, }: LoginPageProps): import("react/jsx-runtime").JSX.Element;
|
|
116
|
+
export declare function LoginPage({ appName, logo, onEmailSignIn, onEmailSignUp, onGoogleSignIn, onSuccess, onAuthError, text: textOverrides, showGoogleSignIn, showSignUp, className, colorVariant, }: LoginPageProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/firebase.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { S as SudobilityApp, a as SafeSubscriptionContext, b as STUB_SUBSCRIPTION_VALUE } from "./SafeSubscriptionContext-
|
|
2
|
+
import { S as SudobilityApp, a as SafeSubscriptionContext, b as STUB_SUBSCRIPTION_VALUE } from "./SafeSubscriptionContext-D4q_l1Kw.js";
|
|
3
3
|
import { useAuthStatus, AuthProvider } from "@sudobility/auth-components";
|
|
4
4
|
import { getFirebaseAuth, FirebaseAuthNetworkService, initializeFirebaseAuth, getFirebaseErrorMessage } from "@sudobility/auth_lib";
|
|
5
5
|
import { createContext, useState, useEffect, useCallback, useRef, useMemo, useContext, Suspense, lazy } from "react";
|
|
@@ -205,7 +205,7 @@ function SudobilityAppWithFirebaseAuth({
|
|
|
205
205
|
);
|
|
206
206
|
}
|
|
207
207
|
const SubscriptionProviderWrapper = lazy(
|
|
208
|
-
() => import("./SubscriptionProviderWrapper-
|
|
208
|
+
() => import("./SubscriptionProviderWrapper-B-B08xjD.js")
|
|
209
209
|
);
|
|
210
210
|
function StubSubscriptionProvider({ children }) {
|
|
211
211
|
return /* @__PURE__ */ jsx(SafeSubscriptionContext.Provider, { value: STUB_SUBSCRIPTION_VALUE, children });
|