@frequencyads/auth 0.1.0

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 (49) hide show
  1. package/dist/chunk-JIENWB3K.mjs +89 -0
  2. package/dist/chunk-NS2JRZGO.mjs +38 -0
  3. package/dist/chunk-OKP757OV.mjs +131 -0
  4. package/dist/chunk-OUUVIDG6.mjs +63 -0
  5. package/dist/chunk-P4OKC4U7.mjs +41 -0
  6. package/dist/chunk-VBLFQXCD.mjs +406 -0
  7. package/dist/chunk-VQCPN62H.mjs +134 -0
  8. package/dist/chunk-XJFMS3SM.mjs +21 -0
  9. package/dist/components/auth-provider.d.mts +24 -0
  10. package/dist/components/auth-provider.d.ts +24 -0
  11. package/dist/components/auth-provider.js +107 -0
  12. package/dist/components/auth-provider.mjs +11 -0
  13. package/dist/components/login.d.mts +24 -0
  14. package/dist/components/login.d.ts +24 -0
  15. package/dist/components/login.js +430 -0
  16. package/dist/components/login.mjs +9 -0
  17. package/dist/components/reset-password.d.mts +11 -0
  18. package/dist/components/reset-password.d.ts +11 -0
  19. package/dist/components/reset-password.js +283 -0
  20. package/dist/components/reset-password.mjs +10 -0
  21. package/dist/components/sign-out-button.d.mts +11 -0
  22. package/dist/components/sign-out-button.d.ts +11 -0
  23. package/dist/components/sign-out-button.js +90 -0
  24. package/dist/components/sign-out-button.mjs +11 -0
  25. package/dist/components/user-menu.d.mts +5 -0
  26. package/dist/components/user-menu.d.ts +5 -0
  27. package/dist/components/user-menu.js +107 -0
  28. package/dist/components/user-menu.mjs +11 -0
  29. package/dist/components/verify-code.d.mts +20 -0
  30. package/dist/components/verify-code.d.ts +20 -0
  31. package/dist/components/verify-code.js +155 -0
  32. package/dist/components/verify-code.mjs +9 -0
  33. package/dist/index.d.mts +44 -0
  34. package/dist/index.d.ts +44 -0
  35. package/dist/index.js +1006 -0
  36. package/dist/index.mjs +159 -0
  37. package/dist/middleware.d.mts +29 -0
  38. package/dist/middleware.d.ts +29 -0
  39. package/dist/middleware.js +114 -0
  40. package/dist/middleware.mjs +83 -0
  41. package/dist/proxy.d.mts +9 -0
  42. package/dist/proxy.d.ts +9 -0
  43. package/dist/proxy.js +71 -0
  44. package/dist/proxy.mjs +41 -0
  45. package/dist/request.d.mts +14 -0
  46. package/dist/request.d.ts +14 -0
  47. package/dist/request.js +46 -0
  48. package/dist/request.mjs +8 -0
  49. package/package.json +101 -0
