@thetechfossil/auth2 1.2.15 → 1.2.17

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.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import React2, { createContext, forwardRef, useContext, useState, useMemo, useEffect, useRef, useCallback } from 'react';
2
+ import React, { createContext, forwardRef, useContext, useState, useMemo, useEffect, useRef, useCallback } from 'react';
3
3
  import axios from 'axios';
4
4
  import { ImageManager, UpfilesClient } from '@thetechfossil/upfiles';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -62,6 +62,11 @@ var HttpClient = class {
62
62
  return Promise.reject(refreshError);
63
63
  }
64
64
  }
65
+ if (error.response && error.response.data && error.response.data.message) {
66
+ const customError = new Error(error.response.data.message);
67
+ customError.response = error.response;
68
+ return Promise.reject(customError);
69
+ }
65
70
  return Promise.reject(error);
66
71
  }
67
72
  );
@@ -643,7 +648,7 @@ var useAuth = (config) => {
643
648
  uploadAndUpdateAvatar
644
649
  };
645
650
  };
646
- var ThemeContext = createContext({ theme: "light", mounted: false });
651
+ var ThemeContext = React.createContext({ theme: "light", mounted: false });
647
652
  function useAuthTheme() {
648
653
  return useContext(ThemeContext);
649
654
  }
@@ -697,7 +702,7 @@ try {
697
702
  } catch (error) {
698
703
  console.warn("react-phone-number-input not available, using fallback");
699
704
  }
