@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.
@@ -1,12 +1,16 @@
1
1
  "use client";
2
2
  import axios from 'axios';
3
- import { UpfilesClient, Uploader, ImageManager } from '@thetechfossil/upfiles';
3
+ import { UpfilesClient, ImageManager } from '@thetechfossil/upfiles';
4
4
  import React3, { createContext, forwardRef, useState, useCallback, useEffect, useContext, useMemo, useRef } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import PhoneInputWithCountry from 'react-phone-number-input';
7
- import 'react-phone-number-input/style.css';
8
6
 
9
- // src/core/http-client.ts
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined")
11
+ return require.apply(this, arguments);
12
+ throw new Error('Dynamic require of "' + x + '" is not supported');
13
+ });
10
14
  var HttpClient = class {
11
15
  constructor(baseUrl, defaultHeaders = {}) {
12
16
  this.csrfToken = null;
@@ -1019,6 +1023,14 @@ function useThemeColors() {
1019
1023
  const { theme } = useAuthTheme();
1020
1024
  return theme === "dark" ? darkTheme : lightTheme;
1021
1025
  }
1026
+ var PhoneInputWithCountry = null;
1027
+ try {
1028
+ const module = __require("react-phone-number-input");
1029
+ PhoneInputWithCountry = module.default || module;
1030
+ __require("react-phone-number-input/style.css");
1031
+ } catch (error) {
1032
+ console.warn("react-phone-number-input not available, using fallback");
1033
+ }
1022
1034
  var CustomPhoneInput = React3.forwardRef((props, ref) => /* @__PURE__ */ jsx(
1023
1035
  "input",
1024
1036
  {
@@ -1211,6 +1223,30 @@ var PhoneInput = ({
1211
1223
  const handleChange = useMemo(() => (val) => {
1212
1224
  onChange(val || "");
1213
1225
  }, [onChange]);
1226
+ if (!PhoneInputWithCountry) {
1227
+ return /* @__PURE__ */ jsx(
1228
+ "input",
1229
+ {
1230
+ id,
1231
+ type: "tel",
1232
+ value,
1233
+ onChange: (e) => onChange(e.target.value),
1234
+ disabled,
1235
+ required,
1236
+ placeholder,
1237
+ style: {
1238
+ width: "100%",
1239
+ padding: "12px 16px",
1240
+ border: `1px solid ${colors.borderSecondary}`,
1241
+ borderRadius: "8px",
1242
+ fontSize: "16px",
1243
+ backgroundColor: colors.bgSecondary,
1244
+ color: colors.textPrimary,
1245
+ ...style
1246
+ }
1247
+ }
1248
+ );
1249
+ }
1214
1250
  return /* @__PURE__ */ jsxs(
1215
1251
  "div",
1216
1252
  {
@@ -4429,15 +4465,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4429
4465
  )
4430
4466
  ] }) });
4431
4467
  };
4468
+ var AvatarUploader = ({
4469
+ onUploadComplete,
4470
+ onError,
4471
+ className,
4472
+ buttonClassName,
4473
+ maxFileSize = 5 * 1024 * 1024,
4474
+ // 5MB default
4475
+ upfilesConfig,
4476
+ buttonText = "Upload Avatar"
4477
+ }) => {
4478
+ const { uploadAndUpdateAvatar } = useAuth2();
4479
+ const [open, setOpen] = useState(false);
4480
+ const [uploading, setUploading] = useState(false);
4481
+ const handleSelect = async (image) => {
4482
+ setUploading(true);
4483
+ try {
4484
+ const response = await fetch(image.url);
4485
+ const blob = await response.blob();
4486
+ const file = new File([blob], image.originalName, { type: image.contentType });
4487
+ const result = await uploadAndUpdateAvatar(file);
4488
+ if (result.success && result.user?.avatar) {
4489
+ onUploadComplete?.(result.user.avatar);
4490
+ setOpen(false);
4491
+ } else {
4492
+ throw new Error(result.message || "Failed to update avatar");
4493
+ }
4494
+ } catch (error) {
4495
+ const err = error instanceof Error ? error : new Error("Upload failed");
4496
+ onError?.(err);
4497
+ } finally {
4498
+ setUploading(false);
4499
+ }
4500
+ };
4501
+ return /* @__PURE__ */ jsxs("div", { className, children: [
4502
+ /* @__PURE__ */ jsx(
4503
+ "button",
4504
+ {
4505
+ type: "button",
4506
+ onClick: () => setOpen(true),
4507
+ disabled: uploading,
4508
+ className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
4509
+ children: uploading ? "Uploading..." : buttonText
4510
+ }
4511
+ ),
4512
+ /* @__PURE__ */ jsx(
4513
+ ImageManager,
4514
+ {
4515
+ open,
4516
+ onOpenChange: setOpen,
4517
+ clientOptions: {
4518
+ baseUrl: upfilesConfig.baseUrl,
4519
+ apiKey: upfilesConfig.apiKey,
4520
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4521
+ presignUrl: upfilesConfig.presignUrl,
4522
+ presignPath: upfilesConfig.presignPath
4523
+ },
4524
+ projectId: upfilesConfig.projectId,
4525
+ folderPath: upfilesConfig.folderPath || "avatars/",
4526
+ title: "Select Avatar",
4527
+ description: "Upload a new avatar or select from existing images.",
4528
+ mode: "full",
4529
+ maxFileSize,
4530
+ maxFiles: 1,
4531
+ autoRecordToDb: true,
4532
+ fetchThumbnails: true,
4533
+ onSelect: handleSelect
4534
+ }
4535
+ )
4536
+ ] });
4537
+ };
4432
4538
  var UserProfile = ({
4433
4539
  showAvatar = true,
4434
4540
  showEmailChange = true,
4435
- showPasswordChange = true
4541
+ showPasswordChange = true,
4542
+ upfilesConfig
4436
4543
  }) => {
4437
4544
  const { user, updateProfile, requestEmailChange } = useAuth2();
4438
4545
  const colors = useThemeColors();
4439
4546
  const [name, setName] = useState(user?.name || "");
4440
- const [avatar, setAvatar] = useState(user?.avatar || "");
4441
4547
  const [phoneNumber, setPhoneNumber] = useState(user?.phoneNumber || "");
4442
4548
  const [newEmail, setNewEmail] = useState("");
4443
4549
  const [isLoading, setIsLoading] = useState(false);
@@ -4453,9 +4559,6 @@ var UserProfile = ({
4453
4559
  if (name !== user?.name) {
4454
4560
  updates.name = name;
4455
4561
  }
4456
- if (showAvatar && avatar !== user?.avatar) {
4457
- updates.avatar = avatar;
4458
- }
4459
4562
  if (phoneNumber !== user?.phoneNumber) {
4460
4563
  updates.phoneNumber = phoneNumber;
4461
4564
  }
@@ -4476,6 +4579,12 @@ var UserProfile = ({
4476
4579
  setIsLoading(false);
4477
4580
  }
4478
4581
  };
4582
+ const handleAvatarUploadComplete = (avatarUrl) => {
4583
+ setSuccess("Avatar updated successfully!");
4584
+ };
4585
+ const handleAvatarUploadError = (error2) => {
4586
+ setError(error2.message || "Failed to upload avatar");
4587
+ };
4479
4588
  const handleRequestEmailChange = async (e) => {
4480
4589
  e.preventDefault();
4481
4590
  setIsLoading(true);
@@ -4578,34 +4687,36 @@ var UserProfile = ({
4578
4687
  }
4579
4688
  )
4580
4689
  ] }),
4581
- showAvatar && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4582
- /* @__PURE__ */ jsx("label", { htmlFor: "avatar", style: {
4690
+ showAvatar && upfilesConfig && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4691
+ /* @__PURE__ */ jsx("label", { style: {
4583
4692
  display: "block",
4584
4693
  marginBottom: "8px",
4585
4694
  fontWeight: 500,
4586
4695
  color: colors.textSecondary,
4587
4696
  fontSize: "14px"
4588
- }, children: "Avatar URL" }),
4589
- /* @__PURE__ */ jsx(
4590
- "input",
4697
+ }, children: "Avatar" }),
4698
+ user?.avatar && /* @__PURE__ */ jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsx(
4699
+ "img",
4591
4700
  {
4592
- id: "avatar",
4593
- type: "url",
4594
- value: avatar,
4595
- onChange: (e) => setAvatar(e.target.value),
4596
- disabled: isLoading,
4701
+ src: user.avatar,
4702
+ alt: "Current avatar",
4597
4703
  style: {
4598
- width: "100%",
4599
- padding: "12px 16px",
4600
- border: `1px solid ${colors.borderSecondary}`,
4601
- borderRadius: "8px",
4602
- fontSize: "16px",
4603
- boxSizing: "border-box",
4604
- backgroundColor: colors.bgSecondary,
4605
- color: colors.textPrimary,
4606
- transition: "all 0.2s ease"
4607
- },
4608
- placeholder: "https://example.com/avatar.jpg"
4704
+ width: "80px",
4705
+ height: "80px",
4706
+ borderRadius: "50%",
4707
+ objectFit: "cover",
4708
+ border: `2px solid ${colors.borderSecondary}`
4709
+ }
4710
+ }
4711
+ ) }),
4712
+ /* @__PURE__ */ jsx(
4713
+ AvatarUploader,
4714
+ {
4715
+ upfilesConfig,
4716
+ onUploadComplete: handleAvatarUploadComplete,
4717
+ onError: handleAvatarUploadError,
4718
+ maxFileSize: 5 * 1024 * 1024,
4719
+ accept: ["image/*"]
4609
4720
  }
4610
4721
  )
4611
4722
  ] }),
