@sudobility/building_blocks 0.0.28 → 0.0.29

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.
@@ -3,4 +3,4 @@ export type { AppSitemapPageProps, SitemapPageText, SitemapSection, SitemapLink,
3
3
  export { AppTextPage } from './app-text-page';
4
4
  export type { AppTextPageProps, TextPageContent, TextSection, TextSectionWithContent, TextSectionWithList, TextSectionWithSubsections, TextPageContact, TextPageContactInfo, GdprNotice, } from './app-text-page';
5
5
  export { LoginPage } from './login-page';
6
- export type { LoginPageProps, LoginPageText } from './login-page';
6
+ export type { LoginPageProps, LoginPageText, AuthErrorInfo, } from './login-page';
@@ -1,5 +1,16 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import { type Auth } from 'firebase/auth';
3
+ /**
4
+ * Auth error info passed to onAuthError callback
5
+ */
6
+ export interface AuthErrorInfo {
7
+ /** Firebase error code (e.g., 'auth/popup-closed-by-user') */
8
+ code: string;
9
+ /** Error message */
10
+ message: string;
11
+ /** Whether this is a user-initiated action (like closing popup) vs actual error */
12
+ isUserAction: boolean;
13
+ }
3
14
  /**
4
15
  * Props for the LoginPage component
5
16
  */
@@ -12,6 +23,8 @@ export interface LoginPageProps {
12
23
  auth: Auth;
13
24
  /** Callback fired on successful authentication */
14
25
  onSuccess: () => void;
26
+ /** Callback fired on auth errors - if provided, errors won't be shown inline */
27
+ onAuthError?: (error: AuthErrorInfo) => void;
15
28
  /** Whether to show Google sign-in option (default: true) */
16
29
  showGoogleSignIn?: boolean;
17
30
  /** Whether to show sign-up option (default: true) */
@@ -38,26 +51,4 @@ export interface LoginPageText {
38
51
  alreadyHaveAccount: string;
39
52
  dontHaveAccount: string;
40
53
  }
41
- /**
42
- * A reusable login page component with email/password and Google sign-in support.
43
- *
44
- * @example
45
- * ```tsx
46
- * import { LoginPage } from '@sudobility/building_blocks';
47
- * import { getFirebaseAuth } from '@sudobility/auth_lib';
48
- *
49
- * function MyLoginPage() {
50
- * const navigate = useNavigate();
51
- * const auth = getFirebaseAuth();
52
- *
53
- * return (
54
- * <LoginPage
55
- * appName="My App"
56
- * auth={auth}
57
- * onSuccess={() => navigate('/')}
58
- * />
59
- * );
60
- * }
61
- * ```
62
- */
63
- export declare function LoginPage({ appName, logo, auth, onSuccess, showGoogleSignIn, showSignUp, className, primaryColorClass, }: LoginPageProps): import("react/jsx-runtime").JSX.Element;
54
+ export declare function LoginPage({ appName, logo, auth, onSuccess, onAuthError, showGoogleSignIn, showSignUp, className, primaryColorClass, }: LoginPageProps): import("react/jsx-runtime").JSX.Element;
package/dist/index.js CHANGED
@@ -5193,11 +5193,17 @@ const defaultText = {
5193
5193
  alreadyHaveAccount: "Already have an account?",
5194
5194
  dontHaveAccount: "Don't have an account?"
5195
5195
  };
5196
+ const USER_ACTION_ERROR_CODES = [
5197
+ "auth/popup-closed-by-user",
5198
+ "auth/cancelled-popup-request",
5199
+ "auth/user-cancelled"
5200
+ ];
5196
5201
  function LoginPage({
5197
5202
  appName,
5198
5203
  logo,
5199
5204
  auth,
5200
5205
  onSuccess,
5206
+ onAuthError,
5201
5207
  showGoogleSignIn = true,
5202
5208
  showSignUp = true,
5203
5209
  className = "",
@@ -5208,6 +5214,17 @@ function LoginPage({
5208
5214
  const [password, setPassword] = useState("");
5209
5215
  const [error, setError] = useState(null);
5210
5216
  const [isLoading, setIsLoading] = useState(false);
5217
+ const handleAuthError = (err) => {
5218
+ const firebaseError = err;
5219
+ const code = firebaseError.code || "unknown";
5220
+ const message = firebaseError.message || "Authentication failed";
5221
+ const isUserAction = USER_ACTION_ERROR_CODES.includes(code);
5222
+ if (onAuthError) {
5223
+ onAuthError({ code, message, isUserAction });
5224
+ } else if (!isUserAction) {
5225
+ setError(message);
5226
+ }
5227
+ };
5211
5228
  const handleSubmit = async (e) => {
5212
5229
  e.preventDefault();
5213
5230
  setError(null);
@@ -5221,7 +5238,7 @@ function LoginPage({
5221
5238
  }
5222
5239
  onSuccess();
5223
5240
  } catch (err) {
5224
- setError(err instanceof Error ? err.message : "Authentication failed");
5241
+ handleAuthError(err);
5225
5242
  } finally {
5226
5243
  setIsLoading(false);
5227
5244
  }
@@ -5235,7 +5252,7 @@ function LoginPage({
5235
5252
  await signInWithPopup(auth, provider);
5236
5253
  onSuccess();
5237
5254
  } catch (err) {
5238
- setError(err instanceof Error ? err.message : "Google sign-in failed");
5255
+ handleAuthError(err);
5239
5256
  } finally {
5240
5257
  setIsLoading(false);
5241
5258
  }