mirror of https://github.com/halo-dev/halo-admin
parent
62412028b0
commit
4ef9f0cf5d
|
@ -27,10 +27,7 @@ const handleRouteToProfile = () => {
|
|||
|
||||
<template>
|
||||
<div class="flex h-full">
|
||||
<aside
|
||||
class="navbar fixed hidden h-full overflow-y-auto md:block"
|
||||
style="background: #fff"
|
||||
>
|
||||
<aside class="navbar fixed hidden h-full overflow-y-auto md:block">
|
||||
<div class="logo flex justify-center py-5">
|
||||
<img :src="logo" alt="Halo Logo" style="width: 78px" />
|
||||
</div>
|
||||
|
@ -174,6 +171,7 @@ const handleRouteToProfile = () => {
|
|||
<style lang="scss">
|
||||
.navbar {
|
||||
@apply w-64;
|
||||
@apply bg-white;
|
||||
z-index: 999;
|
||||
box-shadow: 0 4px 4px #f6c6ce;
|
||||
padding-bottom: 70px;
|
||||
|
|
|
@ -3,8 +3,9 @@ import { BasicLayout } from "@/layouts";
|
|||
import { IconUpload, VButton, VTabbar } from "@halo-dev/components";
|
||||
import { onMounted, provide, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { users } from "@/modules/system/users/users-mock";
|
||||
import { Starport } from "vue-starport";
|
||||
import axiosInstance from "@/utils/api-client";
|
||||
import type { User } from "@/types/extension";
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
|
@ -29,15 +30,20 @@ const tabs = [
|
|||
},
|
||||
];
|
||||
|
||||
const user = ref();
|
||||
const user = ref<User>();
|
||||
|
||||
const route = useRoute();
|
||||
const { params } = useRoute();
|
||||
|
||||
if (route.params.username) {
|
||||
user.value = users.find((u) => u.username === route.params.username);
|
||||
} else {
|
||||
user.value = users[0];
|
||||
}
|
||||
const handleFetchUser = async () => {
|
||||
try {
|
||||
const { data } = await axiosInstance.get(
|
||||
`/api/v1alpha1/users/${params.name}`
|
||||
);
|
||||
user.value = data;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
provide("user", user);
|
||||
|
||||
|
@ -48,6 +54,7 @@ const router = useRouter();
|
|||
|
||||
// set default active tab
|
||||
onMounted(() => {
|
||||
handleFetchUser();
|
||||
const tab = tabs.find((tab) => tab.routeName === currentRouteName);
|
||||
activeTab.value = tab ? tab.id : tabs[0].id;
|
||||
});
|
||||
|
@ -62,19 +69,19 @@ const handleTabChange = (id: string) => {
|
|||
<template>
|
||||
<BasicLayout>
|
||||
<header class="bg-white">
|
||||
<div :class="user.cover" class="h-48 bg-gradient-to-r"></div>
|
||||
<div class="h-48 bg-gradient-to-r from-gray-800 to-red-500"></div>
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<div class="-mt-12 flex items-end space-x-5 sm:-mt-16">
|
||||
<div class="flex">
|
||||
<Starport
|
||||
:port="`user-profile-${user.name}`"
|
||||
class="h-24 w-24 sm:h-32 sm:w-32"
|
||||
:duration="400"
|
||||
:port="`user-profile-${user.metadata?.name}`"
|
||||
class="h-24 w-24 sm:h-32 sm:w-32"
|
||||
>
|
||||
<img
|
||||
:src="user.avatar"
|
||||
:src="user.spec?.avatar"
|
||||
alt="Avatar"
|
||||
class="rounded-full ring-4 ring-white drop-shadow-lg"
|
||||
class="h-full w-full rounded-full ring-4 ring-white drop-shadow-lg"
|
||||
/>
|
||||
</Starport>
|
||||
</div>
|
||||
|
@ -83,7 +90,7 @@ const handleTabChange = (id: string) => {
|
|||
>
|
||||
<div class="mt-6 block min-w-0 flex-1">
|
||||
<h1 class="truncate text-xl font-bold text-gray-900">
|
||||
<span class="mr-1">{{ user.name }}</span>
|
||||
<span class="mr-1">{{ user.spec?.displayName }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
import { useRoute } from "vue-router";
|
||||
import { computed, ref } from "vue";
|
||||
import type { Plugin } from "./types";
|
||||
import type { Plugin } from "@/types/extension";
|
||||
import axiosInstance from "@/utils/api-client";
|
||||
|
||||
const pluginActiveId = ref("detail");
|
||||
|
@ -31,7 +31,9 @@ const handleFetchPlugin = async () => {
|
|||
};
|
||||
|
||||
const isStarted = computed(() => {
|
||||
return plugin.value?.status.phase === "STARTED" && plugin.value?.spec.enabled;
|
||||
return (
|
||||
plugin.value?.status?.phase === "STARTED" && plugin.value?.spec.enabled
|
||||
);
|
||||
});
|
||||
|
||||
const handleChangePluginStatus = async () => {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { Plugin } from "./types";
|
||||
import type { Plugin } from "@/types/extension";
|
||||
import axiosInstance from "@/utils/api-client";
|
||||
|
||||
const checkAll = ref(false);
|
||||
|
@ -30,7 +30,7 @@ const handleRouteToDetail = (plugin: Plugin) => {
|
|||
};
|
||||
|
||||
function isStarted(plugin: Plugin) {
|
||||
return plugin.status.phase === "STARTED" && plugin.spec.enabled;
|
||||
return plugin.status?.phase === "STARTED" && plugin.spec.enabled;
|
||||
}
|
||||
|
||||
const handleFetchPlugins = async () => {
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface PluginDependencies {}
|
||||
|
||||
export interface License {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Spec {
|
||||
displayName: string;
|
||||
version: string;
|
||||
author: string;
|
||||
logo: string;
|
||||
pluginDependencies: PluginDependencies;
|
||||
homepage: string;
|
||||
description: string;
|
||||
license: License[];
|
||||
requires: string;
|
||||
pluginClass: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
version: number;
|
||||
creationTimestamp: Date;
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
phase: string;
|
||||
entry?: string;
|
||||
stylesheet?: string;
|
||||
}
|
||||
|
||||
export interface Plugin {
|
||||
spec: Spec;
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
status: Status;
|
||||
extensions: Extension[];
|
||||
}
|
||||
|
||||
export interface Extension {
|
||||
name: string;
|
||||
fields: string[];
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
<script lang="ts" setup>
|
||||
import { VButton, VInput, VTextarea } from "@halo-dev/components";
|
||||
import { inject } from "vue";
|
||||
import type { User } from "@/types/extension";
|
||||
|
||||
const user = inject("user");
|
||||
const user = inject<User>("user");
|
||||
</script>
|
||||
<template>
|
||||
<form class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
|
||||
|
@ -13,7 +14,7 @@ const user = inject("user");
|
|||
</label>
|
||||
<div class="mt-1 sm:col-span-3 sm:mt-0">
|
||||
<div class="flex max-w-lg shadow-sm">
|
||||
<VInput :modelValue="user.username" />
|
||||
<VInput :modelValue="user?.metadata?.name" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,7 +24,7 @@ const user = inject("user");
|
|||
</label>
|
||||
<div class="mt-1 sm:col-span-3 sm:mt-0">
|
||||
<div class="flex max-w-lg shadow-sm">
|
||||
<VInput :modelValue="user.name" />
|
||||
<VInput :modelValue="user?.spec?.displayName" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,7 +35,7 @@ const user = inject("user");
|
|||
</label>
|
||||
<div class="mt-1 sm:col-span-3 sm:mt-0">
|
||||
<div class="flex max-w-lg shadow-sm">
|
||||
<VInput :modelValue="user.email" />
|
||||
<VInput :modelValue="user?.spec?.email" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,7 +45,7 @@ const user = inject("user");
|
|||
</label>
|
||||
<div class="mt-1 sm:col-span-3 sm:mt-0">
|
||||
<div class="flex max-w-lg shadow-sm">
|
||||
<VTextarea modelValue="Halo" />
|
||||
<VTextarea :modelValue="user?.spec?.bio" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +53,7 @@ const user = inject("user");
|
|||
|
||||
<div class="pt-5">
|
||||
<div class="flex justify-start">
|
||||
<VButton type="secondary"> 保存</VButton>
|
||||
<VButton type="secondary">保存</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
import { IconUserSettings, VTag } from "@halo-dev/components";
|
||||
import { inject } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import type { User } from "@/types/extension";
|
||||
|
||||
const user = inject("user");
|
||||
const user = inject<User>("user");
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
@ -15,7 +16,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">显示名称</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
{{ user.name }}
|
||||
{{ user?.spec?.displayName }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
@ -23,7 +24,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">用户名</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
{{ user.username }}
|
||||
{{ user?.metadata?.name }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
@ -31,7 +32,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">电子邮箱</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
{{ user.email || "未设置" }}
|
||||
{{ user?.spec?.email || "未设置" }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
@ -43,7 +44,7 @@ const router = useRouter();
|
|||
<template #leftIcon>
|
||||
<IconUserSettings />
|
||||
</template>
|
||||
{{ user.role }}
|
||||
{{ user?.metadata?.name }}
|
||||
</VTag>
|
||||
</dd>
|
||||
</div>
|
||||
|
@ -52,7 +53,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">描述</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
Hello Halo
|
||||
{{ user?.spec?.bio }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
@ -66,7 +67,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">注册时间</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
2022-01-01 00:00:00
|
||||
{{ user?.metadata?.creationTimestamp }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
|
@ -74,7 +75,7 @@ const router = useRouter();
|
|||
>
|
||||
<dt class="text-sm font-medium text-gray-900">最近登录时间</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-3 sm:mt-0">
|
||||
2022-05-30 12:00:00
|
||||
{{ user?.metadata?.creationTimestamp }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
|
|
@ -12,18 +12,24 @@ import {
|
|||
VSpace,
|
||||
VTag,
|
||||
} from "@halo-dev/components";
|
||||
import { users } from "./users-mock";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ref } from "vue";
|
||||
import { Starport } from "vue-starport";
|
||||
import axiosInstance from "@/utils/api-client";
|
||||
import type { User } from "@/types/extension";
|
||||
|
||||
const checkAll = ref(false);
|
||||
const users = ref<User[]>([]);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const handleRouteToDetail = (username: string) => {
|
||||
router.push({ name: "UserDetail", params: { username } });
|
||||
const handleFetchUsers = async () => {
|
||||
try {
|
||||
const { data } = await axiosInstance.get("/api/v1alpha1/users");
|
||||
users.value = data;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
handleFetchUsers();
|
||||
</script>
|
||||
<template>
|
||||
<VPageHeader title="用户">
|
||||
|
@ -172,7 +178,12 @@ const handleRouteToDetail = (username: string) => {
|
|||
<li
|
||||
v-for="(user, index) in users"
|
||||
:key="index"
|
||||
@click="handleRouteToDetail(user.username)"
|
||||
@click="
|
||||
$router.push({
|
||||
name: 'UserDetail',
|
||||
params: { name: user.metadata.name },
|
||||
})
|
||||
"
|
||||
>
|
||||
<div
|
||||
:class="{
|
||||
|
@ -192,15 +203,15 @@ const handleRouteToDetail = (username: string) => {
|
|||
type="checkbox"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="user.avatar" class="mr-4">
|
||||
<div v-if="user.spec.avatar" class="mr-4">
|
||||
<Starport
|
||||
:duration="400"
|
||||
:port="`user-profile-${user.name}`"
|
||||
:port="`user-profile-${user.metadata.name}`"
|
||||
class="h-12 w-12"
|
||||
>
|
||||
<img
|
||||
:alt="user.name"
|
||||
:src="user.avatar"
|
||||
:alt="user.spec.displayName"
|
||||
:src="user.spec.avatar"
|
||||
class="h-full w-full overflow-hidden rounded border bg-white hover:shadow-sm"
|
||||
/>
|
||||
</Starport>
|
||||
|
@ -208,14 +219,14 @@ const handleRouteToDetail = (username: string) => {
|
|||
<div class="flex-1">
|
||||
<div class="flex flex-row items-center">
|
||||
<span class="mr-2 truncate text-sm font-medium text-gray-900">
|
||||
{{ user.name }}
|
||||
{{ user.spec.displayName }}
|
||||
</span>
|
||||
<VTag class="sm:hidden">{{ user.role }}</VTag>
|
||||
<VTag class="sm:hidden">{{ user.metadata.name }}</VTag>
|
||||
</div>
|
||||
<div class="mt-1 flex">
|
||||
<VSpace align="start" direction="column" spacing="xs">
|
||||
<span class="text-xs text-gray-500">
|
||||
{{ user.username }}
|
||||
{{ user.metadata.name }}
|
||||
</span>
|
||||
</VSpace>
|
||||
</div>
|
||||
|
@ -224,13 +235,13 @@ const handleRouteToDetail = (username: string) => {
|
|||
<div
|
||||
class="inline-flex flex-col flex-col-reverse items-end gap-4 sm:flex-row sm:items-center sm:gap-6"
|
||||
>
|
||||
<span class="hidden sm:block">
|
||||
<div class="hidden items-center sm:flex">
|
||||
<VTag>
|
||||
{{ user.role }}
|
||||
{{ user.metadata.name }}
|
||||
</VTag>
|
||||
</span>
|
||||
</div>
|
||||
<time class="text-sm text-gray-500" datetime="2020-01-07">
|
||||
2020-01-07
|
||||
{{ user.metadata.creationTimestamp }}
|
||||
</time>
|
||||
<span class="cursor-pointer">
|
||||
<IconSettings />
|
||||
|
|
|
@ -27,7 +27,7 @@ export default definePlugin({
|
|||
],
|
||||
},
|
||||
{
|
||||
path: ":username",
|
||||
path: ":name",
|
||||
component: UserProfileLayout,
|
||||
children: [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
export interface License {
|
||||
name?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
labels?: {
|
||||
[key: string]: string | null;
|
||||
} | null;
|
||||
annotations?: {
|
||||
[key: string]: string | null;
|
||||
} | null;
|
||||
version?: number | null;
|
||||
creationTimestamp?: string | null;
|
||||
deletionTimestamp?: string | null;
|
||||
}
|
||||
|
||||
export interface Plugin {
|
||||
spec: PluginSpec;
|
||||
status?: PluginStatus;
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
extensions: Extension[];
|
||||
}
|
||||
|
||||
export interface Extension {
|
||||
name: string;
|
||||
fields: string[];
|
||||
}
|
||||
|
||||
export interface PluginSpec {
|
||||
displayName?: string;
|
||||
version?: string;
|
||||
author?: string;
|
||||
logo?: string;
|
||||
pluginDependencies?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
homepage?: string;
|
||||
description?: string;
|
||||
license?: License[];
|
||||
requires?: string;
|
||||
pluginClass?: string;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface PluginStatus {
|
||||
phase?:
|
||||
| "CREATED"
|
||||
| "DISABLED"
|
||||
| "RESOLVED"
|
||||
| "STARTED"
|
||||
| "STOPPED"
|
||||
| "FAILED";
|
||||
reason?: string;
|
||||
message?: string;
|
||||
lastStartTime?: string;
|
||||
lastTransitionTime?: string;
|
||||
entry?: string;
|
||||
stylesheet?: string;
|
||||
}
|
||||
|
||||
export interface PersonalAccessToken {
|
||||
spec?: PersonalAccessTokenSpec;
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export interface PersonalAccessTokenSpec {
|
||||
userName?: string;
|
||||
displayName?: string;
|
||||
revoked?: boolean;
|
||||
expiresAt?: string;
|
||||
scopes?: string;
|
||||
tokenDigest?: string;
|
||||
}
|
||||
|
||||
export interface RoleBinding {
|
||||
subjects?: Subject[];
|
||||
roleRef?: RoleRef;
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export interface RoleRef {
|
||||
kind?: string;
|
||||
name?: string;
|
||||
apiGroup?: string;
|
||||
}
|
||||
|
||||
export interface Subject {
|
||||
kind?: string;
|
||||
name?: string;
|
||||
apiGroup?: string;
|
||||
}
|
||||
|
||||
export interface PolicyRule {
|
||||
apiGroups?: string[];
|
||||
resources?: string[];
|
||||
resourceNames?: string[];
|
||||
nonResourceURLs?: string[];
|
||||
verbs?: string[];
|
||||
pluginName?: string;
|
||||
}
|
||||
|
||||
export interface Role {
|
||||
rules?: PolicyRule[];
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export interface LoginHistory {
|
||||
loginAt: string;
|
||||
sourceIp: string;
|
||||
userAgent: string;
|
||||
successful: boolean;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
spec: UserSpec;
|
||||
status?: UserStatus;
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export interface UserSpec {
|
||||
displayName: string;
|
||||
avatar?: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
password?: string;
|
||||
bio?: string;
|
||||
registeredAt?: string;
|
||||
twoFactorAuthEnabled?: boolean;
|
||||
disabled?: boolean;
|
||||
loginHistoryLimit?: number;
|
||||
}
|
||||
|
||||
export interface UserStatus {
|
||||
lastLoginAt?: string;
|
||||
loginHistories?: LoginHistory[];
|
||||
}
|
||||
|
||||
export interface FileReverseProxyProvider {
|
||||
directory?: string;
|
||||
filename?: string;
|
||||
}
|
||||
|
||||
export interface ReverseProxy {
|
||||
rules?: ReverseProxyRule[];
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export interface ReverseProxyRule {
|
||||
path?: string;
|
||||
file?: FileReverseProxyProvider;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import axios from "axios";
|
||||
|
||||
const token =
|
||||
"eyJhbGciOiJSUzUxMiJ9.eyJpc3MiOiJIYWxvIE93bmVyIiwic3ViIjoiYWRtaW4iLCJleHAiOjE2NTU4OTQxNTQsImlhdCI6MTY1NTgwNzc1NCwic2NvcGUiOlsiUk9MRV9zdXBlci1yb2xlIl19.Gnj0rM8DU2bP1KcgKBUVaKf6zs1pDqGxYvii9zxG4lFv4rVZ_uNGXyfhi9V10vRK0GM4v4NEuMtX9-DYnqAV0wR2JcoFevPrJnHHWsvnFrOQm32qeMpew3PsZ5-YAwi9n8Y9GpAcQz_6aWsEuRwm9w5CC3A67CrYPfCK5qwuR5FFLfiMRqPAqNNuZ4r2IfoSZUvXy4HxhUS-01J2BCqP3-hbdN_-tFHCDxtIO637a51EsCmRItY5wSVNmwYPaPOYV7lbHxzBIKXw5RNXg6SrQCSLTVaaJCXsZjwIirk02RQACr6oqTHPbriBVuu-SIgPXS5PJ9i4VaMCn-z8t-oZlQ";
|
||||
"eyJhbGciOiJSUzUxMiJ9.eyJpc3MiOiJIYWxvIE93bmVyIiwic3ViIjoiYWRtaW4iLCJleHAiOjE2NTYwNDM3NTYsImlhdCI6MTY1NTk1NzM1Niwic2NvcGUiOlsiUk9MRV9zdXBlci1yb2xlIl19.XHmq5q9-HWkWQsPdcuvldeiKOQxbKHEd9qP33ZWaLSFVgj5D-8QvfLjuLreMWUBLvZXvsqBuDHpib70gO6V2c4VtUbnAQnzr8oQx4E5ypMnWH4Gdbs8UlSpMGjTPzSk-QNFKB48nMo8wgTcq2oyhBsMEIArKFm7v2pa5dSX1LbWTRRpNfJpHPVwrAPzaNkOs_qasS8QzSTHU1C3wCf_A4lEILVhbrHq_mv9yeMQZL0enD-gpbGXEQzHE59zwxFC7kfgb_YhzYZfzuXAv2BIKn4TU14W9aW4HySymsqM0ItO5RT3GmJgurbX9USHhIKfGdTFEG1cfgZ0ZJNNOOLEndA";
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
headers: {
|
||||
|
|
Loading…
Reference in New Issue