Обновлен стартовый экран
Переписаны запросы для статистики, отчетов Добавлена интеграция отчета сестры
This commit is contained in:
112
resources/js/Components/PageBanner.vue
Normal file
112
resources/js/Components/PageBanner.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<script setup>
|
||||
import { NEl, NFlex, NIcon, NText } from 'naive-ui'
|
||||
import { TbChevronRight } from 'vue-icons-plus/tb'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
title: { type: String, default: '' },
|
||||
// null / имя цвета темы (primary|success|error|warning|info) / 'default' = нейтральный тёмный
|
||||
color: { type: String, default: null },
|
||||
// [{ label, href? }]
|
||||
breadcrumbs: { type: Array, default: () => [] },
|
||||
// компонент-иконка (если не нужен кастомный слот #icon)
|
||||
icon: { type: [Object, Function], default: null },
|
||||
})
|
||||
|
||||
const themeVars = useThemeVars()
|
||||
|
||||
const isNeutral = computed(() => props.color === 'default')
|
||||
const cssColor = computed(() => isNeutral.value ? null : `var(--${props.color ?? 'primary'}-color)`)
|
||||
|
||||
const bannerBg = computed(() => isNeutral.value
|
||||
? themeVars.value.cardColor
|
||||
: `color-mix(in srgb, ${cssColor.value} 8%, ${themeVars.value.cardColor})`
|
||||
)
|
||||
const bannerBorder = computed(() => isNeutral.value
|
||||
? themeVars.value.dividerColor
|
||||
: `color-mix(in srgb, ${cssColor.value} 20%, transparent)`
|
||||
)
|
||||
const iconBg = computed(() => isNeutral.value
|
||||
? `color-mix(in srgb, ${themeVars.value.textColor1} 10%, transparent)`
|
||||
: `color-mix(in srgb, ${cssColor.value} 16%, transparent)`
|
||||
)
|
||||
const iconColor = computed(() => isNeutral.value
|
||||
? themeVars.value.textColor2
|
||||
: cssColor.value
|
||||
)
|
||||
const crumbColor = computed(() => isNeutral.value
|
||||
? themeVars.value.primaryColor
|
||||
: cssColor.value
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NEl
|
||||
class="rounded-2xl px-6 py-5"
|
||||
:style="`background: ${bannerBg}; border: 1px solid ${bannerBorder};`"
|
||||
>
|
||||
<!-- Хлебные крошки -->
|
||||
<NFlex v-if="breadcrumbs.length" align="center" :size="6" style="margin-bottom: 12px;">
|
||||
<template v-for="(crumb, i) in breadcrumbs" :key="i">
|
||||
<NEl
|
||||
v-if="crumb.href"
|
||||
:tag="crumb.tag ?? 'a'"
|
||||
:href="crumb.href"
|
||||
:style="`font-size: 12px; color: ${crumbColor}; text-decoration: none; opacity: .75; transition: opacity .15s;`"
|
||||
@mouseenter="e => e.currentTarget.style.opacity = 1"
|
||||
@mouseleave="e => e.currentTarget.style.opacity = .75"
|
||||
>
|
||||
<NFlex align="center" :size="4">
|
||||
<NIcon v-if="crumb.icon" size="13"><component :is="crumb.icon" /></NIcon>
|
||||
{{ crumb.label }}
|
||||
</NFlex>
|
||||
</NEl>
|
||||
<NText v-else depth="3" style="font-size: 12px;">{{ crumb.label }}</NText>
|
||||
<NIcon v-if="i < breadcrumbs.length - 1" size="12" depth="3"><TbChevronRight /></NIcon>
|
||||
</template>
|
||||
</NFlex>
|
||||
|
||||
<!-- Основная строка -->
|
||||
<NFlex align="center" justify="space-between" :wrap="false">
|
||||
|
||||
<NFlex align="center" :size="14" :wrap="false">
|
||||
<!-- Иконка: кастомный слот или prop -->
|
||||
<NEl
|
||||
v-if="$slots.icon || icon"
|
||||
class="rounded-xl"
|
||||
:style="`
|
||||
width: 48px; height: 48px; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: ${iconBg};
|
||||
`"
|
||||
>
|
||||
<slot name="icon">
|
||||
<NIcon :size="24" :style="`color: ${iconColor};`">
|
||||
<component :is="icon" />
|
||||
</NIcon>
|
||||
</slot>
|
||||
</NEl>
|
||||
|
||||
<div class="min-w-0">
|
||||
<!-- Заголовок: кастомный слот или prop -->
|
||||
<slot name="title">
|
||||
<span style="font-size: 20px; font-weight: 700; line-height: 1.2;">
|
||||
{{ title }}
|
||||
</span>
|
||||
</slot>
|
||||
<!-- Мета-строка -->
|
||||
<div v-if="$slots.meta" style="margin-top: 5px;">
|
||||
<slot name="meta" />
|
||||
</div>
|
||||
</div>
|
||||
</NFlex>
|
||||
|
||||
<!-- Действия (кнопки) -->
|
||||
<NFlex v-if="$slots.actions" :size="8" style="flex-shrink: 0;">
|
||||
<slot name="actions" />
|
||||
</NFlex>
|
||||
|
||||
</NFlex>
|
||||
</NEl>
|
||||
</template>
|
||||
Reference in New Issue
Block a user