@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.
package/dist/index.d.ts CHANGED
@@ -414,6 +414,15 @@ interface UserProfileProps {
414
414
  showAvatar?: boolean;
415
415
  showEmailChange?: boolean;
416
416
  showPasswordChange?: boolean;
417
+ upfilesConfig?: {
418
+ baseUrl: string;
419
+ apiKey?: string;
420
+ apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
421
+ presignUrl?: string;
422
+ presignPath?: string;
423
+ folderPath?: string;
424
+ projectId?: string;
425
+ };
417
426
  }
418
427
  declare const UserProfile: React.FC<UserProfileProps>;
419
428
 
@@ -443,7 +452,9 @@ interface AvatarUploaderProps {
443
452
  presignUrl?: string;
444
453
  presignPath?: string;
445
454
  folderPath?: string;
455
+ projectId?: string;
446
456
  };
457
+ buttonText?: string;
447
458
  }
448
459
  declare const AvatarUploader: React.FC<AvatarUploaderProps>;
449
460
 
package/dist/index.js CHANGED
@@ -5,16 +5,20 @@ 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
14
  var __defProp = Object.defineProperty;
15
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
16
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
17
+ }) : x)(function(x) {
18
+ if (typeof require !== "undefined")
19
+ return require.apply(this, arguments);
20
+ throw new Error('Dynamic require of "' + x + '" is not supported');
21
+ });
18
22
  var __export = (target, all) => {
19
23
  for (var name in all)
20
24
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -1031,6 +1035,14 @@ function useThemeColors() {
1031
1035
  const { theme } = useAuthTheme();
1032
1036
  return theme === "dark" ? darkTheme : lightTheme;
1033
1037
  }
1038
+ var PhoneInputWithCountry = null;
1039
+ try {
1040
+ const module = __require("react-phone-number-input");
1041
+ PhoneInputWithCountry = module.default || module;
1042
+ __require("react-phone-number-input/style.css");
1043
+ } catch (error) {
1044
+ console.warn("react-phone-number-input not available, using fallback");
1045
+ }
1034
1046
  var CustomPhoneInput = React3__default.default.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1035
1047
  "input",
1036
1048
  {
@@ -1223,6 +1235,30 @@ var PhoneInput = ({
1223
1235
  const handleChange = React3.useMemo(() => (val) => {
1224
1236
  onChange(val || "");
1225
1237
  }, [onChange]);
1238
+ if (!PhoneInputWithCountry) {
1239
+ return /* @__PURE__ */ jsxRuntime.jsx(
1240
+ "input",
1241
+ {
1242
+ id,
1243
+ type: "tel",
1244
+ value,
1245
+ onChange: (e) => onChange(e.target.value),
1246
+ disabled,
1247
+ required,
1248
+ placeholder,
1249
+ style: {
1250
+ width: "100%",
1251
+ padding: "12px 16px",
1252
+ border: `1px solid ${colors.borderSecondary}`,
1253
+ borderRadius: "8px",
1254
+ fontSize: "16px",
1255
+ backgroundColor: colors.bgSecondary,
1256
+ color: colors.textPrimary,
1257
+ ...style
1258
+ }
1259
+ }
1260
+ );
1261
+ }
1226
1262
  return /* @__PURE__ */ jsxRuntime.jsxs(
1227
1263
  "div",
1228
1264
  {
@@ -1233,7 +1269,7 @@ var PhoneInput = ({
1233
1269
  children: [
1234
1270
  /* @__PURE__ */ jsxRuntime.jsx("style", { children: styleContent }),
1235
1271
  /* @__PURE__ */ jsxRuntime.jsx(
1236
- PhoneInputWithCountry__default.default,
1272
+ PhoneInputWithCountry,
1237
1273
  {
1238
1274
  id,
1239
1275
  international: true,
@@ -4441,15 +4477,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4441
4477
  )
4442
4478
  ] }) });
4443
4479
  };
4480
+ var AvatarUploader = ({
4481
+ onUploadComplete,
4482
+ onError,
4483
+ className,
4484
+ buttonClassName,
4485
+ maxFileSize = 5 * 1024 * 1024,
4486
+ // 5MB default
4487
+ upfilesConfig,
4488
+ buttonText = "Upload Avatar"
4489
+ }) => {
4490
+ const { uploadAndUpdateAvatar } = useAuth();
4491
+ const [open, setOpen] = React3.useState(false);
4492
+ const [uploading, setUploading] = React3.useState(false);
4493
+ const handleSelect = async (image) => {
4494
+ setUploading(true);
4495
+ try {
4496
+ const response = await fetch(image.url);
4497
+ const blob = await response.blob();
4498
+ const file = new File([blob], image.originalName, { type: image.contentType });
4499
+ const result = await uploadAndUpdateAvatar(file);
4500
+ if (result.success && result.user?.avatar) {
4501
+ onUploadComplete?.(result.user.avatar);
4502
+ setOpen(false);
4503
+ } else {
4504
+ throw new Error(result.message || "Failed to update avatar");
4505
+ }
4506
+ } catch (error) {
4507
+ const err = error instanceof Error ? error : new Error("Upload failed");
4508
+ onError?.(err);
4509
+ } finally {
4510
+ setUploading(false);
4511
+ }
4512
+ };
4513
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
4514
+ /* @__PURE__ */ jsxRuntime.jsx(
4515
+ "button",
4516
+ {
4517
+ type: "button",
4518
+ onClick: () => setOpen(true),
4519
+ disabled: uploading,
4520
+ className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
4521
+ children: uploading ? "Uploading..." : buttonText
4522
+ }
4523
+ ),
4524
+ /* @__PURE__ */ jsxRuntime.jsx(
4525
+ upfiles.ImageManager,
4526
+ {
4527
+ open,
4528
+ onOpenChange: setOpen,
4529
+ clientOptions: {
4530
+ baseUrl: upfilesConfig.baseUrl,
4531
+ apiKey: upfilesConfig.apiKey,
4532
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4533
+ presignUrl: upfilesConfig.presignUrl,
4534
+ presignPath: upfilesConfig.presignPath
4535
+ },
4536
+ projectId: upfilesConfig.projectId,
4537
+ folderPath: upfilesConfig.folderPath || "avatars/",
4538
+ title: "Select Avatar",
4539
+ description: "Upload a new avatar or select from existing images.",
4540
+ mode: "full",
4541
+ maxFileSize,
4542
+ maxFiles: 1,
4543
+ autoRecordToDb: true,
4544
+ fetchThumbnails: true,
4545
+ onSelect: handleSelect
4546
+ }
4547
+ )
4548
+ ] });
4549
+ };
4444
4550
  var UserProfile = ({
4445
4551
  showAvatar = true,
4446
4552
  showEmailChange = true,
4447
- showPasswordChange = true
4553
+ showPasswordChange = true,
4554
+ upfilesConfig
4448
4555
  }) => {
4449
4556
  const { user, updateProfile, requestEmailChange } = useAuth();
4450
4557
  const colors = useThemeColors();
4451
4558
  const [name, setName] = React3.useState(user?.name || "");
4452
- const [avatar, setAvatar] = React3.useState(user?.avatar || "");
4453
4559
  const [phoneNumber, setPhoneNumber] = React3.useState(user?.phoneNumber || "");
4454
4560
  const [newEmail, setNewEmail] = React3.useState("");
4455
4561
  const [isLoading, setIsLoading] = React3.useState(false);
@@ -4465,9 +4571,6 @@ var UserProfile = ({
4465
4571
  if (name !== user?.name) {
4466
4572
  updates.name = name;
4467
4573
  }
4468
- if (showAvatar && avatar !== user?.avatar) {
4469
- updates.avatar = avatar;
4470
- }
4471
4574
  if (phoneNumber !== user?.phoneNumber) {
4472
4575
  updates.phoneNumber = phoneNumber;
4473
4576
  }
@@ -4488,6 +4591,12 @@ var UserProfile = ({
4488
4591
  setIsLoading(false);
4489
4592
  }
4490
4593
  };
4594
+ const handleAvatarUploadComplete = (avatarUrl) => {
4595
+ setSuccess("Avatar updated successfully!");
4596
+ };
4597
+ const handleAvatarUploadError = (error2) => {
4598
+ setError(error2.message || "Failed to upload avatar");
4599
+ };
4491
4600
  const handleRequestEmailChange = async (e) => {
4492
4601
  e.preventDefault();
4493
4602
  setIsLoading(true);
@@ -4590,34 +4699,36 @@ var UserProfile = ({
4590
4699
  }
4591
4700
  )
4592
4701
  ] }),
4593
- showAvatar && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
4594
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "avatar", style: {
4702
+ showAvatar && upfilesConfig && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
4703
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: {
4595
4704
  display: "block",
4596
4705
  marginBottom: "8px",
4597
4706
  fontWeight: 500,
4598
4707
  color: colors.textSecondary,
4599
4708
  fontSize: "14px"
4600
- }, children: "Avatar URL" }),
4601
- /* @__PURE__ */ jsxRuntime.jsx(
4602
- "input",
4709
+ }, children: "Avatar" }),
4710
+ user?.avatar && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
4711
+ "img",
4603
4712
  {
4604
- id: "avatar",
4605
- type: "url",
4606
- value: avatar,
4607
- onChange: (e) => setAvatar(e.target.value),
4608
- disabled: isLoading,
4713
+ src: user.avatar,
4714
+ alt: "Current avatar",
4609
4715
  style: {
4610
- width: "100%",
4611
- padding: "12px 16px",
4612
- border: `1px solid ${colors.borderSecondary}`,
4613
- borderRadius: "8px",
4614
- fontSize: "16px",
4615
- boxSizing: "border-box",
4616
- backgroundColor: colors.bgSecondary,
4617
- color: colors.textPrimary,
4618
- transition: "all 0.2s ease"
4619
- },
4620
- placeholder: "https://example.com/avatar.jpg"
4716
+ width: "80px",
4717
+ height: "80px",
4718
+ borderRadius: "50%",
4719
+ objectFit: "cover",
4720
+ border: `2px solid ${colors.borderSecondary}`
4721
+ }
4722
+ }
4723
+ ) }),
4724
+ /* @__PURE__ */ jsxRuntime.jsx(
4725
+ AvatarUploader,
4726
+ {
4727
+ upfilesConfig,
4728
+ onUploadComplete: handleAvatarUploadComplete,
4729
+ onError: handleAvatarUploadError,
4730
+ maxFileSize: 5 * 1024 * 1024,
4731
+ accept: ["image/*"]
4621
4732
  }
4622
4733
  )
