mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
чиним билд04
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^5.1.4",
|
||||
"vue-tsc": "^2.0.6"
|
||||
"vue-tsc": "^2.0.6",
|
||||
"@tailwindcss/forms": "^0.5.7"
|
||||
}
|
||||
}
|
@@ -55,6 +55,12 @@ const router = createRouter({
|
||||
path: '/admin/login',
|
||||
name: 'AdminLogin',
|
||||
component: () => import('@/views/admin/AdminLoginView.vue')
|
||||
},
|
||||
{
|
||||
path: '/requests',
|
||||
name: 'requests',
|
||||
component: () => import('@/views/RequestsView.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -64,6 +70,12 @@ router.beforeEach((to, _, next) => {
|
||||
|
||||
if (to.meta.requiresAdmin && !authStore.isAdmin) {
|
||||
next({ name: 'AdminLogin' });
|
||||
} else if (to.meta.requiresAuth) {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
next('/login');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
132
frontend/src/views/RequestsView.vue
Normal file
132
frontend/src/views/RequestsView.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<div class="max-w-4xl mx-auto p-6">
|
||||
<h1 class="text-2xl font-bold text-gray-900 mb-6">Создание заявки</h1>
|
||||
|
||||
<form @submit.prevent="handleSubmit" class="space-y-6 bg-white shadow-sm rounded-lg p-6">
|
||||
<div>
|
||||
<label for="department" class="block text-sm font-medium text-gray-700">Отдел</label>
|
||||
<select
|
||||
id="department"
|
||||
v-model="formData.department"
|
||||
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
|
||||
required
|
||||
>
|
||||
<option value="">Выберите отдел</option>
|
||||
<option value="IT">IT</option>
|
||||
<option value="HR">HR</option>
|
||||
<option value="Finance">Финансы</option>
|
||||
<option value="Marketing">Маркетинг</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="request_type" class="block text-sm font-medium text-gray-700">Тип заявки</label>
|
||||
<select
|
||||
id="request_type"
|
||||
v-model="formData.request_type"
|
||||
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
|
||||
required
|
||||
>
|
||||
<option value="">Выберите тип</option>
|
||||
<option value="access">Доступ к системе</option>
|
||||
<option value="software">Установка ПО</option>
|
||||
<option value="hardware">Проблема с оборудованием</option>
|
||||
<option value="other">Другое</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="priority" class="block text-sm font-medium text-gray-700">Приоритет</label>
|
||||
<select
|
||||
id="priority"
|
||||
v-model="formData.priority"
|
||||
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
|
||||
required
|
||||
>
|
||||
<option value="">Выберите приоритет</option>
|
||||
<option value="low">Низкий</option>
|
||||
<option value="medium">Средний</option>
|
||||
<option value="high">Высокий</option>
|
||||
<option value="critical">Критический</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700">Описание</label>
|
||||
<textarea
|
||||
id="description"
|
||||
v-model="formData.description"
|
||||
rows="4"
|
||||
class="mt-1 block w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||
placeholder="Опишите вашу проблему..."
|
||||
required
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span v-if="loading">Отправка...</span>
|
||||
<span v-else>Отправить заявку</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="error" class="mt-2 text-sm text-red-600">
|
||||
{{ error }}
|
||||
</div>
|
||||
|
||||
<div v-if="success" class="mt-2 text-sm text-green-600">
|
||||
Заявка успешно создана!
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
const formData = reactive({
|
||||
department: '',
|
||||
request_type: '',
|
||||
priority: '',
|
||||
description: ''
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
const error = ref('')
|
||||
const success = ref(false)
|
||||
|
||||
const handleSubmit = async () => {
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
success.value = false
|
||||
|
||||
try {
|
||||
const token = localStorage.getItem('token')
|
||||
if (!token) {
|
||||
throw new Error('Не найден токен авторизации')
|
||||
}
|
||||
|
||||
await axios.post('/api/requests/', formData, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
|
||||
success.value = true
|
||||
// Очищаем форму
|
||||
formData.department = ''
|
||||
formData.request_type = ''
|
||||
formData.priority = ''
|
||||
formData.description = ''
|
||||
} catch (e: any) {
|
||||
error.value = e.response?.data?.detail || 'Произошла ошибка при создании заявки'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -7,5 +7,7 @@ export default {
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
],
|
||||
}
|
Reference in New Issue
Block a user