@thetechfossil/auth2 1.2.20 → 1.2.22

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.mjs CHANGED
@@ -7,16 +7,20 @@ import React, { createContext, forwardRef, useContext, useState, useEffect, useC
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
 
9
9
  var __defProp = Object.defineProperty;
10
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
- }) : x)(function(x) {
13
- if (typeof require !== "undefined") return require.apply(this, arguments);
14
- throw Error('Dynamic require of "' + x + '" is not supported');
15
- });
16
10
  var __export = (target, all) => {
17
11
  for (var name in all)
18
12
  __defProp(target, name, { get: all[name], enumerable: true });
19
13
  };
14
+ var ERROR_MESSAGES = {
15
+ NETWORK_ERROR: "Unable to connect to the server. Please check your internet connection and try again.",
16
+ TIMEOUT: "The request took too long. Please try again.",
17
+ SERVER_ERROR: "Something went wrong on our end. Please try again later.",
18
+ UNAUTHORIZED: "Your session has expired. Please log in again.",
19
+ FORBIDDEN: "You do not have permission to perform this action.",
20
+ NOT_FOUND: "The requested resource was not found.",
21
+ RATE_LIMITED: "Too many requests. Please wait a moment and try again.",
22
+ UNKNOWN: "An unexpected error occurred. Please try again."
23
+ };
20
24
  var HttpClient = class {
21
25
  constructor(baseUrl, defaultHeaders = {}) {
22
26
  this.csrfToken = null;
@@ -51,7 +55,7 @@ var HttpClient = class {
51
55
  }
52
56
  return config;
53
57
  },
54
- (error) => Promise.reject(error)
58
+ (error) => Promise.reject(this.createUserFriendlyError(error))
55
59
  );
56
60
  this.axiosInstance.interceptors.response.use(
57
61
  (response) => response,
@@ -66,18 +70,71 @@ var HttpClient = class {
66
70
  }
67
71
  return this.axiosInstance(originalRequest);
68
72
  } catch (refreshError) {
69
- return Promise.reject(refreshError);
73
+ return Promise.reject(this.createUserFriendlyError(refreshError));
70
74
  }
71
75
  }
72
- if (error.response && error.response.data && error.response.data.message) {
73
- const customError = new Error(error.response.data.message);
74
- customError.response = error.response;
75
- return Promise.reject(customError);
76
- }
77
- return Promise.reject(error);
76
+ return Promise.reject(this.createUserFriendlyError(error));
78
77
  }
79
78
  );
80
79
  }
