nfx-ui 0.26.0 → 0.28.0

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.
Files changed (180) hide show
  1. package/dist/apis/authRefresh.js.map +1 -1
  2. package/dist/apis/clients.js.map +1 -1
  3. package/dist/apis/ip.d.ts.map +1 -1
  4. package/dist/apis/ip.js.map +1 -1
  5. package/dist/apis/repositories/AssetRepository.d.ts.map +1 -1
  6. package/dist/apis/repositories/AssetRepository.js.map +1 -1
  7. package/dist/apis/repositories/AuthRepository.d.ts.map +1 -1
  8. package/dist/apis/repositories/AuthRepository.js.map +1 -1
  9. package/dist/config/env.js.map +1 -1
  10. package/dist/constants/index.js +5 -5
  11. package/dist/constants/key.d.ts +4 -0
  12. package/dist/constants/key.d.ts.map +1 -1
  13. package/dist/constants/key.js +23 -1
  14. package/dist/constants/key.js.map +1 -1
  15. package/dist/constants/querykeys.js.map +1 -1
  16. package/dist/enums/auth.d.ts.map +1 -1
  17. package/dist/enums/auth.js.map +1 -1
  18. package/dist/enums/dashboard.d.ts.map +1 -1
  19. package/dist/enums/dashboard.js.map +1 -1
  20. package/dist/enums/language.d.ts.map +1 -1
  21. package/dist/enums/language.js.map +1 -1
  22. package/dist/enums/layout.d.ts.map +1 -1
  23. package/dist/enums/layout.js.map +1 -1
  24. package/dist/enums/theme.d.ts.map +1 -1
  25. package/dist/enums/theme.js.map +1 -1
  26. package/dist/events/EventEmitter.d.ts.map +1 -1
  27. package/dist/events/EventEmitter.js.map +1 -1
  28. package/dist/events/auth.d.ts +4 -0
  29. package/dist/events/auth.d.ts.map +1 -1
  30. package/dist/events/auth.js +9 -1
  31. package/dist/events/auth.js.map +1 -1
  32. package/dist/events/query.d.ts.map +1 -1
  33. package/dist/events/query.js.map +1 -1
  34. package/dist/events/system.d.ts.map +1 -1
  35. package/dist/events/system.js.map +1 -1
  36. package/dist/hooks/asset.d.ts +1 -0
  37. package/dist/hooks/asset.d.ts.map +1 -1
  38. package/dist/hooks/asset.js +10 -7
  39. package/dist/hooks/asset.js.map +1 -1
  40. package/dist/hooks/auth.d.ts +27 -0
  41. package/dist/hooks/auth.d.ts.map +1 -1
  42. package/dist/hooks/auth.js +256 -111
  43. package/dist/hooks/auth.js.map +1 -1
  44. package/dist/hooks/index.d.ts.map +1 -1
  45. package/dist/hooks/index.js +9 -9
  46. package/dist/hooks/preference.d.ts.map +1 -1
  47. package/dist/hooks/preference.js.map +1 -1
  48. package/dist/languages/hooks/useLanguageLabel.d.ts.map +1 -1
  49. package/dist/languages/hooks/useLanguageLabel.js.map +1 -1
  50. package/dist/languages/hooks/useLayoutLabel.d.ts.map +1 -1
  51. package/dist/languages/hooks/useLayoutLabel.js.map +1 -1
  52. package/dist/languages/hooks/usePreferenceLabel.d.ts.map +1 -1
  53. package/dist/languages/hooks/usePreferenceLabel.js.map +1 -1
  54. package/dist/languages/hooks/useThemeLabel.d.ts.map +1 -1
  55. package/dist/languages/hooks/useThemeLabel.js.map +1 -1
  56. package/dist/languages/languages/i18n.d.ts.map +1 -1
  57. package/dist/languages/languages/i18n.js.map +1 -1
  58. package/dist/languages/languages/i18nResources.js.map +1 -1
  59. package/dist/languages/types/components.d.ts.map +1 -1
  60. package/dist/languages/types/language.d.ts.map +1 -1
  61. package/dist/languages/utils/getLocalLanguage.d.ts.map +1 -1
  62. package/dist/languages/utils/getLocalLanguage.js.map +1 -1
  63. package/dist/languages/utils/languageStorage.d.ts.map +1 -1
  64. package/dist/languages/utils/languageStorage.js.map +1 -1
  65. package/dist/navigations/GuestRoute.js.map +1 -1
  66. package/dist/navigations/ProtectedRoute.js.map +1 -1
  67. package/dist/providers/DataProvider/index.d.ts.map +1 -1
  68. package/dist/providers/DataProvider/index.js.map +1 -1
  69. package/dist/providers/LanguageProvider/index.d.ts.map +1 -1
  70. package/dist/providers/LanguageProvider/index.js.map +1 -1
  71. package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
  72. package/dist/providers/ThemeProvider/index.js.map +1 -1
  73. package/dist/schemas/index.js +4 -4
  74. package/dist/schemas/loginSchema.d.ts +15 -0
  75. package/dist/schemas/loginSchema.d.ts.map +1 -1
  76. package/dist/schemas/loginSchema.js +20 -1
  77. package/dist/schemas/loginSchema.js.map +1 -1
  78. package/dist/schemas/profileEditSchema.d.ts.map +1 -1
  79. package/dist/schemas/profileEditSchema.js.map +1 -1
  80. package/dist/schemas/signupSchema.js.map +1 -1
  81. package/dist/stores/auth.d.ts.map +1 -1
  82. package/dist/stores/auth.js.map +1 -1
  83. package/dist/stores/index.d.ts.map +1 -1
  84. package/dist/stores/layout.js.map +1 -1
  85. package/dist/stores/preference.d.ts.map +1 -1
  86. package/dist/stores/preference.js.map +1 -1
  87. package/dist/themes/hooks/index.d.ts.map +1 -1
  88. package/dist/themes/hooks/useTheme.d.ts.map +1 -1
  89. package/dist/themes/hooks/useTheme.js.map +1 -1
  90. package/dist/themes/index.d.ts.map +1 -1
  91. package/dist/themes/radix/mappings.d.ts.map +1 -1
  92. package/dist/themes/radix/mappings.js.map +1 -1
  93. package/dist/themes/types/components.d.ts.map +1 -1
  94. package/dist/themes/types/context.d.ts.map +1 -1
  95. package/dist/themes/types/index.d.ts.map +1 -1
  96. package/dist/themes/types/theme.d.ts.map +1 -1
  97. package/dist/types/domain/auth/login.d.ts.map +1 -1
  98. package/dist/types/domain/auth/profile.d.ts.map +1 -1
  99. package/dist/types/domain/auth/signup.d.ts.map +1 -1
  100. package/dist/utils/apiError.d.ts.map +1 -1
  101. package/dist/utils/apiError.js.map +1 -1
  102. package/dist/utils/array.d.ts.map +1 -1
  103. package/dist/utils/array.js.map +1 -1
  104. package/dist/utils/domain/account.d.ts.map +1 -1
  105. package/dist/utils/domain/account.js.map +1 -1
  106. package/dist/utils/domain/buildProfilePatch.d.ts.map +1 -1
  107. package/dist/utils/domain/buildProfilePatch.js.map +1 -1
  108. package/dist/utils/domain/images.js.map +1 -1
  109. package/dist/utils/factory/hooks.d.ts.map +1 -1
  110. package/dist/utils/factory/hooks.js.map +1 -1
  111. package/dist/utils/lstorage.d.ts.map +1 -1
  112. package/dist/utils/lstorage.js.map +1 -1
  113. package/dist/utils/safe.d.ts.map +1 -1
  114. package/dist/utils/safe.js.map +1 -1
  115. package/dist/utils/suspense.d.ts.map +1 -1
  116. package/dist/utils/suspense.js.map +1 -1
  117. package/package.json +1 -1
  118. package/src/apis/authRefresh.ts +4 -4
  119. package/src/apis/clients.ts +5 -5
  120. package/src/apis/ip.ts +1 -1
  121. package/src/apis/repositories/AssetRepository.ts +1 -1
  122. package/src/apis/repositories/AuthRepository.ts +2 -2
  123. package/src/config/env.ts +1 -1
  124. package/src/constants/key.ts +5 -1
  125. package/src/constants/querykeys.ts +1 -1
  126. package/src/enums/auth.ts +2 -2
  127. package/src/enums/dashboard.ts +2 -2
  128. package/src/enums/language.ts +2 -2
  129. package/src/enums/layout.ts +2 -2
  130. package/src/enums/theme.ts +2 -2
  131. package/src/events/EventEmitter.ts +1 -1
  132. package/src/events/auth.ts +14 -4
  133. package/src/events/query.ts +3 -3
  134. package/src/events/system.ts +3 -3
  135. package/src/hooks/asset.ts +12 -7
  136. package/src/hooks/auth.ts +238 -12
  137. package/src/hooks/index.ts +1 -1
  138. package/src/hooks/preference.ts +5 -5
  139. package/src/languages/hooks/useLanguageLabel.ts +1 -1
  140. package/src/languages/hooks/useLayoutLabel.ts +1 -1
  141. package/src/languages/hooks/usePreferenceLabel.ts +1 -1
  142. package/src/languages/hooks/useThemeLabel.ts +1 -1
  143. package/src/languages/languages/i18n.ts +3 -3
  144. package/src/languages/languages/i18nResources.ts +1 -1
  145. package/src/languages/types/components.ts +1 -1
  146. package/src/languages/types/language.ts +1 -1
  147. package/src/languages/utils/getLocalLanguage.ts +2 -2
  148. package/src/languages/utils/languageStorage.ts +3 -3
  149. package/src/navigations/GuestRoute.tsx +1 -1
  150. package/src/navigations/ProtectedRoute.tsx +1 -1
  151. package/src/providers/DataProvider/index.tsx +7 -7
  152. package/src/providers/LanguageProvider/index.tsx +6 -6
  153. package/src/providers/ThemeProvider/index.tsx +4 -4
  154. package/src/schemas/loginSchema.ts +25 -0
  155. package/src/schemas/profileEditSchema.ts +4 -4
  156. package/src/schemas/signupSchema.ts +1 -1
  157. package/src/stores/auth.ts +3 -3
  158. package/src/stores/index.ts +1 -1
  159. package/src/stores/layout.ts +1 -1
  160. package/src/stores/preference.ts +5 -5
  161. package/src/themes/hooks/index.ts +1 -1
  162. package/src/themes/hooks/useTheme.ts +4 -4
  163. package/src/themes/index.ts +2 -2
  164. package/src/themes/radix/mappings.ts +2 -2
  165. package/src/themes/types/components.ts +1 -1
  166. package/src/themes/types/context.ts +2 -2
  167. package/src/themes/types/index.ts +1 -1
  168. package/src/themes/types/theme.ts +1 -1
  169. package/src/types/domain/auth/login.ts +2 -2
  170. package/src/types/domain/auth/profile.ts +1 -1
  171. package/src/types/domain/auth/signup.ts +1 -1
  172. package/src/utils/apiError.ts +2 -2
  173. package/src/utils/array.ts +1 -1
  174. package/src/utils/domain/account.ts +2 -2
  175. package/src/utils/domain/buildProfilePatch.ts +6 -6
  176. package/src/utils/domain/images.ts +1 -1
  177. package/src/utils/factory/hooks.ts +1 -1
  178. package/src/utils/lstorage.ts +1 -1
  179. package/src/utils/safe.ts +1 -1
  180. package/src/utils/suspense.ts +1 -1