4623
4734
  ] }),
@@ -4729,63 +4840,6 @@ var UserProfile = ({
4729
4840
  ] })
4730
4841
  ] });
4731
4842
  };
4732
- var AvatarUploader = ({
4733
- onUploadComplete,
4734
- onError,
4735
- className,
4736
- buttonClassName,
4737
- dropzoneClassName,
4738
- maxFileSize = 5 * 1024 * 1024,
4739
- // 5MB default
4740
- accept = ["image/*"],
4741
- upfilesConfig
4742
- }) => {
4743
- const { uploadAndUpdateAvatar } = useAuth();
4744
- const [uploading, setUploading] = React3.useState(false);
4745
- const handleUploadComplete = async (files) => {
4746
- if (files.length === 0)
4747
- return;
4748
- setUploading(true);
4749
- try {
4750
- const file = files[0];
4751
- const response = await uploadAndUpdateAvatar(file.file);
4752
- if (response.success && response.user?.avatar) {
4753
- onUploadComplete?.(response.user.avatar);
4754
- } else {
4755
- throw new Error(response.message || "Failed to update avatar");
4756
- }
4757
- } catch (error) {
4758
- const err = error instanceof Error ? error : new Error("Upload failed");
4759
- onError?.(err);
4760
- } finally {
4761
- setUploading(false);
4762
- }
4763
- };
4764
- const handleError = (error) => {
4765
- onError?.(error);
4766
- };
4767
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
4768
- upfiles.Uploader,
4769
- {
4770
- clientOptions: {
4771
- baseUrl: upfilesConfig.baseUrl,
4772
- apiKey: upfilesConfig.apiKey,
4773
- apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4774
- presignUrl: upfilesConfig.presignUrl,
4775
- presignPath: upfilesConfig.presignPath
4776
- },
4777
- multiple: false,
4778
- accept,
4779
- maxFileSize,
4780
- maxFiles: 1,
4781
- onComplete: handleUploadComplete,
4782
- onError: handleError,
4783
- buttonClassName,
4784
- dropzoneClassName,
4785
- children: uploading ? "Uploading..." : "Upload Avatar"
4786
- }
4787
- ) });
4788
- };
4789
4843
  var AvatarManager = ({
4790
4844
  open,
4791
4845
  onOpenChange,