book star front end + favorited tab content

This commit is contained in:
SvyatoslavArtymovych 2023-05-12 17:26:04 +03:00
parent ddfcddeecd
commit ea68e88999
9 changed files with 146235 additions and 14 deletions

View File

@ -1,4 +1,6 @@
from app import db
from flask_login import current_user
from app import db, models as m
from app.models.utils import BaseModel
@ -23,3 +25,12 @@ class Book(BaseModel):
@property
def last_version(self):
return self.versions[-1]
@property
def current_user_has_star(self):
if current_user.is_authenticated:
book_star: m.BookStar = m.BookStar.query.filter_by(
user_id=current_user.id, book_id=self.id
).first()
if book_star:
return True

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,9 +29,9 @@
</p>
{% endif %}
<div class="flex ml-auto align-center justify-center space-x-3">
<span class="space-x-0.5 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
<p>{{ book.stars|length }}</p>
<span class="book-star-block space-x-0.5 flex items-center">
<svg class="star-btn cursor-pointer w-4 h-4 inline-flex mr-1 {% if book.current_user_has_star %}fill-yellow-300{% endif %}" data-book-id={{ book.id }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
<p class="total-stars">{{ book.stars|length }}</p>
</span>
<span class="space-x-0.5 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>

View File

@ -38,8 +38,15 @@
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> <tr> <th scope="col" class="px-6 py-3"> Username </th> <th scope="col" class="px-6 py-3"> Address </th> </tr> </thead>
<tbody>
{% for star in book.stars %}
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"> <th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"> {{star.user.username}} </th> <td class="px-6 py-4"> {{star.user.wallet_id}} </td> </tr>
{% for user in book.stars %}
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{user.username}}
</th>
<td class="px-6 py-4">
{{user.wallet_id}}
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -108,9 +108,9 @@
<p> Last updated on {{book.versions[-1].updated_at.strftime('%B %d, %Y')}} </p>
{% endif %}
<div class="flex ml-auto align-center justify-center space-x-3">
<span class="space-x-0.5 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
<p>{{ book.stars|length }}</p>
<span class="book-star-block space-x-0.5 flex items-center">
<svg class="star-btn cursor-pointer w-4 h-4 inline-flex mr-1 {% if book.current_user_has_star %}fill-yellow-300{% endif %}" data-book-id={{ book.id }} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" /> </svg>
<a href={{ url_for('book.statistic_view', book_id=book.id ) }} class="total-stars">{{ book.stars|length }}</a>
</span>
<span class="space-x-0.5 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" stroke-width="1" stroke="currentColor" class="w-4 h-4 inline-flex mr-1"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /> </svg>

View File

@ -154,8 +154,7 @@ def statistic_view(book_id: int):
log(log.WARNING, "Book with id [%s] not found", book_id)
flash("Book not found", "danger")
return redirect(url_for("book.my_library"))
else:
return render_template("book/stat.html", book=book)
return render_template("book/stat.html", book=book)
@bp.route("/<int:book_id>/<int:collection_id>/subcollections", methods=["GET"])

View File

@ -7,6 +7,7 @@ import {initComments} from './comment';
import {initVote} from './vote';
import {initTheme} from './theme';
import {initApprove} from './approve';
import {initStar} from './star';
initBooks();
initContributors();
@ -17,3 +18,4 @@ initComments();
initVote();
initTheme();
initApprove();
initStar();

38
src/star.ts Normal file
View File

@ -0,0 +1,38 @@
const starClickEventListener = async (btn: Element, totalStars: Element) => {
const bookId = btn.getAttribute('data-book-id');
const requestUrl = '/star/' + bookId;
const response = await fetch(requestUrl, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
});
const json = await response.json();
const currentUserStar = json.current_user_star;
const starsCount = json.stars_count;
totalStars.innerHTML = starsCount;
btn.classList.remove('fill-yellow-300');
if (currentUserStar) {
btn.classList.add('fill-yellow-300');
} else {
btn.classList.remove('fill-yellow-300');
}
};
export function initStar() {
const bookStarsBlocks = document.querySelectorAll('.book-star-block');
bookStarsBlocks.forEach(bookStarsBlock => {
const bookStarBtn = bookStarsBlock.querySelector('.star-btn');
const totalStarsDiv = bookStarsBlock.querySelector('.total-stars');
bookStarBtn.addEventListener('click', () => {
starClickEventListener(bookStarBtn, totalStarsDiv);
});
});
}