@kendevelops/auth-flow-kit 2.3.8 → 2.3.9
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/index.cjs +121 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -215,132 +215,131 @@ function PasswordResetScreen() {
|
|
|
215
215
|
setError(err?.message || "Failed to request reset");
|
|
216
216
|
}
|
|
217
217
|
};
|
|
218
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.
|
|
219
|
-
"
|
|
218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
219
|
+
"div",
|
|
220
220
|
{
|
|
221
|
-
onSubmit: requestReset,
|
|
222
221
|
style: {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
background: "rgba(255, 255, 255, 0.25)",
|
|
230
|
-
backdropFilter: "blur(14px)",
|
|
231
|
-
WebkitBackdropFilter: "blur(14px)",
|
|
232
|
-
boxShadow: "0 20px 40px rgba(0,0,0,0.15)",
|
|
233
|
-
border: "1px solid rgba(255,255,255,0.4)",
|
|
234
|
-
animation: "fadeIn 0.25s ease"
|
|
222
|
+
minHeight: "100vh",
|
|
223
|
+
display: "flex",
|
|
224
|
+
alignItems: "center",
|
|
225
|
+
justifyContent: "center",
|
|
226
|
+
background: "linear-gradient(135deg, #0f172a, #1e293b)",
|
|
227
|
+
fontFamily: "Inter, sans-serif"
|
|
235
228
|
},
|
|
236
|
-
children:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
padding: "0 6px",
|
|
261
|
-
fontSize: 13,
|
|
262
|
-
color: "#444",
|
|
263
|
-
borderRadius: 6
|
|
264
|
-
},
|
|
265
|
-
children: "Email"
|
|
266
|
-
}
|
|
267
|
-
),
|
|
268
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
269
|
-
"input",
|
|
270
|
-
{
|
|
271
|
-
value: email,
|
|
272
|
-
onChange: (e) => setEmail(e.target.value),
|
|
273
|
-
type: "email",
|
|
274
|
-
placeholder: "you@example.com",
|
|
275
|
-
style: {
|
|
276
|
-
width: "90%",
|
|
277
|
-
padding: "14px 16px",
|
|
278
|
-
borderRadius: 12,
|
|
279
|
-
border: "1px solid #d2d2d2",
|
|
280
|
-
fontSize: 15,
|
|
281
|
-
outline: "none",
|
|
282
|
-
transition: "0.25s",
|
|
283
|
-
background: "rgba(255,255,255,0.85)"
|
|
284
|
-
},
|
|
285
|
-
onFocus: (e) => {
|
|
286
|
-
e.currentTarget.style.border = "1px solid #4b4bff";
|
|
287
|
-
e.currentTarget.style.boxShadow = "0 0 0 3px rgba(75,75,255,0.25)";
|
|
288
|
-
},
|
|
289
|
-
onBlur: (e) => {
|
|
290
|
-
e.currentTarget.style.border = "1px solid #d2d2d2";
|
|
291
|
-
e.currentTarget.style.boxShadow = "0 0 0 transparent";
|
|
229
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
230
|
+
"form",
|
|
231
|
+
{
|
|
232
|
+
onSubmit: requestReset,
|
|
233
|
+
style: {
|
|
234
|
+
width: 420,
|
|
235
|
+
padding: 36,
|
|
236
|
+
borderRadius: 16,
|
|
237
|
+
background: "#0b1220",
|
|
238
|
+
border: "1px solid rgba(255,255,255,0.06)",
|
|
239
|
+
boxShadow: "0 25px 60px rgba(0,0,0,0.6)"
|
|
240
|
+
},
|
|
241
|
+
children: [
|
|
242
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
243
|
+
"h2",
|
|
244
|
+
{
|
|
245
|
+
style: {
|
|
246
|
+
marginBottom: 28,
|
|
247
|
+
color: "#f1f5f9",
|
|
248
|
+
fontWeight: 600,
|
|
249
|
+
fontSize: 26,
|
|
250
|
+
textAlign: "center"
|
|
251
|
+
},
|
|
252
|
+
children: "Password Reset"
|
|
292
253
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
254
|
+
),
|
|
255
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: 22 }, children: [
|
|
256
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
257
|
+
"label",
|
|
258
|
+
{
|
|
259
|
+
style: {
|
|
260
|
+
display: "block",
|
|
261
|
+
marginBottom: 8,
|
|
262
|
+
fontSize: 13,
|
|
263
|
+
color: "#94a3b8"
|
|
264
|
+
},
|
|
265
|
+
children: "Email Address"
|
|
266
|
+
}
|
|
267
|
+
),
|
|
268
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
269
|
+
"input",
|
|
270
|
+
{
|
|
271
|
+
value: email,
|
|
272
|
+
onChange: (e) => setEmail(e.target.value),
|
|
273
|
+
type: "email",
|
|
274
|
+
placeholder: "you@example.com",
|
|
275
|
+
style: {
|
|
276
|
+
width: "100%",
|
|
277
|
+
padding: "14px",
|
|
278
|
+
borderRadius: 10,
|
|
279
|
+
border: "1px solid #1f2a44",
|
|
280
|
+
background: "#020617",
|
|
281
|
+
color: "#e2e8f0",
|
|
282
|
+
fontSize: 14,
|
|
283
|
+
outline: "none",
|
|
284
|
+
transition: "0.2s"
|
|
285
|
+
},
|
|
286
|
+
onFocus: (e) => {
|
|
287
|
+
e.currentTarget.style.border = "1px solid #6366f1";
|
|
288
|
+
e.currentTarget.style.boxShadow = "0 0 0 2px rgba(99,102,241,0.25)";
|
|
289
|
+
},
|
|
290
|
+
onBlur: (e) => {
|
|
291
|
+
e.currentTarget.style.border = "1px solid #1f2a44";
|
|
292
|
+
e.currentTarget.style.boxShadow = "none";
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
] }),
|
|
297
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
298
|
+
"button",
|
|
299
|
+
{
|
|
300
|
+
type: "submit",
|
|
301
|
+
style: {
|
|
302
|
+
width: "100%",
|
|
303
|
+
padding: "14px",
|
|
304
|
+
borderRadius: 10,
|
|
305
|
+
border: "none",
|
|
306
|
+
fontSize: 15,
|
|
307
|
+
fontWeight: 600,
|
|
308
|
+
cursor: "pointer",
|
|
309
|
+
background: sent ? "linear-gradient(90deg, #22c55e, #4ade80)" : "linear-gradient(90deg, #6366f1, #4f46e5)",
|
|
310
|
+
color: "white",
|
|
311
|
+
transition: "0.25s"
|
|
312
|
+
},
|
|
313
|
+
children: sent ? "Email Sent \u2714" : "Send Reset Link"
|
|
314
|
+
}
|
|
315
|
+
),
|
|
316
|
+
sent && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
317
|
+
"p",
|
|
318
|
+
{
|
|
319
|
+
style: {
|
|
320
|
+
marginTop: 18,
|
|
321
|
+
fontSize: 14,
|
|
322
|
+
color: "#4ade80",
|
|
323
|
+
textAlign: "center"
|
|
324
|
+
},
|
|
325
|
+
children: "Check your inbox for reset instructions."
|
|
326
|
+
}
|
|
327
|
+
),
|
|
328
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
329
|
+
"p",
|
|
330
|
+
{
|
|
331
|
+
style: {
|
|
332
|
+
marginTop: 18,
|
|
333
|
+
fontSize: 13,
|
|
334
|
+
color: "#f87171",
|
|
335
|
+
textAlign: "center"
|
|
336
|
+
},
|
|
337
|
+
children: error
|
|
338
|
+
}
|
|
339
|
+
)
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
)
|
|
344
343
|
}
|
|
345
344
|
);
|
|
346
345
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/http.ts","../src/Protected.tsx","../src/screens/LoginScreen.tsx","../src/screens/PasswordResetScreen.tsx","../src/screens/SignupScreen.tsx"],"sourcesContent":["export { AuthProvider, useAuth } from \"./AuthContext\";\r\nexport { default as Protected } from \"./Protected\";\r\n\r\n// Screens\r\nexport { default as LoginScreen } from \"./screens/LoginScreen\";\r\nexport { default as SignupScreen } from \"./screens/SignupScreen\";\r\nexport { default as PasswordResetScreen } from \"./screens/PasswordResetScreen\";\r\n\r\n// Types\r\nexport * from \"./types\";\r\n","/* \r\nDevelopers using this library should wrap their app with:\r\n <AuthProvider config={...}>\r\n <App />\r\n </AuthProvider>\r\n \r\n Then they can access auth anywhere with:\r\n const { user, login, logout, getToken } = useAuth();\r\n*/\r\n\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n} from \"react\";\r\n\r\nimport {\r\n AuthContextType,\r\n AuthProviderConfig,\r\n StandardAuthResponse,\r\n User,\r\n} from \"./types\";\r\n\r\nimport {\r\n httpJSON,\r\n makeURL,\r\n setStoredAccessToken,\r\n getStoredAccessToken,\r\n} from \"./http\";\r\n\r\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\r\n\r\nexport function useAuth(): AuthContextType {\r\n const ctx = useContext(AuthContext);\r\n if (!ctx) throw new Error(\"useAuth must be used inside AuthProvider\");\r\n return ctx;\r\n}\r\n\r\nexport function AuthProvider({\r\n config,\r\n children,\r\n}: React.PropsWithChildren<{ config: AuthProviderConfig }>) {\r\n const { baseURL, endpoints, onLoginSuccess, onLogout } = config;\r\n\r\n const [user, setUser] = useState<User | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const getToken = () => getStoredAccessToken();\r\n\r\n // Restore user from localStorage on app load\r\n useEffect(() => {\r\n const savedUser = localStorage.getItem(\"afk_user\");\r\n if (savedUser) {\r\n setUser(JSON.parse(savedUser));\r\n }\r\n setLoading(false);\r\n }, []);\r\n\r\n // LOGIN\r\n const login: AuthContextType[\"login\"] = async (email, password) => {\r\n const url = makeURL(baseURL, endpoints.login);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email, password }),\r\n });\r\n\r\n // store token + user\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // SIGNUP\r\n const signup: AuthContextType[\"signup\"] = async (payload) => {\r\n const url = makeURL(baseURL, endpoints.signup);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // LOGOUT\r\n const logout = () => {\r\n setStoredAccessToken(null);\r\n localStorage.removeItem(\"afk_user\");\r\n setUser(null);\r\n\r\n if (onLogout) onLogout();\r\n };\r\n\r\n const value = useMemo<AuthContextType>(\r\n () => ({\r\n user,\r\n loading,\r\n login,\r\n signup,\r\n logout,\r\n getToken,\r\n config,\r\n }),\r\n [user, loading, config],\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n","/*\r\n Internal HTTP helpers for auth-flow-kit.\r\n\r\n Responsibilities:\r\n • Construct safe URLs (makeURL)\r\n • Persist access token (get/set)\r\n • Perform JSON requests with optional auth (httpJSON)\r\n\r\n ⚠️ Library users should NOT import this directly.\r\n Used internally by AuthProvider + auth UI.\r\n\r\n Design goals:\r\n - predictable\r\n - minimal\r\n - RTK-style familiarity\r\n*/\r\n\r\nexport function makeURL(baseURL: string, path: string) {\r\n const cleanedBase = baseURL.replace(/\\/$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${cleanedBase}${normalizedPath}`;\r\n}\r\n\r\nexport function getStoredAccessToken(): string | null {\r\n try {\r\n const token = localStorage.getItem(\"afk_access_token\");\r\n return token;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function setStoredAccessToken(token: string | null) {\r\n try {\r\n if (!token) {\r\n localStorage.removeItem(\"afk_access_token\");\r\n return;\r\n }\r\n\r\n localStorage.setItem(\"afk_access_token\", token);\r\n } catch {\r\n // Swallow storage issues (e.g. private mode)\r\n }\r\n}\r\n\r\nexport async function httpJSON<T>(\r\n url: string,\r\n opts: RequestInit = {},\r\n withAuth = false,\r\n): Promise<T> {\r\n const baseHeaders: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n };\r\n\r\n if (withAuth) {\r\n const token = getStoredAccessToken();\r\n if (token) {\r\n baseHeaders[\"Authorization\"] = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n ...opts,\r\n headers: {\r\n ...baseHeaders,\r\n ...(opts.headers ?? {}),\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n let errorMessage = `Request failed (${response.status})`;\r\n\r\n // JSON error handling\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n const payload = await response.json();\r\n if (payload?.message) {\r\n errorMessage = payload.message;\r\n }\r\n } catch {\r\n // ignore malformed JSON\r\n }\r\n }\r\n\r\n // HTML fallback (common in Express)\r\n if (contentType.includes(\"text/html\")) {\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n errorMessage =\r\n \"The forgot password endpoint you added in config.endpoints.forgot does not exist in your server. Please check and update your config.endpoints.forgot\";\r\n } else {\r\n errorMessage = \"Unexpected server error\";\r\n }\r\n }\r\n\r\n // Dev hint for common misconfig\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n console.error(\r\n `[auth-flow-kit] Password reset endpoint not found.\r\n\r\nExpected POST route:\r\n ${url}\r\n\r\nFix by:\r\n • Adding the endpoint on your backend\r\n • OR updating config.endpoints.forgot`,\r\n );\r\n }\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n}\r\n","\"use client\";\r\n\r\n/*\r\nProtected component\r\n\r\nWraps authenticated content and prevents rendering when unauthenticated.\r\n\r\nIMPORTANT:\r\nThis component does NOT hard-redirect by default.\r\nNavigation should be handled by the host application (router or state).\r\n\r\nIf redirectTo is provided AND the host app supports routing,\r\na redirect will occur.\r\n*/\r\n\r\nimport React, { useEffect } from \"react\";\r\nimport { useAuth } from \"./AuthContext\";\r\n\r\ntype ProtectedProps = {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n};\r\n\r\nexport default function Protected({ children, redirectTo }: ProtectedProps) {\r\n const { user, loading } = useAuth();\r\n\r\n useEffect(() => {\r\n if (!loading && !user && redirectTo) {\r\n window.location.href = redirectTo;\r\n }\r\n }, [loading, user, redirectTo]);\r\n\r\n if (loading) return <div>Loading...</div>;\r\n if (!user) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport PasswordResetScreen from \"./PasswordResetScreen\";\r\n\r\nexport default function LoginScreen() {\r\n const { login } = useAuth();\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [showReset, setShowReset] = useState(false);\r\n\r\n if (showReset) {\r\n return (\r\n <div style={{ animation: \"fade .2s\" }}>\r\n <PasswordResetScreen />\r\n <p\r\n onClick={() => setShowReset(false)}\r\n style={{\r\n marginTop: 16,\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n textDecoration: \"underline\",\r\n }}\r\n >\r\n Back to login\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n // Submit\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await login(trimmedEmail, trimmedPassword);\r\n } catch (err: any) {\r\n setError(err?.message || \"Login failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Welcome Back 👋\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 10 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <p\r\n onClick={() => setShowReset(true)}\r\n style={{\r\n textAlign: \"right\",\r\n fontSize: 13,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n marginBottom: 24,\r\n }}\r\n >\r\n Forgot password?\r\n </p>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Signing in...\" : \"Sign in\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport { httpJSON, makeURL } from \"../http\";\r\n\r\nexport default function PasswordResetScreen() {\r\n const { config } = useAuth();\r\n\r\n const [email, setEmail] = useState(\"\");\r\n const [sent, setSent] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const requestReset = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n\r\n try {\r\n const url = makeURL(config.baseURL, config.endpoints.forgot);\r\n\r\n await httpJSON(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email }),\r\n });\r\n\r\n setSent(true);\r\n } catch (err: any) {\r\n setError(err?.message || \"Failed to request reset\");\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={requestReset}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.25s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Reset Password 🔑\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: sent ? \"-18px\" : \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"90%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: sent\r\n ? \"linear-gradient(90deg, #7aff9d, #34c759)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.3s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {sent ? \"Link Sent ✔\" : \"Send reset link\"}\r\n </button>\r\n\r\n {sent && (\r\n <p\r\n style={{\r\n marginTop: 20,\r\n color: \"#2ecc71\",\r\n textAlign: \"center\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n }}\r\n >\r\n Check your email for reset instructions.\r\n </p>\r\n )}\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 20,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\n\r\nexport default function SignupScreen() {\r\n const { signup } = useAuth();\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n const trimmedName = name.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword || !trimmedName) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await signup({ name, email, password });\r\n } catch (err: any) {\r\n setError(err?.message || \"Signup failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Create Account ✨\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Name\r\n </label>\r\n\r\n <input\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder=\"Your name\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Creating...\" : \"Create account\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/http.ts","../src/Protected.tsx","../src/screens/LoginScreen.tsx","../src/screens/PasswordResetScreen.tsx","../src/screens/SignupScreen.tsx"],"sourcesContent":["export { AuthProvider, useAuth } from \"./AuthContext\";\r\nexport { default as Protected } from \"./Protected\";\r\n\r\n// Screens\r\nexport { default as LoginScreen } from \"./screens/LoginScreen\";\r\nexport { default as SignupScreen } from \"./screens/SignupScreen\";\r\nexport { default as PasswordResetScreen } from \"./screens/PasswordResetScreen\";\r\n\r\n// Types\r\nexport * from \"./types\";\r\n","/* \r\nDevelopers using this library should wrap their app with:\r\n <AuthProvider config={...}>\r\n <App />\r\n </AuthProvider>\r\n \r\n Then they can access auth anywhere with:\r\n const { user, login, logout, getToken } = useAuth();\r\n*/\r\n\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n} from \"react\";\r\n\r\nimport {\r\n AuthContextType,\r\n AuthProviderConfig,\r\n StandardAuthResponse,\r\n User,\r\n} from \"./types\";\r\n\r\nimport {\r\n httpJSON,\r\n makeURL,\r\n setStoredAccessToken,\r\n getStoredAccessToken,\r\n} from \"./http\";\r\n\r\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\r\n\r\nexport function useAuth(): AuthContextType {\r\n const ctx = useContext(AuthContext);\r\n if (!ctx) throw new Error(\"useAuth must be used inside AuthProvider\");\r\n return ctx;\r\n}\r\n\r\nexport function AuthProvider({\r\n config,\r\n children,\r\n}: React.PropsWithChildren<{ config: AuthProviderConfig }>) {\r\n const { baseURL, endpoints, onLoginSuccess, onLogout } = config;\r\n\r\n const [user, setUser] = useState<User | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const getToken = () => getStoredAccessToken();\r\n\r\n // Restore user from localStorage on app load\r\n useEffect(() => {\r\n const savedUser = localStorage.getItem(\"afk_user\");\r\n if (savedUser) {\r\n setUser(JSON.parse(savedUser));\r\n }\r\n setLoading(false);\r\n }, []);\r\n\r\n // LOGIN\r\n const login: AuthContextType[\"login\"] = async (email, password) => {\r\n const url = makeURL(baseURL, endpoints.login);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email, password }),\r\n });\r\n\r\n // store token + user\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // SIGNUP\r\n const signup: AuthContextType[\"signup\"] = async (payload) => {\r\n const url = makeURL(baseURL, endpoints.signup);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // LOGOUT\r\n const logout = () => {\r\n setStoredAccessToken(null);\r\n localStorage.removeItem(\"afk_user\");\r\n setUser(null);\r\n\r\n if (onLogout) onLogout();\r\n };\r\n\r\n const value = useMemo<AuthContextType>(\r\n () => ({\r\n user,\r\n loading,\r\n login,\r\n signup,\r\n logout,\r\n getToken,\r\n config,\r\n }),\r\n [user, loading, config],\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n","/*\r\n Internal HTTP helpers for auth-flow-kit.\r\n\r\n Responsibilities:\r\n • Construct safe URLs (makeURL)\r\n • Persist access token (get/set)\r\n • Perform JSON requests with optional auth (httpJSON)\r\n\r\n ⚠️ Library users should NOT import this directly.\r\n Used internally by AuthProvider + auth UI.\r\n\r\n Design goals:\r\n - predictable\r\n - minimal\r\n - RTK-style familiarity\r\n*/\r\n\r\nexport function makeURL(baseURL: string, path: string) {\r\n const cleanedBase = baseURL.replace(/\\/$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${cleanedBase}${normalizedPath}`;\r\n}\r\n\r\nexport function getStoredAccessToken(): string | null {\r\n try {\r\n const token = localStorage.getItem(\"afk_access_token\");\r\n return token;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function setStoredAccessToken(token: string | null) {\r\n try {\r\n if (!token) {\r\n localStorage.removeItem(\"afk_access_token\");\r\n return;\r\n }\r\n\r\n localStorage.setItem(\"afk_access_token\", token);\r\n } catch {\r\n // Swallow storage issues (e.g. private mode)\r\n }\r\n}\r\n\r\nexport async function httpJSON<T>(\r\n url: string,\r\n opts: RequestInit = {},\r\n withAuth = false,\r\n): Promise<T> {\r\n const baseHeaders: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n };\r\n\r\n if (withAuth) {\r\n const token = getStoredAccessToken();\r\n if (token) {\r\n baseHeaders[\"Authorization\"] = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n ...opts,\r\n headers: {\r\n ...baseHeaders,\r\n ...(opts.headers ?? {}),\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n let errorMessage = `Request failed (${response.status})`;\r\n\r\n // JSON error handling\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n const payload = await response.json();\r\n if (payload?.message) {\r\n errorMessage = payload.message;\r\n }\r\n } catch {\r\n // ignore malformed JSON\r\n }\r\n }\r\n\r\n // HTML fallback (common in Express)\r\n if (contentType.includes(\"text/html\")) {\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n errorMessage =\r\n \"The forgot password endpoint you added in config.endpoints.forgot does not exist in your server. Please check and update your config.endpoints.forgot\";\r\n } else {\r\n errorMessage = \"Unexpected server error\";\r\n }\r\n }\r\n\r\n // Dev hint for common misconfig\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n console.error(\r\n `[auth-flow-kit] Password reset endpoint not found.\r\n\r\nExpected POST route:\r\n ${url}\r\n\r\nFix by:\r\n • Adding the endpoint on your backend\r\n • OR updating config.endpoints.forgot`,\r\n );\r\n }\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n}\r\n","\"use client\";\r\n\r\n/*\r\nProtected component\r\n\r\nWraps authenticated content and prevents rendering when unauthenticated.\r\n\r\nIMPORTANT:\r\nThis component does NOT hard-redirect by default.\r\nNavigation should be handled by the host application (router or state).\r\n\r\nIf redirectTo is provided AND the host app supports routing,\r\na redirect will occur.\r\n*/\r\n\r\nimport React, { useEffect } from \"react\";\r\nimport { useAuth } from \"./AuthContext\";\r\n\r\ntype ProtectedProps = {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n};\r\n\r\nexport default function Protected({ children, redirectTo }: ProtectedProps) {\r\n const { user, loading } = useAuth();\r\n\r\n useEffect(() => {\r\n if (!loading && !user && redirectTo) {\r\n window.location.href = redirectTo;\r\n }\r\n }, [loading, user, redirectTo]);\r\n\r\n if (loading) return <div>Loading...</div>;\r\n if (!user) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport PasswordResetScreen from \"./PasswordResetScreen\";\r\n\r\nexport default function LoginScreen() {\r\n const { login } = useAuth();\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [showReset, setShowReset] = useState(false);\r\n\r\n if (showReset) {\r\n return (\r\n <div style={{ animation: \"fade .2s\" }}>\r\n <PasswordResetScreen />\r\n <p\r\n onClick={() => setShowReset(false)}\r\n style={{\r\n marginTop: 16,\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n textDecoration: \"underline\",\r\n }}\r\n >\r\n Back to login\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n // Submit\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await login(trimmedEmail, trimmedPassword);\r\n } catch (err: any) {\r\n setError(err?.message || \"Login failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Welcome Back 👋\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 10 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <p\r\n onClick={() => setShowReset(true)}\r\n style={{\r\n textAlign: \"right\",\r\n fontSize: 13,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n marginBottom: 24,\r\n }}\r\n >\r\n Forgot password?\r\n </p>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Signing in...\" : \"Sign in\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport { httpJSON, makeURL } from \"../http\";\r\n\r\nexport default function PasswordResetScreen() {\r\n const { config } = useAuth();\r\n\r\n const [email, setEmail] = useState(\"\");\r\n const [sent, setSent] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const requestReset = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n\r\n try {\r\n const url = makeURL(config.baseURL, config.endpoints.forgot);\r\n\r\n await httpJSON(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email }),\r\n });\r\n\r\n setSent(true);\r\n } catch (err: any) {\r\n setError(err?.message || \"Failed to request reset\");\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n minHeight: \"100vh\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n background: \"linear-gradient(135deg, #0f172a, #1e293b)\",\r\n fontFamily: \"Inter, sans-serif\",\r\n }}\r\n >\r\n <form\r\n onSubmit={requestReset}\r\n style={{\r\n width: 420,\r\n padding: 36,\r\n borderRadius: 16,\r\n background: \"#0b1220\",\r\n border: \"1px solid rgba(255,255,255,0.06)\",\r\n boxShadow: \"0 25px 60px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 28,\r\n color: \"#f1f5f9\",\r\n fontWeight: 600,\r\n fontSize: 26,\r\n textAlign: \"center\",\r\n }}\r\n >\r\n Password Reset\r\n </h2>\r\n\r\n <div style={{ marginBottom: 22 }}>\r\n <label\r\n style={{\r\n display: \"block\",\r\n marginBottom: 8,\r\n fontSize: 13,\r\n color: \"#94a3b8\",\r\n }}\r\n >\r\n Email Address\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px\",\r\n borderRadius: 10,\r\n border: \"1px solid #1f2a44\",\r\n background: \"#020617\",\r\n color: \"#e2e8f0\",\r\n fontSize: 14,\r\n outline: \"none\",\r\n transition: \"0.2s\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #6366f1\";\r\n e.currentTarget.style.boxShadow =\r\n \"0 0 0 2px rgba(99,102,241,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #1f2a44\";\r\n e.currentTarget.style.boxShadow = \"none\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px\",\r\n borderRadius: 10,\r\n border: \"none\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n cursor: \"pointer\",\r\n background: sent\r\n ? \"linear-gradient(90deg, #22c55e, #4ade80)\"\r\n : \"linear-gradient(90deg, #6366f1, #4f46e5)\",\r\n color: \"white\",\r\n transition: \"0.25s\",\r\n }}\r\n >\r\n {sent ? \"Email Sent ✔\" : \"Send Reset Link\"}\r\n </button>\r\n\r\n {sent && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n fontSize: 14,\r\n color: \"#4ade80\",\r\n textAlign: \"center\",\r\n }}\r\n >\r\n Check your inbox for reset instructions.\r\n </p>\r\n )}\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n fontSize: 13,\r\n color: \"#f87171\",\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\n\r\nexport default function SignupScreen() {\r\n const { signup } = useAuth();\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n const trimmedName = name.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword || !trimmedName) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await signup({ name, email, password });\r\n } catch (err: any) {\r\n setError(err?.message || \"Signup failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Create Account ✨\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Name\r\n </label>\r\n\r\n <input\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder=\"Your name\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Creating...\" : \"Create account\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
package/dist/index.js
CHANGED
|
@@ -190,132 +190,131 @@ function PasswordResetScreen() {
|
|
|
190
190
|
setError(err?.message || "Failed to request reset");
|
|
191
191
|
}
|
|
192
192
|
};
|
|
193
|
-
return /* @__PURE__ */
|
|
194
|
-
"
|
|
193
|
+
return /* @__PURE__ */ jsx3(
|
|
194
|
+
"div",
|
|
195
195
|
{
|
|
196
|
-
onSubmit: requestReset,
|
|
197
196
|
style: {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
background: "rgba(255, 255, 255, 0.25)",
|
|
205
|
-
backdropFilter: "blur(14px)",
|
|
206
|
-
WebkitBackdropFilter: "blur(14px)",
|
|
207
|
-
boxShadow: "0 20px 40px rgba(0,0,0,0.15)",
|
|
208
|
-
border: "1px solid rgba(255,255,255,0.4)",
|
|
209
|
-
animation: "fadeIn 0.25s ease"
|
|
197
|
+
minHeight: "100vh",
|
|
198
|
+
display: "flex",
|
|
199
|
+
alignItems: "center",
|
|
200
|
+
justifyContent: "center",
|
|
201
|
+
background: "linear-gradient(135deg, #0f172a, #1e293b)",
|
|
202
|
+
fontFamily: "Inter, sans-serif"
|
|
210
203
|
},
|
|
211
|
-
children:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
padding: "0 6px",
|
|
236
|
-
fontSize: 13,
|
|
237
|
-
color: "#444",
|
|
238
|
-
borderRadius: 6
|
|
239
|
-
},
|
|
240
|
-
children: "Email"
|
|
241
|
-
}
|
|
242
|
-
),
|
|
243
|
-
/* @__PURE__ */ jsx3(
|
|
244
|
-
"input",
|
|
245
|
-
{
|
|
246
|
-
value: email,
|
|
247
|
-
onChange: (e) => setEmail(e.target.value),
|
|
248
|
-
type: "email",
|
|
249
|
-
placeholder: "you@example.com",
|
|
250
|
-
style: {
|
|
251
|
-
width: "90%",
|
|
252
|
-
padding: "14px 16px",
|
|
253
|
-
borderRadius: 12,
|
|
254
|
-
border: "1px solid #d2d2d2",
|
|
255
|
-
fontSize: 15,
|
|
256
|
-
outline: "none",
|
|
257
|
-
transition: "0.25s",
|
|
258
|
-
background: "rgba(255,255,255,0.85)"
|
|
259
|
-
},
|
|
260
|
-
onFocus: (e) => {
|
|
261
|
-
e.currentTarget.style.border = "1px solid #4b4bff";
|
|
262
|
-
e.currentTarget.style.boxShadow = "0 0 0 3px rgba(75,75,255,0.25)";
|
|
263
|
-
},
|
|
264
|
-
onBlur: (e) => {
|
|
265
|
-
e.currentTarget.style.border = "1px solid #d2d2d2";
|
|
266
|
-
e.currentTarget.style.boxShadow = "0 0 0 transparent";
|
|
204
|
+
children: /* @__PURE__ */ jsxs(
|
|
205
|
+
"form",
|
|
206
|
+
{
|
|
207
|
+
onSubmit: requestReset,
|
|
208
|
+
style: {
|
|
209
|
+
width: 420,
|
|
210
|
+
padding: 36,
|
|
211
|
+
borderRadius: 16,
|
|
212
|
+
background: "#0b1220",
|
|
213
|
+
border: "1px solid rgba(255,255,255,0.06)",
|
|
214
|
+
boxShadow: "0 25px 60px rgba(0,0,0,0.6)"
|
|
215
|
+
},
|
|
216
|
+
children: [
|
|
217
|
+
/* @__PURE__ */ jsx3(
|
|
218
|
+
"h2",
|
|
219
|
+
{
|
|
220
|
+
style: {
|
|
221
|
+
marginBottom: 28,
|
|
222
|
+
color: "#f1f5f9",
|
|
223
|
+
fontWeight: 600,
|
|
224
|
+
fontSize: 26,
|
|
225
|
+
textAlign: "center"
|
|
226
|
+
},
|
|
227
|
+
children: "Password Reset"
|
|
267
228
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
229
|
+
),
|
|
230
|
+
/* @__PURE__ */ jsxs("div", { style: { marginBottom: 22 }, children: [
|
|
231
|
+
/* @__PURE__ */ jsx3(
|
|
232
|
+
"label",
|
|
233
|
+
{
|
|
234
|
+
style: {
|
|
235
|
+
display: "block",
|
|
236
|
+
marginBottom: 8,
|
|
237
|
+
fontSize: 13,
|
|
238
|
+
color: "#94a3b8"
|
|
239
|
+
},
|
|
240
|
+
children: "Email Address"
|
|
241
|
+
}
|
|
242
|
+
),
|
|
243
|
+
/* @__PURE__ */ jsx3(
|
|
244
|
+
"input",
|
|
245
|
+
{
|
|
246
|
+
value: email,
|
|
247
|
+
onChange: (e) => setEmail(e.target.value),
|
|
248
|
+
type: "email",
|
|
249
|
+
placeholder: "you@example.com",
|
|
250
|
+
style: {
|
|
251
|
+
width: "100%",
|
|
252
|
+
padding: "14px",
|
|
253
|
+
borderRadius: 10,
|
|
254
|
+
border: "1px solid #1f2a44",
|
|
255
|
+
background: "#020617",
|
|
256
|
+
color: "#e2e8f0",
|
|
257
|
+
fontSize: 14,
|
|
258
|
+
outline: "none",
|
|
259
|
+
transition: "0.2s"
|
|
260
|
+
},
|
|
261
|
+
onFocus: (e) => {
|
|
262
|
+
e.currentTarget.style.border = "1px solid #6366f1";
|
|
263
|
+
e.currentTarget.style.boxShadow = "0 0 0 2px rgba(99,102,241,0.25)";
|
|
264
|
+
},
|
|
265
|
+
onBlur: (e) => {
|
|
266
|
+
e.currentTarget.style.border = "1px solid #1f2a44";
|
|
267
|
+
e.currentTarget.style.boxShadow = "none";
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
] }),
|
|
272
|
+
/* @__PURE__ */ jsx3(
|
|
273
|
+
"button",
|
|
274
|
+
{
|
|
275
|
+
type: "submit",
|
|
276
|
+
style: {
|
|
277
|
+
width: "100%",
|
|
278
|
+
padding: "14px",
|
|
279
|
+
borderRadius: 10,
|
|
280
|
+
border: "none",
|
|
281
|
+
fontSize: 15,
|
|
282
|
+
fontWeight: 600,
|
|
283
|
+
cursor: "pointer",
|
|
284
|
+
background: sent ? "linear-gradient(90deg, #22c55e, #4ade80)" : "linear-gradient(90deg, #6366f1, #4f46e5)",
|
|
285
|
+
color: "white",
|
|
286
|
+
transition: "0.25s"
|
|
287
|
+
},
|
|
288
|
+
children: sent ? "Email Sent \u2714" : "Send Reset Link"
|
|
289
|
+
}
|
|
290
|
+
),
|
|
291
|
+
sent && /* @__PURE__ */ jsx3(
|
|
292
|
+
"p",
|
|
293
|
+
{
|
|
294
|
+
style: {
|
|
295
|
+
marginTop: 18,
|
|
296
|
+
fontSize: 14,
|
|
297
|
+
color: "#4ade80",
|
|
298
|
+
textAlign: "center"
|
|
299
|
+
},
|
|
300
|
+
children: "Check your inbox for reset instructions."
|
|
301
|
+
}
|
|
302
|
+
),
|
|
303
|
+
error && /* @__PURE__ */ jsx3(
|
|
304
|
+
"p",
|
|
305
|
+
{
|
|
306
|
+
style: {
|
|
307
|
+
marginTop: 18,
|
|
308
|
+
fontSize: 13,
|
|
309
|
+
color: "#f87171",
|
|
310
|
+
textAlign: "center"
|
|
311
|
+
},
|
|
312
|
+
children: error
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
)
|
|
319
318
|
}
|
|
320
319
|
);
|
|
321
320
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AuthContext.tsx","../src/http.ts","../src/Protected.tsx","../src/screens/LoginScreen.tsx","../src/screens/PasswordResetScreen.tsx","../src/screens/SignupScreen.tsx"],"sourcesContent":["/* \r\nDevelopers using this library should wrap their app with:\r\n <AuthProvider config={...}>\r\n <App />\r\n </AuthProvider>\r\n \r\n Then they can access auth anywhere with:\r\n const { user, login, logout, getToken } = useAuth();\r\n*/\r\n\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n} from \"react\";\r\n\r\nimport {\r\n AuthContextType,\r\n AuthProviderConfig,\r\n StandardAuthResponse,\r\n User,\r\n} from \"./types\";\r\n\r\nimport {\r\n httpJSON,\r\n makeURL,\r\n setStoredAccessToken,\r\n getStoredAccessToken,\r\n} from \"./http\";\r\n\r\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\r\n\r\nexport function useAuth(): AuthContextType {\r\n const ctx = useContext(AuthContext);\r\n if (!ctx) throw new Error(\"useAuth must be used inside AuthProvider\");\r\n return ctx;\r\n}\r\n\r\nexport function AuthProvider({\r\n config,\r\n children,\r\n}: React.PropsWithChildren<{ config: AuthProviderConfig }>) {\r\n const { baseURL, endpoints, onLoginSuccess, onLogout } = config;\r\n\r\n const [user, setUser] = useState<User | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const getToken = () => getStoredAccessToken();\r\n\r\n // Restore user from localStorage on app load\r\n useEffect(() => {\r\n const savedUser = localStorage.getItem(\"afk_user\");\r\n if (savedUser) {\r\n setUser(JSON.parse(savedUser));\r\n }\r\n setLoading(false);\r\n }, []);\r\n\r\n // LOGIN\r\n const login: AuthContextType[\"login\"] = async (email, password) => {\r\n const url = makeURL(baseURL, endpoints.login);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email, password }),\r\n });\r\n\r\n // store token + user\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // SIGNUP\r\n const signup: AuthContextType[\"signup\"] = async (payload) => {\r\n const url = makeURL(baseURL, endpoints.signup);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // LOGOUT\r\n const logout = () => {\r\n setStoredAccessToken(null);\r\n localStorage.removeItem(\"afk_user\");\r\n setUser(null);\r\n\r\n if (onLogout) onLogout();\r\n };\r\n\r\n const value = useMemo<AuthContextType>(\r\n () => ({\r\n user,\r\n loading,\r\n login,\r\n signup,\r\n logout,\r\n getToken,\r\n config,\r\n }),\r\n [user, loading, config],\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n","/*\r\n Internal HTTP helpers for auth-flow-kit.\r\n\r\n Responsibilities:\r\n • Construct safe URLs (makeURL)\r\n • Persist access token (get/set)\r\n • Perform JSON requests with optional auth (httpJSON)\r\n\r\n ⚠️ Library users should NOT import this directly.\r\n Used internally by AuthProvider + auth UI.\r\n\r\n Design goals:\r\n - predictable\r\n - minimal\r\n - RTK-style familiarity\r\n*/\r\n\r\nexport function makeURL(baseURL: string, path: string) {\r\n const cleanedBase = baseURL.replace(/\\/$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${cleanedBase}${normalizedPath}`;\r\n}\r\n\r\nexport function getStoredAccessToken(): string | null {\r\n try {\r\n const token = localStorage.getItem(\"afk_access_token\");\r\n return token;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function setStoredAccessToken(token: string | null) {\r\n try {\r\n if (!token) {\r\n localStorage.removeItem(\"afk_access_token\");\r\n return;\r\n }\r\n\r\n localStorage.setItem(\"afk_access_token\", token);\r\n } catch {\r\n // Swallow storage issues (e.g. private mode)\r\n }\r\n}\r\n\r\nexport async function httpJSON<T>(\r\n url: string,\r\n opts: RequestInit = {},\r\n withAuth = false,\r\n): Promise<T> {\r\n const baseHeaders: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n };\r\n\r\n if (withAuth) {\r\n const token = getStoredAccessToken();\r\n if (token) {\r\n baseHeaders[\"Authorization\"] = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n ...opts,\r\n headers: {\r\n ...baseHeaders,\r\n ...(opts.headers ?? {}),\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n let errorMessage = `Request failed (${response.status})`;\r\n\r\n // JSON error handling\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n const payload = await response.json();\r\n if (payload?.message) {\r\n errorMessage = payload.message;\r\n }\r\n } catch {\r\n // ignore malformed JSON\r\n }\r\n }\r\n\r\n // HTML fallback (common in Express)\r\n if (contentType.includes(\"text/html\")) {\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n errorMessage =\r\n \"The forgot password endpoint you added in config.endpoints.forgot does not exist in your server. Please check and update your config.endpoints.forgot\";\r\n } else {\r\n errorMessage = \"Unexpected server error\";\r\n }\r\n }\r\n\r\n // Dev hint for common misconfig\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n console.error(\r\n `[auth-flow-kit] Password reset endpoint not found.\r\n\r\nExpected POST route:\r\n ${url}\r\n\r\nFix by:\r\n • Adding the endpoint on your backend\r\n • OR updating config.endpoints.forgot`,\r\n );\r\n }\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n}\r\n","\"use client\";\r\n\r\n/*\r\nProtected component\r\n\r\nWraps authenticated content and prevents rendering when unauthenticated.\r\n\r\nIMPORTANT:\r\nThis component does NOT hard-redirect by default.\r\nNavigation should be handled by the host application (router or state).\r\n\r\nIf redirectTo is provided AND the host app supports routing,\r\na redirect will occur.\r\n*/\r\n\r\nimport React, { useEffect } from \"react\";\r\nimport { useAuth } from \"./AuthContext\";\r\n\r\ntype ProtectedProps = {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n};\r\n\r\nexport default function Protected({ children, redirectTo }: ProtectedProps) {\r\n const { user, loading } = useAuth();\r\n\r\n useEffect(() => {\r\n if (!loading && !user && redirectTo) {\r\n window.location.href = redirectTo;\r\n }\r\n }, [loading, user, redirectTo]);\r\n\r\n if (loading) return <div>Loading...</div>;\r\n if (!user) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport PasswordResetScreen from \"./PasswordResetScreen\";\r\n\r\nexport default function LoginScreen() {\r\n const { login } = useAuth();\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [showReset, setShowReset] = useState(false);\r\n\r\n if (showReset) {\r\n return (\r\n <div style={{ animation: \"fade .2s\" }}>\r\n <PasswordResetScreen />\r\n <p\r\n onClick={() => setShowReset(false)}\r\n style={{\r\n marginTop: 16,\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n textDecoration: \"underline\",\r\n }}\r\n >\r\n Back to login\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n // Submit\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await login(trimmedEmail, trimmedPassword);\r\n } catch (err: any) {\r\n setError(err?.message || \"Login failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Welcome Back 👋\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 10 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <p\r\n onClick={() => setShowReset(true)}\r\n style={{\r\n textAlign: \"right\",\r\n fontSize: 13,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n marginBottom: 24,\r\n }}\r\n >\r\n Forgot password?\r\n </p>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Signing in...\" : \"Sign in\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport { httpJSON, makeURL } from \"../http\";\r\n\r\nexport default function PasswordResetScreen() {\r\n const { config } = useAuth();\r\n\r\n const [email, setEmail] = useState(\"\");\r\n const [sent, setSent] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const requestReset = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n\r\n try {\r\n const url = makeURL(config.baseURL, config.endpoints.forgot);\r\n\r\n await httpJSON(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email }),\r\n });\r\n\r\n setSent(true);\r\n } catch (err: any) {\r\n setError(err?.message || \"Failed to request reset\");\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={requestReset}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.25s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Reset Password 🔑\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: sent ? \"-18px\" : \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"90%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: sent\r\n ? \"linear-gradient(90deg, #7aff9d, #34c759)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.3s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {sent ? \"Link Sent ✔\" : \"Send reset link\"}\r\n </button>\r\n\r\n {sent && (\r\n <p\r\n style={{\r\n marginTop: 20,\r\n color: \"#2ecc71\",\r\n textAlign: \"center\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n }}\r\n >\r\n Check your email for reset instructions.\r\n </p>\r\n )}\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 20,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\n\r\nexport default function SignupScreen() {\r\n const { signup } = useAuth();\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n const trimmedName = name.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword || !trimmedName) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await signup({ name, email, password });\r\n } catch (err: any) {\r\n setError(err?.message || \"Signup failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Create Account ✨\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Name\r\n </label>\r\n\r\n <input\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder=\"Your name\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Creating...\" : \"Create account\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n"],"mappings":"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","names":["useEffect","jsx","useEffect","useState","useState","jsx","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/AuthContext.tsx","../src/http.ts","../src/Protected.tsx","../src/screens/LoginScreen.tsx","../src/screens/PasswordResetScreen.tsx","../src/screens/SignupScreen.tsx"],"sourcesContent":["/* \r\nDevelopers using this library should wrap their app with:\r\n <AuthProvider config={...}>\r\n <App />\r\n </AuthProvider>\r\n \r\n Then they can access auth anywhere with:\r\n const { user, login, logout, getToken } = useAuth();\r\n*/\r\n\r\nimport React, {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n} from \"react\";\r\n\r\nimport {\r\n AuthContextType,\r\n AuthProviderConfig,\r\n StandardAuthResponse,\r\n User,\r\n} from \"./types\";\r\n\r\nimport {\r\n httpJSON,\r\n makeURL,\r\n setStoredAccessToken,\r\n getStoredAccessToken,\r\n} from \"./http\";\r\n\r\nconst AuthContext = createContext<AuthContextType | undefined>(undefined);\r\n\r\nexport function useAuth(): AuthContextType {\r\n const ctx = useContext(AuthContext);\r\n if (!ctx) throw new Error(\"useAuth must be used inside AuthProvider\");\r\n return ctx;\r\n}\r\n\r\nexport function AuthProvider({\r\n config,\r\n children,\r\n}: React.PropsWithChildren<{ config: AuthProviderConfig }>) {\r\n const { baseURL, endpoints, onLoginSuccess, onLogout } = config;\r\n\r\n const [user, setUser] = useState<User | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n\r\n const getToken = () => getStoredAccessToken();\r\n\r\n // Restore user from localStorage on app load\r\n useEffect(() => {\r\n const savedUser = localStorage.getItem(\"afk_user\");\r\n if (savedUser) {\r\n setUser(JSON.parse(savedUser));\r\n }\r\n setLoading(false);\r\n }, []);\r\n\r\n // LOGIN\r\n const login: AuthContextType[\"login\"] = async (email, password) => {\r\n const url = makeURL(baseURL, endpoints.login);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email, password }),\r\n });\r\n\r\n // store token + user\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // SIGNUP\r\n const signup: AuthContextType[\"signup\"] = async (payload) => {\r\n const url = makeURL(baseURL, endpoints.signup);\r\n\r\n const res = await httpJSON<StandardAuthResponse>(url, {\r\n method: \"POST\",\r\n body: JSON.stringify(payload),\r\n });\r\n\r\n setStoredAccessToken(res.accessToken);\r\n localStorage.setItem(\"afk_user\", JSON.stringify(res.user));\r\n\r\n setUser(res.user);\r\n\r\n if (onLoginSuccess) onLoginSuccess();\r\n };\r\n\r\n // LOGOUT\r\n const logout = () => {\r\n setStoredAccessToken(null);\r\n localStorage.removeItem(\"afk_user\");\r\n setUser(null);\r\n\r\n if (onLogout) onLogout();\r\n };\r\n\r\n const value = useMemo<AuthContextType>(\r\n () => ({\r\n user,\r\n loading,\r\n login,\r\n signup,\r\n logout,\r\n getToken,\r\n config,\r\n }),\r\n [user, loading, config],\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n","/*\r\n Internal HTTP helpers for auth-flow-kit.\r\n\r\n Responsibilities:\r\n • Construct safe URLs (makeURL)\r\n • Persist access token (get/set)\r\n • Perform JSON requests with optional auth (httpJSON)\r\n\r\n ⚠️ Library users should NOT import this directly.\r\n Used internally by AuthProvider + auth UI.\r\n\r\n Design goals:\r\n - predictable\r\n - minimal\r\n - RTK-style familiarity\r\n*/\r\n\r\nexport function makeURL(baseURL: string, path: string) {\r\n const cleanedBase = baseURL.replace(/\\/$/, \"\");\r\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\r\n return `${cleanedBase}${normalizedPath}`;\r\n}\r\n\r\nexport function getStoredAccessToken(): string | null {\r\n try {\r\n const token = localStorage.getItem(\"afk_access_token\");\r\n return token;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function setStoredAccessToken(token: string | null) {\r\n try {\r\n if (!token) {\r\n localStorage.removeItem(\"afk_access_token\");\r\n return;\r\n }\r\n\r\n localStorage.setItem(\"afk_access_token\", token);\r\n } catch {\r\n // Swallow storage issues (e.g. private mode)\r\n }\r\n}\r\n\r\nexport async function httpJSON<T>(\r\n url: string,\r\n opts: RequestInit = {},\r\n withAuth = false,\r\n): Promise<T> {\r\n const baseHeaders: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n };\r\n\r\n if (withAuth) {\r\n const token = getStoredAccessToken();\r\n if (token) {\r\n baseHeaders[\"Authorization\"] = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n const response = await fetch(url, {\r\n ...opts,\r\n headers: {\r\n ...baseHeaders,\r\n ...(opts.headers ?? {}),\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n let errorMessage = `Request failed (${response.status})`;\r\n\r\n // JSON error handling\r\n if (contentType.includes(\"application/json\")) {\r\n try {\r\n const payload = await response.json();\r\n if (payload?.message) {\r\n errorMessage = payload.message;\r\n }\r\n } catch {\r\n // ignore malformed JSON\r\n }\r\n }\r\n\r\n // HTML fallback (common in Express)\r\n if (contentType.includes(\"text/html\")) {\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n errorMessage =\r\n \"The forgot password endpoint you added in config.endpoints.forgot does not exist in your server. Please check and update your config.endpoints.forgot\";\r\n } else {\r\n errorMessage = \"Unexpected server error\";\r\n }\r\n }\r\n\r\n // Dev hint for common misconfig\r\n if (response.status === 404 && url.includes(\"forgot\")) {\r\n console.error(\r\n `[auth-flow-kit] Password reset endpoint not found.\r\n\r\nExpected POST route:\r\n ${url}\r\n\r\nFix by:\r\n • Adding the endpoint on your backend\r\n • OR updating config.endpoints.forgot`,\r\n );\r\n }\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n}\r\n","\"use client\";\r\n\r\n/*\r\nProtected component\r\n\r\nWraps authenticated content and prevents rendering when unauthenticated.\r\n\r\nIMPORTANT:\r\nThis component does NOT hard-redirect by default.\r\nNavigation should be handled by the host application (router or state).\r\n\r\nIf redirectTo is provided AND the host app supports routing,\r\na redirect will occur.\r\n*/\r\n\r\nimport React, { useEffect } from \"react\";\r\nimport { useAuth } from \"./AuthContext\";\r\n\r\ntype ProtectedProps = {\r\n children: React.ReactNode;\r\n redirectTo?: string;\r\n};\r\n\r\nexport default function Protected({ children, redirectTo }: ProtectedProps) {\r\n const { user, loading } = useAuth();\r\n\r\n useEffect(() => {\r\n if (!loading && !user && redirectTo) {\r\n window.location.href = redirectTo;\r\n }\r\n }, [loading, user, redirectTo]);\r\n\r\n if (loading) return <div>Loading...</div>;\r\n if (!user) return null;\r\n\r\n return <>{children}</>;\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport PasswordResetScreen from \"./PasswordResetScreen\";\r\n\r\nexport default function LoginScreen() {\r\n const { login } = useAuth();\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [showReset, setShowReset] = useState(false);\r\n\r\n if (showReset) {\r\n return (\r\n <div style={{ animation: \"fade .2s\" }}>\r\n <PasswordResetScreen />\r\n <p\r\n onClick={() => setShowReset(false)}\r\n style={{\r\n marginTop: 16,\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n textDecoration: \"underline\",\r\n }}\r\n >\r\n Back to login\r\n </p>\r\n </div>\r\n );\r\n }\r\n\r\n // Submit\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await login(trimmedEmail, trimmedPassword);\r\n } catch (err: any) {\r\n setError(err?.message || \"Login failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Welcome Back 👋\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 10 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.8)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <p\r\n onClick={() => setShowReset(true)}\r\n style={{\r\n textAlign: \"right\",\r\n fontSize: 13,\r\n color: \"#4b4bff\",\r\n cursor: \"pointer\",\r\n marginBottom: 24,\r\n }}\r\n >\r\n Forgot password?\r\n </p>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Signing in...\" : \"Sign in\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\nimport { httpJSON, makeURL } from \"../http\";\r\n\r\nexport default function PasswordResetScreen() {\r\n const { config } = useAuth();\r\n\r\n const [email, setEmail] = useState(\"\");\r\n const [sent, setSent] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const requestReset = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setError(null);\r\n\r\n try {\r\n const url = makeURL(config.baseURL, config.endpoints.forgot);\r\n\r\n await httpJSON(url, {\r\n method: \"POST\",\r\n body: JSON.stringify({ email }),\r\n });\r\n\r\n setSent(true);\r\n } catch (err: any) {\r\n setError(err?.message || \"Failed to request reset\");\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n minHeight: \"100vh\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n background: \"linear-gradient(135deg, #0f172a, #1e293b)\",\r\n fontFamily: \"Inter, sans-serif\",\r\n }}\r\n >\r\n <form\r\n onSubmit={requestReset}\r\n style={{\r\n width: 420,\r\n padding: 36,\r\n borderRadius: 16,\r\n background: \"#0b1220\",\r\n border: \"1px solid rgba(255,255,255,0.06)\",\r\n boxShadow: \"0 25px 60px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 28,\r\n color: \"#f1f5f9\",\r\n fontWeight: 600,\r\n fontSize: 26,\r\n textAlign: \"center\",\r\n }}\r\n >\r\n Password Reset\r\n </h2>\r\n\r\n <div style={{ marginBottom: 22 }}>\r\n <label\r\n style={{\r\n display: \"block\",\r\n marginBottom: 8,\r\n fontSize: 13,\r\n color: \"#94a3b8\",\r\n }}\r\n >\r\n Email Address\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px\",\r\n borderRadius: 10,\r\n border: \"1px solid #1f2a44\",\r\n background: \"#020617\",\r\n color: \"#e2e8f0\",\r\n fontSize: 14,\r\n outline: \"none\",\r\n transition: \"0.2s\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #6366f1\";\r\n e.currentTarget.style.boxShadow =\r\n \"0 0 0 2px rgba(99,102,241,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #1f2a44\";\r\n e.currentTarget.style.boxShadow = \"none\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px\",\r\n borderRadius: 10,\r\n border: \"none\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n cursor: \"pointer\",\r\n background: sent\r\n ? \"linear-gradient(90deg, #22c55e, #4ade80)\"\r\n : \"linear-gradient(90deg, #6366f1, #4f46e5)\",\r\n color: \"white\",\r\n transition: \"0.25s\",\r\n }}\r\n >\r\n {sent ? \"Email Sent ✔\" : \"Send Reset Link\"}\r\n </button>\r\n\r\n {sent && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n fontSize: 14,\r\n color: \"#4ade80\",\r\n textAlign: \"center\",\r\n }}\r\n >\r\n Check your inbox for reset instructions.\r\n </p>\r\n )}\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n fontSize: 13,\r\n color: \"#f87171\",\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport { useAuth } from \"../AuthContext\";\r\n\r\nexport default function SignupScreen() {\r\n const { signup } = useAuth();\r\n const [name, setName] = useState(\"\");\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [submitting, setSubmitting] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n const onSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setSubmitting(true);\r\n setError(null);\r\n\r\n const trimmedEmail = email.trim();\r\n const trimmedPassword = password.trim();\r\n const trimmedName = name.trim();\r\n\r\n if (!trimmedEmail || !trimmedPassword || !trimmedName) {\r\n setError(\"Email and password cannot be empty.\");\r\n setSubmitting(false);\r\n return;\r\n }\r\n\r\n try {\r\n await signup({ name, email, password });\r\n } catch (err: any) {\r\n setError(err?.message || \"Signup failed\");\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n };\r\n\r\n return (\r\n <form\r\n onSubmit={onSubmit}\r\n style={{\r\n maxWidth: 400,\r\n margin: \"60px auto\",\r\n padding: 32,\r\n borderRadius: 20,\r\n fontFamily: \"Inter, sans-serif\",\r\n\r\n // GLASS EFFECT\r\n background: \"rgba(255, 255, 255, 0.25)\",\r\n backdropFilter: \"blur(14px)\",\r\n WebkitBackdropFilter: \"blur(14px)\",\r\n\r\n boxShadow: \"0 20px 40px rgba(0,0,0,0.15)\",\r\n border: \"1px solid rgba(255,255,255,0.4)\",\r\n animation: \"fadeIn 0.3s ease\",\r\n }}\r\n >\r\n <h2\r\n style={{\r\n marginBottom: 30,\r\n color: \"#060f22\",\r\n fontWeight: 700,\r\n fontSize: 30,\r\n textAlign: \"center\",\r\n letterSpacing: \"-0.5px\",\r\n }}\r\n >\r\n Create Account ✨\r\n </h2>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Name\r\n </label>\r\n\r\n <input\r\n value={name}\r\n onChange={(e) => setName(e.target.value)}\r\n placeholder=\"Your name\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Email\r\n </label>\r\n\r\n <input\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n type=\"email\"\r\n placeholder=\"you@example.com\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <div style={{ position: \"relative\", marginBottom: 26 }}>\r\n <label\r\n style={{\r\n position: \"absolute\",\r\n top: \"-10px\",\r\n left: \"14px\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n padding: \"0 6px\",\r\n fontSize: 13,\r\n color: \"#444\",\r\n borderRadius: 6,\r\n }}\r\n >\r\n Password\r\n </label>\r\n\r\n <input\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n type=\"password\"\r\n placeholder=\"••••••••\"\r\n style={{\r\n width: \"80%\",\r\n padding: \"14px 16px\",\r\n borderRadius: 12,\r\n border: \"1px solid #d2d2d2\",\r\n fontSize: 15,\r\n outline: \"none\",\r\n transition: \"0.25s\",\r\n background: \"rgba(255,255,255,0.85)\",\r\n }}\r\n onFocus={(e) => {\r\n e.currentTarget.style.border = \"1px solid #4b4bff\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 3px rgba(75,75,255,0.25)\";\r\n }}\r\n onBlur={(e) => {\r\n e.currentTarget.style.border = \"1px solid #d2d2d2\";\r\n e.currentTarget.style.boxShadow = \"0 0 0 transparent\";\r\n }}\r\n />\r\n </div>\r\n\r\n <button\r\n disabled={submitting}\r\n type=\"submit\"\r\n style={{\r\n width: \"100%\",\r\n padding: \"14px 20px\",\r\n borderRadius: 12,\r\n background: submitting\r\n ? \"linear-gradient(90deg, #b2bdfd, #8da0ff)\"\r\n : \"linear-gradient(90deg, #5353aaff, #060f22ff)\",\r\n\r\n color: \"white\",\r\n border: \"none\",\r\n fontSize: 16,\r\n fontWeight: 700,\r\n letterSpacing: \"0.3px\",\r\n cursor: \"pointer\",\r\n transition: \"0.25s\",\r\n boxShadow: \"0 8px 20px rgba(75,75,255,0.25)\",\r\n }}\r\n >\r\n {submitting ? \"Creating...\" : \"Create account\"}\r\n </button>\r\n\r\n {error && (\r\n <p\r\n style={{\r\n marginTop: 18,\r\n color: \"crimson\",\r\n textAlign: \"center\",\r\n fontSize: 14,\r\n fontWeight: 500,\r\n }}\r\n >\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n );\r\n}\r\n"],"mappings":";AAUA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACCA,SAAS,QAAQ,SAAiB,MAAc;AACrD,QAAM,cAAc,QAAQ,QAAQ,OAAO,EAAE;AAC7C,QAAM,iBAAiB,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAC7D,SAAO,GAAG,WAAW,GAAG,cAAc;AACxC;AAEO,SAAS,uBAAsC;AACpD,MAAI;AACF,UAAM,QAAQ,aAAa,QAAQ,kBAAkB;AACrD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,OAAsB;AACzD,MAAI;AACF,QAAI,CAAC,OAAO;AACV,mBAAa,WAAW,kBAAkB;AAC1C;AAAA,IACF;AAEA,iBAAa,QAAQ,oBAAoB,KAAK;AAAA,EAChD,QAAQ;AAAA,EAER;AACF;AAEA,eAAsB,SACpB,KACA,OAAoB,CAAC,GACrB,WAAW,OACC;AACZ,QAAM,cAAsC;AAAA,IAC1C,gBAAgB;AAAA,EAClB;AAEA,MAAI,UAAU;AACZ,UAAM,QAAQ,qBAAqB;AACnC,QAAI,OAAO;AACT,kBAAY,eAAe,IAAI,UAAU,KAAK;AAAA,IAChD;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG;AAAA,MACH,GAAI,KAAK,WAAW,CAAC;AAAA,IACvB;AAAA,EACF,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,QAAI,eAAe,mBAAmB,SAAS,MAAM;AAGrD,QAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,KAAK;AACpC,YAAI,SAAS,SAAS;AACpB,yBAAe,QAAQ;AAAA,QACzB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,QAAI,YAAY,SAAS,WAAW,GAAG;AACrC,UAAI,SAAS,WAAW,OAAO,IAAI,SAAS,QAAQ,GAAG;AACrD,uBACE;AAAA,MACJ,OAAO;AACL,uBAAe;AAAA,MACjB;AAAA,IACF;AAGA,QAAI,SAAS,WAAW,OAAO,IAAI,SAAS,QAAQ,GAAG;AACrD,cAAQ;AAAA,QACN;AAAA;AAAA;AAAA,IAGJ,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA,MAKD;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,YAAY;AAAA,EAC9B;AAEA,SAAO,SAAS,KAAK;AACvB;;;ADIS;AArFT,IAAM,cAAc,cAA2C,MAAS;AAEjE,SAAS,UAA2B;AACzC,QAAM,MAAM,WAAW,WAAW;AAClC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,0CAA0C;AACpE,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AACF,GAA4D;AAC1D,QAAM,EAAE,SAAS,WAAW,gBAAgB,SAAS,IAAI;AAEzD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAsB,IAAI;AAClD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAE3C,QAAM,WAAW,MAAM,qBAAqB;AAG5C,YAAU,MAAM;AACd,UAAM,YAAY,aAAa,QAAQ,UAAU;AACjD,QAAI,WAAW;AACb,cAAQ,KAAK,MAAM,SAAS,CAAC;AAAA,IAC/B;AACA,eAAW,KAAK;AAAA,EAClB,GAAG,CAAC,CAAC;AAGL,QAAM,QAAkC,OAAO,OAAO,aAAa;AACjE,UAAM,MAAM,QAAQ,SAAS,UAAU,KAAK;AAE5C,UAAM,MAAM,MAAM,SAA+B,KAAK;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,IAC1C,CAAC;AAGD,yBAAqB,IAAI,WAAW;AACpC,iBAAa,QAAQ,YAAY,KAAK,UAAU,IAAI,IAAI,CAAC;AAEzD,YAAQ,IAAI,IAAI;AAEhB,QAAI,eAAgB,gBAAe;AAAA,EACrC;AAGA,QAAM,SAAoC,OAAO,YAAY;AAC3D,UAAM,MAAM,QAAQ,SAAS,UAAU,MAAM;AAE7C,UAAM,MAAM,MAAM,SAA+B,KAAK;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC9B,CAAC;AAED,yBAAqB,IAAI,WAAW;AACpC,iBAAa,QAAQ,YAAY,KAAK,UAAU,IAAI,IAAI,CAAC;AAEzD,YAAQ,IAAI,IAAI;AAEhB,QAAI,eAAgB,gBAAe;AAAA,EACrC;AAGA,QAAM,SAAS,MAAM;AACnB,yBAAqB,IAAI;AACzB,iBAAa,WAAW,UAAU;AAClC,YAAQ,IAAI;AAEZ,QAAI,SAAU,UAAS;AAAA,EACzB;AAEA,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,SAAS,MAAM;AAAA,EACxB;AAEA,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AACvD;;;AEvGA,SAAgB,aAAAA,kBAAiB;AAiBX,SAGb,UAHa,OAAAC,YAAA;AATP,SAAR,UAA2B,EAAE,UAAU,WAAW,GAAmB;AAC1E,QAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAElC,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,QAAQ,YAAY;AACnC,aAAO,SAAS,OAAO;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,UAAU,CAAC;AAE9B,MAAI,QAAS,QAAO,gBAAAD,KAAC,SAAI,wBAAU;AACnC,MAAI,CAAC,KAAM,QAAO;AAElB,SAAO,gBAAAA,KAAA,YAAG,UAAS;AACrB;;;ACnCA,SAAgB,YAAAE,iBAAgB;;;ACAhC,SAAgB,YAAAC,iBAAgB;AAmDxB,gBAAAC,MAYA,YAZA;AA/CO,SAAR,sBAAuC;AAC5C,QAAM,EAAE,OAAO,IAAI,QAAQ;AAE3B,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,EAAE;AACrC,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AAEtD,QAAM,eAAe,OAAO,MAAuB;AACjD,MAAE,eAAe;AACjB,aAAS,IAAI;AAEb,QAAI;AACF,YAAM,MAAM,QAAQ,OAAO,SAAS,OAAO,UAAU,MAAM;AAE3D,YAAM,SAAS,KAAK;AAAA,QAClB,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,MAChC,CAAC;AAED,cAAQ,IAAI;AAAA,IACd,SAAS,KAAU;AACjB,eAAS,KAAK,WAAW,yBAAyB;AAAA,IACpD;AAAA,EACF;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,WAAW;AAAA,QACX,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO;AAAA,YACP,SAAS;AAAA,YACT,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,WAAW;AAAA,UACb;AAAA,UAEA;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,cAAc;AAAA,kBACd,OAAO;AAAA,kBACP,YAAY;AAAA,kBACZ,UAAU;AAAA,kBACV,WAAW;AAAA,gBACb;AAAA,gBACD;AAAA;AAAA,YAED;AAAA,YAEA,qBAAC,SAAI,OAAO,EAAE,cAAc,GAAG,GAC7B;AAAA,8BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,UAAU;AAAA,oBACV,OAAO;AAAA,kBACT;AAAA,kBACD;AAAA;AAAA,cAED;AAAA,cAEA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,kBACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,kBACxC,MAAK;AAAA,kBACL,aAAY;AAAA,kBACZ,OAAO;AAAA,oBACL,OAAO;AAAA,oBACP,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,YAAY;AAAA,kBACd;AAAA,kBACA,SAAS,CAAC,MAAM;AACd,sBAAE,cAAc,MAAM,SAAS;AAC/B,sBAAE,cAAc,MAAM,YACpB;AAAA,kBACJ;AAAA,kBACA,QAAQ,CAAC,MAAM;AACb,sBAAE,cAAc,MAAM,SAAS;AAC/B,sBAAE,cAAc,MAAM,YAAY;AAAA,kBACpC;AAAA;AAAA,cACF;AAAA,eACF;AAAA,YAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,QAAQ;AAAA,kBACR,YAAY,OACR,6CACA;AAAA,kBACJ,OAAO;AAAA,kBACP,YAAY;AAAA,gBACd;AAAA,gBAEC,iBAAO,sBAAiB;AAAA;AAAA,YAC3B;AAAA,YAEC,QACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,WAAW;AAAA,kBACX,UAAU;AAAA,kBACV,OAAO;AAAA,kBACP,WAAW;AAAA,gBACb;AAAA,gBACD;AAAA;AAAA,YAED;AAAA,YAGD,SACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,WAAW;AAAA,kBACX,UAAU;AAAA,kBACV,OAAO;AAAA,kBACP,WAAW;AAAA,gBACb;AAAA,gBAEC;AAAA;AAAA,YACH;AAAA;AAAA;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;;;ADzIM,SACE,OAAAE,MADF,QAAAC,aAAA;AAVS,SAAR,cAA+B;AACpC,QAAM,EAAE,MAAM,IAAI,QAAQ;AAC1B,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAEhD,MAAI,WAAW;AACb,WACE,gBAAAD,MAAC,SAAI,OAAO,EAAE,WAAW,WAAW,GAClC;AAAA,sBAAAD,KAAC,uBAAoB;AAAA,MACrB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM,aAAa,KAAK;AAAA,UACjC,OAAO;AAAA,YACL,WAAW;AAAA,YACX,WAAW;AAAA,YACX,UAAU;AAAA,YACV,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,gBAAgB;AAAA,UAClB;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,EAEJ;AAGA,QAAM,WAAW,OAAO,MAAuB;AAC7C,MAAE,eAAe;AACjB,kBAAc,IAAI;AAClB,aAAS,IAAI;AAEb,UAAM,eAAe,MAAM,KAAK;AAChC,UAAM,kBAAkB,SAAS,KAAK;AAEtC,QAAI,CAAC,gBAAgB,CAAC,iBAAiB;AACrC,eAAS,qCAAqC;AAC9C,oBAAc,KAAK;AACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,MAAM,cAAc,eAAe;AAAA,IAC3C,SAAS,KAAU;AACjB,eAAS,KAAK,WAAW,cAAc;AAAA,IACzC,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,cAAc;AAAA,QACd,YAAY;AAAA,QAEZ,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QAEtB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,cAAc;AAAA,cACd,OAAO;AAAA,cACP,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,WAAW;AAAA,cACX,eAAe;AAAA,YACjB;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,cAAc,GAAG,GACnD;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,cAChB;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,cACxC,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cACA,SAAS,CAAC,MAAM;AACd,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,cAAc,GAAG,GACnD;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,cAChB;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,cAC3C,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cACA,SAAS,CAAC,MAAM;AACd,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM,aAAa,IAAI;AAAA,YAChC,OAAO;AAAA,cACL,WAAW;AAAA,cACX,UAAU;AAAA,cACV,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,YAChB;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO;AAAA,cACL,OAAO;AAAA,cACP,SAAS;AAAA,cACT,cAAc;AAAA,cAEd,YAAY,aACR,6CACA;AAAA,cAEJ,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe;AAAA,cACf,QAAQ;AAAA,cACR,YAAY;AAAA,cACZ,WAAW;AAAA,YACb;AAAA,YAEC,uBAAa,kBAAkB;AAAA;AAAA,QAClC;AAAA,QAEC,SACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,WAAW;AAAA,cACX,OAAO;AAAA,cACP,WAAW;AAAA,cACX,UAAU;AAAA,cACV,YAAY;AAAA,YACd;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AElOA,SAAgB,YAAAG,iBAAgB;AAuD1B,gBAAAC,MAaA,QAAAC,aAbA;AApDS,SAAR,eAAgC;AACrC,QAAM,EAAE,OAAO,IAAI,QAAQ;AAC3B,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAS,EAAE;AACnC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AAEtD,QAAM,WAAW,OAAO,MAAuB;AAC7C,MAAE,eAAe;AACjB,kBAAc,IAAI;AAClB,aAAS,IAAI;AAEb,UAAM,eAAe,MAAM,KAAK;AAChC,UAAM,kBAAkB,SAAS,KAAK;AACtC,UAAM,cAAc,KAAK,KAAK;AAE9B,QAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,aAAa;AACrD,eAAS,qCAAqC;AAC9C,oBAAc,KAAK;AACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,EAAE,MAAM,OAAO,SAAS,CAAC;AAAA,IACxC,SAAS,KAAU;AACjB,eAAS,KAAK,WAAW,eAAe;AAAA,IAC1C,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,cAAc;AAAA,QACd,YAAY;AAAA;AAAA,QAGZ,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QAEtB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,cAAc;AAAA,cACd,OAAO;AAAA,cACP,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,WAAW;AAAA,cACX,eAAe;AAAA,YACjB;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,cAAc,GAAG,GACnD;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,cAChB;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK;AAAA,cACvC,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cACA,SAAS,CAAC,MAAM;AACd,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,cAAc,GAAG,GACnD;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,cAChB;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,cACxC,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cACA,SAAS,CAAC,MAAM;AACd,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QAEA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,cAAc,GAAG,GACnD;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,cAAc;AAAA,cAChB;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,cAC3C,MAAK;AAAA,cACL,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cACA,SAAS,CAAC,MAAM;AACd,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,kBAAE,cAAc,MAAM,SAAS;AAC/B,kBAAE,cAAc,MAAM,YAAY;AAAA,cACpC;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO;AAAA,cACL,OAAO;AAAA,cACP,SAAS;AAAA,cACT,cAAc;AAAA,cACd,YAAY,aACR,6CACA;AAAA,cAEJ,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe;AAAA,cACf,QAAQ;AAAA,cACR,YAAY;AAAA,cACZ,WAAW;AAAA,YACb;AAAA,YAEC,uBAAa,gBAAgB;AAAA;AAAA,QAChC;AAAA,QAEC,SACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,WAAW;AAAA,cACX,OAAO;AAAA,cACP,WAAW;AAAA,cACX,UAAU;AAAA,cACV,YAAY;AAAA,YACd;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":["useEffect","jsx","useEffect","useState","useState","jsx","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState"]}
|