@thetechfossil/auth2 1.2.7 → 1.2.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.
@@ -440,6 +440,15 @@ interface UserProfileProps {
440
440
  showAvatar?: boolean;
441
441
  showEmailChange?: boolean;
442
442
  showPasswordChange?: boolean;
443
+ upfilesConfig?: {
444
+ baseUrl: string;
445
+ apiKey?: string;
446
+ apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
447
+ presignUrl?: string;
448
+ presignPath?: string;
449
+ folderPath?: string;
450
+ projectId?: string;
451
+ };
443
452
  }
444
453
  declare const UserProfile: React.FC<UserProfileProps>;
445
454
 
@@ -469,7 +478,9 @@ interface AvatarUploaderProps {
469
478
  presignUrl?: string;
470
479
  presignPath?: string;
471
480
  folderPath?: string;
481
+ projectId?: string;
472
482
  };
483
+ buttonText?: string;
473
484
  }
474
485
  declare const AvatarUploader: React.FC<AvatarUploaderProps>;
475
486
 
@@ -5,16 +5,19 @@ var axios = require('axios');
5
5
  var upfiles = require('@thetechfossil/upfiles');
6
6
  var React3 = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
- var PhoneInputWithCountry = require('react-phone-number-input');
9
- require('react-phone-number-input/style.css');
10
8
 
11
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
10
 
13
11
  var axios__default = /*#__PURE__*/_interopDefault(axios);
14
12
  var React3__default = /*#__PURE__*/_interopDefault(React3);
15
- var PhoneInputWithCountry__default = /*#__PURE__*/_interopDefault(PhoneInputWithCountry);
16
13
 
