Училищна Библиотека
Зареждане...
Училищна Библиотека
Табло за управление
0
Общо книги
0
Ученици
0
Наемани книги
0
Просрочени
Детайли
Управление на книги
| Заглавие | Автор | ISBN | Категория | Статус | Действия |
|---|
Управление на ученици
| Име | Клас | Имейл | Телефон | Наети книги | Действия |
|---|
Наемане на книги
| Ученик | Книга | Дата на наемане | Краен срок | Статус | Действия |
|---|
Хронология на заеманията
| Ученик | Книга | Дата на наемане | Дата на връщане | Краен срок | Статус |
|---|
Справки и статистика
Най-заемана книга
-
Най-активен ученик
-
Средно време за заемане
-
| Категория | Общо книги | Наемани | Налични |
|---|
Добави книга
Добави ученик
/* WordPress School Library - Elementor Compatible CSS */
.school-library-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
color: #333;
overflow-x: hidden;
margin: 0;
padding: 0;
}
.school-library-container * {
box-sizing: border-box;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* Loading Screen */
.loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
color: white;
text-align: center;
animation: fadeIn 0.5s ease-out;
backdrop-filter: blur(5px);
}
.loading-screen.hidden {
display: none;
opacity: 0;
transition: opacity 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.loading-icon {
font-size: 4rem;
margin-bottom: 2rem;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.8; }
100% { transform: scale(1); opacity: 1; }
}
.loading-text {
font-size: 1.5rem;
font-weight: 500;
margin-bottom: 1rem;
}
.loading-subtitle {
font-size: 1rem;
opacity: 0.8;
}
/* Header */
.library-header {
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
color: white;
padding: 2rem 0;
text-align: center;
border-radius: 0 0 20px 20px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
margin-bottom: 1rem;
}
.library-header h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
}
/* Navigation */
.library-nav {
background: linear-gradient(135deg, #5a9fd4 0%, #4a90e2 100%);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 100;
border-radius: 15px;
margin: 1rem 0;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.library-nav .container {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 1rem;
}
.nav-btn {
background: rgba(255,255,255,0.2);
color: white;
border: 2px solid rgba(255,255,255,0.3);
padding: 0.75rem 1.5rem;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1rem;
}
.nav-btn:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-2px);
}
.nav-btn.active {
background: rgba(255,255,255,0.4);
border-color: white;
}
/* Main Content */
.library-main {
padding: 1rem 0;
}
.content-section {
display: none;
background: white;
padding: 2rem;
border-radius: 15px;
margin-bottom: 2rem;
animation: slideIn 0.5s;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
}
.content-section.active {
display: block;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 2px solid #e9ecef;
}
.section-header h2 {
color: #2c3e50;
font-size: 2rem;
margin: 0;
}
/* Buttons */
.btn {
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-size: 1rem;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(74, 144, 226, 0.3);
}
.btn-secondary {
background: linear-gradient(135deg, #6c757d 0%, #5a6268 100%);
}
.btn-danger {
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
}
.btn-success {
background: linear-gradient(135deg, #28a745 0%, #1e7e34 100%);
}
.btn-sm {
padding: 0.5rem 1rem;
font-size: 0.875rem;
}
/* Dashboard */
.dashboard-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.stat-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
color: #2c3e50;
padding: 2rem;
border-radius: 15px;
text-align: center;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
transition: all 0.3s;
border: 1px solid #e9ecef;
cursor: pointer;
}
.stat-card:nth-child(2) {
background: linear-gradient(135deg, #ffffff 0%, #e3f2fd 100%);
}
.stat-card:nth-child(3) {
background: linear-gradient(135deg, #ffffff 0%, #e8f5e8 100%);
}
.stat-card:nth-child(4) {
background: linear-gradient(135deg, #ffffff 0%, #fff3e0 100%);
}
.stat-card h3 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
font-weight: 700;
color: #2c3e50;
}
.stat-card p {
font-size: 1.1rem;
font-weight: 500;
color: #6c757d;
}
.stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0,0,0,0.12);
}
.dashboard-detail {
background: white;
border-radius: 15px;
padding: 2rem;
margin-top: 2rem;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
}
.detail-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 2px solid #e9ecef;
}
/* Search and Filters */
.search-filter {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
flex-wrap: wrap;
}
.search-filter input,
.search-filter select {
padding: 0.75rem;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s;
background: white;
flex: 1;
min-width: 200px;
}
.search-filter input:focus,
.search-filter select:focus {
outline: none;
border-color: #4a90e2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
}
/* Tables */
.table-container {
overflow-x: auto;
margin-top: 1rem;
}
table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
th, td {
padding: 1rem;
text-align: left;
border-bottom: 1px solid #e9ecef;
}
th {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
font-weight: 600;
color: #2c3e50;
}
tr:hover {
background: #f8f9fa;
}
/* Status Badges */
.status-badge {
padding: 0.5rem 1rem;
border-radius: 15px;
font-size: 0.875rem;
font-weight: 500;
}
.status-available {
background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
color: #155724;
}
.status-checked-out {
background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
color: #721c24;
}
.status-overdue {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
color: #856404;
}
/* Forms */
.form-group {
margin-bottom: 1.5rem;
position: relative;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
color: #2c3e50;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 0.75rem;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s;
background: white;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: #4a90e2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
}
.form-actions {
display: flex;
gap: 1rem;
justify-content: flex-end;
margin-top: 2rem;
}
/* Modals */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 1000;
animation: fadeIn 0.3s;
}
.modal.show {
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
padding: 2rem;
border-radius: 15px;
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
animation: slideUp 0.3s;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(50px); }
to { opacity: 1; transform: translateY(0); }
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 2px solid #e9ecef;
}
.modal-header h3 {
color: #2c3e50;
font-size: 1.5rem;
margin: 0;
}
.close {
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
border: none;
font-size: 1.5rem;
cursor: pointer;
color: white;
transition: all 0.3s;
padding: 0.5rem;
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.close:hover {
transform: scale(1.1);
}
/* Autocomplete */
.suggestions-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: white;
border: 2px solid #e9ecef;
border-top: none;
border-radius: 0 0 8px 8px;
max-height: 200px;
overflow-y: auto;
z-index: 1000;
display: none;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.suggestions-dropdown.show {
display: block;
}
.suggestion-item {
padding: 0.75rem 1rem;
cursor: pointer;
border-bottom: 1px solid #e9ecef;
transition: background-color 0.2s;
}
.suggestion-item:hover {
background-color: #f8f9fa;
}
.suggestion-item:last-child {
border-bottom: none;
}
.suggestion-item strong {
color: #4a90e2;
}
/* Reports */
.reports-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
margin-bottom: 2rem;
}
.report-card {
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
padding: 2rem;
border-radius: 15px;
text-align: center;
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
border: 1px solid #e9ecef;
}
.report-card h3 {
color: #2c3e50;
margin-bottom: 1rem;
font-size: 1.2rem;
}
.report-card p {
color: #4a90e2;
font-size: 1.5rem;
font-weight: 600;
margin: 0;
}
/* Empty State */
.empty-state {
text-align: center;
padding: 3rem;
color: #6c757d;
}
.empty-state i {
font-size: 3rem;
margin-bottom: 1rem;
opacity: 0.5;
}
/* Responsive Design */
@media (max-width: 768px) {
.container {
padding: 0 10px;
}
.library-header h1 {
font-size: 2rem;
}
.nav-btn {
padding: 0.5rem 1rem;
font-size: 0.9rem;
}
.content-section {
padding: 1rem;
}
.dashboard-stats {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.stat-card {
padding: 1.5rem;
}
.stat-card h3 {
font-size: 2rem;
}
.search-filter {
flex-direction: column;
}
.search-filter input,
.search-filter select {
min-width: auto;
}
.table-container {
font-size: 0.9rem;
}
th, td {
padding: 0.5rem;
}
.modal-content {
padding: 1.5rem;
margin: 1rem;
}
.form-actions {
flex-direction: column;
}
.btn {
width: 100%;
justify-content: center;
}
}
/* WordPress Compatibility */
.elementor-widget-wrap .school-library-container {
margin: 0 !important;
padding: 0 !important;
}
.elementor-section .school-library-container {
background: transparent !important;
}
/* Fix for Elementor conflicts */
.school-library-container .elementor-element {
background: transparent !important;
}
.school-library-container .elementor-widget-container {
padding: 0 !important;
}
// WordPress School Library - Elementor Compatible JavaScript
(function($) {
'use strict';
// Data Storage
let books = [];
let students = [];
let checkouts = [];
let currentEditBookId = null;
let currentEditStudentId = null;
// Initialize the application
$(document).ready(function() {
// Check if we're in WordPress environment
if (typeof wp !== 'undefined' || typeof elementorFrontend !== 'undefined') {
console.log('WordPress Environment Detected');
}
// Initialize app
initializeApp();
});
function initializeApp() {
loadData();
initializeForms();
updateDashboard();
renderBooks();
renderStudents();
renderCheckouts();
renderHistory();
updateReports();
setDefaultDueDate();
// Hide loading screen
setTimeout(() => {
$('#loading-screen').fadeOut(500);
}, 1000);
}
// WordPress compatible data loading
function loadData() {
// Try to load from WordPress user meta first
if (typeof wp !== 'undefined' && wp.apiRequest) {
// WordPress REST API integration
loadFromWordPress();
} else {
// Fallback to localStorage
loadFromLocalStorage();
}
}
function loadFromWordPress() {
// This would integrate with WordPress REST API
// For now, fallback to localStorage
loadFromLocalStorage();
}
function loadFromLocalStorage() {
const savedBooks = localStorage.getItem('school_library_books');
const savedStudents = localStorage.getItem('school_library_students');
const savedCheckouts = localStorage.getItem('school_library_checkouts');
if (savedBooks) books = JSON.parse(savedBooks);
if (savedStudents) students = JSON.parse(savedStudents);
if (savedCheckouts) checkouts = JSON.parse(savedCheckouts);
if (books.length === 0 || students.length === 0) {
loadSampleData();
}
}
function saveData() {
// Try to save to WordPress first
if (typeof wp !== 'undefined' && wp.apiRequest) {
saveToWordPress();
} else {
// Fallback to localStorage
saveToLocalStorage();
}
}
function saveToWordPress() {
// WordPress REST API integration would go here
// For now, use localStorage
saveToLocalStorage();
}
function saveToLocalStorage() {
localStorage.setItem('school_library_books', JSON.stringify(books));
localStorage.setItem('school_library_students', JSON.stringify(students));
localStorage.setItem('school_library_checkouts', JSON.stringify(checkouts));
}
function loadSampleData() {
books = [
{id: 1, title: "1984", author: "Джордж Оруел", isbn: "978-954-292-123-4", category: "Художествена литература", totalCopies: 3, availableCopies: 2},
{id: 2, title: "Кратка история на времето", author: "Стивън Хокинг", isbn: "978-954-292-456-7", category: "Наука", totalCopies: 2, availableCopies: 1},
{id: 3, title: "Война и мир", author: "Лев Толстой", isbn: "978-954-292-789-0", category: "Художествена литература", totalCopies: 2, availableCopies: 2}
];
students = [
{id: 1, name: "Иван Петров", grade: "10", email: "ivan.petrov@school.edu", phone: "0888-123-456", booksBorrowed: 1},
{id: 2, name: "Мария Иванова", grade: "11", email: "maria.ivanova@school.edu", phone: "0888-654-321", booksBorrowed: 0}
];
checkouts = [
{id: 1, studentId: 1, bookId: 1, checkoutDate: new Date('2024-01-15').toISOString(), dueDate: new Date('2024-01-29').toISOString(), returnDate: null, status: 'active'}
];
saveData();
}
function initializeForms() {
// Navigation
$('.nav-btn').on('click', function() {
const section = $(this).data('section');
showSection(section);
$('.nav-btn').removeClass('active');
$(this).addClass('active');
});
// Forms
$('#book-form').on('submit', saveBook);
$('#student-form').on('submit', saveStudent);
$('#checkout-form').on('submit', checkoutBook);
// Search
$('#book-search').on('input', renderBooks);
$('#student-search').on('input', renderStudents);
$('#history-search').on('input', renderHistory);
// Filters
$('#category-filter').on('change', renderBooks);
$('#history-filter').on('change', renderHistory);
// Autocomplete
initializeAutocomplete();
}
function showSection(sectionId) {
$('.content-section').removeClass('active');
$(`#${sectionId}`).addClass('active');
}
// Book Functions
function openBookModal(bookId = null) {
currentEditBookId = bookId;
const modal = $('#book-modal');
const title = $('#book-modal-title');
const form = $('#book-form');
if (bookId) {
const book = books.find(b => b.id === bookId);
if (book) {
title.text('Редактирай книга');
$('#book-title-input').val(book.title);
$('#book-author').val(book.author);
$('#book-isbn').val(book.isbn || '');
$('#book-category').val(book.category);
$('#book-total-copies').val(book.totalCopies);
}
} else {
title.text('Добави книга');
form[0].reset();
}
modal.addClass('show');
}
function closeBookModal() {
$('#book-modal').removeClass('show');
currentEditBookId = null;
}
function saveBook(e) {
e.preventDefault();
const title = $('#book-title-input').val();
const author = $('#book-author').val();
const isbn = $('#book-isbn').val();
const category = $('#book-category').val();
const totalCopies = parseInt($('#book-total-copies').val());
if (currentEditBookId) {
const book = books.find(b => b.id === currentEditBookId);
if (book) {
book.title = title;
book.author = author;
book.isbn = isbn;
book.category = category;
book.totalCopies = totalCopies;
}
} else {
const newBook = {id: Date.now(), title, author, isbn, category, totalCopies, availableCopies: totalCopies};
books.push(newBook);
}
saveData();
renderBooks();
updateDashboard();
closeBookModal();
showToast('Книгата е запазена успешно', 'success');
}
function deleteBook(bookId) {
const book = books.find(b => b.id === bookId);
if (!book) return;
const activeCheckouts = checkouts.filter(c => c.bookId === bookId && c.status === 'active');
if (activeCheckouts.length > 0) {
showToast('Не може да изтриете книга, която е наета', 'error');
return;
}
if (confirm(`Наистина ли искате да изтриете книгата "${book.title}" от ${book.author}?`)) {
books = books.filter(b => b.id !== bookId);
saveData();
renderBooks();
updateDashboard();
showToast('Книгата е изтрита успешно', 'success');
}
}
function renderBooks() {
const tbody = $('#books-table');
const searchTerm = $('#book-search').val().toLowerCase();
const categoryFilter = $('#category-filter').val();
let filteredBooks = books.filter(book => {
const matchesSearch = book.title.toLowerCase().includes(searchTerm) ||
book.author.toLowerCase().includes(searchTerm);
const matchesCategory = !categoryFilter || book.category === categoryFilter;
return matchesSearch && matchesCategory;
});
if (filteredBooks.length === 0) {
tbody.html(`
`);
return;
}
tbody.html(filteredBooks.map(book => {
const statusClass = book.availableCopies > 0 ? 'status-available' : 'status-checked-out';
const statusText = book.availableCopies > 0 ? 'Налична' : 'Наемана';
return `
${book.title}
${book.author}
${book.isbn || '-'}
${book.category}
${statusText}
`;
}).join(''));
}
// Student Functions
function openStudentModal(studentId = null) {
currentEditStudentId = studentId;
const modal = $('#student-modal');
const title = $('#student-modal-title');
const form = $('#student-form');
if (studentId) {
const student = students.find(s => s.id === studentId);
if (student) {
title.text('Редактирай ученик');
$('#student-name-input').val(student.name);
$('#student-grade').val(student.grade);
$('#student-email').val(student.email || '');
$('#student-phone').val(student.phone || '');
}
} else {
title.text('Добави ученик');
form[0].reset();
}
modal.addClass('show');
}
function closeStudentModal() {
$('#student-modal').removeClass('show');
currentEditStudentId = null;
}
function saveStudent(e) {
e.preventDefault();
const name = $('#student-name-input').val();
const grade = $('#student-grade').val();
const email = $('#student-email').val();
const phone = $('#student-phone').val();
if (currentEditStudentId) {
const student = students.find(s => s.id === currentEditStudentId);
if (student) {
student.name = name;
student.grade = grade;
student.email = email;
student.phone = phone;
}
} else {
const newStudent = {id: Date.now(), name, grade, email, phone, booksBorrowed: 0};
students.push(newStudent);
}
saveData();
renderStudents();
updateDashboard();
closeStudentModal();
showToast('Ученикът е запазен успешно', 'success');
}
function deleteStudent(studentId) {
const student = students.find(s => s.id === studentId);
if (!student) return;
const activeCheckouts = checkouts.filter(c => c.studentId === studentId && c.status === 'active');
if (activeCheckouts.length > 0) {
showToast('Не може да изтриете ученик с наети книги', 'error');
return;
}
if (confirm(`Наистина ли искате да изтриете ученика "${student.name}"?`)) {
students = students.filter(s => s.id !== studentId);
saveData();
renderStudents();
updateDashboard();
showToast('Ученикът е изтрит успешно', 'success');
}
}
function renderStudents() {
const tbody = $('#students-table');
const searchTerm = $('#student-search').val().toLowerCase();
let filteredStudents = students.filter(student =>
student.name.toLowerCase().includes(searchTerm)
);
if (filteredStudents.length === 0) {
tbody.html(`
`);
return;
}
tbody.html(filteredStudents.map(student => `
${student.name}
${student.grade} клас
${student.email || '-'}
${student.phone || '-'}
${student.booksBorrowed}
`).join(''));
}
// Checkout Functions
function checkoutBook(e) {
e.preventDefault();
const studentName = $('#student-name').val();
const bookTitle = $('#book-title').val();
const dueDate = $('#due-date').val();
const student = students.find(s => s.name === studentName);
const book = books.find(b => b.title === bookTitle);
if (!student || !book) {
showToast('Моля, изберете валиден ученик и книга', 'error');
return;
}
if (book.availableCopies <= 0) {
showToast('Няма налични копия от тази книга', 'error');
return;
}
const checkout = {
id: Date.now(),
studentId: student.id,
bookId: book.id,
checkoutDate: new Date().toISOString(),
dueDate: dueDate ? new Date(dueDate).toISOString() : new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString(),
returnDate: null,
status: 'active'
};
checkouts.push(checkout);
book.availableCopies--;
student.booksBorrowed++;
saveData();
renderCheckouts();
renderBooks();
renderStudents();
updateDashboard();
$('#checkout-form')[0].reset();
setDefaultDueDate();
showToast('Книгата е наета успешно', 'success');
}
function returnBook(checkoutId) {
const checkout = checkouts.find(c => c.id === checkoutId);
if (!checkout) return;
const book = books.find(b => b.id === checkout.bookId);
const student = students.find(s => s.id === checkout.studentId);
if (book && student) {
book.availableCopies++;
student.booksBorrowed--;
}
checkout.returnDate = new Date().toISOString();
checkout.status = 'returned';
saveData();
renderCheckouts();
renderBooks();
renderStudents();
renderHistory();
updateDashboard();
showToast('Книгата е върната успешно', 'success');
}
function renderCheckouts() {
const tbody = $('#checkouts-table');
const activeCheckouts = checkouts.filter(c => c.status === 'active');
if (activeCheckouts.length === 0) {
tbody.html(`
`);
return;
}
tbody.html(activeCheckouts.map(checkout => {
const student = students.find(s => s.id === checkout.studentId);
const book = books.find(b => b.id === checkout.bookId);
const isOverdue = new Date(checkout.dueDate) < new Date();
return `
${student ? student.name : 'Неизвестен ученик'}
${book ? book.title : 'Неизвестна книга'}
${new Date(checkout.checkoutDate).toLocaleDateString('bg-BG')}
${new Date(checkout.dueDate).toLocaleDateString('bg-BG')}
${isOverdue ? 'Просрочено' : 'Активно'}
`;
}).join(''));
}
// History Functions
function renderHistory() {
const tbody = $('#history-table');
const searchTerm = $('#history-search').val().toLowerCase();
const statusFilter = $('#history-filter').val();
let filteredCheckouts = checkouts.filter(checkout => {
const student = students.find(s => s.id === checkout.studentId);
const book = books.find(b => b.id === checkout.bookId);
const matchesSearch = (student && student.name.toLowerCase().includes(searchTerm)) ||
(book && book.title.toLowerCase().includes(searchTerm));
const matchesStatus = !statusFilter || checkout.status === statusFilter;
return matchesSearch && matchesStatus;
});
if (filteredCheckouts.length === 0) {
tbody.html(`
`);
return;
}
tbody.html(filteredCheckouts.map(checkout => {
const student = students.find(s => s.id === checkout.studentId);
const book = books.find(b => b.id === checkout.bookId);
const isOverdue = checkout.status === 'active' && new Date(checkout.dueDate) < new Date();
return `
${student ? student.name : 'Неизвестен ученик'}
${book ? book.title : 'Неизвестна книга'}
${new Date(checkout.checkoutDate).toLocaleDateString('bg-BG')}
${checkout.returnDate ? new Date(checkout.returnDate).toLocaleDateString('bg-BG') : '-'}
${new Date(checkout.dueDate).toLocaleDateString('bg-BG')}
${checkout.status === 'returned' ? 'Върната' :
isOverdue ? 'Просрочена' : 'Активна'}
`;
}).join(''));
}
// Dashboard Functions
function updateDashboard() {
$('#total-books').text(books.reduce((sum, book) => sum + book.totalCopies, 0));
$('#total-students').text(students.length);
$('#checked-out').text(checkouts.filter(c => c.status === 'active').length);
$('#overdue').text(checkouts.filter(c =>
c.status === 'active' && new Date(c.dueDate) < new Date()
).length);
}
function showDashboardDetail(type) {
const detailSection = $('#dashboard-detail');
const detailTitle = $('#detail-title');
const detailContent = $('#detail-content');
let title = '';
let content = '';
switch(type) {
case 'books':
title = '📚 Детайли за книгите';
const totalBooks = books.reduce((sum, book) => sum + book.totalCopies, 0);
const availableBooks = books.reduce((sum, book) => sum + book.availableCopies, 0);
const borrowedBooks = totalBooks - availableBooks;
content = `
`;
break;
case 'students':
title = '👥 Детайли за учениците';
const totalStudents = students.length;
const activeStudents = students.filter(s => s.booksBorrowed > 0).length;
const inactiveStudents = totalStudents - activeStudents;
content = `
`;
break;
case 'checked-out':
title = '📚 Наети книги';
const activeCheckouts = checkouts.filter(c => c.status === 'active');
content = `
`;
break;
case 'overdue':
title = '⚠️ Просрочени книги';
const overdueCheckouts = checkouts.filter(c => c.status === 'active' && new Date(c.dueDate) < new Date());
content = `
`;
break;
}
detailTitle.text(title);
detailContent.html(content);
detailSection.show();
$('html, body').animate({
scrollTop: detailSection.offset().top - 100
}, 500);
}
function hideDashboardDetail() {
$('#dashboard-detail').hide();
}
// Reports Functions
function updateReports() {
const bookCounts = {};
checkouts.forEach(checkout => {
const book = books.find(b => b.id === checkout.bookId);
if (book) {
bookCounts[book.title] = (bookCounts[book.title] || 0) + 1;
}
});
const mostBorrowedBook = Object.keys(bookCounts).length > 0
? Object.keys(bookCounts).reduce((a, b) => bookCounts[a] > bookCounts[b] ? a : b)
: '-';
$('#most-borrowed-book').text(mostBorrowedBook);
const studentCounts = {};
checkouts.forEach(checkout => {
const student = students.find(s => s.id === checkout.studentId);
if (student) {
studentCounts[student.name] = (studentCounts[student.name] || 0) + 1;
}
});
const mostActiveStudent = Object.keys(studentCounts).length > 0
? Object.keys(studentCounts).reduce((a, b) => studentCounts[a] > studentCounts[b] ? a : b)
: '-';
$('#most-active-student').text(mostActiveStudent);
const returnedCheckouts = checkouts.filter(c => c.status === 'returned' && c.returnDate);
let totalDays = 0;
returnedCheckouts.forEach(checkout => {
const checkoutDate = new Date(checkout.checkoutDate);
const returnDate = new Date(checkout.returnDate);
const days = Math.floor((returnDate - checkoutDate) / (1000 * 60 * 60 * 24));
totalDays += days;
});
const avgDays = returnedCheckouts.length > 0 ? Math.round(totalDays / returnedCheckouts.length) : 0;
$('#avg-borrow-time').text(avgDays > 0 ? `${avgDays} дни` : '-');
const categoryStats = {};
books.forEach(book => {
if (!categoryStats[book.category]) {
categoryStats[book.category] = { total: 0, available: 0 };
}
categoryStats[book.category].total += book.totalCopies;
categoryStats[book.category].available += book.availableCopies;
});
const reportsTable = $('#reports-table');
reportsTable.html(Object.entries(categoryStats).map(([category, stats]) => {
const borrowed = stats.total - stats.available;
return `
${category}
${stats.total}
${borrowed}
${stats.available}
`;
}).join(''));
}
// Autocomplete Functions
function initializeAutocomplete() {
const studentInput = $('#student-name');
const studentSuggestions = $('#student-suggestions');
const bookInput = $('#book-title');
const bookSuggestions = $('#book-suggestions');
if (studentInput.length) {
studentInput.on('input', function() {
const value = $(this).val().toLowerCase();
if (value.length < 2) {
studentSuggestions.removeClass('show');
return;
}
const matches = students.filter(student =>
student.name.toLowerCase().includes(value)
);
if (matches.length > 0) {
studentSuggestions.html(matches.map(student => `
Няма намерени книги
Няма намерени ученици
Няма активни наемания
Няма записи в хронологията
${totalBooks}
Общо книги
${availableBooks}
Налични
${borrowedBooks}
Наемани
${totalStudents}
Общо ученици
${activeStudents}
Активни
${inactiveStudents}
Неактивни
${activeCheckouts.length}
Активни наема
${overdueCheckouts.length}
Просрочени наема
${student.name} - ${student.grade} клас
`).join(''));
studentSuggestions.addClass('show');
} else {
studentSuggestions.removeClass('show');
}
});
studentInput.on('blur', function() {
setTimeout(() => studentSuggestions.removeClass('show'), 200);
});
}
if (bookInput.length) {
bookInput.on('input', function() {
const value = $(this).val().toLowerCase();
if (value.length < 2) {
bookSuggestions.removeClass('show');
return;
}
const matches = books.filter(book =>
book.availableCopies > 0 &&
(book.title.toLowerCase().includes(value) || book.author.toLowerCase().includes(value))
);
if (matches.length > 0) {
bookSuggestions.html(matches.map(book => `
${book.title} - ${book.author}
`).join(''));
bookSuggestions.addClass('show');
} else {
bookSuggestions.removeClass('show');
}
});
bookInput.on('blur', function() {
setTimeout(() => bookSuggestions.removeClass('show'), 200);
});
}
}
function selectStudent(studentId) {
const student = students.find(s => s.id === studentId);
if (student) {
$('#student-name').val(student.name);
$('#student-suggestions').removeClass('show');
}
}
function selectBook(bookId) {
const book = books.find(b => b.id === bookId);
if (book) {
$('#book-title').val(book.title);
$('#book-suggestions').removeClass('show');
}
}
function setDefaultDueDate() {
const defaultDate = new Date();
defaultDate.setDate(defaultDate.getDate() + 14);
$('#due-date').val(defaultDate.toISOString().split('T')[0]);
}
// Toast notification
function showToast(message, type = 'success') {
const toast = $(`${message}
`);
toast.css({
position: 'fixed',
top: '20px',
right: '20px',
padding: '1rem 1.5rem',
borderRadius: '25px',
color: 'white',
fontWeight: '500',
zIndex: '2000',
transform: 'translateX(400px)',
transition: 'all 0.3s ease',
boxShadow: '0 10px 30px rgba(0,0,0,0.2)'
});
if (type === 'success') {
toast.css('background', 'linear-gradient(135deg, #56ab2f 0%, #a8e063 100%)');
} else if (type === 'error') {
toast.css('background', 'linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%)');
}
$('body').append(toast);
setTimeout(() => {
toast.css('transform', 'translateX(0)');
}, 100);
setTimeout(() => {
toast.css('transform', 'translateX(400px)');
setTimeout(() => {
toast.remove();
}, 300);
}, 3000);
}
// Make functions globally accessible
window.openBookModal = openBookModal;
window.closeBookModal = closeBookModal;
window.deleteBook = deleteBook;
window.openStudentModal = openStudentModal;
window.closeStudentModal = closeStudentModal;
window.deleteStudent = deleteStudent;
window.returnBook = returnBook;
window.selectStudent = selectStudent;
window.selectBook = selectBook;
window.showDashboardDetail = showDashboardDetail;
window.hideDashboardDetail = hideDashboardDetail;
})(jQuery);