700
- var CustomPhoneInput = React2.forwardRef((props, ref) => /* @__PURE__ */ jsx(
705
+ var CustomPhoneInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(
701
706
  "input",
702
707
  {
703
708
  ...props,
@@ -3184,7 +3189,19 @@ var UserButton = ({ showName = false, appearance }) => {
3184
3189
  e.currentTarget.style.backgroundColor = "transparent";
3185
3190
  },
3186
3191
  children: [
3187
- /* @__PURE__ */ jsx("div", { style: {
3192
+ user.avatar ? /* @__PURE__ */ jsx(
3193
+ "img",
3194
+ {
3195
+ src: user.avatar,
3196
+ alt: user.name,
3197
+ style: {
3198
+ width: "36px",
3199
+ height: "36px",
3200
+ borderRadius: "50%",
3201
+ objectFit: "cover"
3202
+ }
3203
+ }
3204
+ ) : /* @__PURE__ */ jsx("div", { style: {
3188
3205
  width: "36px",
3189
3206
  height: "36px",
3190
3207
  borderRadius: "50%",
@@ -3221,7 +3238,19 @@ var UserButton = ({ showName = false, appearance }) => {
3221
3238
  alignItems: "center",
3222
3239
  gap: "12px"
3223
3240
  }, children: [
3224
- /* @__PURE__ */ jsx("div", { style: {
3241
+ user.avatar ? /* @__PURE__ */ jsx(
3242
+ "img",
3243
+ {
3244
+ src: user.avatar,
3245
+ alt: user.name,
3246
+ style: {
3247
+ width: "48px",
3248
+ height: "48px",
3249
+ borderRadius: "50%",
3250
+ objectFit: "cover"
3251
+ }
3252
+ }
3253
+ ) : /* @__PURE__ */ jsx("div", { style: {
3225
3254
  width: "48px",
3226
3255
  height: "48px",
3227
3256
  borderRadius: "50%",
@@ -4101,6 +4130,68 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4101
4130
  )
4102
4131
  ] }) });
4103
4132
  };
4133
+
4134
+ // src/react/components/utils/injectModalStyles.ts
4135
+ var injectModalStyles = () => {
4136
+ if (document.getElementById("ttf-auth-modal-styles")) {
4137
+ return;
4138
+ }
4139
+ const styleElement = document.createElement("style");
4140
+ styleElement.id = "ttf-auth-modal-styles";
4141
+ styleElement.textContent = `
4142
+ /* ImageManager Modal Styles - Critical for proper modal display */
4143
+ /* Radix UI Dialog styles - Force visibility */
4144
+ [data-radix-portal] {
4145
+ z-index: 99999 !important;
4146
+ position: fixed !important;
4147
+ inset: 0 !important;
4148
+ pointer-events: none !important;
4149
+ }
4150
+
4151
+ [data-radix-portal] > * {
4152
+ pointer-events: auto !important;
4153
+ }
4154
+
4155
+ /* Dialog Overlay */
4156
+ [data-state="open"][data-radix-dialog-overlay],
4157
+ [role="dialog"] + [data-radix-dialog-overlay] {
4158
+ position: fixed !important;
4159
+ inset: 0 !important;
4160
+ z-index: 99998 !important;
4161
+ background-color: rgba(0, 0, 0, 0.6) !important;
4162
+ pointer-events: auto !important;
4163
+ }
4164
+
4165
+ /* Dialog Content - Center the modal properly */
4166
+ [data-state="open"][data-radix-dialog-content],
4167
+ [role="dialog"][data-radix-dialog-content] {
4168
+ position: fixed !important;
4169
+ left: 50% !important;
4170
+ top: 50% !important;
4171
+ transform: translate(-50%, -50%) !important;
4172
+ z-index: 99999 !important;
4173
+ background: white !important;
4174
+ border-radius: 16px !important;
4175
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
4176
+ pointer-events: auto !important;
4177
+ width: 95vw !important;
4178
+ max-width: 1280px !important;
4179
+ height: 90vh !important;
4180
+ max-height: 90vh !important;
4181
+ min-width: 800px !important;
4182
+ min-height: 600px !important;
4183
+ overflow: hidden !important;
4184
+ }
4185
+
4186
+ /* Dark mode support */
4187
+ .dark [data-state="open"][data-radix-dialog-content],
4188
+ .dark [role="dialog"][data-radix-dialog-content] {
4189
+ background: #0f172a !important;
4190
+ border: 1px solid #334155 !important;
4191
+ }
4192
+ `;
4193
+ document.head.appendChild(styleElement);
4194
+ };
4104
4195
  var AvatarUploader = ({
4105
4196
  onUploadComplete,
4106
4197
  onError,
@@ -4111,32 +4202,30 @@ var AvatarUploader = ({
4111
4202
  upfilesConfig,
4112
4203
  buttonText = "Upload Avatar"
4113
4204
  }) => {
4114
- const { uploadAndUpdateAvatar } = useAuth2();
4205
+ const { user, updateProfile } = useAuth2();
4115
4206
  const [open, setOpen] = useState(false);
4116
4207
  const [uploading, setUploading] = useState(false);
4208
+ useEffect(() => {
4209
+ injectModalStyles();
4210
+ }, []);
4211
+ const effectiveFolderPath = useMemo(() => {
4212
+ if (user?.id) {
4213
+ return `users/${user.id}/`;
4214
+ }
4215
+ return upfilesConfig.folderPath || "/";
4216
+ }, [user?.id, upfilesConfig.folderPath]);
4117
4217
  const handleSelect = async (image) => {
4118
4218
  setUploading(true);
4119
4219
  try {
4120
- const proxyUrl = `${upfilesConfig.baseUrl}/api/download?fileKey=${encodeURIComponent(image.key)}`;
4121
- const response = await fetch(proxyUrl, {
4122
- headers: upfilesConfig.apiKey ? {
4123
- [upfilesConfig.apiKeyHeader || "authorization"]: upfilesConfig.apiKey.startsWith("upk_") ? `Bearer ${upfilesConfig.apiKey}` : upfilesConfig.apiKey
4124
- } : {}
4125
- });
4126
- if (!response.ok) {
4127
- throw new Error("Failed to fetch image");
4128
- }
4129
- const blob = await response.blob();
4130
- const file = new File([blob], image.originalName, { type: image.contentType });
4131
- const result = await uploadAndUpdateAvatar(file);
4132
- if (result.success && result.user?.avatar) {
4133
- onUploadComplete?.(result.user.avatar);
4220
+ const response = await updateProfile({ avatar: image.url });
4221
+ if (response.success && response.user?.avatar) {
4222
+ onUploadComplete?.(response.user.avatar);
4134
4223
  setOpen(false);
4135
4224
  } else {
4136
- throw new Error(result.message || "Failed to update avatar");
4225
+ throw new Error(response.message || "Failed to update avatar");
4137
4226
  }
4138
4227
  } catch (error) {
4139
- const err = error instanceof Error ? error : new Error("Upload failed");
4228
+ const err = error instanceof Error ? error : new Error("Failed to update avatar");
4140
4229
  onError?.(err);
4141
4230
  } finally {
4142
4231
  setUploading(false);
@@ -4166,7 +4255,7 @@ var AvatarUploader = ({
4166
4255
  presignPath: upfilesConfig.presignPath
4167
4256
  },
4168
4257
  projectId: upfilesConfig.projectId,
4169
- folderPath: upfilesConfig.folderPath || "avatars/",
4258
+ folderPath: effectiveFolderPath,
4170
4259
  title: "Select Avatar",
4171
4260
  description: "Upload a new avatar or select from existing images.",
4172
4261
  mode: "full",
@@ -4483,12 +4572,27 @@ var AvatarManager = ({
4483
4572
  gridClassName,
4484
4573
  maxFileSize = 5 * 1024 * 1024,
4485
4574
  // 5MB default
4575
+ maxFiles = 10,
4486
4576
  mode = "full",
4487
4577
  showDelete = false,
4578
+ autoRecordToDb = true,
4579
+ fetchThumbnails = true,
4580
+ projectId,
4581
+ deleteUrl,
4582
+ onDelete,
4488
4583
  upfilesConfig
4489
4584
  }) => {
4490
- const { updateProfile } = useAuth2();
4585
+ const { user, updateProfile } = useAuth2();
4491
4586
  const [updating, setUpdating] = useState(false);
4587
+ useEffect(() => {
4588
+ injectModalStyles();
4589
+ }, []);
4590
+ const effectiveFolderPath = useMemo(() => {
4591
+ if (user?.id) {
4592
+ return `users/${user.id}/`;
4593
+ }
4594
+ return upfilesConfig.folderPath || "/";
4595
+ }, [user?.id, upfilesConfig.folderPath]);
4492
4596
  const handleSelect = async (image) => {
4493
4597
  setUpdating(true);
4494
4598
  try {
@@ -4516,18 +4620,25 @@ var AvatarManager = ({
4516
4620
  apiKey: upfilesConfig.apiKey,
4517
4621
  apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4518
4622
  presignUrl: upfilesConfig.presignUrl,
4519
- presignPath: upfilesConfig.presignPath
4623
+ presignPath: upfilesConfig.presignPath,
4624
+ headers: upfilesConfig.headers,
4625
+ withCredentials: upfilesConfig.withCredentials
4520
4626
  },
4521
- folderPath: upfilesConfig.folderPath || "avatars/",
4627
+ projectId,
4628
+ folderPath: effectiveFolderPath,
4522
4629
  title,
4523
4630
  description,
4524
4631
  className,
4525
4632
  gridClassName,
4526
4633
  onSelect: handleSelect,
4634
+ onDelete,
4635
+ deleteUrl,
4636
+ autoRecordToDb,
4637
+ fetchThumbnails,
4527
4638
  maxFileSize,
4639
+ maxFiles,
4528
4640
  mode,
4529
- showDelete,
4530
- fetchThumbnails: true
4641
+ showDelete
4531
4642
  }
4532
4643
  );
4533
4644
  };