Добавление мета-тэгов

This commit is contained in:
2026-01-31 15:29:15 +03:00
parent 6014db3c81
commit dfa4d14afc
24 changed files with 134 additions and 139 deletions
+23 -22
View File
@@ -1,9 +1,9 @@
# Postgres # Postgres
POSTGRES_HOST="localhost" POSTGRES_HOST=localhost
POSTGRES_PORT="5432" POSTGRES_PORT=5432
POSTGRES_USER="postgres" POSTGRES_USER=postgres
POSTGRES_PASSWORD="postgres" POSTGRES_PASSWORD=postgres
POSTGRES_DB="lib" POSTGRES_DB=lib
# Ollama # Ollama
OLLAMA_URL="http://localhost:11434" OLLAMA_URL="http://localhost:11434"
@@ -16,28 +16,29 @@ OLLAMA_KEEP_ALIVE=5m
# DEFAULT_ADMIN_EMAIL="admin@example.com" # DEFAULT_ADMIN_EMAIL="admin@example.com"
# DEFAULT_ADMIN_PASSWORD="password-is-generated-randomly-on-first-launch" # DEFAULT_ADMIN_PASSWORD="password-is-generated-randomly-on-first-launch"
SECRET_KEY="your-secret-key-change-in-production" SECRET_KEY="your-secret-key-change-in-production"
DOMAIN=localhost
# JWT # JWT
ALGORITHM="HS256" ALGORITHM=HS256
REFRESH_TOKEN_EXPIRE_DAYS="7" REFRESH_TOKEN_EXPIRE_DAYS=7
ACCESS_TOKEN_EXPIRE_MINUTES="15" ACCESS_TOKEN_EXPIRE_MINUTES=15
PARTIAL_TOKEN_EXPIRE_MINUTES="5" PARTIAL_TOKEN_EXPIRE_MINUTES=5
# Hash # Hash
ARGON2_TYPE="id" ARGON2_TYPE=id
ARGON2_TIME_COST="3" ARGON2_TIME_COST=3
ARGON2_MEMORY_COST="65536" ARGON2_MEMORY_COST=65536
ARGON2_PARALLELISM="4" ARGON2_PARALLELISM=4
ARGON2_SALT_LENGTH="16" ARGON2_SALT_LENGTH=16
ARGON2_HASH_LENGTH="48" ARGON2_HASH_LENGTH=48
# Recovery codes # Recovery codes
RECOVERY_CODES_COUNT="10" RECOVERY_CODES_COUNT=10
RECOVERY_CODE_SEGMENTS="4" RECOVERY_CODE_SEGMENTS=4
RECOVERY_CODE_SEGMENT_BYTES="2" RECOVERY_CODE_SEGMENT_BYTES=2
RECOVERY_MIN_REMAINING_WARNING="3" RECOVERY_MIN_REMAINING_WARNING=3
RECOVERY_MAX_AGE_DAYS="365" RECOVERY_MAX_AGE_DAYS=365
# TOTP_2FA # TOTP_2FA
TOTP_ISSUER="LiB" TOTP_ISSUER=LiB
TOTP_VALID_WINDOW="1" TOTP_VALID_WINDOW=1
+23 -22
View File
@@ -1,9 +1,9 @@
# Postgres # Postgres
POSTGRES_HOST="db" POSTGRES_HOST=db
POSTGRES_PORT="5432" POSTGRES_PORT=5432
POSTGRES_USER="postgres" POSTGRES_USER=postgres
POSTGRES_PASSWORD="postgres" POSTGRES_PASSWORD=postgres
POSTGRES_DB="lib" POSTGRES_DB=lib
REMOTE_HOST= REMOTE_HOST=
REMOTE_PORT= REMOTE_PORT=
NODE_ID= NODE_ID=
@@ -19,28 +19,29 @@ DEFAULT_ADMIN_USERNAME="admin"
DEFAULT_ADMIN_EMAIL="admin@example.com" DEFAULT_ADMIN_EMAIL="admin@example.com"
DEFAULT_ADMIN_PASSWORD="Password12345" DEFAULT_ADMIN_PASSWORD="Password12345"
SECRET_KEY="your-secret-key-change-in-production" SECRET_KEY="your-secret-key-change-in-production"
DOMAIN="mydomain.com"
# JWT # JWT
ALGORITHM="HS256" ALGORITHM=HS256
REFRESH_TOKEN_EXPIRE_DAYS="7" REFRESH_TOKEN_EXPIRE_DAYS=7
ACCESS_TOKEN_EXPIRE_MINUTES="15" ACCESS_TOKEN_EXPIRE_MINUTES=15
PARTIAL_TOKEN_EXPIRE_MINUTES="5" PARTIAL_TOKEN_EXPIRE_MINUTES=5
# Hash # Hash
ARGON2_TYPE="id" ARGON2_TYPE=id
ARGON2_TIME_COST="3" ARGON2_TIME_COST=3
ARGON2_MEMORY_COST="65536" ARGON2_MEMORY_COST=65536
ARGON2_PARALLELISM="4" ARGON2_PARALLELISM=4
ARGON2_SALT_LENGTH="16" ARGON2_SALT_LENGTH=16
ARGON2_HASH_LENGTH="48" ARGON2_HASH_LENGTH=48
# Recovery codes # Recovery codes
RECOVERY_CODES_COUNT="10" RECOVERY_CODES_COUNT=10
RECOVERY_CODE_SEGMENTS="4" RECOVERY_CODE_SEGMENTS=4
RECOVERY_CODE_SEGMENT_BYTES="2" RECOVERY_CODE_SEGMENT_BYTES=2
RECOVERY_MIN_REMAINING_WARNING="3" RECOVERY_MIN_REMAINING_WARNING=3
RECOVERY_MAX_AGE_DAYS="365" RECOVERY_MAX_AGE_DAYS=365
# TOTP_2FA # TOTP_2FA
TOTP_ISSUER="LiB" TOTP_ISSUER=LiB
TOTP_VALID_WINDOW="1" TOTP_VALID_WINDOW=1
+23 -22
View File
@@ -1,9 +1,9 @@
# Postgres # Postgres
POSTGRES_HOST="localhost" POSTGRES_HOST=localhost
POSTGRES_PORT="5432" POSTGRES_PORT=5432
POSTGRES_USER="postgres" POSTGRES_USER=postgres
POSTGRES_PASSWORD="postgres" POSTGRES_PASSWORD=postgres
POSTGRES_DB="lib" POSTGRES_DB=lib
# Ollama # Ollama
OLLAMA_URL="http://localhost:11434" OLLAMA_URL="http://localhost:11434"
@@ -16,28 +16,29 @@ DEFAULT_ADMIN_USERNAME="admin"
DEFAULT_ADMIN_EMAIL="admin@example.com" DEFAULT_ADMIN_EMAIL="admin@example.com"
DEFAULT_ADMIN_PASSWORD="Password12345" DEFAULT_ADMIN_PASSWORD="Password12345"
SECRET_KEY="your-secret-key-change-in-production" SECRET_KEY="your-secret-key-change-in-production"
DOMAIN="mydomain.com"
# JWT # JWT
ALGORITHM="HS256" ALGORITHM=HS256
REFRESH_TOKEN_EXPIRE_DAYS="7" REFRESH_TOKEN_EXPIRE_DAYS=7
ACCESS_TOKEN_EXPIRE_MINUTES="15" ACCESS_TOKEN_EXPIRE_MINUTES=15
PARTIAL_TOKEN_EXPIRE_MINUTES="5" PARTIAL_TOKEN_EXPIRE_MINUTES=5
# Hash # Hash
ARGON2_TYPE="id" ARGON2_TYPE=id
ARGON2_TIME_COST="3" ARGON2_TIME_COST=3
ARGON2_MEMORY_COST="65536" ARGON2_MEMORY_COST=65536
ARGON2_PARALLELISM="4" ARGON2_PARALLELISM=4
ARGON2_SALT_LENGTH="16" ARGON2_SALT_LENGTH=16
ARGON2_HASH_LENGTH="48" ARGON2_HASH_LENGTH=48
# Recovery codes # Recovery codes
RECOVERY_CODES_COUNT="10" RECOVERY_CODES_COUNT=10
RECOVERY_CODE_SEGMENTS="4" RECOVERY_CODE_SEGMENTS=4
RECOVERY_CODE_SEGMENT_BYTES="2" RECOVERY_CODE_SEGMENT_BYTES=2
RECOVERY_MIN_REMAINING_WARNING="3" RECOVERY_MIN_REMAINING_WARNING=3
RECOVERY_MAX_AGE_DAYS="365" RECOVERY_MAX_AGE_DAYS=365
# TOTP_2FA # TOTP_2FA
TOTP_ISSUER="LiB" TOTP_ISSUER=LiB
TOTP_VALID_WINDOW="1" TOTP_VALID_WINDOW=1
+1 -1
View File
@@ -81,7 +81,7 @@ async def custom_not_found_handler(request: Request, exc: HTTPException):
content={"detail": "API endpoint not found", "path": path}, content={"detail": "API endpoint not found", "path": path},
) )
return await unknown(request) return await unknown(request, app)
@app.middleware("http") @app.middleware("http")
+39 -36
View File
@@ -1,4 +1,6 @@
"""Модуль прочих эндпоинтов и веб-страниц""" """Модуль прочих эндпоинтов и веб-страниц"""
import os
import sys
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
@@ -31,115 +33,116 @@ def get_info(app) -> Dict:
"description": app.description.rsplit("|", 1)[0], "description": app.description.rsplit("|", 1)[0],
}, },
"server_time": datetime.now().isoformat(), "server_time": datetime.now().isoformat(),
"domain": os.getenv("DOMAIN", ""),
} }
@router.get("/", include_in_schema=False) @router.get("/", include_in_schema=False)
async def root(request: Request): async def root(request: Request, app=Depends(lambda: get_app())):
"""Рендерит главную страницу""" """Рендерит главную страницу"""
return templates.TemplateResponse(request, "index.html") return templates.TemplateResponse(request, "index.html", get_info(app) | {"title": "LiB - Библиотека"})
@router.get("/unknown", include_in_schema=False) @router.get("/unknown", include_in_schema=False)
async def unknown(request: Request): async def unknown(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу 404 ошибки""" """Рендерит страницу 404 ошибки"""
return templates.TemplateResponse(request, "unknown.html") return templates.TemplateResponse(request, "unknown.html", get_info(app) | {"title": "LiB - Страница не найдена"})
@router.get("/genre/create", include_in_schema=False) @router.get("/genre/create", include_in_schema=False)
async def create_genre(request: Request): async def create_genre(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу создания жанра""" """Рендерит страницу создания жанра"""
return templates.TemplateResponse(request, "create_genre.html") return templates.TemplateResponse(request, "create_genre.html", get_info(app) | {"title": "LiB - Создать жанр"})
@router.get("/genre/{genre_id}/edit", include_in_schema=False) @router.get("/genre/{genre_id}/edit", include_in_schema=False)
async def edit_genre(request: Request, genre_id: int): async def edit_genre(request: Request, genre_id: int, app=Depends(lambda: get_app())):
"""Рендерит страницу редактирования жанра""" """Рендерит страницу редактирования жанра"""
return templates.TemplateResponse(request, "edit_genre.html") return templates.TemplateResponse(request, "edit_genre.html", get_info(app) | {"id": genre_id} | {"id": genre_id, "title": "LiB - Редактировать жанр"})
@router.get("/authors", include_in_schema=False) @router.get("/authors", include_in_schema=False)
async def authors(request: Request): async def authors(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу списка авторов""" """Рендерит страницу списка авторов"""
return templates.TemplateResponse(request, "authors.html") return templates.TemplateResponse(request, "authors.html", get_info(app) | {"title": "LiB - Авторы"})
@router.get("/author/create", include_in_schema=False) @router.get("/author/create", include_in_schema=False)
async def create_author(request: Request): async def create_author(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу создания автора""" """Рендерит страницу создания автора"""
return templates.TemplateResponse(request, "create_author.html") return templates.TemplateResponse(request, "create_author.html", get_info(app) | {"title": "LiB - Создать автора"})
@router.get("/author/{author_id}/edit", include_in_schema=False) @router.get("/author/{author_id}/edit", include_in_schema=False)
async def edit_author(request: Request, author_id: int): async def edit_author(request: Request, author_id: int, app=Depends(lambda: get_app())):
"""Рендерит страницу редактирования автора""" """Рендерит страницу редактирования автора"""
return templates.TemplateResponse(request, "edit_author.html") return templates.TemplateResponse(request, "edit_author.html", get_info(app) | {"id": author_id, "title": "LiB - Редактировать автора"})
@router.get("/author/{author_id}", include_in_schema=False) @router.get("/author/{author_id}", include_in_schema=False)
async def author(request: Request, author_id: int): async def author(request: Request, author_id: int, app=Depends(lambda: get_app())):
"""Рендерит страницу просмотра автора""" """Рендерит страницу просмотра автора"""
return templates.TemplateResponse(request, "author.html") return templates.TemplateResponse(request, "author.html", get_info(app) | {"id": author_id, "title": "LiB - Автор"})
@router.get("/books", include_in_schema=False) @router.get("/books", include_in_schema=False)
async def books(request: Request): async def books(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу списка книг""" """Рендерит страницу списка книг"""
return templates.TemplateResponse(request, "books.html") return templates.TemplateResponse(request, "books.html", get_info(app) | {"title": "LiB - Книги"})
@router.get("/book/create", include_in_schema=False) @router.get("/book/create", include_in_schema=False)
async def create_book(request: Request): async def create_book(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу создания книги""" """Рендерит страницу создания книги"""
return templates.TemplateResponse(request, "create_book.html") return templates.TemplateResponse(request, "create_book.html", get_info(app) | {"title": "LiB - Создать книгу"})
@router.get("/book/{book_id}/edit", include_in_schema=False) @router.get("/book/{book_id}/edit", include_in_schema=False)
async def edit_book(request: Request, book_id: int): async def edit_book(request: Request, book_id: int, app=Depends(lambda: get_app())):
"""Рендерит страницу редактирования книги""" """Рендерит страницу редактирования книги"""
return templates.TemplateResponse(request, "edit_book.html") return templates.TemplateResponse(request, "edit_book.html", get_info(app) | {"id": book_id, "title": "LiB - Редактировать книгу"})
@router.get("/book/{book_id}", include_in_schema=False) @router.get("/book/{book_id}", include_in_schema=False)
async def book(request: Request, book_id: int): async def book(request: Request, book_id: int, app=Depends(lambda: get_app())):
"""Рендерит страницу просмотра книги""" """Рендерит страницу просмотра книги"""
return templates.TemplateResponse(request, "book.html") return templates.TemplateResponse(request, "book.html", get_info(app) | {"id": book_id, "title": "LiB - Книга"})
@router.get("/auth", include_in_schema=False) @router.get("/auth", include_in_schema=False)
async def auth(request: Request): async def auth(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу авторизации""" """Рендерит страницу авторизации"""
return templates.TemplateResponse(request, "auth.html") return templates.TemplateResponse(request, "auth.html", get_info(app) | {"title": "LiB - Авторизация"})
@router.get("/2fa", include_in_schema=False) @router.get("/2fa", include_in_schema=False)
async def set2fa(request: Request): async def set2fa(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу установки двухфакторной аутентификации""" """Рендерит страницу установки двухфакторной аутентификации"""
return templates.TemplateResponse(request, "2fa.html") return templates.TemplateResponse(request, "2fa.html", get_info(app) | {"title": "LiB - Двухфакторная аутентификация"})
@router.get("/profile", include_in_schema=False) @router.get("/profile", include_in_schema=False)
async def profile(request: Request): async def profile(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу профиля пользователя""" """Рендерит страницу профиля пользователя"""
return templates.TemplateResponse(request, "profile.html") return templates.TemplateResponse(request, "profile.html", get_info(app) | {"title": "LiB - Профиль"})
@router.get("/users", include_in_schema=False) @router.get("/users", include_in_schema=False)
async def users(request: Request): async def users(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу управления пользователями""" """Рендерит страницу управления пользователями"""
return templates.TemplateResponse(request, "users.html") return templates.TemplateResponse(request, "users.html", get_info(app) | {"title": "LiB - Пользователи"})
@router.get("/my-books", include_in_schema=False) @router.get("/my-books", include_in_schema=False)
async def my_books(request: Request): async def my_books(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу моих книг пользователя""" """Рендерит страницу моих книг пользователя"""
return templates.TemplateResponse(request, "my_books.html") return templates.TemplateResponse(request, "my_books.html", get_info(app) | {"title": "LiB - Мои книги"})
@router.get("/analytics", include_in_schema=False) @router.get("/analytics", include_in_schema=False)
async def analytics(request: Request): async def analytics(request: Request, app=Depends(lambda: get_app())):
"""Рендерит страницу аналитики выдач""" """Рендерит страницу аналитики выдач"""
return templates.TemplateResponse(request, "analytics.html") return templates.TemplateResponse(request, "analytics.html", get_info(app) | {"title": "LiB - Аналитика"})
@router.get("/favicon.ico", include_in_schema=False) @router.get("/favicon.ico", include_in_schema=False)
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Настройка 2FA{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="flex flex-1 items-center justify-center p-4 bg-gray-100"> <div class="flex flex-1 items-center justify-center p-4 bg-gray-100">
<div <div
class="w-full max-w-4xl bg-white rounded-lg shadow-md overflow-hidden flex flex-col md:flex-row" class="w-full max-w-4xl bg-white rounded-lg shadow-md overflow-hidden flex flex-col md:flex-row"
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Аналитика{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-7xl"> <div class="container mx-auto p-4 max-w-7xl">
<div class="mb-8"> <div class="mb-8">
<h1 class="text-2xl font-semibold text-gray-900 mb-1">Аналитика выдач и возвратов</h1> <h1 class="text-2xl font-semibold text-gray-900 mb-1">Аналитика выдач и возвратов</h1>
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Авторизация{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="flex flex-1 items-center justify-center p-4"> <div class="flex flex-1 items-center justify-center p-4">
<div class="w-full max-w-md"> <div class="w-full max-w-md">
<div class="bg-white rounded-lg shadow-md overflow-hidden"> <div class="bg-white rounded-lg shadow-md overflow-hidden">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Автор{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-4xl"> <div class="container mx-auto p-4 max-w-4xl">
<div id="author-card" class="bg-white rounded-lg shadow-md p-6 mb-6"> <div id="author-card" class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Авторы{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4"> <div class="container mx-auto p-4">
<div <div
class="flex flex-col md:flex-row justify-between items-center mb-6 gap-4" class="flex flex-col md:flex-row justify-between items-center mb-6 gap-4"
+7 -1
View File
@@ -1,9 +1,15 @@
<!doctype html> <!doctype html>
<html lang="ru"> <html lang="ru">
<head> <head>
<title>{% block title %}LiB{% endblock %}</title> <title>{{ title }}</title>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="{{ title }}" />
<meta property="og:type" content="website" />
<meta property="og:description" content="Ваша персональная библиотека книг" />
<meta property="og:url" content="//{{ domain }}/" />
<!--<meta property="og:image" content="//{{ domain }}/img/{{ img }}.png" />-->
<script <script
defer defer
src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.3/dist/cdn.min.js" src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.3/dist/cdn.min.js"
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Книга{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-6xl"> <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 id="book-card" class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Книги{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<style> <style>
.range-double { .range-double {
height: 0; height: 0;
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Создание автора{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-xl"> <div class="container mx-auto p-4 max-w-xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Создание книги{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-3xl"> <div class="container mx-auto p-4 max-w-3xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Создание жанра{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-xl"> <div class="container mx-auto p-4 max-w-xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Редактирование автора{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-2xl"> <div class="container mx-auto p-4 max-w-2xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Редактирование книги{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-3xl"> <div class="container mx-auto p-4 max-w-3xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Редактирование жанра{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-2xl"> <div class="container mx-auto p-4 max-w-2xl">
<div class="bg-white rounded-lg shadow-md p-6 md:p-8"> <div class="bg-white rounded-lg shadow-md p-6 md:p-8">
<div class="mb-8 border-b border-gray-100 pb-4"> <div class="mb-8 border-b border-gray-100 pb-4">
+1 -1
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Библиотека{% endblock %} {% extends "base.html" %}
{% block content %} {% block content %}
<div class="flex flex-1 items-center justify-center p-4"> <div class="flex flex-1 items-center justify-center p-4">
<div class="w-full max-w-4xl"> <div class="w-full max-w-4xl">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Мои книги{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-6xl"> <div class="container mx-auto p-4 max-w-6xl">
<div class="mb-6"> <div class="mb-6">
<h1 class="text-3xl font-bold text-gray-900 mb-2">Мои книги</h1> <h1 class="text-3xl font-bold text-gray-900 mb-2">Мои книги</h1>
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Профиль{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4 max-w-2xl" <div class="container mx-auto p-4 max-w-2xl"
x-data="{ showPasswordModal: false, showDisable2FAModal: false, showRecoveryCodesModal: false, is2FAEnabled: false, recoveryCodesRemaining: null }" x-data="{ showPasswordModal: false, showDisable2FAModal: false, showRecoveryCodesModal: false, is2FAEnabled: false, recoveryCodesRemaining: null }"
@update-2fa.window="is2FAEnabled = $event.detail" @update-2fa.window="is2FAEnabled = $event.detail"
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Страница не найдена{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="flex flex-1 items-center justify-center p-4 min-h-[70vh]"> <div class="flex flex-1 items-center justify-center p-4 min-h-[70vh]">
<div class="w-full max-w-2xl"> <div class="w-full max-w-2xl">
<div class="bg-white rounded-lg shadow-md overflow-hidden"> <div class="bg-white rounded-lg shadow-md overflow-hidden">
+1 -2
View File
@@ -1,5 +1,4 @@
{% extends "base.html" %} {% block title %}LiB - Пользователи{% endblock %} {% extends "base.html" %}{% block content %}
{% block content %}
<div class="container mx-auto p-4"> <div class="container mx-auto p-4">
<div class="flex justify-between items-center mb-6"> <div class="flex justify-between items-center mb-6">
<h1 class="text-2xl font-bold text-gray-800"> <h1 class="text-2xl font-bold text-gray-800">