@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,11 +1,16 @@
1
1
  "use client";
2
2
  import React2, { createContext, forwardRef, useContext, useState, useMemo, useEffect, useRef, useCallback } from 'react';
3
3
  import axios from 'axios';
4
- import { Uploader, ImageManager, UpfilesClient } from '@thetechfossil/upfiles';
4
+ import { ImageManager, UpfilesClient } from '@thetechfossil/upfiles';
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
 
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
+ });
9
14
  var HttpClient = class {
10
15
  constructor(baseUrl, defaultHeaders = {}) {
11
16
  this.csrfToken = null;
@@ -687,6 +692,14 @@ function useThemeColors() {
687
692
  const { theme } = useAuthTheme();
688
693
  return theme === "dark" ? darkTheme : lightTheme;
689
694
  }
695
+ var PhoneInputWithCountry = null;
696
+ try {
697
+ const module = __require("react-phone-number-input");
698
+ PhoneInputWithCountry = module.default || module;
699
+ __require("react-phone-number-input/style.css");
700
+ } catch (error) {
701
+ console.warn("react-phone-number-input not available, using fallback");
702
+ }
690
703
  var CustomPhoneInput = React2.forwardRef((props, ref) => /* @__PURE__ */ jsx(
691
704
  "input",
692
705
  {
@@ -879,6 +892,30 @@ var PhoneInput = ({
879
892
  const handleChange = useMemo(() => (val) => {
880
893
  onChange(val || "");
881
894
  }, [onChange]);
895
+ if (!PhoneInputWithCountry) {
896
+ return /* @__PURE__ */ jsx(
897
+ "input",
898
+ {
899
+ id,
900
+ type: "tel",
901
+ value,
902
+ onChange: (e) => onChange(e.target.value),
903
+ disabled,
904
+ required,
905
+ placeholder,
906
+ style: {
907
+ width: "100%",
908
+ padding: "12px 16px",
909
+ border: `1px solid ${colors.borderSecondary}`,
910
+ borderRadius: "8px",
911
+ fontSize: "16px",
912
+ backgroundColor: colors.bgSecondary,
913
+ color: colors.textPrimary,
914
+ ...style
915
+ }
916
+ }
917
+ );
918
+ }
882
919
  return /* @__PURE__ */ jsxs(
883
920
  "div",
884
921
  {
@@ -4105,15 +4142,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4105
4142
  )
4106
4143
  ] }) });
4107
4144
  };
4145
+ var AvatarUploader = ({
4146
+ onUploadComplete,
4147
+ onError,
4148
+ className,
4149
+ buttonClassName,
4150
+ maxFileSize = 5 * 1024 * 1024,
4151
+ // 5MB default
4152
+ upfilesConfig,
4153
+ buttonText = "Upload Avatar"
4154
+ }) => {
4155
+ const { uploadAndUpdateAvatar } = useAuth2();
4156
+ const [open, setOpen] = useState(false);
4157
+ const [uploading, setUploading] = useState(false);
4158
+ const handleSelect = async (image) => {
4159
+ setUploading(true);
4160
+ try {
4161
+ const response = await fetch(image.url);
4162
+ const blob = await response.blob();
4163
+ const file = new File([blob], image.originalName, { type: image.contentType });
4164
+ const result = await uploadAndUpdateAvatar(file);
4165
+ if (result.success && result.user?.avatar) {
4166
+ onUploadComplete?.(result.user.avatar);
4167
+ setOpen(false);
4168
+ } else {
4169
+ throw new Error(result.message || "Failed to update avatar");
4170
+ }
4171
+ } catch (error) {
4172
+ const err = error instanceof Error ? error : new Error("Upload failed");
4173
+ onError?.(err);
4174
+ } finally {
4175
+ setUploading(false);
4176
+ }
4177
+ };
4178
+ return /* @__PURE__ */ jsxs("div", { className, children: [
4179
+ /* @__PURE__ */ jsx(
4180
+ "button",
4181
+ {
4182
+ type: "button",
4183
+ onClick: () => setOpen(true),
4184
+ disabled: uploading,
4185
+ className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
4186
+ children: uploading ? "Uploading..." : buttonText
4187
+ }
4188
+ ),
4189
+ /* @__PURE__ */ jsx(
4190
+ ImageManager,
4191
+ {
4192
+ open,
4193
+ onOpenChange: setOpen,
4194
+ clientOptions: {
4195
+ baseUrl: upfilesConfig.baseUrl,
4196
+ apiKey: upfilesConfig.apiKey,
4197
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4198
+ presignUrl: upfilesConfig.presignUrl,
4199
+ presignPath: upfilesConfig.presignPath
4200
+ },
4201
+ projectId: upfilesConfig.projectId,
4202
+ folderPath: upfilesConfig.folderPath || "avatars/",
4203
+ title: "Select Avatar",
4204
+ description: "Upload a new avatar or select from existing images.",
4205
+ mode: "full",
4206
+ maxFileSize,
4207
+ maxFiles: 1,
4208
+ autoRecordToDb: true,
4209
+ fetchThumbnails: true,
4210
+ onSelect: handleSelect
4211
+ }
4212
+ )
4213
+ ] });
4214
+ };
4108
4215
  var UserProfile = ({
4109
4216
  showAvatar = true,
4110
4217
  showEmailChange = true,
4111
- showPasswordChange = true
4218
+ showPasswordChange = true,
4219
+ upfilesConfig
4112
4220
  }) => {
4113
4221
  const { user, updateProfile, requestEmailChange } = useAuth2();
4114
4222
  const colors = useThemeColors();
4115
4223
  const [name, setName] = useState(user?.name || "");
4116
- const [avatar, setAvatar] = useState(user?.avatar || "");
4117
4224
  const [phoneNumber, setPhoneNumber] = useState(user?.phoneNumber || "");
4118
4225
  const [newEmail, setNewEmail] = useState("");
4119
4226
  const [isLoading, setIsLoading] = useState(false);
@@ -4129,9 +4236,6 @@ var UserProfile = ({
4129
4236
  if (name !== user?.name) {
4130
4237
  updates.name = name;
4131
4238
  }
4132
- if (showAvatar && avatar !== user?.avatar) {
4133
- updates.avatar = avatar;
4134
- }
4135
4239
  if (phoneNumber !== user?.phoneNumber) {
4136
4240
  updates.phoneNumber = phoneNumber;
4137
4241
  }
@@ -4152,6 +4256,12 @@ var UserProfile = ({
4152
4256
  setIsLoading(false);
4153
4257
  }
4154
4258
  };
4259
+ const handleAvatarUploadComplete = (avatarUrl) => {
4260
+ setSuccess("Avatar updated successfully!");
4261
+ };
4262
+ const handleAvatarUploadError = (error2) => {
4263
+ setError(error2.message || "Failed to upload avatar");
4264
+ };
4155
4265
  const handleRequestEmailChange = async (e) => {
4156
4266
  e.preventDefault();
4157
4267
  setIsLoading(true);
@@ -4254,34 +4364,36 @@ var UserProfile = ({
4254
4364
  }
4255
4365
  )
4256
4366
  ] }),
4257
- showAvatar && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4258
- /* @__PURE__ */ jsx("label", { htmlFor: "avatar", style: {
4367
+ showAvatar && upfilesConfig && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4368
+ /* @__PURE__ */ jsx("label", { style: {
4259
4369
  display: "block",
4260
4370
  marginBottom: "8px",
4261
4371
  fontWeight: 500,
4262
4372
  color: colors.textSecondary,
4263
4373
  fontSize: "14px"
4264
- }, children: "Avatar URL" }),
4265
- /* @__PURE__ */ jsx(
4266
- "input",
4374
+ }, children: "Avatar" }),
4375
+ user?.avatar && /* @__PURE__ */ jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsx(
4376
+ "img",
4267
4377
  {
4268
- id: "avatar",
4269
- type: "url",
4270
- value: avatar,
4271
- onChange: (e) => setAvatar(e.target.value),
4272
- disabled: isLoading,
4378
+ src: user.avatar,
4379
+ alt: "Current avatar",
4273
4380
  style: {
4274
- width: "100%",
4275
- padding: "12px 16px",
4276
- border: `1px solid ${colors.borderSecondary}`,
4277
- borderRadius: "8px",
4278
- fontSize: "16px",
4279
- boxSizing: "border-box",
4280
- backgroundColor: colors.bgSecondary,
4281
- color: colors.textPrimary,
4282
- transition: "all 0.2s ease"
4283
- },
4284
- placeholder: "https://example.com/avatar.jpg"
4381
+ width: "80px",
4382
+ height: "80px",
4383
+ borderRadius: "50%",
4384
+ objectFit: "cover",
4385
+ border: `2px solid ${colors.borderSecondary}`
4386
+ }
4387
+ }
4388
+ ) }),
4389
+ /* @__PURE__ */ jsx(
4390
+ AvatarUploader,
4391
+ {
4392
+ upfilesConfig,
4393
+ onUploadComplete: handleAvatarUploadComplete,
4394
+ onError: handleAvatarUploadError,
4395
+ maxFileSize: 5 * 1024 * 1024,
4396
+ accept: ["image/*"]
4285
4397
  }
4286
4398
  )
4287
4399
  ] }),