package/src/hooks/auth.ts CHANGED
@@ -2,15 +2,15 @@
2
2
  * Auth hooks — 组件勿直接调 apis/auth
3
3
  */
4
4
  import type { AxiosError } from "axios";
5
- import type { CurrentProfileResult, Login, Profile, Signup } from "@/types";
5
+ import type { CurrentProfileResult, Login, Profile, Signup } from "nfx-ui/types";
6
6
 
7
7
  import { useEffect } from "react";
8
8
  import { useMutation } from "@tanstack/react-query";
9
- import { useAuthRepository } from "@/apis/repositories";
10
- import { AUTH_EMAILS, AUTH_ME, AUTH_PHONES, AUTH_PROFILES } from "@/constants";
11
- import { AuthSignupPlatformEnum, LanguageEnum, ProfileKindEnum } from "@/enums";
12
- import { authEventEmitter, authEvents } from "@/events/auth";
13
- import { systemEventEmitter } from "@/events/system";
9
+ import { useAuthRepository } from "nfx-ui/apis/repositories";
10
+ import { AUTH_EMAILS, AUTH_ME, AUTH_OWNER_AUTHORITIES, AUTH_OWNER_FORGERS, AUTH_PHONES, AUTH_PROFILE_SEARCH, AUTH_PROFILES, AUTH_PUBLIC_CARD } from "nfx-ui/constants";
11
+ import { AuthSignupPlatformEnum, LanguageEnum, ProfileKindEnum } from "nfx-ui/enums";
12
+ import { authEventEmitter, authEvents } from "nfx-ui/events/auth";
13
+ import { systemEventEmitter } from "nfx-ui/events/system";
14
14
  import {
15
15
  AuthStore,
16
16
  clearAuth,
@@ -22,12 +22,12 @@ import {
22
22
  setIsAuthValid,
23
23
  setTokens,
24
24
  useAuthStore,
25
- } from "@/stores/auth";
26
- import { ensureDeviceIdStorage } from "@/stores/system";
27
- import { getApiErrorMessage } from "@/utils/apiError";
28
- import { pickProfile } from "@/utils/domain/account";
29
- import { useUnifiedQuery } from "@/utils/factory";
30
- import { safeOr, safeStringable } from "@/utils/safe";
25
+ } from "nfx-ui/stores/auth";
26
+ import { ensureDeviceIdStorage } from "nfx-ui/stores/system";
27
+ import { getApiErrorMessage } from "nfx-ui/utils/apiError";
28
+ import { pickProfile } from "nfx-ui/utils/domain/account";
29
+ import { useUnifiedQuery } from "nfx-ui/utils/factory";
30
+ import { safeOr, safeStringable } from "nfx-ui/utils/safe";
31
31
  import { useTranslation } from "react-i18next";
