dev
This commit is contained in:
+1
-1
Submodule backend/openapi updated: 2ec8a1040d...6658869471
@@ -219,9 +219,12 @@ export interface Attribute {
|
||||
export interface IHelperInfo {
|
||||
id: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
roleList: {
|
||||
roleId: string;
|
||||
roleName: string;
|
||||
roleJob: string;
|
||||
avatarLink: string;
|
||||
fame: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
SidebarMenuItem,
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||
|
||||
const props = withDefaults(defineProps<SidebarProps>(), {
|
||||
collapsible: "icon",
|
||||
@@ -43,12 +44,17 @@ const toggleDarkMode = () => {
|
||||
document.documentElement.classList.toggle("dark", isDark.value);
|
||||
};
|
||||
|
||||
const dnfHelperStore = useDnfHelperStore();
|
||||
|
||||
const userInfo = computed(() => {
|
||||
return {
|
||||
name: dnfHelperStore.helperInfo?.name ?? "尚未绑定助手ID",
|
||||
id: dnfHelperStore.helperInfo?.id ?? "",
|
||||
avatar: dnfHelperStore.helperInfo?.avatar ?? "",
|
||||
};
|
||||
});
|
||||
|
||||
const data = {
|
||||
user: {
|
||||
name: "尚未绑定助手ID",
|
||||
email: "m@example.com",
|
||||
avatar: "/avatars/shadcn.jpg",
|
||||
},
|
||||
navMain: [
|
||||
{
|
||||
title: "计算器",
|
||||
@@ -198,7 +204,7 @@ const data = {
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
<NavUser :user="data.user" />
|
||||
<NavUser :user="userInfo" />
|
||||
</SidebarFooter>
|
||||
</Sidebar>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
visible: boolean;
|
||||
text?: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="v-loading-mask" :class="{ 'is-active': visible }">
|
||||
<div class="v-loading-spinner" />
|
||||
<div v-if="text" class="v-loading-text">{{ text }}</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogOut, Sparkles } from "lucide-vue-next";
|
||||
import { Bell, ChevronsUpDown, LogOut } from "lucide-vue-next";
|
||||
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import {
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||
|
||||
const props = defineProps<{
|
||||
user: {
|
||||
@@ -29,6 +30,8 @@ const props = defineProps<{
|
||||
const { user } = toRefs(props);
|
||||
|
||||
const { isMobile } = useSidebar();
|
||||
|
||||
const helperStore = useDnfHelperStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -41,8 +44,8 @@ const { isMobile } = useSidebar();
|
||||
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
>
|
||||
<Avatar class="h-8 w-8 rounded-lg">
|
||||
<AvatarImage :src="user.avatar" :alt="user.name" />
|
||||
<AvatarFallback class="rounded-lg"> Dcalc </AvatarFallback>
|
||||
<AvatarImage :src="user.avatar" :alt="user.id" />
|
||||
<AvatarFallback class="rounded-lg"> DNF </AvatarFallback>
|
||||
</Avatar>
|
||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||
<span class="truncate font-medium">{{ user.name }}</span>
|
||||
@@ -61,7 +64,7 @@ const { isMobile } = useSidebar();
|
||||
<div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||
<Avatar class="h-8 w-8 rounded-lg">
|
||||
<AvatarImage :src="user.avatar" :alt="user.name" />
|
||||
<AvatarFallback class="rounded-lg"> Dcalc </AvatarFallback>
|
||||
<AvatarFallback class="rounded-lg"> DNF </AvatarFallback>
|
||||
</Avatar>
|
||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||
<span class="truncate font-medium">{{ user.name }}</span>
|
||||
@@ -69,32 +72,35 @@ const { isMobile } = useSidebar();
|
||||
</div>
|
||||
</div>
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<!-- <DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<DropdownMenuItem :disabled="!helperStore.helperInfo">
|
||||
<Sparkles />
|
||||
Upgrade to Pro
|
||||
切换绑定
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuGroup> -->
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>
|
||||
<!-- <DropdownMenuItem>
|
||||
<BadgeCheck />
|
||||
Account
|
||||
反馈
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<CreditCard />
|
||||
Billing
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuItem> -->
|
||||
<DropdownMenuItem>
|
||||
<Bell />
|
||||
Notifications
|
||||
反馈
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
:disabled="!helperStore.helperInfo"
|
||||
@click="helperStore.helperInfo = null"
|
||||
>
|
||||
<LogOut />
|
||||
Log out
|
||||
取消绑定
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { h, render } from "vue";
|
||||
import type { App, Directive, DirectiveBinding } from "vue";
|
||||
import LoadingOverlay from "@/components/LoadingOverlay.vue";
|
||||
|
||||
type LoadingValue =
|
||||
| boolean
|
||||
| string
|
||||
| {
|
||||
loading?: boolean;
|
||||
show?: boolean;
|
||||
visible?: boolean;
|
||||
text?: string;
|
||||
};
|
||||
|
||||
type LoadingState = {
|
||||
container: HTMLDivElement;
|
||||
props: {
|
||||
visible: boolean;
|
||||
text: string;
|
||||
};
|
||||
hadRelativePosition: boolean;
|
||||
};
|
||||
|
||||
type LoadingElement = HTMLElement & {
|
||||
__vLoadingState__?: LoadingState;
|
||||
};
|
||||
|
||||
function normalizeBinding(value: LoadingValue): { loading: boolean; text: string } {
|
||||
if (typeof value === "string") {
|
||||
return { loading: true, text: value };
|
||||
}
|
||||
|
||||
if (typeof value === "boolean") {
|
||||
return { loading: value, text: "" };
|
||||
}
|
||||
|
||||
if (value && typeof value === "object") {
|
||||
const loading = value.loading ?? value.show ?? value.visible ?? true;
|
||||
return { loading: Boolean(loading), text: value.text ?? "" };
|
||||
}
|
||||
|
||||
return { loading: false, text: "" };
|
||||
}
|
||||
|
||||
function ensureState(el: LoadingElement): LoadingState {
|
||||
if (el.__vLoadingState__) {
|
||||
return el.__vLoadingState__;
|
||||
}
|
||||
|
||||
const computedPosition = window.getComputedStyle(el).position;
|
||||
const hadRelativePosition = computedPosition !== "static";
|
||||
|
||||
if (!hadRelativePosition) {
|
||||
el.style.position = "relative";
|
||||
}
|
||||
|
||||
const container = document.createElement("div");
|
||||
el.appendChild(container);
|
||||
|
||||
const props = {
|
||||
visible: false,
|
||||
text: "",
|
||||
};
|
||||
|
||||
render(h(LoadingOverlay, props), container);
|
||||
|
||||
const state: LoadingState = {
|
||||
container,
|
||||
props,
|
||||
hadRelativePosition,
|
||||
};
|
||||
|
||||
el.__vLoadingState__ = state;
|
||||
return state;
|
||||
}
|
||||
|
||||
function applyState(el: LoadingElement, binding: DirectiveBinding<LoadingValue>): void {
|
||||
const state = ensureState(el);
|
||||
const { loading, text } = normalizeBinding(binding.value);
|
||||
|
||||
state.props.visible = loading;
|
||||
state.props.text = text;
|
||||
render(h(LoadingOverlay, state.props), state.container);
|
||||
}
|
||||
|
||||
const loadingDirective: Directive<HTMLElement, LoadingValue> = {
|
||||
mounted(el, binding) {
|
||||
applyState(el as LoadingElement, binding);
|
||||
},
|
||||
updated(el, binding) {
|
||||
applyState(el as LoadingElement, binding);
|
||||
},
|
||||
unmounted(el) {
|
||||
const loadingElement = el as LoadingElement;
|
||||
const state = loadingElement.__vLoadingState__;
|
||||
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
render(null, state.container);
|
||||
state.container.remove();
|
||||
|
||||
if (!state.hadRelativePosition) {
|
||||
loadingElement.style.position = "";
|
||||
}
|
||||
|
||||
delete loadingElement.__vLoadingState__;
|
||||
},
|
||||
};
|
||||
|
||||
export const loadingPlugin = {
|
||||
install(app: App): void {
|
||||
app.directive("loading", loadingDirective);
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createApp } from "vue";
|
||||
import { pinia } from "@/stores";
|
||||
import { loadingPlugin } from "@/directives/loading";
|
||||
|
||||
import router from "./router";
|
||||
import App from "@/pages/index.vue";
|
||||
@@ -13,5 +14,6 @@ const app = createApp(App);
|
||||
|
||||
app.use(pinia);
|
||||
app.use(router);
|
||||
app.use(loadingPlugin);
|
||||
|
||||
app.mount(appContainer);
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||
import { RefreshCcw } from "lucide-vue-next";
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -21,6 +22,8 @@ const props = defineProps<{
|
||||
}>();
|
||||
|
||||
const { list } = toRefs(props);
|
||||
|
||||
const helperStore = useDnfHelperStore();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -31,7 +34,12 @@ const { list } = toRefs(props);
|
||||
<h1 class="text-lg font-semibold">角色列表</h1>
|
||||
<p class="text-sm text-muted-foreground">共 {{ list.length }} 个角色</p>
|
||||
</div>
|
||||
<Button variant="outline" size="icon" aria-label="Submit">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
aria-label="Submit"
|
||||
@click="helperStore.refleshHelperInfo(helperStore.helperInfo?.id)"
|
||||
>
|
||||
<RefreshCcw />
|
||||
</Button>
|
||||
</header>
|
||||
@@ -42,7 +50,7 @@ const { list } = toRefs(props);
|
||||
<CardTitle>{{ item.roleJob }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="flex items-center justify-center h-sm">
|
||||
<!-- <img :src="item.avatarLink" alt="avatar" class="w-auto h-sm rounded-full object-cover" /> -->
|
||||
<img :src="item.avatarLink" alt="avatar" class="w-auto h-sm rounded-full object-cover" />
|
||||
</CardContent>
|
||||
<CardFooter class="flex justify-between">
|
||||
<span>{{ item.roleName }}</span>
|
||||
|
||||
@@ -10,9 +10,9 @@ export const useDnfHelperStore = defineStore("dnfHelperStore", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const refleshHelperInfo = async (uid: string) => {
|
||||
const refleshHelperInfo = async (uid?: string) => {
|
||||
if (!uid) return;
|
||||
const data = await api.getHelperList(uid);
|
||||
console.log("helperInfo", data);
|
||||
if (data) {
|
||||
helperInfo.value = data;
|
||||
console.log(helperInfo.value);
|
||||
|
||||
+146
-104
@@ -1,5 +1,4 @@
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap");
|
||||
|
||||
@import "tailwindcss";
|
||||
|
||||
@@ -10,120 +9,163 @@
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
--font-sans: 'Geist Variable', sans-serif;
|
||||
--font-heading: var(--font-sans);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-background: var(--background);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--font-sans: "Geist Variable", sans-serif;
|
||||
--font-heading: var(--font-sans);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-background: var(--background);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.205 0 0);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--radius: 0.625rem;
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.205 0 0);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--radius: 0.625rem;
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.205 0 0);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.922 0 0);
|
||||
--primary-foreground: oklch(0.205 0 0);
|
||||
--secondary: oklch(0.269 0 0);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.269 0 0);
|
||||
--muted-foreground: oklch(0.708 0 0);
|
||||
--accent: oklch(0.269 0 0);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.556 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--sidebar: oklch(0.205 0 0);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.269 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.205 0 0);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.922 0 0);
|
||||
--primary-foreground: oklch(0.205 0 0);
|
||||
--secondary: oklch(0.269 0 0);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.269 0 0);
|
||||
--muted-foreground: oklch(0.708 0 0);
|
||||
--accent: oklch(0.269 0 0);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.556 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--sidebar: oklch(0.205 0 0);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.269 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
@apply font-sans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.v-loading-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 30;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.625rem;
|
||||
background: color-mix(in oklab, var(--background), transparent 28%);
|
||||
-webkit-backdrop-filter: blur(1.5px);
|
||||
backdrop-filter: blur(1.5px);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 180ms ease;
|
||||
}
|
||||
|
||||
.v-loading-mask.is-active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.v-loading-spinner {
|
||||
width: 1.625rem;
|
||||
height: 1.625rem;
|
||||
border-radius: 9999px;
|
||||
border: 2px solid color-mix(in oklab, var(--foreground), transparent 84%);
|
||||
border-top-color: var(--foreground);
|
||||
animation: v-loading-rotate 700ms linear infinite;
|
||||
}
|
||||
|
||||
.v-loading-text {
|
||||
font-size: 0.8125rem;
|
||||
color: color-mix(in oklab, var(--foreground), transparent 22%);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@keyframes v-loading-rotate {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user