17
- // src/core/http-client.ts
14
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
15
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
16
+ }) : x)(function(x) {
17
+ if (typeof require !== "undefined")
18
+ return require.apply(this, arguments);
19
+ throw new Error('Dynamic require of "' + x + '" is not supported');
20
+ });
18
21
  var HttpClient = class {
19
22
  constructor(baseUrl, defaultHeaders = {}) {
20
23
  this.csrfToken = null;
@@ -1027,6 +1030,14 @@ function useThemeColors() {
1027
1030
  const { theme } = useAuthTheme();
1028
1031
  return theme === "dark" ? darkTheme : lightTheme;
1029
1032
  }
1033
+ var PhoneInputWithCountry = null;
1034
+ try {
1035
+ const module = __require("react-phone-number-input");
1036
+ PhoneInputWithCountry = module.default || module;
1037
+ __require("react-phone-number-input/style.css");
1038
+ } catch (error) {
1039
+ console.warn("react-phone-number-input not available, using fallback");
1040
+ }
1030
1041
  var CustomPhoneInput = React3__default.default.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1031
1042
  "input",
1032
1043
  {
@@ -1219,6 +1230,30 @@ var PhoneInput = ({
1219
1230
  const handleChange = React3.useMemo(() => (val) => {
1220
1231
  onChange(val || "");
1221
1232
  }, [onChange]);
1233
+ if (!PhoneInputWithCountry) {
1234
+ return /* @__PURE__ */ jsxRuntime.jsx(
1235
+ "input",
1236
+ {
1237
+ id,
1238
+ type: "tel",
1239
+ value,
1240
+ onChange: (e) => onChange(e.target.value),
1241
+ disabled,
1242
+ required,
1243
+ placeholder,
1244
+ style: {
1245
+ width: "100%",
1246
+ padding: "12px 16px",
1247
+ border: `1px solid ${colors.borderSecondary}`,
1248
+ borderRadius: "8px",
1249
+ fontSize: "16px",
1250
+ backgroundColor: colors.bgSecondary,
1251
+ color: colors.textPrimary,
1252
+ ...style
1253
+ }
1254
+ }
1255
+ );
1256
+ }
1222
1257
  return /* @__PURE__ */ jsxRuntime.jsxs(
1223
1258
  "div",
1224
1259
  {
@@ -1229,7 +1264,7 @@ var PhoneInput = ({
1229
1264
  children: [
1230
1265
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: styleContent }),
1231
1266
  /* @__PURE__ */ jsxRuntime.jsx(
1232
- PhoneInputWithCountry__default.default,
1267
+ PhoneInputWithCountry,
1233
1268
  {
1234
1269
  id,
1235
1270
  international: true,
@@ -4437,15 +4472,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4437
4472
  )
4438
4473
  ] }) });
4439
4474
  };
4475
+ var AvatarUploader = ({
4476
+ onUploadComplete,
4477
+ onError,
4478
+ className,
4479
+ buttonClassName,
4480
+ maxFileSize = 5 * 1024 * 1024,
4481
+ // 5MB default
4482
+ upfilesConfig,
4483
+ buttonText = "Upload Avatar"
4484
+ }) => {
4485
+ const { uploadAndUpdateAvatar } = useAuth2();
4486
+ const [open, setOpen] = React3.useState(false);
4487
+ const [uploading, setUploading] = React3.useState(false);
4488
+ const handleSelect = async (image) => {
4489
+ setUploading(true);
4490
+ try {
4491
+ const response = await fetch(image.url);
4492
+ const blob = await response.blob();
4493
+ const file = new File([blob], image.originalName, { type: image.contentType });
4494
+ const result = await uploadAndUpdateAvatar(file);
4495
+ if (result.success && result.user?.avatar) {
4496
+ onUploadComplete?.(result.user.avatar);
4497
+ setOpen(false);
4498
+ } else {
4499
+ throw new Error(result.message || "Failed to update avatar");
4500
+ }
4501
+ } catch (error) {
4502
+ const err = error instanceof Error ? error : new Error("Upload failed");
4503
+ onError?.(err);
4504
+ } finally {
4505
+ setUploading(false);
4506
+ }
4507
+ };
4508
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
4509
+ /* @__PURE__ */ jsxRuntime.jsx(
4510
+ "button",
4511
+ {
4512
+ type: "button",
4513
+ onClick: () => setOpen(true),
4514
+ disabled: uploading,
4515
+ className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
4516
+ children: uploading ? "Uploading..." : buttonText
4517
+ }
4518
+ ),
4519
+ /* @__PURE__ */ jsxRuntime.jsx(
4520
+ upfiles.ImageManager,
4521
+ {
4522
+ open,
4523
+ onOpenChange: setOpen,
4524
+ clientOptions: {
4525
+ baseUrl: upfilesConfig.baseUrl,
4526
+ apiKey: upfilesConfig.apiKey,
4527
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4528
+ presignUrl: upfilesConfig.presignUrl,
4529
+ presignPath: upfilesConfig.presignPath
4530
+ },
4531
+ projectId: upfilesConfig.projectId,
4532
+ folderPath: upfilesConfig.folderPath || "avatars/",
4533
+ title: "Select Avatar",
4534
+ description: "Upload a new avatar or select from existing images.",
4535
+ mode: "full",
4536
+ maxFileSize,
4537
+ maxFiles: 1,
4538
+ autoRecordToDb: true,
4539
+ fetchThumbnails: true,
4540
+ onSelect: handleSelect
4541
+ }
4542
+ )
4543
+ ] });
4544
+ };
4440
4545
  var UserProfile = ({
4441
4546
  showAvatar = true,
4442
4547
  showEmailChange = true,
4443
- showPasswordChange = true
4548
+ showPasswordChange = true,
4549
+ upfilesConfig
4444
4550
  }) => {
4445
4551
  const { user, updateProfile, requestEmailChange } = useAuth2();
4446
4552
  const colors = useThemeColors();
4447
4553
  const [name, setName] = React3.useState(user?.name || "");
4448
- const [avatar, setAvatar] = React3.useState(user?.avatar || "");
4449
4554
  const [phoneNumber, setPhoneNumber] = React3.useState(user?.phoneNumber || "");
4450
4555
  const [newEmail, setNewEmail] = React3.useState("");
4451
4556
  const [isLoading, setIsLoading] = React3.useState(false);
@@ -4461,9 +4566,6 @@ var UserProfile = ({
4461
4566
  if (name !== user?.name) {
4462
4567
  updates.name = name;
4463
4568
  }
4464
- if (showAvatar && avatar !== user?.avatar) {
4465
- updates.avatar = avatar;
4466
- }
4467
4569
  if (phoneNumber !== user?.phoneNumber) {
4468
4570
  updates.phoneNumber = phoneNumber;
4469
4571
  }
@@ -4484,6 +4586,12 @@ var UserProfile = ({
4484
4586
  setIsLoading(false);
4485
4587
  }
4486
4588
  };
4589
+ const handleAvatarUploadComplete = (avatarUrl) => {
4590
+ setSuccess("Avatar updated successfully!");
4591
+ };
4592
+ const handleAvatarUploadError = (error2) => {
4593
+ setError(error2.message || "Failed to upload avatar");
4594
+ };
4487
4595
  const handleRequestEmailChange = async (e) => {
4488
4596
  e.preventDefault();
4489
4597
  setIsLoading(true);
@@ -4586,34 +4694,36 @@ var UserProfile = ({
4586
4694
  }
4587
4695
  )
4588
4696
  ] }),
4589
- showAvatar && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
4590
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "avatar", style: {
4697
+ showAvatar && upfilesConfig && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
4698
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: {
4591
4699
  display: "block",
4592
4700
  marginBottom: "8px",
4593
4701
  fontWeight: 500,
4594
4702
  color: colors.textSecondary,
4595
4703
  fontSize: "14px"
4596
- }, children: "Avatar URL" }),
4597
- /* @__PURE__ */ jsxRuntime.jsx(
4598
- "input",
4704
+ }, children: "Avatar" }),
4705
+ user?.avatar && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
4706
+ "img",
4599
4707
  {
4600
- id: "avatar",
4601
- type: "url",
4602
- value: avatar,
4603
- onChange: (e) => setAvatar(e.target.value),
4604
- disabled: isLoading,
4708
+ src: user.avatar,
4709
+ alt: "Current avatar",
4605
4710
  style: {
4606
- width: "100%",
4607
- padding: "12px 16px",
4608
- border: `1px solid ${colors.borderSecondary}`,
4609
- borderRadius: "8px",
4610
- fontSize: "16px",
4611
- boxSizing: "border-box",
4612
- backgroundColor: colors.bgSecondary,
4613
- color: colors.textPrimary,
4614
- transition: "all 0.2s ease"
4615
- },
4616
- placeholder: "https://example.com/avatar.jpg"
4711
+ width: "80px",
4712
+ height: "80px",
4713
+ borderRadius: "50%",
4714
+ objectFit: "cover",
4715
+ border: `2px solid ${colors.borderSecondary}`
4716
+ }
4717
+ }
4718
+ ) }),
4719
+ /* @__PURE__ */ jsxRuntime.jsx(
4720
+ AvatarUploader,
4721
+ {
4722
+ upfilesConfig,
4723
+ onUploadComplete: handleAvatarUploadComplete,
4724
+ onError: handleAvatarUploadError,
4725
+ maxFileSize: 5 * 1024 * 1024,
4726
+ accept: ["image/*"]
4617
4727
  }
4618
4728
  )