@@ -4717,63 +4828,6 @@ var UserProfile = ({
4717
4828
  ] })
4718
4829
  ] });
4719
4830
  };
4720
- var AvatarUploader = ({
4721
- onUploadComplete,
4722
- onError,
4723
- className,
4724
- buttonClassName,
4725
- dropzoneClassName,
4726
- maxFileSize = 5 * 1024 * 1024,
4727
- // 5MB default
4728
- accept = ["image/*"],
4729
- upfilesConfig
4730
- }) => {
4731
- const { uploadAndUpdateAvatar } = useAuth2();
4732
- const [uploading, setUploading] = useState(false);
4733
- const handleUploadComplete = async (files) => {
4734
- if (files.length === 0)
4735
- return;
4736
- setUploading(true);
4737
- try {
4738
- const file = files[0];
4739
- const response = await uploadAndUpdateAvatar(file.file);
4740
- if (response.success && response.user?.avatar) {
4741
- onUploadComplete?.(response.user.avatar);
4742
- } else {
4743
- throw new Error(response.message || "Failed to update avatar");
4744
- }
4745
- } catch (error) {
4746
- const err = error instanceof Error ? error : new Error("Upload failed");
4747
- onError?.(err);
4748
- } finally {
4749
- setUploading(false);
4750
- }
4751
- };
4752
- const handleError = (error) => {
4753
- onError?.(error);
4754
- };
4755
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
4756
- Uploader,
4757
- {
4758
- clientOptions: {
4759
- baseUrl: upfilesConfig.baseUrl,
4760
- apiKey: upfilesConfig.apiKey,
4761
- apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4762
- presignUrl: upfilesConfig.presignUrl,
4763
- presignPath: upfilesConfig.presignPath
4764
- },
4765
- multiple: false,
4766
- accept,
4767
- maxFileSize,
4768
- maxFiles: 1,
4769
- onComplete: handleUploadComplete,
4770
- onError: handleError,
4771
- buttonClassName,
4772
- dropzoneClassName,
4773
- children: uploading ? "Uploading..." : "Upload Avatar"
4774
- }
4775
- ) });
4776
- };
4777
4831
  var AvatarManager = ({
4778
4832
  open,
4779
4833
  onOpenChange,