32
32
 
33
33
  export function useAuthQueryScope() {
@@ -156,6 +156,33 @@ export const useLoginWithEmail = () => {
156
156
  });
157
157
  };
158
158
 
159
+ export const useLoginWithPhone = () => {
160
+ const auth = useAuthRepository();
161
+ return useMutation({
162
+ mutationFn: async ({ rememberMe, ...params }: { phone: string; password: string; rememberMe: boolean }) =>
163
+ auth.LoginWithPhone({
164
+ ...params,
165
+ deviceId: await ensureDeviceIdStorage(),
166
+ }),
167
+ onSuccess: (result, variables) => {
168
+ if (!result?.accessToken) return;
169
+ setCurrentProfileId(EMPTY_PROFILE_ID);
170
+ setTokens(
171
+ {
172
+ accessToken: result.accessToken,
173
+ refreshToken: safeStringable(result.refreshToken),
174
+ },
175
+ { rememberMe: variables.rememberMe },
176
+ );
177
+ setIsAuthValid(true);
178
+ if (result.accountId) setCurrentAccountId(result.accountId);
179
+ },
180
+ onError: (error: AxiosError) => {
181
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useLoginWithPhone] error"));
182
+ },
183
+ });
184
+ };
185
+
159
186
  export const useSelectProfile = () => {
160
187
  const auth = useAuthRepository();
161
188
  return useMutation({
@@ -203,14 +230,31 @@ export const usePatchProfile = (options?: { silent?: boolean }) => {
203
230
  export const useUpdateProfileSettings = () => {
204
231
  const auth = useAuthRepository();
205
232
  const { kind } = useAuthQueryScope();
233
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
206
234
  return useMutation({
207
235
  mutationFn: (body: Profile.Request.PatchProfileSettings) => auth.PatchProfileSettings(kind, body),
236
+ onSuccess: () => {
237
+ const aID = AuthStore.getState().currentAccountId;
238
+ authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
239
+ systemEventEmitter.showSuccess(t("updateSettingsSuccess", { defaultValue: "Settings updated." }));
240
+ },
208
241
  onError: (error: AxiosError) => {
209
242
  systemEventEmitter.showError(getApiErrorMessage(error, "[useUpdateProfileSettings] error"));
210
243
  },
211
244
  });
212
245
  };
213
246
 
247
+ export const useUpdatePreference = () => {
248
+ const auth = useAuthRepository();
249
+ const { kind } = useAuthQueryScope();
250
+ return useMutation({
251
+ mutationFn: (preference: string) => auth.UpdatePreference(kind, preference),
252
+ onError: (error: AxiosError) => {
253
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useUpdatePreference] error"));
254
+ },
255
+ });
256
+ };
257
+
214
258
  export const useListProfiles = <K extends ProfileKindEnum>(kind: K) => {
215
259
  const auth = useAuthRepository();
216
260
  const { aID, isAuthValid } = useAuthQueryScope();
@@ -269,6 +313,10 @@ export const useConfirmProfileAvatar = () => {
269
313
  const { kind } = useAuthQueryScope();
270
314
  return useMutation({
271
315
  mutationFn: (body: Profile.Request.ConfirmProfileAvatar) => auth.ConfirmProfileAvatar(kind, body),
316
+ onSuccess: () => {
317
+ const aID = AuthStore.getState().currentAccountId;
318
+ authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
319
+ },
272
320
  onError: (error: AxiosError) => {
273
321
  systemEventEmitter.showError(getApiErrorMessage(error, "[useConfirmProfileAvatar] error"));
274
322
  },
@@ -278,8 +326,14 @@ export const useConfirmProfileAvatar = () => {
278
326
  export const useClearProfileAvatar = () => {
279
327
  const auth = useAuthRepository();
280
328
  const { kind } = useAuthQueryScope();
329
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
281
330
  return useMutation({
282
331
  mutationFn: () => auth.ClearProfileAvatar(kind),
332
+ onSuccess: () => {
333
+ const aID = AuthStore.getState().currentAccountId;
334
+ authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, aID);
335
+ systemEventEmitter.showSuccess(t("clearAvatarSuccess", { defaultValue: "Avatar removed." }));
336
+ },
283
337
  onError: (error: AxiosError) => {
284
338
  systemEventEmitter.showError(getApiErrorMessage(error, "[useClearProfileAvatar] error"));
285
339
  },
@@ -441,5 +495,177 @@ export const useConfirmProfileBackgrounds = () => {
441
495
  });
442
496
  };
443
497
 
498
+ export const useCreatePhone = () => {
499
+ const auth = useAuthRepository();
500
+ const accountId = AuthStore.getState().currentAccountId;
501
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
502
+ return useMutation({
503
+ mutationFn: (body: Login.Request.CreatePhone) => auth.CreatePhone(body),
504
+ onSuccess: () => {
505
+ authEventEmitter.invalidatePhones(accountId);
506
+ systemEventEmitter.showSuccess(t("createPhoneSuccess", { defaultValue: "Phone added." }));
507
+ },
508
+ onError: (error: AxiosError) => {
509
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useCreatePhone] error"));
510
+ },
511
+ });
512
+ };
513
+
514
+ export const useSendPhoneVerificationCode = () => {
515
+ const auth = useAuthRepository();
516
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
517
+ return useMutation({
518
+ mutationFn: (phoneId: string) => auth.SendPhoneVerificationCode(phoneId),
519
+ onSuccess: () => {
520
+ systemEventEmitter.showSuccess(t("sendVerificationCodeSuccess", { defaultValue: "Code sent" }));
521
+ },
522
+ onError: (error: AxiosError) => {
523
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useSendPhoneVerificationCode] error"));
524
+ },
525
+ });
526
+ };
527
+
528
+ export const useVerifyPhone = () => {
529
+ const auth = useAuthRepository();
530
+ const accountId = AuthStore.getState().currentAccountId;
531
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
532
+ return useMutation({
533
+ mutationFn: ({ phoneId, verificationCode }: { phoneId: string; verificationCode: string }) =>
534
+ auth.VerifyPhone(phoneId, { verificationCode }),
535
+ onSuccess: () => {
536
+ authEventEmitter.invalidatePhones(accountId);
537
+ systemEventEmitter.showSuccess(t("verifyPhoneSuccess", { defaultValue: "Phone verified." }));
538
+ },
539
+ onError: (error: AxiosError) => {
540
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useVerifyPhone] error"));
541
+ },
542
+ });
543
+ };
544
+
545
+ export const useUpdatePhone = () => {
546
+ const auth = useAuthRepository();
547
+ const accountId = AuthStore.getState().currentAccountId;
548
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
549
+ return useMutation({
550
+ mutationFn: ({ phoneId, phone }: { phoneId: string; phone: string }) => auth.UpdatePhone(phoneId, { phone }),
551
+ onSuccess: () => {
552
+ authEventEmitter.invalidatePhones(accountId);
553
+ systemEventEmitter.showSuccess(t("updatePhoneSuccess", { defaultValue: "Phone updated." }));
554
+ },
555
+ onError: (error: AxiosError) => {
556
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useUpdatePhone] error"));
557
+ },
558
+ });
559
+ };
560
+
561
+ export const useSetPrimaryPhone = () => {
562
+ const auth = useAuthRepository();
563
+ const accountId = AuthStore.getState().currentAccountId;
564
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
565
+ return useMutation({
566
+ mutationFn: (phoneId: string) => auth.SetPrimaryPhone(phoneId),
567
+ onSuccess: () => {
568
+ authEventEmitter.invalidatePhones(accountId);
569
+ authEventEmitter.emit(authEvents.UPDATE_ACCOUNT_SUCCESS, accountId);
570
+ systemEventEmitter.showSuccess(t("setPrimaryPhoneSuccess", { defaultValue: "Primary phone updated." }));
571
+ },
572
+ onError: (error: AxiosError) => {
573
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useSetPrimaryPhone] error"));
574
+ },
575
+ });
576
+ };
577
+
578
+ export const useDeletePhone = () => {
579
+ const auth = useAuthRepository();
580
+ const accountId = AuthStore.getState().currentAccountId;
581
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
582
+ return useMutation({
583
+ mutationFn: (phoneId: string) => auth.DeletePhone(phoneId),
584
+ onSuccess: () => {
585
+ authEventEmitter.invalidatePhones(accountId);
586
+ systemEventEmitter.showSuccess(t("deletePhoneSuccess", { defaultValue: "Phone removed." }));
587
+ },
588
+ onError: (error: AxiosError) => {
589
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useDeletePhone] error"));
590
+ },
591
+ });
592
+ };
593
+
594
+ export const useSearchForgerProfiles = (query: string) => {
595
+ const auth = useAuthRepository();
596
+ const { aID, isAuthValid } = useAuthQueryScope();
597
+ const trimmed = query.trim();
598
+ return useUnifiedQuery(
599
+ ({ query: q }) => auth.SearchForgerProfiles({ query: q, limit: 50, offset: 0 }),
600
+ AUTH_PROFILE_SEARCH(aID, ProfileKindEnum.FORGER, trimmed),
601
+ { query: trimmed },
602
+ { enabled: isAuthValid && Boolean(aID) && trimmed.length > 0 },
603
+ );
604
+ };
605
+
606
+ export const useSearchAuthorityProfiles = (query: string) => {
607
+ const auth = useAuthRepository();
608
+ const { aID, isAuthValid } = useAuthQueryScope();
609
+ const trimmed = query.trim();
610
+ return useUnifiedQuery(
611
+ ({ query: q }) => auth.SearchAuthorityProfiles({ query: q, limit: 50, offset: 0 }),
612
+ AUTH_PROFILE_SEARCH(aID, ProfileKindEnum.AUTHORITY, trimmed),
613
+ { query: trimmed },
614
+ { enabled: isAuthValid && Boolean(aID) && trimmed.length > 0 },
615
+ );
616
+ };
617
+
618
+ export const useGetPublicProfileCard = (profileId: string) => {
619
+ const auth = useAuthRepository();
620
+ const { isAuthValid } = useAuthQueryScope();
621
+ return useUnifiedQuery(
622
+ () => auth.GetPublicProfileCard(profileId),
623
+ AUTH_PUBLIC_CARD(profileId),
624
+ undefined,
625
+ { enabled: isAuthValid && Boolean(profileId) },
626
+ );
627
+ };
628
+
629
+ export const useListOwnerForgerProfiles = (query = "") => {
630
+ const auth = useAuthRepository();
631
+ const { aID, isAuthValid } = useAuthQueryScope();
632
+ const trimmed = query.trim();
633
+ return useUnifiedQuery(
634
+ ({ query: q }) => auth.ListOwnerForgerProfiles({ limit: 50, offset: 0, query: q || undefined }),
635
+ [...AUTH_OWNER_FORGERS(aID), trimmed],
636
+ { query: trimmed },
637
+ { enabled: isAuthValid && Boolean(aID) },
638
+ );
639
+ };
640
+
641
+ export const useListOwnerAuthorityProfiles = (query = "") => {
642
+ const auth = useAuthRepository();
643
+ const { aID, isAuthValid } = useAuthQueryScope();
644
+ const trimmed = query.trim();
645
+ return useUnifiedQuery(
646
+ ({ query: q }) => auth.ListOwnerAuthorityProfiles({ limit: 50, offset: 0, query: q || undefined }),
647
+ [...AUTH_OWNER_AUTHORITIES(aID), trimmed],
648
+ { query: trimmed },
649
+ { enabled: isAuthValid && Boolean(aID) },
650
+ );
651
+ };
652
+
653
+ export const useUpdateAuthorityProfileRoles = () => {
654
+ const auth = useAuthRepository();
655
+ const accountId = AuthStore.getState().currentAccountId;
656
+ const { t } = useTranslation("hooks", { keyPrefix: "account" });
657
+ return useMutation({
658
+ mutationFn: ({ profileId, authorityRoles }: { profileId: string; authorityRoles: Profile.Request.UpdateAuthorityProfileRoles["authorityRoles"] }) =>
659
+ auth.UpdateAuthorityProfileRoles(profileId, { authorityRoles }),
660
+ onSuccess: () => {
661
+ authEventEmitter.invalidateOwner(accountId);
662
+ systemEventEmitter.showSuccess(t("updateRolesSuccess", { defaultValue: "Roles updated." }));
663
+ },
664
+ onError: (error: AxiosError) => {
665
+ systemEventEmitter.showError(getApiErrorMessage(error, "[useUpdateAuthorityProfileRoles] error"));
666
+ },
667
+ });
668
+ };
669
+
444
670
  export { hasSelectedProfile, AuthStore, useAuthStore };
445
671
  export { LanguageEnum, AuthSignupPlatformEnum };
@@ -14,4 +14,4 @@ export {
14
14
  usePreferenceLabel,
15
15
  getThemeDisplayName,
16
16
  useThemeLabel,
17
- } from "@/languages/hooks";
17
+ } from "nfx-ui/languages/hooks";
@@ -1,19 +1,19 @@
1
1
  /**
2
2
  * Shared preference hooks — appearance resolve + host-configured server sync.
3
3
  */
4
- import type { PreferencePatch, ResolvedPreference } from "@/stores/preference";
5
- import type { RadixAppearance } from "@/themes/radix";
4
+ import type { PreferencePatch, ResolvedPreference } from "nfx-ui/stores/preference";
5
+ import type { RadixAppearance } from "nfx-ui/themes/radix";
6
6
 
7
7
  import { useEffect, useRef, useState } from "react";
8
8
 
9
- import { AppearanceEnum } from "@/enums/theme";
9
+ import { AppearanceEnum } from "nfx-ui/enums/theme";
10
10
  import {
11
11
  PreferenceStore,
12
12
  replacePreference,
13
13
  setPreference,
14
14
  usePreferenceStore,
15
- } from "@/stores/preference";
16
- import { readSystemRadixAppearance, resolveRadixAppearance } from "@/themes/radix";
15
+ } from "nfx-ui/stores/preference";
16
+ import { readSystemRadixAppearance, resolveRadixAppearance } from "nfx-ui/themes/radix";
17
17
 
