dev
This commit is contained in:
+1
-1
Submodule backend/openapi updated: 2ec8a1040d...6658869471
@@ -219,9 +219,12 @@ export interface Attribute {
|
|||||||
export interface IHelperInfo {
|
export interface IHelperInfo {
|
||||||
id: string;
|
id: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
|
name: string;
|
||||||
roleList: {
|
roleList: {
|
||||||
roleId: string;
|
roleId: string;
|
||||||
roleName: string;
|
roleName: string;
|
||||||
|
roleJob: string;
|
||||||
avatarLink: string;
|
avatarLink: string;
|
||||||
|
fame: number;
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import {
|
|||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarTrigger,
|
SidebarTrigger,
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
|
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<SidebarProps>(), {
|
const props = withDefaults(defineProps<SidebarProps>(), {
|
||||||
collapsible: "icon",
|
collapsible: "icon",
|
||||||
@@ -43,12 +44,17 @@ const toggleDarkMode = () => {
|
|||||||
document.documentElement.classList.toggle("dark", isDark.value);
|
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 = {
|
const data = {
|
||||||
user: {
|
|
||||||
name: "尚未绑定助手ID",
|
|
||||||
email: "m@example.com",
|
|
||||||
avatar: "/avatars/shadcn.jpg",
|
|
||||||
},
|
|
||||||
navMain: [
|
navMain: [
|
||||||
{
|
{
|
||||||
title: "计算器",
|
title: "计算器",
|
||||||
@@ -198,7 +204,7 @@ const data = {
|
|||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
<NavUser :user="data.user" />
|
<NavUser :user="userInfo" />
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
</template>
|
</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">
|
<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 { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import {
|
import {
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
useSidebar,
|
useSidebar,
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
|
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
user: {
|
user: {
|
||||||
@@ -29,6 +30,8 @@ const props = defineProps<{
|
|||||||
const { user } = toRefs(props);
|
const { user } = toRefs(props);
|
||||||
|
|
||||||
const { isMobile } = useSidebar();
|
const { isMobile } = useSidebar();
|
||||||
|
|
||||||
|
const helperStore = useDnfHelperStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -41,8 +44,8 @@ const { isMobile } = useSidebar();
|
|||||||
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||||
>
|
>
|
||||||
<Avatar class="h-8 w-8 rounded-lg">
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
<AvatarImage :src="user.avatar" :alt="user.name" />
|
<AvatarImage :src="user.avatar" :alt="user.id" />
|
||||||
<AvatarFallback class="rounded-lg"> Dcalc </AvatarFallback>
|
<AvatarFallback class="rounded-lg"> DNF </AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span class="truncate font-medium">{{ user.name }}</span>
|
<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">
|
<div class="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
|
||||||
<Avatar class="h-8 w-8 rounded-lg">
|
<Avatar class="h-8 w-8 rounded-lg">
|
||||||
<AvatarImage :src="user.avatar" :alt="user.name" />
|
<AvatarImage :src="user.avatar" :alt="user.name" />
|
||||||
<AvatarFallback class="rounded-lg"> Dcalc </AvatarFallback>
|
<AvatarFallback class="rounded-lg"> DNF </AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
<div class="grid flex-1 text-left text-sm leading-tight">
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
||||||
<span class="truncate font-medium">{{ user.name }}</span>
|
<span class="truncate font-medium">{{ user.name }}</span>
|
||||||
@@ -69,32 +72,35 @@ const { isMobile } = useSidebar();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<!-- <DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem :disabled="!helperStore.helperInfo">
|
||||||
<Sparkles />
|
<Sparkles />
|
||||||
Upgrade to Pro
|
切换绑定
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup> -->
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
<DropdownMenuItem>
|
<!-- <DropdownMenuItem>
|
||||||
<BadgeCheck />
|
<BadgeCheck />
|
||||||
Account
|
反馈
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<CreditCard />
|
<CreditCard />
|
||||||
Billing
|
Billing
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem> -->
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<Bell />
|
<Bell />
|
||||||
Notifications
|
反馈
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem
|
||||||
|
:disabled="!helperStore.helperInfo"
|
||||||
|
@click="helperStore.helperInfo = null"
|
||||||
|
>
|
||||||
<LogOut />
|
<LogOut />
|
||||||
Log out
|
取消绑定
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</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 { createApp } from "vue";
|
||||||
import { pinia } from "@/stores";
|
import { pinia } from "@/stores";
|
||||||
|
import { loadingPlugin } from "@/directives/loading";
|
||||||
|
|
||||||
import router from "./router";
|
import router from "./router";
|
||||||
import App from "@/pages/index.vue";
|
import App from "@/pages/index.vue";
|
||||||
@@ -13,5 +14,6 @@ const app = createApp(App);
|
|||||||
|
|
||||||
app.use(pinia);
|
app.use(pinia);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
|
app.use(loadingPlugin);
|
||||||
|
|
||||||
app.mount(appContainer);
|
app.mount(appContainer);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { useDnfHelperStore } from "@/stores/dnfhelper";
|
||||||
import { RefreshCcw } from "lucide-vue-next";
|
import { RefreshCcw } from "lucide-vue-next";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -21,6 +22,8 @@ const props = defineProps<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { list } = toRefs(props);
|
const { list } = toRefs(props);
|
||||||
|
|
||||||
|
const helperStore = useDnfHelperStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -31,7 +34,12 @@ const { list } = toRefs(props);
|
|||||||
<h1 class="text-lg font-semibold">角色列表</h1>
|
<h1 class="text-lg font-semibold">角色列表</h1>
|
||||||
<p class="text-sm text-muted-foreground">共 {{ list.length }} 个角色</p>
|
<p class="text-sm text-muted-foreground">共 {{ list.length }} 个角色</p>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="outline" size="icon" aria-label="Submit">
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
aria-label="Submit"
|
||||||
|
@click="helperStore.refleshHelperInfo(helperStore.helperInfo?.id)"
|
||||||
|
>
|
||||||
<RefreshCcw />
|
<RefreshCcw />
|
||||||
</Button>
|
</Button>
|
||||||
</header>
|
</header>
|
||||||
@@ -42,7 +50,7 @@ const { list } = toRefs(props);
|
|||||||
<CardTitle>{{ item.roleJob }}</CardTitle>
|
<CardTitle>{{ item.roleJob }}</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="flex items-center justify-center h-sm">
|
<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>
|
</CardContent>
|
||||||
<CardFooter class="flex justify-between">
|
<CardFooter class="flex justify-between">
|
||||||
<span>{{ item.roleName }}</span>
|
<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);
|
const data = await api.getHelperList(uid);
|
||||||
console.log("helperInfo", data);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
helperInfo.value = data;
|
helperInfo.value = data;
|
||||||
console.log(helperInfo.value);
|
console.log(helperInfo.value);
|
||||||
|
|||||||
+147
-105
@@ -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";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@@ -10,120 +9,163 @@
|
|||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
--font-sans: 'Geist Variable', sans-serif;
|
--font-sans: "Geist Variable", sans-serif;
|
||||||
--font-heading: var(--font-sans);
|
--font-heading: var(--font-sans);
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
--color-sidebar-border: var(--sidebar-border);
|
--color-sidebar-border: var(--sidebar-border);
|
||||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||||
--color-sidebar-accent: var(--sidebar-accent);
|
--color-sidebar-accent: var(--sidebar-accent);
|
||||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||||
--color-sidebar-primary: var(--sidebar-primary);
|
--color-sidebar-primary: var(--sidebar-primary);
|
||||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||||
--color-sidebar: var(--sidebar);
|
--color-sidebar: var(--sidebar);
|
||||||
--color-chart-5: var(--chart-5);
|
--color-chart-5: var(--chart-5);
|
||||||
--color-chart-4: var(--chart-4);
|
--color-chart-4: var(--chart-4);
|
||||||
--color-chart-3: var(--chart-3);
|
--color-chart-3: var(--chart-3);
|
||||||
--color-chart-2: var(--chart-2);
|
--color-chart-2: var(--chart-2);
|
||||||
--color-chart-1: var(--chart-1);
|
--color-chart-1: var(--chart-1);
|
||||||
--color-ring: var(--ring);
|
--color-ring: var(--ring);
|
||||||
--color-input: var(--input);
|
--color-input: var(--input);
|
||||||
--color-border: var(--border);
|
--color-border: var(--border);
|
||||||
--color-destructive: var(--destructive);
|
--color-destructive: var(--destructive);
|
||||||
--color-accent-foreground: var(--accent-foreground);
|
--color-accent-foreground: var(--accent-foreground);
|
||||||
--color-accent: var(--accent);
|
--color-accent: var(--accent);
|
||||||
--color-muted-foreground: var(--muted-foreground);
|
--color-muted-foreground: var(--muted-foreground);
|
||||||
--color-muted: var(--muted);
|
--color-muted: var(--muted);
|
||||||
--color-secondary-foreground: var(--secondary-foreground);
|
--color-secondary-foreground: var(--secondary-foreground);
|
||||||
--color-secondary: var(--secondary);
|
--color-secondary: var(--secondary);
|
||||||
--color-primary-foreground: var(--primary-foreground);
|
--color-primary-foreground: var(--primary-foreground);
|
||||||
--color-primary: var(--primary);
|
--color-primary: var(--primary);
|
||||||
--color-popover-foreground: var(--popover-foreground);
|
--color-popover-foreground: var(--popover-foreground);
|
||||||
--color-popover: var(--popover);
|
--color-popover: var(--popover);
|
||||||
--color-card-foreground: var(--card-foreground);
|
--color-card-foreground: var(--card-foreground);
|
||||||
--color-card: var(--card);
|
--color-card: var(--card);
|
||||||
--color-foreground: var(--foreground);
|
--color-foreground: var(--foreground);
|
||||||
--color-background: var(--background);
|
--color-background: var(--background);
|
||||||
--radius-sm: calc(var(--radius) - 4px);
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
--radius-md: calc(var(--radius) - 2px);
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
--radius-lg: var(--radius);
|
--radius-lg: var(--radius);
|
||||||
--radius-xl: calc(var(--radius) + 4px);
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.145 0 0);
|
--foreground: oklch(0.145 0 0);
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(1 0 0);
|
||||||
--card-foreground: oklch(0.145 0 0);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1 0 0);
|
||||||
--popover-foreground: oklch(0.145 0 0);
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
--primary: oklch(0.205 0 0);
|
--primary: oklch(0.205 0 0);
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
--secondary: oklch(0.97 0 0);
|
--secondary: oklch(0.97 0 0);
|
||||||
--secondary-foreground: oklch(0.205 0 0);
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
--muted: oklch(0.97 0 0);
|
--muted: oklch(0.97 0 0);
|
||||||
--muted-foreground: oklch(0.556 0 0);
|
--muted-foreground: oklch(0.556 0 0);
|
||||||
--accent: oklch(0.97 0 0);
|
--accent: oklch(0.97 0 0);
|
||||||
--accent-foreground: oklch(0.205 0 0);
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
--destructive: oklch(0.577 0.245 27.325);
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
--border: oklch(0.922 0 0);
|
--border: oklch(0.922 0 0);
|
||||||
--input: oklch(0.922 0 0);
|
--input: oklch(0.922 0 0);
|
||||||
--ring: oklch(0.708 0 0);
|
--ring: oklch(0.708 0 0);
|
||||||
--chart-1: oklch(0.87 0 0);
|
--chart-1: oklch(0.87 0 0);
|
||||||
--chart-2: oklch(0.556 0 0);
|
--chart-2: oklch(0.556 0 0);
|
||||||
--chart-3: oklch(0.439 0 0);
|
--chart-3: oklch(0.439 0 0);
|
||||||
--chart-4: oklch(0.371 0 0);
|
--chart-4: oklch(0.371 0 0);
|
||||||
--chart-5: oklch(0.269 0 0);
|
--chart-5: oklch(0.269 0 0);
|
||||||
--radius: 0.625rem;
|
--radius: 0.625rem;
|
||||||
--sidebar: oklch(0.985 0 0);
|
--sidebar: oklch(0.985 0 0);
|
||||||
--sidebar-foreground: oklch(0.145 0 0);
|
--sidebar-foreground: oklch(0.145 0 0);
|
||||||
--sidebar-primary: oklch(0.205 0 0);
|
--sidebar-primary: oklch(0.205 0 0);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-accent: oklch(0.97 0 0);
|
--sidebar-accent: oklch(0.97 0 0);
|
||||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||||
--sidebar-border: oklch(0.922 0 0);
|
--sidebar-border: oklch(0.922 0 0);
|
||||||
--sidebar-ring: oklch(0.708 0 0);
|
--sidebar-ring: oklch(0.708 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: oklch(0.145 0 0);
|
--background: oklch(0.145 0 0);
|
||||||
--foreground: oklch(0.985 0 0);
|
--foreground: oklch(0.985 0 0);
|
||||||
--card: oklch(0.205 0 0);
|
--card: oklch(0.205 0 0);
|
||||||
--card-foreground: oklch(0.985 0 0);
|
--card-foreground: oklch(0.985 0 0);
|
||||||
--popover: oklch(0.205 0 0);
|
--popover: oklch(0.205 0 0);
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
--primary: oklch(0.922 0 0);
|
--primary: oklch(0.922 0 0);
|
||||||
--primary-foreground: oklch(0.205 0 0);
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
--secondary: oklch(0.269 0 0);
|
--secondary: oklch(0.269 0 0);
|
||||||
--secondary-foreground: oklch(0.985 0 0);
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
--muted: oklch(0.269 0 0);
|
--muted: oklch(0.269 0 0);
|
||||||
--muted-foreground: oklch(0.708 0 0);
|
--muted-foreground: oklch(0.708 0 0);
|
||||||
--accent: oklch(0.269 0 0);
|
--accent: oklch(0.269 0 0);
|
||||||
--accent-foreground: oklch(0.985 0 0);
|
--accent-foreground: oklch(0.985 0 0);
|
||||||
--destructive: oklch(0.704 0.191 22.216);
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
--border: oklch(1 0 0 / 10%);
|
--border: oklch(1 0 0 / 10%);
|
||||||
--input: oklch(1 0 0 / 15%);
|
--input: oklch(1 0 0 / 15%);
|
||||||
--ring: oklch(0.556 0 0);
|
--ring: oklch(0.556 0 0);
|
||||||
--chart-1: oklch(0.87 0 0);
|
--chart-1: oklch(0.87 0 0);
|
||||||
--chart-2: oklch(0.556 0 0);
|
--chart-2: oklch(0.556 0 0);
|
||||||
--chart-3: oklch(0.439 0 0);
|
--chart-3: oklch(0.439 0 0);
|
||||||
--chart-4: oklch(0.371 0 0);
|
--chart-4: oklch(0.371 0 0);
|
||||||
--chart-5: oklch(0.269 0 0);
|
--chart-5: oklch(0.269 0 0);
|
||||||
--sidebar: oklch(0.205 0 0);
|
--sidebar: oklch(0.205 0 0);
|
||||||
--sidebar-foreground: oklch(0.985 0 0);
|
--sidebar-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-accent: oklch(0.269 0 0);
|
--sidebar-accent: oklch(0.269 0 0);
|
||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-border: oklch(1 0 0 / 10%);
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
--sidebar-ring: oklch(0.556 0 0);
|
--sidebar-ring: oklch(0.556 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border outline-ring/50;
|
@apply border-border outline-ring/50;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
@apply font-sans;
|
@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