@@ -0,0 +1,107 @@
1
+ 'use client';
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/components/auth-provider.tsx
23
+ var auth_provider_exports = {};
24
+ __export(auth_provider_exports, {
25
+ AuthProvider: () => AuthProvider,
26
+ useAuth: () => useAuth
27
+ });
28
+ module.exports = __toCommonJS(auth_provider_exports);
29
+ var import_react = require("react");
30
+ var import_client = require("@frequencyads/db/client");
31
+ var import_jsx_runtime = require("react/jsx-runtime");
32
+ var Context = (0, import_react.createContext)(void 0);
33
+ function AuthProvider({ children, loginUrl }) {
34
+ var _a, _b, _c, _d;
35
+ const [supabase] = (0, import_react.useState)(() => (0, import_client.createBrowserClient)());
36
+ const [user, setUser] = (0, import_react.useState)(null);
37
+ const [loading, setLoading] = (0, import_react.useState)(true);
38
+ const userIdRef = (0, import_react.useRef)(null);
39
+ const setUserStable = (0, import_react.useCallback)((newUser) => {
40
+ var _a2;
41
+ const newId = (_a2 = newUser == null ? void 0 : newUser.id) != null ? _a2 : null;
42
+ if (newId !== userIdRef.current) {
43
+ userIdRef.current = newId;
44
+ setUser(newUser);
45
+ }
46
+ }, []);
47
+ (0, import_react.useEffect)(() => {
48
+ if (!supabase) {
49
+ setLoading(false);
50
+ return;
51
+ }
52
+ const {
53
+ data: { subscription }
54
+ } = supabase.auth.onAuthStateChange((_event, session) => {
55
+ var _a2;
56
+ setUserStable((_a2 = session == null ? void 0 : session.user) != null ? _a2 : null);
57
+ setLoading(false);
58
+ });
59
+ async function checkSession() {
60
+ const {
61
+ data: { session }
62
+ } = await supabase.auth.getSession();
63
+ if (!session) {
64
+ await supabase.auth.signOut({ scope: "local" });
65
+ }
66
+ }
67
+ const POLL_MS = 3e4;
68
+ const interval = setInterval(checkSession, POLL_MS);
69
+ const handleVisibilityChange = () => {
70
+ if (document.visibilityState === "visible") {
71
+ checkSession();
72
+ }
73
+ };
74
+ document.addEventListener("visibilitychange", handleVisibilityChange);
75
+ return () => {
76
+ subscription.unsubscribe();
77
+ clearInterval(interval);
78
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
79
+ };
80
+ }, [supabase]);
81
+ (0, import_react.useEffect)(() => {
82
+ if (loading || user) return;
83
+ const url = loginUrl != null ? loginUrl : `${process.env.NEXT_PUBLIC_ACCOUNTS_URL}/login`;
84
+ if (url) {
85
+ window.location.href = `${url}?next=${encodeURIComponent(window.location.href)}`;
86
+ }
87
+ }, [loading, user, loginUrl]);
88
+ const profile = {
89
+ name: (_b = (_a = user == null ? void 0 : user.user_metadata) == null ? void 0 : _a.full_name) != null ? _b : "\u2014",
90
+ email: (_c = user == null ? void 0 : user.email) != null ? _c : "",
91
+ avatarUrl: (_d = user == null ? void 0 : user.user_metadata) == null ? void 0 : _d.avatar_url
92
+ };
93
+ if (loading || !user) return null;
94
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Context.Provider, { value: { supabase, user, profile, loading }, children });
95
+ }
96
+ function useAuth() {
97
+ const context = (0, import_react.useContext)(Context);
98
+ if (context === void 0) {
99
+ throw new Error("useAuth must be used within an AuthProvider");
100
+ }
101
+ return context;
102
+ }
103
+ // Annotate the CommonJS export names for ESM import in node:
104
+ 0 && (module.exports = {
105
+ AuthProvider,
106
+ useAuth
107
+ });
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ "use client";
3
+ import {
4
+ AuthProvider,
5
+ useAuth
6
+ } from "../chunk-JIENWB3K.mjs";
7
+ import "../chunk-NS2JRZGO.mjs";
8
+ export {
9
+ AuthProvider,
10
+ useAuth
11
+ };
@@ -0,0 +1,24 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface LoginPageProps {
5
+ title?: string;
6
+ description?: ReactNode;
7
+ /** Optional content shown in a HoverCard popover next to the title. */
8
+ info?: ReactNode;
9
+ /** Override the OAuth redirectTo URL. Defaults to `window.location.origin + '/auth/callback'`. */
10
+ redirectTo?: string;
11
+ /** Content rendered above the form card (e.g. a logo). */
12
+ header?: ReactNode;
13
+ /** Content rendered below the sign-in button (e.g. privacy policy link). */
14
+ footer?: ReactNode;
15
+ /** Called after successful signup to navigate to verification screen. */
16
+ onVerifyNeeded?: (email: string) => void;
17
+ /** Called when user clicks "Forgot password?" */
18
+ onResetRequest?: () => void;
19
+ /** Called after successful email/password sign-in or sign-up with immediate session. */
20
+ onSuccess?: () => void;
21
+ }
22
+ declare function LoginPage({ title, description, info, redirectTo, header, footer, onVerifyNeeded, onResetRequest, onSuccess, }: LoginPageProps): react_jsx_runtime.JSX.Element;
23
+
24
+ export { LoginPage };
@@ -0,0 +1,24 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface LoginPageProps {
5
+ title?: string;
6
+ description?: ReactNode;
7
+ /** Optional content shown in a HoverCard popover next to the title. */
8
+ info?: ReactNode;
9
+ /** Override the OAuth redirectTo URL. Defaults to `window.location.origin + '/auth/callback'`. */
10
+ redirectTo?: string;
11
+ /** Content rendered above the form card (e.g. a logo). */
12
+ header?: ReactNode;
13
+ /** Content rendered below the sign-in button (e.g. privacy policy link). */
14
+ footer?: ReactNode;
15
+ /** Called after successful signup to navigate to verification screen. */
16
+ onVerifyNeeded?: (email: string) => void;
17
+ /** Called when user clicks "Forgot password?" */
18
+ onResetRequest?: () => void;
19
+ /** Called after successful email/password sign-in or sign-up with immediate session. */
20
+ onSuccess?: () => void;
21
+ }
22
+ declare function LoginPage({ title, description, info, redirectTo, header, footer, onVerifyNeeded, onResetRequest, onSuccess, }: LoginPageProps): react_jsx_runtime.JSX.Element;
23
+
24
+ export { LoginPage };
@@ -0,0 +1,430 @@
1
+ 'use client';
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/components/login/index.tsx
23
+ var login_exports = {};
24
+ __export(login_exports, {
25
+ LoginPage: () => LoginPage
26
+ });
27
+ module.exports = __toCommonJS(login_exports);
28
+ var import_react3 = require("react");
29
+ var import_core3 = require("@mantine/core");
30
+ var import_icons_react = require("@tabler/icons-react");
31
+
32
+ // src/components/login/email-password-form.tsx
33
+ var import_react = require("react");
34
+ var import_core = require("@mantine/core");
35
+ var import_client = require("@frequencyads/db/client");
36
+ var import_jsx_runtime = require("react/jsx-runtime");
37
+ function EmailPasswordForm({
38
+ isPending,
39
+ startTransition,
40
+ onVerifyNeeded,
41
+ onResetRequest,
42
+ onSuccess
43
+ }) {
44
+ const supabase = (0, import_client.createBrowserClient)();
45
+ const [step, setStep] = (0, import_react.useState)("email");
46
+ const [mode, setMode] = (0, import_react.useState)("signin");
47
+ const [email, setEmail] = (0, import_react.useState)("");
48
+ const [password, setPassword] = (0, import_react.useState)("");
49
+ const [confirmPassword, setConfirmPassword] = (0, import_react.useState)("");
50
+ const [firstName, setFirstName] = (0, import_react.useState)("");
51
+ const [lastName, setLastName] = (0, import_react.useState)("");
52
+ const [error, setError] = (0, import_react.useState)(null);
53
+ const goBack = () => {
54
+ setStep("email");
55
+ setPassword("");
56
+ setConfirmPassword("");
57
+ setError(null);
58
+ };
59
+ const toggleMode = () => {
60
+ setMode((m) => m === "signin" ? "signup" : "signin");
61
+ setStep("email");
62
+ setPassword("");
63
+ setConfirmPassword("");
64
+ setFirstName("");
65
+ setLastName("");
66
+ setError(null);
67
+ };
68
+ const validateEmail = () => {
69
+ const trimmed = email.trim();
70
+ if (!trimmed) {
71
+ setError("Email is required.");
72
+ return false;
73
+ }
74
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(trimmed)) {
75
+ setError("Please enter a valid email address.");
76
+ return false;
77
+ }
78
+ return true;
79
+ };
80
+ const handleContinue = (e) => {
81
+ e.preventDefault();
82
+ setError(null);
83
+ if (validateEmail()) {
84
+ setStep("credentials");
85
+ }
86
+ };
87
+ const handleSignIn = (e) => {
88
+ e.preventDefault();
89
+ setError(null);
90
+ if (!validateEmail()) return;
91
+ if (!password.trim()) {
92
+ setError("Password is required.");
93
+ return;
94
+ }
95
+ startTransition(async () => {
96
+ const { error: signInError } = await supabase.auth.signInWithPassword({
97
+ email: email.trim(),
98
+ password: password.trim()
99
+ });
100
+ if (signInError) {
101
+ if (signInError.message === "Email not confirmed") {
102
+ onVerifyNeeded == null ? void 0 : onVerifyNeeded(email);
103
+ } else {
104
+ setError(signInError.message);
105
+ }
106
+ } else {
107
+ onSuccess == null ? void 0 : onSuccess();
108
+ }
109
+ });
110
+ };
111
+ const handleSignUp = (e) => {
112
+ e.preventDefault();
113
+ setError(null);
114
+ if (!firstName.trim()) {
115
+ setError("First name is required.");
116
+ return;
117
+ }
118
+ if (!lastName.trim()) {
119
+ setError("Last name is required.");
120
+ return;
121
+ }
122
+ if (!password.trim()) {
123
+ setError("Password is required.");
124
+ return;
125
+ }
126
+ if (password.trim().length < 8) {
127
+ setError("Password must be at least 8 characters.");
128
+ return;
129
+ }
130
+ const trimmedPassword = password.trim();
131
+ if (trimmedPassword !== confirmPassword.trim()) {
132
+ setError("Passwords do not match.");
133
+ return;
134
+ }
135
+ startTransition(async () => {
136
+ const fullName = `${firstName.trim()} ${lastName.trim()}`;
137
+ const { data: signUpData, error: signUpError } = await supabase.auth.signUp({
138
+ email: email.trim(),
139
+ password: trimmedPassword,
140
+ options: {
141
+ data: {
142
+ name: fullName,
143
+ full_name: fullName,
144
+ first_name: firstName.trim(),
145
+ last_name: lastName.trim()
146
+ }
147
+ }
148
+ });
149
+ if (signUpError) {
150
+ setError(signUpError.message);
151
+ } else if (signUpData.session) {
152
+ onSuccess == null ? void 0 : onSuccess();
153
+ } else {
154
+ onVerifyNeeded == null ? void 0 : onVerifyNeeded(email);
155
+ }
156
+ });
157
+ };
158
+ if (mode === "signin") {
159
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("form", { onSubmit: handleSignIn, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Stack, { children: [
160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
+ import_core.TextInput,
162
+ {
163
+ label: "Email",
164
+ placeholder: "you@frequency.media",
165
+ type: "email",
166
+ value: email,
167
+ onChange: (e) => setEmail(e.currentTarget.value),
168
+ disabled: isPending,
169
+ required: true
170
+ }
171
+ ),
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173
+ import_core.PasswordInput,
174
+ {
175
+ label: "Password",
176
+ placeholder: "Your password",
177
+ value: password,
178
+ onChange: (e) => setPassword(e.currentTarget.value),
179
+ disabled: isPending,
180
+ required: true
181
+ }
182
+ ),
183
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "sm", c: "red", children: error }),
184
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Button, { fullWidth: true, size: "md", type: "submit", loading: isPending, children: "Sign in" }),
185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { justify: "space-between", children: [
186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
187
+ import_core.Anchor,
188
+ {
189
+ component: "button",
190
+ type: "button",
191
+ size: "sm",
192
+ onClick: toggleMode,
193
+ disabled: isPending,
194
+ children: "Don't have an account?"
195
+ }
196
+ ),
197
+ onResetRequest && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
198
+ import_core.Anchor,
199
+ {
200
+ component: "button",
201
+ type: "button",
202
+ size: "sm",
203
+ onClick: onResetRequest,
204
+ disabled: isPending,
205
+ children: "Forgot password?"
206
+ }
207
+ )
208
+ ] })
209
+ ] }) });
210
+ }
211
+ if (step === "email") {
212
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("form", { onSubmit: handleContinue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Stack, { children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
214
+ import_core.TextInput,
215
+ {
216
+ label: "Email",
217
+ placeholder: "you@frequency.media",
218
+ type: "email",
219
+ value: email,
220
+ onChange: (e) => setEmail(e.currentTarget.value),
221
+ required: true
222
+ }
223
+ ),
224
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "sm", c: "red", children: error }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Button, { fullWidth: true, size: "md", type: "submit", children: "Continue" }),
226
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Anchor, { component: "button", type: "button", size: "sm", onClick: toggleMode, children: "Already have an account?" })
227
+ ] }) });
228
+ }
229
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("form", { onSubmit: handleSignUp, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Stack, { children: [
230
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { gap: "xs", align: "baseline", children: [
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "sm", c: "dimmed", children: email }),
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Anchor, { component: "button", type: "button", size: "sm", onClick: goBack, disabled: isPending, children: "Change" })
233
+ ] }),
234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { grow: true, children: [
235
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
236
+ import_core.TextInput,
237
+ {
238
+ label: "First name",
239
+ placeholder: "Jane",
240
+ value: firstName,
241
+ onChange: (e) => setFirstName(e.currentTarget.value),
242
+ disabled: isPending,
243
+ required: true
244
+ }
245
+ ),
246
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
247
+ import_core.TextInput,
248
+ {
249
+ label: "Last name",
250
+ placeholder: "Doe",
251
+ value: lastName,
252
+ onChange: (e) => setLastName(e.currentTarget.value),
253
+ disabled: isPending,
254
+ required: true
255
+ }
256
+ )
257
+ ] }),
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
259
+ import_core.PasswordInput,
260
+ {
261
+ label: "Password",
262
+ placeholder: "At least 8 characters",
263
+ value: password,
264
+ onChange: (e) => setPassword(e.currentTarget.value),
265
+ disabled: isPending,
266
+ required: true
267
+ }
268
+ ),
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
270
+ import_core.PasswordInput,
271
+ {
272
+ label: "Confirm password",
273
+ placeholder: "Repeat your password",
274
+ value: confirmPassword,
275
+ onChange: (e) => setConfirmPassword(e.currentTarget.value),
276
+ disabled: isPending,
277
+ required: true
278
+ }
279
+ ),
280
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "sm", c: "red", children: error }),
281
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Button, { fullWidth: true, size: "md", type: "submit", loading: isPending, children: "Create account" }),
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
283
+ import_core.Anchor,
284
+ {
285
+ component: "button",
286
+ type: "button",
287
+ size: "sm",
288
+ onClick: toggleMode,
289
+ disabled: isPending,
290
+ children: "Already have an account?"
291
+ }
292
+ )
293
+ ] }) });
294
+ }
295
+
296
+ // src/components/login/google-sign-in.tsx
297
+ var import_react2 = require("react");
298
+ var import_core2 = require("@mantine/core");
299
+ var import_client2 = require("@frequencyads/db/client");
300
+ var import_jsx_runtime2 = require("react/jsx-runtime");
301
+ function GoogleIcon() {
302
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", xmlns: "http://www.w3.org/2000/svg", children: [
303
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
304
+ "path",
305
+ {
306
+ d: "M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z",
307
+ fill: "#4285F4"
308
+ }
309
+ ),
310
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
311
+ "path",
312
+ {
313
+ d: "M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z",
314
+ fill: "#34A853"
315
+ }
316
+ ),
317
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
318
+ "path",
319
+ {
320
+ d: "M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.997 8.997 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z",
321
+ fill: "#FBBC05"
322
+ }
323
+ ),
324
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
325
+ "path",
326
+ {
327
+ d: "M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z",
328
+ fill: "#EA4335"
329
+ }
330
+ )
331
+ ] });
332
+ }
333
+ function GoogleSignIn({ redirectTo, isPending }) {
334
+ const supabase = (0, import_client2.createBrowserClient)();
335
+ const [loading, setLoading] = (0, import_react2.useState)(false);
336
+ const handleGoogleLogin = async () => {
337
+ setLoading(true);
338
+ await supabase.auth.signInWithOAuth({
339
+ provider: "google",
340
+ options: {
341
+ redirectTo: redirectTo != null ? redirectTo : `${window.location.origin}/auth/callback`,
342
+ queryParams: { prompt: "select_account" }
343
+ }
344
+ });
345
+ };
346
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
347
+ import_core2.Button,
348
+ {
349
+ type: "button",
350
+ fullWidth: true,
351
+ size: "md",
352
+ variant: "default",
353
+ leftSection: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core2.Loader, { size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(GoogleIcon, {}),
354
+ onClick: handleGoogleLogin,
355
+ disabled: isPending || loading,
356
+ styles: {
357
+ root: {
358
+ fontWeight: 500,
359
+ height: 44,
360
+ backgroundColor: "var(--mantine-color-white)",
361
+ color: "var(--mantine-color-gray-9)",
362
+ borderColor: "var(--mantine-color-gray-3)"
363
+ }
364
+ },
365
+ children: "Sign in with Google"
366
+ }
367
+ );
368
+ }
369
+
370
+ // src/components/login/index.tsx
371
+ var import_jsx_runtime3 = require("react/jsx-runtime");
372
+ function LoginPage({
373
+ title = "Sign in",
374
+ description = "Authenticate once. Operate everywhere.",
375
+ info,
376
+ redirectTo,
377
+ header,
378
+ footer,
379
+ onVerifyNeeded,
380
+ onResetRequest,
381
+ onSuccess
382
+ }) {
383
+ const [isPending, startTransition] = (0, import_react3.useTransition)();
384
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Box, { w: "100%", children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Box, { maw: 460, children: [
386
+ header && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Box, { mb: "lg", ta: "center", children: header }),
387
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Title, { order: 3, fw: 600, c: "gray.7", mb: "xs", children: [
388
+ title,
389
+ info && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.Box, { component: "span", style: { whiteSpace: "nowrap" }, children: [
390
+ "\xA0",
391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_core3.HoverCard, { width: 300, shadow: "md", withArrow: true, position: "bottom-start", openDelay: 100, children: [
392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.HoverCard.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
393
+ import_core3.ActionIcon,
394
+ {
395
+ variant: "subtle",
396
+ color: "gray",
397
+ size: "sm",
398
+ display: "inline-flex",
399
+ style: { verticalAlign: "middle" },
400
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons_react.IconInfoCircle, { size: 16 })
401
+ }
402
+ ) }),
403
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.HoverCard.Dropdown, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Text, { size: "xs", c: "dimmed", lh: 1.6, children: info }) })
404
+ ] })
405
+ ] })
406
+ ] }),
407
+ description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Text, { size: "sm", c: "gray.6", mb: "lg", children: description }),
408
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
409
+ EmailPasswordForm,
410
+ {
411
+ isPending,
412
+ startTransition,
413
+ onVerifyNeeded,
414
+ onResetRequest,
415
+ onSuccess
416
+ }
417
+ ),
418
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Divider, { my: "lg", label: "or continue with", labelPosition: "center", color: "gray.3" }),
419
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GoogleSignIn, { redirectTo, isPending })
420
+ ] }),
421
+ footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Divider, { my: "lg", color: "gray.3" }),
423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Box, { ta: "left", w: "100%", children: footer })
424
+ ] })
425
+ ] });
426
+ }
427
+ // Annotate the CommonJS export names for ESM import in node:
428
+ 0 && (module.exports = {
429
+ LoginPage
430
+ });
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ "use client";
3
+ import {
4
+ LoginPage
5
+ } from "../chunk-VBLFQXCD.mjs";
6
+ import "../chunk-NS2JRZGO.mjs";
7
+ export {
8
+ LoginPage
9
+ };
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface ResetPasswordFormProps {
4
+ onComplete: () => void;
5
+ onBackToLogin?: () => void;
6
+ /** Content rendered above the form (e.g. a logo). */
7
+ header?: React.ReactNode;
8
+ }
9
+ declare function ResetPasswordForm({ onComplete, onBackToLogin, header }: ResetPasswordFormProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { ResetPasswordForm };
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface ResetPasswordFormProps {
4
+ onComplete: () => void;
5
+ onBackToLogin?: () => void;
6
+ /** Content rendered above the form (e.g. a logo). */
7
+ header?: React.ReactNode;
8
+ }
9
+ declare function ResetPasswordForm({ onComplete, onBackToLogin, header }: ResetPasswordFormProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { ResetPasswordForm };