feat: add main app route skeleton
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
type SummaryTone = 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'violet'
|
||||
|
||||
type SummaryItem = {
|
||||
label: string
|
||||
value: string
|
||||
helper?: string
|
||||
tone?: SummaryTone
|
||||
}
|
||||
|
||||
withDefaults(defineProps<{
|
||||
eyebrow?: string
|
||||
title: string
|
||||
description: string
|
||||
status?: string
|
||||
items?: SummaryItem[]
|
||||
}>(), {
|
||||
eyebrow: '',
|
||||
status: '骨架已就绪',
|
||||
items: () => [],
|
||||
})
|
||||
|
||||
const toneClasses: Record<SummaryTone, string> = {
|
||||
blue: 'border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-900/50 dark:bg-blue-950/40 dark:text-blue-100',
|
||||
green: 'border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900/50 dark:bg-emerald-950/40 dark:text-emerald-100',
|
||||
amber: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900/50 dark:bg-amber-950/40 dark:text-amber-100',
|
||||
red: 'border-rose-200 bg-rose-50 text-rose-900 dark:border-rose-900/50 dark:bg-rose-950/40 dark:text-rose-100',
|
||||
slate: 'border-slate-200 bg-white text-slate-900 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100',
|
||||
violet: 'border-violet-200 bg-violet-50 text-violet-900 dark:border-violet-900/50 dark:bg-violet-950/40 dark:text-violet-100',
|
||||
}
|
||||
|
||||
function toneClass(tone?: SummaryTone) {
|
||||
return toneClasses[tone || 'slate']
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="min-h-full w-full">
|
||||
<div class="flex w-full flex-col gap-4">
|
||||
<header class="flex flex-col gap-3 border-b border-slate-200 pb-4 dark:border-slate-800 md:flex-row md:items-start md:justify-between">
|
||||
<div class="min-w-0">
|
||||
<p v-if="eyebrow" class="mb-1 text-xs font-semibold uppercase text-slate-500 dark:text-slate-400">
|
||||
{{ eyebrow }}
|
||||
</p>
|
||||
<h1 class="mb-1 text-2xl font-semibold text-slate-950 dark:text-white">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<p class="max-w-3xl text-sm leading-6 text-slate-600 dark:text-slate-300">
|
||||
{{ description }}
|
||||
</p>
|
||||
</div>
|
||||
<span v-if="status" class="inline-flex shrink-0 items-center rounded-md border border-slate-200 bg-white px-3 py-1 text-xs font-medium text-slate-600 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300">
|
||||
{{ status }}
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<div v-if="items.length" class="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.label"
|
||||
class="rounded-lg border p-4"
|
||||
:class="toneClass(item.tone)"
|
||||
>
|
||||
<p class="text-xs font-medium opacity-75">
|
||||
{{ item.label }}
|
||||
</p>
|
||||
<p class="mt-2 text-2xl font-semibold">
|
||||
{{ item.value }}
|
||||
</p>
|
||||
<p v-if="item.helper" class="mt-1 text-xs opacity-70">
|
||||
{{ item.helper }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user