4619
4729
  ] }),
@@ -4725,63 +4835,6 @@ var UserProfile = ({
4725
4835
  ] })
4726
4836
  ] });
4727
4837
  };
4728
- var AvatarUploader = ({
4729
- onUploadComplete,
4730
- onError,
4731
- className,
4732
- buttonClassName,
4733
- dropzoneClassName,
4734
- maxFileSize = 5 * 1024 * 1024,
4735
- // 5MB default
4736
- accept = ["image/*"],
4737
- upfilesConfig
4738
- }) => {
4739
- const { uploadAndUpdateAvatar } = useAuth2();
4740
- const [uploading, setUploading] = React3.useState(false);
4741
- const handleUploadComplete = async (files) => {
4742
- if (files.length === 0)
4743
- return;
4744
- setUploading(true);
4745
- try {
4746
- const file = files[0];
4747
- const response = await uploadAndUpdateAvatar(file.file);
4748
- if (response.success && response.user?.avatar) {
4749
- onUploadComplete?.(response.user.avatar);
4750
- } else {
4751
- throw new Error(response.message || "Failed to update avatar");
4752
- }
4753
- } catch (error) {
4754
- const err = error instanceof Error ? error : new Error("Upload failed");
4755
- onError?.(err);
4756
- } finally {
4757
- setUploading(false);
4758
- }
4759
- };
4760
- const handleError = (error) => {
4761
- onError?.(error);
4762
- };
4763
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
4764
- upfiles.Uploader,
4765
- {
4766
- clientOptions: {
4767
- baseUrl: upfilesConfig.baseUrl,
4768
- apiKey: upfilesConfig.apiKey,
4769
- apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4770
- presignUrl: upfilesConfig.presignUrl,
4771
- presignPath: upfilesConfig.presignPath
4772
- },
4773
- multiple: false,
4774
- accept,
4775
- maxFileSize,
4776
- maxFiles: 1,
4777
- onComplete: handleUploadComplete,
4778
- onError: handleError,
4779
- buttonClassName,
4780
- dropzoneClassName,
4781
- children: uploading ? "Uploading..." : "Upload Avatar"
4782
- }
4783
- ) });
4784
- };
4785
4838
  var AvatarManager = ({
4786
4839
  open,
4787
4840
  onOpenChange,