@thetechfossil/auth2 1.2.7 → 1.2.8

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,7 +1,6 @@
1
- "use client";
2
1
  import React2, { createContext, forwardRef, useContext, useState, useMemo, useEffect, useRef, useCallback } from 'react';
3
2
  import axios from 'axios';
4
- import { Uploader, ImageManager, UpfilesClient } from '@thetechfossil/upfiles';
3
+ import { ImageManager, UpfilesClient } from '@thetechfossil/upfiles';
5
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
5
  import PhoneInputWithCountry from 'react-phone-number-input';
7
6
  import 'react-phone-number-input/style.css';
@@ -4105,15 +4104,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4105
4104
  )
4106
4105
  ] }) });
4107
4106
  };
4107
+ var AvatarUploader = ({
4108
+ onUploadComplete,
4109
+ onError,
4110
+ className,
4111
+ buttonClassName,
4112
+ maxFileSize = 5 * 1024 * 1024,
4113
+ // 5MB default
4114
+ upfilesConfig,
4115
+ buttonText = "Upload Avatar"
4116
+ }) => {
4117
+ const { uploadAndUpdateAvatar } = useAuth2();
4118
+ const [open, setOpen] = useState(false);
4119
+ const [uploading, setUploading] = useState(false);
4120
+ const handleSelect = async (image) => {
4121
+ setUploading(true);
4122
+ try {
4123
+ const response = await fetch(image.url);
4124
+ const blob = await response.blob();
4125
+ const file = new File([blob], image.originalName, { type: image.contentType });
4126
+ const result = await uploadAndUpdateAvatar(file);
4127
+ if (result.success && result.user?.avatar) {
4128
+ onUploadComplete?.(result.user.avatar);
4129
+ setOpen(false);
4130
+ } else {
4131
+ throw new Error(result.message || "Failed to update avatar");
4132
+ }
4133
+ } catch (error) {
4134
+ const err = error instanceof Error ? error : new Error("Upload failed");
4135
+ onError?.(err);
4136
+ } finally {
4137
+ setUploading(false);
4138
+ }
4139
+ };
4140
+ return /* @__PURE__ */ jsxs("div", { className, children: [
4141
+ /* @__PURE__ */ jsx(
4142
+ "button",
4143
+ {
4144
+ type: "button",
4145
+ onClick: () => setOpen(true),
4146
+ disabled: uploading,
4147
+ className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
4148
+ children: uploading ? "Uploading..." : buttonText
4149
+ }
4150
+ ),
4151
+ /* @__PURE__ */ jsx(
4152
+ ImageManager,
4153
+ {
4154
+ open,
4155
+ onOpenChange: setOpen,
4156
+ clientOptions: {
4157
+ baseUrl: upfilesConfig.baseUrl,
4158
+ apiKey: upfilesConfig.apiKey,
4159
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4160
+ presignUrl: upfilesConfig.presignUrl,
4161
+ presignPath: upfilesConfig.presignPath
4162
+ },
4163
+ projectId: upfilesConfig.projectId,
4164
+ folderPath: upfilesConfig.folderPath || "avatars/",
4165
+ title: "Select Avatar",
4166
+ description: "Upload a new avatar or select from existing images.",
4167
+ mode: "full",
4168
+ maxFileSize,
4169
+ maxFiles: 1,
4170
+ autoRecordToDb: true,
4171
+ fetchThumbnails: true,
4172
+ onSelect: handleSelect
4173
+ }
4174
+ )
4175
+ ] });
4176
+ };
4108
4177
  var UserProfile = ({
4109
4178
  showAvatar = true,
4110
4179
  showEmailChange = true,
4111
- showPasswordChange = true
4180
+ showPasswordChange = true,
4181
+ upfilesConfig
4112
4182
  }) => {
4113
4183
  const { user, updateProfile, requestEmailChange } = useAuth2();
4114
4184
  const colors = useThemeColors();
4115
4185
  const [name, setName] = useState(user?.name || "");
4116
- const [avatar, setAvatar] = useState(user?.avatar || "");
4117
4186
  const [phoneNumber, setPhoneNumber] = useState(user?.phoneNumber || "");
4118
4187
  const [newEmail, setNewEmail] = useState("");
4119
4188
  const [isLoading, setIsLoading] = useState(false);
@@ -4129,9 +4198,6 @@ var UserProfile = ({
4129
4198
  if (name !== user?.name) {
4130
4199
  updates.name = name;
4131
4200
  }
4132
- if (showAvatar && avatar !== user?.avatar) {
4133
- updates.avatar = avatar;
4134
- }
4135
4201
  if (phoneNumber !== user?.phoneNumber) {
4136
4202
  updates.phoneNumber = phoneNumber;
4137
4203
  }
@@ -4152,6 +4218,12 @@ var UserProfile = ({
4152
4218
  setIsLoading(false);
4153
4219
  }
4154
4220
  };
4221
+ const handleAvatarUploadComplete = (avatarUrl) => {
4222
+ setSuccess("Avatar updated successfully!");
4223
+ };
4224
+ const handleAvatarUploadError = (error2) => {
4225
+ setError(error2.message || "Failed to upload avatar");
4226
+ };
4155
4227
  const handleRequestEmailChange = async (e) => {
4156
4228
  e.preventDefault();
4157
4229
  setIsLoading(true);
@@ -4254,34 +4326,36 @@ var UserProfile = ({
4254
4326
  }
4255
4327
  )
4256
4328
  ] }),
4257
- showAvatar && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4258
- /* @__PURE__ */ jsx("label", { htmlFor: "avatar", style: {
4329
+ showAvatar && upfilesConfig && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "20px" }, children: [
4330
+ /* @__PURE__ */ jsx("label", { style: {
4259
4331
  display: "block",
4260
4332
  marginBottom: "8px",
4261
4333
  fontWeight: 500,
4262
4334
  color: colors.textSecondary,
4263
4335
  fontSize: "14px"
4264
- }, children: "Avatar URL" }),
4265
- /* @__PURE__ */ jsx(
4266
- "input",
4336
+ }, children: "Avatar" }),
4337
+ user?.avatar && /* @__PURE__ */ jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsx(
4338
+ "img",
4267
4339
  {
4268
- id: "avatar",
4269
- type: "url",
4270
- value: avatar,
4271
- onChange: (e) => setAvatar(e.target.value),
4272
- disabled: isLoading,
4340
+ src: user.avatar,
4341
+ alt: "Current avatar",
4273
4342
  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"
4343
+ width: "80px",
4344
+ height: "80px",
4345
+ borderRadius: "50%",
4346
+ objectFit: "cover",
4347
+ border: `2px solid ${colors.borderSecondary}`
4348
+ }
4349
+ }
4350
+ ) }),
4351
+ /* @__PURE__ */ jsx(
4352
+ AvatarUploader,
4353
+ {
4354
+ upfilesConfig,
4355
+ onUploadComplete: handleAvatarUploadComplete,
4356
+ onError: handleAvatarUploadError,
4357
+ maxFileSize: 5 * 1024 * 1024,
4358
+ accept: ["image/*"]
4285
4359
  }
4286
4360
  )
4287
4361
  ] }),
@@ -4393,63 +4467,6 @@ var UserProfile = ({
4393
4467
  ] })
4394
4468
  ] });
4395
4469
  };
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
4470
  var AvatarManager = ({
4454
4471
  open,
4455
4472
  onOpenChange,