80
+ /**
81
+ * Creates a user-friendly error message from an Axios error
82
+ */
83
+ createUserFriendlyError(error) {
84
+ if (error instanceof Error && !error.isAxiosError) {
85
+ return error;
86
+ }
87
+ let message;
88
+ let statusCode;
89
+ if (axios.isAxiosError(error)) {
90
+ statusCode = error.response?.status;
91
+ const responseData = error.response?.data;
92
+ if (responseData?.message) {
93
+ message = responseData.message;
94
+ } else if (!error.response) {
95
+ if (error.code === "ECONNABORTED" || error.message.includes("timeout")) {
96
+ message = ERROR_MESSAGES.TIMEOUT;
97
+ } else if (error.code === "ERR_NETWORK" || error.message === "Network Error") {
98
+ message = ERROR_MESSAGES.NETWORK_ERROR;
99
+ } else {
100
+ message = ERROR_MESSAGES.NETWORK_ERROR;
101
+ }
102
+ } else {
103
+ switch (statusCode) {
104
+ case 400:
105
+ message = responseData?.message || "Invalid request. Please check your input.";
106
+ break;
107
+ case 401:
108
+ message = responseData?.message || ERROR_MESSAGES.UNAUTHORIZED;
109
+ break;
110
+ case 403:
111
+ message = responseData?.message || ERROR_MESSAGES.FORBIDDEN;
112
+ break;
113
+ case 404:
114
+ message = responseData?.message || ERROR_MESSAGES.NOT_FOUND;
115
+ break;
116
+ case 429:
117
+ message = ERROR_MESSAGES.RATE_LIMITED;
118
+ break;
119
+ case 500:
120
+ case 502:
121
+ case 503:
122
+ case 504:
123
+ message = ERROR_MESSAGES.SERVER_ERROR;
124
+ break;
125
+ default:
126
+ message = responseData?.message || ERROR_MESSAGES.UNKNOWN;
127
+ }
128
+ }
129
+ } else {
130
+ message = error?.message || ERROR_MESSAGES.UNKNOWN;
131
+ }
132
+ const customError = new Error(message);
133
+ customError.response = error?.response;
134
+ customError.statusCode = statusCode;
135
+ customError.originalError = error;
136
+ return customError;
137
+ }
81
138
  async get(endpoint, headers) {
82
139
  const response = await this.axiosInstance.get(endpoint, { headers });
83
140
  return response.data;
@@ -283,6 +340,7 @@ var AuthService = class {
283
340
  if (token) {
284
341
  this.token = token;
285
342
  this.httpClient.setAuthToken(token);
343
+ this.setTokenCookie(token);
286
344
  }
287
345
  } catch (error) {
288
346
  console.warn("Failed to load token from storage:", error);
@@ -293,15 +351,28 @@ var AuthService = class {
293
351
  if (typeof window !== "undefined" && this.config.localStorageKey) {
294
352
  try {
295
353
  localStorage.setItem(this.config.localStorageKey, token);
354
+ this.setTokenCookie(token);
296
355
  } catch (error) {
297
356
  console.warn("Failed to save token to storage:", error);
298
357
  }
299
358
  }
300
359
  }
360
+ setTokenCookie(token) {
361
+ if (typeof window !== "undefined") {
362
+ const maxAge = 7 * 24 * 60 * 60;
363
+ document.cookie = `auth_token=${token}; path=/; max-age=${maxAge}; SameSite=Lax`;
364
+ }
365
+ }
366
+ removeTokenCookie() {
367
+ if (typeof window !== "undefined") {
368
+ document.cookie = "auth_token=; path=/; max-age=0; SameSite=Lax";
369
+ }
370
+ }
301
371
  removeTokenFromStorage() {
302
372
  if (typeof window !== "undefined" && this.config.localStorageKey) {
303
373
  try {
304
374
  localStorage.removeItem(this.config.localStorageKey);
375
+ this.removeTokenCookie();
305
376
  } catch (error) {
306
377
  console.warn("Failed to remove token from storage:", error);
307
378
  }
@@ -1280,14 +1351,6 @@ function useThemeColors() {
1280
1351
  const { theme } = useAuthTheme();
1281
1352
  return theme === "dark" ? darkTheme : lightTheme;
1282
1353
  }
1283
- var PhoneInputWithCountry = null;
1284
- try {
1285
- const module = __require("react-phone-number-input");
1286
- PhoneInputWithCountry = module.default || module;
1287
- __require("react-phone-number-input/style.css");
1288
- } catch (error) {
1289
- console.warn("react-phone-number-input not available, using fallback");
1290
- }
1291
1354
  var CustomPhoneInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(
1292
1355
  "input",
1293
1356
  {
@@ -1308,6 +1371,8 @@ var PhoneInput = ({
1308
1371
  }) => {
1309
1372
  const colors = useThemeColors();
1310
1373
  const [defaultCountry, setDefaultCountry] = useState("US");
1374
+ const [PhoneInputComponent, setPhoneInputComponent] = useState(null);
1375
+ const [isLoading, setIsLoading] = useState(true);
1311
1376
  const styleContent = useMemo(() => `
1312
1377
  .PhoneInput {
1313
1378
  display: flex;
@@ -1420,6 +1485,29 @@ var PhoneInput = ({
1420
1485
  opacity: 0.6;
1421
1486
  }
1422
1487
  `, [colors]);
1488
+ useEffect(() => {
1489
+ let mounted = true;
1490
+ const loadPhoneInput = async () => {
1491
+ try {
1492
+ const module = await import('react-phone-number-input');
1493
+ if (mounted) {
1494
+ setPhoneInputComponent(() => module.default);
1495
+ }
1496
+ } catch (error) {
1497
+ if (mounted) {
1498
+ setPhoneInputComponent(null);
1499
+ }
1500
+ } finally {
1501
+ if (mounted) {
1502
+ setIsLoading(false);
1503
+ }
1504
+ }
1505
+ };
1506
+ loadPhoneInput();
1507
+ return () => {
1508
+ mounted = false;
1509
+ };
1510
+ }, []);
1423
1511
  useEffect(() => {
1424
1512
  const detectCountry = async () => {
1425
1513
  try {
@@ -1472,7 +1560,6 @@ var PhoneInput = ({
1472
1560
  }
1473
1561
  }
1474
1562
  } catch (error) {
1475
- console.log("Country detection failed, using default US");
1476
1563
  }
1477
1564
  };
1478
1565
  detectCountry();
@@ -1480,7 +1567,31 @@ var PhoneInput = ({
1480
1567
  const handleChange = useMemo(() => (val) => {
1481
1568
  onChange(val || "");
1482
1569
  }, [onChange]);
1483
- if (!PhoneInputWithCountry) {
1570
+ if (isLoading) {
1571
+ return /* @__PURE__ */ jsx(
1572
+ "input",
1573
+ {
1574
+ id,
1575
+ type: "tel",
1576
+ value,
1577
+ onChange: (e) => onChange(e.target.value),
1578
+ disabled,
1579
+ required,
1580
+ placeholder,
1581
+ style: {
1582
+ width: "100%",
1583
+ padding: "12px 16px",
1584
+ border: `1px solid ${colors.borderSecondary}`,
1585
+ borderRadius: "8px",
1586
+ fontSize: "16px",
1587
+ backgroundColor: colors.bgSecondary,
1588
+ color: colors.textPrimary,
1589
+ ...style
1590
+ }
1591
+ }
1592
+ );
1593
+ }
1594
+ if (!PhoneInputComponent) {
1484
1595
  return /* @__PURE__ */ jsx(
1485
1596
  "input",
1486
1597
  {
@@ -1514,7 +1625,7 @@ var PhoneInput = ({
1514
1625
  children: [
1515
1626
  /* @__PURE__ */ jsx("style", { children: styleContent }),
1516
1627
  /* @__PURE__ */ jsx(
1517
- PhoneInputWithCountry,
1628
+ PhoneInputComponent,
1518
1629
  {
1519
1630
  id,
1520
1631
  international: true,
@@ -2012,6 +2123,28 @@ var RegisterForm = ({
2012
2123
  const [error, setError] = useState(null);
2013
2124
  const [showPassword, setShowPassword] = useState(false);
2014
2125
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);
2126
+ const [invitationDetails, setInvitationDetails] = useState(null);
2127
+ const [isLoadingInvitation, setIsLoadingInvitation] = useState(false);
2128
+ const config = authConfig || {
2129
+ baseUrl: "http://localhost:7000"
2130
+ };
2131
+ useEffect(() => {
2132
+ if (invitationToken) {
2133
+ setIsLoadingInvitation(true);
2134
+ fetch(`${config.baseUrl}/api/v1/auth/verify-invitation/${invitationToken}`).then((res) => res.json()).then((data) => {
2135
+ setInvitationDetails(data);
2136
+ if (data.valid && data.email) {
2137
+ setEmail(data.email);
2138
+ }
2139
+ }).catch((err) => {
2140
+ console.error("Failed to verify invitation:", err);
2141
+ setError("Failed to verify invitation. Please try again.");
2142
+ }).finally(() => {
2143
+ setIsLoadingInvitation(false);
2144
+ });
2145
+ }
2146
+ }, [invitationToken, config.baseUrl]);
2147
+ const isEmailDisabled = isLoading || invitationDetails?.valid && !!invitationDetails?.email;
2015
2148
  const getPasswordStrength = (pwd) => {
2016
2149
  if (!pwd) return { strength: "weak", score: 0, label: "" };
2017
2150
  let score = 0;
@@ -2025,9 +2158,6 @@ var RegisterForm = ({
2025
2158
  return { strength: "strong", score, label: "Strong" };
2026
2159
  };
2027
2160
  getPasswordStrength(password);
2028
- const config = authConfig || {
2029
- baseUrl: "http://localhost:7000"
2030
- };
2031
2161
  const { register } = useAuth2(config);
2032
2162
  const handleSubmit = async (e) => {
2033
2163
  e.preventDefault();
@@ -2062,6 +2192,25 @@ var RegisterForm = ({
2062
2192
  if (response.ok && data.success) {
2063
2193
  if (typeof window !== "undefined" && data.token) {
2064
2194
  localStorage.setItem("auth_token", data.token);
2195
+ if (data.invitation?.organizationId && data.invitation?.role) {
2196
+ localStorage.setItem("currentOrganizationId", data.invitation.organizationId);
2197
+ const backendUrl = typeof window !== "undefined" ? process.env.NEXT_PUBLIC_INVENTORY_API_URL || process.env.NEXT_PUBLIC_BIZFLOW_API_URL || "http://localhost:5002" : "http://localhost:5002";
2198
+ try {
2199
+ await fetch(`${backendUrl}/api/auth/sync-with-role`, {
2200
+ method: "POST",
2201
+ headers: {
2202
+ "Content-Type": "application/json",
2203
+ "Authorization": `Bearer ${data.token}`
2204
+ },
2205
+ body: JSON.stringify({
2206
+ organizationId: data.invitation.organizationId,
2207
+ roleName: data.invitation.role
2208
+ })
2209
+ });
2210
+ } catch (syncError) {
2211
+ console.error("Failed to sync user role with backend:", syncError);
2212
+ }
2213
+ }
2065
2214
  }
2066
2215
  onRegisterSuccess?.();
2067
2216
  } else {
@@ -2169,7 +2318,7 @@ var RegisterForm = ({
2169
2318
  value: email,
2170
2319
  onChange: (e) => setEmail(e.target.value),
2171
2320
  required: !phoneNumber,
2172
- disabled: isLoading,
2321
+ disabled: isEmailDisabled,
2173
2322
  style: {
2174
2323
  width: "100%",
2175
2324
  padding: "12px 16px",
@@ -2177,9 +2326,11 @@ var RegisterForm = ({
2177
2326
  borderRadius: "8px",
2178
2327
  fontSize: "16px",
2179
2328
  boxSizing: "border-box",
2180
- color: colors.textPrimary,
2329
+ color: isEmailDisabled ? colors.textSecondary : colors.textPrimary,
2181
2330
  transition: "all 0.2s ease",
2182
- backgroundColor: colors.bgSecondary
2331
+ backgroundColor: isEmailDisabled ? colors.bgHover : colors.bgSecondary,
2332
+ cursor: isEmailDisabled ? "not-allowed" : "text",
2333
+ opacity: isEmailDisabled ? 0.7 : 1
2183
2334
  },
2184
2335
  placeholder: "Enter your email"
2185
2336
  }
@@ -2882,7 +3033,7 @@ var EmailVerificationPage = ({
2882
3033
  } })
2883
3034
  ] }) });
2884
3035
  }
2885
- return /* @__PURE__ */ jsx("div", { style: {
3036
+ return /* @__PURE__ */ jsxs("div", { style: {
2886
3037
  maxWidth: "500px",
2887
3038
  margin: "0 auto",
2888
3039
  padding: "30px",
@@ -2891,44 +3042,86 @@ var EmailVerificationPage = ({
2891
3042
  backgroundColor: "#ffffff",
2892
3043
  textAlign: "center",
2893
3044
  border: "1px solid #eaeaea"
2894
- }, children: /* @__PURE__ */ jsxs("div", { style: {
2895
- padding: "20px"
2896
3045
  }, children: [
2897
- /* @__PURE__ */ jsx("h2", { style: { color: "black" }, children: "Email Verification" }),
2898
- /* @__PURE__ */ jsx("div", { style: {
2899
- padding: "16px 20px",
2900
- margin: "24px 0",
2901
- borderRadius: "8px",
2902
- fontSize: "15px",
2903
- fontWeight: 500,
2904
- backgroundColor: isSuccess ? "#d4edda" : "#f8d7da",
2905
- color: isSuccess ? "#155724" : "#721c24",
2906
- border: isSuccess ? "1px solid #c3e6cb" : "1px solid #f5c6cb"
2907
- }, children: message }),
2908
- isSuccess && /* @__PURE__ */ jsxs("div", { style: {
2909
- marginTop: "24px"
3046
+ /* @__PURE__ */ jsxs("div", { style: {
3047
+ padding: "20px"
2910
3048
  }, children: [
2911
- /* @__PURE__ */ jsx("p", { style: { color: "black" }, children: "Your email has been successfully verified!" }),
2912
- /* @__PURE__ */ jsx(
2913
- "button",
2914
- {
2915
- onClick: () => window.location.href = "/login",
2916
- style: {
2917
- padding: "12px 24px",
2918
- backgroundColor: "#007bff",
2919
- color: "white",
2920
- border: "none",
2921
- borderRadius: "8px",
2922
- fontSize: "16px",
2923
- fontWeight: 600,
2924
- cursor: "pointer",
2925
- transition: "all 0.2s ease"
2926
- },
2927
- children: "Go to Login"
3049
+ /* @__PURE__ */ jsx("h2", { style: { color: "black" }, children: isSuccess ? "\u2713 Email Verified!" : "\u2717 Verification Failed" }),
3050
+ /* @__PURE__ */ jsx("div", { style: {
3051
+ padding: "16px 20px",
3052
+ margin: "24px 0",
3053
+ borderRadius: "8px",
3054
+ fontSize: "15px",
3055
+ fontWeight: 500,
3056
+ backgroundColor: isSuccess ? "#d4edda" : "#f8d7da",
3057
+ color: isSuccess ? "#155724" : "#721c24",
3058
+ border: isSuccess ? "1px solid #c3e6cb" : "1px solid #f5c6cb"
3059
+ }, children: message }),
3060
+ isSuccess ? /* @__PURE__ */ jsxs("div", { style: { marginTop: "24px" }, children: [
3061
+ /* @__PURE__ */ jsx("p", { style: { color: "#666", marginBottom: "16px" }, children: "Redirecting to login..." }),
3062
+ /* @__PURE__ */ jsx("div", { style: {
3063
+ border: "3px solid #d4edda",
3064
+ borderTop: "3px solid #28a745",
3065
+ borderRadius: "50%",
3066
+ width: "30px",
3067
+ height: "30px",
3068
+ animation: "spin 1s linear infinite",
3069
+ margin: "0 auto"
3070
+ } })
3071
+ ] }) : /* @__PURE__ */ jsxs("div", { style: { marginTop: "24px" }, children: [
3072
+ /* @__PURE__ */ jsx("p", { style: { color: "#666", marginBottom: "16px" }, children: "The verification link may have expired or already been used." }),
3073
+ /* @__PURE__ */ jsx(
3074
+ "button",
3075
+ {
3076
+ onClick: () => {
3077
+ const registerPath = process.env.NEXT_PUBLIC_AUTH_REDIRECT_TO_REGISTER || process.env.REACT_APP_AUTH_REDIRECT_TO_REGISTER || "/auth/register";
3078
+ window.location.href = registerPath;
3079
+ },
3080
+ style: {
3081
+ padding: "12px 24px",
3082
+ backgroundColor: "#007bff",
3083
+ color: "white",
3084
+ border: "none",
3085
+ borderRadius: "8px",
3086
+ fontSize: "16px",
3087
+ fontWeight: 600,
3088
+ cursor: "pointer",
3089
+ transition: "all 0.2s ease",
3090
+ marginRight: "12px"
3091
+ },
3092
+ children: "Register Again"
3093
+ }
3094
+ ),
3095
+ /* @__PURE__ */ jsx(
3096
+ "button",
3097
+ {
3098
+ onClick: () => {
3099
+ const loginPath = process.env.NEXT_PUBLIC_AUTH_REDIRECT_TO_LOGIN || process.env.REACT_APP_AUTH_REDIRECT_TO_LOGIN || "/auth/login";
3100
+ window.location.href = loginPath;
3101
+ },
3102
+ style: {
3103
+ padding: "12px 24px",
3104
+ backgroundColor: "#6c757d",
3105
+ color: "white",
3106
+ border: "none",
3107
+ borderRadius: "8px",
3108
+ fontSize: "16px",
3109
+ fontWeight: 600,
3110
+ cursor: "pointer",
3111
+ transition: "all 0.2s ease"
3112
+ },
3113
+ children: "Go to Login"
3114
+ }
3115
+ )
3116
+ ] })
3117
+ ] }),
3118
+ /* @__PURE__ */ jsx("style", { children: `
3119
+ @keyframes spin {
3120
+ 0% { transform: rotate(0deg); }
3121
+ 100% { transform: rotate(360deg); }
2928
3122
  }
2929
- )
2930
- ] })
2931
- ] }) });
3123
+ ` })
3124
+ ] });
2932
3125
  };
2933
3126
  var ThemeWrapper = forwardRef(
2934
3127
  ({ children, className = "", style }, ref) => {
@@ -5139,6 +5332,274 @@ var UserProfile = ({
5139
5332
  ] })
5140
5333
  ] });
5141
5334
  };
5335
+ var SuperAdminSignIn = ({ redirectUrl, appearance }) => {
5336
+ const { signIn, isSignedIn, loading: authLoading, user } = useAuth();
5337
+ const colors = useThemeColors();
5338
+ const [email, setEmail] = useState("");
5339
+ const [password, setPassword] = useState("");
5340
+ const [showPassword, setShowPassword] = useState(false);
5341
+ const [isLoading, setIsLoading] = useState(false);
5342
+ const [error, setError] = useState(null);
5343
+ const [success, setSuccess] = useState(null);
5344
+ useEffect(() => {
5345
+ if (isSignedIn && user) {
5346
+ const isSuperAdmin = user.role === "SUPER_ADMIN" || user.role === "SUPERADMIN";
5347
+ if (isSuperAdmin) {
5348
+ const redirect = redirectUrl || process.env.NEXT_PUBLIC_AUTH_REDIRECT_AFTER_LOGIN || process.env.REACT_APP_AUTH_REDIRECT_AFTER_LOGIN || "/dashboard";
5349
+ const baseUrl = process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || (typeof window !== "undefined" ? window.location.origin : "");
5350
+ window.location.href = `${baseUrl}${redirect}`;
5351
+ } else {
5352
+ setError("Access denied. Only Super Admin users can access this portal.");
5353
+ document.cookie = "auth_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
5354
+ document.cookie = "refresh_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
5355
+ }
5356
+ }
5357
+ }, [isSignedIn, user, redirectUrl]);
5358
+ const handleSubmit = async (e) => {
5359
+ e.preventDefault();
5360
+ setIsLoading(true);
5361
+ setError(null);
5362
+ setSuccess(null);
5363
+ try {
5364
+ const response = await signIn({ email, password });
5365
+ if (response.success) {
5366
+ const userRole = response.user?.role;
5367
+ const isSuperAdmin = userRole === "SUPER_ADMIN" || userRole === "SUPERADMIN";
5368
+ if (!isSuperAdmin) {
5369
+ document.cookie = "auth_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
5370
+ document.cookie = "refresh_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
5371
+ setError("Access denied. Only Super Admin users can access this portal.");
5372
+ return;
5373
+ }
5374
+ setSuccess("Login successful! Redirecting...");
5375
+ } else {
5376
+ setError(response.message || "Login failed. Please check your credentials.");
5377
+ }
5378
+ } catch (err) {
5379
+ setError(err instanceof Error ? err.message : "An error occurred during login.");
5380
+ } finally {
5381
+ setIsLoading(false);
5382
+ }
5383
+ };
5384
+ if (authLoading) {
5385
+ return /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "40px" }, children: /* @__PURE__ */ jsx("div", { children: "Loading..." }) });
5386
+ }
5387
+ return /* @__PURE__ */ jsx(
5388
+ ThemeWrapper,
5389
+ {
5390
+ style: {
5391
+ maxWidth: "400px",
5392
+ margin: "0 auto",
5393
+ padding: "30px",
5394
+ borderRadius: "12px",
5395
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.1)",
5396
+ backgroundColor: colors.bgPrimary,
5397
+ border: `1px solid ${colors.borderPrimary}`,
5398
+ ...appearance?.elements?.card
5399
+ },
5400
+ children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
5401
+ /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", marginBottom: "24px" }, children: [
5402
+ /* @__PURE__ */ jsx("div", { style: {
5403
+ width: "60px",
5404
+ height: "60px",
5405
+ margin: "0 auto 16px",
5406
+ backgroundColor: colors.buttonPrimary + "20",
5407
+ borderRadius: "12px",
5408
+ display: "flex",
5409
+ alignItems: "center",
5410
+ justifyContent: "center"
5411
+ }, children: /* @__PURE__ */ jsxs("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: colors.buttonPrimary, strokeWidth: "2", children: [
5412
+ /* @__PURE__ */ jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
5413
+ /* @__PURE__ */ jsx("path", { d: "M9 12l2 2 4-4" })
5414
+ ] }) }),
5415
+ /* @__PURE__ */ jsx("h2", { style: {
5416
+ color: colors.textPrimary,
5417
+ fontSize: "24px",
5418
+ fontWeight: 600,
5419
+ margin: 0,
5420
+ ...appearance?.elements?.headerTitle
5421
+ }, children: "Super Admin Portal" }),
5422
+ /* @__PURE__ */ jsx("p", { style: {
5423
+ color: colors.textSecondary,
5424
+ fontSize: "14px",
5425
+ marginTop: "8px"
5426
+ }, children: "Sign in with your administrator credentials" })
5427
+ ] }),
5428
+ error && /* @__PURE__ */ jsx("div", { style: {
5429
+ padding: "12px 16px",
5430
+ marginBottom: "20px",
5431
+ backgroundColor: colors.errorBg,
5432
+ color: colors.errorText,
5433
+ border: `1px solid ${colors.errorBorder}`,
5434
+ borderRadius: "8px",
5435
+ fontSize: "14px"
5436
+ }, children: error }),
5437
+ success && /* @__PURE__ */ jsx("div", { style: {
5438
+ padding: "12px 16px",
5439
+ marginBottom: "20px",
5440
+ backgroundColor: colors.successBg,
5441
+ color: colors.successText,
5442
+ border: `1px solid ${colors.successBorder}`,
5443
+ borderRadius: "8px",
5444
+ fontSize: "14px"
5445
+ }, children: success }),
5446
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
5447
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", style: {
5448
+ display: "block",
5449
+ marginBottom: "8px",
5450
+ fontWeight: 500,
5451
+ color: colors.textSecondary,
5452
+ fontSize: "14px"
5453
+ }, children: "Email Address" }),
5454
+ /* @__PURE__ */ jsx(
5455
+ "input",
5456
+ {
5457
+ id: "email",
5458
+ type: "email",
5459
+ value: email,
5460
+ onChange: (e) => setEmail(e.target.value),
5461
+ onFocus: (e) => {
5462
+ e.currentTarget.style.borderColor = colors.buttonPrimary;
5463
+ e.currentTarget.style.outline = `2px solid ${colors.buttonPrimary}40`;
5464
+ },
5465
+ onBlur: (e) => {
5466
+ e.currentTarget.style.borderColor = colors.borderSecondary;
5467
+ e.currentTarget.style.outline = "none";
5468
+ },
5469
+ required: true,
5470
+ disabled: isLoading,
5471
+ autoComplete: "email",
5472
+ style: {
5473
+ width: "100%",
5474
+ padding: "12px 16px",
5475
+ border: `1px solid ${colors.borderSecondary}`,
5476
+ borderRadius: "8px",
5477
+ fontSize: "16px",
5478
+ boxSizing: "border-box",
5479
+ backgroundColor: colors.bgSecondary,
5480
+ color: colors.textPrimary,
5481
+ transition: "all 0.2s ease",
5482
+ WebkitTextFillColor: colors.textPrimary,
5483
+ WebkitBoxShadow: `0 0 0 1000px ${colors.bgSecondary} inset`,
5484
+ ...appearance?.elements?.formFieldInput
5485
+ },
5486
+ placeholder: "admin@example.com"
5487
+ }
5488
+ )
5489
+ ] }),
5490
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: "24px", position: "relative" }, children: [
5491
+ /* @__PURE__ */ jsx("label", { htmlFor: "password", style: {
5492
+ display: "block",
5493
+ marginBottom: "8px",
5494
+ fontWeight: 500,
5495
+ color: colors.textSecondary,
5496
+ fontSize: "14px"
5497
+ }, children: "Password" }),
5498
+ /* @__PURE__ */ jsx(
5499
+ "input",
5500
+ {
5501
+ id: "password",
5502
+ type: showPassword ? "text" : "password",
5503
+ value: password,
5504
+ onChange: (e) => setPassword(e.target.value),
5505
+ onFocus: (e) => {
5506
+ e.currentTarget.style.borderColor = colors.buttonPrimary;
5507
+ e.currentTarget.style.outline = `2px solid ${colors.buttonPrimary}40`;
5508
+ },
5509
+ onBlur: (e) => {
5510
+ e.currentTarget.style.borderColor = colors.borderSecondary;
5511
+ e.currentTarget.style.outline = "none";
5512
+ },
5513
+ required: true,
5514
+ disabled: isLoading,
5515
+ autoComplete: "current-password",
5516
+ style: {
5517
+ width: "100%",
5518
+ padding: "12px 16px",
5519
+ paddingRight: "60px",
5520
+ border: `1px solid ${colors.borderSecondary}`,
5521
+ borderRadius: "8px",
5522
+ fontSize: "16px",
5523
+ boxSizing: "border-box",
5524
+ backgroundColor: colors.bgSecondary,
5525
+ color: colors.textPrimary,
5526
+ transition: "all 0.2s ease",
5527
+ WebkitTextFillColor: colors.textPrimary,
5528
+ WebkitBoxShadow: `0 0 0 1000px ${colors.bgSecondary} inset`,
5529
+ ...appearance?.elements?.formFieldInput
5530
+ },
5531
+ placeholder: "Enter your password"
5532
+ }
5533
+ ),
5534
+ /* @__PURE__ */ jsx(
5535
+ "button",
5536
+ {
5537
+ type: "button",
5538
+ onClick: () => setShowPassword(!showPassword),
5539
+ style: {
5540
+ position: "absolute",
5541
+ right: "12px",
5542
+ top: "38px",
5543
+ background: "none",
5544
+ border: "none",
5545
+ cursor: "pointer",
5546
+ color: colors.textTertiary,
5547
+ fontSize: "14px",
5548
+ padding: "4px 8px"
5549
+ },
5550
+ children: showPassword ? "Hide" : "Show"
5551
+ }
5552
+ )
5553
+ ] }),
5554
+ /* @__PURE__ */ jsx(
5555
+ "button",
5556
+ {
5557
+ type: "submit",
5558
+ disabled: isLoading || !email || !password,
5559
+ onMouseEnter: (e) => {
5560
+ if (!isLoading && email && password) {
5561
+ e.currentTarget.style.backgroundColor = colors.buttonPrimaryHover;
5562
+ }
5563
+ },
5564
+ onMouseLeave: (e) => {
5565
+ e.currentTarget.style.backgroundColor = colors.buttonPrimary;
5566
+ },
5567
+ style: {
5568
+ width: "100%",
5569
+ padding: "14px",
5570
+ backgroundColor: colors.buttonPrimary,
5571
+ color: "white",
5572
+ border: "none",
5573
+ borderRadius: "8px",
5574
+ fontSize: "16px",
5575
+ fontWeight: 600,
5576
+ cursor: isLoading || !email || !password ? "not-allowed" : "pointer",
5577
+ opacity: isLoading || !email || !password ? 0.6 : 1,
5578
+ transition: "all 0.2s ease",
5579
+ ...appearance?.elements?.formButtonPrimary
5580
+ },
5581
+ children: isLoading ? "Signing in..." : "Sign In"
5582
+ }
5583
+ ),
5584
+ /* @__PURE__ */ jsx("div", { style: {
5585
+ marginTop: "20px",
5586
+ padding: "12px",
5587
+ backgroundColor: colors.bgSecondary,
5588
+ borderRadius: "8px",
5589
+ textAlign: "center"
5590
+ }, children: /* @__PURE__ */ jsxs("p", { style: {
5591
+ color: colors.textTertiary,
5592
+ fontSize: "12px",
5593
+ margin: 0
5594
+ }, children: [
5595
+ "\u{1F512} This portal is restricted to Super Admin users only.",
5596
+ /* @__PURE__ */ jsx("br", {}),
5597
+ "Contact your system administrator if you need access."
5598
+ ] }) })
5599
+ ] })
5600
+ }
5601
+ );
5602
+ };
5142
5603
  var AvatarManager = ({
5143
5604
  open,
5144
5605
  onOpenChange,
@@ -5242,6 +5703,7 @@ __export(react_exports, {
5242
5703
  SignIn: () => SignIn,
5243
5704
  SignOut: () => SignOut,
5244
5705
  SignUp: () => SignUp,
5706
+ SuperAdminSignIn: () => SuperAdminSignIn,
5245
5707
  UserButton: () => UserButton,
5246
5708
  UserProfile: () => UserProfile,
5247
5709
  VerifyEmail: () => VerifyEmail,
@@ -5467,6 +5929,6 @@ async function verifyToken(token) {
5467
5929
  return getTokenVerifier().verifyToken(token);
5468
5930
  }
5469
5931
 
5470
- export { AuthFlow, AuthProvider, AuthService, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, SocketService, UserButton, UserProfile, VerifyEmail, node_exports as node, react_exports as react, useAuth };
5932
+ export { AuthFlow, AuthProvider, AuthService, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, SocketService, SuperAdminSignIn, UserButton, UserProfile, VerifyEmail, node_exports as node, react_exports as react, useAuth };
5471
5933
  //# sourceMappingURL=index.mjs.map
5472
5934
  //# sourceMappingURL=index.mjs.map