Обновлен стартовый экран
Переписаны запросы для статистики, отчетов Добавлена интеграция отчета сестры
This commit is contained in:
@@ -1,81 +1,154 @@
|
||||
<script setup>
|
||||
import AppLayout from "../../../Layouts/AppLayout.vue";
|
||||
import {NFlex, NH2, NSpace, NButton, NDataTable} from 'naive-ui'
|
||||
import {h, ref} from "vue";
|
||||
import {Link} from "@inertiajs/vue3";
|
||||
import {
|
||||
NFlex, NButton, NDataTable, NAvatar, NTag,
|
||||
NText, NEl, NIcon, NInput,
|
||||
} from 'naive-ui'
|
||||
import { TbUsers, TbUserCheck, TbUserOff, TbSearch, TbPlus, TbPencil, TbLayoutDashboard } from 'vue-icons-plus/tb'
|
||||
import AppLayout from '../../../Layouts/AppLayout.vue'
|
||||
import AppContainer from '../../../Components/AppContainer.vue'
|
||||
import SectionCard from '../../../Components/SectionCard.vue'
|
||||
import PageBanner from '../../../Components/PageBanner.vue'
|
||||
import { Link } from '@inertiajs/vue3'
|
||||
import { computed, h, ref } from 'vue'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
|
||||
const props = defineProps({
|
||||
users: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
users: { type: Array, default: () => [] }
|
||||
})
|
||||
|
||||
const columns = ref([
|
||||
const themeVars = useThemeVars()
|
||||
const search = ref('')
|
||||
|
||||
const filteredUsers = computed(() => {
|
||||
const q = search.value.toLowerCase().trim()
|
||||
if (!q) return props.users
|
||||
return props.users.filter(u =>
|
||||
u.name.toLowerCase().includes(q) || u.login.toLowerCase().includes(q)
|
||||
)
|
||||
})
|
||||
|
||||
const activeCount = computed(() => props.users.filter(u => u.is_active).length)
|
||||
const blockedCount = computed(() => props.users.filter(u => !u.is_active).length)
|
||||
|
||||
const initials = (name) =>
|
||||
(name ?? '').trim().split(/\s+/).slice(0, 2).map(p => p[0]?.toUpperCase() ?? '').join('')
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
title: 'Имя',
|
||||
key: 'name'
|
||||
key: 'name',
|
||||
title: 'Пользователь',
|
||||
render: (row) => h(NFlex, { align: 'center', size: 10 }, () => [
|
||||
h(NAvatar, {
|
||||
round: true,
|
||||
size: 32,
|
||||
style: `background: color-mix(in srgb, ${themeVars.value.primaryColor} 20%, transparent); color: ${themeVars.value.primaryColor}; font-size: 12px; font-weight: 600; flex-shrink: 0;`
|
||||
}, () => initials(row.name)),
|
||||
h(NFlex, { vertical: true, size: 2 }, () => [
|
||||
h(NText, { style: 'font-weight: 500; font-size: 14px; line-height: 1.2;' }, () => row.name),
|
||||
h(NText, { depth: 3, style: 'font-size: 12px;' }, () => `@${row.login}`),
|
||||
]),
|
||||
])
|
||||
},
|
||||
{
|
||||
title: 'Логин',
|
||||
key: 'login'
|
||||
},
|
||||
{
|
||||
title: 'Активен',
|
||||
key: 'is_active',
|
||||
render: (row) => {
|
||||
return row.is_active ? 'Да' : 'Нет'
|
||||
}
|
||||
title: 'Статус',
|
||||
width: 140,
|
||||
render: (row) => h(NTag, {
|
||||
type: row.is_active ? 'success' : 'error',
|
||||
size: 'small',
|
||||
round: true,
|
||||
bordered: false,
|
||||
}, () => row.is_active ? 'Активен' : 'Заблокирован')
|
||||
},
|
||||
{
|
||||
title: 'Дата создания',
|
||||
key: 'created_at'
|
||||
key: 'created_at',
|
||||
title: 'Создан',
|
||||
width: 160,
|
||||
render: (row) => h(NText, { depth: 3, style: 'font-size: 13px;' }, () => row.created_at)
|
||||
},
|
||||
{
|
||||
title: 'Дата изменения',
|
||||
key: 'updated_at'
|
||||
},
|
||||
{
|
||||
title: 'Действия',
|
||||
key: 'actions',
|
||||
render: (row) => {
|
||||
return h(NButton, {
|
||||
text: true,
|
||||
size: 'small',
|
||||
tag: Link,
|
||||
href: `/admin/users/${row.id}`
|
||||
}, 'Редактировать')
|
||||
}
|
||||
title: '',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
render: (row) => h(NButton, {
|
||||
text: true,
|
||||
size: 'small',
|
||||
tag: Link,
|
||||
href: `/admin/users/${row.id}`,
|
||||
title: 'Редактировать',
|
||||
}, { icon: () => h(NIcon, { size: 18 }, () => h(TbPencil)) })
|
||||
},
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout>
|
||||
<template #header>
|
||||
<NFlex align="center" justify="space-between" class="max-w-6xl mx-auto mt-6 mb-4 w-full">
|
||||
<NH2>
|
||||
Учетные записи
|
||||
</NH2>
|
||||
<NSpace>
|
||||
<NButton :tag="Link" href="/admin/users/new" type="primary">
|
||||
Создать учетную запись
|
||||
<AppContainer>
|
||||
|
||||
<PageBanner
|
||||
title="Учётные записи"
|
||||
:icon="TbUsers"
|
||||
:breadcrumbs="[{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link }]"
|
||||
>
|
||||
<template #meta>
|
||||
<NFlex align="center" :size="8">
|
||||
<NText depth="3" style="font-size: 13px;">
|
||||
{{ props.users.length }} {{ props.users.length === 1 ? 'пользователь' : 'пользователей' }}
|
||||
</NText>
|
||||
<NEl style="width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .3;" />
|
||||
<NFlex align="center" :size="4">
|
||||
<NIcon size="12" style="color: var(--success-color);"><TbUserCheck /></NIcon>
|
||||
<NText depth="3" style="font-size: 13px;">{{ activeCount }} активных</NText>
|
||||
</NFlex>
|
||||
<template v-if="blockedCount > 0">
|
||||
<NEl style="width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .3;" />
|
||||
<NFlex align="center" :size="4">
|
||||
<NIcon size="12" style="color: var(--error-color);"><TbUserOff /></NIcon>
|
||||
<NText style="font-size: 13px; color: var(--error-color);">{{ blockedCount }} заблокировано</NText>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NFlex>
|
||||
</template>
|
||||
<template #actions>
|
||||
<NButton type="primary" :tag="Link" href="/admin/users/new">
|
||||
<template #icon><NIcon><TbPlus /></NIcon></template>
|
||||
Создать пользователя
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NFlex>
|
||||
</template>
|
||||
<NDataTable class="max-w-6xl mx-auto mb-4 w-full" :columns="columns" :data="users" />
|
||||
</template>
|
||||
</PageBanner>
|
||||
|
||||
<!-- Таблица -->
|
||||
<SectionCard :icon="TbUsers" title="Список пользователей" no-padding>
|
||||
<template #header-extra>
|
||||
<NInput
|
||||
v-model:value="search"
|
||||
size="small"
|
||||
placeholder="Поиск..."
|
||||
clearable
|
||||
style="width: 200px;"
|
||||
>
|
||||
<template #prefix><NIcon depth="3"><TbSearch /></NIcon></template>
|
||||
</NInput>
|
||||
</template>
|
||||
<NDataTable
|
||||
:columns="columns"
|
||||
:data="filteredUsers"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
flex-height
|
||||
style="height: calc(100vh - 300px); min-height: 200px;"
|
||||
/>
|
||||
</SectionCard>
|
||||
|
||||
</AppContainer>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.n-h) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.n-data-table-th),
|
||||
:deep(.n-data-table-td) {
|
||||
font-size: var(--n-font-size);
|
||||
}
|
||||
|
||||
:deep(.n-data-table-th) { background: transparent !important; }
|
||||
:deep(.n-data-table) { background: transparent; }
|
||||
:deep(.n-data-table-wrapper) { border-radius: 0; }
|
||||
:deep(.n-data-table-th .n-data-table-th__title) { font-size: 12px; }
|
||||
:deep(.n-data-table-td) { font-size: 13px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user