Работа с ведомостью, начало статистики
This commit is contained in:
@@ -2,9 +2,108 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\ApiService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StatementController extends Controller
|
||||
{
|
||||
//
|
||||
protected ApiService $api;
|
||||
|
||||
public function __construct(ApiService $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$response = $this->api->get('/employee/statements');
|
||||
|
||||
if ($response->successful()) {
|
||||
$statements = $response->json();
|
||||
return view('statements.index', compact('statements'));
|
||||
}
|
||||
|
||||
abort($response->status());
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$groups = $this->api->get('/employee/groups')->json();
|
||||
$disciplines = $this->api->get('/employee/disciplines')->json();
|
||||
$types = $this->api->get('/employee/types')->json();
|
||||
$teachers = $this->api->get('/employee/teachers')->json();
|
||||
|
||||
return view('statements.form', [
|
||||
'groups' => $groups,
|
||||
'disciplines' => $disciplines,
|
||||
'types' => $types,
|
||||
'teachers' => $teachers
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$response = $this->api->post('/employee/statements', $request->all());
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('statements.index')
|
||||
->with('success', 'Ведомость успешно создана');
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['errors'] ?? []);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$statementResponse = $this->api->get("/employee/statements/{$id}");
|
||||
$groupsResponse = $this->api->get('/employee/groups');
|
||||
$disciplinesResponse = $this->api->get('/employee/disciplines');
|
||||
$typesResponse = $this->api->get('/employee/types');
|
||||
$teachersResponse = $this->api->get('/employee/teachers');
|
||||
|
||||
if ($statementResponse->successful() &&
|
||||
$groupsResponse->successful() &&
|
||||
$disciplinesResponse->successful() &&
|
||||
$typesResponse->successful() &&
|
||||
$teachersResponse->successful()) {
|
||||
|
||||
return view('statements.form', [
|
||||
'statement' => $statementResponse->json(),
|
||||
'groups' => $groupsResponse->json(),
|
||||
'disciplines' => $disciplinesResponse->json(),
|
||||
'types' => $typesResponse->json(),
|
||||
'teachers' => $teachersResponse->json(),
|
||||
'isEdit' => true
|
||||
]);
|
||||
}
|
||||
|
||||
abort($statementResponse->status());
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$data = $request->all();
|
||||
$data['is_finalized'] = $data['is_finalized'] ?? false;
|
||||
|
||||
$response = $this->api->patch("/employee/statements/{$id}", $data);
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('statements.index')
|
||||
->with('success', 'Ведомость успешно обновлена');
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['errors'] ?? []);
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$response = $this->api->delete("/employee/statements/{$id}");
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->route('statements.index')
|
||||
->with('success', 'Ведомость удалена');
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['error'] ?? 'Ошибка при удалении');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,45 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\ApiService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StatisticController extends Controller
|
||||
{
|
||||
//
|
||||
protected ApiService $api;
|
||||
|
||||
public function __construct(ApiService $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$response = $this->api->get('/employee/statistics');
|
||||
|
||||
if ($response->successful()) {
|
||||
$statistics = $response->json();
|
||||
return view('statistics.index', compact('statistics'));
|
||||
}
|
||||
|
||||
abort($response->status());
|
||||
}
|
||||
|
||||
public function generate(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'type' => 'required|string|in:group,direction,teacher',
|
||||
'id' => 'required|integer',
|
||||
'start_date' => 'required|date',
|
||||
'end_date' => 'required|date|after_or_equal:start_date',
|
||||
]);
|
||||
|
||||
$response = $this->api->get('/employee/statistics/generate', $validated);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['error'] ?? 'Ошибка при генерации статистики');
|
||||
}
|
||||
}
|
||||
|
||||
277
University.Web/resources/views/statements/form.blade.php
Normal file
277
University.Web/resources/views/statements/form.blade.php
Normal file
@@ -0,0 +1,277 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
{{ isset($statement) ? 'Редактирование ведомости' : 'Создание новой ведомости' }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ isset($statement) ? route('statements.update', $statement['id']) : route('statements.store') }}">
|
||||
@csrf
|
||||
@if(isset($statement))
|
||||
@method('PATCH')
|
||||
@endif
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="discipline_id" class="col-md-4 col-form-label text-md-end">Дисциплина*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="discipline_id" class="form-control @error('discipline_id') is-invalid @enderror" name="discipline_id" required>
|
||||
<option value="" disabled {{ old('discipline_id', $statement['discipline']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите дисциплину</option>
|
||||
@isset($disciplines)
|
||||
@foreach($disciplines as $discipline)
|
||||
<option value="{{ $discipline['id'] }}" {{ (old('discipline_id', $statement['discipline']['id'] ?? '') == $discipline['id'] ? 'selected' : '') }}>
|
||||
{{ $discipline['name'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
@else
|
||||
<option value="" disabled>Нет доступных дисциплин</option>
|
||||
@endisset
|
||||
</select>
|
||||
@error('discipline_id')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="group_id" class="col-md-4 col-form-label text-md-end">Группа*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="group_id" class="form-control @error('group_id') is-invalid @enderror" name="group_id" required>
|
||||
<option value="" disabled {{ old('group_id', $statement['group']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите группу</option>
|
||||
@isset($groups)
|
||||
@foreach($groups as $group)
|
||||
<option value="{{ $group['id'] }}" {{ (old('group_id', $statement['group']['id'] ?? '') == $group['id'] ? 'selected' : '') }}>
|
||||
{{ $group['name'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
@else
|
||||
<option value="" disabled>Нет доступных групп</option>
|
||||
@endisset
|
||||
</select>
|
||||
@error('group_id')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="teacher_id" class="col-md-4 col-form-label text-md-end">Преподаватель*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="teacher_id" name="teacher_id" required class="form-control @error('teacher_id') is-invalid @enderror">
|
||||
<option value="" disabled {{ empty($statement['teacher']['teacher_id'] ?? null) ? 'selected' : '' }}>
|
||||
Выберите преподавателя
|
||||
</option>
|
||||
@isset($teachers['data'])
|
||||
@foreach($teachers['data'] as $teacher)
|
||||
<option value="{{ $teacher['teacher_id'] }}"
|
||||
{{ ($statement['teacher']['teacher_id'] ?? null) == $teacher['teacher_id'] ? 'selected' : '' }}>
|
||||
{{ $teacher['surname'] }} {{ $teacher['name'] }} {{ $teacher['patronymic'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
@else
|
||||
<option value="" disabled>Нет доступных преподавателей</option>
|
||||
@endisset
|
||||
</select>
|
||||
@error('teacher_id')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="type_certification_id" class="col-md-4 col-form-label text-md-end">Тип аттестации*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="type_certification_id" class="form-control @error('type_certification_id') is-invalid @enderror" name="type_certification_id" required>
|
||||
<option value="" disabled {{ old('type_certification_id', $statement['type_certification']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите тип</option>
|
||||
@isset($types)
|
||||
@foreach($types as $type)
|
||||
<option value="{{ $type['id'] }}" {{ (old('type_certification_id', $statement['type_certification']['id'] ?? '') == $type['id'] ? 'selected' : '') }}>
|
||||
{{ $type['name'] }}
|
||||
</option>
|
||||
@endforeach
|
||||
@else
|
||||
<option value="" disabled>Нет доступных типов</option>
|
||||
@endisset
|
||||
</select>
|
||||
@error('type_certification_id')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="semester" class="col-md-4 col-form-label text-md-end">Семестр*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="semester" class="form-control @error('semester') is-invalid @enderror" name="semester" required>
|
||||
<option value="" disabled {{ empty(old('semester', $statement['semester'] ?? '')) ? 'selected' : '' }}>Выберите семестр</option>
|
||||
@php
|
||||
$semesters = [
|
||||
1 => 'Первый семестр',
|
||||
2 => 'Второй семестр',
|
||||
3 => 'Третий семестр',
|
||||
4 => 'Четвертый семестр',
|
||||
5 => 'Пятый семестр',
|
||||
6 => 'Шестой семестр',
|
||||
7 => 'Седьмой семестр',
|
||||
8 => 'Восьмой семестр',
|
||||
9 => 'Девятый семестр',
|
||||
10 => 'Десятый семестр',
|
||||
11 => 'Одиннадцатый семестр',
|
||||
12 => 'Двенадцатый семестр'
|
||||
];
|
||||
$selected = old('semester', $statement['semester'] ?? '');
|
||||
@endphp
|
||||
|
||||
@foreach($semesters as $number => $name)
|
||||
<option value="{{ $name }}" {{ $selected == $name ? 'selected' : '' }}>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('semester')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="academic_year" class="col-md-4 col-form-label text-md-end">Учебный год*</label>
|
||||
<div class="col-md-6">
|
||||
<select id="academic_year" class="form-control @error('academic_year') is-invalid @enderror" name="academic_year" required>
|
||||
<option value="" disabled {{ empty(old('academic_year', $statement['academic_year'] ?? '')) ? 'selected' : '' }}>Выберите учебный год</option>
|
||||
@php
|
||||
$currentYear = date('Y');
|
||||
$nextYear = $currentYear + 1;
|
||||
$selectedYear = old('academic_year', $statement['academic_year'] ?? '');
|
||||
@endphp
|
||||
|
||||
@for($i = 0; $i < 10; $i++)
|
||||
@php
|
||||
$year = $currentYear - $i;
|
||||
$next = $year + 1;
|
||||
$yearRange = "{$year}-{$next}";
|
||||
@endphp
|
||||
<option value="{{ $yearRange }}" {{ $selectedYear == $yearRange ? 'selected' : '' }}>
|
||||
{{ $yearRange }}
|
||||
@if($i == 0) @endif
|
||||
</option>
|
||||
@endfor
|
||||
</select>
|
||||
@error('academic_year')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="hours" class="col-md-4 col-form-label text-md-end">Часы*</label>
|
||||
<div class="col-md-6">
|
||||
<input id="hours" type="text" class="form-control @error('hours') is-invalid @enderror" name="hours" value="{{ old('hours', $statement['hours'] ?? '') }}" required>
|
||||
@error('hours')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="exam_date" class="col-md-4 col-form-label text-md-end">Дата занятия*</label>
|
||||
<div class="col-md-6">
|
||||
<input id="exam_date" type="date" class="form-control @error('exam_date') is-invalid @enderror" name="exam_date"
|
||||
value="{{ old('exam_date', $statement['exam_date'] ?? '') }}"
|
||||
min="" max="" required>
|
||||
@error('exam_date')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
<small class="text-muted" id="date-range-info"></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ isset($statement) ? 'Обновить' : 'Создать' }}
|
||||
</button>
|
||||
<a href="{{ route('statements.index') }}" class="btn btn-secondary">Отмена</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const academicYearSelect = document.getElementById('academic_year');
|
||||
const examDateInput = document.getElementById('exam_date');
|
||||
const dateRangeInfo = document.getElementById('date-range-info');
|
||||
const form = document.getElementById('statementForm');
|
||||
|
||||
academicYearSelect.addEventListener('change', updateDateRange);
|
||||
|
||||
if (academicYearSelect.value) {
|
||||
updateDateRange();
|
||||
}
|
||||
|
||||
// Валидация перед отправкой формы
|
||||
form.addEventListener('submit', function(event) {
|
||||
if (!validateExamDate()) {
|
||||
event.preventDefault();
|
||||
alert('Дата занятия должна быть в пределах выбранного учебного года (с 1 сентября по 30 июня)');
|
||||
}
|
||||
});
|
||||
|
||||
function updateDateRange() {
|
||||
const yearRange = academicYearSelect.value;
|
||||
if (!yearRange) return;
|
||||
|
||||
const [startYear, endYear] = yearRange.split('-').map(Number);
|
||||
const minDate = `${startYear}-09-01`;
|
||||
const maxDate = `${endYear}-06-30`;
|
||||
|
||||
examDateInput.min = minDate;
|
||||
examDateInput.max = maxDate;
|
||||
|
||||
dateRangeInfo.textContent = `Допустимый диапазон: 01.09.${startYear} - 30.06.${endYear}`;
|
||||
|
||||
if (examDateInput.value) {
|
||||
validateExamDate();
|
||||
}
|
||||
}
|
||||
|
||||
function validateExamDate() {
|
||||
const examDate = new Date(examDateInput.value);
|
||||
const minDate = new Date(examDateInput.min);
|
||||
const maxDate = new Date(examDateInput.max);
|
||||
|
||||
if (examDate < minDate || examDate > maxDate) {
|
||||
examDateInput.classList.add('is-invalid');
|
||||
return false;
|
||||
} else {
|
||||
examDateInput.classList.remove('is-invalid');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
98
University.Web/resources/views/statements/index.blade.php
Normal file
98
University.Web/resources/views/statements/index.blade.php
Normal file
@@ -0,0 +1,98 @@
|
||||
@extends('layouts.app')
|
||||
@section('links')
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link href="/resources/css/app.css" rel="stylesheet">
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-8">
|
||||
<h1 class="text-2xl font-bold">Список ведомостей</h1>
|
||||
<div class="flex flex-wrap gap-2 justify-end">
|
||||
<a href="{{ url('/dashboard') }}" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded">
|
||||
Перейти в панель
|
||||
</a>
|
||||
<a href="{{ route('statements.create') }}" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
|
||||
Создать ведомость
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Номер ведомости</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Дата занятия</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Дисциплина</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Семестр</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Группа</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Преподаватель</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Тип</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Статус</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@foreach($statements as $statement)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{{ $statement['id'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ \Carbon\Carbon::parse($statement['exam_date'])->format('d.m.Y') }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{{ $statement['discipline']['name'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ $statement['semester'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ $statement['group']['name'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ $statement['teacher']['surname'] }}
|
||||
{{ $statement['teacher']['name'] }}
|
||||
{{ $statement['teacher']['patronymic'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ $statement['type_certification']['name'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ $statement['status']['name'] }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium flex justify-center items-center space-x-2">
|
||||
<form action="{{ route('statements.destroy', $statement['id']) }}" method="POST" class="inline">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="text-red-500 hover:text-red-700" onclick="return confirm('Вы уверены?')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
88
University.Web/resources/views/statistics/index.blade.php
Normal file
88
University.Web/resources/views/statistics/index.blade.php
Normal file
@@ -0,0 +1,88 @@
|
||||
@extends('layouts.app')
|
||||
@section('links')
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link href="/resources/css/app.css" rel="stylesheet">
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-8">
|
||||
<h1 class="text-2xl font-bold">Статистика</h1>
|
||||
<div class="flex flex-wrap gap-2 justify-end">
|
||||
<a href="{{ url('/dashboard') }}" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded">
|
||||
Перейти в панель
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-lg shadow p-6 mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4">Сформировать отчет</h2>
|
||||
<form method="GET" action="{{ route('statistics.generate') }}" class="space-y-4">
|
||||
@csrf
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="type" class="block text-sm font-medium text-gray-700">Тип отчета*</label>
|
||||
<select id="type" name="type" class="form-select mt-1 block w-full" required>
|
||||
<option value="" disabled selected>Выберите тип</option>
|
||||
<option value="group">По группе</option>
|
||||
<option value="direction">По направлению</option>
|
||||
<option value="teacher">По преподавателю</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="id" class="block text-sm font-medium text-gray-700">ID*</label>
|
||||
<input type="number" id="id" name="id" class="form-input mt-1 block w-full" required>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="start_date" class="block text-sm font-medium text-gray-700">Начальная дата*</label>
|
||||
<input type="date" id="start_date" name="start_date" class="form-input mt-1 block w-full" required>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="end_date" class="block text-sm font-medium text-gray-700">Конечная дата*</label>
|
||||
<input type="date" id="end_date" name="end_date" class="form-input mt-1 block w-full" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
|
||||
Сформировать PDF
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@isset($statistics)
|
||||
<div class="bg-white rounded-lg shadow overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Показатель</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Значение</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@foreach($statistics as $key => $value)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm font-medium text-gray-900">
|
||||
{{ ucfirst(str_replace('_', ' ', $key)) }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ is_array($value) ? json_encode($value) : $value }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endisset
|
||||
</div>
|
||||
@endsection
|
||||
@@ -43,4 +43,5 @@ Route::middleware(['jwt.auth'])->group(function () {
|
||||
|
||||
// Statistics
|
||||
Route::get('/statistics', [StatisticController::class, 'index'])->name('statistics.index');
|
||||
Route::get('/statistics/generate', [StatisticController::class, 'generate'])->name('statistics.generate');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user