18
18
  /** 将 theme.appearance(含 system)解析为当前生效的 Radix light|dark,并在跟随系统时响应 OS 切换。 */
19
19
  export function useResolvedAppearance(): RadixAppearance {
@@ -1,7 +1,7 @@
1
1
  import i18n from "i18next";
2
2
  import { useTranslation } from "react-i18next";
3
3
 
4
- import { BaseEnum } from "@/enums/theme";
4
+ import { BaseEnum } from "nfx-ui/enums/theme";
5
5
  import { LanguageEnum } from "../types";
6
6
 
7
7
  function getLanguageI18nKey(lang: LanguageEnum): string {
@@ -2,7 +2,7 @@
2
2
  * 返回 { getLayoutDisplayName },便于扩展;getLayoutDisplayName 可传给 SlideDownSwitcher 的 getDisplayName。
3
3
  * Returns { getLayoutDisplayName } for extensibility; pass to SlideDownSwitcher getDisplayName.
4
4
  */
5
- import type { LayoutModeEnum } from "@/enums/layout";
5
+ import type { LayoutModeEnum } from "nfx-ui/enums/layout";
6
6
 
7
7
  import { useCallback, useMemo } from "react";
8
8
 
@@ -2,7 +2,7 @@
2
2
  * 返回 { getPreferenceDisplayName }(Base 展示名),便于扩展;可传给 SlideDownSwitcher 的 getDisplayName。
3
3
  * Returns { getPreferenceDisplayName } for extensibility; pass to SlideDownSwitcher getDisplayName.
4
4
  */
5
- import type { BaseEnum } from "@/enums/theme";
5
+ import type { BaseEnum } from "nfx-ui/enums/theme";
6
6
 
7
7
  import { useCallback, useMemo } from "react";
8
8
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Accent / appearance labels for ThemeSettings.
3
3
  */
4
- import type { AccentColorEnum } from "@/enums/theme";
4
+ import type { AccentColorEnum } from "nfx-ui/enums/theme";
5
5
 
6
6
  import { useCallback, useMemo } from "react";
7
7
 
@@ -8,9 +8,9 @@ import i18n from "i18next";
8
8
  import LanguageDetector from "i18next-browser-languagedetector";
9
9
  import { initReactI18next } from "react-i18next";
10
10
 
11
- import { LanguageEnum, LANGUAGE_VALUES } from "@/enums/language";
12
- import { PreferenceStore, setPreference } from "@/stores/preference";
13
- import { safeEnum, safeStringable } from "@/utils/safe";
11
+ import { LanguageEnum, LANGUAGE_VALUES } from "nfx-ui/enums/language";
12
+ import { PreferenceStore, setPreference } from "nfx-ui/stores/preference";
13
+ import { safeEnum, safeStringable } from "nfx-ui/utils/safe";
14
14
 
15
15
  import { getDefaultNfxBundles } from "../resources";
16
16
 
@@ -5,7 +5,7 @@
5
5
  import type { CreateI18nResourcesResult, LanguageEnum, NameSpacesMap, Resources } from "../types";
6
6
 
7
7
  import i18n from "./i18n";
8
- import { setPreference } from "@/stores/preference";
8
+ import { setPreference } from "nfx-ui/stores/preference";
9
9
 
10
10
  /**
11
11
  * 由调用方传入 resources 和 nameSpacesMap,生成 i18n 所需的 RESOURCES、NAME_SPACES_MAP、NAME_SPACES。
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * 语言相关组件的 Props 类型。
3
3
  */
4
- export type { LanguageProviderProps } from "@/providers/LanguageProvider";
4
+ export type { LanguageProviderProps } from "nfx-ui/providers/LanguageProvider";
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * 语言枚举与常量 — 从 enums 再导出,避免 languages 模块重复定义。
3
3
  */
4
- export { LanguageEnum, DEFAULT_LANGUAGE, LANGUAGE_VALUES, Language } from "@/enums/language";
4
+ export { LanguageEnum, DEFAULT_LANGUAGE, LANGUAGE_VALUES, Language } from "nfx-ui/enums/language";
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * 获取本地语言:PreferenceStore 为唯一真相。
3
3
  */
4
- import { PreferenceStore } from "@/stores/preference";
5
- import { DEFAULT_LANGUAGE, type LanguageEnum } from "@/enums/language";
4
+ import { PreferenceStore } from "nfx-ui/stores/preference";
5
+ import { DEFAULT_LANGUAGE, type LanguageEnum } from "nfx-ui/enums/language";
6
6
 
7
7
  export function getLocalLanguage(): LanguageEnum {
8
8
  return PreferenceStore.getState().language ?? DEFAULT_LANGUAGE;
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Language helpers backed by PreferenceStore (CityPulso: no separate language-storage key).
3
3
  */
4
- import type { Nilable } from "@/types/utils";
4
+ import type { Nilable } from "nfx-ui/types/utils";
5
5
 
6
- import { LANGUAGE_VALUES, LanguageEnum } from "@/enums/language";
7
- import { PreferenceStore, setPreference } from "@/stores/preference";
6
+ import { LANGUAGE_VALUES, LanguageEnum } from "nfx-ui/enums/language";
7
+ import { PreferenceStore, setPreference } from "nfx-ui/stores/preference";
8
8
 
9
9
  export function getLanguageStorage(): Nilable<LanguageEnum> {
10
10
  const raw = PreferenceStore.getState().language;
@@ -2,7 +2,7 @@
2
2
  * Guest-only outlet — redirects away when session + profile are already selected.
3
3
  * Host supplies product home path via `redirectTo`.
4
4
  */
5
- import { hasSelectedProfile, useAuthStore } from "@/stores/auth";
5
+ import { hasSelectedProfile, useAuthStore } from "nfx-ui/stores/auth";
6
6
  import { Navigate, Outlet } from "react-router";
7
7
 
8
8
  export interface GuestRouteProps {
@@ -2,7 +2,7 @@
2
2
  * Auth-gated outlet — redirects to login when session/profile missing.
3
3
  * Host supplies product login path via `redirectTo`.
4
4
  */
5
- import { hasSelectedProfile, useAuthStore } from "@/stores/auth";
5
+ import { hasSelectedProfile, useAuthStore } from "nfx-ui/stores/auth";
6
6
  import { Navigate, Outlet, useLocation } from "react-router";
7
7
 
8
8
  export interface ProtectedRouteProps {
@@ -1,13 +1,13 @@
1
- import type { IdentityRepositories } from "@/apis";
1
+ import type { IdentityRepositories } from "nfx-ui/apis";
2
2
  import type { ReactNode } from "react";
3
3
 
4
4
  import { useEffect, useMemo } from "react";
5
- import { ApiAssetRepository, ApiAuthRepository, IdentityRepositoriesContext, setIdentityRepositories, useAuthRepository } from "@/apis";
6
- import { scheduleAccessTokenRefresh } from "@/apis/authRefresh";
7
- import { useAuthQueryScope, useCurrentProfile } from "@/hooks/auth";
8
- import { configurePreferenceSync, useApplyPreferenceOnLoad } from "@/hooks/preference";
9
- import { AuthStore, hasSelectedProfile, subscribeAuthStorageSync } from "@/stores/auth";
10
- import { parseServerPreference, toServerPreference } from "@/stores/preference";
5
+ import { ApiAssetRepository, ApiAuthRepository, IdentityRepositoriesContext, setIdentityRepositories, useAuthRepository } from "nfx-ui/apis";
6
+ import { scheduleAccessTokenRefresh } from "nfx-ui/apis/authRefresh";
7
+ import { useAuthQueryScope, useCurrentProfile } from "nfx-ui/hooks/auth";
8
+ import { configurePreferenceSync, useApplyPreferenceOnLoad } from "nfx-ui/hooks/preference";
9
+ import { AuthStore, hasSelectedProfile, subscribeAuthStorageSync } from "nfx-ui/stores/auth";
10
+ import { parseServerPreference, toServerPreference } from "nfx-ui/stores/preference";
11
11
 
12
12
  const defaultIdentityRepositories: IdentityRepositories = {
13
13
  auth: new ApiAuthRepository(),
@@ -2,16 +2,16 @@
2
2
  * Shared LanguageProvider — host passes product builtin bundles.
3
3
  * Identity error/message namespaces load here (PulsoLink LanguageProvider pattern).
4
4
  */
5
- import type { CreateI18nResourcesResult, ExtraBundleItem, onLoadExtraBundles } from "@/languages/types";
5
+ import type { CreateI18nResourcesResult, ExtraBundleItem, onLoadExtraBundles } from "nfx-ui/languages/types";
6
6
  import type { ReactNode } from "react";
7
7
 
8
8
  import { useEffect, useRef } from "react";
9
9
 
10
- import { getIdentityRepositories } from "@/apis";
11
- import { DEFAULT_LANGUAGE, LANGUAGE_VALUES, LanguageEnum } from "@/enums/language";
12
- import i18n, { initI18n, toSupportedLanguage } from "@/languages/languages/i18n";
13
- import { PreferenceStore } from "@/stores/preference";
14
- import { ERRORS_NS_IDENTITY, MESSAGES_NS_IDENTITY } from "@/utils/apiError";
10
+ import { getIdentityRepositories } from "nfx-ui/apis";
11
+ import { DEFAULT_LANGUAGE, LANGUAGE_VALUES, LanguageEnum } from "nfx-ui/enums/language";
12
+ import i18n, { initI18n, toSupportedLanguage } from "nfx-ui/languages/languages/i18n";
13
+ import { PreferenceStore } from "nfx-ui/stores/preference";
14
+ import { ERRORS_NS_IDENTITY, MESSAGES_NS_IDENTITY } from "nfx-ui/utils/apiError";
15
15
 
16
16
  export interface LanguageProviderProps {
17
17
  children: ReactNode;
@@ -2,16 +2,16 @@
2
2
  * Shared Radix Theme provider — reads unified preference store.
3
3
  * Host may pass document side-effects (e.g. favicon) via `onAppearanceChange`.
4
4
  */
5
- import type { RadixAppearance } from "@/themes/radix";
5
+ import type { RadixAppearance } from "nfx-ui/themes/radix";
6
6
  import type { ReactNode } from "react";
7
7
 
8
8
  import { useEffect } from "react";
9
9
  import { Theme } from "@radix-ui/themes";
10
10
 
11
- import { useResolvedAppearance } from "@/hooks/preference";
12
- import { usePreferenceStore } from "@/stores/preference";
11
+ import { useResolvedAppearance } from "nfx-ui/hooks/preference";
12
+ import { usePreferenceStore } from "nfx-ui/stores/preference";
13
13
 
14
- import "@/themes/index.css";
14
+ import "nfx-ui/themes/index.css";
15
15
 
16
16
  export interface ThemeProviderProps {
17
17
  children: ReactNode;
@@ -30,3 +30,28 @@ export const useInitLoginForm = () => {
30
30
  },
31
31
  });
32
32
  };
33
+
34
+ export function createLoginWithPhoneSchema(t: TFunction) {
35
+ return z.object({
36
+ phone: z.string().min(1, t("form.validation.phoneRequired")).min(6, t("form.validation.phoneInvalid")),
37
+ password: z.string().min(1, t("form.validation.passwordRequired")),
38
+ rememberMe: z.boolean().optional(),
39
+ });
40
+ }
41
+
42
+ export type LoginWithPhoneFormData = z.infer<ReturnType<typeof createLoginWithPhoneSchema>>;
43
+
44
+ export const useInitLoginWithPhoneForm = () => {
45
+ const { t } = useTranslation("pages.Account.Login");
46
+ const schema = createLoginWithPhoneSchema(t);
47
+
48
+ return useForm<LoginWithPhoneFormData>({
49
+ resolver: zodResolver(schema),
50
+ mode: "onChange",
51
+ defaultValues: {
52
+ phone: "",
53
+ password: "",
54
+ rememberMe: false,
55
+ },
56
+ });
57
+ };
@@ -1,10 +1,10 @@
1
1
  import type { TFunction } from "i18next";
2
- import type { Profile } from "@/types";
2
+ import type { Profile } from "nfx-ui/types";
3
3
 
4
4
  import { zodResolver } from "@hookform/resolvers/zod";
5
- import { Language, LanguageEnum } from "@/enums";
6
- import { toDateInputValue } from "@/utils/time";
7
- import { safeStringable } from "@/utils/safe";
5
+ import { Language, LanguageEnum } from "nfx-ui/enums";
6
+ import { toDateInputValue } from "nfx-ui/utils/time";
7
+ import { safeStringable } from "nfx-ui/utils/safe";
8
8
  import { useForm } from "react-hook-form";
9
9
  import { useTranslation } from "react-i18next";
10
10
  import { z } from "zod";
@@ -1,7 +1,7 @@
1
1
  import type { TFunction } from "i18next";
2
2
 
3
3
  import { zodResolver } from "@hookform/resolvers/zod";
4
- import { normalizeVerificationCode, VERIFICATION_CODE_ALPHABET } from "@/utils/domain/verificationCode";
4
+ import { normalizeVerificationCode, VERIFICATION_CODE_ALPHABET } from "nfx-ui/utils/domain/verificationCode";
5
5
  import { useForm } from "react-hook-form";
6
6
  import { useTranslation } from "react-i18next";
7
7
  import { z } from "zod";
@@ -1,7 +1,7 @@
1
- import type { Tokens } from "@/types";
1
+ import type { Tokens } from "nfx-ui/types";
2
2
 
3
- import { DEFAULT_PROFILE_KIND, ProfileKind, ProfileKindEnum } from "@/enums";
4
- import { makeStore } from "@/stores/makeStore";
3
+ import { DEFAULT_PROFILE_KIND, ProfileKind, ProfileKindEnum } from "nfx-ui/enums";
4
+ import { makeStore } from "nfx-ui/stores/makeStore";
5
5
 
6
6
  /**
7
7
  * Auth session: memory is source of truth.
@@ -3,4 +3,4 @@ export * from "./preference";
3
3
  export * from "./layout";
4
4
  export * from "./auth";
5
5
  export * from "./system";
6
- export { DashboardBackgroundEnum, DEFAULT_DASHBOARD_BACKGROUND, DASHBOARD_BACKGROUND_VALUES } from "@/enums/dashboard";
6
+ export { DashboardBackgroundEnum, DEFAULT_DASHBOARD_BACKGROUND, DASHBOARD_BACKGROUND_VALUES } from "nfx-ui/enums/dashboard";
@@ -1,4 +1,4 @@
1
- import { makePersistStore } from "@/stores/makeStore";
1
+ import { makePersistStore } from "nfx-ui/stores/makeStore";
2
2
 
3
3
  interface LayoutState {
4
4
  headerHeight: number;
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * Shared preference store — theme + language + layout (no map/billing/event).
3
3
  */
4
- import { DEFAULT_LAYOUT_MODE, LayoutModeEnum } from "@/enums/layout";
5
- import { DEFAULT_LANGUAGE, Language, type LanguageEnum } from "@/enums/language";
6
- import { DashboardBackground, DEFAULT_DASHBOARD_BACKGROUND, DashboardBackgroundEnum } from "@/enums/dashboard";
7
- import { getDefaultThemePreference, resolveThemePreference, type ResolvedThemePreference } from "@/themes/radix";
8
- import { makePersistStore } from "@/stores/makeStore";
4
+ import { DEFAULT_LAYOUT_MODE, LayoutModeEnum } from "nfx-ui/enums/layout";
5
+ import { DEFAULT_LANGUAGE, Language, type LanguageEnum } from "nfx-ui/enums/language";
6
+ import { DashboardBackground, DEFAULT_DASHBOARD_BACKGROUND, DashboardBackgroundEnum } from "nfx-ui/enums/dashboard";
7
+ import { getDefaultThemePreference, resolveThemePreference, type ResolvedThemePreference } from "nfx-ui/themes/radix";
8
+ import { makePersistStore } from "nfx-ui/stores/makeStore";
9
9
 
10
10
  export interface ResolvedPreference {
11
11
  language: LanguageEnum;
@@ -1,2 +1,2 @@
1
1
  export * from "./useTheme";
2
- export { useResolvedAppearance } from "@/hooks/preference";
2
+ export { useResolvedAppearance } from "nfx-ui/hooks/preference";