@@ -4393,63 +4505,6 @@ var UserProfile = ({
4393
4505
  ] })
4394
4506
  ] });
4395
4507
  };
4396
- var AvatarUploader = ({
4397
- onUploadComplete,
4398
- onError,
4399
- className,
4400
- buttonClassName,
4401
- dropzoneClassName,
4402
- maxFileSize = 5 * 1024 * 1024,
4403
- // 5MB default
4404
- accept = ["image/*"],
4405
- upfilesConfig
4406
- }) => {
4407
- const { uploadAndUpdateAvatar } = useAuth2();
4408
- const [uploading, setUploading] = useState(false);
4409
- const handleUploadComplete = async (files) => {
4410
- if (files.length === 0)
4411
- return;
4412
- setUploading(true);
4413
- try {
4414
- const file = files[0];
4415
- const response = await uploadAndUpdateAvatar(file.file);
4416
- if (response.success && response.user?.avatar) {
4417
- onUploadComplete?.(response.user.avatar);
4418
- } else {
4419
- throw new Error(response.message || "Failed to update avatar");
4420
- }
4421
- } catch (error) {
4422
- const err = error instanceof Error ? error : new Error("Upload failed");
4423
- onError?.(err);
4424
- } finally {
4425
- setUploading(false);
4426
- }
4427
- };
4428
- const handleError = (error) => {
4429
- onError?.(error);
4430
- };
4431
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
4432
- Uploader,
4433
- {
4434
- clientOptions: {
4435
- baseUrl: upfilesConfig.baseUrl,
4436
- apiKey: upfilesConfig.apiKey,
4437
- apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4438
- presignUrl: upfilesConfig.presignUrl,
4439
- presignPath: upfilesConfig.presignPath
4440
- },
4441
- multiple: false,
4442
- accept,
4443
- maxFileSize,
4444
- maxFiles: 1,
4445
- onComplete: handleUploadComplete,
4446
- onError: handleError,
4447
- buttonClassName,
4448
- dropzoneClassName,
4449
- children: uploading ? "Uploading..." : "Upload Avatar"
4450
- }
4451
- ) });
4452
- };
4453
4508
  var AvatarManager = ({
4454
4509
  open,
4455
4510
  onOpenChange,