mirror of
https://github.com/wowlikon/LiB.git
synced 2026-02-04 04:31:09 +00:00
Добавление аналитики
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
{% extends "base.html" %} {% block title %}Аналитика - LiB{% endblock %} {% block content %}
|
||||
<div class="container mx-auto p-4 max-w-7xl">
|
||||
<div class="mb-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900 mb-1">Аналитика выдач и возвратов</h1>
|
||||
<p class="text-sm text-gray-500">Статистика и графики по выдачам книг</p>
|
||||
</div>
|
||||
|
||||
<!-- Период анализа -->
|
||||
<div class="bg-white rounded-xl shadow-sm p-4 mb-6 border border-gray-100">
|
||||
<div class="flex items-center gap-4">
|
||||
<label class="text-sm font-medium text-gray-600">Период анализа:</label>
|
||||
<select id="period-select" class="px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-gray-400 transition bg-white">
|
||||
<option value="7">7 дней</option>
|
||||
<option value="30" selected>30 дней</option>
|
||||
<option value="90">90 дней</option>
|
||||
<option value="180">180 дней</option>
|
||||
<option value="365">365 дней</option>
|
||||
</select>
|
||||
<button id="refresh-btn" class="px-3 py-1.5 bg-gray-600 text-white rounded-lg hover:bg-gray-700 transition-colors text-sm font-medium">
|
||||
Обновить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Общая статистика -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Всего выдач</p>
|
||||
<p class="text-2xl font-semibold text-gray-900" id="total-loans">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Активные выдачи</p>
|
||||
<p class="text-2xl font-semibold text-gray-900" id="active-loans">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Возвращено</p>
|
||||
<p class="text-2xl font-semibold text-gray-900" id="returned-loans">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Просрочено</p>
|
||||
<p class="text-2xl font-semibold text-red-600" id="overdue-loans">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-red-50 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Забронировано</p>
|
||||
<p class="text-2xl font-semibold text-gray-900" id="reserved-books">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-5 border border-gray-100">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-gray-500 mb-1.5 uppercase tracking-wide">Выдано сейчас</p>
|
||||
<p class="text-2xl font-semibold text-gray-900" id="borrowed-books">—</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Графики -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<h2 class="text-base font-medium text-gray-700 mb-6">Выдачи по дням</h2>
|
||||
<div class="h-64">
|
||||
<canvas id="loans-chart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<h2 class="text-base font-medium text-gray-700 mb-6">Возвраты по дням</h2>
|
||||
<div class="h-64">
|
||||
<canvas id="returns-chart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Топ книг -->
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 border border-gray-100">
|
||||
<h2 class="text-base font-medium text-gray-700 mb-6">Топ книг по выдачам</h2>
|
||||
<div id="top-books-container" class="space-y-2">
|
||||
<div class="text-center text-gray-500 py-8">Загрузка данных...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block extra_head %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script src="/static/analytics.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -162,25 +162,46 @@
|
||||
<template
|
||||
x-if="user.roles && user.roles.includes('admin')"
|
||||
>
|
||||
<a
|
||||
href="/users"
|
||||
class="flex items-center px-4 py-2 text-sm hover:bg-gray-100 text-gray-700"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-3 text-gray-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
<div>
|
||||
<a
|
||||
href="/users"
|
||||
class="flex items-center px-4 py-2 text-sm hover:bg-gray-100 text-gray-700"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
|
||||
></path>
|
||||
</svg>
|
||||
Пользователи
|
||||
</a>
|
||||
<svg
|
||||
class="w-4 h-4 mr-3 text-gray-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"
|
||||
></path>
|
||||
</svg>
|
||||
Пользователи
|
||||
</a>
|
||||
<a
|
||||
href="/analytics"
|
||||
class="flex items-center px-4 py-2 text-sm hover:bg-gray-100 text-gray-700"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-3 text-gray-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
|
||||
></path>
|
||||
</svg>
|
||||
Аналитика
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<div class="border-t border-gray-200">
|
||||
<button
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<div class="container mx-auto p-4 max-w-4xl">
|
||||
<div id="book-card" class="bg-white rounded-lg shadow-md p-6">
|
||||
<div class="container mx-auto p-4 max-w-6xl">
|
||||
<div id="book-card" class="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<a
|
||||
href="/books"
|
||||
@@ -84,10 +84,11 @@
|
||||
</div>
|
||||
<div
|
||||
id="book-status-container"
|
||||
class="relative w-full flex justify-center z-10"
|
||||
class="relative w-full flex justify-center z-10 mb-4"
|
||||
></div>
|
||||
<div id="book-actions-container" class="mt-4 w-full"></div>
|
||||
<div id="book-actions-container" class="w-full"></div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 w-full">
|
||||
<div
|
||||
class="flex flex-col md:flex-row md:items-start md:justify-between mb-2"
|
||||
@@ -105,7 +106,6 @@
|
||||
id="book-authors-text"
|
||||
class="text-lg text-gray-600 font-medium mb-6"
|
||||
></p>
|
||||
|
||||
<div class="prose prose-gray max-w-none mb-8">
|
||||
<h3
|
||||
class="text-sm font-bold text-gray-400 uppercase tracking-wider mb-2"
|
||||
@@ -117,7 +117,6 @@
|
||||
class="text-gray-700 leading-relaxed"
|
||||
></p>
|
||||
</div>
|
||||
|
||||
<div id="genres-section" class="mb-6 hidden">
|
||||
<h3
|
||||
class="text-sm font-bold text-gray-400 uppercase tracking-wider mb-2"
|
||||
@@ -129,7 +128,6 @@
|
||||
class="flex flex-wrap gap-2"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div id="authors-section" class="mb-6 hidden">
|
||||
<h3
|
||||
class="text-sm font-bold text-gray-400 uppercase tracking-wider mb-2"
|
||||
@@ -144,6 +142,158 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Секция выдачи для библиотекарей и администраторов -->
|
||||
<div id="loans-section" class="hidden bg-white rounded-lg shadow-md p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold text-gray-900">Выдачи книги</h2>
|
||||
<button
|
||||
id="refresh-loans-btn"
|
||||
class="p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
title="Обновить список выдач"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="loans-container" class="space-y-3">
|
||||
<div class="text-center text-gray-500 py-8">
|
||||
Загрузка информации о выдачах...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Модальное окно для выдачи книги -->
|
||||
<div
|
||||
id="loan-modal"
|
||||
class="hidden fixed inset-0 z-50 overflow-y-auto"
|
||||
aria-labelledby="modal-title"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
<div
|
||||
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
|
||||
>
|
||||
<div
|
||||
class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||
aria-hidden="true"
|
||||
>​</span
|
||||
>
|
||||
<div
|
||||
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
|
||||
>
|
||||
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div
|
||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10"
|
||||
>
|
||||
<svg
|
||||
class="h-6 w-6 text-blue-600"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 4v16m8-8H4"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full"
|
||||
>
|
||||
<h3
|
||||
class="text-lg leading-6 font-medium text-gray-900"
|
||||
id="modal-title"
|
||||
>
|
||||
Оформить выдачу книги
|
||||
</h3>
|
||||
<div class="mt-4">
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
id="user-search-input"
|
||||
class="w-full border border-gray-300 rounded-md px-4 py-2 pl-10 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Поиск пользователя (имя, email)..."
|
||||
/>
|
||||
<svg
|
||||
class="w-5 h-5 text-gray-400 absolute left-3 top-2.5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
id="users-list-container"
|
||||
class="mt-4 border border-gray-200 rounded-md max-h-60 overflow-y-auto divide-y divide-gray-100"
|
||||
>
|
||||
<div
|
||||
class="p-4 text-center text-gray-500 text-sm"
|
||||
>
|
||||
Начните ввод для поиска...
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<label
|
||||
class="block text-sm font-medium text-gray-700"
|
||||
>Срок возврата</label
|
||||
>
|
||||
<input
|
||||
type="date"
|
||||
id="loan-due-date"
|
||||
class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
id="confirm-loan-btn"
|
||||
disabled
|
||||
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
Выдать
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="cancel-loan-btn"
|
||||
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
||||
>
|
||||
Отмена
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script src="/static/book.js"></script>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<div class="container mx-auto p-4 max-w-6xl">
|
||||
<div class="mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-2">Мои книги</h1>
|
||||
<p class="text-gray-600">Управление вашими бронированиями и выдачами</p>
|
||||
</div>
|
||||
|
||||
<!-- Бронирования -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold text-gray-900">Мои бронирования</h2>
|
||||
<span id="reservations-count" class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm font-medium">0</span>
|
||||
</div>
|
||||
<div id="reservations-container" class="space-y-3">
|
||||
<div class="text-center text-gray-500 py-8">
|
||||
Загрузка бронирований...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Активные выдачи -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold text-gray-900">Активные выдачи</h2>
|
||||
<span id="active-loans-count" class="px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full text-sm font-medium">0</span>
|
||||
</div>
|
||||
<div id="active-loans-container" class="space-y-3">
|
||||
<div class="text-center text-gray-500 py-8">
|
||||
Загрузка активных выдач...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Возвращенные книги -->
|
||||
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold text-gray-900">История возвратов</h2>
|
||||
<span id="returned-count" class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm font-medium">0</span>
|
||||
</div>
|
||||
<div id="returned-container" class="space-y-3">
|
||||
<div class="text-center text-gray-500 py-8">
|
||||
Загрузка истории...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script src="/static/my_books.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user