@rebasepro/firebase 0.0.1-canary.2 → 0.0.1-canary.eb08332
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 +97 -3
- package/dist/components/FirebaseLoginView.d.ts +3 -3
- package/dist/components/RebaseFirebaseApp.d.ts +2 -1
- package/dist/components/RebaseFirebaseAppProps.d.ts +9 -13
- package/dist/components/social_icons.d.ts +6 -6
- package/dist/hooks/index.d.ts +3 -1
- package/dist/hooks/useAppCheck.d.ts +2 -2
- package/dist/hooks/useBuildUserManagement.d.ts +78 -0
- package/dist/hooks/useFirebaseAccessGate.d.ts +44 -0
- package/dist/hooks/useFirebaseAuthController.d.ts +2 -2
- package/dist/hooks/useFirebaseRealTimeDBDelegate.d.ts +2 -2
- package/dist/hooks/useFirebaseStorageSource.d.ts +1 -1
- package/dist/hooks/{useFirestoreDataSource.d.ts → useFirestoreDriver.d.ts} +9 -9
- package/dist/index.es.js +2598 -2663
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2704 -2702
- package/dist/index.umd.js.map +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/text_search.d.ts +3 -3
- package/dist/utils/algolia.d.ts +7 -6
- package/dist/utils/collections_firestore.d.ts +4 -4
- package/package.json +75 -65
- package/src/components/FirebaseLoginView.tsx +53 -50
- package/src/components/RebaseFirebaseApp.tsx +82 -56
- package/src/components/RebaseFirebaseAppProps.tsx +10 -24
- package/src/components/social_icons.tsx +8 -8
- package/src/hooks/index.ts +3 -1
- package/src/hooks/useAppCheck.ts +5 -5
- package/src/hooks/useBuildUserManagement.tsx +366 -0
- package/src/hooks/useFirebaseAccessGate.tsx +145 -0
- package/src/hooks/useFirebaseAuthController.ts +6 -8
- package/src/hooks/useFirebaseRealTimeDBDelegate.ts +70 -79
- package/src/hooks/useFirebaseStorageSource.ts +23 -25
- package/src/hooks/useFirestoreDriver.ts +812 -0
- package/src/hooks/useInitialiseFirebase.ts +2 -2
- package/src/types/auth.tsx +2 -2
- package/src/types/text_search.ts +3 -3
- package/src/utils/algolia.ts +6 -9
- package/src/utils/collections_firestore.ts +25 -29
- package/src/utils/database.ts +2 -2
- package/src/utils/local_text_search_controller.ts +12 -12
- package/src/utils/pinecone.ts +3 -3
- package/src/utils/rebase_search_controller.ts +23 -22
- package/src/utils/text_search_controller.ts +2 -2
- package/dist/social_icons.d.ts +0 -6
- package/src/hooks/useFirestoreDataSource.ts +0 -796
- package/src/social_icons.tsx +0 -135
package/dist/types/auth.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApplicationVerifier, ConfirmationResult, User as FirebaseUser } from "@firebase/auth";
|
|
2
|
-
import { AuthController,
|
|
2
|
+
import type { AuthController, User } from "@rebasepro/types";
|
|
3
3
|
/**
|
|
4
4
|
* @group Firebase
|
|
5
5
|
*/
|
|
@@ -37,5 +37,5 @@ export type FirebaseAuthController<USER extends User = FirebaseUserWrapper, Extr
|
|
|
37
37
|
*/
|
|
38
38
|
skipLogin: () => void;
|
|
39
39
|
setUser: (user: USER | null) => void;
|
|
40
|
-
setUserRoles: (roles:
|
|
40
|
+
setUserRoles: (roles: string[]) => void;
|
|
41
41
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { User as FirebaseUser } from "@firebase/auth";
|
|
2
2
|
import { FirebaseApp } from "@firebase/app";
|
|
3
|
-
import {
|
|
3
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
4
4
|
export type FirestoreTextSearchControllerBuilder = (props: {
|
|
5
5
|
firebaseApp: FirebaseApp;
|
|
6
6
|
}) => FirestoreTextSearchController;
|
|
@@ -23,7 +23,7 @@ export type FirestoreTextSearchController = {
|
|
|
23
23
|
init: (props: {
|
|
24
24
|
path: string;
|
|
25
25
|
databaseId?: string;
|
|
26
|
-
collection?:
|
|
26
|
+
collection?: CollectionConfig;
|
|
27
27
|
}) => Promise<boolean>;
|
|
28
28
|
/**
|
|
29
29
|
* Do the search and return a list of ids.
|
|
@@ -34,6 +34,6 @@ export type FirestoreTextSearchController = {
|
|
|
34
34
|
path: string;
|
|
35
35
|
currentUser?: FirebaseUser;
|
|
36
36
|
databaseId?: string;
|
|
37
|
-
collection?:
|
|
37
|
+
collection?: CollectionConfig;
|
|
38
38
|
}) => (Promise<readonly string[] | undefined>);
|
|
39
39
|
};
|
package/dist/utils/algolia.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { buildExternalSearchController } from "./text_search_controller";
|
|
2
1
|
/**
|
|
3
2
|
* Utility function to perform a text search in an algolia index,
|
|
4
3
|
* returning the ids of the entities.
|
|
@@ -7,8 +6,10 @@ import { buildExternalSearchController } from "./text_search_controller";
|
|
|
7
6
|
* @param query
|
|
8
7
|
* @group Firebase
|
|
9
8
|
*/
|
|
10
|
-
export declare function performAlgoliaTextSearch(client:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
export declare function performAlgoliaTextSearch(client: {
|
|
10
|
+
searchSingleIndex: (params: Record<string, unknown>) => Promise<{
|
|
11
|
+
hits: Array<{
|
|
12
|
+
objectID: string;
|
|
13
|
+
}>;
|
|
14
|
+
}>;
|
|
15
|
+
}, indexName: string, query: string): Promise<readonly string[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DocumentSnapshot } from "@firebase/firestore";
|
|
2
|
-
import {
|
|
3
|
-
export declare function buildCollectionId(idOrPath: string,
|
|
4
|
-
export declare const docsToCollectionTree: (docs: DocumentSnapshot[]) =>
|
|
5
|
-
export declare const docToCollection: (doc: DocumentSnapshot) =>
|
|
2
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
3
|
+
export declare function buildCollectionId(idOrPath: string, parentCollectionSlugs?: string[], parentEntityIds?: string[]): string;
|
|
4
|
+
export declare const docsToCollectionTree: (docs: DocumentSnapshot[]) => CollectionConfig[];
|
|
5
|
+
export declare const docToCollection: (doc: DocumentSnapshot) => CollectionConfig;
|
package/package.json
CHANGED
|
@@ -1,67 +1,77 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@rebasepro/firebase",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1-canary.eb08332",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.umd.js",
|
|
9
|
+
"module": "./dist/index.es.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"source": "src/index.ts",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"fast-equals": "6.0.0",
|
|
14
|
+
"fuse.js": "^7.4.2",
|
|
15
|
+
"react-router-dom": "^7.17.0",
|
|
16
|
+
"@rebasepro/admin": "0.0.1-canary.eb08332",
|
|
17
|
+
"@rebasepro/app": "0.0.1-canary.eb08332",
|
|
18
|
+
"@rebasepro/ui": "0.0.1-canary.eb08332",
|
|
19
|
+
"@rebasepro/types": "0.0.1-canary.eb08332",
|
|
20
|
+
"@rebasepro/common": "0.0.1-canary.eb08332",
|
|
21
|
+
"@rebasepro/utils": "0.0.1-canary.eb08332"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"firebase": "^10.12.2 || ^11.0.0 || ^12.0.0",
|
|
25
|
+
"react": ">=19.0.0",
|
|
26
|
+
"react-dom": ">=19.0.0",
|
|
27
|
+
"typesense": "^1.8.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"typesense": {
|
|
31
|
+
"optional": true
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"development": "./dist/index.es.js",
|
|
38
|
+
"import": "./dist/index.es.js",
|
|
39
|
+
"require": "./dist/index.umd.js"
|
|
7
40
|
},
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"./package.json": "./package.json"
|
|
46
|
-
},
|
|
47
|
-
"devDependencies": {
|
|
48
|
-
"@types/node": "^20.19.17",
|
|
49
|
-
"@types/react": "^19.0.8",
|
|
50
|
-
"@types/react-dom": "^19.0.3",
|
|
51
|
-
"babel-plugin-react-compiler": "^19.0.0-beta-af1b7da-20250417",
|
|
52
|
-
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
|
53
|
-
"typescript": "^5.9.3",
|
|
54
|
-
"typesense": "^2.1.0",
|
|
55
|
-
"vite": "^7.2.4"
|
|
56
|
-
},
|
|
57
|
-
"scripts": {
|
|
58
|
-
"dev": "vite",
|
|
59
|
-
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
60
|
-
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
|
|
61
|
-
},
|
|
62
|
-
"files": [
|
|
63
|
-
"dist",
|
|
64
|
-
"src"
|
|
65
|
-
],
|
|
66
|
-
"gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6"
|
|
67
|
-
}
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@firebase/app": "^0.15.0",
|
|
45
|
+
"@firebase/app-check": "^0.12.0",
|
|
46
|
+
"@firebase/auth": "^1.13.3",
|
|
47
|
+
"@firebase/database": "^1.1.3",
|
|
48
|
+
"@firebase/firestore": "^4.16.0",
|
|
49
|
+
"@firebase/functions": "^0.13.5",
|
|
50
|
+
"@firebase/storage": "^0.14.3",
|
|
51
|
+
"@types/jest": "^30.0.0",
|
|
52
|
+
"@types/node": "^25.9.3",
|
|
53
|
+
"@types/react": "^19.2.17",
|
|
54
|
+
"@types/react-dom": "^19.2.3",
|
|
55
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
56
|
+
"babel-plugin-react-compiler": "19.0.0-beta-ebf51a3-20250411",
|
|
57
|
+
"firebase": "^12.15.0",
|
|
58
|
+
"typescript": "^6.0.3",
|
|
59
|
+
"typesense": "^3.0.6",
|
|
60
|
+
"vite": "^8.0.16"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"dist",
|
|
64
|
+
"src"
|
|
65
|
+
],
|
|
66
|
+
"gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "https://github.com/rebasepro/rebase.git",
|
|
70
|
+
"directory": "packages/firebase"
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"dev": "vite",
|
|
74
|
+
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
75
|
+
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
+
|
|
1
2
|
import React, { ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
|
2
3
|
|
|
3
4
|
import { FirebaseApp, FirebaseError } from "@firebase/app";
|
|
4
|
-
import { ErrorView, RebaseLogo, useModeController, useSnackbarController
|
|
5
|
+
import { ErrorView, RebaseLogo, useModeController, useSnackbarController } from "@rebasepro/app";
|
|
5
6
|
import {
|
|
6
|
-
|
|
7
|
+
ArrowLeftIcon,
|
|
7
8
|
Button,
|
|
8
|
-
CallIcon,
|
|
9
9
|
CircularProgress,
|
|
10
10
|
cls,
|
|
11
11
|
IconButton,
|
|
12
|
+
iconSize,
|
|
12
13
|
LoadingButton,
|
|
13
14
|
MailIcon,
|
|
14
|
-
|
|
15
|
+
PhoneIcon,
|
|
15
16
|
TextField,
|
|
16
17
|
Typography,
|
|
18
|
+
UserIcon
|
|
17
19
|
} from "@rebasepro/ui";
|
|
18
20
|
import { appleIcon, facebookIcon, githubIcon, googleIcon, microsoftIcon, twitterIcon } from "./social_icons";
|
|
19
21
|
import {
|
|
20
22
|
getAuth,
|
|
21
23
|
getMultiFactorResolver,
|
|
24
|
+
MultiFactorError,
|
|
22
25
|
PhoneAuthProvider,
|
|
23
26
|
PhoneMultiFactorGenerator,
|
|
24
27
|
RecaptchaVerifier
|
|
@@ -96,7 +99,7 @@ export interface FirebaseLoginViewProps {
|
|
|
96
99
|
*/
|
|
97
100
|
additionalComponent?: ReactNode;
|
|
98
101
|
|
|
99
|
-
notAllowedError?:
|
|
102
|
+
notAllowedError?: string | Error;
|
|
100
103
|
|
|
101
104
|
className?: string;
|
|
102
105
|
|
|
@@ -151,7 +154,7 @@ export function FirebaseLoginView({
|
|
|
151
154
|
const auth = getAuth(firebaseApp);
|
|
152
155
|
const recaptchaVerifier = new RecaptchaVerifier(auth, "recaptcha", { size: "invisible" });
|
|
153
156
|
|
|
154
|
-
const resolver = getMultiFactorResolver(auth, authController.authProviderError as
|
|
157
|
+
const resolver = getMultiFactorResolver(auth, authController.authProviderError as MultiFactorError);
|
|
155
158
|
|
|
156
159
|
if (resolver.hints[0].factorId === PhoneMultiFactorGenerator.FACTOR_ID) {
|
|
157
160
|
|
|
@@ -181,11 +184,11 @@ export function FirebaseLoginView({
|
|
|
181
184
|
}, [authController.authProviderError]);
|
|
182
185
|
|
|
183
186
|
function buildErrorView() {
|
|
184
|
-
let errorView:
|
|
187
|
+
let errorView: React.ReactNode;
|
|
185
188
|
if (authController.user != null) return errorView; // if the user is logged in via MFA
|
|
186
189
|
const ignoredCodes = ["auth/popup-closed-by-user", "auth/cancelled-popup-request"];
|
|
187
190
|
if (authController.authProviderError) {
|
|
188
|
-
const authError = authController.authProviderError as
|
|
191
|
+
const authError = authController.authProviderError as FirebaseError;
|
|
189
192
|
if (authError.code === "auth/operation-not-allowed" ||
|
|
190
193
|
authError.code === "auth/configuration-not-found") {
|
|
191
194
|
errorView =
|
|
@@ -193,7 +196,7 @@ export function FirebaseLoginView({
|
|
|
193
196
|
<div className="p-4">
|
|
194
197
|
<ErrorView
|
|
195
198
|
title={"Firebase Auth not enabled"}
|
|
196
|
-
error={"You need to enable Firebase Auth and the corresponding login provider in your Firebase project"}
|
|
199
|
+
error={"You need to enable Firebase Auth and the corresponding login provider in your Firebase project"}/>
|
|
197
200
|
</div>
|
|
198
201
|
{firebaseApp &&
|
|
199
202
|
<div className="p-4">
|
|
@@ -211,19 +214,19 @@ export function FirebaseLoginView({
|
|
|
211
214
|
errorView = <div className="p-4">
|
|
212
215
|
<ErrorView
|
|
213
216
|
title={"Invalid API key"}
|
|
214
|
-
error={"auth/invalid-api-key: Check that your Firebase config is set correctly in your `firebase_config.ts` file"}
|
|
217
|
+
error={"auth/invalid-api-key: Check that your Firebase config is set correctly in your `firebase_config.ts` file"}/>
|
|
215
218
|
</div>;
|
|
216
219
|
} else if (authError.code === "auth/email-already-in-use") {
|
|
217
220
|
errorView = <div className="p-4">
|
|
218
221
|
<ErrorView
|
|
219
222
|
title={"Email already in use"}
|
|
220
|
-
error={"The selected email is already in use by another account"}
|
|
223
|
+
error={"The selected email is already in use by another account"}/>
|
|
221
224
|
</div>;
|
|
222
225
|
} else if (authError.code === "auth/invalid-credential") {
|
|
223
226
|
errorView = <div className="p-4">
|
|
224
227
|
<ErrorView
|
|
225
228
|
title={"Invalid credential"}
|
|
226
|
-
error={"The provided credential is not correct"}
|
|
229
|
+
error={"The provided credential is not correct"}/>
|
|
227
230
|
</div>;
|
|
228
231
|
} else if (!ignoredCodes.includes(authError.code)) {
|
|
229
232
|
if (authError.code === "auth/multi-factor-auth-required") {
|
|
@@ -231,7 +234,7 @@ export function FirebaseLoginView({
|
|
|
231
234
|
}
|
|
232
235
|
errorView =
|
|
233
236
|
<div className="p-4">
|
|
234
|
-
<ErrorView error={authController.authProviderError as Error}
|
|
237
|
+
<ErrorView error={authController.authProviderError as Error}/>
|
|
235
238
|
</div>;
|
|
236
239
|
}
|
|
237
240
|
}
|
|
@@ -246,9 +249,9 @@ export function FirebaseLoginView({
|
|
|
246
249
|
width: "100%",
|
|
247
250
|
objectFit: "contain"
|
|
248
251
|
}}
|
|
249
|
-
alt={"Logo"}
|
|
252
|
+
alt={"Logo"}/>;
|
|
250
253
|
} else {
|
|
251
|
-
logoComponent = <RebaseLogo
|
|
254
|
+
logoComponent = <RebaseLogo/>;
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
let notAllowedMessage: string | undefined;
|
|
@@ -258,7 +261,7 @@ export function FirebaseLoginView({
|
|
|
258
261
|
} else if (notAllowedError instanceof Error) {
|
|
259
262
|
notAllowedMessage = notAllowedError.message;
|
|
260
263
|
} else {
|
|
261
|
-
notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified
|
|
264
|
+
notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified access gate configuration";
|
|
262
265
|
}
|
|
263
266
|
}
|
|
264
267
|
|
|
@@ -284,36 +287,36 @@ export function FirebaseLoginView({
|
|
|
284
287
|
|
|
285
288
|
{notAllowedMessage &&
|
|
286
289
|
<div className="p-8">
|
|
287
|
-
<ErrorView error={notAllowedMessage}
|
|
290
|
+
<ErrorView error={notAllowedMessage}/>
|
|
288
291
|
</div>}
|
|
289
292
|
|
|
290
293
|
{buildErrorView()}
|
|
291
294
|
|
|
292
295
|
{(!passwordLoginSelected && !phoneLoginSelected) && <div className={"my-4 w-full"}>
|
|
293
296
|
|
|
294
|
-
{buildOauthLoginButtons(authController, resolvedSignInOptions, modeState.mode, disabled)}
|
|
297
|
+
{buildOauthLoginButtons(authController, resolvedSignInOptions, modeState.mode as "light" | "dark", disabled)}
|
|
295
298
|
|
|
296
299
|
{resolvedSignInOptions.includes("password") &&
|
|
297
300
|
<LoginButton
|
|
298
301
|
disabled={disabled}
|
|
299
302
|
text={"Email/password"}
|
|
300
|
-
icon={<MailIcon size={
|
|
301
|
-
onClick={() => setPasswordLoginSelected(true)}
|
|
303
|
+
icon={<MailIcon size={iconSize.medium}/>}
|
|
304
|
+
onClick={() => setPasswordLoginSelected(true)}/>}
|
|
302
305
|
|
|
303
306
|
{resolvedSignInOptions.includes("phone") &&
|
|
304
307
|
<LoginButton
|
|
305
308
|
disabled={disabled}
|
|
306
|
-
text={"
|
|
307
|
-
icon={<
|
|
308
|
-
onClick={() => setPhoneLoginSelected(true)}
|
|
309
|
+
text={"PhoneIcon number"}
|
|
310
|
+
icon={<PhoneIcon size={iconSize.medium}/>}
|
|
311
|
+
onClick={() => setPhoneLoginSelected(true)}/>}
|
|
309
312
|
|
|
310
313
|
{resolvedSignInOptions.includes("anonymous") &&
|
|
311
314
|
<LoginButton
|
|
312
315
|
disabled={disabled}
|
|
313
316
|
text={"Log in anonymously"}
|
|
314
|
-
icon={<
|
|
315
|
-
size={
|
|
316
|
-
onClick={authController.anonymousLogin}
|
|
317
|
+
icon={<UserIcon
|
|
318
|
+
size={"medium"}/>}
|
|
319
|
+
onClick={authController.anonymousLogin}/>}
|
|
317
320
|
|
|
318
321
|
{allowSkipLogin &&
|
|
319
322
|
<Button
|
|
@@ -330,7 +333,7 @@ export function FirebaseLoginView({
|
|
|
330
333
|
{passwordLoginSelected && <LoginForm
|
|
331
334
|
authController={authController}
|
|
332
335
|
onClose={() => setPasswordLoginSelected(false)}
|
|
333
|
-
mode={modeState.mode}
|
|
336
|
+
mode={modeState.mode as "light" | "dark"}
|
|
334
337
|
noUserComponent={noUserComponent}
|
|
335
338
|
disableSignupScreen={disableSignupScreen}
|
|
336
339
|
disableResetPassword={disableResetPassword}
|
|
@@ -362,7 +365,7 @@ export function LoginButton({
|
|
|
362
365
|
return (
|
|
363
366
|
<div className="my-1 w-full">
|
|
364
367
|
<Button
|
|
365
|
-
className={cls("w-full bg-white dark:bg-surface-
|
|
368
|
+
className={cls("w-full bg-white dark:bg-surface-950 text-surface-900 dark:text-surface-100", disabled ? "" : "hover:text-surface-950 hover:dark:text-white")}
|
|
366
369
|
style={{
|
|
367
370
|
height: "40px",
|
|
368
371
|
borderRadius: "4px",
|
|
@@ -397,7 +400,7 @@ function PhoneLoginForm({
|
|
|
397
400
|
const [code, setCode] = useState<string>();
|
|
398
401
|
const [isInvalidCode, setIsInvalidCode] = useState(false);
|
|
399
402
|
|
|
400
|
-
const handleSubmit = async (event:
|
|
403
|
+
const handleSubmit = async (event: React.FormEvent) => {
|
|
401
404
|
event.preventDefault();
|
|
402
405
|
|
|
403
406
|
if (code && authController.confirmationResult) {
|
|
@@ -419,15 +422,15 @@ function PhoneLoginForm({
|
|
|
419
422
|
<form onSubmit={handleSubmit}>
|
|
420
423
|
{isInvalidCode &&
|
|
421
424
|
<div className="p-8">
|
|
422
|
-
<ErrorView error={"Invalid confirmation code"}
|
|
425
|
+
<ErrorView error={"Invalid confirmation code"}/>
|
|
423
426
|
</div>}
|
|
424
427
|
|
|
425
|
-
<div id={RECAPTCHA_CONTAINER_ID}
|
|
428
|
+
<div id={RECAPTCHA_CONTAINER_ID}/>
|
|
426
429
|
|
|
427
430
|
<div className={"flex flex-col gap-1"}>
|
|
428
431
|
<IconButton
|
|
429
432
|
onClick={onClose}>
|
|
430
|
-
<
|
|
433
|
+
<ArrowLeftIcon className="w-5 h-5"/>
|
|
431
434
|
</IconButton>
|
|
432
435
|
<div className="p-1 flex">
|
|
433
436
|
<Typography align={"center"}
|
|
@@ -437,7 +440,7 @@ function PhoneLoginForm({
|
|
|
437
440
|
value={phone ?? ""}
|
|
438
441
|
disabled={Boolean(phone && (authController.authLoading || authController.confirmationResult))}
|
|
439
442
|
type="phone"
|
|
440
|
-
onChange={(event) => setPhone(event.target.value)}
|
|
443
|
+
onChange={(event) => setPhone(event.target.value)}/>
|
|
441
444
|
{Boolean(phone && authController.confirmationResult) &&
|
|
442
445
|
<>
|
|
443
446
|
<div className="mt-2 p-1 flex">
|
|
@@ -447,14 +450,14 @@ function PhoneLoginForm({
|
|
|
447
450
|
<TextField placeholder=""
|
|
448
451
|
value={code ?? ""}
|
|
449
452
|
type="text"
|
|
450
|
-
onChange={(event) => setCode(event.target.value)}
|
|
453
|
+
onChange={(event) => setCode(event.target.value)}/>
|
|
451
454
|
</>
|
|
452
455
|
}
|
|
453
456
|
|
|
454
457
|
<div className="flex justify-end items-center w-full">
|
|
455
458
|
|
|
456
459
|
{authController.authLoading &&
|
|
457
|
-
<CircularProgress className="p-1" size={"small"}
|
|
460
|
+
<CircularProgress className="p-1" size={"small"}/>
|
|
458
461
|
}
|
|
459
462
|
|
|
460
463
|
<Button type="submit">
|
|
@@ -503,8 +506,8 @@ function LoginForm({
|
|
|
503
506
|
|
|
504
507
|
useEffect(() => {
|
|
505
508
|
if (!document) return;
|
|
506
|
-
const escFunction = (event:
|
|
507
|
-
if (event.
|
|
509
|
+
const escFunction = (event: KeyboardEvent) => {
|
|
510
|
+
if (event.key === "Escape") {
|
|
508
511
|
onClose();
|
|
509
512
|
}
|
|
510
513
|
};
|
|
@@ -545,7 +548,7 @@ function LoginForm({
|
|
|
545
548
|
}
|
|
546
549
|
}
|
|
547
550
|
|
|
548
|
-
const handleSubmit = (event:
|
|
551
|
+
const handleSubmit = (event: React.FormEvent) => {
|
|
549
552
|
event.preventDefault();
|
|
550
553
|
if (loginState === "email") {
|
|
551
554
|
handleEnterEmail();
|
|
@@ -568,7 +571,7 @@ function LoginForm({
|
|
|
568
571
|
<div className={"max-w-[480px] w-full flex flex-col gap-4"}>
|
|
569
572
|
<IconButton
|
|
570
573
|
onClick={onBackPressed}>
|
|
571
|
-
<
|
|
574
|
+
<ArrowLeftIcon className="w-5 h-5"/>
|
|
572
575
|
</IconButton>
|
|
573
576
|
|
|
574
577
|
<div>
|
|
@@ -583,7 +586,7 @@ function LoginForm({
|
|
|
583
586
|
value={email ?? ""}
|
|
584
587
|
disabled={authController.authLoading}
|
|
585
588
|
type="email"
|
|
586
|
-
onChange={(event) => setEmail(event.target.value)}
|
|
589
|
+
onChange={(event) => setEmail(event.target.value)}/>}
|
|
587
590
|
|
|
588
591
|
<div
|
|
589
592
|
className={`${loginState === "password" || (loginState === "registration" && !disableSignupScreen) ? "block" : "hidden"}`}>
|
|
@@ -592,14 +595,14 @@ function LoginForm({
|
|
|
592
595
|
disabled={authController.authLoading}
|
|
593
596
|
inputRef={passwordRef}
|
|
594
597
|
type="password"
|
|
595
|
-
onChange={(event) => setPassword(event.target.value)}
|
|
598
|
+
onChange={(event) => setPassword(event.target.value)}/>
|
|
596
599
|
</div>
|
|
597
600
|
|
|
598
601
|
<div
|
|
599
602
|
className={`${loginState === "registration" && disableSignupScreen ? "hidden" : "flex"} justify-end items-center w-full flex gap-2`}>
|
|
600
603
|
|
|
601
604
|
{authController.authLoading &&
|
|
602
|
-
<CircularProgress className="p-1" size={"small"}
|
|
605
|
+
<CircularProgress className="p-1" size={"small"}/>
|
|
603
606
|
}
|
|
604
607
|
|
|
605
608
|
{!disableResetPassword && <LoadingButton variant="text"
|
|
@@ -614,9 +617,9 @@ function LoginForm({
|
|
|
614
617
|
message: "Password reset email sent",
|
|
615
618
|
type: "success"
|
|
616
619
|
});
|
|
617
|
-
} catch (e:
|
|
620
|
+
} catch (e: unknown) {
|
|
618
621
|
snackbarController.open({
|
|
619
|
-
message: e.message,
|
|
622
|
+
message: e instanceof Error ? e.message : String(e),
|
|
620
623
|
type: "error"
|
|
621
624
|
});
|
|
622
625
|
}
|
|
@@ -667,36 +670,36 @@ function buildOauthLoginButtons(authController: FirebaseAuthController, provider
|
|
|
667
670
|
disabled={disabled}
|
|
668
671
|
text={"Sign in with Google"}
|
|
669
672
|
icon={googleIcon(mode)}
|
|
670
|
-
onClick={authController.googleLogin}
|
|
673
|
+
onClick={authController.googleLogin}/>}
|
|
671
674
|
|
|
672
675
|
{providers.includes("microsoft.com") && <LoginButton
|
|
673
676
|
disabled={disabled}
|
|
674
677
|
text={"Sign in with Microsoft"}
|
|
675
678
|
icon={microsoftIcon(mode)}
|
|
676
|
-
onClick={authController.microsoftLogin}
|
|
679
|
+
onClick={authController.microsoftLogin}/>}
|
|
677
680
|
|
|
678
681
|
{providers.includes("apple.com") && <LoginButton
|
|
679
682
|
disabled={disabled}
|
|
680
683
|
text={"Sign in with Apple"}
|
|
681
684
|
icon={appleIcon(mode)}
|
|
682
|
-
onClick={authController.appleLogin}
|
|
685
|
+
onClick={authController.appleLogin}/>}
|
|
683
686
|
|
|
684
687
|
{providers.includes("github.com") && <LoginButton
|
|
685
688
|
disabled={disabled}
|
|
686
689
|
text={"Sign in with Github"}
|
|
687
690
|
icon={githubIcon(mode)}
|
|
688
|
-
onClick={authController.githubLogin}
|
|
691
|
+
onClick={authController.githubLogin}/>}
|
|
689
692
|
|
|
690
693
|
{providers.includes("facebook.com") && <LoginButton
|
|
691
694
|
disabled={disabled}
|
|
692
695
|
text={"Sign in with Facebook"}
|
|
693
696
|
icon={facebookIcon(mode)}
|
|
694
|
-
onClick={authController.facebookLogin}
|
|
697
|
+
onClick={authController.facebookLogin}/>}
|
|
695
698
|
|
|
696
699
|
{providers.includes("twitter.com") && <LoginButton
|
|
697
700
|
disabled={disabled}
|
|
698
701
|
text={"Sign in with Twitter"}
|
|
699
702
|
icon={twitterIcon(mode)}
|
|
700
|
-
onClick={authController.twitterLogin}
|
|
703
|
+
onClick={authController.twitterLogin}/>}
|
|
701
704
|
</>
|
|
702
705
|
}
|