feat: 重构用户认证逻辑,添加导航重定向功能,更新相关组件和路由
This commit is contained in:
4
auto-imports.d.ts
vendored
4
auto-imports.d.ts
vendored
@@ -234,6 +234,7 @@ declare global {
|
|||||||
const useMouseInElement: typeof import('@vueuse/core').useMouseInElement
|
const useMouseInElement: typeof import('@vueuse/core').useMouseInElement
|
||||||
const useMousePressed: typeof import('@vueuse/core').useMousePressed
|
const useMousePressed: typeof import('@vueuse/core').useMousePressed
|
||||||
const useMutationObserver: typeof import('@vueuse/core').useMutationObserver
|
const useMutationObserver: typeof import('@vueuse/core').useMutationObserver
|
||||||
|
const useNavigateToRedirect: typeof import('./src/composables/useNavigateToRedirect').useNavigateToRedirect
|
||||||
const useNavigatorLanguage: typeof import('@vueuse/core').useNavigatorLanguage
|
const useNavigatorLanguage: typeof import('@vueuse/core').useNavigatorLanguage
|
||||||
const useNetwork: typeof import('@vueuse/core').useNetwork
|
const useNetwork: typeof import('@vueuse/core').useNetwork
|
||||||
const useNow: typeof import('@vueuse/core').useNow
|
const useNow: typeof import('@vueuse/core').useNow
|
||||||
@@ -372,7 +373,6 @@ declare module 'vue' {
|
|||||||
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
||||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||||
readonly beforeApp: UnwrapRef<typeof import('./src/composables/beforeApp')['beforeApp']>
|
|
||||||
readonly clearExpiredCaches: UnwrapRef<typeof import('./src/composables/useStorageCache')['clearExpiredCaches']>
|
readonly clearExpiredCaches: UnwrapRef<typeof import('./src/composables/useStorageCache')['clearExpiredCaches']>
|
||||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||||
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
|
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
|
||||||
@@ -516,7 +516,6 @@ declare module 'vue' {
|
|||||||
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
|
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
|
||||||
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
|
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
|
||||||
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
|
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
|
||||||
readonly useAuth: UnwrapRef<typeof import('./src/composables/useAuth')['useAuth']>
|
|
||||||
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
|
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
|
||||||
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
|
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
|
||||||
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
|
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
|
||||||
@@ -595,6 +594,7 @@ declare module 'vue' {
|
|||||||
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
|
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
|
||||||
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
|
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
|
||||||
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
|
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
|
||||||
|
readonly useNavigateToRedirect: UnwrapRef<typeof import('./src/composables/useNavigateToRedirect')['useNavigateToRedirect']>
|
||||||
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
|
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
|
||||||
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
|
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
|
||||||
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
|
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { App as CapacitorApp } from "@capacitor/app";
|
import { App as CapacitorApp } from "@capacitor/app";
|
||||||
|
|
||||||
const { isAuthenticated } = useAuth();
|
const userStore = useUserStore();
|
||||||
|
const { isAuthenticated } = storeToRefs(userStore);
|
||||||
const { locale, loadSavedLanguage } = useLanguage();
|
const { locale, loadSavedLanguage } = useLanguage();
|
||||||
|
const { initializeWallet } = useWalletStore();
|
||||||
|
const { updateProfile } = useUserStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
updateProfile();
|
||||||
|
initializeWallet();
|
||||||
CapacitorApp.addListener("appStateChange", async ({ isActive }) => {
|
CapacitorApp.addListener("appStateChange", async ({ isActive }) => {
|
||||||
if (isActive && isAuthenticated.value) {
|
if (isActive && isAuthenticated.value) {
|
||||||
await userStore.updateProfile();
|
await userStore.updateProfile();
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ const client = treaty<App>(window.location.origin, {
|
|||||||
fetch: {
|
fetch: {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
},
|
},
|
||||||
|
headers() {
|
||||||
|
const token = localStorage.getItem("user-token") || "";
|
||||||
|
return {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": token ? `Bearer ${token}` : "",
|
||||||
|
};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface SafeClientOptions {
|
export interface SafeClientOptions {
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
export function beforeApp() {
|
|
||||||
const { updateProfile } = useUserStore();
|
|
||||||
const { initializeWallet } = useWalletStore();
|
|
||||||
|
|
||||||
return new Promise<void>((resolve) => {
|
|
||||||
useAuth().then((session) => {
|
|
||||||
if (session) {
|
|
||||||
updateProfile();
|
|
||||||
initializeWallet();
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import type { UnwrapRef } from "vue";
|
|
||||||
import { safeClient } from "@/api";
|
|
||||||
import { authClient } from "@/auth";
|
|
||||||
|
|
||||||
type User = UnwrapRef<ReturnType<typeof authClient.useSession> extends Promise<infer R extends { data: any }> ? R["data"] : never>;
|
|
||||||
|
|
||||||
export function useAuth() {
|
|
||||||
const session = ref<User | null>(null);
|
|
||||||
|
|
||||||
if (session.value === undefined) {
|
|
||||||
safeClient(authClient.getSession()).then((res) => {
|
|
||||||
session.value = res.data.value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = computed(() => session.value?.user);
|
|
||||||
const isAuthenticated = computed(() => !!session.value);
|
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
session,
|
|
||||||
isAuthenticated,
|
|
||||||
then(onfulfilled: (value: User | null) => void) {
|
|
||||||
return safeClient(authClient.getSession()).then((res) => {
|
|
||||||
session.value = res.data.value;
|
|
||||||
onfulfilled(session.value);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
12
src/composables/useNavigateToRedirect.ts
Normal file
12
src/composables/useNavigateToRedirect.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import type { LocationQueryValue } from "vue-router";
|
||||||
|
import { router } from "@/router";
|
||||||
|
|
||||||
|
export function useNavigateToRedirect(redirect: LocationQueryValue): void;
|
||||||
|
|
||||||
|
export function useNavigateToRedirect(redirect: LocationQueryValue[], index: number): void;
|
||||||
|
|
||||||
|
export function useNavigateToRedirect(redirect: LocationQueryValue | LocationQueryValue[], index?: number) {
|
||||||
|
const _redirect = Array.isArray(redirect) ? redirect[index || 0] as string : redirect as string;
|
||||||
|
const path = decodeURIComponent(_redirect || "/");
|
||||||
|
router.replace(path);
|
||||||
|
}
|
||||||
@@ -47,8 +47,6 @@ const app = createApp(App)
|
|||||||
.use(router)
|
.use(router)
|
||||||
.use(i18n);
|
.use(i18n);
|
||||||
|
|
||||||
beforeApp().then(() => {
|
router.isReady().then(() => {
|
||||||
router.isReady().then(() => {
|
app.mount("#app");
|
||||||
app.mount("#app");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,11 @@ import type { Router } from "vue-router";
|
|||||||
|
|
||||||
export function createRouterGuard(router: Router) {
|
export function createRouterGuard(router: Router) {
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
if (to.meta.requiresAuth && !userStore.isAuthenticated) {
|
||||||
|
const redirect = encodeURIComponent(to.fullPath);
|
||||||
|
return next({ path: "/auth/login", query: { redirect } });
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,40 +36,49 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: "user",
|
path: "user",
|
||||||
component: () => import("@/views/user/index.vue"),
|
component: () => import("@/views/user/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/onchain-address",
|
path: "/onchain-address",
|
||||||
component: () => import("@/views/onchain-address/index.vue"),
|
component: () => import("@/views/onchain-address/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/deposit/fiat",
|
path: "/deposit/fiat",
|
||||||
component: () => import("@/views/deposit/fiat.vue"),
|
component: () => import("@/views/deposit/fiat.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/withdraw/index",
|
path: "/withdraw/index",
|
||||||
component: () => import("@/views/withdraw/index.vue"),
|
component: () => import("@/views/withdraw/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/user/settings",
|
path: "/user/settings",
|
||||||
component: () => import("@/views/user-settings/outlet.vue"),
|
component: () => import("@/views/user-settings/outlet.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
component: () => import("@/views/user-settings/index.vue"),
|
component: () => import("@/views/user-settings/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "username",
|
path: "username",
|
||||||
component: () => import("@/views/user-settings/username.vue"),
|
component: () => import("@/views/user-settings/username.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "nickname",
|
path: "nickname",
|
||||||
component: () => import("@/views/user-settings/nickname.vue"),
|
component: () => import("@/views/user-settings/nickname.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "email",
|
path: "email",
|
||||||
component: () => import("@/views/user-settings/email.vue"),
|
component: () => import("@/views/user-settings/email.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -95,23 +104,28 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
path: "/issue/issuing-apply",
|
path: "/issue/issuing-apply",
|
||||||
props: ({ query, params }) => ({ query, params }),
|
props: ({ query, params }) => ({ query, params }),
|
||||||
component: () => import("@/views/issue/issuing-apply/index.vue"),
|
component: () => import("@/views/issue/issuing-apply/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/trade-settings/bank-management",
|
path: "/trade-settings/bank-management",
|
||||||
component: () => import("@/views/trade-settings/bank-management/index.vue"),
|
component: () => import("@/views/trade-settings/bank-management/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/trade-settings/my-subscribe",
|
path: "/trade-settings/my-subscribe",
|
||||||
component: () => import("@/views/trade-settings/my-subscribe/index.vue"),
|
component: () => import("@/views/trade-settings/my-subscribe/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/trade-settings/bank-management/add",
|
path: "/trade-settings/bank-management/add",
|
||||||
component: () => import("@/views/trade-settings/bank-management/add.vue"),
|
component: () => import("@/views/trade-settings/bank-management/add.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/trade-rwa/:id",
|
path: "/trade-rwa/:id",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import("@/views/trade-rwa/index.vue"),
|
component: () => import("@/views/trade-rwa/index.vue"),
|
||||||
|
meta: { requiresAuth: true },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -2,24 +2,41 @@ import type { UserData, UserProfileData } from "@/api/types";
|
|||||||
import { client, safeClient } from "@/api";
|
import { client, safeClient } from "@/api";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
user: UserData | null;
|
||||||
userProfile: UserProfileData | null;
|
userProfile: UserProfileData | null;
|
||||||
session: UserData | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserStore = defineStore("user", () => {
|
export const useUserStore = defineStore("user", () => {
|
||||||
|
const token = useStorage<string | null>("user-token", null);
|
||||||
const state = reactive<State>({
|
const state = reactive<State>({
|
||||||
|
user: null,
|
||||||
userProfile: null,
|
userProfile: null,
|
||||||
session: null,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isAuthenticated = computed(() => token.value !== null);
|
||||||
|
|
||||||
async function updateProfile() {
|
async function updateProfile() {
|
||||||
const { data } = await safeClient(client.api.user.profile.get(), { silent: true });
|
const { data } = await safeClient(client.api.user.profile.get(), { silent: true });
|
||||||
state.userProfile = data.value?.userProfile || null;
|
state.userProfile = data.value?.userProfile || null;
|
||||||
state.session = data.value?.user || null;
|
state.user = data.value?.user || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setToken(value: string) {
|
||||||
|
token.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function signOut() {
|
||||||
|
token.value = null;
|
||||||
|
state.userProfile = null;
|
||||||
|
state.user = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
...toRefs(state),
|
||||||
|
token,
|
||||||
|
isAuthenticated,
|
||||||
|
signOut,
|
||||||
|
setToken,
|
||||||
updateProfile,
|
updateProfile,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import type { EmailVerifyClient, PhoneNumberVerifyClient } from "@/api/types";
|
import type { EmailVerifyClient, PhoneNumberVerifyClient } from "@/api/types";
|
||||||
|
import { closeOutline } from "ionicons/icons";
|
||||||
import { authClient } from "@/auth";
|
import { authClient } from "@/auth";
|
||||||
import EmailLogin from "./components/email.vue";
|
import EmailLogin from "./components/email.vue";
|
||||||
import PhoneNumberLogin from "./components/phone-number.vue";
|
import PhoneNumberLogin from "./components/phone-number.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
async function handleSignInEmail(value: EmailVerifyClient) {
|
async function handleSignInEmail(value: EmailVerifyClient) {
|
||||||
const { data } = await authClient.signIn.emailOtp({
|
const { data } = await authClient.signIn.emailOtp({
|
||||||
@@ -13,7 +16,8 @@ async function handleSignInEmail(value: EmailVerifyClient) {
|
|||||||
otp: value.otp,
|
otp: value.otp,
|
||||||
});
|
});
|
||||||
if (data?.token) {
|
if (data?.token) {
|
||||||
router.back();
|
userStore.setToken(data.token);
|
||||||
|
useNavigateToRedirect(route.query.redirect as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function handleSignInPhoneNumber(value: PhoneNumberVerifyClient) {
|
async function handleSignInPhoneNumber(value: PhoneNumberVerifyClient) {
|
||||||
@@ -24,7 +28,8 @@ async function handleSignInPhoneNumber(value: PhoneNumberVerifyClient) {
|
|||||||
updatePhoneNumber: false,
|
updatePhoneNumber: false,
|
||||||
});
|
});
|
||||||
if (data?.token) {
|
if (data?.token) {
|
||||||
router.back();
|
userStore.setToken(data.token);
|
||||||
|
useNavigateToRedirect(route.query.redirect as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -33,7 +38,11 @@ async function handleSignInPhoneNumber(value: PhoneNumberVerifyClient) {
|
|||||||
<IonPage>
|
<IonPage>
|
||||||
<IonHeader class="ion-no-border">
|
<IonHeader class="ion-no-border">
|
||||||
<IonToolbar class="ui-toolbar">
|
<IonToolbar class="ui-toolbar">
|
||||||
<ion-back-button slot="start" />
|
<ion-buttons slot="start">
|
||||||
|
<ion-button @click="$router.back()">
|
||||||
|
<ion-icon slot="icon-only" :icon="closeOutline" />
|
||||||
|
</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
<ion-button slot="end" fill="clear" @click="router.push('/auth/signup')">
|
<ion-button slot="end" fill="clear" @click="router.push('/auth/signup')">
|
||||||
{{ t('auth.login.signupButton') }}
|
{{ t('auth.login.signupButton') }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import { copyOutline, qrCodeOutline, shareOutline } from "ionicons/icons";
|
import { copyOutline, qrCodeOutline, shareOutline } from "ionicons/icons";
|
||||||
|
|
||||||
const { user } = useAuth();
|
const userStore = useUserStore();
|
||||||
|
const { user } = storeToRefs(userStore);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import * as yup from "yup";
|
|||||||
import { safeClient } from "@/api";
|
import { safeClient } from "@/api";
|
||||||
import { authClient, emailSchema } from "@/auth";
|
import { authClient, emailSchema } from "@/auth";
|
||||||
|
|
||||||
const { user } = useAuth();
|
const userStore = useUserStore();
|
||||||
|
const { user } = storeToRefs(userStore);
|
||||||
const email = ref(user.value?.email || "");
|
const email = ref(user.value?.email || "");
|
||||||
const { updateProfile } = useUserStore();
|
const { updateProfile } = useUserStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { authClient } from "@/auth";
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const { user, userProfile } = storeToRefs(userStore);
|
||||||
|
|
||||||
async function handleSignOut() {
|
async function handleSignOut() {
|
||||||
const alert = await alertController.create({
|
const alert = await alertController.create({
|
||||||
@@ -20,6 +21,7 @@ async function handleSignOut() {
|
|||||||
text: "Sign Out",
|
text: "Sign Out",
|
||||||
role: "destructive",
|
role: "destructive",
|
||||||
handler: async () => {
|
handler: async () => {
|
||||||
|
userStore.signOut();
|
||||||
authClient.signOut();
|
authClient.signOut();
|
||||||
router.replace("/layout/riwa");
|
router.replace("/layout/riwa");
|
||||||
},
|
},
|
||||||
@@ -88,7 +90,7 @@ async function handleSignOut() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="end">
|
<div class="end">
|
||||||
{{ userStore.state.userProfile?.nickname }}
|
{{ userProfile?.nickname }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
@@ -101,7 +103,7 @@ async function handleSignOut() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="end">
|
<div class="end">
|
||||||
{{ userStore.state.session?.email }}
|
{{ user?.email }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import { toastController } from "@ionic/vue";
|
import { toastController } from "@ionic/vue";
|
||||||
import { arrowBackOutline } from "ionicons/icons";
|
import { arrowBackOutline } from "ionicons/icons";
|
||||||
import { client, safeClient } from "@/api";
|
import { client, safeClient } from "@/api";
|
||||||
import { authClient } from "@/auth";
|
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const nickname = ref(userStore.state.userProfile?.nickname || "");
|
const { userProfile } = storeToRefs(userStore);
|
||||||
|
const nickname = ref(userProfile.value?.nickname || "");
|
||||||
const { updateProfile } = useUserStore();
|
const { updateProfile } = useUserStore();
|
||||||
|
|
||||||
async function handleSave() {
|
async function handleSave() {
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { arrowBackOutline } from "ionicons/icons";
|
|||||||
import { safeClient } from "@/api";
|
import { safeClient } from "@/api";
|
||||||
import { authClient } from "@/auth";
|
import { authClient } from "@/auth";
|
||||||
|
|
||||||
const { user } = useAuth();
|
const userStore = useUserStore();
|
||||||
|
const { user } = storeToRefs(userStore);
|
||||||
const username = ref(user.value?.username || "");
|
const username = ref(user.value?.username || "");
|
||||||
const { updateProfile } = useUserStore();
|
const { updateProfile } = useUserStore();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import { chevronForwardOutline, copyOutline, qrCodeOutline } from "ionicons/icons";
|
import { chevronForwardOutline, copyOutline, qrCodeOutline } from "ionicons/icons";
|
||||||
|
|
||||||
const { user } = useAuth();
|
const userStore = useUserStore();
|
||||||
|
const { user } = storeToRefs(userStore);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
9
src/vite-env.d.ts
vendored
9
src/vite-env.d.ts
vendored
@@ -7,6 +7,9 @@ import {
|
|||||||
DefineLocaleMessage,
|
DefineLocaleMessage,
|
||||||
DefineNumberFormat,
|
DefineNumberFormat,
|
||||||
} from "vue-i18n";
|
} from "vue-i18n";
|
||||||
|
import "vue-router";
|
||||||
|
|
||||||
|
export {};
|
||||||
|
|
||||||
declare module "vue-i18n" {
|
declare module "vue-i18n" {
|
||||||
// define the locale messages schema
|
// define the locale messages schema
|
||||||
@@ -21,3 +24,9 @@ declare module "vue-i18n" {
|
|||||||
export interface DefineNumberFormat {
|
export interface DefineNumberFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module "vue-router" {
|
||||||
|
interface RouteMeta {
|
||||||
|
requiresAuth: ? boolean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user