1
0
mirror of https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git synced 2025-08-14 00:25:46 +02:00

Починка adm6

This commit is contained in:
MoonTestUse1
2025-01-01 21:13:15 +06:00
parent 57b401e764
commit 1194c2c1bd
6 changed files with 100 additions and 55 deletions

View File

@@ -67,7 +67,7 @@ onMounted(fetchEmployees);
<template> <template>
<div class="space-y-4"> <div class="space-y-4">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6">
<h2 class="text-lg font-semibold">Сотрудники</h2> <h2 class="text-lg font-semibold">Сотрудники88</h2>
<button <button
@click="showAddForm = true" @click="showAddForm = true"
class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700" class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700"

View File

@@ -0,0 +1,21 @@
import { ref } from 'vue';
import type { Request } from '@/types/request';
export function useRequests() {
const requests = ref<Request[]>([]);
const fetchRequests = async () => {
try {
const response = await fetch('/api/admin/requests');
if (!response.ok) throw new Error('Failed to fetch requests');
requests.value = await response.json();
} catch (error) {
console.error('Error fetching requests:', error);
}
};
return {
requests,
fetchRequests
};
}

View File

@@ -0,0 +1,31 @@
import { ref, computed } from 'vue';
import type { Statistics, StatisticCard } from '@/types/statistics';
export function useStatistics() {
const statistics = ref<Statistics | null>(null);
const statisticsCards = computed<StatisticCard[]>(() => {
if (!statistics.value) return [];
return [
{ period: 'total', label: 'Всего заявок', value: statistics.value.totalRequests },
{ period: 'resolved', label: 'Решено', value: statistics.value.resolvedRequests },
{ period: 'avgTime', label: 'Среднее время', value: statistics.value.averageResolutionTime }
];
});
const fetchStatistics = async () => {
try {
const response = await fetch('/api/admin/statistics?period=week');
if (!response.ok) throw new Error('Failed to fetch statistics');
statistics.value = await response.json();
} catch (error) {
console.error('Error fetching statistics:', error);
}
};
return {
statistics,
statisticsCards,
fetchStatistics
};
}

View File

@@ -0,0 +1,17 @@
export interface Statistics {
totalRequests: number;
resolvedRequests: number;
averageResolutionTime: string;
volumeLabels: string[];
volumeData: number[];
typeLabels: string[];
typeData: number[];
statusLabels: string[];
statusData: number[];
}
export interface StatisticCard {
period: string;
label: string;
value: number | string;
}

View File

@@ -0,0 +1,22 @@
const STATUS_LABELS: Record<string, string> = {
new: 'Новая',
in_progress: 'В работе',
resolved: 'Решена',
closed: 'Закрыта'
};
const REQUEST_TYPE_LABELS: Record<string, string> = {
hardware: 'Проблемы с оборудованием',
software: 'Проблемы с ПО',
network: 'Проблемы с сетью',
access: 'Доступ к системам',
other: 'Другое'
};
export const getStatusLabel = (status: string): string => {
return STATUS_LABELS[status] || status;
};
export const getRequestTypeLabel = (type: string): string => {
return REQUEST_TYPE_LABELS[type] || type;
};

View File

@@ -2,18 +2,11 @@
<div class="space-y-6"> <div class="space-y-6">
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h1 class="text-2xl font-bold">Панель администратора</h1> <h1 class="text-2xl font-bold">Панель администратора</h1>
<button
@click="router.push('/admin/employees/add')"
class="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg flex items-center gap-2 transition-colors"
>
<PlusCircle class="w-5 h-5" />
Добавить работника
</button>
</div> </div>
<!-- Statistics --> <!-- Statistics -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div v-for="stat in statistics" :key="stat.period" class="bg-white p-4 rounded-lg shadow"> <div v-for="stat in statisticsCards" :key="stat.period" class="bg-white p-4 rounded-lg shadow">
<h3 class="text-lg font-semibold">{{ stat.label }}</h3> <h3 class="text-lg font-semibold">{{ stat.label }}</h3>
<p class="text-2xl font-bold">{{ stat.value }}</p> <p class="text-2xl font-bold">{{ stat.value }}</p>
</div> </div>
@@ -39,8 +32,8 @@
<tr v-for="request in requests" :key="request.id"> <tr v-for="request in requests" :key="request.id">
<td class="px-6 py-4 whitespace-nowrap">{{ request.id }}</td> <td class="px-6 py-4 whitespace-nowrap">{{ request.id }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ request.employee_last_name }}</td> <td class="px-6 py-4 whitespace-nowrap">{{ request.employee_last_name }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ request.request_type }}</td> <td class="px-6 py-4 whitespace-nowrap">{{ getRequestTypeLabel(request.request_type) }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ request.status }}</td> <td class="px-6 py-4 whitespace-nowrap">{{ getStatusLabel(request.status) }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ formatDate(request.created_at) }}</td> <td class="px-6 py-4 whitespace-nowrap">{{ formatDate(request.created_at) }}</td>
</tr> </tr>
</tbody> </tbody>
@@ -52,56 +45,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRequests } from '@/composables/useRequests';
import { PlusCircle } from 'lucide-vue-next'; import { useStatistics } from '@/composables/useStatistics';
import { getRequestTypeLabel, getStatusLabel } from '@/utils/labels';
interface Statistic { const { requests, fetchRequests } = useRequests();
period: string; const { statistics, statisticsCards, fetchStatistics } = useStatistics();
label: string;
value: number | string;
}
interface Request {
id: number;
employee_last_name: string;
request_type: string;
status: string;
created_at: string;
}
const router = useRouter();
const statistics = ref<Statistic[]>([]);
const requests = ref<Request[]>([]);
const formatDate = (date: string) => { const formatDate = (date: string) => {
return new Date(date).toLocaleString('ru-RU'); return new Date(date).toLocaleString('ru-RU');
}; };
const fetchStatistics = async () => {
try {
const response = await fetch('/api/admin/statistics?period=week');
if (!response.ok) throw new Error('Failed to fetch statistics');
const data = await response.json();
statistics.value = [
{ period: 'total', label: 'Всего заявок', value: data.totalRequests },
{ period: 'resolved', label: 'Решено', value: data.resolvedRequests },
{ period: 'avgTime', label: 'Среднее время', value: data.averageResolutionTime }
];
} catch (error) {
console.error('Error fetching statistics:', error);
}
};
const fetchRequests = async () => {
try {
const response = await fetch('/api/admin/requests');
if (!response.ok) throw new Error('Failed to fetch requests');
requests.value = await response.json();
} catch (error) {
console.error('Error fetching requests:', error);
}
};
onMounted(() => { onMounted(() => {
fetchStatistics(); fetchStatistics();
fetchRequests(); fetchRequests();