@thetechfossil/auth2 1.2.5 → 1.2.7

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,6 +1,7 @@
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
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
  import PhoneInputWithCountry from 'react-phone-number-input';
6
7
  import 'react-phone-number-input/style.css';
@@ -111,11 +112,10 @@ var HttpClient = class {
111
112
  }
112
113
  }
113
114
  };
114
-
115
- // src/core/auth-service.ts
116
115
  var AuthService = class {
117
116
  constructor(config) {
118
117
  this.token = null;
118
+ this.upfilesClient = null;
119
119
  this.config = {
120
120
  localStorageKey: "auth_token",
121
121
  csrfEnabled: true,
@@ -123,6 +123,15 @@ var AuthService = class {
123
123
  };
124
124
  this.httpClient = new HttpClient(this.config.baseUrl);
125
125
  this.loadTokenFromStorage();
126
+ if (this.config.upfilesConfig) {
127
+ this.upfilesClient = new UpfilesClient({
128
+ baseUrl: this.config.upfilesConfig.baseUrl,
129
+ apiKey: this.config.upfilesConfig.apiKey,
130
+ apiKeyHeader: this.config.upfilesConfig.apiKeyHeader,
131
+ presignUrl: this.config.upfilesConfig.presignUrl,
132
+ presignPath: this.config.upfilesConfig.presignPath
133
+ });
134
+ }
126
135
  if (typeof window !== "undefined") {
127
136
  const frontendBaseUrl = process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_APP_URL || window.location.origin;
128
137
  if (frontendBaseUrl) {
@@ -350,6 +359,28 @@ var AuthService = class {
350
359
  }
351
360
  return response;
352
361
  }
362
+ async uploadAndUpdateAvatar(file) {
363
+ if (!this.token) {
364
+ throw new Error("Not authenticated");
365
+ }
366
+ if (!this.upfilesClient) {
367
+ throw new Error("Upfiles configuration is required. Please provide upfilesConfig in AuthConfig.");
368
+ }
369
+ try {
370
+ const folderPath = this.config.upfilesConfig?.folderPath || "avatars/";
371
+ const uploadResult = await this.upfilesClient.upload(file, {
372
+ folderPath,
373
+ fetchThumbnails: true
374
+ });
375
+ const response = await this.updateAvatar(uploadResult.publicUrl);
376
+ return response;
377
+ } catch (error) {
378
+ throw new Error(`Failed to upload avatar: ${error.message || "Unknown error"}`);
379
+ }
380
+ }
381
+ getUpfilesClient() {
382
+ return this.upfilesClient;
383
+ }
353
384
  async requestEmailChange(newEmail) {
354
385
  if (!this.token) {
355
386
  throw new Error("Not authenticated");
@@ -582,6 +613,18 @@ var useAuth = (config) => {
582
613
  setLoading(false);
583
614
  }
584
615
  }, [authService]);
616
+ const uploadAndUpdateAvatar = useCallback(async (file) => {
617
+ setLoading(true);
618
+ try {
619
+ const response = await authService.uploadAndUpdateAvatar(file);
620
+ if (response.success && response.user) {
621
+ setUser(response.user);
622
+ }
623
+ return response;
624
+ } finally {
625
+ setLoading(false);
626
+ }
627
+ }, [authService]);
585
628
  return {
586
629
  user,
587
630
  isAuthenticated,
@@ -594,7 +637,8 @@ var useAuth = (config) => {
594
637
  updateProfile,
595
638
  getProfile,
596
639
  getAllUsers,
597
- getUserById
640
+ getUserById,
641
+ uploadAndUpdateAvatar
598
642
  };
599
643
  };
600
644
  var ThemeContext = createContext({ theme: "light", mounted: false });
@@ -4349,7 +4393,123 @@ var UserProfile = ({
4349
4393
  ] })
4350
4394
  ] });
4351
4395
  };
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
+ var AvatarManager = ({
4454
+ open,
4455
+ onOpenChange,
4456
+ onAvatarUpdated,
4457
+ onError,
4458
+ title = "Select Avatar",
4459
+ description = "Choose an existing image or upload a new one",
4460
+ className,
4461
+ gridClassName,
4462
+ maxFileSize = 5 * 1024 * 1024,
4463
+ // 5MB default
4464
+ mode = "full",
4465
+ showDelete = false,
4466
+ upfilesConfig
4467
+ }) => {
4468
+ const { updateProfile } = useAuth2();
4469
+ const [updating, setUpdating] = useState(false);
4470
+ const handleSelect = async (image) => {
4471
+ setUpdating(true);
4472
+ try {
4473
+ const response = await updateProfile({ avatar: image.url });
4474
+ if (response.success && response.user?.avatar) {
4475
+ onAvatarUpdated?.(response.user.avatar);
4476
+ onOpenChange(false);
4477
+ } else {
4478
+ throw new Error(response.message || "Failed to update avatar");
4479
+ }
4480
+ } catch (error) {
4481
+ const err = error instanceof Error ? error : new Error("Failed to update avatar");
4482
+ onError?.(err);
4483
+ } finally {
4484
+ setUpdating(false);
4485
+ }
4486
+ };
4487
+ return /* @__PURE__ */ jsx(
4488
+ ImageManager,
4489
+ {
4490
+ open,
4491
+ onOpenChange,
4492
+ clientOptions: {
4493
+ baseUrl: upfilesConfig.baseUrl,
4494
+ apiKey: upfilesConfig.apiKey,
4495
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4496
+ presignUrl: upfilesConfig.presignUrl,
4497
+ presignPath: upfilesConfig.presignPath
4498
+ },
4499
+ folderPath: upfilesConfig.folderPath || "avatars/",
4500
+ title,
4501
+ description,
4502
+ className,
4503
+ gridClassName,
4504
+ onSelect: handleSelect,
4505
+ maxFileSize,
4506
+ mode,
4507
+ showDelete,
4508
+ fetchThumbnails: true
4509
+ }
4510
+ );
4511
+ };
4352
4512
 
4353
- export { AuthFlow, ChangePassword, EmailVerificationPage, ForgotPassword, LoginForm, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail };
4513
+ export { AuthFlow, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, LoginForm, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail };
4354
4514
  //# sourceMappingURL=out.js.map
4355
4515
  //# sourceMappingURL=index.components.mjs.map