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.
- package/dist/apis/authRefresh.js.map +1 -1
- package/dist/apis/clients.js.map +1 -1
- package/dist/apis/ip.d.ts.map +1 -1
- package/dist/apis/ip.js.map +1 -1
- package/dist/apis/repositories/AssetRepository.d.ts.map +1 -1
- package/dist/apis/repositories/AssetRepository.js.map +1 -1
- package/dist/apis/repositories/AuthRepository.d.ts.map +1 -1
- package/dist/apis/repositories/AuthRepository.js.map +1 -1
- package/dist/config/env.js.map +1 -1
- package/dist/constants/index.js +5 -5
- package/dist/constants/key.d.ts +4 -0
- package/dist/constants/key.d.ts.map +1 -1
- package/dist/constants/key.js +23 -1
- package/dist/constants/key.js.map +1 -1
- package/dist/constants/querykeys.js.map +1 -1
- package/dist/enums/auth.d.ts.map +1 -1
- package/dist/enums/auth.js.map +1 -1
- package/dist/enums/dashboard.d.ts.map +1 -1
- package/dist/enums/dashboard.js.map +1 -1
- package/dist/enums/language.d.ts.map +1 -1
- package/dist/enums/language.js.map +1 -1
- package/dist/enums/layout.d.ts.map +1 -1
- package/dist/enums/layout.js.map +1 -1
- package/dist/enums/theme.d.ts.map +1 -1
- package/dist/enums/theme.js.map +1 -1
- package/dist/events/EventEmitter.d.ts.map +1 -1
- package/dist/events/EventEmitter.js.map +1 -1
- package/dist/events/auth.d.ts +4 -0
- package/dist/events/auth.d.ts.map +1 -1
- package/dist/events/auth.js +9 -1
- package/dist/events/auth.js.map +1 -1
- package/dist/events/query.d.ts.map +1 -1
- package/dist/events/query.js.map +1 -1
- package/dist/events/system.d.ts.map +1 -1
- package/dist/events/system.js.map +1 -1
- package/dist/hooks/asset.d.ts +1 -0
- package/dist/hooks/asset.d.ts.map +1 -1
- package/dist/hooks/asset.js +10 -7
- package/dist/hooks/asset.js.map +1 -1
- package/dist/hooks/auth.d.ts +27 -0
- package/dist/hooks/auth.d.ts.map +1 -1
- package/dist/hooks/auth.js +256 -111
- package/dist/hooks/auth.js.map +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -9
- package/dist/hooks/preference.d.ts.map +1 -1
- package/dist/hooks/preference.js.map +1 -1
- package/dist/languages/hooks/useLanguageLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useLanguageLabel.js.map +1 -1
- package/dist/languages/hooks/useLayoutLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useLayoutLabel.js.map +1 -1
- package/dist/languages/hooks/usePreferenceLabel.d.ts.map +1 -1
- package/dist/languages/hooks/usePreferenceLabel.js.map +1 -1
- package/dist/languages/hooks/useThemeLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useThemeLabel.js.map +1 -1
- package/dist/languages/languages/i18n.d.ts.map +1 -1
- package/dist/languages/languages/i18n.js.map +1 -1
- package/dist/languages/languages/i18nResources.js.map +1 -1
- package/dist/languages/types/components.d.ts.map +1 -1
- package/dist/languages/types/language.d.ts.map +1 -1
- package/dist/languages/utils/getLocalLanguage.d.ts.map +1 -1
- package/dist/languages/utils/getLocalLanguage.js.map +1 -1
- package/dist/languages/utils/languageStorage.d.ts.map +1 -1
- package/dist/languages/utils/languageStorage.js.map +1 -1
- package/dist/navigations/GuestRoute.js.map +1 -1
- package/dist/navigations/ProtectedRoute.js.map +1 -1
- package/dist/providers/DataProvider/index.d.ts.map +1 -1
- package/dist/providers/DataProvider/index.js.map +1 -1
- package/dist/providers/LanguageProvider/index.d.ts.map +1 -1
- package/dist/providers/LanguageProvider/index.js.map +1 -1
- package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
- package/dist/providers/ThemeProvider/index.js.map +1 -1
- package/dist/schemas/index.js +4 -4
- package/dist/schemas/loginSchema.d.ts +15 -0
- package/dist/schemas/loginSchema.d.ts.map +1 -1
- package/dist/schemas/loginSchema.js +20 -1
- package/dist/schemas/loginSchema.js.map +1 -1
- package/dist/schemas/profileEditSchema.d.ts.map +1 -1
- package/dist/schemas/profileEditSchema.js.map +1 -1
- package/dist/schemas/signupSchema.js.map +1 -1
- package/dist/stores/auth.d.ts.map +1 -1
- package/dist/stores/auth.js.map +1 -1
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/layout.js.map +1 -1
- package/dist/stores/preference.d.ts.map +1 -1
- package/dist/stores/preference.js.map +1 -1
- package/dist/themes/hooks/index.d.ts.map +1 -1
- package/dist/themes/hooks/useTheme.d.ts.map +1 -1
- package/dist/themes/hooks/useTheme.js.map +1 -1
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/radix/mappings.d.ts.map +1 -1
- package/dist/themes/radix/mappings.js.map +1 -1
- package/dist/themes/types/components.d.ts.map +1 -1
- package/dist/themes/types/context.d.ts.map +1 -1
- package/dist/themes/types/index.d.ts.map +1 -1
- package/dist/themes/types/theme.d.ts.map +1 -1
- package/dist/types/domain/auth/login.d.ts.map +1 -1
- package/dist/types/domain/auth/profile.d.ts.map +1 -1
- package/dist/types/domain/auth/signup.d.ts.map +1 -1
- package/dist/utils/apiError.d.ts.map +1 -1
- package/dist/utils/apiError.js.map +1 -1
- package/dist/utils/array.d.ts.map +1 -1
- package/dist/utils/array.js.map +1 -1
- package/dist/utils/domain/account.d.ts.map +1 -1
- package/dist/utils/domain/account.js.map +1 -1
- package/dist/utils/domain/buildProfilePatch.d.ts.map +1 -1
- package/dist/utils/domain/buildProfilePatch.js.map +1 -1
- package/dist/utils/domain/images.js.map +1 -1
- package/dist/utils/factory/hooks.d.ts.map +1 -1
- package/dist/utils/factory/hooks.js.map +1 -1
- package/dist/utils/lstorage.d.ts.map +1 -1
- package/dist/utils/lstorage.js.map +1 -1
- package/dist/utils/safe.d.ts.map +1 -1
- package/dist/utils/safe.js.map +1 -1
- package/dist/utils/suspense.d.ts.map +1 -1
- package/dist/utils/suspense.js.map +1 -1
- package/package.json +1 -1
- package/src/apis/authRefresh.ts +4 -4
- package/src/apis/clients.ts +5 -5
- package/src/apis/ip.ts +1 -1
- package/src/apis/repositories/AssetRepository.ts +1 -1
- package/src/apis/repositories/AuthRepository.ts +2 -2
- package/src/config/env.ts +1 -1
- package/src/constants/key.ts +5 -1
- package/src/constants/querykeys.ts +1 -1
- package/src/enums/auth.ts +2 -2
- package/src/enums/dashboard.ts +2 -2
- package/src/enums/language.ts +2 -2
- package/src/enums/layout.ts +2 -2
- package/src/enums/theme.ts +2 -2
- package/src/events/EventEmitter.ts +1 -1
- package/src/events/auth.ts +14 -4
- package/src/events/query.ts +3 -3
- package/src/events/system.ts +3 -3
- package/src/hooks/asset.ts +12 -7
- package/src/hooks/auth.ts +238 -12
- package/src/hooks/index.ts +1 -1
- package/src/hooks/preference.ts +5 -5
- package/src/languages/hooks/useLanguageLabel.ts +1 -1
- package/src/languages/hooks/useLayoutLabel.ts +1 -1
- package/src/languages/hooks/usePreferenceLabel.ts +1 -1
- package/src/languages/hooks/useThemeLabel.ts +1 -1
- package/src/languages/languages/i18n.ts +3 -3
- package/src/languages/languages/i18nResources.ts +1 -1
- package/src/languages/types/components.ts +1 -1
- package/src/languages/types/language.ts +1 -1
- package/src/languages/utils/getLocalLanguage.ts +2 -2
- package/src/languages/utils/languageStorage.ts +3 -3
- package/src/navigations/GuestRoute.tsx +1 -1
- package/src/navigations/ProtectedRoute.tsx +1 -1
- package/src/providers/DataProvider/index.tsx +7 -7
- package/src/providers/LanguageProvider/index.tsx +6 -6
- package/src/providers/ThemeProvider/index.tsx +4 -4
- package/src/schemas/loginSchema.ts +25 -0
- package/src/schemas/profileEditSchema.ts +4 -4
- package/src/schemas/signupSchema.ts +1 -1
- package/src/stores/auth.ts +3 -3
- package/src/stores/index.ts +1 -1
- package/src/stores/layout.ts +1 -1
- package/src/stores/preference.ts +5 -5
- package/src/themes/hooks/index.ts +1 -1
- package/src/themes/hooks/useTheme.ts +4 -4
- package/src/themes/index.ts +2 -2
- package/src/themes/radix/mappings.ts +2 -2
- package/src/themes/types/components.ts +1 -1
- package/src/themes/types/context.ts +2 -2
- package/src/themes/types/index.ts +1 -1
- package/src/themes/types/theme.ts +1 -1
- package/src/types/domain/auth/login.ts +2 -2
- package/src/types/domain/auth/profile.ts +1 -1
- package/src/types/domain/auth/signup.ts +1 -1
- package/src/utils/apiError.ts +2 -2
- package/src/utils/array.ts +1 -1
- package/src/utils/domain/account.ts +2 -2
- package/src/utils/domain/buildProfilePatch.ts +6 -6
- package/src/utils/domain/images.ts +1 -1
- package/src/utils/factory/hooks.ts +1 -1
- package/src/utils/lstorage.ts +1 -1
- package/src/utils/safe.ts +1 -1
- 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 "
|
|
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 "
|
|
10
|
-
import { AUTH_EMAILS, AUTH_ME, AUTH_PHONES, AUTH_PROFILES } from "
|
|
11
|
-
import { AuthSignupPlatformEnum, LanguageEnum, ProfileKindEnum } from "
|
|
12
|
-
import { authEventEmitter, authEvents } from "
|
|
13
|
-
import { systemEventEmitter } from "
|
|
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 "
|
|
26
|
-
import { ensureDeviceIdStorage } from "
|
|
27
|
-
import { getApiErrorMessage } from "
|
|
28
|
-
import { pickProfile } from "
|
|
29
|
-
import { useUnifiedQuery } from "
|
|
30
|
-
import { safeOr, safeStringable } from "
|
|
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 };
|
package/src/hooks/index.ts
CHANGED
package/src/hooks/preference.ts
CHANGED
|
@@ -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 "
|
|
5
|
-
import type { RadixAppearance } from "
|
|
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 "
|
|
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 "
|
|
16
|
-
import { readSystemRadixAppearance, resolveRadixAppearance } from "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
5
|
+
import type { BaseEnum } from "nfx-ui/enums/theme";
|
|
6
6
|
|
|
7
7
|
import { useCallback, useMemo } from "react";
|
|
8
8
|
|
|
@@ -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 "
|
|
12
|
-
import { PreferenceStore, setPreference } from "
|
|
13
|
-
import { safeEnum, safeStringable } from "
|
|
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 "
|
|
8
|
+
import { setPreference } from "nfx-ui/stores/preference";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* 由调用方传入 resources 和 nameSpacesMap,生成 i18n 所需的 RESOURCES、NAME_SPACES_MAP、NAME_SPACES。
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 获取本地语言:PreferenceStore 为唯一真相。
|
|
3
3
|
*/
|
|
4
|
-
import { PreferenceStore } from "
|
|
5
|
-
import { DEFAULT_LANGUAGE, type LanguageEnum } from "
|
|
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 "
|
|
4
|
+
import type { Nilable } from "nfx-ui/types/utils";
|
|
5
5
|
|
|
6
|
-
import { LANGUAGE_VALUES, LanguageEnum } from "
|
|
7
|
-
import { PreferenceStore, setPreference } from "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
6
|
-
import { scheduleAccessTokenRefresh } from "
|
|
7
|
-
import { useAuthQueryScope, useCurrentProfile } from "
|
|
8
|
-
import { configurePreferenceSync, useApplyPreferenceOnLoad } from "
|
|
9
|
-
import { AuthStore, hasSelectedProfile, subscribeAuthStorageSync } from "
|
|
10
|
-
import { parseServerPreference, toServerPreference } from "
|
|
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 "
|
|
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 "
|
|
11
|
-
import { DEFAULT_LANGUAGE, LANGUAGE_VALUES, LanguageEnum } from "
|
|
12
|
-
import i18n, { initI18n, toSupportedLanguage } from "
|
|
13
|
-
import { PreferenceStore } from "
|
|
14
|
-
import { ERRORS_NS_IDENTITY, MESSAGES_NS_IDENTITY } from "
|
|
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 "
|
|
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 "
|
|
12
|
-
import { usePreferenceStore } from "
|
|
11
|
+
import { useResolvedAppearance } from "nfx-ui/hooks/preference";
|
|
12
|
+
import { usePreferenceStore } from "nfx-ui/stores/preference";
|
|
13
13
|
|
|
14
|
-
import "
|
|
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 "
|
|
2
|
+
import type { Profile } from "nfx-ui/types";
|
|
3
3
|
|
|
4
4
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
-
import { Language, LanguageEnum } from "
|
|
6
|
-
import { toDateInputValue } from "
|
|
7
|
-
import { safeStringable } from "
|
|
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 "
|
|
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";
|
package/src/stores/auth.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Tokens } from "
|
|
1
|
+
import type { Tokens } from "nfx-ui/types";
|
|
2
2
|
|
|
3
|
-
import { DEFAULT_PROFILE_KIND, ProfileKind, ProfileKindEnum } from "
|
|
4
|
-
import { makeStore } from "
|
|
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.
|
package/src/stores/index.ts
CHANGED
|
@@ -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 "
|
|
6
|
+
export { DashboardBackgroundEnum, DEFAULT_DASHBOARD_BACKGROUND, DASHBOARD_BACKGROUND_VALUES } from "nfx-ui/enums/dashboard";
|
package/src/stores/layout.ts
CHANGED
package/src/stores/preference.ts
CHANGED
|
@@ -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 "
|
|
5
|
-
import { DEFAULT_LANGUAGE, Language, type LanguageEnum } from "
|
|
6
|
-
import { DashboardBackground, DEFAULT_DASHBOARD_BACKGROUND, DashboardBackgroundEnum } from "
|
|
7
|
-
import { getDefaultThemePreference, resolveThemePreference, type ResolvedThemePreference } from "
|
|
8
|
-
import { makePersistStore } from "
|
|
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 "
|
|
2
|
+
export { useResolvedAppearance } from "nfx-ui/hooks/preference";
|